From e5b943d13d3376145b8ac3866d91f3038f6aa5a4 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 09:24:57 -0400 Subject: [PATCH 0001/6505] Initial commit --- LICENSE | 21 +++++++++++++++++++++ README.md | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..b3b9c59c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 tteck + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..d68b4165 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Proxmox +Proxmox Helper Scripts From 1a4f083f885abd296f7759b934ab6e29365ea42d Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 09:59:18 -0400 Subject: [PATCH 0002/6505] Add files via upload --- esphome_container.sh | 159 +++++++++++++++++++++++++++++++++++++++++++ esphome_setup.sh | 84 +++++++++++++++++++++++ 2 files changed, 243 insertions(+) create mode 100644 esphome_container.sh create mode 100644 esphome_setup.sh diff --git a/esphome_container.sh b/esphome_container.sh new file mode 100644 index 00000000..fead0561 --- /dev/null +++ b/esphome_container.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://github.com/tteck/proxmox_esphome/raw/master/setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=4G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=esphome +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID setup.sh /setup.sh -perms 755 +pct exec $CTID /setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created esphome LXC Container to $CTID at IP Address ${IP}:6052" \ No newline at end of file diff --git a/esphome_setup.sh b/esphome_setup.sh new file mode 100644 index 00000000..ae8dd67a --- /dev/null +++ b/esphome_setup.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating Container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + # Installing pip3 + msg "Installing pip3..." + apt-get install python3-pip -y &>/dev/null + # Install ESPHome; + msg "Installing ESPHome..." + pip3 install esphome &>/dev/null + # Installing ESPHome Dashboard + msg "Installing ESPHome Dashboard..." + pip3 install tornado esptool &>/dev/null + +echo "Creating service file esphomeDashboard.service" +service_path="/etc/systemd/system/esphomeDashboard.service" + +echo "[Unit] +Description=ESPHome Dashboard +After=network.target +[Service] +ExecStart=/usr/local/bin/esphome /root/config/ dashboard +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable esphomeDashboard.service &>/dev/null +systemctl start esphomeDashboard +# Customize container +msg "Customizing Container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 256ec29a0f09ce62372160b6c8a37b3da53fd16b Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:02:12 -0400 Subject: [PATCH 0003/6505] Update README.md --- README.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d68b4165..1b0d44ba 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,74 @@ -# Proxmox -Proxmox Helper Scripts + + + +
+ESPHome LXC + +

Proxmox ESPHome LXC Container

+ +To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/master/esphome_container.sh)" +``` + + +
+ + + + + +
+MQTT LXC + +

Proxmox MQTT LXC Container

+ +To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/proxmox_mqtt_lxc/raw/master/create_container.sh)" +``` +### The commands below are entered through the newly created mqtt lxc console. +Mosquitto comes with a password file generating utility called mosquitto_passwd. +``` +sudo mosquitto_passwd -c /etc/mosquitto/passwd +``` +Password: < password > + +Create a configuration file for Mosquitto pointing to the password file we have just created. +``` +sudo nano /etc/mosquitto/conf.d/default.conf +``` +This will open an empty file. Paste the following into it. +``` +allow_anonymous false +password_file /etc/mosquitto/passwd +``` +Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X". + +Now restart Mosquitto server. +``` +sudo systemctl restart mosquitto +``` + + +
+ + + + + +
+Node-Red LXC + +

Proxmox Node-Red LXC Container

+ +To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/proxmox_nr_lxc/raw/master/create_container.sh)" +``` + + +
From 921b9615dff0e34c9c35cdca34aef1e1d97885bb Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:04:37 -0400 Subject: [PATCH 0004/6505] Update esphome_container.sh --- esphome_container.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome_container.sh b/esphome_container.sh index fead0561..b1588179 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://github.com/tteck/proxmox_esphome/raw/master/setup.sh +wget -qL https://github.com/tteck/Proxmox/raw/master/esphome_setup.sh # Detect modules and automatically load at boot load_module overlay @@ -151,9 +151,9 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID setup.sh /setup.sh -perms 755 -pct exec $CTID /setup.sh +pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 +pct exec $CTID /esphome_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created esphome LXC Container to $CTID at IP Address ${IP}:6052" \ No newline at end of file +info "Successfully created esphome LXC Container to $CTID at IP Address ${IP}:6052" From a4ff22107c6103a89c4d7c38130ab94be7f53226 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:13:02 -0400 Subject: [PATCH 0005/6505] Update esphome_setup.sh --- esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index ae8dd67a..edfed5de 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -81,4 +81,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 7eaf0ac85878b11810a9e9d7665dbe549928a1fa Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:18:09 -0400 Subject: [PATCH 0006/6505] Update esphome_setup.sh --- esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index edfed5de..e793b857 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -81,4 +81,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /setup1.sh /var/{cache,log}/* /var/lib/apt/lists/* From 8c299dd8970f7c10a5086bca5c728778857faeb5 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:18:53 -0400 Subject: [PATCH 0007/6505] Rename esphome_setup.sh to setup1.sh --- esphome_setup.sh => setup1.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename esphome_setup.sh => setup1.sh (100%) diff --git a/esphome_setup.sh b/setup1.sh similarity index 100% rename from esphome_setup.sh rename to setup1.sh From 952e1294663f7621e7bfa76314acc4b33fa9647e Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:20:21 -0400 Subject: [PATCH 0008/6505] Update esphome_container.sh --- esphome_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome_container.sh b/esphome_container.sh index b1588179..5547d617 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://github.com/tteck/Proxmox/raw/master/esphome_setup.sh +wget -qL https://github.com/tteck/Proxmox/raw/master/setup1.sh # Detect modules and automatically load at boot load_module overlay @@ -151,8 +151,8 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 -pct exec $CTID /esphome_setup.sh +pct push $CTID setup1.sh /setup1.sh -perms 755 +pct exec $CTID /setup1.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From b94757a8f1d995d2c1e6e583339e6ca656bda191 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:23:28 -0400 Subject: [PATCH 0009/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b0d44ba..47c0ee20 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/master/esphome_container.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/blob/main/esphome_container.sh)" ``` From f0db1de4d990b7b1f34c90233b24f3b946d657b8 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:25:46 -0400 Subject: [PATCH 0010/6505] Update esphome_container.sh --- esphome_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_container.sh b/esphome_container.sh index 5547d617..c551a5d2 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://github.com/tteck/Proxmox/raw/master/setup1.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup1.sh # Detect modules and automatically load at boot load_module overlay From be1bfb85d3e76b18d42723001bdf7370484e190d Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:26:46 -0400 Subject: [PATCH 0011/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47c0ee20..8bdd2355 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/blob/main/esphome_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_container.sh)" ``` From 807471e0a7fc49b1d1dcc4d968652e562b385ec4 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:29:49 -0400 Subject: [PATCH 0012/6505] Update and rename setup1.sh to esphome_setup.sh --- setup1.sh => esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename setup1.sh => esphome_setup.sh (97%) diff --git a/setup1.sh b/esphome_setup.sh similarity index 97% rename from setup1.sh rename to esphome_setup.sh index e793b857..edfed5de 100644 --- a/setup1.sh +++ b/esphome_setup.sh @@ -81,4 +81,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /setup1.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 87b2205759fc3316f3760796b163533c85c1e638 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:32:16 -0400 Subject: [PATCH 0013/6505] Update esphome_container.sh --- esphome_container.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome_container.sh b/esphome_container.sh index c551a5d2..b00ee2de 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup1.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_setup.sh # Detect modules and automatically load at boot load_module overlay @@ -151,9 +151,9 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID setup1.sh /setup1.sh -perms 755 -pct exec $CTID /setup1.sh +pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 +pct exec $CTID /esphome_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created esphome LXC Container to $CTID at IP Address ${IP}:6052" +info "Successfully created ESPHome LXC Container to $CTID at IP Address ${IP}:6052" From ed4e3dcb6b85894822de9e85b68feba3488a9c8a Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:44:59 -0400 Subject: [PATCH 0014/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bdd2355..a54a15a5 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ sudo systemctl restart mosquitto To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/proxmox_nr_lxc/raw/master/create_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_container.sh)" ``` From dcdec9c0ec963d31a9ff0ccbfdf032529b01f5f8 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:46:24 -0400 Subject: [PATCH 0015/6505] Add files via upload --- node-red_container.sh | 161 ++++++++++++++++++++++++++++++++++++++++++ node-red_setup.sh | 77 ++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 node-red_container.sh create mode 100644 node-red_setup.sh diff --git a/node-red_container.sh b/node-red_container.sh new file mode 100644 index 00000000..fc71cb31 --- /dev/null +++ b/node-red_container.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_setup.sh + +# Detect modules and automatically load at boot +#load_module aufs +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=nodered +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 +pct exec $CTID /node-red_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Node-RED LXC Container to $CTID at IP Address ${IP}" diff --git a/node-red_setup.sh b/node-red_setup.sh new file mode 100644 index 00000000..f4201e80 --- /dev/null +++ b/node-red_setup.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing Node..." +sudo apt -y install nodejs npm &>/dev/null + +msg "Installing PM2..." +npm install -g pm2 &>/dev/null + +# Install Node Red +msg "Installing Node-RED..." +npm install -g --unsafe-perm node-red &>/dev/null + +# Set up PM2 to manage startup of Node Red +msg "Setting up PM2..." +/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null +/usr/local/bin/pm2 save &>/dev/null +/usr/local/bin/pm2 startup &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 716cf4eaee083792ba5bf159e36d007a15b1cf25 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:53:46 -0400 Subject: [PATCH 0016/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a54a15a5..84a571c9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esph To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/proxmox_mqtt_lxc/raw/master/create_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_container.sh)" ``` ### The commands below are entered through the newly created mqtt lxc console. Mosquitto comes with a password file generating utility called mosquitto_passwd. From 9e2dde4d557cb4aaca0c382c88bb00d350317d4b Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 10:54:21 -0400 Subject: [PATCH 0017/6505] Add files via upload --- mqtt_container.sh | 161 ++++++++++++++++++++++++++++++++++++++++++++++ mqtt_setup.sh | 67 +++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 mqtt_container.sh create mode 100644 mqtt_setup.sh diff --git a/mqtt_container.sh b/mqtt_container.sh new file mode 100644 index 00000000..76a840ef --- /dev/null +++ b/mqtt_container.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_setup.sh + +# Detect modules and automatically load at boot +#load_module aufs +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=mqtt +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID mqtt_setup.sh /mqtt_setup.sh -perms 755 +pct exec $CTID /mqtt_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a MQTT LXC Container to $CTID at IP Address ${IP}" diff --git a/mqtt_setup.sh b/mqtt_setup.sh new file mode 100644 index 00000000..d4a84d1c --- /dev/null +++ b/mqtt_setup.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +# Installing Mosquitto MQTT broker +msg "Installing Mosquitto MQTT broker.." +sudo apt-get update >/dev/null +sudo apt-get -y install mosquitto &>/dev/null +sudo apt-get -y install mosquitto-clients &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From fa7929d4b3d437a9505a0160277308f50a2fb13c Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:04:01 -0400 Subject: [PATCH 0018/6505] Update README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 84a571c9..8e47dc64 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,23 @@ +
+Home Assistant OS VM + +

Proxmox VM with Home Assistant OS

+ +To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell + +``` +bash -c "$(wget -qLO - https://github.com/tteck/proxmox_haos_vm/raw/master/install.sh)" +``` +###

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. + + +
+ + +
ESPHome LXC From e7b061588ff7170c7062328d57a317d6e9d17798 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:06:33 -0400 Subject: [PATCH 0019/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e47dc64..dbd40850 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell ``` -bash -c "$(wget -qLO - https://github.com/tteck/proxmox_haos_vm/raw/master/install.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" ``` ###

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. From c53da890ca7f8daa9674e8bc96bf02b7f825eaaf Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:06:59 -0400 Subject: [PATCH 0020/6505] Add files via upload --- haos_vm.sh | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 haos_vm.sh diff --git a/haos_vm.sh b/haos_vm.sh new file mode 100644 index 00000000..de7c9566 --- /dev/null +++ b/haos_vm.sh @@ -0,0 +1,188 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Disk image' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +VMID=$(pvesh get /cluster/nextid) +info "Container ID is $VMID." + +# Get latest Home Assistant disk image archive URL +echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" +RELEASE_TYPE=vmdk +URL=$(cat< /dev/null; then + echo -e "\e[1;33m Installing Unzip... \e[0m" + apt-get update + apt install unzip -y + fi +fi + +# Extract Home Assistant disk image +echo -e "\e[1;33m Extracting disk image... \e[0m" +case $FILE in + *"gz") gunzip -f $FILE;; + *"zip") unzip -o $FILE;; + *"xz") xz -d $FILE;; + *) die "Unable to handle file extension '${FILE##*.}'.";; +esac + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + IMPORT_OPT="-format qcow2" +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done + +# Create VM +echo -e "\e[1;33m Creating VM... \e[0m" +VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) +qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},size=128K \ + -sata0 ${DISK1_REF},size=32G > /dev/null +qm set $VMID \ + -boot order=sata0 > /dev/null + +# Add serial port and enable console output +set +o errtrace +( + echo -e "\e[1;33m Adding serial port and configuring console... \e[0m" + trap ' + warn "Unable to configure serial port. VM is still functional." + if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VMID --delete serial0 >/dev/null + fi + exit + ' ERR + if [ "$(command -v kpartx)" = "" ]; then + echo -e "\e[1;33m Installing kpartx... \e[0m" + apt-get update >/dev/null + apt-get -qqy install kpartx &>/dev/null + fi + DISK1_PATH="$(pvesm path $DISK1_REF)" + DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" + DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" + TEMP_MOUNT="${TEMP_DIR}/mnt" + trap ' + findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT + command -v kpartx >/dev/null && kpartx -d $DISK1_PATH + ' EXIT + kpartx -a $DISK1_PATH + mkdir $TEMP_MOUNT + mount $DISK1_PART1_PATH $TEMP_MOUNT + sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt + qm set $VMID -serial0 socket >/dev/null +) + +info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." \ No newline at end of file From 633f4b08bf81d378d0153f46419df7cb31706274 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:11:22 -0400 Subject: [PATCH 0021/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dbd40850..65d33313 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

Select the Proxmox Helper Below

From b7f36bedd72eafe9feb206ccec6dbabf262dddd3 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:12:03 -0400 Subject: [PATCH 0022/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65d33313..0196704c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Select the Proxmox Helper Below

+

Select A Proxmox Helper Below

From c0473d7b0a2f9c81446a72a0a03b4a54ef666abc Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:12:34 -0400 Subject: [PATCH 0023/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0196704c..0e593121 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Select A Proxmox Helper Below

+

Select Proxmox Helper Below

From f74f513dcf32df9d9f8823bdda34e38847198e01 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:23:54 -0400 Subject: [PATCH 0024/6505] Update README.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 0e593121..f7121909 100644 --- a/README.md +++ b/README.md @@ -90,4 +90,21 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node ``` +
+ + + + +
+Mariadb LXC + +

Proxmox Mariadb LXC Container

+ +To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_container.sh)" +``` + +
From 4b080b48969a9e4a470b68c09b275b564e8338c9 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:25:31 -0400 Subject: [PATCH 0025/6505] Update README.md --- README.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/README.md b/README.md index f7121909..4098a200 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,74 @@ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_container.sh)" ``` +To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: +``` +nano /etc/mysql/mariadb.conf.d/50-server.cnf +``` +Un-comment port, and comment skip-networking and bind-address. (match below) +```user = mysql +pid-file = /run/mysqld/mysqld.pid +socket = /run/mysqld/mysqld.sock +port = 3306 +basedir = /usr +datadir = /var/lib/mysql +tmpdir = /tmp +lc-messages-dir = /usr/share/mysql +# skip-external-locking +# skip-networking +# Instead of skip-networking the default is now to listen only on +# localhost which is more compatible and is not less secure. +# bind-address = 127.0.0.1 +``` + +For new MariaDB installations, the next step is to run the included security script. This script changes some of the less secure default options. We will use it to block remote root logins and to remove unused database users. + +Run the security script: +``` +sudo mysql_secure_installation +``` +This will take you through a series of prompts where you can make some changes to your MariaDB installation’s security options. The first prompt will ask you to enter the current database root password. Since we have not set one up yet, press ENTER to indicate “none”. + +The next prompt asks you whether you’d like to set up a database root password. Type N and then press ENTER. In Debian, the root account for MariaDB is tied closely to automated system maintenance, so we should not change the configured authentication methods for that account. Doing so would make it possible for a package update to break the database system by removing access to the administrative account. Later, we will cover how to optionally set up an additional administrative account for password access if socket authentication is not appropriate for your use case. + +From there, you can press Y and then ENTER to accept the defaults for all the subsequent questions. This will remove some anonymous users and the test database, disable remote root logins, and load these new rules so that MariaDB immediately respects the changes you have made. + + +The root MariaDB user is set to authenticate using the unix_socket plugin by default rather than with a password. This allows for some greater security and usability in many cases, but it can also complicate things when you need to allow an external program (e.g., phpMyAdmin) administrative rights. + +Because the server uses the root account for tasks like log rotation and starting and stopping the server, it is best not to change the root account’s authentication details. Changing credentials in the /etc/mysql/debian.cnf configuration file may work initially, but package updates could potentially overwrite those changes. Instead of modifying the root account, the package maintainers recommend creating a separate administrative account for password-based access. + +To do so, we will create a new account called admin with the same capabilities as the root account, but configured for password authentication. +``` +sudo mysql +``` +Prompt will change to ```MariaDB [(none)]>``` + +Now, we will create the user admin with root privileges and password-based access that can connect from anywhere on my local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: +``` +GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; +``` +Flush the privileges to ensure that they are saved and available in the current session: +``` +FLUSH PRIVILEGES; +``` +Following this, exit the MariaDB shell: +``` +exit +``` +Log in as the new database user you just created: +``` +mysql -u admin -p +``` +Create a new database: +``` +CREATE DATABASE homeassistant; +``` +Checking status. +``` +sudo systemctl status mariadb +``` +Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@192.168.100.lxc-ip:3306/homeassistant?charset=utf8mb4``` From ef5628c05fd0e84174e77de00e0a38c87e8a60f1 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:27:17 -0400 Subject: [PATCH 0026/6505] Add files via upload --- mariadb_container.sh | 161 +++++++++++++++++++++++++++++++++++++++++++ mariadb_setup.sh | 66 ++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 mariadb_container.sh create mode 100644 mariadb_setup.sh diff --git a/mariadb_container.sh b/mariadb_container.sh new file mode 100644 index 00000000..f6ccde3f --- /dev/null +++ b/mariadb_container.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_setup.sh + +# Detect modules and automatically load at boot +#load_module aufs +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=mariadb +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID mariadb_setup.sh /mariadb_setup.sh -perms 755 +pct exec $CTID /mariadb_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a MariaDB LXC Container to $CTID at IP Address ${IP}" diff --git a/mariadb_setup.sh b/mariadb_setup.sh new file mode 100644 index 00000000..4bfb0267 --- /dev/null +++ b/mariadb_setup.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +# Installing MariaDB +msg "Installing MariaDB..." +sudo apt-get update >/dev/null +sudo apt-get install -y mariadb-server &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 2dbe0215ebb0d9524449a8a1a17205847ca51f2a Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:47:15 -0400 Subject: [PATCH 0027/6505] Update README.md --- README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/README.md b/README.md index 4098a200..ad7027f2 100644 --- a/README.md +++ b/README.md @@ -175,4 +175,57 @@ sudo systemctl status mariadb Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@192.168.100.lxc-ip:3306/homeassistant?charset=utf8mb4``` + + + + + +
+PVE6 Zigbee2MQTT LXC + +

Proxmox PVE6 Zigbee2MQTT LXC Container

+ +To create a new Proxmox 6 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/proxmox6_z2m_lxc/raw/master/create_container.sh)" +``` + +Determine the location of your adapter (Run in the zigbee2mqtt console) +``` +ls -l /dev/serial/by-id +``` +Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` + +:warning: **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** +``` +nano /opt/zigbee2mqtt/data/configuration.yaml +``` + +Example: +``` +frontend: + port: 9442 +homeassistant: true +permit_join: false +mqtt: + base_topic: zigbee2mqtt + server: 'mqtt://192.168.86.224:1883' + user: usr + password: pwd + keepalive: 60 + reject_unauthorized: true + version: 4 +serial: + port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 +advanced: + pan_id: GENERATE + network_key: GENERATE + channel: 20 + ``` +Zigbee2mqtt can be started after completing the configuration by running +``` +sudo systemctl start zigbee2mqtt +``` +
From 4b4616ebc5d259c86b88e08b2f44df47fe2ae83e Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:48:18 -0400 Subject: [PATCH 0028/6505] Add files via upload --- pve6_zigbee2mqtt_container.sh | 173 ++++++++++++++++++++++++++++++++++ pve6_zigbee2mqtt_setup.sh | 90 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 pve6_zigbee2mqtt_container.sh create mode 100644 pve6_zigbee2mqtt_setup.sh diff --git a/pve6_zigbee2mqtt_container.sh b/pve6_zigbee2mqtt_container.sh new file mode 100644 index 00000000..950222f8 --- /dev/null +++ b/pve6_zigbee2mqtt_container.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_zigbee2mqtt_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=zigbee2mqtt +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Modify LXC permissions to support Zigbee Sticks +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup.devices.allow: c 188:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID pve6_zigbee2mqtt_setup.sh /pve6_zigbee2mqtt_setup.sh -perms 755 +pct exec $CTID /pve6_zigbee2mqtt_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" +echo +echo -e "\e[1;31m Update of configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" +echo +echo -e "Z2M can be started after completing the configuration buy running \e[1;33m sudo systemctl start zigbee2mqtt \e[0m" +echo diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh new file mode 100644 index 00000000..86b46ed9 --- /dev/null +++ b/pve6_zigbee2mqtt_setup.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating Container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + # Setup Node.js repository + msg "Setting up Node.js Repository..." + sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null + # Install Node.js; + msg "Installing Node.js..." + sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + # Clone Zigbee2MQTT repository + msg "Setting up Zigbee2MQTT Repository..." + sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null + # Install zigbee2mqtt + msg "Installing Zigbee2MQTT..." + cd /opt/zigbee2mqtt &>/dev/null + npm ci --production &>/dev/null + +echo "Creating service file zigbee2mqtt.service" +service_path="/etc/systemd/system/zigbee2mqtt.service" + +echo "[Unit] +Description=zigbee2mqtt +After=network.target +[Service] +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zigbee2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path + +# Customize container +msg "Customizing Container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /pve6_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 7fd75f9b0eb5abffc536ce415df4f95897bb1f4c Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:56:33 -0400 Subject: [PATCH 0029/6505] Update README.md --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ad7027f2..1c3f44dc 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,60 @@ Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:pass To create a new Proxmox 6 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/proxmox6_z2m_lxc/raw/master/create_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_zigbee2mqtt_container.sh)" +``` + +Determine the location of your adapter (Run in the zigbee2mqtt console) +``` +ls -l /dev/serial/by-id +``` +Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` + +:warning: **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** +``` +nano /opt/zigbee2mqtt/data/configuration.yaml +``` + +Example: +``` +frontend: + port: 9442 +homeassistant: true +permit_join: false +mqtt: + base_topic: zigbee2mqtt + server: 'mqtt://192.168.86.224:1883' + user: usr + password: pwd + keepalive: 60 + reject_unauthorized: true + version: 4 +serial: + port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 +advanced: + pan_id: GENERATE + network_key: GENERATE + channel: 20 + ``` +Zigbee2mqtt can be started after completing the configuration by running +``` +sudo systemctl start zigbee2mqtt +``` + + + + + + +
+PVE7 Zigbee2MQTT LXC + +

Proxmox PVE7 Zigbee2MQTT LXC Container

+ +To create a new Proxmox 7 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_zigbee2mqtt_container.sh)" ``` Determine the location of your adapter (Run in the zigbee2mqtt console) From 0770e0a15a3814adcfdba75edaff3e4960306994 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:57:40 -0400 Subject: [PATCH 0030/6505] Add files via upload --- pve7_zigbee2mqtt_container.sh | 173 ++++++++++++++++++++++++++++++++++ pve7_zigbee2mqtt_setup.sh | 90 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 pve7_zigbee2mqtt_container.sh create mode 100644 pve7_zigbee2mqtt_setup.sh diff --git a/pve7_zigbee2mqtt_container.sh b/pve7_zigbee2mqtt_container.sh new file mode 100644 index 00000000..8d6b1cac --- /dev/null +++ b/pve7_zigbee2mqtt_container.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_zigbee2mqtt_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=zigbee2mqtt +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Modify LXC permissions to support Zigbee Sticks +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID pve7_zigbee2mqtt_setup.sh /pve7_zigbee2mqtt_setup.sh -perms 755 +pct exec $CTID /pve7_zigbee2mqtt_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" +echo +echo -e "\e[1;31m Update of configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" +echo +echo -e "Z2M can be started after completing the configuration buy running \e[1;33m sudo systemctl start zigbee2mqtt \e[0m" +echo diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh new file mode 100644 index 00000000..b125c2a1 --- /dev/null +++ b/pve7_zigbee2mqtt_setup.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating Container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + # Setup Node.js repository + msg "Setting up Node.js Repository..." + sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null + # Install Node.js; + msg "Installing Node.js..." + sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + # Clone Zigbee2MQTT repository + msg "Setting up Zigbee2MQTT Repository..." + sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null + # Install zigbee2mqtt + msg "Installing Zigbee2MQTT..." + cd /opt/zigbee2mqtt &>/dev/null + npm ci --production &>/dev/null + +echo "Creating service file zigbee2mqtt.service" +service_path="/etc/systemd/system/zigbee2mqtt.service" + +echo "[Unit] +Description=zigbee2mqtt +After=network.target +[Service] +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zigbee2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path + +# Customize container +msg "Customizing Container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /pve7_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 86c73e96a6102edb167a2408ab07a87df59921b0 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 11:59:54 -0400 Subject: [PATCH 0031/6505] Add files via upload --- autodev.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 autodev.sh diff --git a/autodev.sh b/autodev.sh new file mode 100644 index 00000000..dbee7730 --- /dev/null +++ b/autodev.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Array of device types to enable in container +#CHAR_DEVS+=(major:minor) +CHAR_DEVS+=("1:1") #mem (physical memory access) +CHAR_DEVS+=("4:\([3-9]\|[1-5][0-9]\|6[0-3]\)") #tty* (virtual console, minor 3-63) +CHAR_DEVS+=("4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)") #ttyS* (UART serial port, minor 64-255) +CHAR_DEVS+=("10:200") #net/tun (TAP/TUN network device) +CHAR_DEVS+=("116:.*") #(ALSA devices) +CHAR_DEVS+=("166:.*") #ttyACM* (ACM USB modems) +CHAR_DEVS+=("180:\([0-9]\|1[0-5]\)") #usb/hiddev* (UPS devices, minor 0-15) +CHAR_DEVS+=("188:.*") #ttyUSB* (USB serial converters) +CHAR_DEVS+=("189:.*") #bus/usb/* (USB serial converters - alternate devices) + +# Proccess char device string +for char_dev in ${CHAR_DEVS[@]}; do + [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" + CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" +done + +# Store autodev hook script in variable +read -r -d '' HOOK_SCRIPT <<- EOF || true +for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do + dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; + mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); + for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do + mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); + cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; + done; + cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; +done; +EOF +HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} #Remove newline char from variable + +# Remove autodev settings +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf +cat CTID.conf >$CTID_CONFIG_PATH + +# Add autodev settings +cat <> $CTID_CONFIG_PATH +lxc.autodev: 1 +lxc.hook.autodev: bash -c '$HOOK_SCRIPT' +EOF \ No newline at end of file From 70d1bfda62ea3bef432def941af972953aa56f96 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:14:36 -0400 Subject: [PATCH 0032/6505] Update README.md --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index 1c3f44dc..c0e35de4 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,40 @@ After the script completes, If you're dissatisfied with the default settings, cl
+
+PVE6 Home Assistant Container LXC + +

Proxmox 6 Home Assistant LXC Container

+ +To create a new Proxmox 6 Home Assistant Container, run the following from Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" +``` + + +
+ + + + +
+PVE7 Home Assistant Container LXC + +

Proxmox 7 Home Assistant LXC Container

+ +To create a new Proxmox 7 Home Assistant Container, run the following from Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_container.sh)" +``` + + +
+ + + +
ESPHome LXC From 3644038dd99f50b60699696f4904eab6863fb0e6 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:16:25 -0400 Subject: [PATCH 0033/6505] Update README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index c0e35de4..fa80fce1 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,20 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ``` + +## Defaults +32GB storage and 512 MiB memory, + +go to Resources > Memory and edit your memory amount (4GB=4096) and cores (2) + +For Home Assistant interface http:// (LXC IP) :8123 + +For Portainer interface http:// (LXC IP) :9000 + +Path to HA configuration.yaml +``` +/var/lib/docker/volumes/hass_config/_data
@@ -47,7 +60,20 @@ To create a new Proxmox 7 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_container.sh)" ``` + +## Defaults +32GB storage and 512 MiB memory, + +go to Resources > Memory and edit your memory amount (4GB=4096) and cores (2) + +For Home Assistant interface http:// (LXC IP) :8123 + +For Portainer interface http:// (LXC IP) :9000 + +Path to HA configuration.yaml +``` +/var/lib/docker/volumes/hass_config/_data From e40d677ff38d71dc3a79dd6f45b5907c841a2e58 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:17:10 -0400 Subject: [PATCH 0034/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fa80fce1..7f21ea74 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data + @@ -75,6 +76,7 @@ Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data + From c66dc658c55620ee040286c66d5f256f8eea7134 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:18:59 -0400 Subject: [PATCH 0035/6505] Update README.md --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7f21ea74..32076b68 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,6 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ``` - ## Defaults 32GB storage and 512 MiB memory, @@ -44,8 +43,8 @@ For Portainer interface http:// (LXC IP) :9000 Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data - - + ``` + @@ -75,7 +74,7 @@ For Portainer interface http:// (LXC IP) :9000 Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data - + ``` From e36d546dd14fd1671810ca11e430fe0ff420db97 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:24:08 -0400 Subject: [PATCH 0036/6505] Add files via upload --- pve6_ha_container.sh | 178 +++++++++++++++++++++++++++++++++++++++++++ pve6_ha_setup.sh | 100 ++++++++++++++++++++++++ pve7_ha_container.sh | 178 +++++++++++++++++++++++++++++++++++++++++++ pve7_ha_setup.sh | 100 ++++++++++++++++++++++++ 4 files changed, 556 insertions(+) create mode 100644 pve6_ha_container.sh create mode 100644 pve6_ha_setup.sh create mode 100644 pve7_ha_container.sh create mode 100644 pve7_ha_setup.sh diff --git a/pve6_ha_container.sh b/pve6_ha_container.sh new file mode 100644 index 00000000..e047a9af --- /dev/null +++ b/pve6_ha_container.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_setup.sh + +# Detect modules and automatically load at boot +load_module aufs +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=32G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=homeassistant +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Modify LXC permissions to support Docker +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup.devices.allow: a +lxc.cap.drop: +EOF + +# Set container description +pct set $CTID -description "Access Portainer interface using the following URL. + +http://:9000" + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID pve6_ha_setup.sh /pve6_ha_setup.sh -perms 755 +pct exec $CTID /pve6_ha_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Home Assistant Container LXC to $CTID." +msg " + +Home Assistant is reachable by going to the following URLs. + + http://${IP}:8123 +" \ No newline at end of file diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh new file mode 100644 index 00000000..563831c9 --- /dev/null +++ b/pve6_ha_setup.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl &>/dev/null + +# Customize Docker configuration +msg "Customizing Docker..." +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +# Install Docker +msg "Installing Docker..." +sh <(curl -sSL https://get.docker.com) &>/dev/null + +# Install Portainer +msg "Installing Portainer..." +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer &>/dev/null + +# Install Home Assistant +msg "Installing Home Assistant..." +docker volume create hass_config >/dev/null +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /pve6_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh new file mode 100644 index 00000000..621ea11c --- /dev/null +++ b/pve7_ha_container.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_setup.sh + +# Detect modules and automatically load at boot +load_module aufs +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=32G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=homeassistant +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Modify LXC permissions to support Docker +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +# Set container description +pct set $CTID -description "Access Portainer interface using the following URL. + +http://:9000" + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID pve7_ha_setup.sh /pve7_ha_setup.sh -perms 755 +pct exec $CTID /pve7_ha_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Home Assistant Container LXC to $CTID." +msg " + +Home Assistant is reachable by going to the following URLs. + + http://${IP}:8123 +" \ No newline at end of file diff --git a/pve7_ha_setup.sh b/pve7_ha_setup.sh new file mode 100644 index 00000000..7a1d6a79 --- /dev/null +++ b/pve7_ha_setup.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl &>/dev/null + +# Customize Docker configuration +msg "Customizing Docker..." +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +# Install Docker +msg "Installing Docker..." +sh <(curl -sSL https://get.docker.com) &>/dev/null + +# Install Portainer +msg "Installing Portainer..." +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer &>/dev/null + +# Install Home Assistant +msg "Installing Home Assistant..." +docker volume create hass_config >/dev/null +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /pve7_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 67ded85ab0a1dc597b17df0f8ac2ae2605eded88 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:30:57 -0400 Subject: [PATCH 0037/6505] Create troubleshoot.md --- troubleshoot.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 troubleshoot.md diff --git a/troubleshoot.md b/troubleshoot.md new file mode 100644 index 00000000..67fee070 --- /dev/null +++ b/troubleshoot.md @@ -0,0 +1,11 @@ +If no device is found after running `ls -l /dev/serial/by-id` reboot the zigbee2mqtt lxc and try again. + +Make sure Proxmox sees the device by running `ls -l /dev/serial/by-id` from the Proxmox web shell. + +If Proxmox sees your device, you can try setting autodev by running the below script from the Proxmox web shell. +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 100 +``` +change 100 to your LXC ID. + +Note: The changes will apply after a reboot of the LXC. From 9d05ef27152d3d27825dcd38024a4fb6b8f13bf3 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:32:42 -0400 Subject: [PATCH 0038/6505] Update troubleshoot.md --- troubleshoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot.md b/troubleshoot.md index 67fee070..70d0c265 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -6,6 +6,6 @@ If Proxmox sees your device, you can try setting autodev by running the below sc ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 100 ``` -change 100 to your LXC ID. +:warning: change 100 to your LXC ID. Note: The changes will apply after a reboot of the LXC. From a8b3e11fece31f47edf43bfcfb96408dd652522c Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:33:07 -0400 Subject: [PATCH 0039/6505] Update troubleshoot.md --- troubleshoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot.md b/troubleshoot.md index 70d0c265..65247b16 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -6,6 +6,6 @@ If Proxmox sees your device, you can try setting autodev by running the below sc ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 100 ``` -:warning: change 100 to your LXC ID. +:warning: change `100` to your LXC ID. Note: The changes will apply after a reboot of the LXC. From 2a680c4b90550be46774ef7b33581f62f494d766 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:36:26 -0400 Subject: [PATCH 0040/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 621ea11c..e08d8da6 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -68,7 +68,6 @@ pushd $TEMP_DIR >/dev/null wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_setup.sh # Detect modules and automatically load at boot -load_module aufs load_module overlay # Select storage location @@ -175,4 +174,4 @@ msg " Home Assistant is reachable by going to the following URLs. http://${IP}:8123 -" \ No newline at end of file +" From 09fd90869b0943be3f0cc6ecc53d712e9956786f Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:39:08 -0400 Subject: [PATCH 0041/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index e08d8da6..5746f6d9 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -140,7 +140,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 4096 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Modify LXC permissions to support Docker From 1027f8eeb4a9bc0d2b9d5d831176f58a4e879660 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:43:30 -0400 Subject: [PATCH 0042/6505] Update README.md --- README.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 32076b68..7db079d0 100644 --- a/README.md +++ b/README.md @@ -30,11 +30,7 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ``` -## Defaults - -32GB storage and 512 MiB memory, - -go to Resources > Memory and edit your memory amount (4GB=4096) and cores (2) +

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

For Home Assistant interface http:// (LXC IP) :8123 @@ -61,11 +57,7 @@ To create a new Proxmox 7 Home Assistant Container, run the following from Proxm bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_container.sh)" ``` -## Defaults - -32GB storage and 512 MiB memory, - -go to Resources > Memory and edit your memory amount (4GB=4096) and cores (2) +

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

For Home Assistant interface http:// (LXC IP) :8123 From cc148522873702196f76ecffdc2c527275a92f1c Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:47:00 -0400 Subject: [PATCH 0043/6505] Update pve6_ha_container.sh --- pve6_ha_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve6_ha_container.sh b/pve6_ha_container.sh index e047a9af..78d7bb0e 100644 --- a/pve6_ha_container.sh +++ b/pve6_ha_container.sh @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 4096 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Modify LXC permissions to support Docker @@ -175,4 +175,4 @@ msg " Home Assistant is reachable by going to the following URLs. http://${IP}:8123 -" \ No newline at end of file +" From 582b35f9cd1432e58ff404d410dffe8860b2b3d1 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:49:21 -0400 Subject: [PATCH 0044/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7db079d0..9ef58707 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Select Proxmox Helper Below

+

Select a Proxmox Helper Below

From baf6ec4fecc9c373cb4c1c7bd4b107f98309d3b6 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:54:15 -0400 Subject: [PATCH 0045/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9ef58707..f18e5e32 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ```

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. For Home Assistant interface http:// (LXC IP) :8123 @@ -58,6 +59,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7 ```

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. For Home Assistant interface http:// (LXC IP) :8123 From fd7bb1edd2d9fb3ce852a7d5763d18bf1e8ccd22 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:55:48 -0400 Subject: [PATCH 0046/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f18e5e32..946f7e53 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ```

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+ After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. For Home Assistant interface http:// (LXC IP) :8123 @@ -59,6 +60,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7 ```

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+ After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. For Home Assistant interface http:// (LXC IP) :8123 From 315d0015545803a5845f90d1d0d59936adca7f5c Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 12:56:21 -0400 Subject: [PATCH 0047/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 946f7e53..fc050f83 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ To create a new Proxmox VM with the latest version of Home Assistant OS, run the bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" ``` ###

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+ After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. From f1fda1d709a12cd2dfe67e2a2b2919313f52e805 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:12:42 -0400 Subject: [PATCH 0048/6505] Update mqtt_container.sh --- mqtt_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_container.sh b/mqtt_container.sh index 76a840ef..4c917d70 100644 --- a/mqtt_container.sh +++ b/mqtt_container.sh @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=mqtt TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null From e80145e71bc92d5459ed1c833a8b8f6761a94257 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:15:25 -0400 Subject: [PATCH 0049/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fc050f83..f474a5ab 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_container.sh)" ``` +

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

### The commands below are entered through the newly created mqtt lxc console. Mosquitto comes with a password file generating utility called mosquitto_passwd. ``` From aec1a83ea1f152d059b6449ff3c1c88d6c42f8e5 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:15:56 -0400 Subject: [PATCH 0050/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f474a5ab..e289d889 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_container.sh)" ```

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+ ### The commands below are entered through the newly created mqtt lxc console. Mosquitto comes with a password file generating utility called mosquitto_passwd. ``` From 2d4a845f04d0aabb1502b73711572f8956c45d76 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:16:57 -0400 Subject: [PATCH 0051/6505] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index e289d889..bd180208 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt ```

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

-### The commands below are entered through the newly created mqtt lxc console. Mosquitto comes with a password file generating utility called mosquitto_passwd. ``` sudo mosquitto_passwd -c /etc/mosquitto/passwd From 8d6344a2ddc17dbac1b2d374417774d06bcdb56f Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:19:17 -0400 Subject: [PATCH 0052/6505] Update mariadb_container.sh --- mariadb_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index f6ccde3f..0f4fd46e 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -130,7 +130,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} # Create LXC msg "Creating LXC container..." -DISK_SIZE=2G +DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=mariadb TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null From 9b7627006a37401c978a5f7be22e139bd3e1e931 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:21:08 -0400 Subject: [PATCH 0053/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bd180208..c8d56722 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,8 @@ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_container.sh)" ``` +

:zap: Default Settings: 1GB RAM - 4GB Storage - 1vCPU :zap:

+ To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: ``` nano /etc/mysql/mariadb.conf.d/50-server.cnf From 7bdd6dfbb07396cb116dda148a147d12a9c05066 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:24:00 -0400 Subject: [PATCH 0054/6505] Update node-red_container.sh --- node-red_container.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/node-red_container.sh b/node-red_container.sh index fc71cb31..a89d5a28 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -68,7 +68,6 @@ pushd $TEMP_DIR >/dev/null wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_setup.sh # Detect modules and automatically load at boot -#load_module aufs load_module overlay # Select storage location @@ -130,7 +129,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} # Create LXC msg "Creating LXC container..." -DISK_SIZE=2G +DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." @@ -141,7 +140,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=nodered TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null From 963151fe557d0c89acb7984ddad272243e58a20b Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:25:19 -0400 Subject: [PATCH 0055/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c8d56722..ccf92d87 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_container.sh)" ``` - +

:zap: Default Settings: 1GB RAM - 4GB Storage - 1vCPU :zap:

From 3912faf5390cadda8ecf8710ede41a3846ae698a Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:55:09 -0400 Subject: [PATCH 0056/6505] Update pve6_zigbee2mqtt_container.sh --- pve6_zigbee2mqtt_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve6_zigbee2mqtt_container.sh b/pve6_zigbee2mqtt_container.sh index 950222f8..7feee544 100644 --- a/pve6_zigbee2mqtt_container.sh +++ b/pve6_zigbee2mqtt_container.sh @@ -129,7 +129,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} # Create LXC msg "Creating LXC container..." -DISK_SIZE=2G +DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." @@ -140,7 +140,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=zigbee2mqtt TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Modify LXC permissions to support Zigbee Sticks From 364fcffd598eff98c08d47c781d1837c195958af Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:55:53 -0400 Subject: [PATCH 0057/6505] Update pve7_zigbee2mqtt_container.sh --- pve7_zigbee2mqtt_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve7_zigbee2mqtt_container.sh b/pve7_zigbee2mqtt_container.sh index 8d6b1cac..9310deb7 100644 --- a/pve7_zigbee2mqtt_container.sh +++ b/pve7_zigbee2mqtt_container.sh @@ -129,7 +129,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} # Create LXC msg "Creating LXC container..." -DISK_SIZE=2G +DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." @@ -140,7 +140,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=zigbee2mqtt TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Modify LXC permissions to support Zigbee Sticks From 1c5fc347733aa6142a2d9097100b99c3fab9d71e Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 13:57:28 -0400 Subject: [PATCH 0058/6505] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccf92d87..3e13aa57 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,8 @@ To create a new Proxmox 6 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Contain ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_zigbee2mqtt_container.sh)" ``` - +

:zap: Default Settings: 1GB RAM - 4GB Storage - 2vCPU :zap:

+ Determine the location of your adapter (Run in the zigbee2mqtt console) ``` ls -l /dev/serial/by-id @@ -304,7 +305,8 @@ To create a new Proxmox 7 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Contain ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_zigbee2mqtt_container.sh)" ``` - +

:zap: Default Settings: 1GB RAM - 4GB Storage - 2vCPU :zap:

+ Determine the location of your adapter (Run in the zigbee2mqtt console) ``` ls -l /dev/serial/by-id From f1bdc0404c394af62aa5df2edf47bbde8ec8c823 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 15:36:21 -0400 Subject: [PATCH 0059/6505] Update README.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 3e13aa57..c9627221 100644 --- a/README.md +++ b/README.md @@ -345,3 +345,22 @@ sudo systemctl start zigbee2mqtt ``` + + + + +
+Base Debian 10 LXC + +

Proxmox Debian 10 LXC Container

+ +To create a new Proxmox Debian 10 LXC Container, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_container.sh)" +``` +

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. + +
From f4a813b36bc46237c3fdde404758e74d83bd207c Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 15:38:04 -0400 Subject: [PATCH 0060/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9627221..de20177d 100644 --- a/README.md +++ b/README.md @@ -354,7 +354,7 @@ sudo systemctl start zigbee2mqtt

Proxmox Debian 10 LXC Container

-To create a new Proxmox Debian 10 LXC Container, run the following in the Proxmox web shell. +To create a new Proxmox Debian 10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_container.sh)" From e5959270caab5edc88c691f531cb1c80e218ca6e Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 15:38:40 -0400 Subject: [PATCH 0061/6505] Add files via upload --- debian10_container.sh | 159 ++++++++++++++++++++++++++++++++++++++++++ debian10_setup.sh | 71 +++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 debian10_container.sh create mode 100644 debian10_setup.sh diff --git a/debian10_container.sh b/debian10_container.sh new file mode 100644 index 00000000..e03c34d3 --- /dev/null +++ b/debian10_container.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=lxc +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID setup.sh /setup.sh -perms 755 +pct exec $CTID /setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a LXC Container to $CTID at IP Address ${IP}" diff --git a/debian10_setup.sh b/debian10_setup.sh new file mode 100644 index 00000000..73a87c42 --- /dev/null +++ b/debian10_setup.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +# Customize Docker configuration +# msg "Customizing Docker..." +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /debian10_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 297f07f7ab23074c523b40832acdd4314b991039 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 15:40:27 -0400 Subject: [PATCH 0062/6505] Update debian10_container.sh --- debian10_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian10_container.sh b/debian10_container.sh index e03c34d3..647d51d6 100644 --- a/debian10_container.sh +++ b/debian10_container.sh @@ -137,7 +137,7 @@ else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi ARCH=$(dpkg --print-architecture) -HOSTNAME=lxc +HOSTNAME=debian10 TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ From 05179c66680f5145abad45e079f414f8e0c0c09d Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 15:42:05 -0400 Subject: [PATCH 0063/6505] Update debian10_container.sh --- debian10_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian10_container.sh b/debian10_container.sh index 647d51d6..8925c6c6 100644 --- a/debian10_container.sh +++ b/debian10_container.sh @@ -151,9 +151,9 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID setup.sh /setup.sh -perms 755 -pct exec $CTID /setup.sh +pct push $CTID debian10_setup.sh /debian10_setup.sh -perms 755 +pct exec $CTID /debian10_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a LXC Container to $CTID at IP Address ${IP}" +info "Successfully created a Debian 10 LXC Container to $CTID at IP Address ${IP}" From b994de625f1eb66d7f188fd61a959a3fcc700441 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 12 Aug 2021 21:12:08 -0400 Subject: [PATCH 0064/6505] Update troubleshoot.md --- troubleshoot.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/troubleshoot.md b/troubleshoot.md index 65247b16..d01ee624 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -8,4 +8,5 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/auto ``` :warning: change `100` to your LXC ID. -Note: The changes will apply after a reboot of the LXC. +Note: The changes will apply after a reboot of the LXC +________________________________________________________________________________________________________________________________________ From 2dad1bf755498465e61720fd275630988558fedf Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 13 Aug 2021 14:13:00 -0400 Subject: [PATCH 0065/6505] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index de20177d..00489209 100644 --- a/README.md +++ b/README.md @@ -343,6 +343,11 @@ Zigbee2mqtt can be started after completing the configuration by running ``` sudo systemctl start zigbee2mqtt ``` +To start Zigbee2MQTT automatically on boot + ``` + sudo systemctl enable zigbee2mqtt.service + ``` + From b2313dd57c4efb31e2c9cec7bcff7f441b6bb02b Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 13 Aug 2021 14:14:34 -0400 Subject: [PATCH 0066/6505] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 00489209..1c5eae77 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,10 @@ Zigbee2mqtt can be started after completing the configuration by running ``` sudo systemctl start zigbee2mqtt ``` +To start Zigbee2MQTT automatically on boot + ``` + sudo systemctl enable zigbee2mqtt.service + ``` From ded006b1841a54a9169a1969935e0762a109b2df Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 13 Aug 2021 14:42:02 -0400 Subject: [PATCH 0067/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c5eae77..4ce1947d 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ Checking status. ``` sudo systemctl status mariadb ``` -Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@192.168.100.lxc-ip:3306/homeassistant?charset=utf8mb4``` +Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@_lxc-ip_:3306/homeassistant?charset=utf8mb4``` From a61ffa64d014fa1a15f7e73d12249327d1a41a94 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 13 Aug 2021 14:44:10 -0400 Subject: [PATCH 0068/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ce1947d..0cb5bd1a 100644 --- a/README.md +++ b/README.md @@ -233,8 +233,8 @@ Checking status. ``` sudo systemctl status mariadb ``` -Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@_lxc-ip_:3306/homeassistant?charset=utf8mb4``` - +Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@lxc-ip:3306/homeassistant?charset=utf8mb4``` +Example: `mysql://admin:password@192.168.1.26:3306/homeassistant?charset=utf8mb4` From 2e94e9422946869bccf3f0c2f6104a6cb2103780 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 13 Aug 2021 14:45:26 -0400 Subject: [PATCH 0069/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0cb5bd1a..94194d66 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,7 @@ Checking status. sudo systemctl status mariadb ``` Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@lxc-ip:3306/homeassistant?charset=utf8mb4``` + Example: `mysql://admin:password@192.168.1.26:3306/homeassistant?charset=utf8mb4` From e06313cb2fec75c2a77d40e8800d21fea811cedc Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 13 Aug 2021 23:42:21 -0400 Subject: [PATCH 0070/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 94194d66..58ad9dd4 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ Checking status. ``` sudo systemctl status mariadb ``` -Change your recorder: db_url: in the HA configuration.yaml ```mysql://admin:password@lxc-ip:3306/homeassistant?charset=utf8mb4``` +Change the recorder: `db_url:` in your HA configuration.yaml ```mysql://admin:password@lxc-ip:3306/homeassistant?charset=utf8mb4``` Example: `mysql://admin:password@192.168.1.26:3306/homeassistant?charset=utf8mb4` From 27d0e3f955664e98ebe10de205e52f8f04038279 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 14 Aug 2021 16:03:46 -0400 Subject: [PATCH 0071/6505] Update haos_vm.sh --- haos_vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/haos_vm.sh b/haos_vm.sh index de7c9566..41befcae 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -113,7 +113,7 @@ if [[ $FILE == *.zip ]]; then echo -e "\e[1;33m Checking for unzip command... \e[0m" if ! command -v unzip &> /dev/null; then echo -e "\e[1;33m Installing Unzip... \e[0m" - apt-get update + apt update apt install unzip -y fi fi @@ -185,4 +185,4 @@ set +o errtrace qm set $VMID -serial0 socket >/dev/null ) -info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." \ No newline at end of file +info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." From 2eb625ca13cae5000217e4d098e945377936aa51 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 14 Aug 2021 18:04:29 -0400 Subject: [PATCH 0072/6505] Update haos_vm.sh --- haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haos_vm.sh b/haos_vm.sh index 41befcae..56e3fd95 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -113,7 +113,7 @@ if [[ $FILE == *.zip ]]; then echo -e "\e[1;33m Checking for unzip command... \e[0m" if ! command -v unzip &> /dev/null; then echo -e "\e[1;33m Installing Unzip... \e[0m" - apt update + apt-get update >/dev/null apt install unzip -y fi fi From 7be0dae84a1741bc671cc6db1ed060c5026f6332 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 14 Aug 2021 18:11:47 -0400 Subject: [PATCH 0073/6505] Update haos_vm.sh --- haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haos_vm.sh b/haos_vm.sh index 56e3fd95..7688e63f 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -113,7 +113,7 @@ if [[ $FILE == *.zip ]]; then echo -e "\e[1;33m Checking for unzip command... \e[0m" if ! command -v unzip &> /dev/null; then echo -e "\e[1;33m Installing Unzip... \e[0m" - apt-get update >/dev/null + apt update >/dev/null apt install unzip -y fi fi From ff31cab98d95611a6321c79f4a192e7d1e569e10 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 18:25:03 -0400 Subject: [PATCH 0074/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index b125c2a1..bdbc1edb 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,8 +32,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null -apt-get -qqy upgrade &>/dev/null +apt update >/dev/null +apt -qqy upgrade &>/dev/null # Install prerequisites msg "Installing Prerequisites..." @@ -87,4 +87,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /pve7_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /pve7_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 700f95f26d5bac6bbed8456a3f18c831278df468 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 18:29:11 -0400 Subject: [PATCH 0075/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index bdbc1edb..6850c3c8 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,8 +32,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt update >/dev/null -apt -qqy upgrade &>/dev/null +apt-get update >/dev/null +apt-get upgrade &>/dev/null # Install prerequisites msg "Installing Prerequisites..." From b59973da5f5b92e55ad756ae311341facfd61c6e Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 18:33:27 -0400 Subject: [PATCH 0076/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index 6850c3c8..4f94e8cd 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get upgrade &>/dev/null # Install prerequisites From 9ab653afdcfececd82842f18d2fd29f158bd627d Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 18:42:14 -0400 Subject: [PATCH 0077/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index 4f94e8cd..bcb492c8 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get --allow-releaseinfo-change update -y >/dev/null apt-get upgrade &>/dev/null # Install prerequisites From 5ffc330ad73cbb533dbad45c62ddeb9f17549204 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 18:44:32 -0400 Subject: [PATCH 0078/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index bcb492c8..38d62e60 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,8 +32,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get --allow-releaseinfo-change update -y >/dev/null -apt-get upgrade &>/dev/null +apt-get --allow-releaseinfo-change update >/dev/null +apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing Prerequisites..." From dd222aa211054b5c9b129013c75bb89615a7d30f Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 18:54:40 -0400 Subject: [PATCH 0079/6505] Update haos_vm.sh --- haos_vm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/haos_vm.sh b/haos_vm.sh index 7688e63f..dd9250ec 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -113,8 +113,8 @@ if [[ $FILE == *.zip ]]; then echo -e "\e[1;33m Checking for unzip command... \e[0m" if ! command -v unzip &> /dev/null; then echo -e "\e[1;33m Installing Unzip... \e[0m" - apt update >/dev/null - apt install unzip -y + apt-get --allow-releaseinfo-change update >/dev/null + apt-get -qqy install unzip &>/dev/null fi fi @@ -167,7 +167,7 @@ set +o errtrace ' ERR if [ "$(command -v kpartx)" = "" ]; then echo -e "\e[1;33m Installing kpartx... \e[0m" - apt-get update >/dev/null + apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy install kpartx &>/dev/null fi DISK1_PATH="$(pvesm path $DISK1_REF)" From 8c7f18855ba4599454dd03f815dc4752d10f3fe3 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:04:44 -0400 Subject: [PATCH 0080/6505] Update pve7_ha_setup.sh --- pve7_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve7_ha_setup.sh b/pve7_ha_setup.sh index 7a1d6a79..a68006d3 100644 --- a/pve7_ha_setup.sh +++ b/pve7_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -97,4 +97,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /pve7_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /pve7_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From f6c19027af2924cfe5b10cd11af3068134b51128 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:05:27 -0400 Subject: [PATCH 0081/6505] Update pve6_zigbee2mqtt_setup.sh --- pve6_zigbee2mqtt_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh index 86b46ed9..83c6fd38 100644 --- a/pve6_zigbee2mqtt_setup.sh +++ b/pve6_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -87,4 +87,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /pve6_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /pve6_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From ebd70c3673a5109ec8387279e5881d7ebe78645c Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:06:07 -0400 Subject: [PATCH 0082/6505] Update pve6_ha_setup.sh --- pve6_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh index 563831c9..0efe94f4 100644 --- a/pve6_ha_setup.sh +++ b/pve6_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -97,4 +97,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /pve6_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /pve6_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 4dd471b0b02af76ccd4a2f6e34917e64ad5c6392 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:06:51 -0400 Subject: [PATCH 0083/6505] Update node-red_setup.sh --- node-red_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index f4201e80..9e1cc6cc 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -74,4 +74,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 454910c7493010a4bdfde9347caef8e463189dbf Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:07:21 -0400 Subject: [PATCH 0084/6505] Update mqtt_setup.sh --- mqtt_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mqtt_setup.sh b/mqtt_setup.sh index d4a84d1c..ca33ea6f 100644 --- a/mqtt_setup.sh +++ b/mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -64,4 +64,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From a9ca062d37d5850c45e8eefa1a82851a1aae9f9e Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:08:54 -0400 Subject: [PATCH 0085/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index 4bfb0267..b415ceba 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -43,7 +43,7 @@ apt-get -qqy install \ # Installing MariaDB msg "Installing MariaDB..." -sudo apt-get update >/dev/null +sudo apt-get --allow-releaseinfo-change update >/dev/null sudo apt-get install -y mariadb-server &>/dev/null # Customize container @@ -63,4 +63,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From ba8ea3f32b082a7d7f8061ad05003137dd16813b Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:09:40 -0400 Subject: [PATCH 0086/6505] Update esphome_setup.sh --- esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index edfed5de..ad7b3cbf 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 52b58d29b77e587daadf9ef6f0e1098157b8e4d0 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:10:12 -0400 Subject: [PATCH 0087/6505] Update debian10_setup.sh --- debian10_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian10_setup.sh b/debian10_setup.sh index 73a87c42..2d1a035c 100644 --- a/debian10_setup.sh +++ b/debian10_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -68,4 +68,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /debian10_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /debian10_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From afe2ba37af78b3903308bc5fc67c59c481af5f4f Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:28:39 -0400 Subject: [PATCH 0088/6505] Update debian10_container.sh --- debian10_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian10_container.sh b/debian10_container.sh index 8925c6c6..b34136bf 100644 --- a/debian10_container.sh +++ b/debian10_container.sh @@ -106,7 +106,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 1becf560acfc41bbc2963dc914de1794ebdafae3 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 19:30:06 -0400 Subject: [PATCH 0089/6505] Update debian10_container.sh --- debian10_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian10_container.sh b/debian10_container.sh index b34136bf..8925c6c6 100644 --- a/debian10_container.sh +++ b/debian10_container.sh @@ -106,7 +106,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-11 +OSVERSION=${OSTYPE}-10 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 7c26d0472cbbb398484e0d3f391689a440355473 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 20:59:23 -0400 Subject: [PATCH 0090/6505] Update debian10_setup.sh --- debian10_setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian10_setup.sh b/debian10_setup.sh index 2d1a035c..db45d9c6 100644 --- a/debian10_setup.sh +++ b/debian10_setup.sh @@ -33,7 +33,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." apt-get --allow-releaseinfo-change update >/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get -qqy upgrade >/dev/null +apt-get -qqy dist-upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 4433636e33a99becc93407c23adfcf8fd3a38000 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 16 Aug 2021 21:19:09 -0400 Subject: [PATCH 0091/6505] Update debian10_setup.sh --- debian10_setup.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/debian10_setup.sh b/debian10_setup.sh index db45d9c6..2d1a035c 100644 --- a/debian10_setup.sh +++ b/debian10_setup.sh @@ -33,8 +33,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." apt-get --allow-releaseinfo-change update >/dev/null -apt-get -qqy upgrade >/dev/null -apt-get -qqy dist-upgrade &>/dev/null +apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 0200bb8dc617259267c5f1033f4e337c697e1c3e Mon Sep 17 00:00:00 2001 From: tteck Date: Wed, 18 Aug 2021 10:30:40 -0400 Subject: [PATCH 0092/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 58ad9dd4..9d121373 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox we bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_container.sh)" ``` +

:zap: Default Settings: 1GB RAM - 4GB Storage - 2vCPU :zap:

From d769c1b774992cee17837f3ffbc91659e0f6f049 Mon Sep 17 00:00:00 2001 From: tteck Date: Wed, 18 Aug 2021 10:32:56 -0400 Subject: [PATCH 0093/6505] Update esphome_container.sh --- esphome_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_container.sh b/esphome_container.sh index b00ee2de..ad725cba 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -140,7 +140,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=esphome TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Set container timezone to match host From 3aeeb99d9d29da63937ca9e88d9fe52143beb610 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 04:26:19 -0400 Subject: [PATCH 0094/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index 38d62e60..805e652e 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -52,7 +52,7 @@ apt-get -qqy install \ # Install zigbee2mqtt msg "Installing Zigbee2MQTT..." cd /opt/zigbee2mqtt &>/dev/null - npm ci --production &>/dev/null + npm ci &>/dev/null echo "Creating service file zigbee2mqtt.service" service_path="/etc/systemd/system/zigbee2mqtt.service" From 598d38f1f0417e257bdf241e402da482acba3cb8 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 04:27:35 -0400 Subject: [PATCH 0095/6505] Update pve6_zigbee2mqtt_setup.sh --- pve6_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh index 83c6fd38..78fc52ca 100644 --- a/pve6_zigbee2mqtt_setup.sh +++ b/pve6_zigbee2mqtt_setup.sh @@ -52,7 +52,7 @@ apt-get -qqy install \ # Install zigbee2mqtt msg "Installing Zigbee2MQTT..." cd /opt/zigbee2mqtt &>/dev/null - npm ci --production &>/dev/null + npm ci &>/dev/null echo "Creating service file zigbee2mqtt.service" service_path="/etc/systemd/system/zigbee2mqtt.service" From aadd4e230e3a0df240e6858895b70388e64780d6 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 08:17:42 -0400 Subject: [PATCH 0096/6505] Update debian10_container.sh --- debian10_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian10_container.sh b/debian10_container.sh index 8925c6c6..b34136bf 100644 --- a/debian10_container.sh +++ b/debian10_container.sh @@ -106,7 +106,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From ea75448b90e7641818cc8ef700b77aa6119d6182 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 08:24:59 -0400 Subject: [PATCH 0097/6505] Update debian10_container.sh --- debian10_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian10_container.sh b/debian10_container.sh index b34136bf..8925c6c6 100644 --- a/debian10_container.sh +++ b/debian10_container.sh @@ -106,7 +106,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-11 +OSVERSION=${OSTYPE}-10 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 6ccc12335355832d9199ca01b5ef4ff9ad114c94 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 08:35:42 -0400 Subject: [PATCH 0098/6505] Add files via upload --- debian11_container.sh | 159 ++++++++++++++++++++++++++++++++++++++++++ debian11_setup.sh | 71 +++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 debian11_container.sh create mode 100644 debian11_setup.sh diff --git a/debian11_container.sh b/debian11_container.sh new file mode 100644 index 00000000..01d47601 --- /dev/null +++ b/debian11_container.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/debian11_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=debian11 +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID debian11_setup.sh /debian11_setup.sh -perms 755 +pct exec $CTID /debian11_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Debian 11 LXC Container to $CTID at IP Address ${IP}" \ No newline at end of file diff --git a/debian11_setup.sh b/debian11_setup.sh new file mode 100644 index 00000000..f9b3b92f --- /dev/null +++ b/debian11_setup.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get --allow-releaseinfo-change update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +# Customize Docker configuration +# msg "Customizing Docker..." +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 07d310f039a4e59c80d2620492486901062d9d10 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 08:37:01 -0400 Subject: [PATCH 0099/6505] Update README.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 9d121373..b9a6f110 100644 --- a/README.md +++ b/README.md @@ -375,3 +375,22 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debi After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. + + + + +
+Base Debian 11 LXC + +

Proxmox Debian 11 LXC Container

+ +To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian11_container.sh)" +``` +

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. + +
From bba1370d918513b0136d5fc3576fa21b977d4e69 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 10:21:29 -0400 Subject: [PATCH 0100/6505] Update esphome_container.sh --- esphome_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome_container.sh b/esphome_container.sh index ad725cba..72be2a5c 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -101,12 +101,12 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 159c4f09eafcd8cb955e124fd1852b4a456b3080 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 10:22:55 -0400 Subject: [PATCH 0101/6505] Update esphome_setup.sh --- esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index ad7b3cbf..edfed5de 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 541e9fb60a5deab20b9a5d68193b0978eb8988e4 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 10:40:57 -0400 Subject: [PATCH 0102/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index f9b3b92f..bb5d6bd5 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 53c30657d0ebaef2527acece8902bcd7e23a683a Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 11:23:14 -0400 Subject: [PATCH 0103/6505] Update pve7_ha_setup.sh --- pve7_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve7_ha_setup.sh b/pve7_ha_setup.sh index a68006d3..eb78d8b4 100644 --- a/pve7_ha_setup.sh +++ b/pve7_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -64,7 +64,7 @@ docker run -d \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ - portainer/portainer &>/dev/null + portainer/portainer-ce:latest &>/dev/null # Install Home Assistant msg "Installing Home Assistant..." From b9c2566e15ae40b06469088fd47e3c8a3287c71f Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 11:24:19 -0400 Subject: [PATCH 0104/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 5746f6d9..3d97ed4f 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -106,7 +106,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 4c0aea921459eee93411ec642c76f064860ee768 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 11:25:36 -0400 Subject: [PATCH 0105/6505] Update pve6_ha_setup.sh --- pve6_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh index 0efe94f4..37eaa2bd 100644 --- a/pve6_ha_setup.sh +++ b/pve6_ha_setup.sh @@ -64,7 +64,7 @@ docker run -d \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ - portainer/portainer &>/dev/null + portainer/portainer-ce:latest &>/dev/null # Install Home Assistant msg "Installing Home Assistant..." From a05a2295db6d93a2c86da93fcdd500472870d3d7 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:25:35 -0400 Subject: [PATCH 0106/6505] Update pve6_ha_setup.sh --- pve6_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh index 37eaa2bd..4059cf8c 100644 --- a/pve6_ha_setup.sh +++ b/pve6_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 31b0c5e2da79e04343a9655539aa19db30ca85f2 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:26:26 -0400 Subject: [PATCH 0107/6505] Update pve6_ha_container.sh --- pve6_ha_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve6_ha_container.sh b/pve6_ha_container.sh index 78d7bb0e..38d2ce60 100644 --- a/pve6_ha_container.sh +++ b/pve6_ha_container.sh @@ -102,12 +102,12 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 654eacffd41e717df13215b416b88b6e065e574a Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:28:07 -0400 Subject: [PATCH 0108/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index 805e652e..ca7264bd 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From a22e20018a21dbd15fe6d046642d16647eb84904 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:28:49 -0400 Subject: [PATCH 0109/6505] Update pve7_zigbee2mqtt_container.sh --- pve7_zigbee2mqtt_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve7_zigbee2mqtt_container.sh b/pve7_zigbee2mqtt_container.sh index 9310deb7..224b8aed 100644 --- a/pve7_zigbee2mqtt_container.sh +++ b/pve7_zigbee2mqtt_container.sh @@ -101,12 +101,12 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 2f4eeb6c05274b6e2b6c43e0e34994f32ee7e778 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:29:32 -0400 Subject: [PATCH 0110/6505] Update pve6_zigbee2mqtt_setup.sh --- pve6_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh index 78fc52ca..12695147 100644 --- a/pve6_zigbee2mqtt_setup.sh +++ b/pve6_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From f217c92733d919569c005691cb3e2313bd18768a Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:30:07 -0400 Subject: [PATCH 0111/6505] Update pve6_zigbee2mqtt_container.sh --- pve6_zigbee2mqtt_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve6_zigbee2mqtt_container.sh b/pve6_zigbee2mqtt_container.sh index 7feee544..23af1ac6 100644 --- a/pve6_zigbee2mqtt_container.sh +++ b/pve6_zigbee2mqtt_container.sh @@ -101,12 +101,12 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 8bcba14589cd35c3eef2e890ca9eef4f1e4f5ad4 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:30:50 -0400 Subject: [PATCH 0112/6505] Update node-red_setup.sh --- node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index 9e1cc6cc..fec60e5d 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 2d7a865d0221877d78e03f6ce6ea2a0fd2797c7f Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:31:20 -0400 Subject: [PATCH 0113/6505] Update node-red_container.sh --- node-red_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node-red_container.sh b/node-red_container.sh index a89d5a28..5c614f4a 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -101,12 +101,12 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 134af7c8270abd162c2c7c1e4abc29da2efeefdd Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:31:53 -0400 Subject: [PATCH 0114/6505] Update mqtt_setup.sh --- mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_setup.sh b/mqtt_setup.sh index ca33ea6f..f62a89b9 100644 --- a/mqtt_setup.sh +++ b/mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 6dd708aad4c768a8edea5a6a389d786eb4b72777 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:32:20 -0400 Subject: [PATCH 0115/6505] Update mqtt_container.sh --- mqtt_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mqtt_container.sh b/mqtt_container.sh index 4c917d70..b42668be 100644 --- a/mqtt_container.sh +++ b/mqtt_container.sh @@ -102,12 +102,12 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 5b2ddcc119d5794cfcb2036699603449bfd234ff Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:32:54 -0400 Subject: [PATCH 0116/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index b415ceba..c1814f51 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 4c55841559c9b3f414e4381822dda855b9dae6b1 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 13:33:33 -0400 Subject: [PATCH 0117/6505] Update mariadb_container.sh --- mariadb_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index 0f4fd46e..c3091fe5 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -102,12 +102,12 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From e9ce4e1937da4da5873365a088541c5b30a0b0e5 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 19:31:50 -0400 Subject: [PATCH 0118/6505] Add files via upload --- update_ha.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 update_ha.md diff --git a/update_ha.md b/update_ha.md new file mode 100644 index 00000000..187acdde --- /dev/null +++ b/update_ha.md @@ -0,0 +1,58 @@ +In the homeassistant lxc console run `nano upha.sh` +it will open a new file, copy and paste the Stable Branch +Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X" +To update HA go to the root prompt and run `bash upha.sh` + +Stable Branch +``` +### upha.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Stable Version... \e[0m" +docker pull homeassistant/home-assistant:stable +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:stable +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` + +Beta Branch +``` +### uphabeta.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Beta Version... \e[0m" +docker pull homeassistant/home-assistant:beta +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:beta +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` + +Development Branch +``` +### uphadev.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Dev Version... \e[0m" +docker pull homeassistant/home-assistant:dev +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:dev +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` From 4475347940089e5f8498d4dfe02abdce81b474a4 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 19:33:52 -0400 Subject: [PATCH 0119/6505] Update update_ha.md --- update_ha.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/update_ha.md b/update_ha.md index 187acdde..5df15ec0 100644 --- a/update_ha.md +++ b/update_ha.md @@ -1,5 +1,7 @@ +## Home Assistant Container Update ## + In the homeassistant lxc console run `nano upha.sh` -it will open a new file, copy and paste the Stable Branch +it will open a new file, copy and paste the Stable Branch. Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X" To update HA go to the root prompt and run `bash upha.sh` From 383e000932f901a41d57c2c46a7ad2d01b2633bb Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 19 Aug 2021 19:36:21 -0400 Subject: [PATCH 0120/6505] Update troubleshoot.md --- troubleshoot.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/troubleshoot.md b/troubleshoot.md index d01ee624..802f9e4f 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -1,3 +1,5 @@ +## Zigbee2MQTT Device Troubleshooting ## + If no device is found after running `ls -l /dev/serial/by-id` reboot the zigbee2mqtt lxc and try again. Make sure Proxmox sees the device by running `ls -l /dev/serial/by-id` from the Proxmox web shell. From ccb2583be53917031243f980f5e2dc0a963f43ff Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 20 Aug 2021 08:28:24 -0400 Subject: [PATCH 0121/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 3d97ed4f..8c5963e1 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -129,7 +129,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} # Create LXC msg "Creating LXC container..." -DISK_SIZE=32G +DISK_SIZE=16G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." From 2e72aa32811b0ad4331c31301ebba3ba26c81552 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 20 Aug 2021 08:29:05 -0400 Subject: [PATCH 0122/6505] Update pve6_ha_container.sh --- pve6_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_ha_container.sh b/pve6_ha_container.sh index 38d2ce60..ca2f6f87 100644 --- a/pve6_ha_container.sh +++ b/pve6_ha_container.sh @@ -130,7 +130,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} # Create LXC msg "Creating LXC container..." -DISK_SIZE=32G +DISK_SIZE=16G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." From af51106ec25e6819dee1f7bdcc0c371c17881995 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 20 Aug 2021 08:30:12 -0400 Subject: [PATCH 0123/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b9a6f110..569936f8 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ``` -

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+

:zap: Default Settings: 4GB RAM - 16GB Storage - 2vCPU :zap:

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. @@ -60,7 +60,7 @@ To create a new Proxmox 7 Home Assistant Container, run the following from Proxm bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_container.sh)" ``` -

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+

:zap: Default Settings: 4GB RAM - 16GB Storage - 2vCPU :zap:

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. From 7b91a70145f34d52b49ca1d119142d8f275bb564 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 20 Aug 2021 16:26:30 -0400 Subject: [PATCH 0124/6505] Update update_ha.md --- update_ha.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/update_ha.md b/update_ha.md index 5df15ec0..8ed2ce26 100644 --- a/update_ha.md +++ b/update_ha.md @@ -1,9 +1,9 @@ ## Home Assistant Container Update ## In the homeassistant lxc console run `nano upha.sh` -it will open a new file, copy and paste the Stable Branch. +it will open a new file, copy and paste the Stable Branch (change TZ) Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X" -To update HA go to the root prompt and run `bash upha.sh` +To update HA, run `bash upha.sh` from the console Stable Branch ``` From 5d15ea6a5777893bf61836800a74c8b58dbc807f Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 20 Aug 2021 20:56:59 -0400 Subject: [PATCH 0125/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 569936f8..7beeb7c9 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ``` +

Debian 11

:zap: Default Settings: 4GB RAM - 16GB Storage - 2vCPU :zap:

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. From 092bc1397316c57b2725c971bf5cf1c1bff72c96 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 20 Aug 2021 20:57:52 -0400 Subject: [PATCH 0126/6505] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 7beeb7c9..569936f8 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ``` -

Debian 11

:zap: Default Settings: 4GB RAM - 16GB Storage - 2vCPU :zap:

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. From 05d160c587e1e900f71a73dbb3bf81b1a2490615 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 08:37:19 -0400 Subject: [PATCH 0127/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 569936f8..1df8954e 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,8 @@ This will open an empty file. Paste the following into it. ``` allow_anonymous false password_file /etc/mosquitto/passwd +listener 1883 +# ... ``` Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X". From c025007c403f7a9669af1adc6ed7fa73ef445dbc Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 09:22:49 -0400 Subject: [PATCH 0128/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1df8954e..65de2e43 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ sudo nano /etc/mosquitto/conf.d/default.conf This will open an empty file. Paste the following into it. ``` allow_anonymous false +persistence true password_file /etc/mosquitto/passwd listener 1883 # ... From fdcb783276429051194fd0967abb3fedf5932ee6 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 09:46:36 -0400 Subject: [PATCH 0129/6505] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 65de2e43..9615154e 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,6 @@ allow_anonymous false persistence true password_file /etc/mosquitto/passwd listener 1883 -# ... ``` Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X". From ee8f1ee0276efb82cc2ed48587aae59156d0a1e9 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 12:51:03 -0400 Subject: [PATCH 0130/6505] Update mariadb_container.sh --- mariadb_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index c3091fe5..5a165de0 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -107,7 +107,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-11 +OSVERSION=${OSTYPE}-10 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 9fc95c248c37aa2b3a89c8c14468e5f7b9b803ed Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 13:00:38 -0400 Subject: [PATCH 0131/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index c1814f51..b415ceba 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 12f8924ba3c160f34a499c691e2303913fc0ab84 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 13:44:20 -0400 Subject: [PATCH 0132/6505] Update mariadb_container.sh --- mariadb_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index 5a165de0..c3091fe5 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -107,7 +107,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 2ef90113a949b232ffdd09890987680c2f5a4027 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 13:45:31 -0400 Subject: [PATCH 0133/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9615154e..6f04c7f9 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node
Mariadb LXC -

Proxmox Mariadb LXC Container

+

Proxmox Mariadb LXC Container Under Construction

To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. From c0e05113e387b6787425a6839c4aae0bb0cd4d00 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 15:23:38 -0400 Subject: [PATCH 0134/6505] Update mariadb_container.sh --- mariadb_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index c3091fe5..5a165de0 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -107,7 +107,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-11 +OSVERSION=${OSTYPE}-10 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 41353b63967fe21e72918ab1afb054927dfb9413 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 16:15:06 -0400 Subject: [PATCH 0135/6505] Update mariadb_container.sh --- mariadb_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index 5a165de0..c3091fe5 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -107,7 +107,7 @@ msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." OSTYPE=debian -OSVERSION=${OSTYPE}-10 +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 39d5d288650fefda33ff10593e4ae5c026bf5a98 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 16:16:03 -0400 Subject: [PATCH 0136/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index b415ceba..4e1091a0 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites @@ -43,7 +43,7 @@ apt-get -qqy install \ # Installing MariaDB msg "Installing MariaDB..." -sudo apt-get --allow-releaseinfo-change update >/dev/null +sudo apt-get update >/dev/null sudo apt-get install -y mariadb-server &>/dev/null # Customize container From 44f26a40bf8e9d9f4ae0dc9ca4e9021b0bbb628e Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 20:30:27 -0400 Subject: [PATCH 0137/6505] Update README.md --- README.md | 63 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 6f04c7f9..5cea192b 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node
Mariadb LXC -

Proxmox Mariadb LXC Container Under Construction

+

Proxmox Mariadb 10.5 LXC Container

To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. @@ -170,24 +170,17 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mari

:zap: Default Settings: 1GB RAM - 4GB Storage - 1vCPU :zap:

To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: +``` +nano /etc/mysql/my.cnf +``` +Un-comment `port =3306` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". + ``` nano /etc/mysql/mariadb.conf.d/50-server.cnf ``` -Un-comment port, and comment skip-networking and bind-address. (match below) -```user = mysql -pid-file = /run/mysqld/mysqld.pid -socket = /run/mysqld/mysqld.sock -port = 3306 -basedir = /usr -datadir = /var/lib/mysql -tmpdir = /tmp -lc-messages-dir = /usr/share/mysql -# skip-external-locking -# skip-networking -# Instead of skip-networking the default is now to listen only on -# localhost which is more compatible and is not less secure. -# bind-address = 127.0.0.1 -``` +Comment `bind-address = 127.0.0.1` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". For new MariaDB installations, the next step is to run the included security script. This script changes some of the less secure default options. We will use it to block remote root logins and to remove unused database users. @@ -195,26 +188,32 @@ Run the security script: ``` sudo mysql_secure_installation ``` -This will take you through a series of prompts where you can make some changes to your MariaDB installation’s security options. The first prompt will ask you to enter the current database root password. Since we have not set one up yet, press ENTER to indicate “none”. +Enter current password for root (enter for none): enter +Switch to unix_socket authentication [Y/n] y +Change the root password? [Y/n] n +Remove anonymous users? [Y/n] y +Disallow root login remotely? [Y/n] y +Remove test database and access to it? [Y/n] y +Reload privilege tables now? [Y/n] y -The next prompt asks you whether you’d like to set up a database root password. Type N and then press ENTER. In Debian, the root account for MariaDB is tied closely to automated system maintenance, so we should not change the configured authentication methods for that account. Doing so would make it possible for a package update to break the database system by removing access to the administrative account. Later, we will cover how to optionally set up an additional administrative account for password access if socket authentication is not appropriate for your use case. - -From there, you can press Y and then ENTER to accept the defaults for all the subsequent questions. This will remove some anonymous users and the test database, disable remote root logins, and load these new rules so that MariaDB immediately respects the changes you have made. - - -The root MariaDB user is set to authenticate using the unix_socket plugin by default rather than with a password. This allows for some greater security and usability in many cases, but it can also complicate things when you need to allow an external program (e.g., phpMyAdmin) administrative rights. - -Because the server uses the root account for tasks like log rotation and starting and stopping the server, it is best not to change the root account’s authentication details. Changing credentials in the /etc/mysql/debian.cnf configuration file may work initially, but package updates could potentially overwrite those changes. Instead of modifying the root account, the package maintainers recommend creating a separate administrative account for password-based access. - -To do so, we will create a new account called admin with the same capabilities as the root account, but configured for password authentication. +We will create a new account called admin with the same capabilities as the root account, but configured for password authentication. ``` sudo mysql ``` Prompt will change to ```MariaDB [(none)]>``` -Now, we will create the user admin with root privileges and password-based access that can connect from anywhere on my local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: +Now, we'll create a new local admin ``` -GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; +CREATE USER 'admin'@'localhost' IDENTIFIED BY 'twt'; +``` +Give local admin root privileges +``` +GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'twt' WITH GRANT OPTION; +``` + +Now, we'll create the user admin with root privileges and password-based access that can connect from anywhere on my local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: +``` +GRANT ALL ON *.* TO 'admin'@'192.168.86.%' IDENTIFIED BY 'twt' WITH GRANT OPTION; ``` Flush the privileges to ensure that they are saved and available in the current session: ``` @@ -232,6 +231,12 @@ Create a new database: ``` CREATE DATABASE homeassistant; ``` +Following this, exit the MariaDB shell: +``` +exit +``` +:warning: Reboot the lxc + Checking status. ``` sudo systemctl status mariadb From a1eb3add8ce7d30d392f424fee2f5f7489391ddc Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 20:32:22 -0400 Subject: [PATCH 0138/6505] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5cea192b..ecb45e4d 100644 --- a/README.md +++ b/README.md @@ -189,11 +189,17 @@ Run the security script: sudo mysql_secure_installation ``` Enter current password for root (enter for none): enter + Switch to unix_socket authentication [Y/n] y + Change the root password? [Y/n] n + Remove anonymous users? [Y/n] y + Disallow root login remotely? [Y/n] y + Remove test database and access to it? [Y/n] y + Reload privilege tables now? [Y/n] y We will create a new account called admin with the same capabilities as the root account, but configured for password authentication. From 605d39b4a0758b3476dda772a8ac60d99b21dca6 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 20:37:57 -0400 Subject: [PATCH 0139/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ecb45e4d..e8788c61 100644 --- a/README.md +++ b/README.md @@ -208,18 +208,18 @@ sudo mysql ``` Prompt will change to ```MariaDB [(none)]>``` -Now, we'll create a new local admin +Create a new local admin ``` -CREATE USER 'admin'@'localhost' IDENTIFIED BY 'twt'; +CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password'; ``` Give local admin root privileges ``` -GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'twt' WITH GRANT OPTION; +GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` -Now, we'll create the user admin with root privileges and password-based access that can connect from anywhere on my local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: +Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on my local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: ``` -GRANT ALL ON *.* TO 'admin'@'192.168.86.%' IDENTIFIED BY 'twt' WITH GRANT OPTION; +GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` Flush the privileges to ensure that they are saved and available in the current session: ``` From 17cbbac19dab4da964109412ce5498cd5cc031ac Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 20:42:54 -0400 Subject: [PATCH 0140/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8788c61..9817c976 100644 --- a/README.md +++ b/README.md @@ -208,11 +208,11 @@ sudo mysql ``` Prompt will change to ```MariaDB [(none)]>``` -Create a new local admin +Create a new local admin (Change the username and password to match your preferences) ``` CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password'; ``` -Give local admin root privileges +Give local admin root privileges (Change the username and password to match from above) ``` GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` From 13c9d80e107a726f9f1b07b99ce2d6c9ff6fea15 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 20:48:04 -0400 Subject: [PATCH 0141/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9817c976..ce643fc3 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node
-Mariadb LXC +Mariadb 10.5 LXC

Proxmox Mariadb 10.5 LXC Container

From 6aebe677ced72a003133a4a26fb4c2fd79b09c17 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 21:07:15 -0400 Subject: [PATCH 0142/6505] Update mariadb_container.sh --- mariadb_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index c3091fe5..461ae3df 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -158,4 +158,4 @@ pct exec $CTID /mariadb_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a MariaDB LXC Container to $CTID at IP Address ${IP}" +info "Successfully created a MariaDB 10.5 LXC Container to $CTID at IP Address ${IP}" From a1a4dd1969bc9858be03d51966428cbfcc49fb30 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 21:13:59 -0400 Subject: [PATCH 0143/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce643fc3..754c3d02 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ Create a new local admin (Change the username and password to match your prefere ``` CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password'; ``` -Give local admin root privileges (Change the username and password to match from above) +Give local admin root privileges (Change the username and password to match above) ``` GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` From b4061d3365a2039a9c958a6b293f83be3225af95 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:38:53 -0400 Subject: [PATCH 0144/6505] Add files via upload --- node-red2_setup.sh | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 node-red2_setup.sh diff --git a/node-red2_setup.sh b/node-red2_setup.sh new file mode 100644 index 00000000..0df64f66 --- /dev/null +++ b/node-red2_setup.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing NVM..." +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash &>/dev/null + +msg "Installing Node.js 16.7..." +nvm install v16.7.0 &>/dev/null + +msg "Installing PM2..." +npm install -g pm2 &>/dev/null + +# Install Node Red +msg "Installing Node-RED..." +npm install -g --unsafe-perm node-red &>/dev/null + +# Set up PM2 to manage startup of Node Red +msg "Setting up PM2..." +/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null +/usr/local/bin/pm2 save &>/dev/null +/usr/local/bin/pm2 startup &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 8b7a1fa25e1de762e89419b108897e63d305c6be Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:39:28 -0400 Subject: [PATCH 0145/6505] Update node-red_container.sh --- node-red_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_container.sh b/node-red_container.sh index 5c614f4a..4c31523a 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red2_setup.sh # Detect modules and automatically load at boot load_module overlay From fb7c5ba6ccfa32b9bf36ceeb653ab181e3abac61 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:42:49 -0400 Subject: [PATCH 0146/6505] Update node-red_container.sh --- node-red_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node-red_container.sh b/node-red_container.sh index 4c31523a..6e41d4dd 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -152,8 +152,8 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 -pct exec $CTID /node-red_setup.sh +pct push $CTID node-red2_setup.sh /node-red2_setup.sh -perms 755 +pct exec $CTID /node-red2_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From a4e2b7d1e9bb56d7696a860ce85c00de4c72bfce Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:43:23 -0400 Subject: [PATCH 0147/6505] Update node-red_setup.sh --- node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index fec60e5d..b70b4ac7 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -74,4 +74,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /node-red2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 3145024d310e7fdad9b656d345b92fdc30dbb768 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:47:23 -0400 Subject: [PATCH 0148/6505] Update node-red_container.sh --- node-red_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/node-red_container.sh b/node-red_container.sh index 6e41d4dd..5c614f4a 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red2_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_setup.sh # Detect modules and automatically load at boot load_module overlay @@ -152,8 +152,8 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID node-red2_setup.sh /node-red2_setup.sh -perms 755 -pct exec $CTID /node-red2_setup.sh +pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 +pct exec $CTID /node-red_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 16e384b8e242fe66ce716c16c0ce1d050d1e5937 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:48:06 -0400 Subject: [PATCH 0149/6505] Update node-red_setup.sh --- node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index b70b4ac7..fec60e5d 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -74,4 +74,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /node-red2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 630bc5f4f218614ac912f681ce8aad85432a0df2 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:49:04 -0400 Subject: [PATCH 0150/6505] Update node-red2_setup.sh --- node-red2_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red2_setup.sh b/node-red2_setup.sh index 0df64f66..e739bdf7 100644 --- a/node-red2_setup.sh +++ b/node-red2_setup.sh @@ -77,4 +77,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /node-red2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 39c2882807749e4cac5fbb5c513563d9d94b1a60 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:49:47 -0400 Subject: [PATCH 0151/6505] Update node-red_container.sh --- node-red_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/node-red_container.sh b/node-red_container.sh index 5c614f4a..6e41d4dd 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red2_setup.sh # Detect modules and automatically load at boot load_module overlay @@ -152,8 +152,8 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 -pct exec $CTID /node-red_setup.sh +pct push $CTID node-red2_setup.sh /node-red2_setup.sh -perms 755 +pct exec $CTID /node-red2_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 9e766be0acf6bec518d01f621d01f4163b6c5d9e Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 21 Aug 2021 22:53:38 -0400 Subject: [PATCH 0152/6505] Update node-red_container.sh --- node-red_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/node-red_container.sh b/node-red_container.sh index 6e41d4dd..5c614f4a 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -65,7 +65,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red2_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_setup.sh # Detect modules and automatically load at boot load_module overlay @@ -152,8 +152,8 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID node-red2_setup.sh /node-red2_setup.sh -perms 755 -pct exec $CTID /node-red2_setup.sh +pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 +pct exec $CTID /node-red_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 7f9aaf7de98cb3e7961d0bc582b5fbab654bda71 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 03:30:11 -0400 Subject: [PATCH 0153/6505] Delete node-red2_setup.sh --- node-red2_setup.sh | 80 ---------------------------------------------- 1 file changed, 80 deletions(-) delete mode 100644 node-red2_setup.sh diff --git a/node-red2_setup.sh b/node-red2_setup.sh deleted file mode 100644 index e739bdf7..00000000 --- a/node-red2_setup.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt-get update >/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -msg "Installing NVM..." -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash &>/dev/null - -msg "Installing Node.js 16.7..." -nvm install v16.7.0 &>/dev/null - -msg "Installing PM2..." -npm install -g pm2 &>/dev/null - -# Install Node Red -msg "Installing Node-RED..." -npm install -g --unsafe-perm node-red &>/dev/null - -# Set up PM2 to manage startup of Node Red -msg "Setting up PM2..." -/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null -/usr/local/bin/pm2 save &>/dev/null -/usr/local/bin/pm2 startup &>/dev/null - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /node-red2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c4e04ba788372106208c1d6f885a1f00efe17a07 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 05:54:33 -0400 Subject: [PATCH 0154/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 754c3d02..0c0b8841 100644 --- a/README.md +++ b/README.md @@ -247,7 +247,7 @@ Checking status. ``` sudo systemctl status mariadb ``` -Change the recorder: `db_url:` in your HA configuration.yaml ```mysql://admin:password@lxc-ip:3306/homeassistant?charset=utf8mb4``` +Change the recorder: `db_url:` in your HA configuration.yaml Example: `mysql://admin:password@192.168.1.26:3306/homeassistant?charset=utf8mb4` From 6ba1f5a34b51b303d0231592b62e5718bb70d610 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 05:55:40 -0400 Subject: [PATCH 0155/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c0b8841..c450ae44 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ sudo systemctl status mariadb ``` Change the recorder: `db_url:` in your HA configuration.yaml -Example: `mysql://admin:password@192.168.1.26:3306/homeassistant?charset=utf8mb4` +Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4`
From ee4e68a494a3ca9092c5fd0b5f3c31135222cc32 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:14:12 -0400 Subject: [PATCH 0156/6505] Update troubleshoot.md --- troubleshoot.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/troubleshoot.md b/troubleshoot.md index 802f9e4f..783f795a 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -1,14 +1,24 @@ ## Zigbee2MQTT Device Troubleshooting ## -If no device is found after running `ls -l /dev/serial/by-id` reboot the zigbee2mqtt lxc and try again. -Make sure Proxmox sees the device by running `ls -l /dev/serial/by-id` from the Proxmox web shell. - -If Proxmox sees your device, you can try setting autodev by running the below script from the Proxmox web shell. +If all else fails, try this: +In the Proxmox web shell run (replace `105` with your lxc Id) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 100 +nano /etc/pve/lxc/105.conf ``` -:warning: change `100` to your LXC ID. - -Note: The changes will apply after a reboot of the LXC +replace the last 4 lines +``` +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +``` +with these 4 lines +``` +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.autodev: 1 +lxc.hook.autodev: bash -c 'for char_dev in $(find /sys/dev/char -regextype sed -regex ".*/1:1" -o -regex ".*/4:\([3-9]\|[1-5][0-9]\|6[0-3]\)" -o -regex ".*/4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)" -o -regex ".*/10:200" -o -regex ".*/116:.*" -o -regex ".*/166:.*" -o -regex ".*/180:\([0-9]\|1[0-5]\)" -o -regex ".*/188:.*" -o -regex ".*/189:.*" -o -regex ".*/24[0-2]:.*"); do dev="/dev/$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" ${char_dev}/uevent)"; mkdir -p $(dirname ${LXC_ROOTFS_MOUNT}${dev}); for link in $(udevadm info --query=property $dev | sed -n "s/DEVLINKS=//p"); do mkdir -p ${LXC_ROOTFS_MOUNT}$(dirname $link); cp -dpR $link ${LXC_ROOTFS_MOUNT}${link}; done; cp -dpR $dev ${LXC_ROOTFS_MOUNT}${dev};done;' +``` +Reboot the LXC ________________________________________________________________________________________________________________________________________ From 68fbb69c3e849e93a4f5f1667a88ee9a42feddc0 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:14:33 -0400 Subject: [PATCH 0157/6505] Update troubleshoot.md --- troubleshoot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/troubleshoot.md b/troubleshoot.md index 783f795a..1418d80a 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -2,6 +2,7 @@ If all else fails, try this: + In the Proxmox web shell run (replace `105` with your lxc Id) ``` nano /etc/pve/lxc/105.conf From 250b671248c564346773a72d551daaef2f88a4dc Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:16:31 -0400 Subject: [PATCH 0158/6505] Update troubleshoot.md --- troubleshoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot.md b/troubleshoot.md index 1418d80a..86cbcec5 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -14,7 +14,7 @@ lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none b lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file ``` -with these 4 lines +with these 4 lines (change `cgroup2` with `cgroup` for PVE6) ``` lxc.cgroup2.devices.allow: a lxc.cap.drop: From 1ba6c25e4f2be429fb86e82db295f6b2746cc75b Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:17:59 -0400 Subject: [PATCH 0159/6505] Update troubleshoot.md --- troubleshoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot.md b/troubleshoot.md index 86cbcec5..3442f8be 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -10,7 +10,7 @@ nano /etc/pve/lxc/105.conf replace the last 4 lines ``` lxc.cgroup2.devices.allow: c 188:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file ``` From 65586c240cc51dd7c58abd57fe03659d21b3c376 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:21:06 -0400 Subject: [PATCH 0160/6505] Update troubleshoot.md --- troubleshoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot.md b/troubleshoot.md index 3442f8be..61d27920 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -1,7 +1,7 @@ ## Zigbee2MQTT Device Troubleshooting ## -If all else fails, try this: +**Alternative method:** In the Proxmox web shell run (replace `105` with your lxc Id) ``` From 8a2e038ca7f776c7609b9d087003a9020cd050d9 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:21:44 -0400 Subject: [PATCH 0161/6505] Update troubleshoot.md --- troubleshoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot.md b/troubleshoot.md index 61d27920..5ad27b38 100644 --- a/troubleshoot.md +++ b/troubleshoot.md @@ -14,7 +14,7 @@ lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bi lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file ``` -with these 4 lines (change `cgroup2` with `cgroup` for PVE6) +with these 4 lines (change `cgroup2` to `cgroup` for PVE6) ``` lxc.cgroup2.devices.allow: a lxc.cap.drop: From c07806086bced763b6c74b4a99c0f1f26081471a Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:32:54 -0400 Subject: [PATCH 0162/6505] Update and rename troubleshoot.md to Alternative.md --- troubleshoot.md => Alternative.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename troubleshoot.md => Alternative.md (97%) diff --git a/troubleshoot.md b/Alternative.md similarity index 97% rename from troubleshoot.md rename to Alternative.md index 5ad27b38..7a94f638 100644 --- a/troubleshoot.md +++ b/Alternative.md @@ -1,7 +1,7 @@ ## Zigbee2MQTT Device Troubleshooting ## -**Alternative method:** +**Alternative method to pass devices to LXC:** In the Proxmox web shell run (replace `105` with your lxc Id) ``` From 74dcc5c065818a457914a2dce118afd9453af271 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 19:40:27 -0400 Subject: [PATCH 0163/6505] Update Alternative.md --- Alternative.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Alternative.md b/Alternative.md index 7a94f638..467762a9 100644 --- a/Alternative.md +++ b/Alternative.md @@ -21,5 +21,7 @@ lxc.cap.drop: lxc.autodev: 1 lxc.hook.autodev: bash -c 'for char_dev in $(find /sys/dev/char -regextype sed -regex ".*/1:1" -o -regex ".*/4:\([3-9]\|[1-5][0-9]\|6[0-3]\)" -o -regex ".*/4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)" -o -regex ".*/10:200" -o -regex ".*/116:.*" -o -regex ".*/166:.*" -o -regex ".*/180:\([0-9]\|1[0-5]\)" -o -regex ".*/188:.*" -o -regex ".*/189:.*" -o -regex ".*/24[0-2]:.*"); do dev="/dev/$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" ${char_dev}/uevent)"; mkdir -p $(dirname ${LXC_ROOTFS_MOUNT}${dev}); for link in $(udevadm info --query=property $dev | sed -n "s/DEVLINKS=//p"); do mkdir -p ${LXC_ROOTFS_MOUNT}$(dirname $link); cp -dpR $link ${LXC_ROOTFS_MOUNT}${link}; done; cp -dpR $dev ${LXC_ROOTFS_MOUNT}${dev};done;' ``` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X" + Reboot the LXC ________________________________________________________________________________________________________________________________________ From 9c368bedf833ff6af880f796dfed5f913a722431 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 22:31:19 -0400 Subject: [PATCH 0164/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c450ae44..af10e663 100644 --- a/README.md +++ b/README.md @@ -273,6 +273,8 @@ Determine the location of your adapter (Run in the zigbee2mqtt console) ls -l /dev/serial/by-id ``` Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` + + If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) :warning: **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** ``` From a068d454ca4675cf45eb9ce8138ad42123faeee0 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 22 Aug 2021 22:34:15 -0400 Subject: [PATCH 0165/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index af10e663..4a3b22e8 100644 --- a/README.md +++ b/README.md @@ -334,7 +334,9 @@ ls -l /dev/serial/by-id ``` Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` -:warning: **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** + If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) + + :warning: **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** ``` nano /opt/zigbee2mqtt/data/configuration.yaml ``` From 8fe24b86af6ec3d29e93e713a57242183cd4e5af Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 05:20:04 -0400 Subject: [PATCH 0166/6505] Update Alternative.md --- Alternative.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Alternative.md b/Alternative.md index 467762a9..3a41ea34 100644 --- a/Alternative.md +++ b/Alternative.md @@ -3,7 +3,7 @@ **Alternative method to pass devices to LXC:** -In the Proxmox web shell run (replace `105` with your lxc Id) +In the Proxmox web shell run (replace `105` with your zigbee2mqtt lxc Id) ``` nano /etc/pve/lxc/105.conf ``` @@ -25,3 +25,26 @@ Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X" Reboot the LXC ________________________________________________________________________________________________________________________________________ + +## ZHA Device Pass Through ## + +In the Proxmox web shell run (replace `105` with your home assistant container lxc Id) +``` +nano /etc/pve/lxc/105.conf +``` +add these 2 lines +``` +lxc.autodev: 1 +lxc.hook.autodev: bash -c 'for char_dev in $(find /sys/dev/char -regextype sed -regex ".*/1:1" -o -regex ".*/4:\([3-9]\|[1-5][0-9]\|6[0-3]\)" -o -regex ".*/4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)" -o -regex ".*/10:200" -o -regex ".*/116:.*" -o -regex ".*/166:.*" -o -regex ".*/180:\([0-9]\|1[0-5]\)" -o -regex ".*/188:.*" -o -regex ".*/189:.*" -o -regex ".*/24[0-2]:.*"); do dev="/dev/$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" ${char_dev}/uevent)"; mkdir -p $(dirname ${LXC_ROOTFS_MOUNT}${dev}); for link in $(udevadm info --query=property $dev | sed -n "s/DEVLINKS=//p"); do mkdir -p ${LXC_ROOTFS_MOUNT}$(dirname $link); cp -dpR $link ${LXC_ROOTFS_MOUNT}${link}; done; cp -dpR $dev ${LXC_ROOTFS_MOUNT}${dev};done;' +``` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X" + +Reboot the LXC + + + + + + + + From e6dd7f50d1670078ae181f27db677c1224c22d1d Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 05:24:28 -0400 Subject: [PATCH 0167/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4a3b22e8..cb2cb180 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data ``` +[To pass a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through)
@@ -72,6 +73,7 @@ Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data ``` +[To pass a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through)
From 75c3c741bbcf1d38617b6defac8831ab068b780a Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 05:25:49 -0400 Subject: [PATCH 0168/6505] Update Alternative.md --- Alternative.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alternative.md b/Alternative.md index 3a41ea34..23b6233e 100644 --- a/Alternative.md +++ b/Alternative.md @@ -1,4 +1,4 @@ -## Zigbee2MQTT Device Troubleshooting ## +## Zigbee2MQTT Device Pass Through ## **Alternative method to pass devices to LXC:** From 551c434ca0ba7b7886d506f126eb917e44568940 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 05:35:11 -0400 Subject: [PATCH 0169/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cb2cb180..4941fbdb 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data ``` -[To pass a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) +[To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) @@ -73,7 +73,7 @@ Path to HA configuration.yaml ``` /var/lib/docker/volumes/hass_config/_data ``` -[To pass a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) +[To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) From 2245e99e934b3b5a1af42d9128124c5c644ea0eb Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 05:41:48 -0400 Subject: [PATCH 0170/6505] Update Alternative.md --- Alternative.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alternative.md b/Alternative.md index 23b6233e..205d09f7 100644 --- a/Alternative.md +++ b/Alternative.md @@ -32,7 +32,7 @@ In the Proxmox web shell run (replace `105` with your home assistant container l ``` nano /etc/pve/lxc/105.conf ``` -add these 2 lines +add these 2 lines to the bottom ``` lxc.autodev: 1 lxc.hook.autodev: bash -c 'for char_dev in $(find /sys/dev/char -regextype sed -regex ".*/1:1" -o -regex ".*/4:\([3-9]\|[1-5][0-9]\|6[0-3]\)" -o -regex ".*/4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)" -o -regex ".*/10:200" -o -regex ".*/116:.*" -o -regex ".*/166:.*" -o -regex ".*/180:\([0-9]\|1[0-5]\)" -o -regex ".*/188:.*" -o -regex ".*/189:.*" -o -regex ".*/24[0-2]:.*"); do dev="/dev/$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" ${char_dev}/uevent)"; mkdir -p $(dirname ${LXC_ROOTFS_MOUNT}${dev}); for link in $(udevadm info --query=property $dev | sed -n "s/DEVLINKS=//p"); do mkdir -p ${LXC_ROOTFS_MOUNT}$(dirname $link); cp -dpR $link ${LXC_ROOTFS_MOUNT}${link}; done; cp -dpR $dev ${LXC_ROOTFS_MOUNT}${dev};done;' From 63dc6f7713f609172b296417e41d2c50308ff399 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 06:09:35 -0400 Subject: [PATCH 0171/6505] Update README.md --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4941fbdb..8699bb3f 100644 --- a/README.md +++ b/README.md @@ -312,7 +312,12 @@ To start Zigbee2MQTT automatically on boot ``` sudo systemctl enable zigbee2mqtt.service ``` - +To update Zigbee2Mqtt, from the console run: + ``` + cd /opt/zigbee2mqtt + bash update.sh + ``` + @@ -372,8 +377,12 @@ To start Zigbee2MQTT automatically on boot ``` sudo systemctl enable zigbee2mqtt.service ``` - - + To update Zigbee2Mqtt, from the console run: + ``` + cd /opt/zigbee2mqtt + bash update.sh + ``` + From 13df0d4e09ac8bc76b55343c6e9c9f69b87ff621 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 06:37:41 -0400 Subject: [PATCH 0172/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8699bb3f..56ac3120 100644 --- a/README.md +++ b/README.md @@ -312,7 +312,7 @@ To start Zigbee2MQTT automatically on boot ``` sudo systemctl enable zigbee2mqtt.service ``` -To update Zigbee2Mqtt, from the console run: +To update Zigbee2Mqtt ``` cd /opt/zigbee2mqtt bash update.sh @@ -377,7 +377,7 @@ To start Zigbee2MQTT automatically on boot ``` sudo systemctl enable zigbee2mqtt.service ``` - To update Zigbee2Mqtt, from the console run: + To update Zigbee2Mqtt ``` cd /opt/zigbee2mqtt bash update.sh From 0aad7e9657416d5167c72e61390bc16eca3e3187 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 23 Aug 2021 12:37:06 -0400 Subject: [PATCH 0173/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 56ac3120..b1cb066a 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,7 @@ Give local admin root privileges (Change the username and password to match abov GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` -Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on my local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: +Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on your local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: ``` GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` From ca24a3672802baa2f4fe185d5e72ce28fce13a2c Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 07:06:03 -0400 Subject: [PATCH 0174/6505] Add files via upload --- ha_venv_container.sh | 159 +++++++++++++++++++++++++++++++++++++++++++ ha_venv_setup.sh | 86 +++++++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 ha_venv_container.sh create mode 100644 ha_venv_setup.sh diff --git a/ha_venv_container.sh b/ha_venv_container.sh new file mode 100644 index 00000000..4b2603e6 --- /dev/null +++ b/ha_venv_container.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ha_venv_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 11 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=ha_venv +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID ha_venv_setup.sh /ha_venv_setup.sh -perms 755 +pct exec $CTID /ha_venv_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Home Assistant venv LXC Container to $CTID at IP Address ${IP}" diff --git a/ha_venv_setup.sh b/ha_venv_setup.sh new file mode 100644 index 00000000..fe0814b6 --- /dev/null +++ b/ha_venv_setup.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating Container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing Dependencies" +sudo apt-get install -y python3 \ +python3-dev \ +python3-venv \ +python3-pip \ +libffi-dev \ +libssl-dev \ +libjpeg-dev \ +zlib1g-dev \ +autoconf build-essential \ +libopenjp2-7 \ +libtiff5 tzdata &>/dev/null + +sudo useradd -rm homeassistant &>/dev/null +sudo mkdir /srv/homeassistant &>/dev/null +sudo chown homeassistant:homeassistant /srv/homeassistant &>/dev/null +sudo -u homeassistant -H -s &>/dev/null +cd /srv/homeassistant &>/dev/null + +msg "Installing VENV" +python3.8 -m venv . &>/dev/null +source bin/activate &>/dev/null + +msg "Installing Wheel" +python3 -m pip install wheel + +msg "Installing Home Assistant" +pip3 install homeassistant + +# Customize container +msg "Customizing Container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /ha_venv_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 2b554c11c97c2b587e6503a2adf7bae6d1d83917 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 07:09:58 -0400 Subject: [PATCH 0175/6505] Update ha_venv_container.sh --- ha_venv_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ha_venv_container.sh b/ha_venv_container.sh index 4b2603e6..0fde73ca 100644 --- a/ha_venv_container.sh +++ b/ha_venv_container.sh @@ -137,7 +137,7 @@ else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi ARCH=$(dpkg --print-architecture) -HOSTNAME=ha_venv +HOSTNAME=havenv TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ From 5c16ad59c5fd6261c5c1d25ee42b2cd737f7959f Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 07:27:14 -0400 Subject: [PATCH 0176/6505] Update ha_venv_container.sh --- ha_venv_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ha_venv_container.sh b/ha_venv_container.sh index 0fde73ca..3cb5147e 100644 --- a/ha_venv_container.sh +++ b/ha_venv_container.sh @@ -137,10 +137,10 @@ else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi ARCH=$(dpkg --print-architecture) -HOSTNAME=havenv +HOSTNAME=homeassistantvenv TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Set container timezone to match host From 3010f5d045800863c815b4af9f64e0c8cf3fb166 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 07:45:37 -0400 Subject: [PATCH 0177/6505] Update ha_venv_setup.sh --- ha_venv_setup.sh | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/ha_venv_setup.sh b/ha_venv_setup.sh index fe0814b6..f1b7f5d9 100644 --- a/ha_venv_setup.sh +++ b/ha_venv_setup.sh @@ -37,18 +37,30 @@ apt-get -qqy install \ curl \ sudo &>/dev/null -msg "Installing Dependencies" -sudo apt-get install -y python3 \ -python3-dev \ -python3-venv \ -python3-pip \ -libffi-dev \ -libssl-dev \ -libjpeg-dev \ -zlib1g-dev \ -autoconf build-essential \ -libopenjp2-7 \ -libtiff5 tzdata &>/dev/null +msg "Installing Dependencies..." +sudo apt-get -qqy install \ +msg "1..." + python3 \ +msg "2..." + python3-dev \ +msg "3..." + python3-venv \ +msg "4..." + python3-pip \ +msg "5..." + libffi-dev \ +msg "6..." + libssl-dev \ +msg "7..." + libjpeg-dev \ +msg "8..." + zlib1g-dev \ +msg "9..." + autoconf build-essential \ +msg "1..." + libopenjp2-7 \ +msg "10..." + libtiff5 tzdata &>/dev/null sudo useradd -rm homeassistant &>/dev/null sudo mkdir /srv/homeassistant &>/dev/null @@ -83,4 +95,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /ha_venv_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /ha_venv_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 37b16d7417c1d64d9607a86bdacce0267c72e221 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 07:51:19 -0400 Subject: [PATCH 0178/6505] Update ha_venv_setup.sh --- ha_venv_setup.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/ha_venv_setup.sh b/ha_venv_setup.sh index f1b7f5d9..9dbed169 100644 --- a/ha_venv_setup.sh +++ b/ha_venv_setup.sh @@ -39,27 +39,16 @@ apt-get -qqy install \ msg "Installing Dependencies..." sudo apt-get -qqy install \ -msg "1..." python3 \ -msg "2..." python3-dev \ -msg "3..." python3-venv \ -msg "4..." python3-pip \ -msg "5..." libffi-dev \ -msg "6..." libssl-dev \ -msg "7..." libjpeg-dev \ -msg "8..." zlib1g-dev \ -msg "9..." autoconf build-essential \ -msg "1..." libopenjp2-7 \ -msg "10..." libtiff5 tzdata &>/dev/null sudo useradd -rm homeassistant &>/dev/null From e6d2fc43955bae4cb4e3514845bcacc682dd993e Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 08:00:42 -0400 Subject: [PATCH 0179/6505] Update ha_venv_setup.sh --- ha_venv_setup.sh | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/ha_venv_setup.sh b/ha_venv_setup.sh index 9dbed169..e4a50724 100644 --- a/ha_venv_setup.sh +++ b/ha_venv_setup.sh @@ -38,19 +38,7 @@ apt-get -qqy install \ sudo &>/dev/null msg "Installing Dependencies..." -sudo apt-get -qqy install \ - python3 \ - python3-dev \ - python3-venv \ - python3-pip \ - libffi-dev \ - libssl-dev \ - libjpeg-dev \ - zlib1g-dev \ - autoconf build-essential \ - libopenjp2-7 \ - libtiff5 tzdata &>/dev/null - +sudo apt-get install -y python3 python3-dev python3-venv python3-pip libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libopenjp2-7 libtiff5 tzdata &>/dev/null sudo useradd -rm homeassistant &>/dev/null sudo mkdir /srv/homeassistant &>/dev/null sudo chown homeassistant:homeassistant /srv/homeassistant &>/dev/null From 455b049b8b0235a8c49d083ebe7f9f105b274566 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:13:24 -0400 Subject: [PATCH 0180/6505] Delete ha_venv_container.sh --- ha_venv_container.sh | 159 ------------------------------------------- 1 file changed, 159 deletions(-) delete mode 100644 ha_venv_container.sh diff --git a/ha_venv_container.sh b/ha_venv_container.sh deleted file mode 100644 index 3cb5147e..00000000 --- a/ha_venv_container.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ha_venv_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=homeassistantvenv -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID ha_venv_setup.sh /ha_venv_setup.sh -perms 755 -pct exec $CTID /ha_venv_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Home Assistant venv LXC Container to $CTID at IP Address ${IP}" From 012983abdca146b52cef9170c0e47bcf809c65e4 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:13:42 -0400 Subject: [PATCH 0181/6505] Delete ha_venv_setup.sh --- ha_venv_setup.sh | 75 ------------------------------------------------ 1 file changed, 75 deletions(-) delete mode 100644 ha_venv_setup.sh diff --git a/ha_venv_setup.sh b/ha_venv_setup.sh deleted file mode 100644 index e4a50724..00000000 --- a/ha_venv_setup.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -msg "Setting up Container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -msg "Updating Container OS..." -apt-get update >/dev/null -apt-get -qqy upgrade &>/dev/null - -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -msg "Installing Dependencies..." -sudo apt-get install -y python3 python3-dev python3-venv python3-pip libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libopenjp2-7 libtiff5 tzdata &>/dev/null -sudo useradd -rm homeassistant &>/dev/null -sudo mkdir /srv/homeassistant &>/dev/null -sudo chown homeassistant:homeassistant /srv/homeassistant &>/dev/null -sudo -u homeassistant -H -s &>/dev/null -cd /srv/homeassistant &>/dev/null - -msg "Installing VENV" -python3.8 -m venv . &>/dev/null -source bin/activate &>/dev/null - -msg "Installing Wheel" -python3 -m pip install wheel - -msg "Installing Home Assistant" -pip3 install homeassistant - -# Customize container -msg "Customizing Container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /ha_venv_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From bc17a0eed87988c065e6f6423da268fe7db2b27c Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:14:04 -0400 Subject: [PATCH 0182/6505] Add files via upload --- ha.sh | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++ lxc_create.sh | 139 +++++++++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+) create mode 100644 ha.sh create mode 100644 lxc_create.sh diff --git a/ha.sh b/ha.sh new file mode 100644 index 00000000..d2ee9a59 --- /dev/null +++ b/ha.sh @@ -0,0 +1,195 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Create LXC +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=10 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -cmode shell + -features nesting=1 + -hostname homeassistant + -net0 name=eth0,bridge=vmbr0 + -onboot 1 + -tags homeassistant +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/lxc_create.sh)" || exit + +# Detect storage pool type +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +# Download setup script +REPO="https://github.com/tteck/Proxmox" +wget -qO - ${REPO}/tarball/master | tar -xz --strip-components=1 + +# Modify LXC permissions to support Docker +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup.devices.allow: a +lxc.cap.drop: +EOF + +# Load modules for Docker before starting LXC +cat << 'EOF' >> $LXC_CONFIG +lxc.hook.pre-start: sh -ec 'for module in aufs overlay; do modinfo $module; $(lsmod | grep -Fq $module) || modprobe $module; done;' +EOF + +# Set autodev hook to enable access to devices in container +bash ./set_autodev_hook.sh $CTID + +# Set container timezone to match host +cat << 'EOF' >> $LXC_CONFIG +lxc.hook.mount: sh -c 'ln -fs $(readlink /etc/localtime) ${LXC_ROOTFS_MOUNT}/etc/localtime' +EOF + +# Setup container for Home Assistant +msg "Starting LXC container..." +pct start $CTID + +### Begin LXC commands ### +alias lxc-cmd="lxc-attach -n $CTID --" +# Prepare container OS +msg "Setting up container OS..." +lxc-cmd dhclient -4 +lxc-cmd sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +lxc-cmd locale-gen >/dev/null +lxc-cmd apt-get -y purge openssh-{client,server} >/dev/null + +# Update container OS +msg "Updating container OS..." +lxc-cmd apt-get update >/dev/null +lxc-cmd apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl &>/dev/null + +# Customize Docker configuration +msg "Customizing Docker..." +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +# Install Docker +msg "Installing Docker..." +lxc-cmd sh <(curl -sSL https://get.docker.com) &>/dev/null + +# Install Portainer +msg "Installing Portainer..." +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest &>/dev/null + +# Install Home Assistant +msg "Installing Home Assistant..." +docker volume create hass_config >/dev/null +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +lxc-cmd apt-get autoremove >/dev/null +lxc-cmd apt-get autoclean >/dev/null +lxc-cmd rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +### Finish LXC commands ### + +# Get network details +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +# Show completion message +info "Successfully created Home Assistant LXC to $CTID." +msg " + +Home Assistant is reachable by going to the following URLs. + + http://${IP}:8123 + http://${HOSTNAME}.local:8123 + +" \ No newline at end of file diff --git a/lxc_create.sh b/lxc_create.sh new file mode 100644 index 00000000..1252b6cc --- /dev/null +++ b/lxc_create.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." +[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +# Create variable for 'pct' options +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 +) +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +info "LXC container '$CTID' was successfully created." \ No newline at end of file From f54aa9c1866c9296237868e505227510676ba665 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:22:07 -0400 Subject: [PATCH 0183/6505] Update ha.sh --- ha.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ha.sh b/ha.sh index d2ee9a59..f24a8184 100644 --- a/ha.sh +++ b/ha.sh @@ -72,19 +72,19 @@ if [ "$STORAGE_TYPE" == "zfspool" ]; then fi # Download setup script -REPO="https://github.com/tteck/Proxmox" -wget -qO - ${REPO}/tarball/master | tar -xz --strip-components=1 +#REPO="https://github.com/tteck/Proxmox" +#wget -qO - ${REPO}/tarball/master | tar -xz --strip-components=1 # Modify LXC permissions to support Docker LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG -lxc.cgroup.devices.allow: a +lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF # Load modules for Docker before starting LXC cat << 'EOF' >> $LXC_CONFIG -lxc.hook.pre-start: sh -ec 'for module in aufs overlay; do modinfo $module; $(lsmod | grep -Fq $module) || modprobe $module; done;' +lxc.hook.pre-start: sh -ec 'do modinfo $module; $(lsmod | grep -Fq $module) || modprobe $module; done;' EOF # Set autodev hook to enable access to devices in container @@ -192,4 +192,4 @@ Home Assistant is reachable by going to the following URLs. http://${IP}:8123 http://${HOSTNAME}.local:8123 -" \ No newline at end of file +" From faed31210fc177bc470c78610190e5d203266959 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:24:28 -0400 Subject: [PATCH 0184/6505] Update ha.sh --- ha.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ha.sh b/ha.sh index f24a8184..2e671e3b 100644 --- a/ha.sh +++ b/ha.sh @@ -88,7 +88,7 @@ lxc.hook.pre-start: sh -ec 'do modinfo $module; $(lsmod | grep -Fq $module) || m EOF # Set autodev hook to enable access to devices in container -bash ./set_autodev_hook.sh $CTID +#bash ./set_autodev_hook.sh $CTID # Set container timezone to match host cat << 'EOF' >> $LXC_CONFIG From d977ac31d0df44b1c0a7aa23d912009d758924d7 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:34:17 -0400 Subject: [PATCH 0185/6505] Update ha.sh --- ha.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/ha.sh b/ha.sh index 2e671e3b..bc4307be 100644 --- a/ha.sh +++ b/ha.sh @@ -50,6 +50,18 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} + # Create LXC export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian @@ -71,10 +83,6 @@ if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi -# Download setup script -#REPO="https://github.com/tteck/Proxmox" -#wget -qO - ${REPO}/tarball/master | tar -xz --strip-components=1 - # Modify LXC permissions to support Docker LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG @@ -82,13 +90,7 @@ lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF -# Load modules for Docker before starting LXC -cat << 'EOF' >> $LXC_CONFIG -lxc.hook.pre-start: sh -ec 'do modinfo $module; $(lsmod | grep -Fq $module) || modprobe $module; done;' -EOF - -# Set autodev hook to enable access to devices in container -#bash ./set_autodev_hook.sh $CTID +load_module overlay # Set container timezone to match host cat << 'EOF' >> $LXC_CONFIG From 99f3b8fb606b79840a75d768d7aa0d469ecec67c Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:40:09 -0400 Subject: [PATCH 0186/6505] Update ha.sh --- ha.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ha.sh b/ha.sh index bc4307be..e73f0b8c 100644 --- a/ha.sh +++ b/ha.sh @@ -65,8 +65,8 @@ function load_module() { # Create LXC export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian -export PCT_OSVERSION=10 -export PCT_DISK_SIZE=4 +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=16 export PCT_OPTIONS=" -cmode shell -features nesting=1 From f9a80be09a7c450f9b481c93ce8450dfbea6e1ca Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 12:48:24 -0400 Subject: [PATCH 0187/6505] Update ha.sh --- ha.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ha.sh b/ha.sh index e73f0b8c..2ea97539 100644 --- a/ha.sh +++ b/ha.sh @@ -132,7 +132,7 @@ EOF # Install Docker msg "Installing Docker..." -lxc-cmd sh <(curl -sSL https://get.docker.com) &>/dev/null +sh <(curl -sSL https://get.docker.com) &>/dev/null # Install Portainer msg "Installing Portainer..." From 803a16d7649bba47d5b082d07075e0a764b6e480 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 13:03:05 -0400 Subject: [PATCH 0188/6505] Delete ha.sh --- ha.sh | 197 ---------------------------------------------------------- 1 file changed, 197 deletions(-) delete mode 100644 ha.sh diff --git a/ha.sh b/ha.sh deleted file mode 100644 index 2ea97539..00000000 --- a/ha.sh +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} - -# Create LXC -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=16 -export PCT_OPTIONS=" - -cmode shell - -features nesting=1 - -hostname homeassistant - -net0 name=eth0,bridge=vmbr0 - -onboot 1 - -tags homeassistant -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/lxc_create.sh)" || exit - -# Detect storage pool type -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -# Modify LXC permissions to support Docker -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -load_module overlay - -# Set container timezone to match host -cat << 'EOF' >> $LXC_CONFIG -lxc.hook.mount: sh -c 'ln -fs $(readlink /etc/localtime) ${LXC_ROOTFS_MOUNT}/etc/localtime' -EOF - -# Setup container for Home Assistant -msg "Starting LXC container..." -pct start $CTID - -### Begin LXC commands ### -alias lxc-cmd="lxc-attach -n $CTID --" -# Prepare container OS -msg "Setting up container OS..." -lxc-cmd dhclient -4 -lxc-cmd sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -lxc-cmd locale-gen >/dev/null -lxc-cmd apt-get -y purge openssh-{client,server} >/dev/null - -# Update container OS -msg "Updating container OS..." -lxc-cmd apt-get update >/dev/null -lxc-cmd apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing prerequisites..." -apt-get -qqy install \ - curl &>/dev/null - -# Customize Docker configuration -msg "Customizing Docker..." -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -# Install Docker -msg "Installing Docker..." -sh <(curl -sSL https://get.docker.com) &>/dev/null - -# Install Portainer -msg "Installing Portainer..." -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null - -# Install Home Assistant -msg "Installing Home Assistant..." -docker volume create hass_config >/dev/null -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -lxc-cmd apt-get autoremove >/dev/null -lxc-cmd apt-get autoclean >/dev/null -lxc-cmd rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -### Finish LXC commands ### - -# Get network details -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -# Show completion message -info "Successfully created Home Assistant LXC to $CTID." -msg " - -Home Assistant is reachable by going to the following URLs. - - http://${IP}:8123 - http://${HOSTNAME}.local:8123 - -" From 7da1f9020539e7fd2dba843df7e97dafa4a21b2c Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 13:03:33 -0400 Subject: [PATCH 0189/6505] Delete lxc_create.sh --- lxc_create.sh | 139 -------------------------------------------------- 1 file changed, 139 deletions(-) delete mode 100644 lxc_create.sh diff --git a/lxc_create.sh b/lxc_create.sh deleted file mode 100644 index 1252b6cc..00000000 --- a/lxc_create.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=( "$TAG" "$ITEM" "OFF" ) - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected - printf ${MENU[0]} - else # More than one storage location is detected - local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Test if required variables are set -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." -[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 -) -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Success message -info "LXC container '$CTID' was successfully created." \ No newline at end of file From f76a8f3b225997d64f72472ff7ee13ffb22dc8d3 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 24 Aug 2021 16:39:02 -0400 Subject: [PATCH 0190/6505] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b1cb066a..dc9a3c8e 100644 --- a/README.md +++ b/README.md @@ -190,19 +190,19 @@ Run the security script: ``` sudo mysql_secure_installation ``` -Enter current password for root (enter for none): enter +Enter current password for root (enter for none): `enter` -Switch to unix_socket authentication [Y/n] y +Switch to unix_socket authentication [Y/n] `y` -Change the root password? [Y/n] n +Change the root password? [Y/n] `n` -Remove anonymous users? [Y/n] y +Remove anonymous users? [Y/n] `y` -Disallow root login remotely? [Y/n] y +Disallow root login remotely? [Y/n] `y` -Remove test database and access to it? [Y/n] y +Remove test database and access to it? [Y/n] `y` -Reload privilege tables now? [Y/n] y +Reload privilege tables now? [Y/n] `y` We will create a new account called admin with the same capabilities as the root account, but configured for password authentication. ``` From a7bdc5c13da5a9b9542c145d20297ca6f37001e5 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 27 Aug 2021 05:59:26 -0400 Subject: [PATCH 0191/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc9a3c8e..be4fa241 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,7 @@ Give local admin root privileges (Change the username and password to match abov GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` -Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on your local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the username, password and subnet to match your preferences: +Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on your local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the **_username_**, **_password_** and **_subnet_** to match your preferences: ``` GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` From b90e5e441d35dc46b54d80caeca492fe2ea8fe0c Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 27 Aug 2021 14:48:46 -0400 Subject: [PATCH 0192/6505] Update update_ha.md --- update_ha.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/update_ha.md b/update_ha.md index 8ed2ce26..bc814a08 100644 --- a/update_ha.md +++ b/update_ha.md @@ -58,3 +58,21 @@ echo -e "\e[1;33m Removing Old Image... \e[0m" docker image prune -f echo -e "\e[1;33m Finished Update! \e[0m" ``` + +Portainer-CE +``` +### upportainer.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Portainer-Ce Version... \e[0m" +docker pull portainer/portainer-ce:latest +echo -e "\e[1;33m Stopping Portainer... \e[0m" +docker stop portainer +echo -e "\e[1;33m Removing Portainer... \e[0m" +docker rm portainer +echo -e "\e[1;33m Starting Portainer... \e[0m" +docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` From dfd8c3556cfd9d90fd1d2f9e57c653c4d60ed8b5 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 27 Aug 2021 18:15:26 -0400 Subject: [PATCH 0193/6505] Update README.md --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index be4fa241..17b5f08e 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,21 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m +
+Nginx Proxy Manager LXC + +

Proxmox Nginx Proxy Manager LXC Container

+ +To create a new Proxmox Nginx Proxy Manager LXC Container, go to the following URL. + + +https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md + + + +
+ + From d6188538bdc22869ad4d2546d6f4cc0712bd12b9 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 28 Aug 2021 00:49:59 -0400 Subject: [PATCH 0194/6505] Update README.md --- README.md | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/README.md b/README.md index 17b5f08e..eac3051b 100644 --- a/README.md +++ b/README.md @@ -253,21 +253,9 @@ Change the recorder: `db_url:` in your HA configuration.yaml Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4` + -
-Nginx Proxy Manager LXC - -

Proxmox Nginx Proxy Manager LXC Container

- -To create a new Proxmox Nginx Proxy Manager LXC Container, go to the following URL. - - -https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md - - - -
From 3d4f7e34d40c8d929d39c623437ba21973282751 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 28 Aug 2021 01:42:42 -0400 Subject: [PATCH 0195/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eac3051b..2337db9c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
PVE6 Home Assistant Container LXC -

Proxmox 6 Home Assistant LXC Container

+

Proxmox 6 Home Assistant Container LXC

To create a new Proxmox 6 Home Assistant Container, run the following from Proxmox web shell. @@ -53,7 +53,7 @@ Path to HA configuration.yaml
PVE7 Home Assistant Container LXC -

Proxmox 7 Home Assistant LXC Container

+

Proxmox 7 Home Assistant Container LXC

To create a new Proxmox 7 Home Assistant Container, run the following from Proxmox web shell. From ddc1b3640a9691f10444d6a881811d3634d97409 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 28 Aug 2021 01:44:20 -0400 Subject: [PATCH 0196/6505] Update update_ha.md --- update_ha.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update_ha.md b/update_ha.md index bc814a08..dfb4276b 100644 --- a/update_ha.md +++ b/update_ha.md @@ -1,7 +1,7 @@ ## Home Assistant Container Update ## In the homeassistant lxc console run `nano upha.sh` -it will open a new file, copy and paste the Stable Branch (change TZ) +it will open a empty file, copy and paste the Stable Branch (change TZ) Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X" To update HA, run `bash upha.sh` from the console From 21933be7095eb87089e6e01b5de5a6665d09dfa0 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 15:33:46 -0400 Subject: [PATCH 0197/6505] Update README.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 2337db9c..82f6aa64 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,23 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esph
+
+ + +
+Nginx Proxy Manager LXC + +

Proxmox Nginx Proxy Manager LXC Container

+ +To create a new Proxmox Nginx Proxy Manager LXC Container, run the following from Proxmox web shell. + +``` + curl -sL https://raw.githubusercontent.com/ej52/proxmox/main/lxc/nginx-proxy-manager/create.sh | bash -s +``` +Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) + + +
From 98993a9a56121900595d8a3bf6bf4fb3984f30d5 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 15:38:43 -0400 Subject: [PATCH 0198/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 82f6aa64..afad2dbc 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,8 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ``` curl -sL https://raw.githubusercontent.com/ej52/proxmox/main/lxc/nginx-proxy-manager/create.sh | bash -s ``` +

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+ Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) From b408e8ede618d5c9ceae2425c66129dea0f1da91 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 15:41:25 -0400 Subject: [PATCH 0199/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index afad2dbc..f1d0a0f5 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ``` curl -sL https://raw.githubusercontent.com/ej52/proxmox/main/lxc/nginx-proxy-manager/create.sh | bash -s ``` -

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+

:zap: Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) From 2f9fed1c39676657e3256e6e202bcf57c857f9f7 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 15:52:58 -0400 Subject: [PATCH 0200/6505] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index f1d0a0f5..49d26044 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,16 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ```

:zap: Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+Initial Login + +username ``` + admin@example.com + ``` + password ``` + changeme + ``` + + Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) From b99fba1a9190901671ccd2427964b5e33a02d19d Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 15:53:35 -0400 Subject: [PATCH 0201/6505] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 49d26044..6a9cf164 100644 --- a/README.md +++ b/README.md @@ -112,10 +112,12 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro Initial Login -username ``` +username + ``` admin@example.com ``` - password ``` + password + ``` changeme ``` From 5f7e65feab1679c331277a38c700d8ffcf277b72 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 15:54:58 -0400 Subject: [PATCH 0202/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6a9cf164..4fdb87d1 100644 --- a/README.md +++ b/README.md @@ -110,13 +110,13 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ```

:zap: Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

-Initial Login +**Initial Login** -username +**username** ``` admin@example.com ``` - password + **password** ``` changeme ``` From cd9d6d2c1d40fccc1b9fd4b58e1fab46a840f8f0 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 15:56:06 -0400 Subject: [PATCH 0203/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4fdb87d1..ad48d2eb 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ``` -Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) +Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. From 1bbea86fdfc5db8b17158cadc798b881ed7993a7 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 16:10:51 -0400 Subject: [PATCH 0204/6505] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ad48d2eb..ad15954d 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,13 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ``` changeme ``` - +Add to your `configuration.yaml` +``` + http: + use_x_forwarded_for: true + trusted_proxies: + - 192.168.86.103 #(Nginx Proxy Manager LXC IP) +``` Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. From d7897fff016f6904540d6bb4614ac51518b82b7f Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 16:11:42 -0400 Subject: [PATCH 0205/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad15954d..24dea56a 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ Add to your `configuration.yaml` http: use_x_forwarded_for: true trusted_proxies: - - 192.168.86.103 #(Nginx Proxy Manager LXC IP) + - 192.168.86.103 ### (Nginx Proxy Manager LXC IP) ``` Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. From 0b14f7517ff1b7526c0c81152d15d6d58c97a19f Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 16:13:36 -0400 Subject: [PATCH 0206/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 24dea56a..88d069d3 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ Add to your `configuration.yaml` http: use_x_forwarded_for: true trusted_proxies: - - 192.168.86.103 ### (Nginx Proxy Manager LXC IP) + - 192.168.100.27 ###(Nginx Proxy Manager LXC IP) ``` Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. From 93d56412691865f18270347b1df8188498d1fe88 Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 16:14:27 -0400 Subject: [PATCH 0207/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88d069d3..12217e09 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ Add to your `configuration.yaml` http: use_x_forwarded_for: true trusted_proxies: - - 192.168.100.27 ###(Nginx Proxy Manager LXC IP) + - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### ``` Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. From b0e86288958589f495201896af8e4c0614da6cee Mon Sep 17 00:00:00 2001 From: tteck Date: Fri, 3 Sep 2021 16:24:52 -0400 Subject: [PATCH 0208/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12217e09..b49dcae9 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ``` changeme ``` -Add to your `configuration.yaml` +Add the following to your `configuration.yaml` in Home Assistant. ``` http: use_x_forwarded_for: true From 3de89044c384082d42839ac76bef1a7e24bd8431 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 4 Sep 2021 08:07:22 -0400 Subject: [PATCH 0209/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b49dcae9..94a10ab0 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ Add the following to your `configuration.yaml` in Home Assistant. trusted_proxies: - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### ``` +Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. From ee6333232a1a955a0f12d6b7334f5a504cb03eaa Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 4 Sep 2021 09:18:21 -0400 Subject: [PATCH 0210/6505] Update README.md --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 94a10ab0..ec3c4ac5 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,16 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ```

:zap: Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. + +Add the following to your `configuration.yaml` in Home Assistant. +``` + http: + use_x_forwarded_for: true + trusted_proxies: + - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### +``` + **Initial Login** **username** @@ -120,14 +130,6 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ``` changeme ``` -Add the following to your `configuration.yaml` in Home Assistant. -``` - http: - use_x_forwarded_for: true - trusted_proxies: - - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### -``` -Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. From d9cc2fd766ba03045f90ef365466525b600690c7 Mon Sep 17 00:00:00 2001 From: tteck Date: Sat, 4 Sep 2021 11:03:40 -0400 Subject: [PATCH 0211/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ec3c4ac5..9d9bf751 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro curl -sL https://raw.githubusercontent.com/ej52/proxmox/main/lxc/nginx-proxy-manager/create.sh | bash -s ```

:zap: Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+ +____________________________________________________________________________________ Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. From 1ec9bf5ec39d8172784091b8ca55b85ed3b0e995 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 5 Sep 2021 08:48:00 -0400 Subject: [PATCH 0212/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 8c5963e1..1975d3b1 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -155,6 +155,8 @@ pct set $CTID -description "Access Portainer interface using the following URL. http://:9000" +bash ./autodev.sh $CTID + # Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime From 214136f42467a659c41500c5c1187e891b339f84 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 5 Sep 2021 08:51:52 -0400 Subject: [PATCH 0213/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 1975d3b1..665cf7c4 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -155,7 +155,7 @@ pct set $CTID -description "Access Portainer interface using the following URL. http://:9000" -bash ./autodev.sh $CTID +bash /autodev.sh $CTID # Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From eb9861bb7d4b6c56b9f66d5ff0663b282873bec8 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 5 Sep 2021 08:54:55 -0400 Subject: [PATCH 0214/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 665cf7c4..44d145c0 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -155,7 +155,7 @@ pct set $CTID -description "Access Portainer interface using the following URL. http://:9000" -bash /autodev.sh $CTID +bash https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh $CTID # Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 6cad62f09791ffe6d5b1355ce60194af6c0096e1 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 5 Sep 2021 08:57:12 -0400 Subject: [PATCH 0215/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 44d145c0..22031abe 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -155,7 +155,7 @@ pct set $CTID -description "Access Portainer interface using the following URL. http://:9000" -bash https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh $CTID +# bash ./autodev.sh $CTID # Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From fb2f980fe8a69d4ed73dd8f24f8b422162090089 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 5 Sep 2021 09:10:22 -0400 Subject: [PATCH 0216/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 22031abe..8db9f122 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -155,7 +155,7 @@ pct set $CTID -description "Access Portainer interface using the following URL. http://:9000" -# bash ./autodev.sh $CTID +bash wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh $CTID # Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From b8bb928704b03c3a5a8fa3621f95e8554fac65e8 Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 5 Sep 2021 09:13:43 -0400 Subject: [PATCH 0217/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 8db9f122..e72d01bd 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -155,7 +155,7 @@ pct set $CTID -description "Access Portainer interface using the following URL. http://:9000" -bash wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh $CTID +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh $CTID # Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 06e90568c42eb54d733d64631c042afcc00b387f Mon Sep 17 00:00:00 2001 From: tteck Date: Sun, 5 Sep 2021 09:15:38 -0400 Subject: [PATCH 0218/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index e72d01bd..8c5963e1 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -155,8 +155,6 @@ pct set $CTID -description "Access Portainer interface using the following URL. http://:9000" -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh $CTID - # Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime From b0ad37efe1b56bc0e54681541b40bbcc1a661ac4 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 6 Sep 2021 18:37:20 -0400 Subject: [PATCH 0219/6505] Update haos_vm.sh --- haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haos_vm.sh b/haos_vm.sh index dd9250ec..ded12c19 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -81,7 +81,7 @@ info "Container ID is $VMID." # Get latest Home Assistant disk image archive URL echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" -RELEASE_TYPE=vmdk +RELEASE_TYPE=qcow2 URL=$(cat< Date: Fri, 17 Sep 2021 10:30:52 -0400 Subject: [PATCH 0220/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9d9bf751..f5070c4b 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esph

:zap: Default Settings: 1GB RAM - 4GB Storage - 2vCPU :zap:

+For ESPHome interface http:// (LXC IP) :6052 + From 4ef77b98629fceb11be454ff06e9dc29e6532aaf Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 08:00:15 -0400 Subject: [PATCH 0221/6505] Add files via upload --- post_install.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 post_install.sh diff --git a/post_install.sh b/post_install.sh new file mode 100644 index 00000000..e374391a --- /dev/null +++ b/post_install.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +echo -e "\e[1;33m This script will disable the Enterprise Repo, +enable the No Subscription Repo and attempt a No Nag fix *PVE7 ONLY*\e[0m" +read -p "Press [Enter] to start the PVE7 Post Install Script" +read -t 2 -p "Disabling Enterprise Repo ..." +sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list +read -t 2 -p "Enabling No Subscription Repo ..." +cat < /etc/apt/sources.list +deb http://ftp.us.debian.org/debian bullseye main contrib +deb http://ftp.us.debian.org/debian bullseye-updates main contrib +deb http://security.debian.org bullseye-security main contrib +deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription +# deb http://download.proxmox.com/debian/pve bullseye pvetest +EOF + +read -t 2 -p "Enabling No Nag ..." +sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service + +echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" \ No newline at end of file From 48fdd6fdf6b7c6d42437affeca7cfac1c2bcee7f Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 08:09:15 -0400 Subject: [PATCH 0222/6505] Delete post_install.sh --- post_install.sh | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 post_install.sh diff --git a/post_install.sh b/post_install.sh deleted file mode 100644 index e374391a..00000000 --- a/post_install.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -echo -e "\e[1;33m This script will disable the Enterprise Repo, -enable the No Subscription Repo and attempt a No Nag fix *PVE7 ONLY*\e[0m" -read -p "Press [Enter] to start the PVE7 Post Install Script" -read -t 2 -p "Disabling Enterprise Repo ..." -sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list -read -t 2 -p "Enabling No Subscription Repo ..." -cat < /etc/apt/sources.list -deb http://ftp.us.debian.org/debian bullseye main contrib -deb http://ftp.us.debian.org/debian bullseye-updates main contrib -deb http://security.debian.org bullseye-security main contrib -deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription -# deb http://download.proxmox.com/debian/pve bullseye pvetest -EOF - -read -t 2 -p "Enabling No Nag ..." -sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service - -echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" \ No newline at end of file From ab8e9abc588a7870845ce0a10493b3b0eedc4789 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 08:09:55 -0400 Subject: [PATCH 0223/6505] Add files via upload --- post_install.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 post_install.sh diff --git a/post_install.sh b/post_install.sh new file mode 100644 index 00000000..8c12611b --- /dev/null +++ b/post_install.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +echo -e "\e[1;33m This script will Disable the Enterprise Repo and Enable the No Subscription Repo *PVE7 ONLY*\e[0m" + +read -p "Press [Enter] to start the PVE7 Post Install Script" + +read -t 2 -p "Disabling Enterprise Repo ..." +sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list + +read -t 2 -p "Enabling No Subscription Repo ..." +cat < /etc/apt/sources.list +deb http://ftp.us.debian.org/debian bullseye main contrib +deb http://ftp.us.debian.org/debian bullseye-updates main contrib +deb http://security.debian.org bullseye-security main contrib +deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription +# deb http://download.proxmox.com/debian/pve bullseye pvetest +EOF + +# read -t 2 -p "Enabling No Nag ..." +# sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service + +echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" + +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From 74705e357cb20f98178b97e11e155bb86a95038e Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 08:14:13 -0400 Subject: [PATCH 0224/6505] Update post_install.sh --- post_install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/post_install.sh b/post_install.sh index 8c12611b..d0251c8b 100644 --- a/post_install.sh +++ b/post_install.sh @@ -4,10 +4,10 @@ echo -e "\e[1;33m This script will Disable the Enterprise Repo and Enable the No read -p "Press [Enter] to start the PVE7 Post Install Script" -read -t 2 -p "Disabling Enterprise Repo ..." +read -t 2 -p "Disabling Enterprise Repo..." sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list -read -t 2 -p "Enabling No Subscription Repo ..." +read -t 2 -p "Enabling No Subscription Repo..." cat < /etc/apt/sources.list deb http://ftp.us.debian.org/debian bullseye main contrib deb http://ftp.us.debian.org/debian bullseye-updates main contrib @@ -19,6 +19,6 @@ EOF # read -t 2 -p "Enabling No Nag ..." # sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service -echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" +echo -e "\e[1;33m Finished, Please Update Proxmox \e[0m" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From 1f42d03b5e6a1b402372c0a36a492f1e3807b719 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 09:47:47 -0400 Subject: [PATCH 0225/6505] Update README.md --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index f5070c4b..4b0f23f2 100644 --- a/README.md +++ b/README.md @@ -469,3 +469,23 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debi After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. + + + + + +
+PVE7 Post Install + +

Proxmox PVE7 Post Install

+ +This script disables the Enterprise Repo and Enables the No Subscription Repo, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" +``` +

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+ +I recommend updating Proxmox before adding any VM/CT. + +
From 2f503e13c5ffd926790b3b555fd573ca4b3117ef Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 09:48:39 -0400 Subject: [PATCH 0226/6505] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4b0f23f2..fbd48e6c 100644 --- a/README.md +++ b/README.md @@ -484,7 +484,6 @@ This script disables the Enterprise Repo and Enables the No Subscription Repo, r ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" ``` -

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

I recommend updating Proxmox before adding any VM/CT. From 188f8e835f87fb762a4437f334c186ccb4bb1701 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 09:50:04 -0400 Subject: [PATCH 0227/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fbd48e6c..b6b9217b 100644 --- a/README.md +++ b/README.md @@ -485,6 +485,6 @@ This script disables the Enterprise Repo and Enables the No Subscription Repo, r bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" ``` -I recommend updating Proxmox before adding any VM/CT. +I recommend updating Proxmox after running this script, before adding any VM/CT. From 3ff0e8bf823edd84efd2c9e74fc35d5238959bed Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:31:10 -0400 Subject: [PATCH 0228/6505] Update post_install.sh --- post_install.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/post_install.sh b/post_install.sh index d0251c8b..d18dae89 100644 --- a/post_install.sh +++ b/post_install.sh @@ -1,13 +1,14 @@ #!/usr/bin/env bash -echo -e "\e[1;33m This script will Disable the Enterprise Repo and Enable the No Subscription Repo *PVE7 ONLY*\e[0m" +echo -e "\e[1;33m This script will Disable the Enterprise Repo, Enable the No Subscription Repo, +Enable the Test Repo (repo's can be enabled/disabled in the UI "Repositories" and attempt the No Nag fix *PVE7 ONLY*\e[0m" read -p "Press [Enter] to start the PVE7 Post Install Script" -read -t 2 -p "Disabling Enterprise Repo..." +read -t 2 -p "Disabling Enterprise Repo ..." &>/dev/null sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list -read -t 2 -p "Enabling No Subscription Repo..." +read -t 2 -p "Enabling No Subscription Repo ..." &>/dev/null cat < /etc/apt/sources.list deb http://ftp.us.debian.org/debian bullseye main contrib deb http://ftp.us.debian.org/debian bullseye-updates main contrib @@ -16,9 +17,10 @@ deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF -# read -t 2 -p "Enabling No Nag ..." -# sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service +read -t 2 -p "Enabling No Nag ..." &>/dev/null +sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js -echo -e "\e[1;33m Finished, Please Update Proxmox \e[0m" +echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" +systemctl restart pveproxy.service # for the no-nag # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From 9e4885aae017e1ccc0f891af8d494b2dd1f95701 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:32:40 -0400 Subject: [PATCH 0229/6505] Update post_install.sh --- post_install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/post_install.sh b/post_install.sh index d18dae89..3001bb90 100644 --- a/post_install.sh +++ b/post_install.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash echo -e "\e[1;33m This script will Disable the Enterprise Repo, Enable the No Subscription Repo, -Enable the Test Repo (repo's can be enabled/disabled in the UI "Repositories" and attempt the No Nag fix *PVE7 ONLY*\e[0m" +Enable the Test Repo (repo's can be enabled/disabled in the UI "Repositories" and +attempt the No Nag fix *PVE7 ONLY*\e[0m" read -p "Press [Enter] to start the PVE7 Post Install Script" From 818bc50cc4582ba5886d77395681899cba8ce057 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:36:45 -0400 Subject: [PATCH 0230/6505] Update post_install.sh --- post_install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/post_install.sh b/post_install.sh index 3001bb90..9bf9802c 100644 --- a/post_install.sh +++ b/post_install.sh @@ -6,19 +6,16 @@ attempt the No Nag fix *PVE7 ONLY*\e[0m" read -p "Press [Enter] to start the PVE7 Post Install Script" -read -t 2 -p "Disabling Enterprise Repo ..." &>/dev/null sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list -read -t 2 -p "Enabling No Subscription Repo ..." &>/dev/null cat < /etc/apt/sources.list deb http://ftp.us.debian.org/debian bullseye main contrib deb http://ftp.us.debian.org/debian bullseye-updates main contrib deb http://security.debian.org bullseye-security main contrib deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription -# deb http://download.proxmox.com/debian/pve bullseye pvetest +deb http://download.proxmox.com/debian/pve bullseye pvetest EOF -read -t 2 -p "Enabling No Nag ..." &>/dev/null sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" From df829210d0e498ecdb82cd3bb0acace6d205d699 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:39:45 -0400 Subject: [PATCH 0231/6505] Update post_install.sh --- post_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post_install.sh b/post_install.sh index 9bf9802c..74de47ff 100644 --- a/post_install.sh +++ b/post_install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash echo -e "\e[1;33m This script will Disable the Enterprise Repo, Enable the No Subscription Repo, -Enable the Test Repo (repo's can be enabled/disabled in the UI "Repositories" and +Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories and attempt the No Nag fix *PVE7 ONLY*\e[0m" read -p "Press [Enter] to start the PVE7 Post Install Script" From 288f31001f8e2b67301de7b3b2c54e774971ccf4 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:40:55 -0400 Subject: [PATCH 0232/6505] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b6b9217b..76a4ec96 100644 --- a/README.md +++ b/README.md @@ -479,7 +479,8 @@ After the script completes, If you're dissatisfied with the default settings, cl

Proxmox PVE7 Post Install

-This script disables the Enterprise Repo and Enables the No Subscription Repo, run the following in the Proxmox web shell. +This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories and +attempt the No Nag fix *PVE7 ONLY*, run the following in the Proxmox web shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From d2dcb5a85a666a2953425dfa7b8f30eacd426e49 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:43:05 -0400 Subject: [PATCH 0233/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76a4ec96..e7838ae8 100644 --- a/README.md +++ b/README.md @@ -479,8 +479,8 @@ After the script completes, If you're dissatisfied with the default settings, cl

Proxmox PVE7 Post Install

-This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories and -attempt the No Nag fix *PVE7 ONLY*, run the following in the Proxmox web shell. +This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories) and +attempt the No Nag fix *PVE7 ONLY*, run the following in the Proxmox Web Shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From 438bdd77973586b51c2397c88f83feeabade77a7 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:46:55 -0400 Subject: [PATCH 0234/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7838ae8..19b31b1b 100644 --- a/README.md +++ b/README.md @@ -480,7 +480,7 @@ After the script completes, If you're dissatisfied with the default settings, cl

Proxmox PVE7 Post Install

This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories) and -attempt the No Nag fix *PVE7 ONLY*, run the following in the Proxmox Web Shell. +attempt the No Nag fix, run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From 43b81b5840b754c353fb2955345d4836ddf5e2b6 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:49:07 -0400 Subject: [PATCH 0235/6505] Update post_install.sh --- post_install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/post_install.sh b/post_install.sh index 74de47ff..4249fb8f 100644 --- a/post_install.sh +++ b/post_install.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash echo -e "\e[1;33m This script will Disable the Enterprise Repo, Enable the No Subscription Repo, -Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories and -attempt the No Nag fix *PVE7 ONLY*\e[0m" +Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt +the No Nag fix *PVE7 ONLY*\e[0m" read -p "Press [Enter] to start the PVE7 Post Install Script" From d6c34d72104b738464b7eeb481f4851439e9e3eb Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:55:11 -0400 Subject: [PATCH 0236/6505] Update post_install.sh --- post_install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/post_install.sh b/post_install.sh index 4249fb8f..0a02df7b 100644 --- a/post_install.sh +++ b/post_install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash echo -e "\e[1;33m This script will Disable the Enterprise Repo, Enable the No Subscription Repo, -Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt +Add (Disabled) Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt the No Nag fix *PVE7 ONLY*\e[0m" read -p "Press [Enter] to start the PVE7 Post Install Script" @@ -13,7 +13,7 @@ deb http://ftp.us.debian.org/debian bullseye main contrib deb http://ftp.us.debian.org/debian bullseye-updates main contrib deb http://security.debian.org bullseye-security main contrib deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription -deb http://download.proxmox.com/debian/pve bullseye pvetest +# deb http://download.proxmox.com/debian/pve bullseye pvetest EOF sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js From f681667742985331242b28fdb1df94ddb953ddad Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:56:11 -0400 Subject: [PATCH 0237/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 19b31b1b..9746140b 100644 --- a/README.md +++ b/README.md @@ -479,8 +479,8 @@ After the script completes, If you're dissatisfied with the default settings, cl

Proxmox PVE7 Post Install

-This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Enable the Test Repo (repo's can be enabled/disabled via the UI in Repositories) and -attempt the No Nag fix, run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* +This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Add (Disabled) Test Repo (repo's can be enabled/disabled via the UI in Repositories) and +attempt the *No-Nag* fix, run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From d39084c283d7cd3548f2b5ab05be8cd73bd59fa6 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 12:58:29 -0400 Subject: [PATCH 0238/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9746140b..f4073edb 100644 --- a/README.md +++ b/README.md @@ -480,7 +480,9 @@ After the script completes, If you're dissatisfied with the default settings, cl

Proxmox PVE7 Post Install

This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Add (Disabled) Test Repo (repo's can be enabled/disabled via the UI in Repositories) and -attempt the *No-Nag* fix, run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* +attempt the *No-Nag* fix. + +Run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From bba19ef8a17e3d53423a3fcaee2cb0593e724baa Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 13:07:09 -0400 Subject: [PATCH 0239/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f4073edb..f8a29b72 100644 --- a/README.md +++ b/README.md @@ -479,8 +479,8 @@ After the script completes, If you're dissatisfied with the default settings, cl

Proxmox PVE7 Post Install

-This script will Disable the Enterprise Repo, Enable the No Subscription Repo, Add (Disabled) Test Repo (repo's can be enabled/disabled via the UI in Repositories) and -attempt the *No-Nag* fix. +This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) +and attempt the *No-Nag* fix. Run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* From 39c82bf4d0e7ae7b7b8bec8475230ac4b1c53dc8 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 13:10:27 -0400 Subject: [PATCH 0240/6505] Update post_install.sh --- post_install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/post_install.sh b/post_install.sh index 0a02df7b..bd984aa7 100644 --- a/post_install.sh +++ b/post_install.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -echo -e "\e[1;33m This script will Disable the Enterprise Repo, Enable the No Subscription Repo, -Add (Disabled) Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt -the No Nag fix *PVE7 ONLY*\e[0m" +echo -e "\e[1;33m This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, +Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) +and attempt the No-Nag fix. PVE7 ONLY \e[0m" read -p "Press [Enter] to start the PVE7 Post Install Script" From 7cec55f8cc32af470eb653e8ffeed3ab67544e5c Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 13:24:20 -0400 Subject: [PATCH 0241/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8a29b72..914d6333 100644 --- a/README.md +++ b/README.md @@ -488,6 +488,6 @@ Run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" ``` -I recommend updating Proxmox after running this script, before adding any VM/CT. +It's recommended to update Proxmox after running this script, before adding any VM/CT. From b91f60d1db39ac873a5a3d2a408aa44345e2d24d Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 13:29:22 -0400 Subject: [PATCH 0242/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 914d6333..7b1d0447 100644 --- a/README.md +++ b/README.md @@ -475,7 +475,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
-PVE7 Post Install +Proxmox PVE7 Post Install

Proxmox PVE7 Post Install

From ec74160386c94ebf2082651281f8676b50a1c601 Mon Sep 17 00:00:00 2001 From: tteck Date: Mon, 27 Sep 2021 13:30:46 -0400 Subject: [PATCH 0243/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7b1d0447..a7e93945 100644 --- a/README.md +++ b/README.md @@ -475,9 +475,9 @@ After the script completes, If you're dissatisfied with the default settings, cl
-Proxmox PVE7 Post Install +Proxmox VE 7 Post Install -

Proxmox PVE7 Post Install

+

Proxmox VE 7 Post Install

This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt the *No-Nag* fix. From ff5379198b8c8f1f4581b34f42080b02902f79a4 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 17:27:59 -0400 Subject: [PATCH 0244/6505] Update post_install.sh --- post_install.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/post_install.sh b/post_install.sh index bd984aa7..2faeca86 100644 --- a/post_install.sh +++ b/post_install.sh @@ -4,7 +4,14 @@ echo -e "\e[1;33m This script will Disable the Enterprise Repo, Add & Enable the Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt the No-Nag fix. PVE7 ONLY \e[0m" -read -p "Press [Enter] to start the PVE7 Post Install Script" +while true; do + read -p "Start the PVE7 Post Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list From 70c4661e1c244f7c1951dab6d09bbf944e4505fe Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 17:45:16 -0400 Subject: [PATCH 0245/6505] Update esphome_container.sh --- esphome_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/esphome_container.sh b/esphome_container.sh index 72be2a5c..c4f71d93 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a new Proxmox ESPHome LXC Container, continue(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From 0e311272721518ea2a439aee4c48a6fdaa5f27bd Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 17:50:01 -0400 Subject: [PATCH 0246/6505] Update esphome_container.sh --- esphome_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_container.sh b/esphome_container.sh index c4f71d93..dc471385 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "This will create a new Proxmox ESPHome LXC Container, continue(y/n)?" yn + read -p "This will create a New Proxmox ESPHome LXC Container. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From ecdd875ffda74db366f124a183cb04a1a5b803e2 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 17:55:30 -0400 Subject: [PATCH 0247/6505] Update haos_vm.sh --- haos_vm.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/haos_vm.sh b/haos_vm.sh index ded12c19..f74d5752 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Proxmox Home Assistant OS VM. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From 30a6065626ab0f31df831a798cd18ac9a6445a77 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:01:13 -0400 Subject: [PATCH 0248/6505] Update esphome_container.sh --- esphome_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_container.sh b/esphome_container.sh index dc471385..2796790b 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "This will create a New Proxmox ESPHome LXC Container. Proceed(y/n)?" yn + read -p "This will create a New ESPHome LXC Container. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From 324fff10b5371f5f4422951241aa13ab97444065 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:01:41 -0400 Subject: [PATCH 0249/6505] Update haos_vm.sh --- haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haos_vm.sh b/haos_vm.sh index f74d5752..c61e2dfa 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "This will create a New Proxmox Home Assistant OS VM. Proceed(y/n)?" yn + read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From da669f2751f8519095b63b1f932c0cab7b0857a3 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:04:26 -0400 Subject: [PATCH 0250/6505] Update mariadb_container.sh --- mariadb_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mariadb_container.sh b/mariadb_container.sh index 461ae3df..01fc2ae9 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Mariadb LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From b00078ce76b81b5063eb5b29d02eb6fa4718dd8e Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:05:30 -0400 Subject: [PATCH 0251/6505] Update mqtt_container.sh --- mqtt_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mqtt_container.sh b/mqtt_container.sh index b42668be..ccaf4aaf 100644 --- a/mqtt_container.sh +++ b/mqtt_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New MQTT LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From d930d3911625a15121fc11d813d9368cafcc2fce Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:06:11 -0400 Subject: [PATCH 0252/6505] Update node-red_container.sh --- node-red_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/node-red_container.sh b/node-red_container.sh index 5c614f4a..b94a29b5 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Node-Red LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From 22d85660d13eb0109ef159a16262e8cb03e3b714 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:07:35 -0400 Subject: [PATCH 0253/6505] Update pve6_ha_container.sh --- pve6_ha_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pve6_ha_container.sh b/pve6_ha_container.sh index ca2f6f87..878331f6 100644 --- a/pve6_ha_container.sh +++ b/pve6_ha_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Home Assistant LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From a03e626a3aad1a867f32f66efa8da86d01fa07bd Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:08:24 -0400 Subject: [PATCH 0254/6505] Update pve6_zigbee2mqtt_container.sh --- pve6_zigbee2mqtt_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pve6_zigbee2mqtt_container.sh b/pve6_zigbee2mqtt_container.sh index 23af1ac6..e7580af8 100644 --- a/pve6_zigbee2mqtt_container.sh +++ b/pve6_zigbee2mqtt_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Zigbee2MQTT LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From 96d4c4faee9d465bc2d82c0bc87bb8266a525972 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:09:11 -0400 Subject: [PATCH 0255/6505] Update pve7_ha_container.sh --- pve7_ha_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pve7_ha_container.sh b/pve7_ha_container.sh index 8c5963e1..d705c9a9 100644 --- a/pve7_ha_container.sh +++ b/pve7_ha_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Home Assistant LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From e28186411c12c51bc3a99ca2d31b2a9fd7df52a9 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:10:00 -0400 Subject: [PATCH 0256/6505] Update pve7_zigbee2mqtt_container.sh --- pve7_zigbee2mqtt_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pve7_zigbee2mqtt_container.sh b/pve7_zigbee2mqtt_container.sh index 224b8aed..0b88b7bc 100644 --- a/pve7_zigbee2mqtt_container.sh +++ b/pve7_zigbee2mqtt_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Zigbee2MQTT LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From c7b4f5c197236d0110c6ed117d760bab419a3a00 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:10:59 -0400 Subject: [PATCH 0257/6505] Update debian10_container.sh --- debian10_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/debian10_container.sh b/debian10_container.sh index 8925c6c6..a0c5a22e 100644 --- a/debian10_container.sh +++ b/debian10_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Debian 10+ LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell From 1c6be12c0fe3b57c1c9d7327623dabe0f72f0c04 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:11:42 -0400 Subject: [PATCH 0258/6505] Update debian11_container.sh --- debian11_container.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/debian11_container.sh b/debian11_container.sh index 01d47601..9178e8f7 100644 --- a/debian11_container.sh +++ b/debian11_container.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash +while true; do + read -p "This will create a New Debian 11+ LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell @@ -156,4 +165,4 @@ pct exec $CTID /debian11_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Debian 11 LXC Container to $CTID at IP Address ${IP}" \ No newline at end of file +info "Successfully created a Debian 11 LXC Container to $CTID at IP Address ${IP}" From 868e9438783015da30c59b2e4eac8854dcc3ce18 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 28 Sep 2021 18:17:53 -0400 Subject: [PATCH 0259/6505] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a7e93945..7fd384c1 100644 --- a/README.md +++ b/README.md @@ -308,7 +308,7 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m
PVE6 Zigbee2MQTT LXC -

Proxmox PVE6 Zigbee2MQTT LXC Container

+

Proxmox 6 Zigbee2MQTT LXC Container

To create a new Proxmox 6 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. @@ -373,7 +373,7 @@ To update Zigbee2Mqtt
PVE7 Zigbee2MQTT LXC -

Proxmox PVE7 Zigbee2MQTT LXC Container

+

Proxmox 7 Zigbee2MQTT LXC Container

To create a new Proxmox 7 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. @@ -436,7 +436,7 @@ To start Zigbee2MQTT automatically on boot
-Base Debian 10 LXC +Base Debian 10+ LXC

Proxmox Debian 10 LXC Container

@@ -455,7 +455,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
-Base Debian 11 LXC +Base Debian 11+ LXC

Proxmox Debian 11 LXC Container

From f1ed1f78cc32872bfd1a888d6c7883c0d7e9e420 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 09:52:01 -0400 Subject: [PATCH 0260/6505] Add files via upload --- pihole_container.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++ pihole_setup.sh | 58 ++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 pihole_container.sh create mode 100644 pihole_setup.sh diff --git a/pihole_container.sh b/pihole_container.sh new file mode 100644 index 00000000..b6dcee6d --- /dev/null +++ b/pihole_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Pi-hole LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "LXC ID is $CTID." + +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +msg "Creating LXC..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=pi-hole +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +msg "Starting LXC..." +pct start $CTID +pct push $CTID pihole_setup.sh /pihole_setup.sh -perms 755 +pct exec $CTID /pihole_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Pi-hole LXC to $CTID at IP Address ${IP}" diff --git a/pihole_setup.sh b/pihole_setup.sh new file mode 100644 index 00000000..0acf4375 --- /dev/null +++ b/pihole_setup.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up LXC OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating LXC OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing Pi-hole.." +curl -sSL https://install.pi-hole.net | bash + +msg "Customizing LXC..." +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /pihole_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 55f1adf51d97b8a412126a776b3f908454c44fe3 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 09:58:31 -0400 Subject: [PATCH 0261/6505] Update pihole_setup.sh --- pihole_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pihole_setup.sh b/pihole_setup.sh index 0acf4375..ff0dcc39 100644 --- a/pihole_setup.sh +++ b/pihole_setup.sh @@ -42,7 +42,7 @@ curl -sSL https://install.pi-hole.net | bash msg "Customizing LXC..." rm /etc/motd -rm /etc/update-motd.d/10-uname +rm /etc/update-motd.d/11-uname touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -55,4 +55,4 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg "Cleanup..." -rm -rf /pihole_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /pihole_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 87056049b5f3d8cc26a2634af48cbbcdeb90c29b Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:08:05 -0400 Subject: [PATCH 0262/6505] Update pihole_setup.sh --- pihole_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pihole_setup.sh b/pihole_setup.sh index ff0dcc39..655f6979 100644 --- a/pihole_setup.sh +++ b/pihole_setup.sh @@ -29,7 +29,7 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null msg "Updating LXC OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." @@ -42,7 +42,7 @@ curl -sSL https://install.pi-hole.net | bash msg "Customizing LXC..." rm /etc/motd -rm /etc/update-motd.d/11-uname +rm /etc/update-motd.d/10-uname touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) From a88775c1a4ae0e52eb57adfde1bae00650d05c3c Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:18:48 -0400 Subject: [PATCH 0263/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index bb5d6bd5..65f2ebd5 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 26dfd2fd93b74e2bc4d90ce05c3bf1e70466d1c1 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:19:14 -0400 Subject: [PATCH 0264/6505] Update esphome_setup.sh --- esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index edfed5de..77efcd7d 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 3d33c6ae9d02cca1f5dd7a0f6d379c45ed96ff5e Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:19:44 -0400 Subject: [PATCH 0265/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index 4e1091a0..8a022f42 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 686f84964a76889d0e21a7e929a53a1b603b2127 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:20:12 -0400 Subject: [PATCH 0266/6505] Update mqtt_setup.sh --- mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_setup.sh b/mqtt_setup.sh index f62a89b9..374ea8c9 100644 --- a/mqtt_setup.sh +++ b/mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 33f65d35803d7ea309f3f30def976374511e72f5 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:20:44 -0400 Subject: [PATCH 0267/6505] Update node-red_setup.sh --- node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index fec60e5d..7b4e667e 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From fa4deb086c6c273c51d7fb618a1c8df10c63921d Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:21:22 -0400 Subject: [PATCH 0268/6505] Update pve6_ha_setup.sh --- pve6_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh index 4059cf8c..150d7fde 100644 --- a/pve6_ha_setup.sh +++ b/pve6_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 64717169ffabdefc33263a399d7c91a7cc6163cf Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:21:56 -0400 Subject: [PATCH 0269/6505] Update pve6_zigbee2mqtt_setup.sh --- pve6_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh index 12695147..9bd39c8f 100644 --- a/pve6_zigbee2mqtt_setup.sh +++ b/pve6_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From b73e4ec90de5bb6d144000e2f9a6420217185470 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:22:27 -0400 Subject: [PATCH 0270/6505] Update pve7_ha_setup.sh --- pve7_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_setup.sh b/pve7_ha_setup.sh index eb78d8b4..9b5d835b 100644 --- a/pve7_ha_setup.sh +++ b/pve7_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From ce2f4e52ffc36f3352992df7a23e2f3ef180131a Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:23:01 -0400 Subject: [PATCH 0271/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index ca7264bd..e5b83668 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +apt-get dist-upgrade >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From b784a7efc7e1003dc3e3f9cccdb9e6bbd609742e Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 10:38:05 -0400 Subject: [PATCH 0272/6505] Update pihole_container.sh --- pihole_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole_container.sh b/pihole_container.sh index b6dcee6d..874bd76c 100644 --- a/pihole_container.sh +++ b/pihole_container.sh @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=pi-hole TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 3ecfce7da68f5793cf202a76815957bfa2088126 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 30 Sep 2021 13:12:34 -0400 Subject: [PATCH 0273/6505] Update README.md --- README.md | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7fd384c1..d62b5279 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,26 @@

Select a Proxmox Helper Below

+ +
+ + +
+Proxmox VE 7 Post Install + +

Proxmox VE 7 Post Install

+ +This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) +and attempt the *No-Nag* fix. + +Run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" +``` + +It's recommended to update Proxmox after running this script, before adding any VM/CT. + +
+
@@ -470,24 +492,26 @@ After the script completes, If you're dissatisfied with the default settings, cl
-
-Proxmox VE 7 Post Install +Pi-hole LXC -

Proxmox VE 7 Post Install

+

Pi-hole LXC

-This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) -and attempt the *No-Nag* fix. +To create a new Proxmox Pi-hole LXC, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_container.sh)" +``` +

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

-Run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* +To set your password (Run in the pi-hole console) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" +pihole -a -p ``` -It's recommended to update Proxmox after running this script, before adding any VM/CT. -
+ From fe71fa8fc87a7495ee1e99a706550659dfcceab2 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 12:53:57 -0400 Subject: [PATCH 0274/6505] Add files via upload --- plex_container.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++++ plex_setup.sh | 62 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 plex_container.sh create mode 100644 plex_setup.sh diff --git a/plex_container.sh b/plex_container.sh new file mode 100644 index 00000000..66be7d85 --- /dev/null +++ b/plex_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Plex Server LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/plex_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "LXC ID is $CTID." + +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +msg "Creating LXC..." +DISK_SIZE=20G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=plex +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +msg "Starting LXC..." +pct start $CTID +pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 +pct exec $CTID /plex_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Plex Server LXC to $CTID at IP Address ${IP}" diff --git a/plex_setup.sh b/plex_setup.sh new file mode 100644 index 00000000..8c3e214a --- /dev/null +++ b/plex_setup.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up LXC OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating LXC OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing Plex Server.." +echo deb https://downloads.plex.tv/repo/deb public main | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null +curl https://downloads.plex.tv/plex-keys/PlexSign.key | apt-key add - &>/dev/null +apt-get update &>/dev/null +apt-get install plexmediaserver &>/dev/null +apt-get upgrade &>/dev/null + +msg "Customizing LXC..." +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From b6899356075d66a6e417f8dfb85a253ae9e90baf Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 13:05:31 -0400 Subject: [PATCH 0275/6505] Update plex_setup.sh --- plex_setup.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plex_setup.sh b/plex_setup.sh index 8c3e214a..3ee70c3e 100644 --- a/plex_setup.sh +++ b/plex_setup.sh @@ -30,7 +30,7 @@ apt-get autoremove >/dev/null msg "Updating LXC OS..." apt-get update >/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get dist-upgrade &>/dev/null msg "Installing Prerequisites..." apt-get -qqy install \ @@ -38,11 +38,11 @@ apt-get -qqy install \ sudo &>/dev/null msg "Installing Plex Server.." -echo deb https://downloads.plex.tv/repo/deb public main | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null -curl https://downloads.plex.tv/plex-keys/PlexSign.key | apt-key add - &>/dev/null +deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null +curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo apt-key add - &>/dev/null apt-get update &>/dev/null apt-get install plexmediaserver &>/dev/null -apt-get upgrade &>/dev/null +apt-get dist-upgrade &>/dev/null msg "Customizing LXC..." rm /etc/motd @@ -59,4 +59,4 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg "Cleanup..." -rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 65ba63a2be49b0706bae04f3b443fb8f10121b48 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 13:24:16 -0400 Subject: [PATCH 0276/6505] Update plex_setup.sh --- plex_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plex_setup.sh b/plex_setup.sh index 3ee70c3e..40ec7097 100644 --- a/plex_setup.sh +++ b/plex_setup.sh @@ -30,7 +30,7 @@ apt-get autoremove >/dev/null msg "Updating LXC OS..." apt-get update >/dev/null -apt-get dist-upgrade &>/dev/null +apt-get upgrade &>/dev/null msg "Installing Prerequisites..." apt-get -qqy install \ @@ -42,7 +42,7 @@ deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.l curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo apt-key add - &>/dev/null apt-get update &>/dev/null apt-get install plexmediaserver &>/dev/null -apt-get dist-upgrade &>/dev/null +apt-get upgrade &>/dev/null msg "Customizing LXC..." rm /etc/motd From c3ae0fdc251b91b81b0c91a4944b5d7c82e2a128 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 13:38:26 -0400 Subject: [PATCH 0277/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 65f2ebd5..bb5d6bd5 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From f382ae0e643fde02ab70c5aaf69ae571ef81480e Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 13:43:17 -0400 Subject: [PATCH 0278/6505] Update debian11_setup.sh --- debian11_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index bb5d6bd5..08a08704 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -31,9 +31,9 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -msg "Updating container OS..." -apt-get update >/dev/null -apt-get -qqy upgrade &>/dev/null +#msg "Updating container OS..." +#apt-get update >/dev/null +#apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 8e7f90d347f4245322efe2ad0ca66d9c53cfffc4 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 13:51:35 -0400 Subject: [PATCH 0279/6505] Delete plex_setup.sh --- plex_setup.sh | 62 --------------------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 plex_setup.sh diff --git a/plex_setup.sh b/plex_setup.sh deleted file mode 100644 index 40ec7097..00000000 --- a/plex_setup.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -msg "Setting up LXC OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -msg "Updating LXC OS..." -apt-get update >/dev/null -apt-get upgrade &>/dev/null - -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -msg "Installing Plex Server.." -deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null -curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo apt-key add - &>/dev/null -apt-get update &>/dev/null -apt-get install plexmediaserver &>/dev/null -apt-get upgrade &>/dev/null - -msg "Customizing LXC..." -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -msg "Cleanup..." -rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 2206627af7025427d760ad76366a5f896d42d008 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 13:51:55 -0400 Subject: [PATCH 0280/6505] Delete plex_container.sh --- plex_container.sh | 157 ---------------------------------------------- 1 file changed, 157 deletions(-) delete mode 100644 plex_container.sh diff --git a/plex_container.sh b/plex_container.sh deleted file mode 100644 index 66be7d85..00000000 --- a/plex_container.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Plex Server LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/plex_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "LXC ID is $CTID." - -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -msg "Creating LXC..." -DISK_SIZE=20G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=plex -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -msg "Starting LXC..." -pct start $CTID -pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 -pct exec $CTID /plex_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Plex Server LXC to $CTID at IP Address ${IP}" From cb3dec513c47de1e805649a3b634c0c80ee29195 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 14:24:35 -0400 Subject: [PATCH 0281/6505] Update debian11_setup.sh --- debian11_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 08a08704..bb5d6bd5 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -31,9 +31,9 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -#msg "Updating container OS..." -#apt-get update >/dev/null -#apt-get -qqy upgrade &>/dev/null +msg "Updating container OS..." +apt-get update >/dev/null +apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 4cf9b64f7a52edc496b8fd1436cb06230ea4c117 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 14:31:11 -0400 Subject: [PATCH 0282/6505] Update debian11_setup.sh --- debian11_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index bb5d6bd5..f6f181b2 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,8 +32,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null -apt-get -qqy upgrade &>/dev/null +apt update >/dev/null +apt upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From e9a5f3c26d6de23fb46c5f5eb407c7595c808465 Mon Sep 17 00:00:00 2001 From: tteck Date: Tue, 5 Oct 2021 14:46:09 -0400 Subject: [PATCH 0283/6505] Update debian11_setup.sh --- debian11_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index f6f181b2..ba521d4f 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,8 +32,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt update >/dev/null -apt upgrade &>/dev/null +apt-get update >/dev/null +apt-get upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From ba8172121976aa9d2a1ad0362a22875d3f8e75b4 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:14:45 -0400 Subject: [PATCH 0284/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index ba521d4f..8e39990c 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt update --allow-releaseinfo-change >/dev/null apt-get upgrade &>/dev/null # Install prerequisites From 43a66920347440804e0ebc409569df24fd4cc9f8 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:21:07 -0400 Subject: [PATCH 0285/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 8e39990c..eea7b308 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt update --allow-releaseinfo-change >/dev/null +apt-get --allow-releaseinfo-change update >/dev/null apt-get upgrade &>/dev/null # Install prerequisites From 72f2c4fd1d6a167e0e8121b1f96342c306bea522 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:38:32 -0400 Subject: [PATCH 0286/6505] Update esphome_setup.sh --- esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index 77efcd7d..edfed5de 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From d0a26255d1290eb223e8078ac0e7faef85dd0809 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:39:02 -0400 Subject: [PATCH 0287/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index 8a022f42..4e1091a0 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 10e34664e95a45dda98e14eabe19f0dc969c06b4 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:39:34 -0400 Subject: [PATCH 0288/6505] Update mqtt_setup.sh --- mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_setup.sh b/mqtt_setup.sh index 374ea8c9..f62a89b9 100644 --- a/mqtt_setup.sh +++ b/mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 2574216f716a03342026b011b04363ce768754e1 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:40:06 -0400 Subject: [PATCH 0289/6505] Update node-red_setup.sh --- node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index 7b4e667e..fec60e5d 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 2e3ff88ddeb257a46fc6c72181e40c8a92d7f2be Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:40:43 -0400 Subject: [PATCH 0290/6505] Update pihole_setup.sh --- pihole_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole_setup.sh b/pihole_setup.sh index 655f6979..9a442587 100644 --- a/pihole_setup.sh +++ b/pihole_setup.sh @@ -29,7 +29,7 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null msg "Updating LXC OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." From 3f66670807ab4206c0751ce1cc5b2dbe5d562b07 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:41:16 -0400 Subject: [PATCH 0291/6505] Update pve6_ha_setup.sh --- pve6_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh index 150d7fde..4059cf8c 100644 --- a/pve6_ha_setup.sh +++ b/pve6_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 4bb02fc9ce48292b5f440a58445f1aa9a220d968 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:42:00 -0400 Subject: [PATCH 0292/6505] Update pve6_zigbee2mqtt_setup.sh --- pve6_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh index 9bd39c8f..12695147 100644 --- a/pve6_zigbee2mqtt_setup.sh +++ b/pve6_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 4df48b679792f3dbcf40a2706a12a9247161efe5 Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:42:30 -0400 Subject: [PATCH 0293/6505] Update pve7_ha_setup.sh --- pve7_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_setup.sh b/pve7_ha_setup.sh index 9b5d835b..eb78d8b4 100644 --- a/pve7_ha_setup.sh +++ b/pve7_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 2c85b07fab72b5f1aa0b312903e273e180623bdf Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 07:43:00 -0400 Subject: [PATCH 0294/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index e5b83668..ca7264bd 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get dist-upgrade >/dev/null +apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 69368b28a12c5906f293b2fa7fe73c3cced9ec9b Mon Sep 17 00:00:00 2001 From: tteck Date: Thu, 7 Oct 2021 09:12:55 -0400 Subject: [PATCH 0295/6505] Update post_install.sh --- post_install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/post_install.sh b/post_install.sh index 2faeca86..aa150b42 100644 --- a/post_install.sh +++ b/post_install.sh @@ -16,9 +16,9 @@ done sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list cat < /etc/apt/sources.list -deb http://ftp.us.debian.org/debian bullseye main contrib -deb http://ftp.us.debian.org/debian bullseye-updates main contrib -deb http://security.debian.org bullseye-security main contrib +deb http://ftp.debian.org/debian bullseye main contrib +deb http://ftp.debian.org/debian bullseye-updates main contrib +deb http://security.debian.org/debian-security bullseye-security main contrib deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF From 7dc24e287f35f27aff99c6bac9127e5307bcb3b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 14:04:37 -0400 Subject: [PATCH 0296/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index eea7b308..ba3ca8c3 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null +#apt-get --allow-releaseinfo-change update >/dev/null apt-get upgrade &>/dev/null # Install prerequisites From 8249b700697c400f8c2d22daebc7ed46a8cd525d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 15:47:58 -0400 Subject: [PATCH 0297/6505] Update debian11_container.sh --- debian11_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian11_container.sh b/debian11_container.sh index 9178e8f7..6bf952db 100644 --- a/debian11_container.sh +++ b/debian11_container.sh @@ -153,9 +153,9 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT +#MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +#ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +#pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." From fa89871c60caf395d3a1a9ab2337a0e946641d51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 15:49:59 -0400 Subject: [PATCH 0298/6505] Update debian11_setup.sh --- debian11_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index ba3ca8c3..f64752cc 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -#apt-get --allow-releaseinfo-change update >/dev/null +apt-get update >/dev/null apt-get upgrade &>/dev/null # Install prerequisites @@ -68,4 +68,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /debian11_setup.sh /var/{cache,log}/* #/var/lib/apt/lists/* From 1f2a81c06b1a555ef530e118c161320fc76791fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 16:04:20 -0400 Subject: [PATCH 0299/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index f64752cc..cc2f046e 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt-get update -y &>/dev/null apt-get upgrade &>/dev/null # Install prerequisites From 3ace8c6453cc267d4edfc5867e4c263be69003f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 16:07:13 -0400 Subject: [PATCH 0300/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index cc2f046e..31b34571 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -68,4 +68,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /debian11_setup.sh /var/{cache,log}/* #/var/lib/apt/lists/* +rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 6e5a9861472593da9b91ea4abd1b5fdd8568c180 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 16:45:09 -0400 Subject: [PATCH 0301/6505] Update debian11_container.sh --- debian11_container.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/debian11_container.sh b/debian11_container.sh index 6bf952db..5c1717de 100644 --- a/debian11_container.sh +++ b/debian11_container.sh @@ -13,7 +13,7 @@ done set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +#set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -110,7 +110,7 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template +# Download latest Debian 11 LXC template msg "Updating LXC template list..." pveam update >/dev/null msg "Downloading LXC template..." @@ -153,9 +153,9 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Set container timezone to match host -#MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -#ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -#pct unmount $CTID && unset MOUNT +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." From ea043702e96aa8f516f98e84c58839121ffba464 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 16:47:48 -0400 Subject: [PATCH 0302/6505] Update debian11_setup.sh --- debian11_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 31b34571..45560d4f 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -2,9 +2,9 @@ # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +#set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +#set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR From 8684a5cdf9e114dbb5df742d03bd315409bb87cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:00:35 -0400 Subject: [PATCH 0303/6505] Update debian11_setup.sh --- debian11_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 45560d4f..ad58832c 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -2,9 +2,9 @@ # Setup script environment set -o errexit #Exit immediately if a pipeline returns a non-zero status -#set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error -#set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update -y &>/dev/null +apt-get update || true >/dev/null apt-get upgrade &>/dev/null # Install prerequisites From e95e2feb1d8a679a9283a8385ead9f47e2f21c72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:01:09 -0400 Subject: [PATCH 0304/6505] Update debian11_container.sh --- debian11_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_container.sh b/debian11_container.sh index 5c1717de..6ebc5687 100644 --- a/debian11_container.sh +++ b/debian11_container.sh @@ -13,7 +13,7 @@ done set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error -#set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR From cc4fb2698fcca49f78a74748c13213dd1f10898c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:08:10 -0400 Subject: [PATCH 0305/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index ad58832c..f726b708 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update || true >/dev/null +apt-get update --allow-releaseinfo-change || true >/dev/null apt-get upgrade &>/dev/null # Install prerequisites From dfd7a3ae00de0a3e4390d3c95331611d6be83cee Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:27:00 -0400 Subject: [PATCH 0306/6505] Update debian11_setup.sh --- debian11_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index f726b708..6f177c4f 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,8 +32,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update --allow-releaseinfo-change || true >/dev/null -apt-get upgrade &>/dev/null +apt-get qqy update --allow-releaseinfo-change && apt-get qqy full-upgrade &>/dev/null +#apt-get upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 9f40c2dbe870b978a64640b2f09b88eafeb92119 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:30:14 -0400 Subject: [PATCH 0307/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 6f177c4f..20681a7b 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get qqy update --allow-releaseinfo-change && apt-get qqy full-upgrade &>/dev/null +apt-get update --allow-releaseinfo-change && apt-get qqy full-upgrade &>/dev/null #apt-get upgrade &>/dev/null # Install prerequisites From 9fec1c996fdb98c13f6021acb0798ce472ad0eef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:35:26 -0400 Subject: [PATCH 0308/6505] Update debian11_setup.sh --- debian11_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 20681a7b..8c36fbc0 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,8 +32,8 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update --allow-releaseinfo-change && apt-get qqy full-upgrade &>/dev/null -#apt-get upgrade &>/dev/null +apt-get update --allow-releaseinfo-change &>/dev/null +apt-get apt-get full-upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 343dd6548cb95cff141786b4757595ae5ce99fac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:39:10 -0400 Subject: [PATCH 0309/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 8c36fbc0..ec616da9 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -33,7 +33,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." apt-get update --allow-releaseinfo-change &>/dev/null -apt-get apt-get full-upgrade &>/dev/null +apt-get full-upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From b4edc3c1be34ae7703f3f9e8e646bc814d1c0a0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:43:09 -0400 Subject: [PATCH 0310/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index ec616da9..ebf3bbb4 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -33,7 +33,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." apt-get update --allow-releaseinfo-change &>/dev/null -apt-get full-upgrade &>/dev/null +apt-get upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 39d37a9adec8348dd769f14850b5eb6488059e0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:50:54 -0400 Subject: [PATCH 0311/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index ca7264bd..2c5af974 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +#apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 73b2452a99bfa6c1eaebd3c8563adc41cc47f107 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:51:31 -0400 Subject: [PATCH 0312/6505] Update pve7_ha_setup.sh --- pve7_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_setup.sh b/pve7_ha_setup.sh index eb78d8b4..cd2af108 100644 --- a/pve7_ha_setup.sh +++ b/pve7_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +#apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From ccff384e2aab441005b259bd67616c9f2b297768 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:52:21 -0400 Subject: [PATCH 0313/6505] Update pihole_setup.sh --- pihole_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole_setup.sh b/pihole_setup.sh index 9a442587..c2c3abe2 100644 --- a/pihole_setup.sh +++ b/pihole_setup.sh @@ -29,7 +29,7 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null msg "Updating LXC OS..." -apt-get update >/dev/null +#apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." From ee4ce898e69fbe238a659f796ef8f2a2d9f441b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:52:51 -0400 Subject: [PATCH 0314/6505] Update node-red_setup.sh --- node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index fec60e5d..7e6ed9ab 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +#apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From f088053b4143cdaef4049a781edc5f7b9298db11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:53:23 -0400 Subject: [PATCH 0315/6505] Update mqtt_setup.sh --- mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_setup.sh b/mqtt_setup.sh index f62a89b9..f06ee72c 100644 --- a/mqtt_setup.sh +++ b/mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +#apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 83f2b219b5ab490f9c80cd8da891e7f0cdd7199a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:53:58 -0400 Subject: [PATCH 0316/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index 4e1091a0..b0f501d6 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +#apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From b4c25a85845f6959b4b5a08957bdb5328aad326b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:54:34 -0400 Subject: [PATCH 0317/6505] Update esphome_setup.sh --- esphome_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index edfed5de..b748d3eb 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." -apt-get update >/dev/null +#apt-get update >/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From a136796704bbd329de0d685b4ef05d94e0ac3372 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 17:55:03 -0400 Subject: [PATCH 0318/6505] Update debian11_setup.sh --- debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index ebf3bbb4..86b20a4f 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update --allow-releaseinfo-change &>/dev/null +#apt-get update --allow-releaseinfo-change &>/dev/null apt-get upgrade &>/dev/null # Install prerequisites From 531814eef06b601ca09cf680ab7e91ffa351baee Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 22:47:29 -0400 Subject: [PATCH 0319/6505] Update debian11_setup.sh --- debian11_setup.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index 86b20a4f..df2a3e1e 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -31,9 +31,9 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -msg "Updating container OS..." +#msg "Updating container OS..." #apt-get update --allow-releaseinfo-change &>/dev/null -apt-get upgrade &>/dev/null +#apt-get upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." @@ -43,13 +43,13 @@ apt-get -qqy install \ # Customize Docker configuration # msg "Customizing Docker..." -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF +#DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +#mkdir -p $(dirname $DOCKER_CONFIG_PATH) +#cat >$DOCKER_CONFIG_PATH <<'EOF' +#{ +# "log-driver": "journald" +#} +#EOF # Customize container msg "Customizing container..." @@ -66,6 +66,11 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +# Update container OS +msg "Updating container OS..." +apt-get update >/dev/null +apt-get upgrade &>/dev/null + # Cleanup container msg "Cleanup..." rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c7c9e6a1823363a81c0b741c9fc8beed59c13741 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Oct 2021 22:52:28 -0400 Subject: [PATCH 0320/6505] Update debian11_setup.sh --- debian11_setup.sh | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index df2a3e1e..b09b5441 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -41,16 +41,6 @@ apt-get -qqy install \ curl \ sudo &>/dev/null -# Customize Docker configuration -# msg "Customizing Docker..." -#DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -#mkdir -p $(dirname $DOCKER_CONFIG_PATH) -#cat >$DOCKER_CONFIG_PATH <<'EOF' -#{ -# "log-driver": "journald" -#} -#EOF - # Customize container msg "Customizing container..." rm /etc/motd # Remove message of the day after login @@ -66,11 +56,6 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -# Update container OS -msg "Updating container OS..." -apt-get update >/dev/null -apt-get upgrade &>/dev/null - # Cleanup container msg "Cleanup..." rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 01b693a8e966b479739531cc9b263ab6dc7c7d8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:40:09 -0400 Subject: [PATCH 0321/6505] Update debian11_setup.sh --- debian11_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian11_setup.sh b/debian11_setup.sh index b09b5441..0bca50d1 100644 --- a/debian11_setup.sh +++ b/debian11_setup.sh @@ -31,9 +31,9 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -#msg "Updating container OS..." -#apt-get update --allow-releaseinfo-change &>/dev/null -#apt-get upgrade &>/dev/null +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." From 347ea045120c9a96ddd6f92728ba9f8d56d790fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:46:01 -0400 Subject: [PATCH 0322/6505] Update esphome_setup.sh --- esphome_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome_setup.sh b/esphome_setup.sh index b748d3eb..86fb104d 100644 --- a/esphome_setup.sh +++ b/esphome_setup.sh @@ -31,8 +31,8 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -msg "Updating Container OS..." -#apt-get update >/dev/null +msg "Updating container OS..." +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 2f2ba11cbe8f9334a39951eb2efbd0a01336cc4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:46:36 -0400 Subject: [PATCH 0323/6505] Update mariadb_setup.sh --- mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_setup.sh b/mariadb_setup.sh index b0f501d6..5b4d5120 100644 --- a/mariadb_setup.sh +++ b/mariadb_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -#apt-get update >/dev/null +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 13c34525376504a10751cdef3c42c82fda9edbf1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:47:03 -0400 Subject: [PATCH 0324/6505] Update mqtt_setup.sh --- mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_setup.sh b/mqtt_setup.sh index f06ee72c..f2276a8c 100644 --- a/mqtt_setup.sh +++ b/mqtt_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -#apt-get update >/dev/null +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 5390e81248e959c36ae495ea75f905b25b2deb28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:47:35 -0400 Subject: [PATCH 0325/6505] Update node-red_setup.sh --- node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index 7e6ed9ab..0d693abf 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -#apt-get update >/dev/null +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 4a097c039008fcdb70f06dfbf9e4d4713e76d6cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:48:10 -0400 Subject: [PATCH 0326/6505] Update pihole_setup.sh --- pihole_setup.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pihole_setup.sh b/pihole_setup.sh index c2c3abe2..b47a39ff 100644 --- a/pihole_setup.sh +++ b/pihole_setup.sh @@ -28,8 +28,9 @@ locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null -msg "Updating LXC OS..." -#apt-get update >/dev/null +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." From 01963bdcda847388f432ba75bc53eacd8039726a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:49:04 -0400 Subject: [PATCH 0327/6505] Update pve6_ha_setup.sh --- pve6_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh index 4059cf8c..451fd81b 100644 --- a/pve6_ha_setup.sh +++ b/pve6_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -apt-get update >/dev/null +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From dd09e5cf0c588bd470dd53a402902a32df2325d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:50:00 -0400 Subject: [PATCH 0328/6505] Update pve6_zigbee2mqtt_setup.sh --- pve6_zigbee2mqtt_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh index 12695147..2163d8d4 100644 --- a/pve6_zigbee2mqtt_setup.sh +++ b/pve6_zigbee2mqtt_setup.sh @@ -31,8 +31,8 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -msg "Updating Container OS..." -apt-get update >/dev/null +msg "Updating container OS..." +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 1f5695f4fbae907cbbdc32f2e28535becc358117 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:50:45 -0400 Subject: [PATCH 0329/6505] Update pve7_ha_setup.sh --- pve7_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pve7_ha_setup.sh b/pve7_ha_setup.sh index cd2af108..10f21cf6 100644 --- a/pve7_ha_setup.sh +++ b/pve7_ha_setup.sh @@ -32,7 +32,7 @@ apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." -#apt-get update >/dev/null +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From f0d9e65bb4b8b252c1a3777910fba90ff0d7f57f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Oct 2021 13:51:21 -0400 Subject: [PATCH 0330/6505] Update pve7_zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pve7_zigbee2mqtt_setup.sh b/pve7_zigbee2mqtt_setup.sh index 2c5af974..083a9766 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/pve7_zigbee2mqtt_setup.sh @@ -31,8 +31,8 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -msg "Updating Container OS..." -#apt-get update >/dev/null +msg "Updating container OS..." +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From cfda65cade5c2b9c75ad8c018c72f194ad572afb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Oct 2021 14:34:31 -0400 Subject: [PATCH 0331/6505] Update node-red_setup.sh --- node-red_setup.sh | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/node-red_setup.sh b/node-red_setup.sh index 0d693abf..0f314261 100644 --- a/node-red_setup.sh +++ b/node-red_setup.sh @@ -1,10 +1,9 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -23,41 +22,38 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS msg "Setting up container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null -# Update container OS msg "Updating container OS..." apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -# Install prerequisites msg "Installing prerequisites..." apt-get -qqy install \ curl \ sudo &>/dev/null -msg "Installing Node..." -sudo apt -y install nodejs npm &>/dev/null +msg "Installing Node-Red..." +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi -msg "Installing PM2..." -npm install -g pm2 &>/dev/null +#msg "Installing Node..." +#sudo apt -y install nodejs npm &>/dev/null -# Install Node Red -msg "Installing Node-RED..." -npm install -g --unsafe-perm node-red &>/dev/null +#msg "Installing PM2..." +#npm install -g pm2 &>/dev/null -# Set up PM2 to manage startup of Node Red -msg "Setting up PM2..." -/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null -/usr/local/bin/pm2 save &>/dev/null -/usr/local/bin/pm2 startup &>/dev/null +#msg "Installing Node-RED..." +#npm install -g --unsafe-perm node-red &>/dev/null + +#msg "Setting up PM2..." +#/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null +#/usr/local/bin/pm2 save &>/dev/null +#/usr/local/bin/pm2 startup &>/dev/null -# Customize container msg "Customizing container..." rm /etc/motd # Remove message of the day after login rm /etc/update-motd.d/10-uname # Remove kernel information after login @@ -72,6 +68,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -# Cleanup container msg "Cleanup..." rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 8bf070f4d841627d9e0418c66334fa9f1f91bb8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Oct 2021 14:41:48 -0400 Subject: [PATCH 0332/6505] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index d62b5279..55784bec 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,18 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node ```

:zap: Default Settings: 1GB RAM - 4GB Storage - 1vCPU :zap:

+From your nodered LXC console, the following commands can be run + +`node-red-start` to start Node-Red + +`sudo systemctl enable nodered.service` to autostart Node-RED at every boot + +`node-red-restart` to restart Node-Red + +`sudo systemctl disable nodered.service` to disable autostart on boot + +`sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-start` required after update) +
From 23cc145b109a2916c1c83099a47fbec97acc8953 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 05:16:07 -0400 Subject: [PATCH 0333/6505] Set theme jekyll-theme-hacker --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..fc24e7a6 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-hacker \ No newline at end of file From 2c32528a97c640ed48d564fb633813eb6b823e94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 05:17:39 -0400 Subject: [PATCH 0334/6505] Update _config.yml --- _config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index fc24e7a6..d46fb140 100644 --- a/_config.yml +++ b/_config.yml @@ -1 +1,4 @@ -theme: jekyll-theme-hacker \ No newline at end of file +theme: jekyll-theme-hacker +markdown: kramdown +kramdown: + parse_block_html: true From f2c0a24b5fcdce7a2da1e287fce15133e36a7a44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 05:20:45 -0400 Subject: [PATCH 0335/6505] Update README.md --- README.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 55784bec..593338ae 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Select a Proxmox Helper Below

-
+
@@ -21,7 +21,7 @@ It's recommended to update Proxmox after running this script, before adding any
- +
Home Assistant OS VM @@ -40,7 +40,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
- +
@@ -69,7 +69,7 @@ Path to HA configuration.yaml
- +
@@ -99,7 +99,7 @@ Path to HA configuration.yaml
- +
@@ -119,7 +119,6 @@ For ESPHome interface http:// (LXC IP) :6052
-
@@ -162,7 +161,7 @@ Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-pro
- +
@@ -205,7 +204,7 @@ sudo systemctl restart mosquitto
- +
@@ -234,7 +233,6 @@ From your nodered LXC console, the following commands can be run
-
@@ -336,7 +334,7 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m -
+
@@ -401,7 +399,7 @@ To update Zigbee2Mqtt
- +
@@ -466,7 +464,7 @@ To start Zigbee2MQTT automatically on boot
- +
@@ -485,7 +483,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
- +
@@ -504,7 +502,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
- +
From 164b0ea9ab65c2d09e08a3370aec048f94a104af Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 05:29:30 -0400 Subject: [PATCH 0336/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 593338ae..6c2f7f0b 100644 --- a/README.md +++ b/README.md @@ -357,7 +357,7 @@ Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) -:warning: **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** +⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** ``` nano /opt/zigbee2mqtt/data/configuration.yaml ``` @@ -422,7 +422,7 @@ Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) - :warning: **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** + ⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** ``` nano /opt/zigbee2mqtt/data/configuration.yaml ``` From 76062daa237527bb9297d529c35fae64430791f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 05:47:27 -0400 Subject: [PATCH 0337/6505] Update README.md --- README.md | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 6c2f7f0b..0841779c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
-Proxmox VE 7 Post Install +Proxmox VE 7 Post Install

Proxmox VE 7 Post Install

@@ -24,7 +24,7 @@ It's recommended to update Proxmox after running this script, before adding any
-Home Assistant OS VM +Home Assistant OS VM

Proxmox VM with Home Assistant OS

@@ -44,7 +44,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
-PVE6 Home Assistant Container LXC +PVE6 Home Assistant Container LXC

Proxmox 6 Home Assistant Container LXC

@@ -53,7 +53,7 @@ To create a new Proxmox 6 Home Assistant Container, run the following from Proxm ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" ``` -

:zap: Default Settings: 4GB RAM - 16GB Storage - 2vCPU :zap:

+

⚡ Default Settings: 4GB RAM - 16GB Storage - 2vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. @@ -73,7 +73,7 @@ Path to HA configuration.yaml
-PVE7 Home Assistant Container LXC +PVE7 Home Assistant Container LXC

Proxmox 7 Home Assistant Container LXC

@@ -83,7 +83,7 @@ To create a new Proxmox 7 Home Assistant Container, run the following from Proxm bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_container.sh)" ``` -

:zap: Default Settings: 4GB RAM - 16GB Storage - 2vCPU :zap:

+

⚡ Default Settings: 4GB RAM - 16GB Storage - 2vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. @@ -103,7 +103,7 @@ Path to HA configuration.yaml
-ESPHome LXC +ESPHome LXC

Proxmox ESPHome LXC Container

@@ -113,7 +113,7 @@ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox we bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_container.sh)" ``` -

:zap: Default Settings: 1GB RAM - 4GB Storage - 2vCPU :zap:

+

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

For ESPHome interface http:// (LXC IP) :6052 @@ -122,7 +122,7 @@ For ESPHome interface http:// (LXC IP) :6052
-Nginx Proxy Manager LXC +Nginx Proxy Manager LXC

Proxmox Nginx Proxy Manager LXC Container

@@ -131,7 +131,7 @@ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following fro ``` curl -sL https://raw.githubusercontent.com/ej52/proxmox/main/lxc/nginx-proxy-manager/create.sh | bash -s ``` -

:zap: Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+

⚡ Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

____________________________________________________________________________________ @@ -165,7 +165,7 @@ Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-pro
-MQTT LXC +MQTT LXC

Proxmox MQTT LXC Container

@@ -174,7 +174,7 @@ To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_container.sh)" ``` -

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

Mosquitto comes with a password file generating utility called mosquitto_passwd. ``` @@ -208,7 +208,7 @@ sudo systemctl restart mosquitto
-Node-Red LXC +Node-Red LXC

Proxmox Node-Red LXC Container

@@ -217,7 +217,7 @@ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_container.sh)" ``` -

:zap: Default Settings: 1GB RAM - 4GB Storage - 1vCPU :zap:

+

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

From your nodered LXC console, the following commands can be run @@ -236,7 +236,7 @@ From your nodered LXC console, the following commands can be run
-Mariadb 10.5 LXC +Mariadb 10.5 LXC

Proxmox Mariadb 10.5 LXC Container

@@ -245,7 +245,7 @@ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_container.sh)" ``` -

:zap: Default Settings: 1GB RAM - 4GB Storage - 1vCPU :zap:

+

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: ``` @@ -319,7 +319,7 @@ Following this, exit the MariaDB shell: ``` exit ``` -:warning: Reboot the lxc +⚠️ Reboot the lxc Checking status. ``` @@ -338,7 +338,7 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m
-PVE6 Zigbee2MQTT LXC +PVE6 Zigbee2MQTT LXC

Proxmox 6 Zigbee2MQTT LXC Container

@@ -347,7 +347,7 @@ To create a new Proxmox 6 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Contain ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_zigbee2mqtt_container.sh)" ``` -

:zap: Default Settings: 1GB RAM - 4GB Storage - 2vCPU :zap:

+

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

Determine the location of your adapter (Run in the zigbee2mqtt console) ``` @@ -403,7 +403,7 @@ To update Zigbee2Mqtt
-PVE7 Zigbee2MQTT LXC +PVE7 Zigbee2MQTT LXC

Proxmox 7 Zigbee2MQTT LXC Container

@@ -412,7 +412,7 @@ To create a new Proxmox 7 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Contain ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_zigbee2mqtt_container.sh)" ``` -

:zap: Default Settings: 1GB RAM - 4GB Storage - 2vCPU :zap:

+

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

Determine the location of your adapter (Run in the zigbee2mqtt console) ``` @@ -468,7 +468,7 @@ To start Zigbee2MQTT automatically on boot
-Base Debian 10+ LXC +Base Debian 10+ LXC

Proxmox Debian 10 LXC Container

@@ -477,7 +477,7 @@ To create a new Proxmox Debian 10 (curl. sudo, auto login) LXC Container, run th ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_container.sh)" ``` -

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. @@ -487,7 +487,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
-Base Debian 11+ LXC +Base Debian 11+ LXC

Proxmox Debian 11 LXC Container

@@ -496,7 +496,7 @@ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run th ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian11_container.sh)" ``` -

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. @@ -506,7 +506,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
-Pi-hole LXC +Pi-hole LXC

Pi-hole LXC

@@ -515,7 +515,7 @@ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox web shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_container.sh)" ``` -

:zap: Default Settings: 512MiB RAM - 2GB Storage - 1vCPU :zap:

+

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

To set your password (Run in the pi-hole console) From a26b88d826e45f72b374e7fc386585577d5e7463 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 05:52:58 -0400 Subject: [PATCH 0338/6505] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0841779c..00551d89 100644 --- a/README.md +++ b/README.md @@ -389,12 +389,12 @@ sudo systemctl start zigbee2mqtt ``` To start Zigbee2MQTT automatically on boot ``` - sudo systemctl enable zigbee2mqtt.service +sudo systemctl enable zigbee2mqtt.service ``` To update Zigbee2Mqtt ``` - cd /opt/zigbee2mqtt - bash update.sh +cd /opt/zigbee2mqtt +bash update.sh ```
@@ -454,12 +454,12 @@ sudo systemctl start zigbee2mqtt ``` To start Zigbee2MQTT automatically on boot ``` - sudo systemctl enable zigbee2mqtt.service +sudo systemctl enable zigbee2mqtt.service ``` - To update Zigbee2Mqtt +To update Zigbee2Mqtt ``` - cd /opt/zigbee2mqtt - bash update.sh +cd /opt/zigbee2mqtt +bash update.sh ```
From 627b72817a91de2c0835fa896327c8b5bbd8b74d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 05:56:32 -0400 Subject: [PATCH 0339/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00551d89..8f4cd8c2 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ To create a new Proxmox VM with the latest version of Home Assistant OS, run the ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" ``` -###

:zap: Default Settings: 4GB RAM - 32GB Storage - 2vCPU :zap:

+

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. From 11b21271b7d645a523150df3351f89a52c7f021c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 07:08:07 -0400 Subject: [PATCH 0340/6505] Update README.md --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f4cd8c2..f9298d46 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@ -
Proxmox VE 7 Post Install + +

Proxmox Server Solutions

Proxmox VE 7 Post Install

@@ -26,6 +27,8 @@ It's recommended to update Proxmox after running this script, before adding any
Home Assistant OS VM +

@home-assistant

+

Proxmox VM with Home Assistant OS

To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell @@ -45,6 +48,8 @@ After the script completes, If you're dissatisfied with the default settings, cl
PVE6 Home Assistant Container LXC + +

@home-assistant

Proxmox 6 Home Assistant Container LXC

@@ -74,6 +79,8 @@ Path to HA configuration.yaml
PVE7 Home Assistant Container LXC + +

@home-assistant

Proxmox 7 Home Assistant Container LXC

@@ -104,6 +111,8 @@ Path to HA configuration.yaml
ESPHome LXC + +

Logo

Proxmox ESPHome LXC Container

@@ -123,6 +132,9 @@ For ESPHome interface http:// (LXC IP) :6052
Nginx Proxy Manager LXC + +

hero

+

Proxmox Nginx Proxy Manager LXC Container

@@ -166,6 +178,9 @@ Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-pro
MQTT LXC + +

+

Proxmox MQTT LXC Container

@@ -209,8 +224,11 @@ sudo systemctl restart mosquitto
Node-Red LXC + +

@node-red

Proxmox Node-Red LXC Container

+ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. @@ -237,6 +255,9 @@ From your nodered LXC console, the following commands can be run
Mariadb 10.5 LXC + +

MariaDB

+

Proxmox Mariadb 10.5 LXC Container

@@ -339,6 +360,8 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m
PVE6 Zigbee2MQTT LXC + +

logo.png

Proxmox 6 Zigbee2MQTT LXC Container

@@ -404,6 +427,9 @@ bash update.sh
PVE7 Zigbee2MQTT LXC + +

logo.png

+

Proxmox 7 Zigbee2MQTT LXC Container

@@ -469,6 +495,8 @@ bash update.sh
Base Debian 10+ LXC + +

Debian

Proxmox Debian 10 LXC Container

@@ -488,6 +516,8 @@ After the script completes, If you're dissatisfied with the default settings, cl
Base Debian 11+ LXC + +

Debian

Proxmox Debian 11 LXC Container

@@ -507,6 +537,8 @@ After the script completes, If you're dissatisfied with the default settings, cl
Pi-hole LXC + +

Pi-hole

Pi-hole LXC

From b70ea4ee440734d53147dfb53e2f28648459688f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 07:15:10 -0400 Subject: [PATCH 0341/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f9298d46..3c3945d8 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ For ESPHome interface http:// (LXC IP) :6052
Nginx Proxy Manager LXC -

hero

+

hero

Proxmox Nginx Proxy Manager LXC Container

@@ -179,7 +179,7 @@ Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-pro
MQTT LXC -

+

Proxmox MQTT LXC Container

From 289ac38c26e635cbaca0fb8bbc6aeb5713f83e97 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 07:19:49 -0400 Subject: [PATCH 0342/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c3945d8..c73be560 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@
Proxmox VE 7 Post Install -

Proxmox Server Solutions

+

Proxmox Server Solutions

Proxmox VE 7 Post Install

From e042c1c5c3edabb313c7bba659f4020b2ca1a852 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 07:47:43 -0400 Subject: [PATCH 0343/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c73be560..0ec98418 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@
Proxmox VE 7 Post Install -

Proxmox Server Solutions

+

Proxmox Server Solutions

Proxmox VE 7 Post Install

From 1e7c8bb46a67d9b2e3b87ece4c799e277d17676d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 07:53:44 -0400 Subject: [PATCH 0344/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ec98418..1f8c5e00 100644 --- a/README.md +++ b/README.md @@ -247,7 +247,7 @@ From your nodered LXC console, the following commands can be run `sudo systemctl disable nodered.service` to disable autostart on boot -`sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-start` required after update) +`sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-restart` after update)
From fe7e41678ccfad9d22420e0ea670f6d820d500a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 08:19:55 -0400 Subject: [PATCH 0345/6505] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1f8c5e00..77a1b303 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
-PVE6 Home Assistant Container LXC +Home Assistant Container LXC (PVE6)

@home-assistant

@@ -78,7 +78,7 @@ Path to HA configuration.yaml
-PVE7 Home Assistant Container LXC +Home Assistant Container LXC (PVE7)

@home-assistant

@@ -359,7 +359,7 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m
-PVE6 Zigbee2MQTT LXC +Zigbee2MQTT LXC (PVE6)

logo.png

@@ -426,7 +426,7 @@ bash update.sh
-PVE7 Zigbee2MQTT LXC +Zigbee2MQTT LXC (PVE7)

logo.png

@@ -494,7 +494,7 @@ bash update.sh
-Base Debian 10+ LXC +Debian 10+ LXC

Debian

@@ -515,7 +515,7 @@ After the script completes, If you're dissatisfied with the default settings, cl
-Base Debian 11+ LXC +Debian 11+ LXC

Debian

From 58dfacbc33fb78238e47999970c2eb9ffcd75737 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 08:46:03 -0400 Subject: [PATCH 0346/6505] Update _config.yml --- _config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/_config.yml b/_config.yml index d46fb140..7a6d92f4 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,5 @@ theme: jekyll-theme-hacker +description: Proxmox Home Automation Helper Scripts markdown: kramdown kramdown: parse_block_html: true From 87ca95c239dae38b8eafbc9c88cdbad5939d0351 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 08:49:53 -0400 Subject: [PATCH 0347/6505] Update _config.yml --- _config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 7a6d92f4..6979f9d8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,5 +1,6 @@ theme: jekyll-theme-hacker -description: Proxmox Home Automation Helper Scripts +title: Proxmox Helper Scripts +description: Proxmox Scripts For Home Automation markdown: kramdown kramdown: parse_block_html: true From 7e49b258152ed419038204bc79dfa3a492c39a4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 10:25:06 -0400 Subject: [PATCH 0348/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77a1b303..9383d404 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@
Proxmox VE 7 Post Install -

Proxmox Server Solutions

+

Proxmox Server Solutions

Proxmox VE 7 Post Install

@@ -112,7 +112,7 @@ Path to HA configuration.yaml
ESPHome LXC -

Logo

+

Logo

Proxmox ESPHome LXC Container

From 26c6590584e954d9a4378ca64f821ef291d11e43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 10:41:05 -0400 Subject: [PATCH 0349/6505] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9383d404..205864e0 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,8 @@ After the script completes, If you're dissatisfied with the default settings, cl
Home Assistant Container LXC (PVE6) -

@home-assistant

+

Docker Logos | Docker +@home-assistantGitHub - portainer/portainer-docs: Portainer documentation

Proxmox 6 Home Assistant Container LXC

@@ -80,7 +81,8 @@ Path to HA configuration.yaml
Home Assistant Container LXC (PVE7) -

@home-assistant

+

Docker Logos | Docker +@home-assistantGitHub - portainer/portainer-docs: Portainer documentation

Proxmox 7 Home Assistant Container LXC

From 459ae447e85fc3976611f3a65f71ee83bc877793 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 18:18:17 -0400 Subject: [PATCH 0350/6505] Add files via upload --- adguard_container.sh | 157 +++++++++++++++++++++++++++++++++++++++++++ adguard_setup.sh | 58 ++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 adguard_container.sh create mode 100644 adguard_setup.sh diff --git a/adguard_container.sh b/adguard_container.sh new file mode 100644 index 00000000..fccdf66f --- /dev/null +++ b/adguard_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New AdGuard Home LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/adguard_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "LXC ID is $CTID." + +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +msg "Creating LXC..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=pi-hole +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +msg "Starting LXC..." +pct start $CTID +pct push $CTID adguard_setup.sh /adguard_setup.sh -perms 755 +pct exec $CTID /adguard_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a AdGuard Home LXC to $CTID at IP Address ${IP}" \ No newline at end of file diff --git a/adguard_setup.sh b/adguard_setup.sh new file mode 100644 index 00000000..5f93d283 --- /dev/null +++ b/adguard_setup.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating Container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing AdGuard Home.." +curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null + +msg "Customizing LXC..." +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /adguard_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 11d6a1405a78b46d1098219f43a2005d74152cbe Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 18:27:08 -0400 Subject: [PATCH 0351/6505] Update README.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 205864e0..8b2438b4 100644 --- a/README.md +++ b/README.md @@ -559,3 +559,20 @@ pihole -a -p
+
+AdGuard Home LXC + +

+ +

AdGuard Home LXC

+ +To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adguard_container.sh)" +``` +

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

+ +For AdGuard Home interface http:// (LXC IP) :3000 + +
From 8b76d9d14ad06186471b43c27916d9101df4e99f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 18:38:41 -0400 Subject: [PATCH 0352/6505] Update adguard_container.sh --- adguard_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adguard_container.sh b/adguard_container.sh index fccdf66f..61a75d82 100644 --- a/adguard_container.sh +++ b/adguard_container.sh @@ -138,7 +138,7 @@ else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi ARCH=$(dpkg --print-architecture) -HOSTNAME=pi-hole +HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ @@ -154,4 +154,4 @@ pct push $CTID adguard_setup.sh /adguard_setup.sh -perms 755 pct exec $CTID /adguard_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a AdGuard Home LXC to $CTID at IP Address ${IP}" \ No newline at end of file +info "Successfully created a AdGuard Home LXC to $CTID at IP Address ${IP}" From b2a9283c2cb37f81a7ca2bb8aa55125b5f2213ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Oct 2021 23:11:22 -0400 Subject: [PATCH 0353/6505] Update README.md --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8b2438b4..b20085aa 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ To create a new Proxmox VM with the latest version of Home Assistant OS, run the bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

+ +Home Assistant Interface http:// (VM IP) :8123 After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. @@ -63,9 +65,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6 After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. -For Home Assistant interface http:// (LXC IP) :8123 +Home Assistant Interface http:// (LXC IP) :8123 -For Portainer interface http:// (LXC IP) :9000 +Portainer Interface http:// (LXC IP) :9000 Path to HA configuration.yaml ``` @@ -96,9 +98,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7 After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. -For Home Assistant interface http:// (LXC IP) :8123 +Home Assistant Interface http:// (LXC IP) :8123 -For Portainer interface http:// (LXC IP) :9000 +Portainer Interface http:// (LXC IP) :9000 Path to HA configuration.yaml ``` @@ -126,7 +128,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esph

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

-For ESPHome interface http:// (LXC IP) :6052 +ESPHome Interface http:// (LXC IP) :6052
@@ -159,6 +161,8 @@ Add the following to your `configuration.yaml` in Home Assistant. - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### ``` +Nginx Proxy Manager Interface http:// (LXC IP) :81 + **Initial Login** **username** @@ -251,6 +255,8 @@ From your nodered LXC console, the following commands can be run `sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-restart` after update) +Node-Red Interface http:// (LXC IP) :1880 +
@@ -573,6 +579,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adgu ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

-For AdGuard Home interface http:// (LXC IP) :3000 +AdGuard Home Interface http:// (LXC IP) :3000
From 28494bb3d96fb91e2185d9f9aa8b38aba74e4485 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Oct 2021 11:24:16 -0400 Subject: [PATCH 0354/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index b20085aa..7eb26a33 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,10 @@ To create a new Proxmox VM with the latest version of Home Assistant OS, run the bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

- -Home Assistant Interface http:// (VM IP) :8123 After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. +Home Assistant Interface http:// (VM IP) :8123
From da2e0978d1d630cf6ad3f047cc8fbf79e65ed0b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Oct 2021 12:22:38 -0400 Subject: [PATCH 0355/6505] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7eb26a33..8173a344 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. -Home Assistant Interface http:// (VM IP) :8123 +Home Assistant Interface - IP:8123
@@ -64,9 +64,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6 After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. -Home Assistant Interface http:// (LXC IP) :8123 +Home Assistant Interface - IP:8123 -Portainer Interface http:// (LXC IP) :9000 +Portainer Interface - IP:9000 Path to HA configuration.yaml ``` @@ -97,9 +97,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7 After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. -Home Assistant Interface http:// (LXC IP) :8123 +Home Assistant Interface - IP:8123 -Portainer Interface http:// (LXC IP) :9000 +Portainer Interface - IP:9000 Path to HA configuration.yaml ``` @@ -127,7 +127,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esph

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

-ESPHome Interface http:// (LXC IP) :6052 +ESPHome Interface - IP:6052
@@ -160,7 +160,7 @@ Add the following to your `configuration.yaml` in Home Assistant. - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### ``` -Nginx Proxy Manager Interface http:// (LXC IP) :81 +Nginx Proxy Manager Interface - IP:81 **Initial Login** @@ -254,7 +254,7 @@ From your nodered LXC console, the following commands can be run `sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-restart` after update) -Node-Red Interface http:// (LXC IP) :1880 +Node-Red Interface - IP:1880
@@ -578,6 +578,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adgu ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

-AdGuard Home Interface http:// (LXC IP) :3000 +AdGuard Home Interface - IP:3000
From c0933fa38decc46dad7408b2322d5c8addf4e120 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Oct 2021 12:34:29 -0400 Subject: [PATCH 0356/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8173a344..a957e59b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Select a Proxmox Helper Below

+

https://tteck.github.io/Proxmox/
Select a Proxmox Helper Below

From d263b1852139c6183bd0c7dbaffeedd809e369b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Oct 2021 12:38:31 -0400 Subject: [PATCH 0357/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a957e59b..8173a344 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

https://tteck.github.io/Proxmox/
Select a Proxmox Helper Below

+

Select a Proxmox Helper Below

From 0cca34b72845854e122964b8251aaac1dfa8fc65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Oct 2021 12:44:20 -0400 Subject: [PATCH 0358/6505] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8173a344..0a5a6210 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. -Home Assistant Interface - IP:8123 +**Home Assistant Interface - IP:8123**
@@ -64,9 +64,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6 After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. -Home Assistant Interface - IP:8123 +**Home Assistant Interface - IP:8123** -Portainer Interface - IP:9000 +**Portainer Interface - IP:9000** Path to HA configuration.yaml ``` @@ -97,9 +97,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7 After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. -Home Assistant Interface - IP:8123 +**Home Assistant Interface - IP:8123** -Portainer Interface - IP:9000 +**Portainer Interface - IP:9000** Path to HA configuration.yaml ``` @@ -127,7 +127,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esph

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

-ESPHome Interface - IP:6052 +**ESPHome Interface - IP:6052**
@@ -160,7 +160,7 @@ Add the following to your `configuration.yaml` in Home Assistant. - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### ``` -Nginx Proxy Manager Interface - IP:81 +**Nginx Proxy Manager Interface - IP:81** **Initial Login** @@ -254,7 +254,7 @@ From your nodered LXC console, the following commands can be run `sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-restart` after update) -Node-Red Interface - IP:1880 +**Node-Red Interface - IP:1880**
@@ -578,6 +578,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adgu ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

-AdGuard Home Interface - IP:3000 +**AdGuard Home Interface - IP:3000**
From bd1a29f6215e6fa8457b80c4b395d8058476460c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Nov 2021 14:02:32 -0400 Subject: [PATCH 0359/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0a5a6210..602e86aa 100644 --- a/README.md +++ b/README.md @@ -387,7 +387,7 @@ Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) -⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** +⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** ``` nano /opt/zigbee2mqtt/data/configuration.yaml ``` @@ -455,7 +455,7 @@ Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) - ⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/information/configuration.html)** + ⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://https://www.zigbee2mqtt.io/guide/configuration/)** ``` nano /opt/zigbee2mqtt/data/configuration.yaml ``` From 2bb658971a807a80c324f03a7337ba55be0e528b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Nov 2021 14:04:11 -0400 Subject: [PATCH 0360/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 602e86aa..86500bb6 100644 --- a/README.md +++ b/README.md @@ -455,7 +455,7 @@ Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) - ⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://https://www.zigbee2mqtt.io/guide/configuration/)** + ⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** ``` nano /opt/zigbee2mqtt/data/configuration.yaml ``` From bd1705f2d23f8e57eb645ae2ca0489e27e226f45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Nov 2021 07:27:21 -0400 Subject: [PATCH 0361/6505] Update haos_vm.sh --- haos_vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/haos_vm.sh b/haos_vm.sh index c61e2dfa..0bd8eba4 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -122,7 +122,7 @@ if [[ $FILE == *.zip ]]; then echo -e "\e[1;33m Checking for unzip command... \e[0m" if ! command -v unzip &> /dev/null; then echo -e "\e[1;33m Installing Unzip... \e[0m" - apt-get --allow-releaseinfo-change update >/dev/null + apt-get update >/dev/null apt-get -qqy install unzip &>/dev/null fi fi @@ -176,7 +176,7 @@ set +o errtrace ' ERR if [ "$(command -v kpartx)" = "" ]; then echo -e "\e[1;33m Installing kpartx... \e[0m" - apt-get --allow-releaseinfo-change update >/dev/null + apt-get update >/dev/null apt-get -qqy install kpartx &>/dev/null fi DISK1_PATH="$(pvesm path $DISK1_REF)" From 55a2058385dbb2fdb0383469820bf56b8d7f32b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Nov 2021 14:56:03 -0500 Subject: [PATCH 0362/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86500bb6..acb120bd 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ It's recommended to update Proxmox after running this script, before adding any

@home-assistant

-

Proxmox VM with Home Assistant OS

+

Proxmox Home Assistant OS VM

To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell From 7ba75c5e77a45c2de465f0d9465d6373cc4eb75c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Nov 2021 14:59:19 -0500 Subject: [PATCH 0363/6505] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index acb120bd..87122e29 100644 --- a/README.md +++ b/README.md @@ -80,12 +80,12 @@ Path to HA configuration.yaml
-Home Assistant Container LXC (PVE7) +Home Assistant Container LXC

Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

-

Proxmox 7 Home Assistant Container LXC

+

Proxmox Home Assistant Container LXC

To create a new Proxmox 7 Home Assistant Container, run the following from Proxmox web shell. @@ -433,12 +433,12 @@ bash update.sh
-Zigbee2MQTT LXC (PVE7) +Zigbee2MQTT LXC

logo.png

-

Proxmox 7 Zigbee2MQTT LXC Container

+

Proxmox Zigbee2MQTT LXC Container

To create a new Proxmox 7 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. From 64e845e6e8c1f99f662507e103f775e6f4cadbf9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Nov 2021 13:15:04 -0500 Subject: [PATCH 0364/6505] Add files via upload --- hacs.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 hacs.sh diff --git a/hacs.sh b/hacs.sh new file mode 100644 index 00000000..d8c6a7c9 --- /dev/null +++ b/hacs.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" + +while true; do + read -p "Start the HACS Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +apt update &>/dev/null +apt install unzip &>/dev/null +cd /var/lib/docker/volumes/hass_config/_data +wget -O - https://get.hacs.xyz | bash - + +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" \ No newline at end of file From d3c81b794cbeca713d627c5acb9c76db9a164079 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Nov 2021 13:24:05 -0500 Subject: [PATCH 0365/6505] Update hacs.sh --- hacs.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hacs.sh b/hacs.sh index d8c6a7c9..7134d1ba 100644 --- a/hacs.sh +++ b/hacs.sh @@ -15,4 +15,5 @@ apt install unzip &>/dev/null cd /var/lib/docker/volumes/hass_config/_data wget -O - https://get.hacs.xyz | bash - -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" \ No newline at end of file +# To install HACS run the following from the container (LXC) console +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" From 9668e1487821a93bb6b9c6aa1bf6ed4bcd35b3e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Nov 2021 13:28:05 -0500 Subject: [PATCH 0366/6505] Update hacs.sh --- hacs.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/hacs.sh b/hacs.sh index 7134d1ba..5079c45e 100644 --- a/hacs.sh +++ b/hacs.sh @@ -17,3 +17,4 @@ wget -O - https://get.hacs.xyz | bash - # To install HACS run the following from the container (LXC) console # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" +# Then add the integration in HA From cb3c207e4c552ee0ec583d63772ded72c3dfbc37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:02:14 -0500 Subject: [PATCH 0367/6505] Create HACS.md --- HACS.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 HACS.md diff --git a/HACS.md b/HACS.md new file mode 100644 index 00000000..9b3408bf --- /dev/null +++ b/HACS.md @@ -0,0 +1,9 @@ +## Home Assistant Community Store ## + +This script is for installong HACS on Home Assistant Container LXC ONLY + +Run the following from the Home Assistant container (LXC) console +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" +``` +After install, reboot Home Assistant and clear browser cache From a5dec80236d965879d31ffe633fcc95f152eac0e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:04:35 -0500 Subject: [PATCH 0368/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 87122e29..2391e3d7 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ Path to HA configuration.yaml /var/lib/docker/volumes/hass_config/_data ``` [To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) +[Install HACS](https://github.com/tteck/Proxmox/blob/main/HACS.md)
From f4a7de38e3d198b6c92e44225b12ee047197f67f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:06:06 -0500 Subject: [PATCH 0369/6505] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2391e3d7..69b5f7c2 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ Path to HA configuration.yaml /var/lib/docker/volumes/hass_config/_data ``` [To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) + [Install HACS](https://github.com/tteck/Proxmox/blob/main/HACS.md)
@@ -107,6 +108,8 @@ Path to HA configuration.yaml /var/lib/docker/volumes/hass_config/_data ``` [To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) + +[Install HACS](https://github.com/tteck/Proxmox/blob/main/HACS.md)
From 6d08a46274d9714355a18b87b7be66dd8bbc062e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:06:49 -0500 Subject: [PATCH 0370/6505] Update HACS.md --- HACS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACS.md b/HACS.md index 9b3408bf..9e82a353 100644 --- a/HACS.md +++ b/HACS.md @@ -1,6 +1,6 @@ ## Home Assistant Community Store ## -This script is for installong HACS on Home Assistant Container LXC ONLY +This script is for installing HACS on Home Assistant Container LXC ONLY Run the following from the Home Assistant container (LXC) console ``` From c1436a5eee6ec7fd4bb033ebb2b51fb5dcf6fae5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:13:03 -0500 Subject: [PATCH 0371/6505] Update HACS.md --- HACS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HACS.md b/HACS.md index 9e82a353..c756c1fb 100644 --- a/HACS.md +++ b/HACS.md @@ -1,9 +1,9 @@ ## Home Assistant Community Store ## -This script is for installing HACS on Home Assistant Container LXC ONLY +**This script is for installing HACS on Home Assistant Container LXC ONLY** Run the following from the Home Assistant container (LXC) console ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" ``` -After install, reboot Home Assistant and clear browser cache +After install, reboot Home Assistant and **clear browser cache** From ffbf807f337ba8fadf5f13ea1fa65625c20474f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:20:19 -0500 Subject: [PATCH 0372/6505] Update HACS.md --- HACS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HACS.md b/HACS.md index c756c1fb..6bac0bf1 100644 --- a/HACS.md +++ b/HACS.md @@ -7,3 +7,5 @@ Run the following from the Home Assistant container (LXC) console bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** + +Add HACS integration. From fa1677de6ffc782f473cc0552571c1ecc8a8edea Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:20:47 -0500 Subject: [PATCH 0373/6505] Update HACS.md --- HACS.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/HACS.md b/HACS.md index 6bac0bf1..e17a9ec1 100644 --- a/HACS.md +++ b/HACS.md @@ -6,6 +6,4 @@ Run the following from the Home Assistant container (LXC) console ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" ``` -After install, reboot Home Assistant and **clear browser cache** - -Add HACS integration. +After install, reboot Home Assistant and **clear browser cache** and Add HACS integration. From 82a0bad1b4934016d8a5e5b1eb83a033c4be97a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:21:18 -0500 Subject: [PATCH 0374/6505] Update HACS.md --- HACS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACS.md b/HACS.md index e17a9ec1..14d89781 100644 --- a/HACS.md +++ b/HACS.md @@ -6,4 +6,4 @@ Run the following from the Home Assistant container (LXC) console ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" ``` -After install, reboot Home Assistant and **clear browser cache** and Add HACS integration. +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. From 0444e9d7bb4973afc8f696657cb370d1b2a8966a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:28:44 -0500 Subject: [PATCH 0375/6505] Update README.md --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 69b5f7c2..d8473507 100644 --- a/README.md +++ b/README.md @@ -68,10 +68,16 @@ After the script completes, If you're dissatisfied with the default settings, cl **Portainer Interface - IP:9000** -Path to HA configuration.yaml +Path to HA /config ``` /var/lib/docker/volumes/hass_config/_data ``` +Edit HA configuration.yaml (run from the LXC console) +``` +nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + [To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) [Install HACS](https://github.com/tteck/Proxmox/blob/main/HACS.md) @@ -103,10 +109,16 @@ After the script completes, If you're dissatisfied with the default settings, cl **Portainer Interface - IP:9000** -Path to HA configuration.yaml +Path to HA /config ``` /var/lib/docker/volumes/hass_config/_data ``` +Edit HA configuration.yaml (run from the LXC console) +``` +nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + [To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) [Install HACS](https://github.com/tteck/Proxmox/blob/main/HACS.md) From 8be0427c930d97a13221984173d7424ca3fdd3ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:30:47 -0500 Subject: [PATCH 0376/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d8473507..167d264d 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Path to HA /config ``` /var/lib/docker/volumes/hass_config/_data ``` -Edit HA configuration.yaml (run from the LXC console) +To edit the HA configuration.yaml (run from the LXC console) ``` nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` @@ -113,7 +113,7 @@ Path to HA /config ``` /var/lib/docker/volumes/hass_config/_data ``` -Edit HA configuration.yaml (run from the LXC console) +To edit the HA configuration.yaml (run from the LXC console) ``` nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` From f5a3282e85511143bf5142241f6fec5788a777a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:37:28 -0500 Subject: [PATCH 0377/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 167d264d..db5e6179 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Path to HA /config ``` /var/lib/docker/volumes/hass_config/_data ``` -To edit the HA configuration.yaml (run from the LXC console) +To edit the HA configuration.yaml (run from the Home Assistant container LXC console) ``` nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` @@ -113,7 +113,7 @@ Path to HA /config ``` /var/lib/docker/volumes/hass_config/_data ``` -To edit the HA configuration.yaml (run from the LXC console) +To edit the HA configuration.yaml (run from the Home Assistant container LXC console) ``` nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` From 7315da4bf559b6042babfca5e4bad90fbfc30588 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Nov 2021 04:41:17 -0500 Subject: [PATCH 0378/6505] Update HACS.md --- HACS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACS.md b/HACS.md index 14d89781..512bbea8 100644 --- a/HACS.md +++ b/HACS.md @@ -2,7 +2,7 @@ **This script is for installing HACS on Home Assistant Container LXC ONLY** -Run the following from the Home Assistant container (LXC) console +Run the following from the Home Assistant Container LXC console ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" ``` From ade8d9bbf51fb95eaf5fdcfe4cf1b2cd20622cdf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Nov 2021 19:59:50 -0500 Subject: [PATCH 0379/6505] Update HACS.md --- HACS.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/HACS.md b/HACS.md index 512bbea8..ddbded9e 100644 --- a/HACS.md +++ b/HACS.md @@ -1,6 +1,8 @@ -## Home Assistant Community Store ## +

Home Assistant Community Store

-**This script is for installing HACS on Home Assistant Container LXC ONLY** +

+ +

⚠️ This script is for installing HACS on Home Assistant Container LXC ONLY ⚠️

Run the following from the Home Assistant Container LXC console ``` From bd5230b5076c2d971bfd47f97b36f40eabbc63cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Nov 2021 19:50:57 -0500 Subject: [PATCH 0380/6505] Add files via upload --- zwavejs2mqtt_container.sh | 157 ++++++++++++++++++++++++++++++++++++++ zwavejs2mqtt_setup.sh | 68 +++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 zwavejs2mqtt_container.sh create mode 100644 zwavejs2mqtt_setup.sh diff --git a/zwavejs2mqtt_container.sh b/zwavejs2mqtt_container.sh new file mode 100644 index 00000000..2878255a --- /dev/null +++ b/zwavejs2mqtt_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Zwavejs2MQTT LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +msg "Creating LXC container..." +DISK_SIZE=4G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=zwavejs2mqtt +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +msg "Starting LXC container..." +pct start $CTID +pct push $CTID zwavejs2mqtt_setup.sh /zwavejs2mqtt_setup.sh -perms 755 +pct exec $CTID /zwavejs2mqtt_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}" \ No newline at end of file diff --git a/zwavejs2mqtt_setup.sh b/zwavejs2mqtt_setup.sh new file mode 100644 index 00000000..544dc8a9 --- /dev/null +++ b/zwavejs2mqtt_setup.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing prerequisites..." +apt-get -qqy install \ + curl \ + sudo \ + unzip &>/dev/null + +msg "Installing zwavejs2mqtt..." +cd ~ +mkdir zwavejs2mqtt +cd zwavejs2mqtt +curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest \ +| grep "browser_download_url.*zip" \ +| cut -d : -f 2,3 \ +| tr -d \" \ +| wget -i - &>/dev/null +unzip zwavejs2mqtt-v*.zip &>/dev/null +./zwavejs2mqtt + +msg "Customizing container..." +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /zwavejs2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From dc86479cc4a7dc4323b4f72e623651f7ae8353f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Nov 2021 22:06:37 -0500 Subject: [PATCH 0381/6505] Update zwavejs2mqtt_setup.sh --- zwavejs2mqtt_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zwavejs2mqtt_setup.sh b/zwavejs2mqtt_setup.sh index 544dc8a9..a207060e 100644 --- a/zwavejs2mqtt_setup.sh +++ b/zwavejs2mqtt_setup.sh @@ -48,7 +48,7 @@ curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest \ | tr -d \" \ | wget -i - &>/dev/null unzip zwavejs2mqtt-v*.zip &>/dev/null -./zwavejs2mqtt +#./zwavejs2mqtt msg "Customizing container..." rm /etc/motd @@ -65,4 +65,4 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg "Cleanup..." -rm -rf /zwavejs2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /zwavejs2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From b824253edf4494a5125691a0a23e2faf1a86e316 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Nov 2021 23:01:10 -0500 Subject: [PATCH 0382/6505] Add files via upload --- autodev.sh | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/autodev.sh b/autodev.sh index dbee7730..3a519223 100644 --- a/autodev.sh +++ b/autodev.sh @@ -1,10 +1,18 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +while true; do + read -p "To allow device passthrough to the predefined LXC container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -29,25 +37,22 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Array of device types to enable in container -#CHAR_DEVS+=(major:minor) -CHAR_DEVS+=("1:1") #mem (physical memory access) -CHAR_DEVS+=("4:\([3-9]\|[1-5][0-9]\|6[0-3]\)") #tty* (virtual console, minor 3-63) -CHAR_DEVS+=("4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)") #ttyS* (UART serial port, minor 64-255) -CHAR_DEVS+=("10:200") #net/tun (TAP/TUN network device) -CHAR_DEVS+=("116:.*") #(ALSA devices) -CHAR_DEVS+=("166:.*") #ttyACM* (ACM USB modems) -CHAR_DEVS+=("180:\([0-9]\|1[0-5]\)") #usb/hiddev* (UPS devices, minor 0-15) -CHAR_DEVS+=("188:.*") #ttyUSB* (USB serial converters) -CHAR_DEVS+=("189:.*") #bus/usb/* (USB serial converters - alternate devices) +CHAR_DEVS+=("1:1") +CHAR_DEVS+=("4:\([3-9]\|[1-5][0-9]\|6[0-3]\)") +CHAR_DEVS+=("4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)") +CHAR_DEVS+=("10:200") +CHAR_DEVS+=("116:.*") +CHAR_DEVS+=("166:.*") +CHAR_DEVS+=("180:\([0-9]\|1[0-5]\)") +CHAR_DEVS+=("188:.*") +CHAR_DEVS+=("189:.*") +CHAR_DEVS+=("24[0-2]:.*") -# Proccess char device string for char_dev in ${CHAR_DEVS[@]}; do [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" done -# Store autodev hook script in variable read -r -d '' HOOK_SCRIPT <<- EOF || true for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; @@ -59,15 +64,13 @@ for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; done; EOF -HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} #Remove newline char from variable +HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} -# Remove autodev settings CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH -# Add autodev settings cat <> $CTID_CONFIG_PATH lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' From 58d7bd94d84e5ff6bf0696acbc6af59fc244d615 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Nov 2021 14:27:41 -0500 Subject: [PATCH 0383/6505] Update autodev.sh --- autodev.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/autodev.sh b/autodev.sh index 3a519223..3131cd41 100644 --- a/autodev.sh +++ b/autodev.sh @@ -72,6 +72,8 @@ sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH cat <> $CTID_CONFIG_PATH +lxc.cgroup2.devices.allow: a +lxc.cap.drop: lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' -EOF \ No newline at end of file +EOF From 6a767618e3e46f47b5cf0e0a70066c46397846f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Nov 2021 15:03:41 -0500 Subject: [PATCH 0384/6505] Update autodev.sh --- autodev.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/autodev.sh b/autodev.sh index 3131cd41..76ed5af2 100644 --- a/autodev.sh +++ b/autodev.sh @@ -72,8 +72,6 @@ sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH cat <> $CTID_CONFIG_PATH -lxc.cgroup2.devices.allow: a -lxc.cap.drop: lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF From 3a83a7dc21eedd53df31ac22cf6fd6c64baf0714 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Nov 2021 15:06:15 -0500 Subject: [PATCH 0385/6505] Update zwavejs2mqtt_container.sh --- zwavejs2mqtt_container.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/zwavejs2mqtt_container.sh b/zwavejs2mqtt_container.sh index 2878255a..4e773bba 100644 --- a/zwavejs2mqtt_container.sh +++ b/zwavejs2mqtt_container.sh @@ -144,6 +144,12 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024\ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT @@ -154,4 +160,4 @@ pct push $CTID zwavejs2mqtt_setup.sh /zwavejs2mqtt_setup.sh -perms 755 pct exec $CTID /zwavejs2mqtt_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}" \ No newline at end of file +info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}" From b8e8b46eec8b910858e10a76b13fdb89e4aaa06a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Nov 2021 15:41:25 -0500 Subject: [PATCH 0386/6505] Add files via upload --- autodev.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/autodev.sh b/autodev.sh index 76ed5af2..7a608e28 100644 --- a/autodev.sh +++ b/autodev.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "To allow device passthrough to the predefined LXC container. Proceed(y/n)?" yn + read -p "Allow device passthrough to the predefined LXC container. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -75,3 +75,7 @@ cat <> $CTID_CONFIG_PATH lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF + +# In the Proxmox web shell run (replace 106 with your LXC ID) +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +# Reboot the LXC to apply the changes \ No newline at end of file From ce3e8858853ba5da65385bb6761111d90f3d31f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Nov 2021 21:54:48 -0500 Subject: [PATCH 0387/6505] Add files via upload --- podman_ha_container.sh | 163 +++++++++++++++++++++++++++++++++++++++++ podman_ha_setup.sh | 68 +++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 podman_ha_container.sh create mode 100644 podman_ha_setup.sh diff --git a/podman_ha_container.sh b/podman_ha_container.sh new file mode 100644 index 00000000..de697234 --- /dev/null +++ b/podman_ha_container.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Home Assistant LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +msg "Creating LXC container..." +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=homeassistant +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +msg "Starting LXC container..." +pct start $CTID +pct push $CTID podman_ha_setup.sh /podman_ha_setup.sh -perms 755 +pct exec $CTID /podman_ha_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Home Assistant Container LXC to $CTID." +msg " + +Home Assistant is reachable by going to the following URLs. + + http://${IP}:8123 +" \ No newline at end of file diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh new file mode 100644 index 00000000..70f75d48 --- /dev/null +++ b/podman_ha_setup.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing prerequisites..." +apt-get -qqy install \ + curl &>/dev/null + +msg "Installing Podman..." +apt-get -y install podman &>/dev/null + +msg "Installing Home Assistant..." +podman volume create hass_config >/dev/null +podman run -d \ + --name homeassistant \ + --restart=always \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null + +msg "Customizing container..." +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From d725d3e8b6d91881cecb7a0f866fc10f4f8f2b8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Nov 2021 22:04:12 -0500 Subject: [PATCH 0388/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 70f75d48..15a424f4 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -39,8 +39,11 @@ apt-get -qqy install \ msg "Installing Podman..." apt-get -y install podman &>/dev/null -msg "Installing Home Assistant..." +msg "Pulling Home Assistant Image..." podman volume create hass_config >/dev/null +podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null + +msg "Installing Home Assistant..." podman run -d \ --name homeassistant \ --restart=always \ @@ -65,4 +68,4 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg "Cleanup..." -rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 0d80ee95d6f48f9833a115db0a23e4f61d015c96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Nov 2021 22:31:48 -0500 Subject: [PATCH 0389/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 15a424f4..79621eff 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -53,6 +53,21 @@ podman run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null +echo "Creating service file podman@.service" +service_path="/etc/systemd/system/podman@.service" + +echo "[Unit] +Description=podman %I container + +[Service] +Restart=always +ExecStart=/usr/bin/podman start -a %i +ExecStop=/usr/bin/podman stop -t 2 %i + +[Install] +WantedBy=local.target" > $service_path +systemctl enable --now podman@container_homeassistant &>/dev/null + msg "Customizing container..." rm /etc/motd rm /etc/update-motd.d/10-uname From 3aa7e08204d44bfd614b0264b304429337b28eef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Nov 2021 22:45:43 -0500 Subject: [PATCH 0390/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 79621eff..9c4eb6eb 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -66,7 +66,7 @@ ExecStop=/usr/bin/podman stop -t 2 %i [Install] WantedBy=local.target" > $service_path -systemctl enable --now podman@container_homeassistant &>/dev/null +systemctl enable --now podman@homeassistant &>/dev/null msg "Customizing container..." rm /etc/motd From 18273b8e2808d1537e0f18813f5a6f45759357a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Nov 2021 23:15:22 -0500 Subject: [PATCH 0391/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 9c4eb6eb..e99fd6d9 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -53,20 +53,13 @@ podman run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -echo "Creating service file podman@.service" -service_path="/etc/systemd/system/podman@.service" +podman generate systemd \ + --new --name homeassistant \ + > /etc/systemd/system/homeassistant.service &>/dev/null -echo "[Unit] -Description=podman %I container +systemctl enable homeassistant +systemctl start homeassistant -[Service] -Restart=always -ExecStart=/usr/bin/podman start -a %i -ExecStop=/usr/bin/podman stop -t 2 %i - -[Install] -WantedBy=local.target" > $service_path -systemctl enable --now podman@homeassistant &>/dev/null msg "Customizing container..." rm /etc/motd From 6af306a250137bf66362a7c432aecac51dd07808 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Nov 2021 23:27:23 -0500 Subject: [PATCH 0392/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index e99fd6d9..5bd50159 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -57,8 +57,8 @@ podman generate systemd \ --new --name homeassistant \ > /etc/systemd/system/homeassistant.service &>/dev/null -systemctl enable homeassistant -systemctl start homeassistant +#systemctl enable homeassistant +#systemctl start homeassistant msg "Customizing container..." From c31048d52cde12c8f991edd4c0d34613a899b707 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Nov 2021 23:42:07 -0500 Subject: [PATCH 0393/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 5bd50159..15a424f4 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -53,14 +53,6 @@ podman run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -podman generate systemd \ - --new --name homeassistant \ - > /etc/systemd/system/homeassistant.service &>/dev/null - -#systemctl enable homeassistant -#systemctl start homeassistant - - msg "Customizing container..." rm /etc/motd rm /etc/update-motd.d/10-uname From b5f493a21358cf9dacde175ccb74f6ebbfc8132b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 00:13:35 -0500 Subject: [PATCH 0394/6505] Update README.md --- README.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/README.md b/README.md index db5e6179..ae442607 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,51 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X”
+
+Home Assistant Container LXC (Podman) + +

+@home-assistant

+ +

Proxmox Podman Home Assistant Container LXC

+ +To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" +``` +

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. + +**Home Assistant Interface - IP:8123** + + +Path to HA /config +``` +/var/lib/containers/storage/volumes/hass_config/_data + ``` +To edit the HA configuration.yaml (run from the Home Assistant container LXC console) +``` +nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + +To autostart Home Assistant at every boot (run from the LXC console) +``` +podman generate systemd \ + --new --name homeassistant \ + > /etc/systemd/system/homeassistant.service +systemctl enable homeassistant +``` +Check the status of homeassistant service (run from the LXC console) +``` +systemctl status homeassistant +``` + + + +
From 8c438e26ff647fe523c7ccf037c85b901c6207e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 00:26:53 -0500 Subject: [PATCH 0395/6505] Add files via upload --- Podman_HACS.md | 11 +++++++++++ podman_hacs.sh | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 Podman_HACS.md create mode 100644 podman_hacs.sh diff --git a/Podman_HACS.md b/Podman_HACS.md new file mode 100644 index 00000000..d17ff9d8 --- /dev/null +++ b/Podman_HACS.md @@ -0,0 +1,11 @@ +

Home Assistant Community Store

+ +

+ +

⚠️ This script is for installing HACS on Podman Home Assistant Container LXC ONLY ⚠️

+ +Run the following from the Home Assistant Container LXC console +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. \ No newline at end of file diff --git a/podman_hacs.sh b/podman_hacs.sh new file mode 100644 index 00000000..4cebe949 --- /dev/null +++ b/podman_hacs.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" + +while true; do + read -p "Start the HACS Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +apt update &>/dev/null +apt install unzip &>/dev/null +cd /var/lib/containers/storage/volumes/hass_config/_data +wget -O - https://get.hacs.xyz | bash - + +# To install HACS run the following from the container (LXC) console +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" +# Then add the integration in HA \ No newline at end of file From f68213e00fc7c9a884f3305ca353d94ca72e2756 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 00:28:40 -0500 Subject: [PATCH 0396/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index ae442607..59ae68f9 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,6 @@ After the script completes, If you're dissatisfied with the default settings, cl **Home Assistant Interface - IP:8123** - Path to HA /config ``` /var/lib/containers/storage/volumes/hass_config/_data @@ -126,7 +125,7 @@ Check the status of homeassistant service (run from the LXC console) ``` systemctl status homeassistant ``` - +[Install HACS](https://github.com/tteck/Proxmox/blob/main/Podman_HACS.md)
From 4c47b9ee3fde24b1f5fcd2fd8f536802b209742f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:22:45 -0500 Subject: [PATCH 0397/6505] Update and rename pve7_zigbee2mqtt_setup.sh to zigbee2mqtt_setup.sh --- pve7_zigbee2mqtt_setup.sh => zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename pve7_zigbee2mqtt_setup.sh => zigbee2mqtt_setup.sh (97%) diff --git a/pve7_zigbee2mqtt_setup.sh b/zigbee2mqtt_setup.sh similarity index 97% rename from pve7_zigbee2mqtt_setup.sh rename to zigbee2mqtt_setup.sh index 083a9766..fabb3dd6 100644 --- a/pve7_zigbee2mqtt_setup.sh +++ b/zigbee2mqtt_setup.sh @@ -87,4 +87,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /pve7_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c276e2302846b79c38389baa057fa819fca02c5c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:24:25 -0500 Subject: [PATCH 0398/6505] Update and rename pve7_zigbee2mqtt_container.sh to zigbee2mqtt_container.sh --- pve7_zigbee2mqtt_container.sh => zigbee2mqtt_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename pve7_zigbee2mqtt_container.sh => zigbee2mqtt_container.sh (96%) diff --git a/pve7_zigbee2mqtt_container.sh b/zigbee2mqtt_container.sh similarity index 96% rename from pve7_zigbee2mqtt_container.sh rename to zigbee2mqtt_container.sh index 0b88b7bc..e8a9875f 100644 --- a/pve7_zigbee2mqtt_container.sh +++ b/zigbee2mqtt_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_zigbee2mqtt_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/zigbee2mqtt_setup.sh # Detect modules and automatically load at boot load_module overlay @@ -169,8 +169,8 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID pve7_zigbee2mqtt_setup.sh /pve7_zigbee2mqtt_setup.sh -perms 755 -pct exec $CTID /pve7_zigbee2mqtt_setup.sh +pct push $CTID zigbee2mqtt_setup.sh /zigbee2mqtt_setup.sh -perms 755 +pct exec $CTID /zigbee2mqtt_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 9ad579dfaaeb73baded62c378c0fe7f93d952ee7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:25:44 -0500 Subject: [PATCH 0399/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 59ae68f9..fcf098e8 100644 --- a/README.md +++ b/README.md @@ -503,7 +503,7 @@ bash update.sh To create a new Proxmox 7 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_zigbee2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigbee2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

From 0cf2d9f8900b8ecd178ef9fe96840158ca23e8fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:28:14 -0500 Subject: [PATCH 0400/6505] Update and rename pve7_ha_setup.sh to ha_setup.sh --- pve7_ha_setup.sh => ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename pve7_ha_setup.sh => ha_setup.sh (97%) diff --git a/pve7_ha_setup.sh b/ha_setup.sh similarity index 97% rename from pve7_ha_setup.sh rename to ha_setup.sh index 10f21cf6..660918f9 100644 --- a/pve7_ha_setup.sh +++ b/ha_setup.sh @@ -97,4 +97,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # Cleanup container msg "Cleanup..." -rm -rf /pve7_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c8f4c89d6bd055761b37e92df7c31af9ac97718a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:29:33 -0500 Subject: [PATCH 0401/6505] Update and rename pve7_ha_container.sh to ha_container.sh --- pve7_ha_container.sh => ha_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename pve7_ha_container.sh => ha_container.sh (96%) diff --git a/pve7_ha_container.sh b/ha_container.sh similarity index 96% rename from pve7_ha_container.sh rename to ha_container.sh index d705c9a9..0a15609c 100644 --- a/pve7_ha_container.sh +++ b/ha_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ha_setup.sh # Detect modules and automatically load at boot load_module overlay @@ -172,8 +172,8 @@ pct unmount $CTID && unset MOUNT # Setup container msg "Starting LXC container..." pct start $CTID -pct push $CTID pve7_ha_setup.sh /pve7_ha_setup.sh -perms 755 -pct exec $CTID /pve7_ha_setup.sh +pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 +pct exec $CTID /ha_setup.sh # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 84d83162ab4daccb1f3b0f47d711b6442b03b016 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:30:19 -0500 Subject: [PATCH 0402/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fcf098e8..7b757b19 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ systemctl status homeassistant To create a new Proxmox 7 Home Assistant Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve7_ha_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ha_container.sh)" ```

⚡ Default Settings: 4GB RAM - 16GB Storage - 2vCPU ⚡

From d589387e36517ce6ae47a91b0fbe4684b4945605 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:32:12 -0500 Subject: [PATCH 0403/6505] Update ha_container.sh --- ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ha_container.sh b/ha_container.sh index 0a15609c..3840cfa6 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "This will create a New Home Assistant LXC Container. Proceed(y/n)?" yn + read -p "This will create a New Home Assistant Container LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From 27328372492c46f95b42e380d76ec467a42d6656 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 01:33:18 -0500 Subject: [PATCH 0404/6505] Update podman_ha_container.sh --- podman_ha_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/podman_ha_container.sh b/podman_ha_container.sh index de697234..6cec73d0 100644 --- a/podman_ha_container.sh +++ b/podman_ha_container.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "This will create a New Home Assistant LXC Container. Proceed(y/n)?" yn + read -p "This will create a New Podman Home Assistant Container LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -160,4 +160,4 @@ msg " Home Assistant is reachable by going to the following URLs. http://${IP}:8123 -" \ No newline at end of file +" From f9d0124ccead847abe8727855831b3f18c7e34ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 07:40:50 -0500 Subject: [PATCH 0405/6505] Update README.md --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b757b19..bf3753d4 100644 --- a/README.md +++ b/README.md @@ -491,7 +491,6 @@ bash update.sh -
Zigbee2MQTT LXC @@ -558,6 +557,28 @@ bash update.sh
+
+Zwavejs2MQTT LXC + +

+ +

Proxmox Zwave2js2MQTT LXC Container

+ +To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_container.sh)" +``` +

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

+ +To start Zwavejs2Mqtt (run from the LXC console) + ``` +cd zwavejs2mqtt +./zwavejs2mqtt + ``` +**Zwavejs2MQTT Interface - IP:8091** + +
From f8cf666326ba6a24b8b38139e0ab8254693c092d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:05:16 -0500 Subject: [PATCH 0406/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bf3753d4..843b2d80 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X”

Proxmox Podman Home Assistant Container LXC

To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. +[( What is Podman? )](https://github.com/tteck/Proxmox/blob/main/HACS.md) ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" From 3b10f1033b360df44580e891fb69cd60609d9771 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:06:22 -0500 Subject: [PATCH 0407/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 843b2d80..ffb35340 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X”

Proxmox Podman Home Assistant Container LXC

To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. -[( What is Podman? )](https://github.com/tteck/Proxmox/blob/main/HACS.md) +[( What is Podman? )](https://github.com/tteck/Proxmox/blob/main/Podman.md) ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" From 174a783c8a0f25e33ae4960f89485c32563dcf97 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:06:48 -0500 Subject: [PATCH 0408/6505] Add files via upload --- Podman.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Podman.md diff --git a/Podman.md b/Podman.md new file mode 100644 index 00000000..f233cc5a --- /dev/null +++ b/Podman.md @@ -0,0 +1,7 @@ +Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System. Similar to Docker, Podman is an open source project. Anybody can check out the source code for the program. Contrary to Docker, Podman does not require a daemon process to launch and manage containers. This is an important difference between the two projects. + +Podman seeks to improve on some of Docker’s drawbacks. For one, Podman does not require a daemon running as root. In fact, Podman containers run with the same permissions as the user who launched them. This addresses a significant security concern, although you can still run containers with root permissions if you really want to. + +Podman seeks to be a drop-in replacement for Docker as far as the CLI is concerned. The developers boast that most users can simply use alias docker=podman and continue running the same familiar commands. The container image format is also fully compatible between Docker and Podman, so existing containers built on Dockerfiles will work with Podman. + +Another key difference is that, it handles running containers, but not building them (non-monolithic). The goal here is to have a set of container standards that any application can be developed to support, rather than relying on a single monolithic application such as Docker to perform all duties. \ No newline at end of file From b4a91e2555ee9f6e39d7afa7820e8368c93cd069 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:13:48 -0500 Subject: [PATCH 0409/6505] Update Podman.md --- Podman.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Podman.md b/Podman.md index f233cc5a..caa1cff6 100644 --- a/Podman.md +++ b/Podman.md @@ -1,7 +1,11 @@ +

+ Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System. Similar to Docker, Podman is an open source project. Anybody can check out the source code for the program. Contrary to Docker, Podman does not require a daemon process to launch and manage containers. This is an important difference between the two projects. Podman seeks to improve on some of Docker’s drawbacks. For one, Podman does not require a daemon running as root. In fact, Podman containers run with the same permissions as the user who launched them. This addresses a significant security concern, although you can still run containers with root permissions if you really want to. Podman seeks to be a drop-in replacement for Docker as far as the CLI is concerned. The developers boast that most users can simply use alias docker=podman and continue running the same familiar commands. The container image format is also fully compatible between Docker and Podman, so existing containers built on Dockerfiles will work with Podman. -Another key difference is that, it handles running containers, but not building them (non-monolithic). The goal here is to have a set of container standards that any application can be developed to support, rather than relying on a single monolithic application such as Docker to perform all duties. \ No newline at end of file +Another key difference is that, it handles running containers, but not building them (non-monolithic). The goal here is to have a set of container standards that any application can be developed to support, rather than relying on a single monolithic application such as Docker to perform all duties. + +https://www.liquidweb.com/kb/podman-vs-docker/ ________________________________________________ https://podman.io/ From 947adeda4e7dafc1e4e0bd405d1b3e9568b1c6cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:15:04 -0500 Subject: [PATCH 0410/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ffb35340..78315da3 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X”

Proxmox Podman Home Assistant Container LXC

To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. + [( What is Podman? )](https://github.com/tteck/Proxmox/blob/main/Podman.md) ``` From 92b034bda7f868814a7674af450eb868192a68bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:17:51 -0500 Subject: [PATCH 0411/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 78315da3..d5fe8f36 100644 --- a/README.md +++ b/README.md @@ -93,9 +93,9 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X”

Proxmox Podman Home Assistant Container LXC

-To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. +To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. -[( What is Podman? )](https://github.com/tteck/Proxmox/blob/main/Podman.md) + [( What is Podman? )](https://github.com/tteck/Proxmox/blob/main/Podman.md) ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" From 1bc7655cef131a70a2ca5d931b39760ab3933e15 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:41:25 -0500 Subject: [PATCH 0412/6505] Update Podman.md --- Podman.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podman.md b/Podman.md index caa1cff6..34b45371 100644 --- a/Podman.md +++ b/Podman.md @@ -8,4 +8,4 @@ Podman seeks to be a drop-in replacement for Docker as far as the CLI is concern Another key difference is that, it handles running containers, but not building them (non-monolithic). The goal here is to have a set of container standards that any application can be developed to support, rather than relying on a single monolithic application such as Docker to perform all duties. -https://www.liquidweb.com/kb/podman-vs-docker/ ________________________________________________ https://podman.io/ +https://www.liquidweb.com/kb/podman-vs-docker/ ___ https://github.com/containers/podman-compose ___ https://podman.io/ From 596930e2ef0f879bc89cbef23c22b9b5006026d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 08:45:16 -0500 Subject: [PATCH 0413/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5fe8f36..f4ac5e6f 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. - [( What is Podman? )](https://github.com/tteck/Proxmox/blob/main/Podman.md) + ([What is Podman?](https://github.com/tteck/Proxmox/blob/main/Podman.md)) ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" From a35627698d01f1613d180608489f65f33cdcbc1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Nov 2021 09:09:56 -0500 Subject: [PATCH 0414/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f4ac5e6f..70c3d298 100644 --- a/README.md +++ b/README.md @@ -564,7 +564,7 @@ bash update.sh

-

Proxmox Zwave2js2MQTT LXC Container

+

Proxmox Zwavejs2MQTT LXC Container

To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. From b33267f9dfa228e07a81c2d683ecf6fb2bc375a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:12:25 -0500 Subject: [PATCH 0415/6505] Update README.md --- README.md | 128 ++++++++---------------------------------------------- 1 file changed, 19 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 70c3d298..70a4f76a 100644 --- a/README.md +++ b/README.md @@ -46,45 +46,6 @@ After the script completes, If you're dissatisfied with the default settings, cl - -
-Home Assistant Container LXC (PVE6) - -

Docker Logos | Docker -@home-assistantGitHub - portainer/portainer-docs: Portainer documentation

- -

Proxmox 6 Home Assistant Container LXC

- -To create a new Proxmox 6 Home Assistant Container, run the following from Proxmox web shell. - -``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_container.sh)" -``` -

⚡ Default Settings: 4GB RAM - 16GB Storage - 2vCPU ⚡

- -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. - -**Home Assistant Interface - IP:8123** - -**Portainer Interface - IP:9000** - -Path to HA /config -``` -/var/lib/docker/volumes/hass_config/_data - ``` -To edit the HA configuration.yaml (run from the Home Assistant container LXC console) -``` -nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -[To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) - -[Install HACS](https://github.com/tteck/Proxmox/blob/main/HACS.md) - -
- -
Home Assistant Container LXC (Podman) @@ -141,7 +102,7 @@ systemctl status homeassistant

Proxmox Home Assistant Container LXC

-To create a new Proxmox 7 Home Assistant Container, run the following from Proxmox web shell. +To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ha_container.sh)" @@ -165,10 +126,26 @@ nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -[To pass through a device for ZHA](https://github.com/tteck/Proxmox/blob/main/Alternative.md#zha-device-pass-through) -[Install HACS](https://github.com/tteck/Proxmox/blob/main/HACS.md) +**To allow device passthrough:** +In the Proxmox web shell run (replace 106 with your LXC ID) +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +``` + +Reboot the LXC to apply the changes + + +**To install HACS** + +Run the following from the Home Assistant Container LXC console +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + +____________________________________________________________________________________________
@@ -426,73 +403,6 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m - -
-Zigbee2MQTT LXC (PVE6) - -

logo.png

- -

Proxmox 6 Zigbee2MQTT LXC Container

- -To create a new Proxmox 6 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. - -``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_zigbee2mqtt_container.sh)" -``` -

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

- -Determine the location of your adapter (Run in the zigbee2mqtt console) -``` -ls -l /dev/serial/by-id -``` -Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` - - If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) - -⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** -``` -nano /opt/zigbee2mqtt/data/configuration.yaml -``` - -Example: -``` -frontend: - port: 9442 -homeassistant: true -permit_join: false -mqtt: - base_topic: zigbee2mqtt - server: 'mqtt://192.168.86.224:1883' - user: usr - password: pwd - keepalive: 60 - reject_unauthorized: true - version: 4 -serial: - port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 -advanced: - pan_id: GENERATE - network_key: GENERATE - channel: 20 - ``` -Zigbee2mqtt can be started after completing the configuration by running -``` -sudo systemctl start zigbee2mqtt -``` -To start Zigbee2MQTT automatically on boot - ``` -sudo systemctl enable zigbee2mqtt.service - ``` -To update Zigbee2Mqtt - ``` -cd /opt/zigbee2mqtt -bash update.sh - ``` - -
- - -
Zigbee2MQTT LXC From 1d1be9c7b6e867ba12beff68e024b4c368b41f2b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:18:36 -0500 Subject: [PATCH 0416/6505] Update README.md --- README.md | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 70a4f76a..39eb8297 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post ``` It's recommended to update Proxmox after running this script, before adding any VM/CT. +____________________________________________________________________________________________
@@ -41,6 +42,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. **Home Assistant Interface - IP:8123** +____________________________________________________________________________________________
@@ -90,7 +92,7 @@ systemctl status homeassistant ``` [Install HACS](https://github.com/tteck/Proxmox/blob/main/Podman_HACS.md) - +____________________________________________________________________________________________
@@ -137,7 +139,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/auto Reboot the LXC to apply the changes -**To install HACS** +**To install HACS:** Run the following from the Home Assistant Container LXC console ``` @@ -167,6 +169,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esph

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

**ESPHome Interface - IP:6052** + +____________________________________________________________________________________________
@@ -214,7 +218,8 @@ Add the following to your `configuration.yaml` in Home Assistant. Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. - + ____________________________________________________________________________________________ +
@@ -259,6 +264,7 @@ Now restart Mosquitto server. sudo systemctl restart mosquitto ``` +____________________________________________________________________________________________
@@ -294,6 +300,8 @@ From your nodered LXC console, the following commands can be run `sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-restart` after update) **Node-Red Interface - IP:1880** + +____________________________________________________________________________________________
@@ -396,6 +404,7 @@ Change the recorder: `db_url:` in your HA configuration.yaml Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4` +____________________________________________________________________________________________
@@ -466,6 +475,8 @@ cd /opt/zigbee2mqtt bash update.sh ``` +____________________________________________________________________________________________ +
@@ -489,7 +500,9 @@ cd zwavejs2mqtt ./zwavejs2mqtt ``` **Zwavejs2MQTT Interface - IP:8091** - + +____________________________________________________________________________________________ +
@@ -509,6 +522,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debi After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +____________________________________________________________________________________________ +
@@ -530,6 +545,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debi After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +____________________________________________________________________________________________ +
@@ -555,8 +572,12 @@ To set your password (Run in the pi-hole console) pihole -a -p ``` +____________________________________________________________________________________________ +
+ +
AdGuard Home LXC @@ -573,4 +594,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adgu **AdGuard Home Interface - IP:3000** +____________________________________________________________________________________________ +
From ecdf27dadda95d74f6d6b8976d578996719b8b66 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:20:26 -0500 Subject: [PATCH 0417/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 39eb8297..9abad0b7 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post ``` It's recommended to update Proxmox after running this script, before adding any VM/CT. + ____________________________________________________________________________________________
@@ -42,6 +43,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. **Home Assistant Interface - IP:8123** + ____________________________________________________________________________________________
From 06e419f975d54f2df69e36f1c25239514b34321f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:23:23 -0500 Subject: [PATCH 0418/6505] Update README.md --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9abad0b7..ff4e3fac 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,15 @@ Check the status of homeassistant service (run from the LXC console) ``` systemctl status homeassistant ``` -[Install HACS](https://github.com/tteck/Proxmox/blob/main/Podman_HACS.md) + + **To install HACS:** + +Run the following from the Home Assistant Container LXC console +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + ____________________________________________________________________________________________
From 427993f7ce53619b1209d0dd80051a2929151c56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:24:19 -0500 Subject: [PATCH 0419/6505] Delete HACS.md --- HACS.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 HACS.md diff --git a/HACS.md b/HACS.md deleted file mode 100644 index ddbded9e..00000000 --- a/HACS.md +++ /dev/null @@ -1,11 +0,0 @@ -

Home Assistant Community Store

- -

- -

⚠️ This script is for installing HACS on Home Assistant Container LXC ONLY ⚠️

- -Run the following from the Home Assistant Container LXC console -``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. From 3181263f0eaf4fdd8a6e177efa0dc7b7f90ae371 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:24:45 -0500 Subject: [PATCH 0420/6505] Delete Podman_HACS.md --- Podman_HACS.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 Podman_HACS.md diff --git a/Podman_HACS.md b/Podman_HACS.md deleted file mode 100644 index d17ff9d8..00000000 --- a/Podman_HACS.md +++ /dev/null @@ -1,11 +0,0 @@ -

Home Assistant Community Store

- -

- -

⚠️ This script is for installing HACS on Podman Home Assistant Container LXC ONLY ⚠️

- -Run the following from the Home Assistant Container LXC console -``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. \ No newline at end of file From f31e81c433297a5ebeb770ea0bd4f3c18e42f48c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:27:20 -0500 Subject: [PATCH 0421/6505] Update zigbee2mqtt_container.sh --- zigbee2mqtt_container.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/zigbee2mqtt_container.sh b/zigbee2mqtt_container.sh index e8a9875f..9d84626e 100644 --- a/zigbee2mqtt_container.sh +++ b/zigbee2mqtt_container.sh @@ -155,10 +155,8 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ # Modify LXC permissions to support Zigbee Sticks LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.cgroup2.devices.allow: a +lxc.cap.drop: EOF # Set container timezone to match host From 1382733d6e5f8eaafc1177007a6adb9dd58fe3e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:30:08 -0500 Subject: [PATCH 0422/6505] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index ff4e3fac..6fe38fc1 100644 --- a/README.md +++ b/README.md @@ -437,6 +437,17 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigb ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

+ +**To allow device passthrough:** + +In the Proxmox web shell run (replace 106 with your LXC ID) +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +``` + +Reboot the LXC to apply the changes + + Determine the location of your adapter (Run in the zigbee2mqtt console) ``` ls -l /dev/serial/by-id From 93ff2fc786d1c0b1b0699e4161f08d03553d982b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:31:08 -0500 Subject: [PATCH 0423/6505] Delete Alternative.md --- Alternative.md | 50 -------------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 Alternative.md diff --git a/Alternative.md b/Alternative.md deleted file mode 100644 index 205d09f7..00000000 --- a/Alternative.md +++ /dev/null @@ -1,50 +0,0 @@ -## Zigbee2MQTT Device Pass Through ## - - -**Alternative method to pass devices to LXC:** - -In the Proxmox web shell run (replace `105` with your zigbee2mqtt lxc Id) -``` -nano /etc/pve/lxc/105.conf -``` -replace the last 4 lines -``` -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -``` -with these 4 lines (change `cgroup2` to `cgroup` for PVE6) -``` -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.autodev: 1 -lxc.hook.autodev: bash -c 'for char_dev in $(find /sys/dev/char -regextype sed -regex ".*/1:1" -o -regex ".*/4:\([3-9]\|[1-5][0-9]\|6[0-3]\)" -o -regex ".*/4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)" -o -regex ".*/10:200" -o -regex ".*/116:.*" -o -regex ".*/166:.*" -o -regex ".*/180:\([0-9]\|1[0-5]\)" -o -regex ".*/188:.*" -o -regex ".*/189:.*" -o -regex ".*/24[0-2]:.*"); do dev="/dev/$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" ${char_dev}/uevent)"; mkdir -p $(dirname ${LXC_ROOTFS_MOUNT}${dev}); for link in $(udevadm info --query=property $dev | sed -n "s/DEVLINKS=//p"); do mkdir -p ${LXC_ROOTFS_MOUNT}$(dirname $link); cp -dpR $link ${LXC_ROOTFS_MOUNT}${link}; done; cp -dpR $dev ${LXC_ROOTFS_MOUNT}${dev};done;' -``` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X" - -Reboot the LXC -________________________________________________________________________________________________________________________________________ - -## ZHA Device Pass Through ## - -In the Proxmox web shell run (replace `105` with your home assistant container lxc Id) -``` -nano /etc/pve/lxc/105.conf -``` -add these 2 lines to the bottom -``` -lxc.autodev: 1 -lxc.hook.autodev: bash -c 'for char_dev in $(find /sys/dev/char -regextype sed -regex ".*/1:1" -o -regex ".*/4:\([3-9]\|[1-5][0-9]\|6[0-3]\)" -o -regex ".*/4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)" -o -regex ".*/10:200" -o -regex ".*/116:.*" -o -regex ".*/166:.*" -o -regex ".*/180:\([0-9]\|1[0-5]\)" -o -regex ".*/188:.*" -o -regex ".*/189:.*" -o -regex ".*/24[0-2]:.*"); do dev="/dev/$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" ${char_dev}/uevent)"; mkdir -p $(dirname ${LXC_ROOTFS_MOUNT}${dev}); for link in $(udevadm info --query=property $dev | sed -n "s/DEVLINKS=//p"); do mkdir -p ${LXC_ROOTFS_MOUNT}$(dirname $link); cp -dpR $link ${LXC_ROOTFS_MOUNT}${link}; done; cp -dpR $dev ${LXC_ROOTFS_MOUNT}${dev};done;' -``` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X" - -Reboot the LXC - - - - - - - - From f51b6024d4882b31f52c77a9fe1ca0851811543e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:33:11 -0500 Subject: [PATCH 0424/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 6fe38fc1..59fe7793 100644 --- a/README.md +++ b/README.md @@ -454,9 +454,8 @@ ls -l /dev/serial/by-id ``` Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` - If you are having diffucuilty with device pass through or starting check the [Alternative method](https://github.com/tteck/Proxmox/blob/main/Alternative.md) - ⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** +⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** ``` nano /opt/zigbee2mqtt/data/configuration.yaml ``` From a646d33a03562aa36d6a5e3a5b1171f2a9ad06f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 10:37:46 -0500 Subject: [PATCH 0425/6505] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 59fe7793..fd358a49 100644 --- a/README.md +++ b/README.md @@ -521,6 +521,15 @@ cd zwavejs2mqtt ``` **Zwavejs2MQTT Interface - IP:8091** +**To allow device passthrough:** + +In the Proxmox web shell run (replace 106 with your LXC ID) +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +``` + +Reboot the LXC to apply the changes + ____________________________________________________________________________________________
From a714cb8cdd34dd064266975203d19233703a977f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:14:04 -0500 Subject: [PATCH 0426/6505] Update README.md --- README.md | 56 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index fd358a49..2b4ff279 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt the *No-Nag* fix. -Run the following in the Proxmox Web Shell. ⚠️ *_PVE7 ONLY_* +Run the following in the Proxmox Web Shell. ⚠️ **PVE7 ONLY** ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" @@ -71,31 +71,37 @@ After the script completes, If you're dissatisfied with the default settings, cl **Home Assistant Interface - IP:8123** -Path to HA /config +⚙️ **Path to HA /config** ``` /var/lib/containers/storage/volumes/hass_config/_data ``` -To edit the HA configuration.yaml (run from the Home Assistant container LXC console) +⚙️ **To edit the HA configuration.yaml** + +Run from the LXC console ``` nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -To autostart Home Assistant at every boot (run from the LXC console) +⚙️ **To autostart Home Assistant at every boot:** + +Run from the LXC console ``` podman generate systemd \ --new --name homeassistant \ > /etc/systemd/system/homeassistant.service systemctl enable homeassistant ``` -Check the status of homeassistant service (run from the LXC console) +⚙️ **Check the status of homeassistant service:** + +Run from the LXC console ``` systemctl status homeassistant ``` - **To install HACS:** +⚙️ **To install HACS:** -Run the following from the Home Assistant Container LXC console +Run the from the LXC console ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" ``` @@ -128,20 +134,22 @@ After the script completes, If you're dissatisfied with the default settings, cl **Portainer Interface - IP:9000** -Path to HA /config +⚙️ **Path to HA /config** ``` /var/lib/docker/volumes/hass_config/_data ``` -To edit the HA configuration.yaml (run from the Home Assistant container LXC console) +⚙️ **To edit the HA configuration.yaml** + +Run from the LXC console ``` nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -**To allow device passthrough:** +⚙️ **To allow device passthrough:** -In the Proxmox web shell run (replace 106 with your LXC ID) +In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 ``` @@ -149,9 +157,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/auto Reboot the LXC to apply the changes -**To install HACS:** +⚙️ **To install HACS:** -Run the following from the Home Assistant Container LXC console +Run the from the LXC console ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" ``` @@ -438,9 +446,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigb

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

-**To allow device passthrough:** +⚙️ **To allow device passthrough:** -In the Proxmox web shell run (replace 106 with your LXC ID) +In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 ``` @@ -448,7 +456,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/auto Reboot the LXC to apply the changes -Determine the location of your adapter (Run in the zigbee2mqtt console) +⚙️ **Determine the location of your adapter** + +Run in the zigbee2mqtt console ``` ls -l /dev/serial/by-id ``` @@ -481,15 +491,15 @@ advanced: network_key: GENERATE channel: 20 ``` -Zigbee2mqtt can be started after completing the configuration by running +⚙️ **Zigbee2mqtt can be started after completing the configuration** ``` sudo systemctl start zigbee2mqtt ``` -To start Zigbee2MQTT automatically on boot +⚙️ **To start Zigbee2MQTT automatically on boot** ``` sudo systemctl enable zigbee2mqtt.service ``` -To update Zigbee2Mqtt +⚙️ **To update Zigbee2Mqtt** ``` cd /opt/zigbee2mqtt bash update.sh @@ -514,16 +524,18 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwav ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

-To start Zwavejs2Mqtt (run from the LXC console) +⚙️ **To start Zwavejs2Mqtt** + +Run from the LXC console ``` cd zwavejs2mqtt ./zwavejs2mqtt ``` **Zwavejs2MQTT Interface - IP:8091** -**To allow device passthrough:** +⚙️ **To allow device passthrough:** -In the Proxmox web shell run (replace 106 with your LXC ID) +In the Proxmox web shell run (**replace `106` with your LXC ID)** ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 ``` From 98cb3bda7fb8b4b5a8312a0b394e89b562c80c9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:23:07 -0500 Subject: [PATCH 0427/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b4ff279..209e4b2d 100644 --- a/README.md +++ b/README.md @@ -438,7 +438,7 @@ ________________________________________________________________________________

Proxmox Zigbee2MQTT LXC Container

-To create a new Proxmox 7 [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. +To create a new Proxmox [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigbee2mqtt_container.sh)" From ee71b26f0c1651a44d654cad6aaf85170be3f4d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:25:21 -0500 Subject: [PATCH 0428/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 209e4b2d..8d9e1404 100644 --- a/README.md +++ b/README.md @@ -607,7 +607,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/piho ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

-To set your password (Run in the pi-hole console) +⚙️ **To set your password:** + +Run in the LXC console ``` pihole -a -p From 138693bf3e43cefce3db41949d91abb009f6b771 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:27:28 -0500 Subject: [PATCH 0429/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d9e1404..829f4f52 100644 --- a/README.md +++ b/README.md @@ -609,7 +609,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/piho ⚙️ **To set your password:** -Run in the LXC console +Run from the LXC console ``` pihole -a -p From 323551e6a9c14be8dcb8064a41da002f0f6607b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:29:53 -0500 Subject: [PATCH 0430/6505] Delete pve6_zigbee2mqtt_setup.sh --- pve6_zigbee2mqtt_setup.sh | 90 --------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 pve6_zigbee2mqtt_setup.sh diff --git a/pve6_zigbee2mqtt_setup.sh b/pve6_zigbee2mqtt_setup.sh deleted file mode 100644 index 2163d8d4..00000000 --- a/pve6_zigbee2mqtt_setup.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up Container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - # Setup Node.js repository - msg "Setting up Node.js Repository..." - sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null - # Install Node.js; - msg "Installing Node.js..." - sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - # Clone Zigbee2MQTT repository - msg "Setting up Zigbee2MQTT Repository..." - sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null - # Install zigbee2mqtt - msg "Installing Zigbee2MQTT..." - cd /opt/zigbee2mqtt &>/dev/null - npm ci &>/dev/null - -echo "Creating service file zigbee2mqtt.service" -service_path="/etc/systemd/system/zigbee2mqtt.service" - -echo "[Unit] -Description=zigbee2mqtt -After=network.target -[Service] -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zigbee2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path - -# Customize container -msg "Customizing Container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /pve6_zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 1a06958fbfd3a28fc9504a7b1759e36d2917f878 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:30:06 -0500 Subject: [PATCH 0431/6505] Delete pve6_zigbee2mqtt_container.sh --- pve6_zigbee2mqtt_container.sh | 182 ---------------------------------- 1 file changed, 182 deletions(-) delete mode 100644 pve6_zigbee2mqtt_container.sh diff --git a/pve6_zigbee2mqtt_container.sh b/pve6_zigbee2mqtt_container.sh deleted file mode 100644 index e7580af8..00000000 --- a/pve6_zigbee2mqtt_container.sh +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Zigbee2MQTT LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_zigbee2mqtt_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=zigbee2mqtt -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Modify LXC permissions to support Zigbee Sticks -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup.devices.allow: c 188:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID pve6_zigbee2mqtt_setup.sh /pve6_zigbee2mqtt_setup.sh -perms 755 -pct exec $CTID /pve6_zigbee2mqtt_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" -echo -echo -e "\e[1;31m Update of configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" -echo -echo -e "Z2M can be started after completing the configuration buy running \e[1;33m sudo systemctl start zigbee2mqtt \e[0m" -echo From 8e7e101cc775585ffce5d16c4bff505f2308e258 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:30:26 -0500 Subject: [PATCH 0432/6505] Delete pve6_ha_setup.sh --- pve6_ha_setup.sh | 100 ----------------------------------------------- 1 file changed, 100 deletions(-) delete mode 100644 pve6_ha_setup.sh diff --git a/pve6_ha_setup.sh b/pve6_ha_setup.sh deleted file mode 100644 index 451fd81b..00000000 --- a/pve6_ha_setup.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing prerequisites..." -apt-get -qqy install \ - curl &>/dev/null - -# Customize Docker configuration -msg "Customizing Docker..." -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -# Install Docker -msg "Installing Docker..." -sh <(curl -sSL https://get.docker.com) &>/dev/null - -# Install Portainer -msg "Installing Portainer..." -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null - -# Install Home Assistant -msg "Installing Home Assistant..." -docker volume create hass_config >/dev/null -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /pve6_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 31960729ac954b4bbcc957b93fbb942ea1637483 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Nov 2021 11:30:40 -0500 Subject: [PATCH 0433/6505] Delete pve6_ha_container.sh --- pve6_ha_container.sh | 187 ------------------------------------------- 1 file changed, 187 deletions(-) delete mode 100644 pve6_ha_container.sh diff --git a/pve6_ha_container.sh b/pve6_ha_container.sh deleted file mode 100644 index 878331f6..00000000 --- a/pve6_ha_container.sh +++ /dev/null @@ -1,187 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Home Assistant LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pve6_ha_setup.sh - -# Detect modules and automatically load at boot -load_module aufs -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=16G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=homeassistant -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 4096 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Modify LXC permissions to support Docker -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup.devices.allow: a -lxc.cap.drop: -EOF - -# Set container description -pct set $CTID -description "Access Portainer interface using the following URL. - -http://:9000" - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID pve6_ha_setup.sh /pve6_ha_setup.sh -perms 755 -pct exec $CTID /pve6_ha_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Home Assistant Container LXC to $CTID." -msg " - -Home Assistant is reachable by going to the following URLs. - - http://${IP}:8123 -" From cee68e9f298474edfff5fc671063579b7827f1f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 19:32:47 -0500 Subject: [PATCH 0434/6505] Update README.md --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 829f4f52..ae9bb82b 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ and attempt the *No-Nag* fix. Run the following in the Proxmox Web Shell. ⚠️ **PVE7 ONLY** ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/post_install.sh)" ``` It's recommended to update Proxmox after running this script, before adding any VM/CT. @@ -36,7 +36,7 @@ ________________________________________________________________________________ To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/haos_vm.sh)" ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

@@ -60,10 +60,10 @@ ________________________________________________________________________________ To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. - ([What is Podman?](https://github.com/tteck/Proxmox/blob/main/Podman.md)) + ([What is Podman?](https://github.com/tteck/Proxmox2/blob/main/Podman.md)) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/podman_ha_container.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -103,7 +103,7 @@ systemctl status homeassistant Run the from the LXC console ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/podman_hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -123,7 +123,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ha_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/ha_container.sh)" ```

⚡ Default Settings: 4GB RAM - 16GB Storage - 2vCPU ⚡

@@ -151,7 +151,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -161,7 +161,7 @@ Reboot the LXC to apply the changes Run the from the LXC console ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -181,7 +181,7 @@ ________________________________________________________________________________ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/esphome_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -254,7 +254,7 @@ Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-pro To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/mqtt_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -301,7 +301,7 @@ ________________________________________________________________________________ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/node-red_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -336,7 +336,7 @@ ________________________________________________________________________________ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/mariadb_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -441,7 +441,7 @@ ________________________________________________________________________________ To create a new Proxmox [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigbee2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/zigbee2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -450,7 +450,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigb In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -520,7 +520,7 @@ ________________________________________________________________________________ To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/zwavejs2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -537,7 +537,7 @@ cd zwavejs2mqtt In the Proxmox web shell run (**replace `106` with your LXC ID)** ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -557,7 +557,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/debian10_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -580,7 +580,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian11_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/debian11_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -603,7 +603,7 @@ ________________________________________________________________________________ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/pihole_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -631,7 +631,7 @@ ________________________________________________________________________________ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adguard_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/adguard_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

From 51464c9ee0a771d896cb811ef2defdeee3b8f5f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 19:34:30 -0500 Subject: [PATCH 0435/6505] Update pihole_container.sh --- pihole_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole_container.sh b/pihole_container.sh index 874bd76c..abf6d55b 100644 --- a/pihole_container.sh +++ b/pihole_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox2/main/pihole_setup.sh load_module overlay From 32a329cff1a687064c7f920fc0483e3133285b0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 19:40:21 -0500 Subject: [PATCH 0436/6505] Update pihole_container.sh --- pihole_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole_container.sh b/pihole_container.sh index abf6d55b..874bd76c 100644 --- a/pihole_container.sh +++ b/pihole_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox2/main/pihole_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_setup.sh load_module overlay From 547d45216ed3f44e760cf0977369d207ebbd67fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 19:44:45 -0500 Subject: [PATCH 0437/6505] Update README.md --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index ae9bb82b..829f4f52 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ and attempt the *No-Nag* fix. Run the following in the Proxmox Web Shell. ⚠️ **PVE7 ONLY** ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/post_install.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" ``` It's recommended to update Proxmox after running this script, before adding any VM/CT. @@ -36,7 +36,7 @@ ________________________________________________________________________________ To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/haos_vm.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

@@ -60,10 +60,10 @@ ________________________________________________________________________________ To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. - ([What is Podman?](https://github.com/tteck/Proxmox2/blob/main/Podman.md)) + ([What is Podman?](https://github.com/tteck/Proxmox/blob/main/Podman.md)) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/podman_ha_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -103,7 +103,7 @@ systemctl status homeassistant Run the from the LXC console ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/podman_hacs.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -123,7 +123,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/ha_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ha_container.sh)" ```

⚡ Default Settings: 4GB RAM - 16GB Storage - 2vCPU ⚡

@@ -151,7 +151,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -161,7 +161,7 @@ Reboot the LXC to apply the changes Run the from the LXC console ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/hacs.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -181,7 +181,7 @@ ________________________________________________________________________________ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/esphome_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -254,7 +254,7 @@ Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-pro To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -301,7 +301,7 @@ ________________________________________________________________________________ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/node-red_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -336,7 +336,7 @@ ________________________________________________________________________________ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/mariadb_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -441,7 +441,7 @@ ________________________________________________________________________________ To create a new Proxmox [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/zigbee2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigbee2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -450,7 +450,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/zig In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -520,7 +520,7 @@ ________________________________________________________________________________ To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/zwavejs2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -537,7 +537,7 @@ cd zwavejs2mqtt In the Proxmox web shell run (**replace `106` with your LXC ID)** ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -557,7 +557,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/debian10_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -580,7 +580,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/debian11_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian11_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -603,7 +603,7 @@ ________________________________________________________________________________ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/pihole_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -631,7 +631,7 @@ ________________________________________________________________________________ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox2/main/adguard_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adguard_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

From af8fd48df89bbb6e54768c1aeecfa960ce57368e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 19:53:10 -0500 Subject: [PATCH 0438/6505] Update autodev.sh --- autodev.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autodev.sh b/autodev.sh index 7a608e28..ffa1f75a 100644 --- a/autodev.sh +++ b/autodev.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "Allow device passthrough to the predefined LXC container. Proceed(y/n)?" yn + read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -78,4 +78,4 @@ EOF # In the Proxmox web shell run (replace 106 with your LXC ID) # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 -# Reboot the LXC to apply the changes \ No newline at end of file +# Reboot the LXC to apply the changes From 46aa6b86d11ca21f1b00395645d2a0f87b0655fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 20:01:17 -0500 Subject: [PATCH 0439/6505] Update README.md --- README.md | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/README.md b/README.md index 829f4f52..400de467 100644 --- a/README.md +++ b/README.md @@ -547,28 +547,6 @@ ________________________________________________________________________________
-
-Debian 10+ LXC - -

Debian

- -

Proxmox Debian 10 LXC Container

- -To create a new Proxmox Debian 10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. - -``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_container.sh)" -``` -

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

- -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. - -____________________________________________________________________________________________ - -
- - -
Debian 11+ LXC From cc81de9243ab6dda9175e99ee49abc20178a2ba8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 20:01:33 -0500 Subject: [PATCH 0440/6505] Delete debian10_container.sh --- debian10_container.sh | 168 ------------------------------------------ 1 file changed, 168 deletions(-) delete mode 100644 debian10_container.sh diff --git a/debian10_container.sh b/debian10_container.sh deleted file mode 100644 index a0c5a22e..00000000 --- a/debian10_container.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Debian 10+ LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/debian10_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 10 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-10 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=debian10 -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID debian10_setup.sh /debian10_setup.sh -perms 755 -pct exec $CTID /debian10_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Debian 10 LXC Container to $CTID at IP Address ${IP}" From 9a2ec431b728a0790e31e970156548f630bcaef8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Nov 2021 20:01:43 -0500 Subject: [PATCH 0441/6505] Delete debian10_setup.sh --- debian10_setup.sh | 71 ----------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 debian10_setup.sh diff --git a/debian10_setup.sh b/debian10_setup.sh deleted file mode 100644 index 2d1a035c..00000000 --- a/debian10_setup.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt-get --allow-releaseinfo-change update >/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -# Customize Docker configuration -# msg "Customizing Docker..." -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /debian10_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 6286575da593eafb63f9edbaa026d3df8ee0116b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Dec 2021 07:46:57 -0500 Subject: [PATCH 0442/6505] Add files via upload --- core_container.sh | 174 ++++++++++++++++++++++++++++++++++++++++++++++ core_setup.sh | 74 ++++++++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 core_container.sh create mode 100644 core_setup.sh diff --git a/core_container.sh b/core_container.sh new file mode 100644 index 00000000..cc4b25e2 --- /dev/null +++ b/core_container.sh @@ -0,0 +1,174 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Home Assistant Core LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/core_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 10 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=16G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=homeassistant +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 4096 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID core_setup.sh /core_setup.sh -perms 755 +pct exec $CTID /core_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Home Assistant Core LXC to $CTID." +msg " + +Home Assistant is reachable by going to the following URLs. + + http://${IP}:8123 +" \ No newline at end of file diff --git a/core_setup.sh b/core_setup.sh new file mode 100644 index 00000000..8fd26882 --- /dev/null +++ b/core_setup.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get install -y curl sudo python3 python3-dev python3-venv python3-pip libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libopenjp2-7 libtiff5 libturbojpeg0 tzdata &>/dev/null + +msg "Installing Home Assistant Core..." +useradd -rm homeassistant &>/dev/null + +mkdir /srv/homeassistant &>/dev/null +chown homeassistant:homeassistant /srv/homeassistant &>/dev/null + +sudo -u homeassistant -H -s \ +cd /srv/homeassistant \ +python3.9 -m venv . \ +source bin/activate &>/dev/null + +python3 -m pip install wheel &>/dev/null + +pip3 install homeassistant &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /core_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 769df2405f4c47e00ae664b6d26af75020cf7952 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Dec 2021 07:59:02 -0500 Subject: [PATCH 0443/6505] Add files via upload --- core_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core_setup.sh b/core_setup.sh index 8fd26882..eced7597 100644 --- a/core_setup.sh +++ b/core_setup.sh @@ -40,10 +40,10 @@ msg "Installing prerequisites..." apt-get install -y curl sudo python3 python3-dev python3-venv python3-pip libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libopenjp2-7 libtiff5 libturbojpeg0 tzdata &>/dev/null msg "Installing Home Assistant Core..." -useradd -rm homeassistant &>/dev/null +sudo useradd -rm homeassistant &>/dev/null -mkdir /srv/homeassistant &>/dev/null -chown homeassistant:homeassistant /srv/homeassistant &>/dev/null +sudo mkdir /srv/homeassistant &>/dev/null +sudo chown homeassistant:homeassistant /srv/homeassistant &>/dev/null sudo -u homeassistant -H -s \ cd /srv/homeassistant \ From 05efbc81e4e9cd6f8c7453fecfcda58764e25f62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Dec 2021 08:06:13 -0500 Subject: [PATCH 0444/6505] Delete core_setup.sh --- core_setup.sh | 74 --------------------------------------------------- 1 file changed, 74 deletions(-) delete mode 100644 core_setup.sh diff --git a/core_setup.sh b/core_setup.sh deleted file mode 100644 index eced7597..00000000 --- a/core_setup.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing prerequisites..." -apt-get install -y curl sudo python3 python3-dev python3-venv python3-pip libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libopenjp2-7 libtiff5 libturbojpeg0 tzdata &>/dev/null - -msg "Installing Home Assistant Core..." -sudo useradd -rm homeassistant &>/dev/null - -sudo mkdir /srv/homeassistant &>/dev/null -sudo chown homeassistant:homeassistant /srv/homeassistant &>/dev/null - -sudo -u homeassistant -H -s \ -cd /srv/homeassistant \ -python3.9 -m venv . \ -source bin/activate &>/dev/null - -python3 -m pip install wheel &>/dev/null - -pip3 install homeassistant &>/dev/null - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /core_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 732008e364e53050fe7d35ea9ff72f036efd4c55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Dec 2021 08:06:24 -0500 Subject: [PATCH 0445/6505] Delete core_container.sh --- core_container.sh | 174 ---------------------------------------------- 1 file changed, 174 deletions(-) delete mode 100644 core_container.sh diff --git a/core_container.sh b/core_container.sh deleted file mode 100644 index cc4b25e2..00000000 --- a/core_container.sh +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Home Assistant Core LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/core_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 10 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=16G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=homeassistant -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 4096 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID core_setup.sh /core_setup.sh -perms 755 -pct exec $CTID /core_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Home Assistant Core LXC to $CTID." -msg " - -Home Assistant is reachable by going to the following URLs. - - http://${IP}:8123 -" \ No newline at end of file From 3c80d4158addfe91925da249e981a2737a7313c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Dec 2021 06:19:20 -0500 Subject: [PATCH 0446/6505] Update ha_container.sh --- ha_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ha_container.sh b/ha_container.sh index 3840cfa6..f46bb8a1 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -138,7 +138,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} # Create LXC msg "Creating LXC container..." -DISK_SIZE=16G +DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." @@ -149,7 +149,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 4096 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null # Modify LXC permissions to support Docker From 64f4514315da7a19ea0e75166f358fef01d06dae Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Dec 2021 06:20:12 -0500 Subject: [PATCH 0447/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 400de467..c62717aa 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ To create a new Proxmox Home Assistant Container, run the following from Proxmox bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ha_container.sh)" ``` -

⚡ Default Settings: 4GB RAM - 16GB Storage - 2vCPU ⚡

+

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. From c4d324de2f0bb8ed9ae82d57ed587a6ef476927b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Dec 2021 07:48:36 -0500 Subject: [PATCH 0448/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c62717aa..890b0a10 100644 --- a/README.md +++ b/README.md @@ -326,12 +326,12 @@ ________________________________________________________________________________
-Mariadb 10.5 LXC +Mariadb LXC

MariaDB

-

Proxmox Mariadb 10.5 LXC Container

+

Proxmox Mariadb LXC Container

To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. From 545e68641acd5a202a67f6ef77e1d39f3c2c4479 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Dec 2021 12:31:30 -0500 Subject: [PATCH 0449/6505] Update README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 890b0a10..8adf6090 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,27 @@ ________________________________________________________________________________
+
+Proxmox Dark Theme + +

+ +

Proxmox Dark Theme

+ +A dark theme for the Proxmox Web UI by [Weilbyte](https://github.com/Weilbyte/PVEDiscordDark) + +Run the following in the Proxmox Web Shell. + +``` +bash <(curl -s https://raw.githubusercontent.com/Weilbyte/PVEDiscordDark/master/PVEDiscordDark.sh ) install +``` + +To uninstall the theme, simply run the script with the `uninstall` command. + +____________________________________________________________________________________________ + +
+
Home Assistant OS VM From 15803e5d27abb5b3c7f9442934bd19a41c92475f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Dec 2021 12:35:18 -0500 Subject: [PATCH 0450/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8adf6090..7900f265 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ ________________________________________________________________________________

-

Proxmox Dark Theme

+

Proxmox Discord Dark Theme

A dark theme for the Proxmox Web UI by [Weilbyte](https://github.com/Weilbyte/PVEDiscordDark) From 6e85f6c26646d0534a41d61957a0bad9b77dac19 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Dec 2021 19:53:10 -0500 Subject: [PATCH 0451/6505] Add files via upload --- new_haos_vm.sh | 177 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 new_haos_vm.sh diff --git a/new_haos_vm.sh b/new_haos_vm.sh new file mode 100644 index 00000000..4d1317e2 --- /dev/null +++ b/new_haos_vm.sh @@ -0,0 +1,177 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Disk image' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." +VMID=$(pvesh get /cluster/nextid) +info "Container ID is $VMID." +echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" +RELEASE_TYPE=qcow2 +URL=$(cat< /dev/null; then + echo -e "${CHECKMARK} \e[1;92m Installing Unzip... \e[0m" + apt-get update >/dev/null + apt-get -qqy install unzip &>/dev/null + fi +fi +echo -e "${CHECKMARK} \e[1;92m Extracting disk image... \e[0m" +case $FILE in + *"gz") gunzip -f $FILE;; + *"zip") unzip -o $FILE;; + *"xz") xz -d $FILE;; + *) die "Unable to handle file extension '${FILE##*.}'.";; +esac +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + IMPORT_OPT="-format qcow2" +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +echo -e "${CHECKMARK} \e[1;92m Creating VM... \e[0m" +VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) +qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},size=128K \ + -sata0 ${DISK1_REF},size=32G > /dev/null +qm set $VMID \ + -boot order=sata0 > /dev/null +set +o errtrace +( + echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" + trap ' + warn "Unable to configure serial port. VM is still functional." + if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VMID --delete serial0 >/dev/null + fi + exit + ' ERR + if [ "$(command -v kpartx)" = "" ]; then + echo -e "${CHECKMARK} \e[1;92m Installing kpartx... \e[0m" + apt-get update >/dev/null + apt-get -qqy install kpartx &>/dev/null + fi + DISK1_PATH="$(pvesm path $DISK1_REF)" + DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" + DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" + TEMP_MOUNT="${TEMP_DIR}/mnt" + trap ' + findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT + command -v kpartx >/dev/null && kpartx -d $DISK1_PATH + ' EXIT + kpartx -a $DISK1_PATH + mkdir $TEMP_MOUNT + mount $DISK1_PART1_PATH $TEMP_MOUNT + sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt + qm set $VMID -serial0 socket >/dev/null +) + +info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." \ No newline at end of file From fd104c5cd9ff9c2e09d7bfcf314ab21245e77554 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Dec 2021 19:58:47 -0500 Subject: [PATCH 0452/6505] Delete new_haos_vm.sh --- new_haos_vm.sh | 177 ------------------------------------------------- 1 file changed, 177 deletions(-) delete mode 100644 new_haos_vm.sh diff --git a/new_haos_vm.sh b/new_haos_vm.sh deleted file mode 100644 index 4d1317e2..00000000 --- a/new_haos_vm.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content images | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Disk image' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." -VMID=$(pvesh get /cluster/nextid) -info "Container ID is $VMID." -echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" -RELEASE_TYPE=qcow2 -URL=$(cat< /dev/null; then - echo -e "${CHECKMARK} \e[1;92m Installing Unzip... \e[0m" - apt-get update >/dev/null - apt-get -qqy install unzip &>/dev/null - fi -fi -echo -e "${CHECKMARK} \e[1;92m Extracting disk image... \e[0m" -case $FILE in - *"gz") gunzip -f $FILE;; - *"zip") unzip -o $FILE;; - *"xz") xz -d $FILE;; - *) die "Unable to handle file extension '${FILE##*.}'.";; -esac -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - IMPORT_OPT="-format qcow2" -esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done -echo -e "${CHECKMARK} \e[1;92m Creating VM... \e[0m" -VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) -qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF},size=128K \ - -sata0 ${DISK1_REF},size=32G > /dev/null -qm set $VMID \ - -boot order=sata0 > /dev/null -set +o errtrace -( - echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" - trap ' - warn "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VMID --delete serial0 >/dev/null - fi - exit - ' ERR - if [ "$(command -v kpartx)" = "" ]; then - echo -e "${CHECKMARK} \e[1;92m Installing kpartx... \e[0m" - apt-get update >/dev/null - apt-get -qqy install kpartx &>/dev/null - fi - DISK1_PATH="$(pvesm path $DISK1_REF)" - DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" - DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" - TEMP_MOUNT="${TEMP_DIR}/mnt" - trap ' - findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT - command -v kpartx >/dev/null && kpartx -d $DISK1_PATH - ' EXIT - kpartx -a $DISK1_PATH - mkdir $TEMP_MOUNT - mount $DISK1_PART1_PATH $TEMP_MOUNT - sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt - qm set $VMID -serial0 socket >/dev/null -) - -info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." \ No newline at end of file From fe3e3840bb7610cc31b07536a6e388497f4b5a19 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Dec 2021 19:59:17 -0500 Subject: [PATCH 0453/6505] Add files via upload --- haos_vm.sh | 48 ++++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/haos_vm.sh b/haos_vm.sh index 0bd8eba4..4d1317e2 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -8,17 +8,15 @@ while true; do * ) echo "Please answer yes or no.";; esac done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT - function error_exit() { trap - ERR local DEFAULT='Unknown failure occured.' @@ -56,8 +54,6 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -83,12 +79,8 @@ else done fi info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID VMID=$(pvesh get /cluster/nextid) info "Container ID is $VMID." - -# Get latest Home Assistant disk image archive URL echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" RELEASE_TYPE=qcow2 URL=$(cat< /dev/null; then - echo -e "\e[1;33m Installing Unzip... \e[0m" + echo -e "${CHECKMARK} \e[1;92m Installing Unzip... \e[0m" apt-get update >/dev/null apt-get -qqy install unzip &>/dev/null fi fi - -# Extract Home Assistant disk image -echo -e "\e[1;33m Extracting disk image... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Extracting disk image... \e[0m" case $FILE in *"gz") gunzip -f $FILE;; *"zip") unzip -o $FILE;; *"xz") xz -d $FILE;; *) die "Unable to handle file extension '${FILE##*.}'.";; esac - -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in nfs|dir) @@ -149,9 +133,7 @@ for i in {0,1}; do eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done - -# Create VM -echo -e "\e[1;33m Creating VM... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Creating VM... \e[0m" VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci @@ -162,11 +144,9 @@ qm set $VMID \ -sata0 ${DISK1_REF},size=32G > /dev/null qm set $VMID \ -boot order=sata0 > /dev/null - -# Add serial port and enable console output set +o errtrace ( - echo -e "\e[1;33m Adding serial port and configuring console... \e[0m" + echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" trap ' warn "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then @@ -175,7 +155,7 @@ set +o errtrace exit ' ERR if [ "$(command -v kpartx)" = "" ]; then - echo -e "\e[1;33m Installing kpartx... \e[0m" + echo -e "${CHECKMARK} \e[1;92m Installing kpartx... \e[0m" apt-get update >/dev/null apt-get -qqy install kpartx &>/dev/null fi @@ -194,4 +174,4 @@ set +o errtrace qm set $VMID -serial0 socket >/dev/null ) -info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." +info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." \ No newline at end of file From 44eb8ab1b27d230fd0a206f4648d9b8192ca0cf8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:10:36 -0500 Subject: [PATCH 0454/6505] Add files via upload --- webmin.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 webmin.sh diff --git a/webmin.sh b/webmin.sh new file mode 100644 index 00000000..37874129 --- /dev/null +++ b/webmin.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +while true; do + read -p "This will Install Webmin, Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +echo -e "Loading Script..." +echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt install -y libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info >&/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb >&/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" +dpkg --install webmin_1.983_all.deb >&/dev/null +echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" +/usr/share/webmin/changepass.pl /etc/webmin root root >&/dev/null +echo -e "Installed Successfully! Go To IP:10000" + + +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webmin.sh)" From ed2ba19d9a45a6196875923641b47f61a1e75142 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:13:49 -0500 Subject: [PATCH 0455/6505] Add files via upload --- webmin.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/webmin.sh b/webmin.sh index 37874129..d85dbeaa 100644 --- a/webmin.sh +++ b/webmin.sh @@ -10,6 +10,7 @@ done CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt update >&/dev/null apt install -y libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info >&/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb >&/dev/null From a098376d50fd63854cd2ce615b479a3fdfe6b491 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:16:48 -0500 Subject: [PATCH 0456/6505] Add files via upload --- webmin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webmin.sh b/webmin.sh index d85dbeaa..82a6309b 100644 --- a/webmin.sh +++ b/webmin.sh @@ -10,8 +10,8 @@ done CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt update >&/dev/null -apt install -y libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info >&/dev/null +apt-get update >&/dev/null +apt-get install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info >&/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb >&/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" From 35de290510bd0e98575b589df5cc8661373383ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:23:46 -0500 Subject: [PATCH 0457/6505] Add files via upload --- webmin.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/webmin.sh b/webmin.sh index 82a6309b..25b17be3 100644 --- a/webmin.sh +++ b/webmin.sh @@ -10,14 +10,14 @@ done CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt-get update >&/dev/null -apt-get install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info >&/dev/null +apt-get update / #>&/dev/null +apt-get install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info / #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb >&/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb / #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" -dpkg --install webmin_1.983_all.deb >&/dev/null +dpkg --install webmin_1.983_all.deb / #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" -/usr/share/webmin/changepass.pl /etc/webmin root root >&/dev/null +/usr/share/webmin/changepass.pl /etc/webmin root root #>&/dev/null echo -e "Installed Successfully! Go To IP:10000" From b32d5246b0cbc7f9d221d9caa0ad75f33e6e7630 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:25:21 -0500 Subject: [PATCH 0458/6505] Add files via upload --- webmin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webmin.sh b/webmin.sh index 25b17be3..0007490e 100644 --- a/webmin.sh +++ b/webmin.sh @@ -10,8 +10,8 @@ done CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt-get update / #>&/dev/null -apt-get install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info / #>&/dev/null +apt update / #>&/dev/null +apt install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info / #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb / #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" From a3ba23a30defe2783ccecae0621d0f5d3967911d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:27:05 -0500 Subject: [PATCH 0459/6505] Add files via upload --- webmin.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webmin.sh b/webmin.sh index 0007490e..2ebdc34f 100644 --- a/webmin.sh +++ b/webmin.sh @@ -10,12 +10,12 @@ done CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt update / #>&/dev/null -apt install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info / #>&/dev/null +apt update #>&/dev/null +apt install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb / #>&/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" -dpkg --install webmin_1.983_all.deb / #>&/dev/null +dpkg --install webmin_1.983_all.deb #>&/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" /usr/share/webmin/changepass.pl /etc/webmin root root #>&/dev/null echo -e "Installed Successfully! Go To IP:10000" From f05e74a93b6fd0fe3933e3ad2310252e513e591e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:30:44 -0500 Subject: [PATCH 0460/6505] Add files via upload --- webmin.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/webmin.sh b/webmin.sh index 2ebdc34f..057467a2 100644 --- a/webmin.sh +++ b/webmin.sh @@ -10,14 +10,14 @@ done CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt update #>&/dev/null -apt install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info #>&/dev/null +apt update &>/dev/null +apt-get -qqy install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb #>&/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" -dpkg --install webmin_1.983_all.deb #>&/dev/null +dpkg --install webmin_1.983_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" -/usr/share/webmin/changepass.pl /etc/webmin root root #>&/dev/null +/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null echo -e "Installed Successfully! Go To IP:10000" From 2187880f32e22f87a32620377733efd6946c7466 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:39:59 -0500 Subject: [PATCH 0461/6505] Add files via upload --- webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmin.sh b/webmin.sh index 057467a2..b13dd2ad 100644 --- a/webmin.sh +++ b/webmin.sh @@ -11,7 +11,7 @@ CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" apt update &>/dev/null -apt-get -qqy install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null +apt-get install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" From 44eb405e62a2415ab396d0f5f35be8662760dd1e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 16:52:47 -0500 Subject: [PATCH 0462/6505] Add files via upload --- webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmin.sh b/webmin.sh index b13dd2ad..73c8fff9 100644 --- a/webmin.sh +++ b/webmin.sh @@ -11,7 +11,7 @@ CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' echo -e "Loading Script..." echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" apt update &>/dev/null -apt-get install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null +apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" From 413c4e1dbcf01b171be4a188f3ba7132863d8f20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 17:09:06 -0500 Subject: [PATCH 0463/6505] Add files via upload --- webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmin.sh b/webmin.sh index 73c8fff9..7c2c41cc 100644 --- a/webmin.sh +++ b/webmin.sh @@ -18,7 +18,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" dpkg --install webmin_1.983_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -echo -e "Installed Successfully! Go To IP:10000" +echo -e "Install Complete, Now Go To IP:10000" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webmin.sh)" From c8ff22f566a0102f9978965637ea665fad2ace9b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 18:31:36 -0500 Subject: [PATCH 0464/6505] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 7900f265..2950d5ea 100644 --- a/README.md +++ b/README.md @@ -639,3 +639,26 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adgu ____________________________________________________________________________________________
+ + +
+Webmin System Administration + +

+ +

Webmin System Administration

+ +To Install [Webmin System Administration](https://www.webmin.com/index.html), run the following in a LXC console. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webmin.sh)" +``` + +If you prefer to manage all aspects of your Linux LXC from a graphical interface instead of the command line interface, Webmin might be right for you. + + +**Webmin Interface - https:// IP:10000 (https)** + +____________________________________________________________________________________________ + +
From 446eaf23079be6540091e11a889568f7e1d86e3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 18:43:38 -0500 Subject: [PATCH 0465/6505] Update webmin.sh --- webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmin.sh b/webmin.sh index 7c2c41cc..5d0cb019 100644 --- a/webmin.sh +++ b/webmin.sh @@ -18,7 +18,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" dpkg --install webmin_1.983_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -echo -e "Install Complete, Now Go To IP:10000" +echo -e "Install Complete, Now Go To https:// IP:10000" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webmin.sh)" From 8cc0c1258a7e5e9da7bc5f3403e83f34981a72b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 18:48:27 -0500 Subject: [PATCH 0466/6505] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 2950d5ea..af7ed19b 100644 --- a/README.md +++ b/README.md @@ -659,6 +659,17 @@ If you prefer to manage all aspects of your Linux LXC from a graphical interface **Webmin Interface - https:// IP:10000 (https)** +⚙️ **Initial Login** + +**username** + ``` + root + ``` + **password** + ``` + root + ``` + ____________________________________________________________________________________________
From 4c0b07271b3deb034d68f0535ab09af9dbf76bef Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 19:02:24 -0500 Subject: [PATCH 0467/6505] Update README.md --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index af7ed19b..58cde5e7 100644 --- a/README.md +++ b/README.md @@ -662,13 +662,10 @@ If you prefer to manage all aspects of your Linux LXC from a graphical interface ⚙️ **Initial Login** **username** - ``` - root - ``` + `root` + **password** - ``` - root - ``` + `root` ____________________________________________________________________________________________ From 18b318ad5d2e0b95f53ddb4d46082fe566e22a14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 19:04:34 -0500 Subject: [PATCH 0468/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 58cde5e7..b547f4db 100644 --- a/README.md +++ b/README.md @@ -644,7 +644,7 @@ ________________________________________________________________________________
Webmin System Administration -

+

Webmin System Administration

From 0d7a2985d7554e98f6180921fb63aa9a147c14ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 19:51:01 -0500 Subject: [PATCH 0469/6505] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index b547f4db..f997817f 100644 --- a/README.md +++ b/README.md @@ -656,6 +656,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webm If you prefer to manage all aspects of your Linux LXC from a graphical interface instead of the command line interface, Webmin might be right for you. +Benefits include automatic daily security updates, backup and restore, file manager with editor, web control panel, and preconfigured system monitoring with optional email alerts. + + **Webmin Interface - https:// IP:10000 (https)** From 26052609195ccb9390ff48533277d507403d5801 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Dec 2021 21:13:05 -0500 Subject: [PATCH 0470/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f997817f..c61f718b 100644 --- a/README.md +++ b/README.md @@ -654,7 +654,7 @@ To Install [Webmin System Administration](https://www.webmin.com/index.html), ru bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webmin.sh)" ``` -If you prefer to manage all aspects of your Linux LXC from a graphical interface instead of the command line interface, Webmin might be right for you. +If you prefer to manage all aspects of your Proxmox LXC from a graphical interface instead of the command line interface, Webmin might be right for you. Benefits include automatic daily security updates, backup and restore, file manager with editor, web control panel, and preconfigured system monitoring with optional email alerts. From be5883553198c601a82a44320602a9c68b7b0ec9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Dec 2021 10:36:41 -0500 Subject: [PATCH 0471/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c61f718b..00d481d2 100644 --- a/README.md +++ b/README.md @@ -113,11 +113,11 @@ podman generate systemd \ > /etc/systemd/system/homeassistant.service systemctl enable homeassistant ``` -⚙️ **Check the status of homeassistant service:** +⚙️ **Start the homeassistant service:** Run from the LXC console ``` -systemctl status homeassistant +systemctl start homeassistant ``` ⚙️ **To install HACS:** From d118fb066f0b6c6ea885250d61a3317a4b7d3ee7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 07:56:15 -0500 Subject: [PATCH 0472/6505] Create proxmox.yml --- .github/workflows/proxmox.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/proxmox.yml diff --git a/.github/workflows/proxmox.yml b/.github/workflows/proxmox.yml new file mode 100644 index 00000000..7541d41b --- /dev/null +++ b/.github/workflows/proxmox.yml @@ -0,0 +1,22 @@ +name: Close inactive issues +on: + schedule: + - cron: "30 1 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v3 + with: + days-before-issue-stale: 7 + days-before-issue-close: 2 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 5 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 2 days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 + repo-token: ${{ secrets.GITHUB_TOKEN }} From 8de7b525c2586178da45d197f9d40496bc25a3e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 08:19:10 -0500 Subject: [PATCH 0473/6505] Update proxmox.yml --- .github/workflows/proxmox.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proxmox.yml b/.github/workflows/proxmox.yml index 7541d41b..bd49f99a 100644 --- a/.github/workflows/proxmox.yml +++ b/.github/workflows/proxmox.yml @@ -15,7 +15,7 @@ jobs: days-before-issue-stale: 7 days-before-issue-close: 2 stale-issue-label: "stale" - stale-issue-message: "This issue is stale because it has been open for 5 days with no activity." + stale-issue-message: "This issue is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 2 days." close-issue-message: "This issue was closed because it has been inactive for 2 days since being marked as stale." days-before-pr-stale: -1 days-before-pr-close: -1 From 4a137b60992fc0ec259a502fb6ec458840415b2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 08:19:58 -0500 Subject: [PATCH 0474/6505] Rename proxmox.yml to stale.yml --- .github/workflows/{proxmox.yml => stale.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{proxmox.yml => stale.yml} (100%) diff --git a/.github/workflows/proxmox.yml b/.github/workflows/stale.yml similarity index 100% rename from .github/workflows/proxmox.yml rename to .github/workflows/stale.yml From bae72c4b6d498cec4849fd69d0b64f0da3ad368d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 08:24:21 -0500 Subject: [PATCH 0475/6505] Update stale.yml --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index bd49f99a..00b8075d 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,7 +1,7 @@ name: Close inactive issues on: schedule: - - cron: "30 1 * * *" + - cron: "0 0 * * *" jobs: close-issues: From 9e598d0acac66e53ab4412a729bad561dc06a4ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:20:37 -0500 Subject: [PATCH 0476/6505] Set theme jekyll-theme-midnight --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 6979f9d8..ad51bf59 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-hacker +theme: jekyll-theme-midnight title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From f614c518892c8f58d5b4abf63c30ad75852e26ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:21:26 -0500 Subject: [PATCH 0477/6505] Set theme jekyll-theme-hacker --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index ad51bf59..6979f9d8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-midnight +theme: jekyll-theme-hacker title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From 87fcd3b15801d999ebbfd881f60ab3bd56a8c891 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:25:50 -0500 Subject: [PATCH 0478/6505] Set theme jekyll-theme-midnight --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 6979f9d8..ad51bf59 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-hacker +theme: jekyll-theme-midnight title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From f58f5c0fb5259e84d7e9eea498c5df6af5b20857 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:26:24 -0500 Subject: [PATCH 0479/6505] Set theme jekyll-theme-hacker --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index ad51bf59..6979f9d8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-midnight +theme: jekyll-theme-hacker title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From df77b834e0441b2ab5cd550cad761925f8a274d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:28:51 -0500 Subject: [PATCH 0480/6505] Set theme jekyll-theme-modernist --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 6979f9d8..b8393646 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-hacker +theme: jekyll-theme-modernist title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From ea370c4634ccde8e332ad2b4ccb858f8052e6ee7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:31:24 -0500 Subject: [PATCH 0481/6505] Set theme jekyll-theme-hacker --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index b8393646..6979f9d8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-modernist +theme: jekyll-theme-hacker title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From 0446ffcdaacac0940563ec286533d25aa04bc57e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:34:38 -0500 Subject: [PATCH 0482/6505] Set theme jekyll-theme-midnight --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 6979f9d8..ad51bf59 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-hacker +theme: jekyll-theme-midnight title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From c18d32b4e8b1a91e5365515f22be9c22ff4e6404 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Dec 2021 12:37:22 -0500 Subject: [PATCH 0483/6505] Set theme jekyll-theme-hacker --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index ad51bf59..6979f9d8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-midnight +theme: jekyll-theme-hacker title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From baca4e972d97977d06134ef19b7fdf41785a1229 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Dec 2021 19:29:46 -0500 Subject: [PATCH 0484/6505] Update stale.yml --- .github/workflows/stale.yml | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 00b8075d..25cb40d8 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,22 +1,19 @@ -name: Close inactive issues +name: "Close stale issues/pull requests" on: schedule: - - cron: "0 0 * * *" + - cron: "0 0 * * *" + workflow_dispatch: jobs: - close-issues: + stale: runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write steps: - - uses: actions/stale@v3 - with: - days-before-issue-stale: 7 - days-before-issue-close: 2 - stale-issue-label: "stale" - stale-issue-message: "This issue is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 2 days." - close-issue-message: "This issue was closed because it has been inactive for 2 days since being marked as stale." - days-before-pr-stale: -1 - days-before-pr-close: -1 - repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 2 days' + stale-pr-message: 'This pull request is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 2 days' + days-before-stale: 5 + days-before-close: 2 + operations-per-run: 500 + exempt-issue-labels: 'breaking change' From 4453ae255061e1aa0308dbe993bf218b98a92f9b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Dec 2021 19:43:38 -0500 Subject: [PATCH 0485/6505] Delete stale.yml --- .github/workflows/stale.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 25cb40d8..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: "Close stale issues/pull requests" -on: - schedule: - - cron: "0 0 * * *" - workflow_dispatch: - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 2 days' - stale-pr-message: 'This pull request is stale because it has been open 5 days with no activity. Remove stale label or comment or this will be closed in 2 days' - days-before-stale: 5 - days-before-close: 2 - operations-per-run: 500 - exempt-issue-labels: 'breaking change' From dad59cffd31e577731de7bdd4d0b9639fb0098fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 Dec 2021 12:56:19 -0500 Subject: [PATCH 0486/6505] Add files via upload --- plex_container.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++++ plex_setup.sh | 65 +++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 plex_container.sh create mode 100644 plex_setup.sh diff --git a/plex_container.sh b/plex_container.sh new file mode 100644 index 00000000..4feb5433 --- /dev/null +++ b/plex_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Plex Media Server LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/plex_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for Storage Location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=plex +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 +pct exec $CTID /plex_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Plex Media Server LXC Container to $CTID at IP Address ${IP}:32400/web" diff --git a/plex_setup.sh b/plex_setup.sh new file mode 100644 index 00000000..d57045b7 --- /dev/null +++ b/plex_setup.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt-get -qqy install \ + curl \ + sudo \ + gnupg &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading Plex Media Server... \e[0m" +wget https://downloads.plex.tv/plex-media-server-new/1.25.2.5319-c43dc0277/debian/plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" +sudo dpkg -i plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null + +cat < /etc/apt/sources.list.d/plexmediaserver.list +deb https://downloads.plex.tv/repo/deb/ public main +EOF + +wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 3f82ffc7c8f84edbc283463789c0437b7c476d98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 Dec 2021 13:05:37 -0500 Subject: [PATCH 0487/6505] Add files via upload --- plex_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plex_container.sh b/plex_container.sh index 4feb5433..f9050b70 100644 --- a/plex_container.sh +++ b/plex_container.sh @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=plex TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From aa8044c492eb4e9e21170717ff6ddd8cedfbc2c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 Dec 2021 13:30:06 -0500 Subject: [PATCH 0488/6505] Update README.md --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 00d481d2..6b391c5c 100644 --- a/README.md +++ b/README.md @@ -590,6 +590,28 @@ ________________________________________________________________________________
+
+Plex Media Server LXC + +

+ +

Plex Media Server LXC

+ +To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_container.sh)" +``` +

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. + +**Plex Media Server Interface - IP:32400/web** + +____________________________________________________________________________________________ + +
+
From 4fbf6d1f790edd5cd234894e320755bc3c0e4250 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Dec 2021 08:58:27 -0500 Subject: [PATCH 0489/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b391c5c..3118cb3b 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ ________________________________________________________________________________ To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. - ([What is Podman?](https://github.com/tteck/Proxmox/blob/main/Podman.md)) + ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" From aeacf8ce84f37e4819973d7cb671d6a41ef2d83c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Dec 2021 10:58:52 -0500 Subject: [PATCH 0490/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 15a424f4..771a8b72 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -34,7 +34,8 @@ apt-get -qqy upgrade &>/dev/null msg "Installing prerequisites..." apt-get -qqy install \ - curl &>/dev/null + curl \ + runc &>/dev/null msg "Installing Podman..." apt-get -y install podman &>/dev/null From f96fb6b27adaededcf60690bf10237c3e9c02765 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jan 2022 15:07:52 -0500 Subject: [PATCH 0491/6505] Update webmin.sh --- webmin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webmin.sh b/webmin.sh index 5d0cb019..0972c846 100644 --- a/webmin.sh +++ b/webmin.sh @@ -13,9 +13,9 @@ echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" apt update &>/dev/null apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.983_all.deb &>/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" -dpkg --install webmin_1.983_all.deb &>/dev/null +dpkg --install webmin_1.984_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null echo -e "Install Complete, Now Go To https:// IP:10000" From 84f491ff910c32ebc6b11c9fa41805c7d24a7e1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Jan 2022 10:55:00 -0500 Subject: [PATCH 0492/6505] Update adguard_setup.sh --- adguard_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adguard_setup.sh b/adguard_setup.sh index 5f93d283..2e1d82d6 100644 --- a/adguard_setup.sh +++ b/adguard_setup.sh @@ -33,7 +33,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." -apt-get -qqy install \ +apt-get install \ curl \ sudo &>/dev/null @@ -55,4 +55,4 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg "Cleanup..." -rm -rf /adguard_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /adguard_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 921e7710c6412cce0e87baab5cd9c6fee99a67fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Jan 2022 11:00:24 -0500 Subject: [PATCH 0493/6505] Update adguard_setup.sh --- adguard_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adguard_setup.sh b/adguard_setup.sh index 2e1d82d6..e29e9a5d 100644 --- a/adguard_setup.sh +++ b/adguard_setup.sh @@ -33,7 +33,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." -apt-get install \ +apt-get -y install \ curl \ sudo &>/dev/null From e3ef77e6aae4418948aea52e28c693e6ef49f208 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jan 2022 23:17:09 -0500 Subject: [PATCH 0494/6505] Add files via upload --- plex_hardware_acceleration.sh | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 plex_hardware_acceleration.sh diff --git a/plex_hardware_acceleration.sh b/plex_hardware_acceleration.sh new file mode 100644 index 00000000..aedd534a --- /dev/null +++ b/plex_hardware_acceleration.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will add Hardware Acceleration Support to your Plex Media Server LXC. + Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +cat <> $CTID_CONFIG_PATH +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +EOF +echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" + +# Plex can transcode media files on the fly. By default they use the CPU. +# All Intel CPU’s since Sandy Bridge released in 2011 have hardware acceleration for H.264 built in. +# So if your CPU supports Quick Sync you can speed up transcoding and reduce load by running the +# following in the Proxmox web shell (replace 106 with your LXC ID) +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_hardware_acceleration.sh)" -s 106 +# Reboot the LXC to apply the changes \ No newline at end of file From 4da2816ff88bc7b25d9dc53050640b32cf52f807 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jan 2022 16:35:05 -0500 Subject: [PATCH 0495/6505] Add files via upload --- plex_hardware_acceleration.sh | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/plex_hardware_acceleration.sh b/plex_hardware_acceleration.sh index aedd534a..14bb9e18 100644 --- a/plex_hardware_acceleration.sh +++ b/plex_hardware_acceleration.sh @@ -31,11 +31,27 @@ function msg() { CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf cat <> $CTID_CONFIG_PATH +### Intel iGPU: ### lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 +#lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file 0, 0 +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 0, 0 +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file 0, 0 + +### NVidia GPU: ### +#lxc.cgroup2.devices.allow: c 195:* rwm +#lxc.cgroup2.devices.allow: c 243:* rwm +#lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file +#lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file +#lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file +#lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file +#lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file +#lxc.cgroup2.devices.allow: c 226:0 rwm +#lxc.cgroup2.devices.allow: c 226:128 rwm +#lxc.cgroup2.devices.allow: c 29:0 rwm +#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 EOF echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" @@ -44,4 +60,6 @@ echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" # So if your CPU supports Quick Sync you can speed up transcoding and reduce load by running the # following in the Proxmox web shell (replace 106 with your LXC ID) # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_hardware_acceleration.sh)" -s 106 -# Reboot the LXC to apply the changes \ No newline at end of file +# Reboot the LXC to apply the changes + + From fb359c5541b44b6623fed96b233348d9320a59d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jan 2022 22:39:44 -0500 Subject: [PATCH 0496/6505] Add files via upload --- plex_hardware_acceleration2.sh | 90 ++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 plex_hardware_acceleration2.sh diff --git a/plex_hardware_acceleration2.sh b/plex_hardware_acceleration2.sh new file mode 100644 index 00000000..cb7738b0 --- /dev/null +++ b/plex_hardware_acceleration2.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will add Hardware Acceleration Support (hopefully) to your Plex Media Server LXC. + Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +CHAR_DEVS+=("1:1") +CHAR_DEVS+=("4:\([3-9]\|[1-5][0-9]\|6[0-3]\)") +CHAR_DEVS+=("4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)") +CHAR_DEVS+=("10:200") +CHAR_DEVS+=("116:.*") +CHAR_DEVS+=("166:.*") +CHAR_DEVS+=("180:\([0-9]\|1[0-5]\)") +CHAR_DEVS+=("188:.*") +CHAR_DEVS+=("189:.*") +CHAR_DEVS+=("226:.*") +CHAR_DEVS+=("29:.*") +CHAR_DEVS+=("24[0-2]:.*") + +for char_dev in ${CHAR_DEVS[@]}; do + [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" + CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" +done + +read -r -d '' HOOK_SCRIPT <<- EOF || true +for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do + dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; + mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); + for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do + mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); + cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; + done; + cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; +done; +EOF +HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} + +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf +cat CTID.conf >$CTID_CONFIG_PATH + +cat <> $CTID_CONFIG_PATH +lxc.autodev: 1 +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.hook.autodev: bash -c '$HOOK_SCRIPT' +EOF +echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" + +# Plex can transcode media files on the fly. By default they use the CPU. +# All Intel CPU’s since Sandy Bridge released in 2011 have hardware acceleration for H.264 built in. +# So if your CPU supports Quick Sync you can speed up transcoding and reduce load by running the +# following in the Proxmox web shell (replace 106 with your LXC ID) +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_hardware_acceleration2.sh)" -s 106 +# Reboot the LXC to apply the changes From 5d80da198bdba7850bbd8b010e220b037cde6bda Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jan 2022 22:45:08 -0500 Subject: [PATCH 0497/6505] Add files via upload --- plex_hardware_acceleration2.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/plex_hardware_acceleration2.sh b/plex_hardware_acceleration2.sh index cb7738b0..7e418ade 100644 --- a/plex_hardware_acceleration2.sh +++ b/plex_hardware_acceleration2.sh @@ -45,8 +45,6 @@ CHAR_DEVS+=("10:200") CHAR_DEVS+=("116:.*") CHAR_DEVS+=("166:.*") CHAR_DEVS+=("180:\([0-9]\|1[0-5]\)") -CHAR_DEVS+=("188:.*") -CHAR_DEVS+=("189:.*") CHAR_DEVS+=("226:.*") CHAR_DEVS+=("29:.*") CHAR_DEVS+=("24[0-2]:.*") From a4169ad50413ebb0cdc8dea08d0c3226a00b46e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jan 2022 11:44:25 -0500 Subject: [PATCH 0498/6505] Update haos_vm.sh --- haos_vm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/haos_vm.sh b/haos_vm.sh index 4d1317e2..a4aa4f54 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -141,9 +141,9 @@ pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ - -sata0 ${DISK1_REF},size=32G > /dev/null + -scsi0 ${DISK1_REF},size=32G > /dev/null qm set $VMID \ - -boot order=sata0 > /dev/null + -boot order=scsi0 > /dev/null set +o errtrace ( echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" @@ -174,4 +174,4 @@ set +o errtrace qm set $VMID -serial0 socket >/dev/null ) -info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." \ No newline at end of file +info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." From f3bbef78fbf3aa4ea086cb8c3575372688be8370 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jan 2022 12:07:42 -0500 Subject: [PATCH 0499/6505] Update haos_vm.sh --- haos_vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/haos_vm.sh b/haos_vm.sh index a4aa4f54..1b231801 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -141,9 +141,9 @@ pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},size=32G > /dev/null + -sata0 ${DISK1_REF},size=32G > /dev/null qm set $VMID \ - -boot order=scsi0 > /dev/null + -boot order=sata0 > /dev/null set +o errtrace ( echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" From d56134fe4cfecb6f4433ef4f808b6bd08bd16340 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jan 2022 12:18:25 -0500 Subject: [PATCH 0500/6505] Update haos_vm.sh --- haos_vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/haos_vm.sh b/haos_vm.sh index 1b231801..a4aa4f54 100644 --- a/haos_vm.sh +++ b/haos_vm.sh @@ -141,9 +141,9 @@ pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ - -sata0 ${DISK1_REF},size=32G > /dev/null + -scsi0 ${DISK1_REF},size=32G > /dev/null qm set $VMID \ - -boot order=sata0 > /dev/null + -boot order=scsi0 > /dev/null set +o errtrace ( echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" From ee94f10c2dedc477cef9c99016174e09ca8b3144 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jan 2022 18:36:32 -0500 Subject: [PATCH 0501/6505] Update autodev.sh --- autodev.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/autodev.sh b/autodev.sh index ffa1f75a..74d67f89 100644 --- a/autodev.sh +++ b/autodev.sh @@ -37,16 +37,8 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -CHAR_DEVS+=("1:1") -CHAR_DEVS+=("4:\([3-9]\|[1-5][0-9]\|6[0-3]\)") -CHAR_DEVS+=("4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)") -CHAR_DEVS+=("10:200") -CHAR_DEVS+=("116:.*") -CHAR_DEVS+=("166:.*") -CHAR_DEVS+=("180:\([0-9]\|1[0-5]\)") CHAR_DEVS+=("188:.*") CHAR_DEVS+=("189:.*") -CHAR_DEVS+=("24[0-2]:.*") for char_dev in ${CHAR_DEVS[@]}; do [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" From 433c48561a067b9cfcf6c3abba3c0983faa72a64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Jan 2022 00:47:38 -0500 Subject: [PATCH 0502/6505] Delete plex_hardware_acceleration2.sh --- plex_hardware_acceleration2.sh | 88 ---------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 plex_hardware_acceleration2.sh diff --git a/plex_hardware_acceleration2.sh b/plex_hardware_acceleration2.sh deleted file mode 100644 index 7e418ade..00000000 --- a/plex_hardware_acceleration2.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will add Hardware Acceleration Support (hopefully) to your Plex Media Server LXC. - Did you replace 106 with your LXC ID? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -CHAR_DEVS+=("1:1") -CHAR_DEVS+=("4:\([3-9]\|[1-5][0-9]\|6[0-3]\)") -CHAR_DEVS+=("4:\(6[4-9]\|[7-9][0-9]\|1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)") -CHAR_DEVS+=("10:200") -CHAR_DEVS+=("116:.*") -CHAR_DEVS+=("166:.*") -CHAR_DEVS+=("180:\([0-9]\|1[0-5]\)") -CHAR_DEVS+=("226:.*") -CHAR_DEVS+=("29:.*") -CHAR_DEVS+=("24[0-2]:.*") - -for char_dev in ${CHAR_DEVS[@]}; do - [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" - CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" -done - -read -r -d '' HOOK_SCRIPT <<- EOF || true -for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do - dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; - mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); - for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do - mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); - cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; - done; - cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; -done; -EOF -HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} - -CTID=$1 -CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf -cat CTID.conf >$CTID_CONFIG_PATH - -cat <> $CTID_CONFIG_PATH -lxc.autodev: 1 -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.hook.autodev: bash -c '$HOOK_SCRIPT' -EOF -echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" - -# Plex can transcode media files on the fly. By default they use the CPU. -# All Intel CPU’s since Sandy Bridge released in 2011 have hardware acceleration for H.264 built in. -# So if your CPU supports Quick Sync you can speed up transcoding and reduce load by running the -# following in the Proxmox web shell (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_hardware_acceleration2.sh)" -s 106 -# Reboot the LXC to apply the changes From 17ae16d55f6ce43e03129e5f9a6b34ddc64a5292 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Jan 2022 16:42:02 -0500 Subject: [PATCH 0503/6505] Update post_install.sh --- post_install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/post_install.sh b/post_install.sh index aa150b42..9c26f4b0 100644 --- a/post_install.sh +++ b/post_install.sh @@ -23,9 +23,10 @@ deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF -sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js - +#sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js +echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script +apt --reinstall install proxmox-widget-toolkit &>/dev/null echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" -systemctl restart pveproxy.service # for the no-nag +#systemctl restart pveproxy.service # for the no-nag # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From 8cd07c3c6c730ab9b8e008b92de59be3e52a73db Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Jan 2022 17:43:10 -0500 Subject: [PATCH 0504/6505] Update post_install.sh --- post_install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/post_install.sh b/post_install.sh index 9c26f4b0..d85dced7 100644 --- a/post_install.sh +++ b/post_install.sh @@ -3,7 +3,6 @@ echo -e "\e[1;33m This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt the No-Nag fix. PVE7 ONLY \e[0m" - while true; do read -p "Start the PVE7 Post Install Script (y/n)?" yn case $yn in @@ -12,9 +11,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done - sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list - cat < /etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib deb http://ftp.debian.org/debian bullseye-updates main contrib @@ -22,11 +19,8 @@ deb http://security.debian.org/debian-security bullseye-security main contrib deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF - -#sed -i.backup -z "s/res === null || res === undefined || \!res || res\n\t\t\t.data.status.toLowerCase() \!== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" -#systemctl restart pveproxy.service # for the no-nag # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From 16e8894d57aa53c77456bf4cf4f16d7af8a990bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jan 2022 01:29:40 -0500 Subject: [PATCH 0505/6505] Update zwavejs2mqtt_container.sh --- zwavejs2mqtt_container.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/zwavejs2mqtt_container.sh b/zwavejs2mqtt_container.sh index 4e773bba..744d6797 100644 --- a/zwavejs2mqtt_container.sh +++ b/zwavejs2mqtt_container.sh @@ -15,6 +15,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -72,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/zwavejs2mqtt_setup.sh load_module overlay @@ -100,14 +101,14 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -info "Using '$STORAGE' for storage location." +info "Using '$STORAGE' for Storage Location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -129,7 +130,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -154,10 +155,10 @@ MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID zwavejs2mqtt_setup.sh /zwavejs2mqtt_setup.sh -perms 755 pct exec $CTID /zwavejs2mqtt_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}" +info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}:8091" From 7eb9f60731e0c87f82ab1d9f56b46e95943a5e81 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jan 2022 01:31:11 -0500 Subject: [PATCH 0506/6505] Update zwavejs2mqtt_setup.sh --- zwavejs2mqtt_setup.sh | 54 ++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/zwavejs2mqtt_setup.sh b/zwavejs2mqtt_setup.sh index a207060e..02566c86 100644 --- a/zwavejs2mqtt_setup.sh +++ b/zwavejs2mqtt_setup.sh @@ -6,6 +6,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap 'die "Script interrupted."' INT @@ -22,35 +23,54 @@ function msg() { echo -e "$TEXT" } -msg "Setting up container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -msg "Installing prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" apt-get -qqy install \ curl \ sudo \ unzip &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" + sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" + sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Installing yarn... \e[0m" + npm install --global yarn &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Build/Install Zwavejs2MQTT (5-6 min)... \e[0m" + sudo git clone https://github.com/zwave-js/zwavejs2mqtt /opt/zwavejs2mqtt &>/dev/null + cd /opt/zwavejs2mqtt &>/dev/null + yarn install &>/dev/null + yarn run build &>/dev/null -msg "Installing zwavejs2mqtt..." -cd ~ -mkdir zwavejs2mqtt -cd zwavejs2mqtt -curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest \ -| grep "browser_download_url.*zip" \ -| cut -d : -f 2,3 \ -| tr -d \" \ -| wget -i - &>/dev/null -unzip zwavejs2mqtt-v*.zip &>/dev/null -#./zwavejs2mqtt +echo -e "${CHECKMARK} \e[1;92m Creating Service file zwavejs2mqtt.service... \e[0m" +service_path="/etc/systemd/system/zwavejs2mqtt.service" -msg "Customizing container..." +echo "[Unit] +Description=zwavejs2mqtt +After=network.target +[Service] +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zwavejs2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path + +echo -e "${CHECKMARK} \e[1;92m Customizing container... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -64,5 +84,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /zwavejs2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +systemctl start zwavejs2mqtt +systemctl enable zwavejs2mqtt &>/dev/null From 480a213b5ecb9de8ba996138ec7d2fc57d9f4324 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jan 2022 01:32:27 -0500 Subject: [PATCH 0507/6505] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 3118cb3b..01e88f73 100644 --- a/README.md +++ b/README.md @@ -545,12 +545,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwav ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

-⚙️ **To start Zwavejs2Mqtt** - -Run from the LXC console - ``` -cd zwavejs2mqtt -./zwavejs2mqtt ``` **Zwavejs2MQTT Interface - IP:8091** From 27a1730373e7e938af0bbf175b01154cef5aa398 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jan 2022 01:36:01 -0500 Subject: [PATCH 0508/6505] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 01e88f73..ca11a350 100644 --- a/README.md +++ b/README.md @@ -545,7 +545,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwav ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

- ``` **Zwavejs2MQTT Interface - IP:8091** ⚙️ **To allow device passthrough:** From de97e9b5e58f543836ec539d5b5cace5d0d3d2ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jan 2022 01:38:57 -0500 Subject: [PATCH 0509/6505] Update zwavejs2mqtt_container.sh --- zwavejs2mqtt_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zwavejs2mqtt_container.sh b/zwavejs2mqtt_container.sh index 744d6797..c3bce3bc 100644 --- a/zwavejs2mqtt_container.sh +++ b/zwavejs2mqtt_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/zwavejs2mqtt_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_setup.sh load_module overlay From 0c6c9fa2fea5d1ffca1d2fd0481d8d17f96ef21e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jan 2022 14:24:48 -0500 Subject: [PATCH 0510/6505] Add files via upload --- npm_container.sh | 159 ++++++++++++++++++++++++++++++++++++ npm_setup.sh | 207 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 366 insertions(+) create mode 100644 npm_container.sh create mode 100644 npm_setup.sh diff --git a/npm_container.sh b/npm_container.sh new file mode 100644 index 00000000..3f3e373e --- /dev/null +++ b/npm_container.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +#!/usr/bin/env bash +while true; do + read -p "This will create a New Nginx Proxy Manager LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/npm_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "LXC ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" +DISK_SIZE=3G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=npm +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC...... \e[0m" +pct start $CTID +pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 +pct exec $CTID /npm_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" \ No newline at end of file diff --git a/npm_setup.sh b/npm_setup.sh new file mode 100644 index 00000000..e6ba9b97 --- /dev/null +++ b/npm_setup.sh @@ -0,0 +1,207 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +LASTCMD="" +WGETOPT="-t 1 -T 15 -q" + + # Cleanup + apt-get remove --purge -y build-essential python3-dev git -qq &>/dev/null + apt-get autoremove -y -qq &>/dev/null + apt-get clean + + # Install dependencies + echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" + echo "fs.file-max = 65535" > /etc/sysctl.conf + apt-get update &>/dev/null + apt-get -y install --no-install-recommends sudo curl wget gnupg openssl ca-certificates apache2-utils logrotate build-essential python3-dev git lsb-release &>/dev/null + + # Install Python + echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" + apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null + pip3 install --upgrade setuptools &>/dev/null + pip3 install --upgrade pip &>/dev/null + python3 -m venv /opt/certbot/ &>/dev/null + if [ "$(getconf LONG_BIT)" = "32" ]; then + python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null + fi + python3 -m pip install --no-cache-dir cffi certbot &>/dev/null +#fi + # Install openresty +echo -e "${CHECKMARK} \e[1;92m Installing Openresty... \e[0m" +wget -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null +codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null +echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null +apt-get -y update &>/dev/null +apt-get -y install --no-install-recommends openresty &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Yarn... \e[0m" +npm install --global yarn &>/dev/null + +# Download nginx-proxy-manager source +echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.14... \e[0m" +wget https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.14 -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-2.9.14 + +# Crate required symbolic links +echo -e "${CHECKMARK} \e[1;92m Setting up Enviroment... \e[0m" +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /usr/bin/certbot /opt/certbot/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx + +# Update NPM version in package.json files +sed -i "s+0.0.0+#v2.9.14+g" backend/package.json +sed -i "s+0.0.0+#v2.9.14+g" frontend/package.json + +# Fix nginx config files for use with openresty defaults +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done + +# Copy runtime files +mkdir -p /var/www/html /etc/nginx/logs +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf + +# Create required folders +mkdir -p /tmp/nginx/body \ +/run/nginx \ +/data/nginx \ +/data/custom_ssl \ +/data/logs \ +/data/access \ +/data/nginx/default_host \ +/data/nginx/default_www \ +/data/nginx/proxy_host \ +/data/nginx/redirection_host \ +/data/nginx/stream \ +/data/nginx/dead_host \ +/data/nginx/temp \ +/var/lib/nginx/cache/public \ +/var/lib/nginx/cache/private \ +/var/cache/nginx/proxy_temp + +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx + +# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf + +# Generate dummy self-signed certificate. +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi + +# Copy app files +mkdir -p /app/global /app/frontend/images +cp -r backend/* /app +cp -r global/* /app/global + +# Build the frontend +echo -e "${CHECKMARK} \e[1;92m Building Frontend... \e[0m" +cd ./frontend +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +yarn build &>/dev/null +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images + +# Initialize backend +echo -e "${CHECKMARK} \e[1;92m Initializing Backend... \e[0m" +rm -rf /app/config/default.json &>/dev/null +if [ ! -f /app/config/production.json ]; then +cat << 'EOF' > /app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF +fi +cd /app +export NODE_ENV=development +yarn install --network-timeout=30000 + +# Create NPM service +echo -e "${CHECKMARK} \e[1;92m Creating NPM Service... \e[0m" +cat << 'EOF' > /lib/systemd/system/npm.service +[Unit] +Description=Nginx Proxy Manager +After=network.target +Wants=openresty.service + +[Service] +Type=simple +Environment=NODE_ENV=production +ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge +ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 +WorkingDirectory=/app +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Start services +echo -e "${CHECKMARK} \e[1;92m Starting Services... \e[0m" +systemctl enable npm &>/dev/null +systemctl start openresty +systemctl start npm + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /npm_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 1b77da6c183008371bbeb6dbcf483e914d9db198 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jan 2022 14:30:07 -0500 Subject: [PATCH 0511/6505] Update README.md --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ca11a350..fa26e318 100644 --- a/README.md +++ b/README.md @@ -226,9 +226,9 @@ ________________________________________________________________________________ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following from Proxmox web shell. ``` - curl -sL https://raw.githubusercontent.com/ej52/proxmox/main/lxc/nginx-proxy-manager/create.sh | bash -s + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/npm_container.sh)" ``` -

⚡ Alpine Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

+

⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

____________________________________________________________________________________ @@ -244,7 +244,7 @@ Add the following to your `configuration.yaml` in Home Assistant. **Nginx Proxy Manager Interface - IP:81** -**Initial Login** +⚙️ **Initial Login** **username** ``` @@ -254,9 +254,6 @@ Add the following to your `configuration.yaml` in Home Assistant. ``` changeme ``` - -Thanks to [ej52](https://github.com/ej52/proxmox-scripts/blob/main/lxc/nginx-proxy-manager/README.md) for his hard work. - ____________________________________________________________________________________________
From e5699e079fea663044859b12ef715c7a3059ea37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Jan 2022 02:10:17 -0500 Subject: [PATCH 0512/6505] Update ha_setup.sh --- ha_setup.sh | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/ha_setup.sh b/ha_setup.sh index 660918f9..88841149 100644 --- a/ha_setup.sh +++ b/ha_setup.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap 'die "Script interrupted."' INT @@ -23,25 +23,22 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS -msg "Setting up container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null -# Update container OS -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -# Install prerequisites -msg "Installing prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ - curl &>/dev/null - -# Customize Docker configuration -msg "Customizing Docker..." + curl \ + wget &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Customizing Docker... \e[0m" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) cat >$DOCKER_CONFIG_PATH <<'EOF' @@ -50,12 +47,10 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' } EOF -# Install Docker -msg "Installing Docker..." -sh <(curl -sSL https://get.docker.com) &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Docker.io... \e[0m" +apt-get install -y docker.io &>/dev/null -# Install Portainer -msg "Installing Portainer..." +echo -e "${CHECKMARK} \e[1;92m Installing Portainer... \e[0m" docker volume create portainer_data >/dev/null docker run -d \ -p 8000:8000 \ @@ -66,8 +61,7 @@ docker run -d \ -v portainer_data:/data \ portainer/portainer-ce:latest &>/dev/null -# Install Home Assistant -msg "Installing Home Assistant..." +echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" docker volume create hass_config >/dev/null docker run -d \ --name homeassistant \ @@ -80,11 +74,10 @@ docker run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE @@ -95,6 +88,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -# Cleanup container -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From fe4e35e8460282cac2d7a763302a7631fc21d067 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Jan 2022 02:17:21 -0500 Subject: [PATCH 0513/6505] Update ha_container.sh --- ha_container.sh | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/ha_container.sh b/ha_container.sh index f46bb8a1..1ffee469 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -8,14 +8,13 @@ while true; do * ) echo "Please answer yes or no.";; esac done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -73,13 +72,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Download setup script wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ha_setup.sh -# Detect modules and automatically load at boot load_module overlay -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -105,15 +101,12 @@ else done fi info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 10 LXC template -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -121,7 +114,6 @@ TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in dir|nfs) @@ -136,8 +128,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -# Create LXC -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -152,35 +143,26 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -# Modify LXC permissions to support Docker LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF -# Set container description -pct set $CTID -description "Access Portainer interface using the following URL. - -http://:9000" - -# Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -# Setup container -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 pct exec $CTID /ha_setup.sh -# Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Home Assistant Container LXC to $CTID." +info "Successfully Created Home Assistant Container LXC to $CTID." msg " -Home Assistant is reachable by going to the following URLs. +Home Assistant should be reachable by going to the following URL. http://${IP}:8123 " From beb804b2bdf1ab3b1c020abd1ea9a070e4e0513a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Jan 2022 15:41:44 -0500 Subject: [PATCH 0514/6505] Update README.md --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fa26e318..5303c2dd 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@

Select a Proxmox Helper Below

+📬 updated in the past 7 days
-Proxmox VE 7 Post Install +📬 Proxmox VE 7 Post Install

Proxmox Server Solutions

@@ -48,7 +49,7 @@ ________________________________________________________________________________
-Home Assistant OS VM +📬 Home Assistant OS VM

@home-assistant

@@ -72,7 +73,7 @@ ________________________________________________________________________________
-Home Assistant Container LXC (Podman) + Home Assistant Container LXC (Podman)

@home-assistant

@@ -134,7 +135,7 @@ ________________________________________________________________________________
-Home Assistant Container LXC +📬 Home Assistant Container LXC

Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

@@ -216,7 +217,7 @@ ________________________________________________________________________________
-Nginx Proxy Manager LXC +📬 Nginx Proxy Manager LXC

hero

@@ -529,7 +530,7 @@ ________________________________________________________________________________
-Zwavejs2MQTT LXC +📬 Zwavejs2MQTT LXC

@@ -581,7 +582,7 @@ ________________________________________________________________________________
-Plex Media Server LXC + Plex Media Server LXC

From 3441c7144b403901d0f8fa4536349e833b568a93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Jan 2022 16:15:18 -0500 Subject: [PATCH 0515/6505] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5303c2dd..aa55a367 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@

Select a Proxmox Helper Below

-📬 updated in the past 7 days +🔸 updated in the past 7 days
-📬 Proxmox VE 7 Post Install +🔸 Proxmox VE 7 Post Install

Proxmox Server Solutions

@@ -49,7 +49,7 @@ ________________________________________________________________________________
-📬 Home Assistant OS VM +🔸 Home Assistant OS VM

@home-assistant

@@ -135,7 +135,7 @@ ________________________________________________________________________________
-📬 Home Assistant Container LXC +🔸 Home Assistant Container LXC

Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

@@ -217,7 +217,7 @@ ________________________________________________________________________________
-📬 Nginx Proxy Manager LXC +🔸 Nginx Proxy Manager LXC

hero

@@ -530,7 +530,7 @@ ________________________________________________________________________________
-📬 Zwavejs2MQTT LXC +🔸 Zwavejs2MQTT LXC

From 068a06be53c19d8da0192b74c5e4db6be2af53e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Jan 2022 16:27:20 -0500 Subject: [PATCH 0516/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa55a367..07c30f16 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Select a Proxmox Helper Below

-🔸 updated in the past 7 days +🔸 updated in the past 7 days
From e9b8de99449ef9072d19ecb5ffedc8e2e25a4661 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Jan 2022 17:08:07 -0500 Subject: [PATCH 0517/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 07c30f16..dac53144 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
-🔸 Proxmox VE 7 Post Install +🔸Proxmox VE 7 Post Install

Proxmox Server Solutions

@@ -49,7 +49,7 @@ ________________________________________________________________________________
-🔸 Home Assistant OS VM +🔸Home Assistant OS VM

@home-assistant

@@ -135,7 +135,7 @@ ________________________________________________________________________________
-🔸 Home Assistant Container LXC +🔸Home Assistant Container LXC

Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

@@ -217,7 +217,7 @@ ________________________________________________________________________________
-🔸 Nginx Proxy Manager LXC +🔸Nginx Proxy Manager LXC

hero

@@ -530,7 +530,7 @@ ________________________________________________________________________________
-🔸 Zwavejs2MQTT LXC +🔸Zwavejs2MQTT LXC

From 2ccec15dba9d574cc2ee88def48d09047f175ef7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 13:14:25 -0500 Subject: [PATCH 0518/6505] Update ha_setup.sh --- ha_setup.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ha_setup.sh b/ha_setup.sh index 88841149..2464260d 100644 --- a/ha_setup.sh +++ b/ha_setup.sh @@ -37,7 +37,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ curl \ wget &>/dev/null - + echo -e "${CHECKMARK} \e[1;92m Customizing Docker... \e[0m" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) @@ -47,8 +47,11 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' } EOF -echo -e "${CHECKMARK} \e[1;92m Installing Docker.io... \e[0m" -apt-get install -y docker.io &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" +sh <(curl -sSL https://get.docker.com) &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Pulling Portainer Image...\e[0m" +docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Portainer... \e[0m" docker volume create portainer_data >/dev/null @@ -60,7 +63,10 @@ docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest &>/dev/null - + +echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" +docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" docker volume create hass_config >/dev/null docker run -d \ @@ -74,7 +80,7 @@ docker run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin From f9d95abdd26b2ff36c6f7086e2013b244429cc02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 13:15:36 -0500 Subject: [PATCH 0519/6505] Update ha_container.sh --- ha_container.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ha_container.sh b/ha_container.sh index 1ffee469..114d9c97 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/ha_setup.sh load_module overlay @@ -132,17 +132,23 @@ echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8/fuse-overlayfs-x86_64 warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi -ARCH=$(dpkg --print-architecture) + ARCH=$(dpkg --print-architecture) HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features fuse=1,keyctl=1,mknod=1,nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +else pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - +fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a @@ -155,9 +161,12 @@ pct unmount $CTID && unset MOUNT echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +info "Using fuse-overlayfs." +fi pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 pct exec $CTID /ha_setup.sh - IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully Created Home Assistant Container LXC to $CTID." msg " From 0a7d0a0dfc77aa0d2fb9d74218faf3c779183c44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 13:17:12 -0500 Subject: [PATCH 0520/6505] Update podman_ha_container.sh --- podman_ha_container.sh | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/podman_ha_container.sh b/podman_ha_container.sh index 6cec73d0..c63450b7 100644 --- a/podman_ha_container.sh +++ b/podman_ha_container.sh @@ -15,6 +15,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -72,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/podman_ha_setup.sh load_module overlay @@ -104,10 +105,9 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." - -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -128,28 +128,43 @@ case $STORAGE_TYPE in esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8/fuse-overlayfs-x86_64 warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi -ARCH=$(dpkg --print-architecture) + ARCH=$(dpkg --print-architecture) HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features fuse=1,keyctl=1,mknod=1,nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +else pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +info "Using fuse-overlayfs." +fi pct push $CTID podman_ha_setup.sh /podman_ha_setup.sh -perms 755 pct exec $CTID /podman_ha_setup.sh @@ -157,7 +172,8 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 info "Successfully created Home Assistant Container LXC to $CTID." msg " -Home Assistant is reachable by going to the following URLs. +Home Assistant should be reachable by going to the following URL. + http://${IP}:8123 " From 764acd1cade80f7d7fda90a919fb02f3d8c52bed Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 13:18:17 -0500 Subject: [PATCH 0521/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 771a8b72..5cde58f8 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -6,6 +6,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap 'die "Script interrupted."' INT @@ -22,29 +23,29 @@ function msg() { echo -e "$TEXT" } -msg "Setting up container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -msg "Installing prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ curl \ runc &>/dev/null -msg "Installing Podman..." +echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" apt-get -y install podman &>/dev/null -msg "Pulling Home Assistant Image..." -podman volume create hass_config >/dev/null +echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null -msg "Installing Home Assistant..." +echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" +podman volume create hass_config >/dev/null podman run -d \ --name homeassistant \ --restart=always \ @@ -54,7 +55,7 @@ podman run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -msg "Customizing container..." +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -68,5 +69,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 6b4fc08adc74cf2cea2594bb678f3dc861c4dfaf Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 13:19:05 -0500 Subject: [PATCH 0522/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dac53144..b96c3b8f 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ ________________________________________________________________________________
- Home Assistant Container LXC (Podman) + 🔸Home Assistant Container LXC (Podman)

@home-assistant

From 7b818bb7c8afd26c3ff6af846f30be728daf8dfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 14:01:39 -0500 Subject: [PATCH 0523/6505] Update podman_ha_setup.sh --- podman_ha_setup.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh index 5cde58f8..66a70e08 100644 --- a/podman_ha_setup.sh +++ b/podman_ha_setup.sh @@ -68,6 +68,10 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +podman generate systemd \ + --new --name homeassistant \ + > /etc/systemd/system/homeassistant.service +systemctl enable homeassistant &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 37f8476aa6619e14d29ac85866af63b642633976 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 14:03:18 -0500 Subject: [PATCH 0524/6505] Update ha_container.sh --- ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ha_container.sh b/ha_container.sh index 114d9c97..83bc47c4 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ha_setup.sh load_module overlay From 74690161b1cccfd4eaa13dfcdf510f166bfc955d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 14:03:48 -0500 Subject: [PATCH 0525/6505] Update podman_ha_container.sh --- podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/podman_ha_container.sh b/podman_ha_container.sh index c63450b7..8634e2c8 100644 --- a/podman_ha_container.sh +++ b/podman_ha_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/podman_ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_setup.sh load_module overlay From 461e9f985ff215887c6299d68b907d4b04d0378d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 14:22:18 -0500 Subject: [PATCH 0526/6505] Update README.md --- README.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b96c3b8f..4310b600 100644 --- a/README.md +++ b/README.md @@ -105,21 +105,14 @@ nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **To autostart Home Assistant at every boot:** +⚙️ **To allow device passthrough:** -Run from the LXC console +In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -podman generate systemd \ - --new --name homeassistant \ - > /etc/systemd/system/homeassistant.service -systemctl enable homeassistant +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 ``` -⚙️ **Start the homeassistant service:** -Run from the LXC console -``` -systemctl start homeassistant -``` +Reboot the LXC to apply the changes ⚙️ **To install HACS:** From 0503fe0c62f49367f340d1669e3bef98d4289796 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 22:20:25 -0500 Subject: [PATCH 0527/6505] Update ha_container.sh --- ha_container.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ha_container.sh b/ha_container.sh index 83bc47c4..cedea309 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -141,14 +141,13 @@ fi HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features fuse=1,keyctl=1,mknod=1,nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features fuse=1,keyctl=1,mknod=1,nesting=1 >/dev/null else -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 >/dev/null fi +-hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ +-ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a From 217e06930a05c7b2166900f03a62bbe510dbbd5c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 22:24:53 -0500 Subject: [PATCH 0528/6505] Update ha_container.sh --- ha_container.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ha_container.sh b/ha_container.sh index cedea309..bde0dd55 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -141,13 +141,13 @@ fi HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features fuse=1,keyctl=1,mknod=1,nesting=1 >/dev/null + CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" else -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 >/dev/null + CT_FEATURES="nesting=1" fi --hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ --ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a From 44ae530f987a29498ffa42a0cf843c8feb645203 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jan 2022 22:28:06 -0500 Subject: [PATCH 0529/6505] Update podman_ha_container.sh --- podman_ha_container.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/podman_ha_container.sh b/podman_ha_container.sh index 8634e2c8..66c08ea4 100644 --- a/podman_ha_container.sh +++ b/podman_ha_container.sh @@ -141,15 +141,13 @@ fi HOSTNAME=homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features fuse=1,keyctl=1,mknod=1,nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" else -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + CT_FEATURES="nesting=1" fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/nullLXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: From 42d7eb2b7f403c4d47b2634c346715835f15d594 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 07:12:45 -0500 Subject: [PATCH 0530/6505] Update npm_setup.sh --- npm_setup.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/npm_setup.sh b/npm_setup.sh index e6ba9b97..11066355 100644 --- a/npm_setup.sh +++ b/npm_setup.sh @@ -23,13 +23,17 @@ function msg() { echo -e "$TEXT" } -LASTCMD="" -WGETOPT="-t 1 -T 15 -q" +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null - # Cleanup - apt-get remove --purge -y build-essential python3-dev git -qq &>/dev/null - apt-get autoremove -y -qq &>/dev/null - apt-get clean +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null # Install dependencies echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" @@ -204,4 +208,4 @@ systemctl start openresty systemctl start npm echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /npm_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /npm_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 799397bbd1a4e26253d39bcb041d1f0cd240c2dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 07:16:34 -0500 Subject: [PATCH 0531/6505] Update npm_setup.sh --- npm_setup.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/npm_setup.sh b/npm_setup.sh index 11066355..28600ce4 100644 --- a/npm_setup.sh +++ b/npm_setup.sh @@ -70,9 +70,9 @@ echo -e "${CHECKMARK} \e[1;92m Installing Yarn... \e[0m" npm install --global yarn &>/dev/null # Download nginx-proxy-manager source -echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.14... \e[0m" -wget https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.14 -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-2.9.14 +echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.15... \e[0m" +wget https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.15 -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-2.9.15 # Crate required symbolic links echo -e "${CHECKMARK} \e[1;92m Setting up Enviroment... \e[0m" @@ -82,8 +82,8 @@ ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx # Update NPM version in package.json files -sed -i "s+0.0.0+#v2.9.14+g" backend/package.json -sed -i "s+0.0.0+#v2.9.14+g" frontend/package.json +sed -i "s+0.0.0+#v2.9.15+g" backend/package.json +sed -i "s+0.0.0+#v2.9.15+g" frontend/package.json # Fix nginx config files for use with openresty defaults sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf From 00bd215b4165e331ef1509f4b1ab6a931ecafbff Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 07:19:28 -0500 Subject: [PATCH 0532/6505] Update npm_container.sh --- npm_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm_container.sh b/npm_container.sh index 3f3e373e..3bdd0d8b 100644 --- a/npm_container.sh +++ b/npm_container.sh @@ -74,7 +74,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/npm_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/npm_setup.sh load_module overlay @@ -156,4 +156,4 @@ pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 pct exec $CTID /npm_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" \ No newline at end of file +info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" From 60e639a4552a868f6fced8f0c4216bc0c531ddf3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 07:19:59 -0500 Subject: [PATCH 0533/6505] Update npm_container.sh --- npm_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm_container.sh b/npm_container.sh index 3f3e373e..48fa1eb1 100644 --- a/npm_container.sh +++ b/npm_container.sh @@ -74,7 +74,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/wip/npm_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/npm_setup.sh load_module overlay @@ -156,4 +156,4 @@ pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 pct exec $CTID /npm_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" \ No newline at end of file +info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" From d2f641558bb230196f17e6b4b4a0ba23ea94d982 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 07:55:07 -0500 Subject: [PATCH 0534/6505] Update npm_setup.sh --- npm_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm_setup.sh b/npm_setup.sh index 28600ce4..8adba8aa 100644 --- a/npm_setup.sh +++ b/npm_setup.sh @@ -24,14 +24,14 @@ function msg() { } # Prepare container OS -msg "Setting up container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 3804210089d76e3e8d7d95dc35af0170ff65ed71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 08:01:09 -0500 Subject: [PATCH 0535/6505] Update npm_container.sh --- npm_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm_container.sh b/npm_container.sh index 3bdd0d8b..48fa1eb1 100644 --- a/npm_container.sh +++ b/npm_container.sh @@ -74,7 +74,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/npm_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/npm_setup.sh load_module overlay From 5b85e0e4866ed2beea9aeab987df24f7da98e0f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 09:11:41 -0500 Subject: [PATCH 0536/6505] Update ha_container.sh --- ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ha_container.sh b/ha_container.sh index bde0dd55..9fcf0647 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -132,7 +132,7 @@ echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8/fuse-overlayfs-x86_64 + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null From 22f6e8c377b33f6b361d9e0f1d7eca6db9205681 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 09:12:19 -0500 Subject: [PATCH 0537/6505] Update podman_ha_container.sh --- podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/podman_ha_container.sh b/podman_ha_container.sh index 66c08ea4..82c2782f 100644 --- a/podman_ha_container.sh +++ b/podman_ha_container.sh @@ -132,7 +132,7 @@ echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8/fuse-overlayfs-x86_64 + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null From 1eb9bc3759a01730dff0ace8e45a1398b3ca8251 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 15:33:35 -0500 Subject: [PATCH 0538/6505] Add files via upload --- ubuntu_container.sh | 158 ++++++++++++++++++++++++++++++++++++++++++++ ubuntu_setup.sh | 55 +++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 ubuntu_container.sh create mode 100644 ubuntu_setup.sh diff --git a/ubuntu_container.sh b/ubuntu_container.sh new file mode 100644 index 00000000..5dfd39f9 --- /dev/null +++ b/ubuntu_container.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Ubuntu 21.10 LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ubuntu_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-21.10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=$OSTYPE +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" +pct start $CTID +pct push $CTID ubuntu_setup.sh /ubuntu_setup.sh -perms 755 +pct exec $CTID /ubuntu_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Ubuntu LXC Container to $CTID at IP Address ${IP}" \ No newline at end of file diff --git a/ubuntu_setup.sh b/ubuntu_setup.sh new file mode 100644 index 00000000..97870853 --- /dev/null +++ b/ubuntu_setup.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /ubuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 755f7fb2c957302bfa97cf7df96c456146c461c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 15:49:12 -0500 Subject: [PATCH 0539/6505] Update README.md --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4310b600..fa0c9365 100644 --- a/README.md +++ b/README.md @@ -554,7 +554,7 @@ ________________________________________________________________________________
-Debian 11+ LXC +Debian 11 LXC

Debian

@@ -574,6 +574,27 @@ ________________________________________________________________________________
+
+🔸Ubuntu 21.10 LXC + +

Ubuntu

+ +

Proxmox Ubuntu 21.10 LXC Container

+ +To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ubuntu_container.sh)" +``` +

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. + +____________________________________________________________________________________________ + +
+ +
Plex Media Server LXC From 1065860ca9bc80c93e28c47424463a2e982f4816 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:18:50 -0500 Subject: [PATCH 0540/6505] Create setup files --- setup/setup files | 1 + 1 file changed, 1 insertion(+) create mode 100644 setup/setup files diff --git a/setup/setup files b/setup/setup files new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/setup/setup files @@ -0,0 +1 @@ + From 75079891cfd5b77b3c3f9dbd0b1b893174fc7df3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:19:45 -0500 Subject: [PATCH 0541/6505] Add files via upload --- setup/ubuntu_setup.sh | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 setup/ubuntu_setup.sh diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh new file mode 100644 index 00000000..97870853 --- /dev/null +++ b/setup/ubuntu_setup.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /ubuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 3e2e299c77ade33c22a83a2e3c6b42d953c2719e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:21:38 -0500 Subject: [PATCH 0542/6505] Update ubuntu_container.sh --- ubuntu_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ubuntu_container.sh b/ubuntu_container.sh index 5dfd39f9..dfef6a5a 100644 --- a/ubuntu_container.sh +++ b/ubuntu_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ubuntu_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu_setup.sh load_module overlay @@ -155,4 +155,4 @@ pct push $CTID ubuntu_setup.sh /ubuntu_setup.sh -perms 755 pct exec $CTID /ubuntu_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Ubuntu LXC Container to $CTID at IP Address ${IP}" \ No newline at end of file +info "Successfully created a Ubuntu LXC Container to $CTID at IP Address ${IP}" From 1ae8d9d4179a2d700a84ce16c5a8dfbbb32ae2ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:30:07 -0500 Subject: [PATCH 0543/6505] Create adguard_setup.sh --- setup/adguard_setup.sh | 58 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 setup/adguard_setup.sh diff --git a/setup/adguard_setup.sh b/setup/adguard_setup.sh new file mode 100644 index 00000000..e29e9a5d --- /dev/null +++ b/setup/adguard_setup.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating Container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing Prerequisites..." +apt-get -y install \ + curl \ + sudo &>/dev/null + +msg "Installing AdGuard Home.." +curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null + +msg "Customizing LXC..." +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /adguard_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From beec96bbca8b7f26761ef749e982ae6844e4c7a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:30:28 -0500 Subject: [PATCH 0544/6505] Delete setup files --- setup/setup files | 1 - 1 file changed, 1 deletion(-) delete mode 100644 setup/setup files diff --git a/setup/setup files b/setup/setup files deleted file mode 100644 index 8b137891..00000000 --- a/setup/setup files +++ /dev/null @@ -1 +0,0 @@ - From a90e612e73377a81ea0ded215bbb662459362f12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:31:51 -0500 Subject: [PATCH 0545/6505] Create debian11_setup.sh --- setup/debian11_setup.sh | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 setup/debian11_setup.sh diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh new file mode 100644 index 00000000..0bca50d1 --- /dev/null +++ b/setup/debian11_setup.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 21d769ac3d524e8d06a8bf5f1f7fc80f7226ed0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:32:46 -0500 Subject: [PATCH 0546/6505] Create esphome_setup.sh --- setup/esphome_setup.sh | 84 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 setup/esphome_setup.sh diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh new file mode 100644 index 00000000..86fb104d --- /dev/null +++ b/setup/esphome_setup.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + # Installing pip3 + msg "Installing pip3..." + apt-get install python3-pip -y &>/dev/null + # Install ESPHome; + msg "Installing ESPHome..." + pip3 install esphome &>/dev/null + # Installing ESPHome Dashboard + msg "Installing ESPHome Dashboard..." + pip3 install tornado esptool &>/dev/null + +echo "Creating service file esphomeDashboard.service" +service_path="/etc/systemd/system/esphomeDashboard.service" + +echo "[Unit] +Description=ESPHome Dashboard +After=network.target +[Service] +ExecStart=/usr/local/bin/esphome /root/config/ dashboard +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable esphomeDashboard.service &>/dev/null +systemctl start esphomeDashboard +# Customize container +msg "Customizing Container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 7a73bfc983217263465c3bd6332ee2fbd2b2cbe5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:33:31 -0500 Subject: [PATCH 0547/6505] Create ha_setup.sh --- setup/ha_setup.sh | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 setup/ha_setup.sh diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh new file mode 100644 index 00000000..2464260d --- /dev/null +++ b/setup/ha_setup.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get -qqy install \ + curl \ + wget &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Customizing Docker... \e[0m" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" +sh <(curl -sSL https://get.docker.com) &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Pulling Portainer Image...\e[0m" +docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Portainer... \e[0m" +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" +docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" +docker volume create hass_config >/dev/null +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 8fcbd5afe5a3486d2418cd9dc5e9d5ec6b4c3580 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:34:53 -0500 Subject: [PATCH 0548/6505] Create mariadb_setup.sh --- setup/mariadb_setup.sh | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 setup/mariadb_setup.sh diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh new file mode 100644 index 00000000..5b4d5120 --- /dev/null +++ b/setup/mariadb_setup.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +# Installing MariaDB +msg "Installing MariaDB..." +sudo apt-get update >/dev/null +sudo apt-get install -y mariadb-server &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 4357d917d3a3467473488f1657e8b724513a2f1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:35:48 -0500 Subject: [PATCH 0549/6505] Create mqtt_setup.sh --- setup/mqtt_setup.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 setup/mqtt_setup.sh diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh new file mode 100644 index 00000000..f2276a8c --- /dev/null +++ b/setup/mqtt_setup.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +# Installing Mosquitto MQTT broker +msg "Installing Mosquitto MQTT broker.." +sudo apt-get update >/dev/null +sudo apt-get -y install mosquitto &>/dev/null +sudo apt-get -y install mosquitto-clients &>/dev/null + +# Customize container +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From e7f036ac61cec69bddff0dbdfe2098d68c25f487 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:37:19 -0500 Subject: [PATCH 0550/6505] Create node-red_setup.sh --- setup/node-red_setup.sh | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 setup/node-red_setup.sh diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh new file mode 100644 index 00000000..0f314261 --- /dev/null +++ b/setup/node-red_setup.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing Node-Red..." +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi + +#msg "Installing Node..." +#sudo apt -y install nodejs npm &>/dev/null + +#msg "Installing PM2..." +#npm install -g pm2 &>/dev/null + +#msg "Installing Node-RED..." +#npm install -g --unsafe-perm node-red &>/dev/null + +#msg "Setting up PM2..." +#/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null +#/usr/local/bin/pm2 save &>/dev/null +#/usr/local/bin/pm2 startup &>/dev/null + +msg "Customizing container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 1ba2770ae8389f1013346ef32219ff6ad9c44fc7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:38:19 -0500 Subject: [PATCH 0551/6505] Create npm_setup.sh --- setup/npm_setup.sh | 211 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 setup/npm_setup.sh diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh new file mode 100644 index 00000000..8adba8aa --- /dev/null +++ b/setup/npm_setup.sh @@ -0,0 +1,211 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + + # Install dependencies + echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" + echo "fs.file-max = 65535" > /etc/sysctl.conf + apt-get update &>/dev/null + apt-get -y install --no-install-recommends sudo curl wget gnupg openssl ca-certificates apache2-utils logrotate build-essential python3-dev git lsb-release &>/dev/null + + # Install Python + echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" + apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null + pip3 install --upgrade setuptools &>/dev/null + pip3 install --upgrade pip &>/dev/null + python3 -m venv /opt/certbot/ &>/dev/null + if [ "$(getconf LONG_BIT)" = "32" ]; then + python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null + fi + python3 -m pip install --no-cache-dir cffi certbot &>/dev/null +#fi + # Install openresty +echo -e "${CHECKMARK} \e[1;92m Installing Openresty... \e[0m" +wget -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null +codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null +echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null +apt-get -y update &>/dev/null +apt-get -y install --no-install-recommends openresty &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Yarn... \e[0m" +npm install --global yarn &>/dev/null + +# Download nginx-proxy-manager source +echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.15... \e[0m" +wget https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.15 -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-2.9.15 + +# Crate required symbolic links +echo -e "${CHECKMARK} \e[1;92m Setting up Enviroment... \e[0m" +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /usr/bin/certbot /opt/certbot/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx + +# Update NPM version in package.json files +sed -i "s+0.0.0+#v2.9.15+g" backend/package.json +sed -i "s+0.0.0+#v2.9.15+g" frontend/package.json + +# Fix nginx config files for use with openresty defaults +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done + +# Copy runtime files +mkdir -p /var/www/html /etc/nginx/logs +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf + +# Create required folders +mkdir -p /tmp/nginx/body \ +/run/nginx \ +/data/nginx \ +/data/custom_ssl \ +/data/logs \ +/data/access \ +/data/nginx/default_host \ +/data/nginx/default_www \ +/data/nginx/proxy_host \ +/data/nginx/redirection_host \ +/data/nginx/stream \ +/data/nginx/dead_host \ +/data/nginx/temp \ +/var/lib/nginx/cache/public \ +/var/lib/nginx/cache/private \ +/var/cache/nginx/proxy_temp + +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx + +# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf + +# Generate dummy self-signed certificate. +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi + +# Copy app files +mkdir -p /app/global /app/frontend/images +cp -r backend/* /app +cp -r global/* /app/global + +# Build the frontend +echo -e "${CHECKMARK} \e[1;92m Building Frontend... \e[0m" +cd ./frontend +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +yarn build &>/dev/null +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images + +# Initialize backend +echo -e "${CHECKMARK} \e[1;92m Initializing Backend... \e[0m" +rm -rf /app/config/default.json &>/dev/null +if [ ! -f /app/config/production.json ]; then +cat << 'EOF' > /app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF +fi +cd /app +export NODE_ENV=development +yarn install --network-timeout=30000 + +# Create NPM service +echo -e "${CHECKMARK} \e[1;92m Creating NPM Service... \e[0m" +cat << 'EOF' > /lib/systemd/system/npm.service +[Unit] +Description=Nginx Proxy Manager +After=network.target +Wants=openresty.service + +[Service] +Type=simple +Environment=NODE_ENV=production +ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge +ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 +WorkingDirectory=/app +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Start services +echo -e "${CHECKMARK} \e[1;92m Starting Services... \e[0m" +systemctl enable npm &>/dev/null +systemctl start openresty +systemctl start npm + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /npm_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 77fa05f2fd8cc16044ab54ff234b158426e9e6ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:39:32 -0500 Subject: [PATCH 0552/6505] Create pihole_setup.sh --- setup/pihole_setup.sh | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 setup/pihole_setup.sh diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh new file mode 100644 index 00000000..b47a39ff --- /dev/null +++ b/setup/pihole_setup.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +msg "Setting up LXC OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + +msg "Installing Pi-hole.." +curl -sSL https://install.pi-hole.net | bash + +msg "Customizing LXC..." +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +msg "Cleanup..." +rm -rf /pihole_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 0363b7b2bcf4ae443edab669fb0fca63c88daa69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:40:40 -0500 Subject: [PATCH 0553/6505] Create plex_setup.sh --- setup/plex_setup.sh | 65 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 setup/plex_setup.sh diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh new file mode 100644 index 00000000..fb4e24fe --- /dev/null +++ b/setup/plex_setup.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt-get -qqy install \ + curl \ + sudo \ + gnupg &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading Plex Media Server... \e[0m" +wget https://downloads.plex.tv/plex-media-server-new/1.25.2.5319-c43dc0277/debian/plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" +sudo dpkg -i plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null + +cat < /etc/apt/sources.list.d/plexmediaserver.list +deb https://downloads.plex.tv/repo/deb/ public main +EOF + +wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c1286cd498125ca55bbcc58c49e4c842c9d607e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:42:19 -0500 Subject: [PATCH 0554/6505] Create podman_ha_setup.sh --- setup/podman_ha_setup.sh | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 setup/podman_ha_setup.sh diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh new file mode 100644 index 00000000..66a70e08 --- /dev/null +++ b/setup/podman_ha_setup.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get -qqy install \ + curl \ + runc &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" +apt-get -y install podman &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" +podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" +podman volume create hass_config >/dev/null +podman run -d \ + --name homeassistant \ + --restart=always \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +podman generate systemd \ + --new --name homeassistant \ + > /etc/systemd/system/homeassistant.service +systemctl enable homeassistant &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From feb9571d3e05042100b75a4759d779da7ae9bda2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:43:28 -0500 Subject: [PATCH 0555/6505] Create zigbee2mqtt_setup.sh --- setup/zigbee2mqtt_setup.sh | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 setup/zigbee2mqtt_setup.sh diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh new file mode 100644 index 00000000..fabb3dd6 --- /dev/null +++ b/setup/zigbee2mqtt_setup.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +# Prepare container OS +msg "Setting up Container OS..." +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +# Update container OS +msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +# Install prerequisites +msg "Installing Prerequisites..." +apt-get -qqy install \ + curl \ + sudo &>/dev/null + # Setup Node.js repository + msg "Setting up Node.js Repository..." + sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null + # Install Node.js; + msg "Installing Node.js..." + sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + # Clone Zigbee2MQTT repository + msg "Setting up Zigbee2MQTT Repository..." + sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null + # Install zigbee2mqtt + msg "Installing Zigbee2MQTT..." + cd /opt/zigbee2mqtt &>/dev/null + npm ci &>/dev/null + +echo "Creating service file zigbee2mqtt.service" +service_path="/etc/systemd/system/zigbee2mqtt.service" + +echo "[Unit] +Description=zigbee2mqtt +After=network.target +[Service] +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zigbee2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path + +# Customize container +msg "Customizing Container..." +rm /etc/motd # Remove message of the day after login +rm /etc/update-motd.d/10-uname # Remove kernel information after login +touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +# Cleanup container +msg "Cleanup..." +rm -rf /zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From ae4edd0bf0b4198df252f6174b0f9b12b42d6767 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:44:47 -0500 Subject: [PATCH 0556/6505] Create zwavejs2mqtt_setup.sh --- setup/zwavejs2mqtt_setup.sh | 90 +++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 setup/zwavejs2mqtt_setup.sh diff --git a/setup/zwavejs2mqtt_setup.sh b/setup/zwavejs2mqtt_setup.sh new file mode 100644 index 00000000..02566c86 --- /dev/null +++ b/setup/zwavejs2mqtt_setup.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt-get -qqy install \ + curl \ + sudo \ + unzip &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" + sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" + sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Installing yarn... \e[0m" + npm install --global yarn &>/dev/null + + echo -e "${CHECKMARK} \e[1;92m Build/Install Zwavejs2MQTT (5-6 min)... \e[0m" + sudo git clone https://github.com/zwave-js/zwavejs2mqtt /opt/zwavejs2mqtt &>/dev/null + cd /opt/zwavejs2mqtt &>/dev/null + yarn install &>/dev/null + yarn run build &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Creating Service file zwavejs2mqtt.service... \e[0m" +service_path="/etc/systemd/system/zwavejs2mqtt.service" + +echo "[Unit] +Description=zwavejs2mqtt +After=network.target +[Service] +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zwavejs2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path + +echo -e "${CHECKMARK} \e[1;92m Customizing container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /zwavejs2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +systemctl start zwavejs2mqtt +systemctl enable zwavejs2mqtt &>/dev/null From c59a73bbc4241b3112465215a80b8e5a11805397 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:46:47 -0500 Subject: [PATCH 0557/6505] Update adguard_container.sh --- adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adguard_container.sh b/adguard_container.sh index 61a75d82..547c776e 100644 --- a/adguard_container.sh +++ b/adguard_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/adguard_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard_setup.sh load_module overlay From aea889b80bb8f6bab3af5506d0c4e82b35596c23 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:47:18 -0500 Subject: [PATCH 0558/6505] Update debian11_container.sh --- debian11_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian11_container.sh b/debian11_container.sh index 6ebc5687..be641145 100644 --- a/debian11_container.sh +++ b/debian11_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/debian11_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian11_setup.sh # Detect modules and automatically load at boot load_module overlay From d5216032b589cb74dda2667bda29a422ca420190 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:47:51 -0500 Subject: [PATCH 0559/6505] Update esphome_container.sh --- esphome_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome_container.sh b/esphome_container.sh index 2796790b..3979e7c2 100644 --- a/esphome_container.sh +++ b/esphome_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/esphome_setup.sh # Detect modules and automatically load at boot load_module overlay From a957b4abfe1014838f797985fa710c08d7ff8047 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:48:21 -0500 Subject: [PATCH 0560/6505] Update ha_container.sh --- ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ha_container.sh b/ha_container.sh index 9fcf0647..9616f0ba 100644 --- a/ha_container.sh +++ b/ha_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ha_setup.sh load_module overlay From 153acc367c626017c163034461254c7f60638d2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:48:52 -0500 Subject: [PATCH 0561/6505] Update mariadb_container.sh --- mariadb_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mariadb_container.sh b/mariadb_container.sh index 01fc2ae9..9ab1ea7c 100644 --- a/mariadb_container.sh +++ b/mariadb_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb_setup.sh # Detect modules and automatically load at boot #load_module aufs From b5576fbe7634af099e032475dad8ea58f75fef14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:49:21 -0500 Subject: [PATCH 0562/6505] Update mqtt_container.sh --- mqtt_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_container.sh b/mqtt_container.sh index ccaf4aaf..655f5f4f 100644 --- a/mqtt_container.sh +++ b/mqtt_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt_setup.sh # Detect modules and automatically load at boot #load_module aufs From f8ea7aba3a1415172b869b523a35a17676d49607 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:50:19 -0500 Subject: [PATCH 0563/6505] Update node-red_container.sh --- node-red_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-red_container.sh b/node-red_container.sh index b94a29b5..d287e88f 100644 --- a/node-red_container.sh +++ b/node-red_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red_setup.sh # Detect modules and automatically load at boot load_module overlay From e573a905770215deb2fdf6c88a1badf5648ca1e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:50:54 -0500 Subject: [PATCH 0564/6505] Update npm_container.sh --- npm_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm_container.sh b/npm_container.sh index 48fa1eb1..4e6c7c64 100644 --- a/npm_container.sh +++ b/npm_container.sh @@ -74,7 +74,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/npm_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/npm_setup.sh load_module overlay From 0e6f3a275551011e8d82d39bd913a0b4c028bc71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:51:25 -0500 Subject: [PATCH 0565/6505] Update pihole_container.sh --- pihole_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole_container.sh b/pihole_container.sh index 874bd76c..7eb7c05a 100644 --- a/pihole_container.sh +++ b/pihole_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/pihole_setup.sh load_module overlay From 328904fba086ba7ecf6e063f994a137a25a16f28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:52:01 -0500 Subject: [PATCH 0566/6505] Update plex_container.sh --- plex_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plex_container.sh b/plex_container.sh index f9050b70..c3c8b492 100644 --- a/plex_container.sh +++ b/plex_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/plex_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh load_module overlay From 851395e867c269ea5f748b7390a201076b3db1fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:52:33 -0500 Subject: [PATCH 0567/6505] Update podman_ha_container.sh --- podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/podman_ha_container.sh b/podman_ha_container.sh index 82c2782f..fe294e68 100644 --- a/podman_ha_container.sh +++ b/podman_ha_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman_ha_setup.sh load_module overlay From dfd225fa29197cd11825a2fbb6275b0b8b93f388 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:53:14 -0500 Subject: [PATCH 0568/6505] Update zigbee2mqtt_container.sh --- zigbee2mqtt_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zigbee2mqtt_container.sh b/zigbee2mqtt_container.sh index 9d84626e..1c19adfb 100644 --- a/zigbee2mqtt_container.sh +++ b/zigbee2mqtt_container.sh @@ -74,7 +74,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null # Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/zigbee2mqtt_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt_setup.sh # Detect modules and automatically load at boot load_module overlay From fa1f5b6ecfc2c0a0302cfcb7ccc9f1a1e53fd2df Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:53:48 -0500 Subject: [PATCH 0569/6505] Update zwavejs2mqtt_container.sh --- zwavejs2mqtt_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zwavejs2mqtt_container.sh b/zwavejs2mqtt_container.sh index c3bce3bc..3d42e6a5 100644 --- a/zwavejs2mqtt_container.sh +++ b/zwavejs2mqtt_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zwavejs2mqtt_setup.sh load_module overlay From 001666017f8bdac500ac036cfea3fba714d70f0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 18:57:50 -0500 Subject: [PATCH 0570/6505] Create holder --- misc/holder | 1 + 1 file changed, 1 insertion(+) create mode 100644 misc/holder diff --git a/misc/holder b/misc/holder new file mode 100644 index 00000000..55f985c9 --- /dev/null +++ b/misc/holder @@ -0,0 +1 @@ +place holder From c30f1289c968b0a96fa31000e0fe9a392721cd32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:27:01 -0500 Subject: [PATCH 0571/6505] Create autodev.sh --- misc/autodev.sh | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 misc/autodev.sh diff --git a/misc/autodev.sh b/misc/autodev.sh new file mode 100644 index 00000000..e96f2245 --- /dev/null +++ b/misc/autodev.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +while true; do + read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +CHAR_DEVS+=("188:.*") +CHAR_DEVS+=("189:.*") + +for char_dev in ${CHAR_DEVS[@]}; do + [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" + CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" +done + +read -r -d '' HOOK_SCRIPT <<- EOF || true +for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do + dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; + mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); + for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do + mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); + cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; + done; + cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; +done; +EOF +HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} + +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf +cat CTID.conf >$CTID_CONFIG_PATH + +cat <> $CTID_CONFIG_PATH +lxc.autodev: 1 +lxc.hook.autodev: bash -c '$HOOK_SCRIPT' +EOF + +# In the Proxmox web shell run (replace 106 with your LXC ID) +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 +# Reboot the LXC to apply the changes From 57c0fbeb028a8430c9cc1ef32e385cdedbcb5862 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:28:17 -0500 Subject: [PATCH 0572/6505] Create plex_hardware_acceleration.sh --- misc/plex_hardware_acceleration.sh | 64 ++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 misc/plex_hardware_acceleration.sh diff --git a/misc/plex_hardware_acceleration.sh b/misc/plex_hardware_acceleration.sh new file mode 100644 index 00000000..5cba0db2 --- /dev/null +++ b/misc/plex_hardware_acceleration.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will add Hardware Acceleration Support to your Plex Media Server LXC. + Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +cat <> $CTID_CONFIG_PATH +### Intel iGPU: ### +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 +#lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file 0, 0 +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 0, 0 +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file 0, 0 + +### NVidia GPU: ### +#lxc.cgroup2.devices.allow: c 195:* rwm +#lxc.cgroup2.devices.allow: c 243:* rwm +#lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file +#lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file +#lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file +#lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file +#lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file +#lxc.cgroup2.devices.allow: c 226:0 rwm +#lxc.cgroup2.devices.allow: c 226:128 rwm +#lxc.cgroup2.devices.allow: c 29:0 rwm +#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 +EOF +echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" + +# Plex can transcode media files on the fly. By default they use the CPU. +# All Intel CPU’s since Sandy Bridge released in 2011 have hardware acceleration for H.264 built in. +# So if your CPU supports Quick Sync you can speed up transcoding and reduce load by running the +# following in the Proxmox web shell (replace 106 with your LXC ID) +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_hardware_acceleration.sh)" -s 106 +# Reboot the LXC to apply the changes + From 2e7cbf54a63c8d5ae56a701013d28de325c136f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:29:49 -0500 Subject: [PATCH 0573/6505] Create hacs.sh --- misc/hacs.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 misc/hacs.sh diff --git a/misc/hacs.sh b/misc/hacs.sh new file mode 100644 index 00000000..ed476b0d --- /dev/null +++ b/misc/hacs.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" + +while true; do + read -p "Start the HACS Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +apt update &>/dev/null +apt install unzip &>/dev/null +cd /var/lib/docker/volumes/hass_config/_data +wget -O - https://get.hacs.xyz | bash - + +# To install HACS run the following from the container (LXC) console +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs.sh)" +# Then add the integration in HA From 78d6900a83bf9017a15eff21ce193378167a0249 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:31:23 -0500 Subject: [PATCH 0574/6505] Create podman_hacs.sh --- misc/podman_hacs.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 misc/podman_hacs.sh diff --git a/misc/podman_hacs.sh b/misc/podman_hacs.sh new file mode 100644 index 00000000..d85ad7da --- /dev/null +++ b/misc/podman_hacs.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" + +while true; do + read -p "Start the HACS Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +apt update &>/dev/null +apt install unzip &>/dev/null +cd /var/lib/containers/storage/volumes/hass_config/_data +wget -O - https://get.hacs.xyz | bash - + +# To install HACS run the following from the container (LXC) console +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman_hacs.sh)" +# Then add the integration in HA From fdb4ea667e6a436dce9e8441c798c26ca20830fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:32:42 -0500 Subject: [PATCH 0575/6505] Create post_install.sh --- misc/post_install.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 misc/post_install.sh diff --git a/misc/post_install.sh b/misc/post_install.sh new file mode 100644 index 00000000..c890bc8e --- /dev/null +++ b/misc/post_install.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +echo -e "\e[1;33m This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, +Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) +and attempt the No-Nag fix. PVE7 ONLY \e[0m" +while true; do + read -p "Start the PVE7 Post Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list +cat < /etc/apt/sources.list +deb http://ftp.debian.org/debian bullseye main contrib +deb http://ftp.debian.org/debian bullseye-updates main contrib +deb http://security.debian.org/debian-security bullseye-security main contrib +deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription +# deb http://download.proxmox.com/debian/pve bullseye pvetest +EOF +echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script +apt --reinstall install proxmox-widget-toolkit &>/dev/null +echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" + +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/post_install.sh)" From 4ee060b66be705c88ae87d1267600cf8ab2587e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:34:18 -0500 Subject: [PATCH 0576/6505] Create update_ha.md --- misc/update_ha.md | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 misc/update_ha.md diff --git a/misc/update_ha.md b/misc/update_ha.md new file mode 100644 index 00000000..dfb4276b --- /dev/null +++ b/misc/update_ha.md @@ -0,0 +1,78 @@ +## Home Assistant Container Update ## + +In the homeassistant lxc console run `nano upha.sh` +it will open a empty file, copy and paste the Stable Branch (change TZ) +Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X" +To update HA, run `bash upha.sh` from the console + +Stable Branch +``` +### upha.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Stable Version... \e[0m" +docker pull homeassistant/home-assistant:stable +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:stable +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` + +Beta Branch +``` +### uphabeta.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Beta Version... \e[0m" +docker pull homeassistant/home-assistant:beta +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:beta +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` + +Development Branch +``` +### uphadev.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Dev Version... \e[0m" +docker pull homeassistant/home-assistant:dev +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:dev +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` + +Portainer-CE +``` +### upportainer.sh ### +#!/bin/bash + +echo -e "\e[1;33m Pulling New Portainer-Ce Version... \e[0m" +docker pull portainer/portainer-ce:latest +echo -e "\e[1;33m Stopping Portainer... \e[0m" +docker stop portainer +echo -e "\e[1;33m Removing Portainer... \e[0m" +docker rm portainer +echo -e "\e[1;33m Starting Portainer... \e[0m" +docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" +``` From f6264e3975a8cfb35b29ca87bddd29b4970b2d70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:34:46 -0500 Subject: [PATCH 0577/6505] Delete holder --- misc/holder | 1 - 1 file changed, 1 deletion(-) delete mode 100644 misc/holder diff --git a/misc/holder b/misc/holder deleted file mode 100644 index 55f985c9..00000000 --- a/misc/holder +++ /dev/null @@ -1 +0,0 @@ -place holder From 5e8d2ff8a05748604ba1b7440d26202a9ac8eee5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:39:13 -0500 Subject: [PATCH 0578/6505] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fa0c9365..63f0857e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ and attempt the *No-Nag* fix. Run the following in the Proxmox Web Shell. ⚠️ **PVE7 ONLY** ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/post_install.sh)" ``` It's recommended to update Proxmox after running this script, before adding any VM/CT. @@ -109,7 +109,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -118,7 +118,7 @@ Reboot the LXC to apply the changes Run the from the LXC console ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman_hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -166,7 +166,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -176,7 +176,7 @@ Reboot the LXC to apply the changes Run the from the LXC console ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -462,7 +462,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigb In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -542,7 +542,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwav In the Proxmox web shell run (**replace `106` with your LXC ID)** ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` Reboot the LXC to apply the changes From 18b7db3a4c4983768da504539658766a30b431a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:45:05 -0500 Subject: [PATCH 0579/6505] Update podman_ha_container.sh --- podman_ha_container.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/podman_ha_container.sh b/podman_ha_container.sh index fe294e68..d78d9d99 100644 --- a/podman_ha_container.sh +++ b/podman_ha_container.sh @@ -147,7 +147,8 @@ else fi pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/nullLXC_CONFIG=/etc/pve/lxc/${CTID}.conf + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: From d10141144e2b4e8fb9c8281ab432981f4d2127f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:54:02 -0500 Subject: [PATCH 0580/6505] Create podman.md --- misc/podman.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 misc/podman.md diff --git a/misc/podman.md b/misc/podman.md new file mode 100644 index 00000000..34b45371 --- /dev/null +++ b/misc/podman.md @@ -0,0 +1,11 @@ +

+ +Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System. Similar to Docker, Podman is an open source project. Anybody can check out the source code for the program. Contrary to Docker, Podman does not require a daemon process to launch and manage containers. This is an important difference between the two projects. + +Podman seeks to improve on some of Docker’s drawbacks. For one, Podman does not require a daemon running as root. In fact, Podman containers run with the same permissions as the user who launched them. This addresses a significant security concern, although you can still run containers with root permissions if you really want to. + +Podman seeks to be a drop-in replacement for Docker as far as the CLI is concerned. The developers boast that most users can simply use alias docker=podman and continue running the same familiar commands. The container image format is also fully compatible between Docker and Podman, so existing containers built on Dockerfiles will work with Podman. + +Another key difference is that, it handles running containers, but not building them (non-monolithic). The goal here is to have a set of container standards that any application can be developed to support, rather than relying on a single monolithic application such as Docker to perform all duties. + +https://www.liquidweb.com/kb/podman-vs-docker/ ___ https://github.com/containers/podman-compose ___ https://podman.io/ From 70d4f55bb4299411e6bf669f5a708fd274cffd82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:54:25 -0500 Subject: [PATCH 0581/6505] Delete Podman.md --- Podman.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 Podman.md diff --git a/Podman.md b/Podman.md deleted file mode 100644 index 34b45371..00000000 --- a/Podman.md +++ /dev/null @@ -1,11 +0,0 @@ -

- -Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System. Similar to Docker, Podman is an open source project. Anybody can check out the source code for the program. Contrary to Docker, Podman does not require a daemon process to launch and manage containers. This is an important difference between the two projects. - -Podman seeks to improve on some of Docker’s drawbacks. For one, Podman does not require a daemon running as root. In fact, Podman containers run with the same permissions as the user who launched them. This addresses a significant security concern, although you can still run containers with root permissions if you really want to. - -Podman seeks to be a drop-in replacement for Docker as far as the CLI is concerned. The developers boast that most users can simply use alias docker=podman and continue running the same familiar commands. The container image format is also fully compatible between Docker and Podman, so existing containers built on Dockerfiles will work with Podman. - -Another key difference is that, it handles running containers, but not building them (non-monolithic). The goal here is to have a set of container standards that any application can be developed to support, rather than relying on a single monolithic application such as Docker to perform all duties. - -https://www.liquidweb.com/kb/podman-vs-docker/ ___ https://github.com/containers/podman-compose ___ https://podman.io/ From 2650ab65c6221cfab3159bcda1cfa1b53efd2d29 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:55:31 -0500 Subject: [PATCH 0582/6505] Delete adguard_setup.sh --- adguard_setup.sh | 58 ------------------------------------------------ 1 file changed, 58 deletions(-) delete mode 100644 adguard_setup.sh diff --git a/adguard_setup.sh b/adguard_setup.sh deleted file mode 100644 index e29e9a5d..00000000 --- a/adguard_setup.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -msg "Setting up Container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -msg "Updating Container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -msg "Installing Prerequisites..." -apt-get -y install \ - curl \ - sudo &>/dev/null - -msg "Installing AdGuard Home.." -curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null - -msg "Customizing LXC..." -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -msg "Cleanup..." -rm -rf /adguard_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From de4710b0f386a0f644bca6e848204b47df3448d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:55:50 -0500 Subject: [PATCH 0583/6505] Delete autodev.sh --- autodev.sh | 73 ------------------------------------------------------ 1 file changed, 73 deletions(-) delete mode 100644 autodev.sh diff --git a/autodev.sh b/autodev.sh deleted file mode 100644 index 74d67f89..00000000 --- a/autodev.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -CHAR_DEVS+=("188:.*") -CHAR_DEVS+=("189:.*") - -for char_dev in ${CHAR_DEVS[@]}; do - [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" - CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" -done - -read -r -d '' HOOK_SCRIPT <<- EOF || true -for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do - dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; - mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); - for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do - mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); - cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; - done; - cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; -done; -EOF -HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} - -CTID=$1 -CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf -cat CTID.conf >$CTID_CONFIG_PATH - -cat <> $CTID_CONFIG_PATH -lxc.autodev: 1 -lxc.hook.autodev: bash -c '$HOOK_SCRIPT' -EOF - -# In the Proxmox web shell run (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/autodev.sh)" -s 106 -# Reboot the LXC to apply the changes From 29dd27044e9d194e8d380a9c710ba5648247a83e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:56:03 -0500 Subject: [PATCH 0584/6505] Delete debian11_setup.sh --- debian11_setup.sh | 61 ----------------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 debian11_setup.sh diff --git a/debian11_setup.sh b/debian11_setup.sh deleted file mode 100644 index 0bca50d1..00000000 --- a/debian11_setup.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 35fe272169ea25e2cd4f3be7865792bbe303f96c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:56:13 -0500 Subject: [PATCH 0585/6505] Delete esphome_setup.sh --- esphome_setup.sh | 84 ------------------------------------------------ 1 file changed, 84 deletions(-) delete mode 100644 esphome_setup.sh diff --git a/esphome_setup.sh b/esphome_setup.sh deleted file mode 100644 index 86fb104d..00000000 --- a/esphome_setup.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up Container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - # Installing pip3 - msg "Installing pip3..." - apt-get install python3-pip -y &>/dev/null - # Install ESPHome; - msg "Installing ESPHome..." - pip3 install esphome &>/dev/null - # Installing ESPHome Dashboard - msg "Installing ESPHome Dashboard..." - pip3 install tornado esptool &>/dev/null - -echo "Creating service file esphomeDashboard.service" -service_path="/etc/systemd/system/esphomeDashboard.service" - -echo "[Unit] -Description=ESPHome Dashboard -After=network.target -[Service] -ExecStart=/usr/local/bin/esphome /root/config/ dashboard -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path -systemctl enable esphomeDashboard.service &>/dev/null -systemctl start esphomeDashboard -# Customize container -msg "Customizing Container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 4d39fcdc4f00baeb7073fba53c146671189d2d8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:56:28 -0500 Subject: [PATCH 0586/6505] Delete ha_setup.sh --- ha_setup.sh | 98 ----------------------------------------------------- 1 file changed, 98 deletions(-) delete mode 100644 ha_setup.sh diff --git a/ha_setup.sh b/ha_setup.sh deleted file mode 100644 index 2464260d..00000000 --- a/ha_setup.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get -qqy install \ - curl \ - wget &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing Docker... \e[0m" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" -sh <(curl -sSL https://get.docker.com) &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Pulling Portainer Image...\e[0m" -docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Portainer... \e[0m" -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" -docker volume create hass_config >/dev/null -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 0eec677b6a4738151a6c342cfc6267e8e5cc74c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:56:40 -0500 Subject: [PATCH 0587/6505] Delete hacs.sh --- hacs.sh | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 hacs.sh diff --git a/hacs.sh b/hacs.sh deleted file mode 100644 index 5079c45e..00000000 --- a/hacs.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" - -while true; do - read -p "Start the HACS Install Script (y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -apt update &>/dev/null -apt install unzip &>/dev/null -cd /var/lib/docker/volumes/hass_config/_data -wget -O - https://get.hacs.xyz | bash - - -# To install HACS run the following from the container (LXC) console -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/hacs.sh)" -# Then add the integration in HA From 0cacff1729efa8b5dbf427822a3c93da8106b702 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:56:52 -0500 Subject: [PATCH 0588/6505] Delete mariadb_setup.sh --- mariadb_setup.sh | 66 ------------------------------------------------ 1 file changed, 66 deletions(-) delete mode 100644 mariadb_setup.sh diff --git a/mariadb_setup.sh b/mariadb_setup.sh deleted file mode 100644 index 5b4d5120..00000000 --- a/mariadb_setup.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -# Installing MariaDB -msg "Installing MariaDB..." -sudo apt-get update >/dev/null -sudo apt-get install -y mariadb-server &>/dev/null - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 3094013234e170401f007cc6d4ae378ad06a4b38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:57:05 -0500 Subject: [PATCH 0589/6505] Delete mqtt_setup.sh --- mqtt_setup.sh | 67 --------------------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 mqtt_setup.sh diff --git a/mqtt_setup.sh b/mqtt_setup.sh deleted file mode 100644 index f2276a8c..00000000 --- a/mqtt_setup.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -# Installing Mosquitto MQTT broker -msg "Installing Mosquitto MQTT broker.." -sudo apt-get update >/dev/null -sudo apt-get -y install mosquitto &>/dev/null -sudo apt-get -y install mosquitto-clients &>/dev/null - -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 573dfd185f0ad297f89b7796bac08a3de02dad76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:57:20 -0500 Subject: [PATCH 0590/6505] Delete node-red_setup.sh --- node-red_setup.sh | 72 ----------------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 node-red_setup.sh diff --git a/node-red_setup.sh b/node-red_setup.sh deleted file mode 100644 index 0f314261..00000000 --- a/node-red_setup.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -msg "Setting up container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -msg "Installing prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -msg "Installing Node-Red..." -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi - -#msg "Installing Node..." -#sudo apt -y install nodejs npm &>/dev/null - -#msg "Installing PM2..." -#npm install -g pm2 &>/dev/null - -#msg "Installing Node-RED..." -#npm install -g --unsafe-perm node-red &>/dev/null - -#msg "Setting up PM2..." -#/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null -#/usr/local/bin/pm2 save &>/dev/null -#/usr/local/bin/pm2 startup &>/dev/null - -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -msg "Cleanup..." -rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From d3c41887057f042ee092fda00457aae9006f702f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:57:35 -0500 Subject: [PATCH 0591/6505] Delete npm_setup.sh --- npm_setup.sh | 211 --------------------------------------------------- 1 file changed, 211 deletions(-) delete mode 100644 npm_setup.sh diff --git a/npm_setup.sh b/npm_setup.sh deleted file mode 100644 index 8adba8aa..00000000 --- a/npm_setup.sh +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - - # Install dependencies - echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" - echo "fs.file-max = 65535" > /etc/sysctl.conf - apt-get update &>/dev/null - apt-get -y install --no-install-recommends sudo curl wget gnupg openssl ca-certificates apache2-utils logrotate build-essential python3-dev git lsb-release &>/dev/null - - # Install Python - echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null - pip3 install --upgrade setuptools &>/dev/null - pip3 install --upgrade pip &>/dev/null - python3 -m venv /opt/certbot/ &>/dev/null - if [ "$(getconf LONG_BIT)" = "32" ]; then - python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null - fi - python3 -m pip install --no-cache-dir cffi certbot &>/dev/null -#fi - # Install openresty -echo -e "${CHECKMARK} \e[1;92m Installing Openresty... \e[0m" -wget -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null -codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null -echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null -apt-get -y update &>/dev/null -apt-get -y install --no-install-recommends openresty &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Yarn... \e[0m" -npm install --global yarn &>/dev/null - -# Download nginx-proxy-manager source -echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.15... \e[0m" -wget https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.15 -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-2.9.15 - -# Crate required symbolic links -echo -e "${CHECKMARK} \e[1;92m Setting up Enviroment... \e[0m" -ln -sf /usr/bin/python3 /usr/bin/python -ln -sf /usr/bin/certbot /opt/certbot/bin/certbot -ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx -ln -sf /usr/local/openresty/nginx/ /etc/nginx - -# Update NPM version in package.json files -sed -i "s+0.0.0+#v2.9.15+g" backend/package.json -sed -i "s+0.0.0+#v2.9.15+g" frontend/package.json - -# Fix nginx config files for use with openresty defaults -sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf -NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") -for NGINX_CONF in $NGINX_CONFS; do - sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" -done - -# Copy runtime files -mkdir -p /var/www/html /etc/nginx/logs -cp -r docker/rootfs/var/www/html/* /var/www/html/ -cp -r docker/rootfs/etc/nginx/* /etc/nginx/ -cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini -cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager -ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf -rm -f /etc/nginx/conf.d/dev.conf - -# Create required folders -mkdir -p /tmp/nginx/body \ -/run/nginx \ -/data/nginx \ -/data/custom_ssl \ -/data/logs \ -/data/access \ -/data/nginx/default_host \ -/data/nginx/default_www \ -/data/nginx/proxy_host \ -/data/nginx/redirection_host \ -/data/nginx/stream \ -/data/nginx/dead_host \ -/data/nginx/temp \ -/var/lib/nginx/cache/public \ -/var/lib/nginx/cache/private \ -/var/cache/nginx/proxy_temp - -chmod -R 777 /var/cache/nginx -chown root /tmp/nginx - -# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf - -# Generate dummy self-signed certificate. -if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null -fi - -# Copy app files -mkdir -p /app/global /app/frontend/images -cp -r backend/* /app -cp -r global/* /app/global - -# Build the frontend -echo -e "${CHECKMARK} \e[1;92m Building Frontend... \e[0m" -cd ./frontend -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -yarn build &>/dev/null -cp -r dist/* /app/frontend -cp -r app-images/* /app/frontend/images - -# Initialize backend -echo -e "${CHECKMARK} \e[1;92m Initializing Backend... \e[0m" -rm -rf /app/config/default.json &>/dev/null -if [ ! -f /app/config/production.json ]; then -cat << 'EOF' > /app/config/production.json -{ - "database": { - "engine": "knex-native", - "knex": { - "client": "sqlite3", - "connection": { - "filename": "/data/database.sqlite" - } - } - } -} -EOF -fi -cd /app -export NODE_ENV=development -yarn install --network-timeout=30000 - -# Create NPM service -echo -e "${CHECKMARK} \e[1;92m Creating NPM Service... \e[0m" -cat << 'EOF' > /lib/systemd/system/npm.service -[Unit] -Description=Nginx Proxy Manager -After=network.target -Wants=openresty.service - -[Service] -Type=simple -Environment=NODE_ENV=production -ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge -ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 -WorkingDirectory=/app -Restart=on-failure - -[Install] -WantedBy=multi-user.target -EOF - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Start services -echo -e "${CHECKMARK} \e[1;92m Starting Services... \e[0m" -systemctl enable npm &>/dev/null -systemctl start openresty -systemctl start npm - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /npm_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 518a47bd4d658168574d8292ed1a2bcef4fa1652 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:57:50 -0500 Subject: [PATCH 0592/6505] Delete pihole_setup.sh --- pihole_setup.sh | 59 ------------------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 pihole_setup.sh diff --git a/pihole_setup.sh b/pihole_setup.sh deleted file mode 100644 index b47a39ff..00000000 --- a/pihole_setup.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -msg "Setting up LXC OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -msg "Installing Pi-hole.." -curl -sSL https://install.pi-hole.net | bash - -msg "Customizing LXC..." -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -msg "Cleanup..." -rm -rf /pihole_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 5dab2d7a02a35a6ccc5a43048b85d97445907549 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:58:07 -0500 Subject: [PATCH 0593/6505] Delete plex_hardware_acceleration.sh --- plex_hardware_acceleration.sh | 65 ----------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 plex_hardware_acceleration.sh diff --git a/plex_hardware_acceleration.sh b/plex_hardware_acceleration.sh deleted file mode 100644 index 14bb9e18..00000000 --- a/plex_hardware_acceleration.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will add Hardware Acceleration Support to your Plex Media Server LXC. - Did you replace 106 with your LXC ID? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -CTID=$1 -CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -cat <> $CTID_CONFIG_PATH -### Intel iGPU: ### -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 -#lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file 0, 0 -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 0, 0 -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file 0, 0 - -### NVidia GPU: ### -#lxc.cgroup2.devices.allow: c 195:* rwm -#lxc.cgroup2.devices.allow: c 243:* rwm -#lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file -#lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file -#lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file -#lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file -#lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file -#lxc.cgroup2.devices.allow: c 226:0 rwm -#lxc.cgroup2.devices.allow: c 226:128 rwm -#lxc.cgroup2.devices.allow: c 29:0 rwm -#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 -EOF -echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" - -# Plex can transcode media files on the fly. By default they use the CPU. -# All Intel CPU’s since Sandy Bridge released in 2011 have hardware acceleration for H.264 built in. -# So if your CPU supports Quick Sync you can speed up transcoding and reduce load by running the -# following in the Proxmox web shell (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_hardware_acceleration.sh)" -s 106 -# Reboot the LXC to apply the changes - - From 0a0df2d05fd38bb3884e707e2929c859b3e7c1eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:58:25 -0500 Subject: [PATCH 0594/6505] Delete plex_setup.sh --- plex_setup.sh | 65 --------------------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 plex_setup.sh diff --git a/plex_setup.sh b/plex_setup.sh deleted file mode 100644 index d57045b7..00000000 --- a/plex_setup.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt-get -qqy install \ - curl \ - sudo \ - gnupg &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading Plex Media Server... \e[0m" -wget https://downloads.plex.tv/plex-media-server-new/1.25.2.5319-c43dc0277/debian/plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" -sudo dpkg -i plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null - -cat < /etc/apt/sources.list.d/plexmediaserver.list -deb https://downloads.plex.tv/repo/deb/ public main -EOF - -wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 6be568481be489200b52e2e190c155de09f8830d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:58:38 -0500 Subject: [PATCH 0595/6505] Delete podman_ha_setup.sh --- podman_ha_setup.sh | 77 ---------------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 podman_ha_setup.sh diff --git a/podman_ha_setup.sh b/podman_ha_setup.sh deleted file mode 100644 index 66a70e08..00000000 --- a/podman_ha_setup.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get -qqy install \ - curl \ - runc &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" -apt-get -y install podman &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" -podman volume create hass_config >/dev/null -podman run -d \ - --name homeassistant \ - --restart=always \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -podman generate systemd \ - --new --name homeassistant \ - > /etc/systemd/system/homeassistant.service -systemctl enable homeassistant &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From f2133bdbae9976b6be0b1a719de4a7065d23db65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:58:52 -0500 Subject: [PATCH 0596/6505] Delete podman_hacs.sh --- podman_hacs.sh | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 podman_hacs.sh diff --git a/podman_hacs.sh b/podman_hacs.sh deleted file mode 100644 index 4cebe949..00000000 --- a/podman_hacs.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" - -while true; do - read -p "Start the HACS Install Script (y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -apt update &>/dev/null -apt install unzip &>/dev/null -cd /var/lib/containers/storage/volumes/hass_config/_data -wget -O - https://get.hacs.xyz | bash - - -# To install HACS run the following from the container (LXC) console -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_hacs.sh)" -# Then add the integration in HA \ No newline at end of file From 91d23242994049f2b3988b2469d0288f156b45ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:59:31 -0500 Subject: [PATCH 0597/6505] Delete post_install.sh --- post_install.sh | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 post_install.sh diff --git a/post_install.sh b/post_install.sh deleted file mode 100644 index d85dced7..00000000 --- a/post_install.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -echo -e "\e[1;33m This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, -Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) -and attempt the No-Nag fix. PVE7 ONLY \e[0m" -while true; do - read -p "Start the PVE7 Post Install Script (y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list -cat < /etc/apt/sources.list -deb http://ftp.debian.org/debian bullseye main contrib -deb http://ftp.debian.org/debian bullseye-updates main contrib -deb http://security.debian.org/debian-security bullseye-security main contrib -deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription -# deb http://download.proxmox.com/debian/pve bullseye pvetest -EOF -echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script -apt --reinstall install proxmox-widget-toolkit &>/dev/null -echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" - -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/post_install.sh)" From ba71a9903b6d482e9d0067d7229ce6d0816b90ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 19:59:47 -0500 Subject: [PATCH 0598/6505] Delete update_ha.md --- update_ha.md | 78 ---------------------------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 update_ha.md diff --git a/update_ha.md b/update_ha.md deleted file mode 100644 index dfb4276b..00000000 --- a/update_ha.md +++ /dev/null @@ -1,78 +0,0 @@ -## Home Assistant Container Update ## - -In the homeassistant lxc console run `nano upha.sh` -it will open a empty file, copy and paste the Stable Branch (change TZ) -Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X" -To update HA, run `bash upha.sh` from the console - -Stable Branch -``` -### upha.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Stable Version... \e[0m" -docker pull homeassistant/home-assistant:stable -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" -docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" -docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" -docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:stable -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` - -Beta Branch -``` -### uphabeta.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Beta Version... \e[0m" -docker pull homeassistant/home-assistant:beta -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" -docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" -docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" -docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:beta -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` - -Development Branch -``` -### uphadev.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Dev Version... \e[0m" -docker pull homeassistant/home-assistant:dev -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" -docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" -docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" -docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:dev -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` - -Portainer-CE -``` -### upportainer.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Portainer-Ce Version... \e[0m" -docker pull portainer/portainer-ce:latest -echo -e "\e[1;33m Stopping Portainer... \e[0m" -docker stop portainer -echo -e "\e[1;33m Removing Portainer... \e[0m" -docker rm portainer -echo -e "\e[1;33m Starting Portainer... \e[0m" -docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` From cf7f84dbfe8e008d5d7767e2128949ea81a113cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 20:00:05 -0500 Subject: [PATCH 0599/6505] Delete zigbee2mqtt_setup.sh --- zigbee2mqtt_setup.sh | 90 -------------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 zigbee2mqtt_setup.sh diff --git a/zigbee2mqtt_setup.sh b/zigbee2mqtt_setup.sh deleted file mode 100644 index fabb3dd6..00000000 --- a/zigbee2mqtt_setup.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -# Prepare container OS -msg "Setting up Container OS..." -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -# Update container OS -msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -# Install prerequisites -msg "Installing Prerequisites..." -apt-get -qqy install \ - curl \ - sudo &>/dev/null - # Setup Node.js repository - msg "Setting up Node.js Repository..." - sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null - # Install Node.js; - msg "Installing Node.js..." - sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - # Clone Zigbee2MQTT repository - msg "Setting up Zigbee2MQTT Repository..." - sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null - # Install zigbee2mqtt - msg "Installing Zigbee2MQTT..." - cd /opt/zigbee2mqtt &>/dev/null - npm ci &>/dev/null - -echo "Creating service file zigbee2mqtt.service" -service_path="/etc/systemd/system/zigbee2mqtt.service" - -echo "[Unit] -Description=zigbee2mqtt -After=network.target -[Service] -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zigbee2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path - -# Customize container -msg "Customizing Container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." -rm -rf /zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 824774b97630eae68eec0b0fe7ddff9ef2d3559b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 20:00:19 -0500 Subject: [PATCH 0600/6505] Delete zwavejs2mqtt_setup.sh --- zwavejs2mqtt_setup.sh | 90 ------------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 zwavejs2mqtt_setup.sh diff --git a/zwavejs2mqtt_setup.sh b/zwavejs2mqtt_setup.sh deleted file mode 100644 index 02566c86..00000000 --- a/zwavejs2mqtt_setup.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt-get -qqy install \ - curl \ - sudo \ - unzip &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" - sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" - sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Installing yarn... \e[0m" - npm install --global yarn &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Build/Install Zwavejs2MQTT (5-6 min)... \e[0m" - sudo git clone https://github.com/zwave-js/zwavejs2mqtt /opt/zwavejs2mqtt &>/dev/null - cd /opt/zwavejs2mqtt &>/dev/null - yarn install &>/dev/null - yarn run build &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Creating Service file zwavejs2mqtt.service... \e[0m" -service_path="/etc/systemd/system/zwavejs2mqtt.service" - -echo "[Unit] -Description=zwavejs2mqtt -After=network.target -[Service] -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zwavejs2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path - -echo -e "${CHECKMARK} \e[1;92m Customizing container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /zwavejs2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* -systemctl start zwavejs2mqtt -systemctl enable zwavejs2mqtt &>/dev/null From d8f371ec5cf24619be857c64db363583e8e04412 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 20:01:07 -0500 Subject: [PATCH 0601/6505] Delete ubuntu_setup.sh --- ubuntu_setup.sh | 55 ------------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 ubuntu_setup.sh diff --git a/ubuntu_setup.sh b/ubuntu_setup.sh deleted file mode 100644 index 97870853..00000000 --- a/ubuntu_setup.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /ubuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 3ca553306a69cc7aaa02baa29d81338f95669b9e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 20:10:02 -0500 Subject: [PATCH 0602/6505] Create webmin.sh --- misc/webmin.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 misc/webmin.sh diff --git a/misc/webmin.sh b/misc/webmin.sh new file mode 100644 index 00000000..0eac337b --- /dev/null +++ b/misc/webmin.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +while true; do + read -p "This will Install Webmin, Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +echo -e "Loading Script..." +echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt update &>/dev/null +apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" +dpkg --install webmin_1.984_all.deb &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" +/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null +echo -e "Install Complete, Now Go To https:// IP:10000" + + +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From 5b3dcb6565e4daf92ebf89dfda303c88bb45ab0e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 20:12:10 -0500 Subject: [PATCH 0603/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 63f0857e..689b1e47 100644 --- a/README.md +++ b/README.md @@ -678,7 +678,7 @@ ________________________________________________________________________________ To Install [Webmin System Administration](https://www.webmin.com/index.html), run the following in a LXC console. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webmin.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" ``` If you prefer to manage all aspects of your Proxmox LXC from a graphical interface instead of the command line interface, Webmin might be right for you. From 16f7fab1af228e3e88522cce49ba3e7998118347 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 20:12:52 -0500 Subject: [PATCH 0604/6505] Delete webmin.sh --- webmin.sh | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 webmin.sh diff --git a/webmin.sh b/webmin.sh deleted file mode 100644 index 0972c846..00000000 --- a/webmin.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -while true; do - read -p "This will Install Webmin, Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -echo -e "Loading Script..." -echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt update &>/dev/null -apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" -dpkg --install webmin_1.984_all.deb &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" -/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -echo -e "Install Complete, Now Go To https:// IP:10000" - - -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/webmin.sh)" From cdfc9170edbfd712884203e9b755a0871bab2f2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:10:39 -0500 Subject: [PATCH 0605/6505] Create ubuntu_container.sh --- ct/ubuntu_container.sh | 158 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 ct/ubuntu_container.sh diff --git a/ct/ubuntu_container.sh b/ct/ubuntu_container.sh new file mode 100644 index 00000000..dfef6a5a --- /dev/null +++ b/ct/ubuntu_container.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Ubuntu 21.10 LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-21.10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=$OSTYPE +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" +pct start $CTID +pct push $CTID ubuntu_setup.sh /ubuntu_setup.sh -perms 755 +pct exec $CTID /ubuntu_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Ubuntu LXC Container to $CTID at IP Address ${IP}" From fa9bc8769561acdc6bcf6dde5eb225fc2852562f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:14:38 -0500 Subject: [PATCH 0606/6505] Create adguard_container.sh --- ct/adguard_container.sh | 157 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 ct/adguard_container.sh diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh new file mode 100644 index 00000000..547c776e --- /dev/null +++ b/ct/adguard_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New AdGuard Home LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "LXC ID is $CTID." + +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +msg "Creating LXC..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=adguard +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +msg "Starting LXC..." +pct start $CTID +pct push $CTID adguard_setup.sh /adguard_setup.sh -perms 755 +pct exec $CTID /adguard_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a AdGuard Home LXC to $CTID at IP Address ${IP}" From 01e350958b19d301532960d333aea1c41b1e3a40 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:15:26 -0500 Subject: [PATCH 0607/6505] Create debian11_container.sh --- ct/debian11_container.sh | 168 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 ct/debian11_container.sh diff --git a/ct/debian11_container.sh b/ct/debian11_container.sh new file mode 100644 index 00000000..be641145 --- /dev/null +++ b/ct/debian11_container.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Debian 11+ LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian11_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 11 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=debian11 +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID debian11_setup.sh /debian11_setup.sh -perms 755 +pct exec $CTID /debian11_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Debian 11 LXC Container to $CTID at IP Address ${IP}" From 9d30ac46cdde901c0a33c6f633cbf87d1a72642b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:16:21 -0500 Subject: [PATCH 0608/6505] Create esphome_container.sh --- ct/esphome_container.sh | 168 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 ct/esphome_container.sh diff --git a/ct/esphome_container.sh b/ct/esphome_container.sh new file mode 100644 index 00000000..3979e7c2 --- /dev/null +++ b/ct/esphome_container.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New ESPHome LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/esphome_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 11 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=4G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=esphome +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 +pct exec $CTID /esphome_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created ESPHome LXC Container to $CTID at IP Address ${IP}:6052" From f8def7963c357ad0920e9158da2e3badd98db08d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:18:04 -0500 Subject: [PATCH 0609/6505] Create ha_container.sh --- ct/ha_container.sh | 176 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 ct/ha_container.sh diff --git a/ct/ha_container.sh b/ct/ha_container.sh new file mode 100644 index 00000000..9616f0ba --- /dev/null +++ b/ct/ha_container.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ha_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi + ARCH=$(dpkg --print-architecture) +HOSTNAME=homeassistant +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +if [ "$STORAGE_TYPE" == "zfspool" ]; then + CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" +else + CT_FEATURES="nesting=1" +fi +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +info "Using fuse-overlayfs." +fi +pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 +pct exec $CTID /ha_setup.sh +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully Created Home Assistant Container LXC to $CTID." +msg " + +Home Assistant should be reachable by going to the following URL. + + http://${IP}:8123 +" From 9da29e0877982e1c8f6bbda2fdb1bfd93d3f5a0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:19:50 -0500 Subject: [PATCH 0610/6505] Create mariadb_container.sh --- ct/mariadb_container.sh | 170 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 ct/mariadb_container.sh diff --git a/ct/mariadb_container.sh b/ct/mariadb_container.sh new file mode 100644 index 00000000..e06fa9b9 --- /dev/null +++ b/ct/mariadb_container.sh @@ -0,0 +1,170 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Mariadb LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb_setup.sh + +# Detect modules and automatically load at boot +#load_module aufs +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 11 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=4G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=mariadb +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID mariadb_setup.sh /mariadb_setup.sh -perms 755 +pct exec $CTID /mariadb_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a MariaDB LXC Container to $CTID at IP Address ${IP}" From 0fc1807ac31ebfc2b98bad5289adcc75e54fdd9b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:20:41 -0500 Subject: [PATCH 0611/6505] Create mqtt_container.sh --- ct/mqtt_container.sh | 170 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 ct/mqtt_container.sh diff --git a/ct/mqtt_container.sh b/ct/mqtt_container.sh new file mode 100644 index 00000000..655f5f4f --- /dev/null +++ b/ct/mqtt_container.sh @@ -0,0 +1,170 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New MQTT LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt_setup.sh + +# Detect modules and automatically load at boot +#load_module aufs +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 11 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=mqtt +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID mqtt_setup.sh /mqtt_setup.sh -perms 755 +pct exec $CTID /mqtt_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a MQTT LXC Container to $CTID at IP Address ${IP}" From bec00d4954d81d5fffc650e95d016eae07629b9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:21:30 -0500 Subject: [PATCH 0612/6505] Create node-red_container.sh --- ct/node-red_container.sh | 169 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 ct/node-red_container.sh diff --git a/ct/node-red_container.sh b/ct/node-red_container.sh new file mode 100644 index 00000000..d287e88f --- /dev/null +++ b/ct/node-red_container.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Node-Red LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 11 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=4G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=nodered +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 +pct exec $CTID /node-red_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Node-RED LXC Container to $CTID at IP Address ${IP}" From 9c1921e4e1afd99474e819211f4e8eb98791b728 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:22:25 -0500 Subject: [PATCH 0613/6505] Create npm_container.sh --- ct/npm_container.sh | 159 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 ct/npm_container.sh diff --git a/ct/npm_container.sh b/ct/npm_container.sh new file mode 100644 index 00000000..4e6c7c64 --- /dev/null +++ b/ct/npm_container.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +#!/usr/bin/env bash +while true; do + read -p "This will create a New Nginx Proxy Manager LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/npm_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "LXC ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" +DISK_SIZE=3G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=npm +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC...... \e[0m" +pct start $CTID +pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 +pct exec $CTID /npm_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" From f0c3f70b5c53e5f8c11b2929f7da6b43eb55a688 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:23:13 -0500 Subject: [PATCH 0614/6505] Create pihole_container.sh --- ct/pihole_container.sh | 157 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 ct/pihole_container.sh diff --git a/ct/pihole_container.sh b/ct/pihole_container.sh new file mode 100644 index 00000000..7eb7c05a --- /dev/null +++ b/ct/pihole_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Pi-hole LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/pihole_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "LXC ID is $CTID." + +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +msg "Creating LXC..." +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=pi-hole +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +msg "Starting LXC..." +pct start $CTID +pct push $CTID pihole_setup.sh /pihole_setup.sh -perms 755 +pct exec $CTID /pihole_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Pi-hole LXC to $CTID at IP Address ${IP}" From eca9be717a853e63f6229932c7c8c82c462c3f36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:24:11 -0500 Subject: [PATCH 0615/6505] Create plex_container.sh --- ct/plex_container.sh | 157 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 ct/plex_container.sh diff --git a/ct/plex_container.sh b/ct/plex_container.sh new file mode 100644 index 00000000..c3c8b492 --- /dev/null +++ b/ct/plex_container.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Plex Media Server LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for Storage Location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=plex +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 +pct exec $CTID /plex_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Plex Media Server LXC Container to $CTID at IP Address ${IP}:32400/web" From 82af3c2f590aa0692d2321beeb5efadb151c1a50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:25:31 -0500 Subject: [PATCH 0616/6505] Create podman_ha_container.sh --- ct/podman_ha_container.sh | 178 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 ct/podman_ha_container.sh diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh new file mode 100644 index 00000000..c4705455 --- /dev/null +++ b/ct/podman_ha_container.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Podman Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman_ha_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi + ARCH=$(dpkg --print-architecture) +HOSTNAME=homeassistant +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +if [ "$STORAGE_TYPE" == "zfspool" ]; then + CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" +else + CT_FEATURES="nesting=1" +fi +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +info "Using fuse-overlayfs." +fi +pct push $CTID podman_ha_setup.sh /podman_ha_setup.sh -perms 755 +pct exec $CTID /podman_ha_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created Podman Home Assistant Container LXC to $CTID." +msg " + +Home Assistant should be reachable by going to the following URL. + + + http://${IP}:8123 +" From cc66fff974e4c73e3c13b1aeceddb19856a1dae1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:26:41 -0500 Subject: [PATCH 0617/6505] Create zigbee2mqtt_container.sh --- ct/zigbee2mqtt_container.sh | 180 ++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 ct/zigbee2mqtt_container.sh diff --git a/ct/zigbee2mqtt_container.sh b/ct/zigbee2mqtt_container.sh new file mode 100644 index 00000000..1c19adfb --- /dev/null +++ b/ct/zigbee2mqtt_container.sh @@ -0,0 +1,180 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Zigbee2MQTT LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Setup script environment +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +# Download setup script +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt_setup.sh + +# Detect modules and automatically load at boot +load_module overlay + +# Select storage location +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +# Get the next guest VM/LXC ID +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +# Download latest Debian 11 LXC template +msg "Updating LXC template list..." +pveam update >/dev/null +msg "Downloading LXC template..." +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +# Create variables for container disk +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +# Create LXC +msg "Creating LXC container..." +DISK_SIZE=4G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=zigbee2mqtt +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +# Modify LXC permissions to support Zigbee Sticks +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +# Set container timezone to match host +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +# Setup container +msg "Starting LXC container..." +pct start $CTID +pct push $CTID zigbee2mqtt_setup.sh /zigbee2mqtt_setup.sh -perms 755 +pct exec $CTID /zigbee2mqtt_setup.sh + +# Get network details and show completion message +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" +echo +echo -e "\e[1;31m Update of configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" +echo +echo -e "Z2M can be started after completing the configuration buy running \e[1;33m sudo systemctl start zigbee2mqtt \e[0m" +echo From 73c22de44ecb80945d25e9bcf07d0e3b364a3ff7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:27:40 -0500 Subject: [PATCH 0618/6505] Create zwavejs2mqtt_container.sh --- ct/zwavejs2mqtt_container.sh | 164 +++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 ct/zwavejs2mqtt_container.sh diff --git a/ct/zwavejs2mqtt_container.sh b/ct/zwavejs2mqtt_container.sh new file mode 100644 index 00000000..3d42e6a5 --- /dev/null +++ b/ct/zwavejs2mqtt_container.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Zwavejs2MQTT LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zwavejs2mqtt_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for Storage Location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=4G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=zwavejs2mqtt +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID zwavejs2mqtt_setup.sh /zwavejs2mqtt_setup.sh -perms 755 +pct exec $CTID /zwavejs2mqtt_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}:8091" From 1037cb7e941e6942916333c0b8b632eb05aea1bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:29:46 -0500 Subject: [PATCH 0619/6505] Create haos_vm.sh --- vm/haos_vm.sh | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 vm/haos_vm.sh diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh new file mode 100644 index 00000000..a4aa4f54 --- /dev/null +++ b/vm/haos_vm.sh @@ -0,0 +1,177 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Disk image' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." +VMID=$(pvesh get /cluster/nextid) +info "Container ID is $VMID." +echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" +RELEASE_TYPE=qcow2 +URL=$(cat< /dev/null; then + echo -e "${CHECKMARK} \e[1;92m Installing Unzip... \e[0m" + apt-get update >/dev/null + apt-get -qqy install unzip &>/dev/null + fi +fi +echo -e "${CHECKMARK} \e[1;92m Extracting disk image... \e[0m" +case $FILE in + *"gz") gunzip -f $FILE;; + *"zip") unzip -o $FILE;; + *"xz") xz -d $FILE;; + *) die "Unable to handle file extension '${FILE##*.}'.";; +esac +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + IMPORT_OPT="-format qcow2" +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +echo -e "${CHECKMARK} \e[1;92m Creating VM... \e[0m" +VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) +qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},size=128K \ + -scsi0 ${DISK1_REF},size=32G > /dev/null +qm set $VMID \ + -boot order=scsi0 > /dev/null +set +o errtrace +( + echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" + trap ' + warn "Unable to configure serial port. VM is still functional." + if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VMID --delete serial0 >/dev/null + fi + exit + ' ERR + if [ "$(command -v kpartx)" = "" ]; then + echo -e "${CHECKMARK} \e[1;92m Installing kpartx... \e[0m" + apt-get update >/dev/null + apt-get -qqy install kpartx &>/dev/null + fi + DISK1_PATH="$(pvesm path $DISK1_REF)" + DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" + DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" + TEMP_MOUNT="${TEMP_DIR}/mnt" + trap ' + findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT + command -v kpartx >/dev/null && kpartx -d $DISK1_PATH + ' EXIT + kpartx -a $DISK1_PATH + mkdir $TEMP_MOUNT + mount $DISK1_PART1_PATH $TEMP_MOUNT + sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt + qm set $VMID -serial0 socket >/dev/null +) + +info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." From cb93cca820a5bd026e95ed333ceda2e2ed7afb84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:36:09 -0500 Subject: [PATCH 0620/6505] Update README.md --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 689b1e47..0c614063 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ ________________________________________________________________________________ To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/haos_vm.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/vm/haos_vm.sh)" ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

@@ -85,7 +85,7 @@ To create a new Proxmox Podman Home Assistant Container, run the following from ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/podman_ha_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/podman_ha_container.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -138,7 +138,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ha_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ha_container.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -196,7 +196,7 @@ ________________________________________________________________________________ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/esphome_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -220,7 +220,7 @@ ________________________________________________________________________________ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following from Proxmox web shell. ``` - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/npm_container.sh)" + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/npm_container.sh)" ```

⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

@@ -266,7 +266,7 @@ Add the following to your `configuration.yaml` in Home Assistant. To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -313,7 +313,7 @@ ________________________________________________________________________________ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/node-red_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -348,7 +348,7 @@ ________________________________________________________________________________ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/mariadb_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -453,7 +453,7 @@ ________________________________________________________________________________ To create a new Proxmox [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zigbee2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -532,7 +532,7 @@ ________________________________________________________________________________ To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/zwavejs2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zwavejs2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -563,7 +563,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/debian11_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian11_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -584,7 +584,7 @@ ________________________________________________________________________________ To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ubuntu_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -605,7 +605,7 @@ ________________________________________________________________________________ To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/plex_container.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -629,7 +629,7 @@ ________________________________________________________________________________ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/pihole_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/pihole_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -657,7 +657,7 @@ ________________________________________________________________________________ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/adguard_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

From 6af023634c97218e3b25c7482acc8c4c97e287cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:37:09 -0500 Subject: [PATCH 0621/6505] Delete zwavejs2mqtt_container.sh --- zwavejs2mqtt_container.sh | 164 -------------------------------------- 1 file changed, 164 deletions(-) delete mode 100644 zwavejs2mqtt_container.sh diff --git a/zwavejs2mqtt_container.sh b/zwavejs2mqtt_container.sh deleted file mode 100644 index 3d42e6a5..00000000 --- a/zwavejs2mqtt_container.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Zwavejs2MQTT LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zwavejs2mqtt_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for Storage Location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=zwavejs2mqtt -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID zwavejs2mqtt_setup.sh /zwavejs2mqtt_setup.sh -perms 755 -pct exec $CTID /zwavejs2mqtt_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}:8091" From 433c256fa4570a39206a0ff0327cb4135c2a9247 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:37:20 -0500 Subject: [PATCH 0622/6505] Delete adguard_container.sh --- adguard_container.sh | 157 ------------------------------------------- 1 file changed, 157 deletions(-) delete mode 100644 adguard_container.sh diff --git a/adguard_container.sh b/adguard_container.sh deleted file mode 100644 index 547c776e..00000000 --- a/adguard_container.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New AdGuard Home LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "LXC ID is $CTID." - -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -msg "Creating LXC..." -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=adguard -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -msg "Starting LXC..." -pct start $CTID -pct push $CTID adguard_setup.sh /adguard_setup.sh -perms 755 -pct exec $CTID /adguard_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a AdGuard Home LXC to $CTID at IP Address ${IP}" From 616aa1159e1daa824ecdb71a996651fbf1fedc63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:37:30 -0500 Subject: [PATCH 0623/6505] Delete debian11_container.sh --- debian11_container.sh | 168 ------------------------------------------ 1 file changed, 168 deletions(-) delete mode 100644 debian11_container.sh diff --git a/debian11_container.sh b/debian11_container.sh deleted file mode 100644 index be641145..00000000 --- a/debian11_container.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Debian 11+ LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian11_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=debian11 -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID debian11_setup.sh /debian11_setup.sh -perms 755 -pct exec $CTID /debian11_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Debian 11 LXC Container to $CTID at IP Address ${IP}" From 23c143b71f57e611bdaa4ed9a03c015591213d26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:37:39 -0500 Subject: [PATCH 0624/6505] Delete esphome_container.sh --- esphome_container.sh | 168 ------------------------------------------- 1 file changed, 168 deletions(-) delete mode 100644 esphome_container.sh diff --git a/esphome_container.sh b/esphome_container.sh deleted file mode 100644 index 3979e7c2..00000000 --- a/esphome_container.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New ESPHome LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/esphome_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=esphome -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 -pct exec $CTID /esphome_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created ESPHome LXC Container to $CTID at IP Address ${IP}:6052" From 2e670a9070b1a070636f7013a7dbe27468f10443 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:37:48 -0500 Subject: [PATCH 0625/6505] Delete ha_container.sh --- ha_container.sh | 176 ------------------------------------------------ 1 file changed, 176 deletions(-) delete mode 100644 ha_container.sh diff --git a/ha_container.sh b/ha_container.sh deleted file mode 100644 index 9616f0ba..00000000 --- a/ha_container.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ha_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi - ARCH=$(dpkg --print-architecture) -HOSTNAME=homeassistant -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -if [ "$STORAGE_TYPE" == "zfspool" ]; then - CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" -else - CT_FEATURES="nesting=1" -fi -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -info "Using fuse-overlayfs." -fi -pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 -pct exec $CTID /ha_setup.sh -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Home Assistant Container LXC to $CTID." -msg " - -Home Assistant should be reachable by going to the following URL. - - http://${IP}:8123 -" From 36cf9f9e543eeaa40f12a515c9ff9f2b96c6ec6b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:38:00 -0500 Subject: [PATCH 0626/6505] Delete haos_vm.sh --- haos_vm.sh | 177 ----------------------------------------------------- 1 file changed, 177 deletions(-) delete mode 100644 haos_vm.sh diff --git a/haos_vm.sh b/haos_vm.sh deleted file mode 100644 index a4aa4f54..00000000 --- a/haos_vm.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content images | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Disk image' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." -VMID=$(pvesh get /cluster/nextid) -info "Container ID is $VMID." -echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" -RELEASE_TYPE=qcow2 -URL=$(cat< /dev/null; then - echo -e "${CHECKMARK} \e[1;92m Installing Unzip... \e[0m" - apt-get update >/dev/null - apt-get -qqy install unzip &>/dev/null - fi -fi -echo -e "${CHECKMARK} \e[1;92m Extracting disk image... \e[0m" -case $FILE in - *"gz") gunzip -f $FILE;; - *"zip") unzip -o $FILE;; - *"xz") xz -d $FILE;; - *) die "Unable to handle file extension '${FILE##*.}'.";; -esac -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - IMPORT_OPT="-format qcow2" -esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done -echo -e "${CHECKMARK} \e[1;92m Creating VM... \e[0m" -VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) -qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},size=32G > /dev/null -qm set $VMID \ - -boot order=scsi0 > /dev/null -set +o errtrace -( - echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" - trap ' - warn "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VMID --delete serial0 >/dev/null - fi - exit - ' ERR - if [ "$(command -v kpartx)" = "" ]; then - echo -e "${CHECKMARK} \e[1;92m Installing kpartx... \e[0m" - apt-get update >/dev/null - apt-get -qqy install kpartx &>/dev/null - fi - DISK1_PATH="$(pvesm path $DISK1_REF)" - DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" - DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" - TEMP_MOUNT="${TEMP_DIR}/mnt" - trap ' - findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT - command -v kpartx >/dev/null && kpartx -d $DISK1_PATH - ' EXIT - kpartx -a $DISK1_PATH - mkdir $TEMP_MOUNT - mount $DISK1_PART1_PATH $TEMP_MOUNT - sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt - qm set $VMID -serial0 socket >/dev/null -) - -info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." From 8143ebca821fd4bd3441aeaec0b4a68ee06172a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:38:09 -0500 Subject: [PATCH 0627/6505] Delete mariadb_container.sh --- mariadb_container.sh | 170 ------------------------------------------- 1 file changed, 170 deletions(-) delete mode 100644 mariadb_container.sh diff --git a/mariadb_container.sh b/mariadb_container.sh deleted file mode 100644 index 9ab1ea7c..00000000 --- a/mariadb_container.sh +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Mariadb LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb_setup.sh - -# Detect modules and automatically load at boot -#load_module aufs -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=mariadb -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID mariadb_setup.sh /mariadb_setup.sh -perms 755 -pct exec $CTID /mariadb_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a MariaDB 10.5 LXC Container to $CTID at IP Address ${IP}" From d9ef4ac11b2b5e70a27a25ecd8f42a643ded6119 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:38:19 -0500 Subject: [PATCH 0628/6505] Delete mqtt_container.sh --- mqtt_container.sh | 170 ---------------------------------------------- 1 file changed, 170 deletions(-) delete mode 100644 mqtt_container.sh diff --git a/mqtt_container.sh b/mqtt_container.sh deleted file mode 100644 index 655f5f4f..00000000 --- a/mqtt_container.sh +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New MQTT LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt_setup.sh - -# Detect modules and automatically load at boot -#load_module aufs -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=mqtt -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID mqtt_setup.sh /mqtt_setup.sh -perms 755 -pct exec $CTID /mqtt_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a MQTT LXC Container to $CTID at IP Address ${IP}" From 568912c05b30d506656a1059b9a566c4a8d5dfa0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:38:28 -0500 Subject: [PATCH 0629/6505] Delete node-red_container.sh --- node-red_container.sh | 169 ------------------------------------------ 1 file changed, 169 deletions(-) delete mode 100644 node-red_container.sh diff --git a/node-red_container.sh b/node-red_container.sh deleted file mode 100644 index d287e88f..00000000 --- a/node-red_container.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Node-Red LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=nodered -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 -pct exec $CTID /node-red_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Node-RED LXC Container to $CTID at IP Address ${IP}" From 897667db87c691f414f94af1c9d3ca14e8c64e91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:38:39 -0500 Subject: [PATCH 0630/6505] Delete npm_container.sh --- npm_container.sh | 159 ----------------------------------------------- 1 file changed, 159 deletions(-) delete mode 100644 npm_container.sh diff --git a/npm_container.sh b/npm_container.sh deleted file mode 100644 index 4e6c7c64..00000000 --- a/npm_container.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env bash - -#!/usr/bin/env bash -while true; do - read -p "This will create a New Nginx Proxy Manager LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/npm_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "LXC ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" -DISK_SIZE=3G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=npm -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC...... \e[0m" -pct start $CTID -pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 -pct exec $CTID /npm_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" From 2bfc845f92425aaf6eff513bbd7ade6a9ce4b1e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:38:49 -0500 Subject: [PATCH 0631/6505] Delete pihole_container.sh --- pihole_container.sh | 157 -------------------------------------------- 1 file changed, 157 deletions(-) delete mode 100644 pihole_container.sh diff --git a/pihole_container.sh b/pihole_container.sh deleted file mode 100644 index 7eb7c05a..00000000 --- a/pihole_container.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Pi-hole LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/pihole_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "LXC ID is $CTID." - -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -msg "Creating LXC..." -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=pi-hole -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -msg "Starting LXC..." -pct start $CTID -pct push $CTID pihole_setup.sh /pihole_setup.sh -perms 755 -pct exec $CTID /pihole_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Pi-hole LXC to $CTID at IP Address ${IP}" From 97efd60a485fde8a033c03e81fc2626e429f4920 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:38:59 -0500 Subject: [PATCH 0632/6505] Delete plex_container.sh --- plex_container.sh | 157 ---------------------------------------------- 1 file changed, 157 deletions(-) delete mode 100644 plex_container.sh diff --git a/plex_container.sh b/plex_container.sh deleted file mode 100644 index c3c8b492..00000000 --- a/plex_container.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Plex Media Server LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for Storage Location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=plex -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 -pct exec $CTID /plex_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Plex Media Server LXC Container to $CTID at IP Address ${IP}:32400/web" From 09157f63904fc2bcee840ffa449f2deedccd4a2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:39:08 -0500 Subject: [PATCH 0633/6505] Delete podman_ha_container.sh --- podman_ha_container.sh | 178 ----------------------------------------- 1 file changed, 178 deletions(-) delete mode 100644 podman_ha_container.sh diff --git a/podman_ha_container.sh b/podman_ha_container.sh deleted file mode 100644 index d78d9d99..00000000 --- a/podman_ha_container.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Podman Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman_ha_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi - ARCH=$(dpkg --print-architecture) -HOSTNAME=homeassistant -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -if [ "$STORAGE_TYPE" == "zfspool" ]; then - CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" -else - CT_FEATURES="nesting=1" -fi -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -info "Using fuse-overlayfs." -fi -pct push $CTID podman_ha_setup.sh /podman_ha_setup.sh -perms 755 -pct exec $CTID /podman_ha_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Home Assistant Container LXC to $CTID." -msg " - -Home Assistant should be reachable by going to the following URL. - - - http://${IP}:8123 -" From ed68e157077dc3a3e958b608bdd7a30942a72b90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:39:21 -0500 Subject: [PATCH 0634/6505] Delete ubuntu_container.sh --- ubuntu_container.sh | 158 -------------------------------------------- 1 file changed, 158 deletions(-) delete mode 100644 ubuntu_container.sh diff --git a/ubuntu_container.sh b/ubuntu_container.sh deleted file mode 100644 index dfef6a5a..00000000 --- a/ubuntu_container.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Ubuntu 21.10 LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=$OSTYPE -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" -pct start $CTID -pct push $CTID ubuntu_setup.sh /ubuntu_setup.sh -perms 755 -pct exec $CTID /ubuntu_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Ubuntu LXC Container to $CTID at IP Address ${IP}" From 2c39704bb8b2dae8ff02763af61fa490bb6efdcd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jan 2022 22:39:30 -0500 Subject: [PATCH 0635/6505] Delete zigbee2mqtt_container.sh --- zigbee2mqtt_container.sh | 180 --------------------------------------- 1 file changed, 180 deletions(-) delete mode 100644 zigbee2mqtt_container.sh diff --git a/zigbee2mqtt_container.sh b/zigbee2mqtt_container.sh deleted file mode 100644 index 1c19adfb..00000000 --- a/zigbee2mqtt_container.sh +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Zigbee2MQTT LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -# Download setup script -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt_setup.sh - -# Detect modules and automatically load at boot -load_module overlay - -# Select storage location -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -# Get the next guest VM/LXC ID -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." -pveam update >/dev/null -msg "Downloading LXC template..." -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -# Create variables for container disk -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -# Create LXC -msg "Creating LXC container..." -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=zigbee2mqtt -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Modify LXC permissions to support Zigbee Sticks -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -# Set container timezone to match host -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -# Setup container -msg "Starting LXC container..." -pct start $CTID -pct push $CTID zigbee2mqtt_setup.sh /zigbee2mqtt_setup.sh -perms 755 -pct exec $CTID /zigbee2mqtt_setup.sh - -# Get network details and show completion message -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" -echo -echo -e "\e[1;31m Update of configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" -echo -echo -e "Z2M can be started after completing the configuration buy running \e[1;33m sudo systemctl start zigbee2mqtt \e[0m" -echo From 45e1c7dc871676a9191a63ae23b42855db6118d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 15:50:42 -0500 Subject: [PATCH 0636/6505] Add files via upload --- misc/update.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 misc/update.sh diff --git a/misc/update.sh b/misc/update.sh new file mode 100644 index 00000000..40b1d4e3 --- /dev/null +++ b/misc/update.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +echo -e "\e[1;33m Pulling New Stable Version... \e[0m" +docker pull homeassistant/home-assistant:stable +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro\ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m" \ No newline at end of file From f14b5aa5a7274eb8266c44a6fa02cfaa7996ac8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 16:06:32 -0500 Subject: [PATCH 0637/6505] Update update.sh --- misc/update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/update.sh b/misc/update.sh index 40b1d4e3..232ba95e 100644 --- a/misc/update.sh +++ b/misc/update.sh @@ -17,7 +17,7 @@ docker run -d \ -v /etc/localtime:/etc/localtime:ro \ -v /etc/timezone:/etc/timezone:ro\ --net=host \ - homeassistant/home-assistant:stable &>/dev/null + homeassistant/home-assistant:stable echo -e "\e[1;33m Removing Old Image... \e[0m" docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" \ No newline at end of file +echo -e "\e[1;33m Finished Update! \e[0m" From eff3af5bdca55b23abf59f93ed7b6b6261d5ca2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 16:23:24 -0500 Subject: [PATCH 0638/6505] Update ha_container.sh --- ct/ha_container.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/ha_container.sh b/ct/ha_container.sh index 9616f0ba..8470b815 100644 --- a/ct/ha_container.sh +++ b/ct/ha_container.sh @@ -73,6 +73,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/misc/update.sh load_module overlay @@ -165,6 +166,7 @@ pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 info "Using fuse-overlayfs." fi pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 +pct push $CTID update.sh /root/update.sh -perms 755 pct exec $CTID /ha_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully Created Home Assistant Container LXC to $CTID." From 931bedda5d7685a6ce888ef012a773e33ff3fa93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 16:24:51 -0500 Subject: [PATCH 0639/6505] Update ha_setup.sh --- setup/ha_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 2464260d..be213ee0 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -77,6 +77,7 @@ docker run -d \ -v /dev:/dev \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro\ --net=host \ homeassistant/home-assistant:stable &>/dev/null From 10158e1ed51a02e58fc27fd9e3e0c8ff47106370 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 16:30:39 -0500 Subject: [PATCH 0640/6505] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 0c614063..5b18c8f5 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,14 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + +⚙️ **To update Home Assistant:** + +Run the from the LXC console +``` +./update.sh +``` + ____________________________________________________________________________________________
From 825118fb019331377f029c1f06758e122bd4f92a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 16:32:57 -0500 Subject: [PATCH 0641/6505] Delete update_ha.md --- misc/update_ha.md | 78 ----------------------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 misc/update_ha.md diff --git a/misc/update_ha.md b/misc/update_ha.md deleted file mode 100644 index dfb4276b..00000000 --- a/misc/update_ha.md +++ /dev/null @@ -1,78 +0,0 @@ -## Home Assistant Container Update ## - -In the homeassistant lxc console run `nano upha.sh` -it will open a empty file, copy and paste the Stable Branch (change TZ) -Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X" -To update HA, run `bash upha.sh` from the console - -Stable Branch -``` -### upha.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Stable Version... \e[0m" -docker pull homeassistant/home-assistant:stable -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" -docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" -docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" -docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:stable -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` - -Beta Branch -``` -### uphabeta.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Beta Version... \e[0m" -docker pull homeassistant/home-assistant:beta -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" -docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" -docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" -docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:beta -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` - -Development Branch -``` -### uphadev.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Dev Version... \e[0m" -docker pull homeassistant/home-assistant:dev -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" -docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" -docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" -docker run -d --name homeassistant --restart unless-stopped -v hass_config:/config -e TZ=US/Eastern --net=host homeassistant/home-assistant:dev -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` - -Portainer-CE -``` -### upportainer.sh ### -#!/bin/bash - -echo -e "\e[1;33m Pulling New Portainer-Ce Version... \e[0m" -docker pull portainer/portainer-ce:latest -echo -e "\e[1;33m Stopping Portainer... \e[0m" -docker stop portainer -echo -e "\e[1;33m Removing Portainer... \e[0m" -docker rm portainer -echo -e "\e[1;33m Starting Portainer... \e[0m" -docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" -``` From 3730cd92c075c15dc75e399149cc434985f5f5bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 16:45:58 -0500 Subject: [PATCH 0642/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b18c8f5..4d66f0aa 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ``` /var/lib/docker/volumes/hass_config/_data ``` -⚙️ **To edit the HA configuration.yaml** +⚙️ **To edit the HA configuration.yaml** (Recommend Installing Webmin System Administration) Run from the LXC console ``` From ae9615a9782012991878b676bc01095a3d4bdced Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 18:13:33 -0500 Subject: [PATCH 0643/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d66f0aa..4a070036 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ``` /var/lib/docker/volumes/hass_config/_data ``` -⚙️ **To edit the HA configuration.yaml** (Recommend Installing Webmin System Administration) +⚙️ **To edit the HA configuration.yaml** (Recommend Using Webmin System Administration) Run from the LXC console ``` From 0218bdea0e7cb6d4a3dcb8658c318845c2e048a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 21:44:41 -0500 Subject: [PATCH 0644/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4a070036..8f2a47cd 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ``` /var/lib/docker/volumes/hass_config/_data ``` -⚙️ **To edit the HA configuration.yaml** (Recommend Using Webmin System Administration) +⚙️ **To Edit the HA configuration.yaml** (Recommend Using Webmin System Administration) Run from the LXC console ``` @@ -162,7 +162,7 @@ nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **To allow device passthrough:** +⚙️ **To Allow Device Passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID**) ``` @@ -172,7 +172,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc Reboot the LXC to apply the changes -⚙️ **To install HACS:** +⚙️ **To Install HACS:** Run the from the LXC console ``` @@ -181,9 +181,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **To update Home Assistant:** +⚙️ **To Update Home Assistant:** -Run the from the LXC console +Run from the LXC console ``` ./update.sh ``` From a1cbcc68fb671359fe425879e29243f56d78929d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 19 Jan 2022 21:45:53 -0500 Subject: [PATCH 0645/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f2a47cd..ec7b211e 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ Reboot the LXC to apply the changes ⚙️ **To Install HACS:** -Run the from the LXC console +Run from the LXC console ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs.sh)" ``` From c468d8a6819c9a40057bce66e7456ce2470372d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Jan 2022 07:41:11 -0500 Subject: [PATCH 0646/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ec7b211e..fa7a5990 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
-🔸Proxmox VE 7 Post Install +Proxmox VE 7 Post Install

Proxmox Server Solutions

@@ -49,7 +49,7 @@ ________________________________________________________________________________
-🔸Home Assistant OS VM +Home Assistant OS VM

@home-assistant

From eee2f8bae1ddce10a69f808c5f795cbb7284d6ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 03:51:48 -0500 Subject: [PATCH 0647/6505] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fa7a5990..b0a1d209 100644 --- a/README.md +++ b/README.md @@ -705,6 +705,10 @@ Benefits include automatic daily security updates, backup and restore, file mana **password** `root` -____________________________________________________________________________________________ +⚙️ **To Uninstall Webmin** + ```yaml +bash /etc/webmin/uninstall.sh +``` +___________________________________________________________________________________________
From eb5872b0f91c8b786bd3b5071f22865f5b134458 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 04:01:06 -0500 Subject: [PATCH 0648/6505] Update README.md --- README.md | 114 +++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index b0a1d209..2b32078a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ and attempt the *No-Nag* fix. Run the following in the Proxmox Web Shell. ⚠️ **PVE7 ONLY** -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/post_install.sh)" ``` @@ -37,7 +37,7 @@ A dark theme for the Proxmox Web UI by [Weilbyte](https://github.com/Weilbyte/PV Run the following in the Proxmox Web Shell. -``` +```yaml bash <(curl -s https://raw.githubusercontent.com/Weilbyte/PVEDiscordDark/master/PVEDiscordDark.sh ) install ``` @@ -57,7 +57,7 @@ ________________________________________________________________________________ To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/vm/haos_vm.sh)" ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

@@ -84,7 +84,7 @@ To create a new Proxmox Podman Home Assistant Container, run the following from ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/podman_ha_container.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -94,13 +94,13 @@ After the script completes, If you're dissatisfied with the default settings, cl **Home Assistant Interface - IP:8123** ⚙️ **Path to HA /config** -``` +```yaml /var/lib/containers/storage/volumes/hass_config/_data ``` ⚙️ **To edit the HA configuration.yaml** Run from the LXC console -``` +```yaml nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” @@ -108,7 +108,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” ⚙️ **To allow device passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID**) -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` @@ -117,7 +117,7 @@ Reboot the LXC to apply the changes ⚙️ **To install HACS:** Run the from the LXC console -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman_hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -137,7 +137,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ha_container.sh)" ``` @@ -150,13 +150,13 @@ After the script completes, If you're dissatisfied with the default settings, cl **Portainer Interface - IP:9000** ⚙️ **Path to HA /config** -``` +```yaml /var/lib/docker/volumes/hass_config/_data ``` ⚙️ **To Edit the HA configuration.yaml** (Recommend Using Webmin System Administration) Run from the LXC console -``` +```yaml nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” @@ -165,7 +165,7 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” ⚙️ **To Allow Device Passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID**) -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` @@ -175,7 +175,7 @@ Reboot the LXC to apply the changes ⚙️ **To Install HACS:** Run from the LXC console -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -184,7 +184,7 @@ After install, reboot Home Assistant and **clear browser cache** then Add HACS i ⚙️ **To Update Home Assistant:** Run from the LXC console -``` +```yaml ./update.sh ``` @@ -203,7 +203,7 @@ ________________________________________________________________________________ To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome_container.sh)" ``` @@ -227,7 +227,7 @@ ________________________________________________________________________________ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following from Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/npm_container.sh)" ```

⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

@@ -237,7 +237,7 @@ ________________________________________________________________________________ Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. Add the following to your `configuration.yaml` in Home Assistant. -``` +```yaml http: use_x_forwarded_for: true trusted_proxies: @@ -249,11 +249,11 @@ Add the following to your `configuration.yaml` in Home Assistant. ⚙️ **Initial Login** **username** - ``` + ```yaml admin@example.com ``` **password** - ``` + ```yaml changeme ``` ____________________________________________________________________________________________ @@ -273,23 +273,23 @@ Add the following to your `configuration.yaml` in Home Assistant. To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

Mosquitto comes with a password file generating utility called mosquitto_passwd. -``` +```yaml sudo mosquitto_passwd -c /etc/mosquitto/passwd ``` Password: < password > Create a configuration file for Mosquitto pointing to the password file we have just created. -``` +```yaml sudo nano /etc/mosquitto/conf.d/default.conf ``` This will open an empty file. Paste the following into it. -``` +```yaml allow_anonymous false persistence true password_file /etc/mosquitto/passwd @@ -298,7 +298,7 @@ listener 1883 Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X". Now restart Mosquitto server. -``` +```yaml sudo systemctl restart mosquitto ``` @@ -320,7 +320,7 @@ ________________________________________________________________________________ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -355,19 +355,19 @@ ________________________________________________________________________________ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: -``` +```yaml nano /etc/mysql/my.cnf ``` Un-comment `port =3306` Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". -``` +```yaml nano /etc/mysql/mariadb.conf.d/50-server.cnf ``` Comment `bind-address = 127.0.0.1` @@ -376,7 +376,7 @@ Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". For new MariaDB installations, the next step is to run the included security script. This script changes some of the less secure default options. We will use it to block remote root logins and to remove unused database users. Run the security script: -``` +```yaml sudo mysql_secure_installation ``` Enter current password for root (enter for none): `enter` @@ -394,48 +394,48 @@ Remove test database and access to it? [Y/n] `y` Reload privilege tables now? [Y/n] `y` We will create a new account called admin with the same capabilities as the root account, but configured for password authentication. -``` +```yaml sudo mysql ``` Prompt will change to ```MariaDB [(none)]>``` Create a new local admin (Change the username and password to match your preferences) -``` +```yaml CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password'; ``` Give local admin root privileges (Change the username and password to match above) -``` +```yaml GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on your local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the **_username_**, **_password_** and **_subnet_** to match your preferences: -``` +```yaml GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` Flush the privileges to ensure that they are saved and available in the current session: -``` +```yaml FLUSH PRIVILEGES; ``` Following this, exit the MariaDB shell: -``` +```yaml exit ``` Log in as the new database user you just created: -``` +```yaml mysql -u admin -p ``` Create a new database: -``` +```yaml CREATE DATABASE homeassistant; ``` Following this, exit the MariaDB shell: -``` +```yaml exit ``` ⚠️ Reboot the lxc Checking status. -``` +```yaml sudo systemctl status mariadb ``` Change the recorder: `db_url:` in your HA configuration.yaml @@ -460,7 +460,7 @@ ________________________________________________________________________________ To create a new Proxmox [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -469,7 +469,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z ⚙️ **To allow device passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID**) -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` @@ -479,19 +479,19 @@ Reboot the LXC to apply the changes ⚙️ **Determine the location of your adapter** Run in the zigbee2mqtt console -``` +```yaml ls -l /dev/serial/by-id ``` Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` ⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** -``` +```yaml nano /opt/zigbee2mqtt/data/configuration.yaml ``` Example: -``` +```yaml frontend: port: 9442 homeassistant: true @@ -510,17 +510,17 @@ advanced: pan_id: GENERATE network_key: GENERATE channel: 20 - ``` -⚙️ **Zigbee2mqtt can be started after completing the configuration** ``` +⚙️ **Zigbee2mqtt can be started after completing the configuration** +```yaml sudo systemctl start zigbee2mqtt ``` ⚙️ **To start Zigbee2MQTT automatically on boot** - ``` + ```yaml sudo systemctl enable zigbee2mqtt.service ``` ⚙️ **To update Zigbee2Mqtt** - ``` + ```yaml cd /opt/zigbee2mqtt bash update.sh ``` @@ -539,7 +539,7 @@ ________________________________________________________________________________ To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zwavejs2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

@@ -549,7 +549,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z ⚙️ **To allow device passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID)** -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` @@ -570,7 +570,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian11_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -591,7 +591,7 @@ ________________________________________________________________________________ To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -612,7 +612,7 @@ ________________________________________________________________________________ To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/plex_container.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -636,7 +636,7 @@ ________________________________________________________________________________ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/pihole_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -645,7 +645,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/p Run from the LXC console -``` +```yaml pihole -a -p ``` @@ -664,7 +664,7 @@ ________________________________________________________________________________ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox web shell. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard_container.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -685,7 +685,7 @@ ________________________________________________________________________________ To Install [Webmin System Administration](https://www.webmin.com/index.html), run the following in a LXC console. -``` +```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" ``` From caccfe5c2ae7e2c80f1c18193fb3976b336bfb6b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 11:14:37 -0500 Subject: [PATCH 0649/6505] Create copy-data.sh --- misc/copy-data.sh | 104 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 misc/copy-data.sh diff --git a/misc/copy-data.sh b/misc/copy-data.sh new file mode 100644 index 00000000..d86bc401 --- /dev/null +++ b/misc/copy-data.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +#**Experimental** +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Home Assistant LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"**Experimental** Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: Alpha 01"13 50 || exit +info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" + +msg "Mounting Container Disks..." +DOCKER_PATH=/var/lib/docker/volumes/hass_config/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_TO' not found." + +rm -rf ${CTID_TO_PATH}${DOCKER_PATH} +mkdir ${CTID_TO_PATH}${DOCKER_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Docker Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." From 38200375322a3843fb43c237fb9079d038723d06 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 11:18:31 -0500 Subject: [PATCH 0650/6505] Update copy-data.sh --- misc/copy-data.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/copy-data.sh b/misc/copy-data.sh index d86bc401..980872cf 100644 --- a/misc/copy-data.sh +++ b/misc/copy-data.sh @@ -71,7 +71,7 @@ done whiptail --defaultno --title "$TITLE" --yesno \ "**Experimental** Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: Alpha 01"13 50 || exit +Version: Alpha 01" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" msg "Mounting Container Disks..." @@ -102,3 +102,5 @@ rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKE echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." + +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data.sh)" From 81e834f8a32a3de3573b7d425cd7bd92a48ab144 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 13:00:02 -0500 Subject: [PATCH 0651/6505] Update and rename copy-data.sh to ha-copy-data.sh --- misc/{copy-data.sh => ha-copy-data.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename misc/{copy-data.sh => ha-copy-data.sh} (98%) diff --git a/misc/copy-data.sh b/misc/ha-copy-data.sh similarity index 98% rename from misc/copy-data.sh rename to misc/ha-copy-data.sh index 980872cf..c2285f55 100644 --- a/misc/copy-data.sh +++ b/misc/ha-copy-data.sh @@ -103,4 +103,4 @@ echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" From b81955e5fee13a8b058915ca6b77948db80da815 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 13:37:25 -0500 Subject: [PATCH 0652/6505] Add files via upload --- misc/z2m-copy-data.sh | 106 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 misc/z2m-copy-data.sh diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh new file mode 100644 index 00000000..f2c67523 --- /dev/null +++ b/misc/z2m-copy-data.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +#**Experimental** +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Zigbee2MQTT LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Zigbee2MQTT LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Zigbee2MQTT LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"**Experimental** Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: Alpha 01" 13 50 || exit +info "Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'" + +msg "Mounting Container Disks..." +DATA_PATH=/opt/zigbee2mqtt/data/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ + die "Zigbee2igbee2MQTT directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ + die "Zigbee2MQTT directories in '$CTID_TO' not found." + +#rm -rf ${CTID_TO_PATH}${DATA_PATH} +#mkdir ${CTID_TO_PATH}${DATA_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Zigbee2MQTT Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" \ No newline at end of file From 0879d0275926d30630e2591cf65973c142c56b11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 15:24:55 -0500 Subject: [PATCH 0653/6505] Update mqtt_setup.sh --- setup/mqtt_setup.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh index f2276a8c..31e96b5f 100644 --- a/setup/mqtt_setup.sh +++ b/setup/mqtt_setup.sh @@ -24,14 +24,14 @@ function msg() { } # Prepare container OS -msg "Setting up container OS..." +msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null # Update container OS -msg "Updating container OS..." +msg "Updating Container OS..." apt update &>/dev/null apt-get -qqy upgrade &>/dev/null @@ -39,16 +39,21 @@ apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." apt-get -qqy install \ curl \ + gnupg \ sudo &>/dev/null # Installing Mosquitto MQTT broker msg "Installing Mosquitto MQTT broker.." -sudo apt-get update >/dev/null -sudo apt-get -y install mosquitto &>/dev/null -sudo apt-get -y install mosquitto-clients &>/dev/null +wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null +apt-key add mosquitto-repo.gpg.key &>/dev/null +cd /etc/apt/sources.list.d/ +wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list &>/dev/null +apt-get update >/dev/null +apt-get -y install mosquitto &>/dev/null +apt-get -y install mosquitto-clients &>/dev/null # Customize container -msg "Customizing container..." +msg "Customizing LXC..." rm /etc/motd # Remove message of the day after login rm /etc/update-motd.d/10-uname # Remove kernel information after login touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login From eba894d69936b30b602b7eb9019abba58e67000b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 15:37:58 -0500 Subject: [PATCH 0654/6505] Update z2m-copy-data.sh --- misc/z2m-copy-data.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh index f2c67523..f6c44ab8 100644 --- a/misc/z2m-copy-data.sh +++ b/misc/z2m-copy-data.sh @@ -102,5 +102,5 @@ rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PA echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." - -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" \ No newline at end of file +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" From 32af2a0b003c5c2925c07c0bca8307063cbcb64b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 15:45:06 -0500 Subject: [PATCH 0655/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 5b4d5120..f20cba2d 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -43,9 +43,9 @@ apt-get -qqy install \ # Installing MariaDB msg "Installing MariaDB..." -sudo apt-get update >/dev/null -sudo apt-get install -y mariadb-server &>/dev/null - +#sudo apt-get update >/dev/null +#sudo apt-get install -y mariadb-server &>/dev/null +curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null # Customize container msg "Customizing container..." rm /etc/motd # Remove message of the day after login From 144de2b83163e076e20ccdd394fd374e6b110b8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 15:53:43 -0500 Subject: [PATCH 0656/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index f20cba2d..7824e616 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -43,9 +43,9 @@ apt-get -qqy install \ # Installing MariaDB msg "Installing MariaDB..." -#sudo apt-get update >/dev/null -#sudo apt-get install -y mariadb-server &>/dev/null curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null +apt-get update >/dev/null +apt-get install -y mariadb-server &>/dev/null # Customize container msg "Customizing container..." rm /etc/motd # Remove message of the day after login From 5757b7e2470a0e8aab2f8597e9e6c83dad4e15ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 16:11:42 -0500 Subject: [PATCH 0657/6505] Update ha-copy-data.sh --- misc/ha-copy-data.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index c2285f55..2c270982 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -103,4 +103,5 @@ echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." +# run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" From e7b45b3555d53da69f47ac6f5e66f5c91bfb3fa8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 16:31:45 -0500 Subject: [PATCH 0658/6505] Update z2m-copy-data.sh --- misc/z2m-copy-data.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh index f6c44ab8..dcf5023e 100644 --- a/misc/z2m-copy-data.sh +++ b/misc/z2m-copy-data.sh @@ -102,5 +102,7 @@ rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PA echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." + +# Use to copy all data from one Zigbee2MQTT LXC to another # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" From c601c249f562dc085823808198cbe0e805b2b38d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 16:32:36 -0500 Subject: [PATCH 0659/6505] Update ha-copy-data.sh --- misc/ha-copy-data.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index 2c270982..5c5c125f 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -103,5 +103,6 @@ echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." +# Use to copy all data from one Home Assistant LXC to another # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" From fded7a856b093defe116d3d56753189bd323b4e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 17:02:15 -0500 Subject: [PATCH 0660/6505] Add files via upload --- misc/npm-copy-data.sh | 116 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 misc/npm-copy-data.sh diff --git a/misc/npm-copy-data.sh b/misc/npm-copy-data.sh new file mode 100644 index 00000000..36b523a5 --- /dev/null +++ b/misc/npm-copy-data.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +while true; do + read -p "Use to copy all data from one Nginx Proxy Manager LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +#**Experimental** +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Nginx Proxy Manager LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Nginx Proxy Manager LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Nginx Proxy Manager LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"**Experimental** Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.01.21" 13 50 || exit +info "Nginx Proxy Manager Data from '$CTID_FROM' to '$CTID_TO'" + +msg "Mounting Container Disks..." +DATA_PATH=/data/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ + die "Nginx Proxy Manager directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ + die "Nginx Proxy Manager directories in '$CTID_TO' not found." + +#rm -rf ${CTID_TO_PATH}${DATA_PATH} +#mkdir ${CTID_TO_PATH}${DATA_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Nginx Proxy Manager Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from one Nginx Proxy Manager LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/npm-copy-data.sh)" \ No newline at end of file From c66109b522b72c8fad6a81dbc81d30eb46a72b8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 17:41:24 -0500 Subject: [PATCH 0661/6505] Update npm-copy-data.sh --- misc/npm-copy-data.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/npm-copy-data.sh b/misc/npm-copy-data.sh index 36b523a5..5676f5f4 100644 --- a/misc/npm-copy-data.sh +++ b/misc/npm-copy-data.sh @@ -93,8 +93,8 @@ CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ [ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ die "Nginx Proxy Manager directories in '$CTID_TO' not found." -#rm -rf ${CTID_TO_PATH}${DATA_PATH} -#mkdir ${CTID_TO_PATH}${DATA_PATH} +rm -rf ${CTID_TO_PATH}${DATA_PATH} +mkdir ${CTID_TO_PATH}${DATA_PATH} msg "Copying Data Between Containers..." RSYNC_OPTIONS=( @@ -113,4 +113,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Nginx Proxy Manager LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/npm-copy-data.sh)" \ No newline at end of file +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/npm-copy-data.sh)" From 3c0cc1100b603ec6bcbda46a25ed8b5e8b2ed9eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 17:47:26 -0500 Subject: [PATCH 0662/6505] Delete npm-copy-data.sh --- misc/npm-copy-data.sh | 116 ------------------------------------------ 1 file changed, 116 deletions(-) delete mode 100644 misc/npm-copy-data.sh diff --git a/misc/npm-copy-data.sh b/misc/npm-copy-data.sh deleted file mode 100644 index 5676f5f4..00000000 --- a/misc/npm-copy-data.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash -while true; do - read -p "Use to copy all data from one Nginx Proxy Manager LXC to another. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -#**Experimental** -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM - [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -TITLE="Nginx Proxy Manager LXC Data Copy" -while read -r line; do - TAG=$(echo "$line" | awk '{print $1}') - ITEM=$(echo "$line" | awk '{print substr($0,36)}') - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) -done < <(pct list | awk 'NR>1') -while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Nginx Proxy Manager LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit -done -while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Nginx Proxy Manager LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit -done -for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) -done -whiptail --defaultno --title "$TITLE" --yesno \ -"**Experimental** Are you sure you want to copy data between the following LXCs? -$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: 2022.01.21" 13 50 || exit -info "Nginx Proxy Manager Data from '$CTID_FROM' to '$CTID_TO'" - -msg "Mounting Container Disks..." -DATA_PATH=/data/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ - die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ - die "Nginx Proxy Manager directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ - die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ - die "Nginx Proxy Manager directories in '$CTID_TO' not found." - -rm -rf ${CTID_TO_PATH}${DATA_PATH} -mkdir ${CTID_TO_PATH}${DATA_PATH} - -msg "Copying Data Between Containers..." -RSYNC_OPTIONS=( - --archive - --hard-links - --sparse - --xattrs - --no-inc-recursive - --info=progress2 -) -msg "<======== Nginx Proxy Manager Data ========>" -rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} -echo -en "\e[1A\e[0K\e[1A\e[0K" - -info "Successfully Transferred Data." - -# Use to copy all data from one Nginx Proxy Manager LXC to another -# run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/npm-copy-data.sh)" From db4be15386abf4dc181a015ba122192c6d3968d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 18:02:33 -0500 Subject: [PATCH 0663/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b32078a..b06db2eb 100644 --- a/README.md +++ b/README.md @@ -531,7 +531,7 @@ ________________________________________________________________________________
-🔸Zwavejs2MQTT LXC +Zwavejs2MQTT LXC

From 9eabaa43125d6cc070ea22e63a7aa04b4208aba2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jan 2022 21:13:44 -0500 Subject: [PATCH 0664/6505] Add files via upload --- misc/ha-copy-data.sh | 10 +++++++++- misc/z2m-copy-data.sh | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index 5c5c125f..4ab88f52 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -1,4 +1,12 @@ #!/usr/bin/env bash +while true; do + read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done #**Experimental** set -o errexit set -o errtrace @@ -105,4 +113,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Home Assistant LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" \ No newline at end of file diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh index dcf5023e..d0cb6923 100644 --- a/misc/z2m-copy-data.sh +++ b/misc/z2m-copy-data.sh @@ -1,4 +1,12 @@ #!/usr/bin/env bash +while true; do + read -p "Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done #**Experimental** set -o errexit set -o errtrace @@ -105,4 +113,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Zigbee2MQTT LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" \ No newline at end of file From caba12b210d6bbdb04ff84577f8b39a20592d98e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 10:22:33 -0500 Subject: [PATCH 0665/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b06db2eb..10cfa505 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,7 @@ ________________________________________________________________________________
-🔸Nginx Proxy Manager LXC +Nginx Proxy Manager LXC

hero

From 9342895db3c2a84f906a168cd62693462f046b4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 13:07:02 -0500 Subject: [PATCH 0666/6505] Add files via upload --- setup/ha-copy-data.sh | 115 +++++++++++++++++++++++++++++++++++++++++ setup/z2m-copy-data.sh | 115 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 setup/ha-copy-data.sh create mode 100644 setup/z2m-copy-data.sh diff --git a/setup/ha-copy-data.sh b/setup/ha-copy-data.sh new file mode 100644 index 00000000..9d567b7a --- /dev/null +++ b/setup/ha-copy-data.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +while true; do + read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Home Assistant LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: Alpha 01" 13 50 || exit +info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" + +msg "Mounting Container Disks..." +DOCKER_PATH=/var/lib/docker/volumes/hass_config/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_TO' not found." + +rm -rf ${CTID_TO_PATH}${DOCKER_PATH} +mkdir ${CTID_TO_PATH}${DOCKER_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Docker Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from one Home Assistant LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" \ No newline at end of file diff --git a/setup/z2m-copy-data.sh b/setup/z2m-copy-data.sh new file mode 100644 index 00000000..f63d471b --- /dev/null +++ b/setup/z2m-copy-data.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +while true; do + read -p "Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Zigbee2MQTT LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Zigbee2MQTT LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Zigbee2MQTT LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: Alpha 01" 13 50 || exit +info "Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'" + +msg "Mounting Container Disks..." +DATA_PATH=/opt/zigbee2mqtt/data/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ + die "Zigbee2igbee2MQTT directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ + die "Zigbee2MQTT directories in '$CTID_TO' not found." + +#rm -rf ${CTID_TO_PATH}${DATA_PATH} +#mkdir ${CTID_TO_PATH}${DATA_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Zigbee2MQTT Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from one Zigbee2MQTT LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" \ No newline at end of file From 94a23f3ea2607799ff8ea37856faa9db4f93eddb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 13:08:05 -0500 Subject: [PATCH 0667/6505] Delete ha-copy-data.sh --- setup/ha-copy-data.sh | 115 ------------------------------------------ 1 file changed, 115 deletions(-) delete mode 100644 setup/ha-copy-data.sh diff --git a/setup/ha-copy-data.sh b/setup/ha-copy-data.sh deleted file mode 100644 index 9d567b7a..00000000 --- a/setup/ha-copy-data.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env bash -while true; do - read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM - [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -TITLE="Home Assistant LXC Data Copy" -while read -r line; do - TAG=$(echo "$line" | awk '{print $1}') - ITEM=$(echo "$line" | awk '{print substr($0,36)}') - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) -done < <(pct list | awk 'NR>1') -while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit -done -while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit -done -for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) -done -whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? -$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: Alpha 01" 13 50 || exit -info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" - -msg "Mounting Container Disks..." -DOCKER_PATH=/var/lib/docker/volumes/hass_config/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ - die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ - die "Home Assistant directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ - die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ - die "Home Assistant directories in '$CTID_TO' not found." - -rm -rf ${CTID_TO_PATH}${DOCKER_PATH} -mkdir ${CTID_TO_PATH}${DOCKER_PATH} - -msg "Copying Data Between Containers..." -RSYNC_OPTIONS=( - --archive - --hard-links - --sparse - --xattrs - --no-inc-recursive - --info=progress2 -) -msg "<======== Docker Data ========>" -rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH} -echo -en "\e[1A\e[0K\e[1A\e[0K" - -info "Successfully Transferred Data." - -# Use to copy all data from one Home Assistant LXC to another -# run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" \ No newline at end of file From e446e67e7c917f62c2ab2da827b89a4a5508b8cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 13:08:20 -0500 Subject: [PATCH 0668/6505] Delete z2m-copy-data.sh --- setup/z2m-copy-data.sh | 115 ----------------------------------------- 1 file changed, 115 deletions(-) delete mode 100644 setup/z2m-copy-data.sh diff --git a/setup/z2m-copy-data.sh b/setup/z2m-copy-data.sh deleted file mode 100644 index f63d471b..00000000 --- a/setup/z2m-copy-data.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env bash -while true; do - read -p "Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM - [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -TITLE="Zigbee2MQTT LXC Data Copy" -while read -r line; do - TAG=$(echo "$line" | awk '{print $1}') - ITEM=$(echo "$line" | awk '{print substr($0,36)}') - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) -done < <(pct list | awk 'NR>1') -while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Zigbee2MQTT LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit -done -while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Zigbee2MQTT LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit -done -for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) -done -whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? -$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: Alpha 01" 13 50 || exit -info "Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'" - -msg "Mounting Container Disks..." -DATA_PATH=/opt/zigbee2mqtt/data/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ - die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ - die "Zigbee2igbee2MQTT directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ - die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ - die "Zigbee2MQTT directories in '$CTID_TO' not found." - -#rm -rf ${CTID_TO_PATH}${DATA_PATH} -#mkdir ${CTID_TO_PATH}${DATA_PATH} - -msg "Copying Data Between Containers..." -RSYNC_OPTIONS=( - --archive - --hard-links - --sparse - --xattrs - --no-inc-recursive - --info=progress2 -) -msg "<======== Zigbee2MQTT Data ========>" -rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} -echo -en "\e[1A\e[0K\e[1A\e[0K" - -info "Successfully Transferred Data." - -# Use to copy all data from one Zigbee2MQTT LXC to another -# run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" \ No newline at end of file From eda9649d7264254410b0219db0a9e7c3354c5fed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 13:08:57 -0500 Subject: [PATCH 0669/6505] Add files via upload --- misc/ha-copy-data.sh | 3 +-- misc/z2m-copy-data.sh | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index 4ab88f52..9d567b7a 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -7,7 +7,6 @@ while true; do * ) echo "Please answer yes or no.";; esac done -#**Experimental** set -o errexit set -o errtrace set -o nounset @@ -77,7 +76,7 @@ for i in ${!CTID_MENU[@]}; do CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"**Experimental** Are you sure you want to copy data between the following LXCs? +"Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: Alpha 01" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh index d0cb6923..f63d471b 100644 --- a/misc/z2m-copy-data.sh +++ b/misc/z2m-copy-data.sh @@ -7,7 +7,6 @@ while true; do * ) echo "Please answer yes or no.";; esac done -#**Experimental** set -o errexit set -o errtrace set -o nounset @@ -77,7 +76,7 @@ for i in ${!CTID_MENU[@]}; do CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"**Experimental** Are you sure you want to copy data between the following LXCs? +"Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: Alpha 01" 13 50 || exit info "Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'" From 03c82373af5885fe6e8ad6d3a89238bea295ab85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 14:46:59 -0500 Subject: [PATCH 0670/6505] Create place-holder --- img/place-holder | 1 + 1 file changed, 1 insertion(+) create mode 100644 img/place-holder diff --git a/img/place-holder b/img/place-holder new file mode 100644 index 00000000..29454e56 --- /dev/null +++ b/img/place-holder @@ -0,0 +1 @@ +Place Holder From d3936f28c7e6e5845d9be038286158bb3ed3aa74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 14:48:17 -0500 Subject: [PATCH 0671/6505] Add files via upload --- img/mosquitto.png | Bin 0 -> 26622 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 img/mosquitto.png diff --git a/img/mosquitto.png b/img/mosquitto.png new file mode 100644 index 0000000000000000000000000000000000000000..d67f1a7fd612466f38a98d59db1bc82759fbb0e5 GIT binary patch literal 26622 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 Date: Sat, 22 Jan 2022 14:52:40 -0500 Subject: [PATCH 0672/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10cfa505..aa3db524 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ Add the following to your `configuration.yaml` in Home Assistant.
MQTT LXC -

+

Proxmox MQTT LXC Container

From 39e53ffe254b565c6d42d41a85b34fda854fa1b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 14:54:41 -0500 Subject: [PATCH 0673/6505] Delete place-holder --- img/place-holder | 1 - 1 file changed, 1 deletion(-) delete mode 100644 img/place-holder diff --git a/img/place-holder b/img/place-holder deleted file mode 100644 index 29454e56..00000000 --- a/img/place-holder +++ /dev/null @@ -1 +0,0 @@ -Place Holder From 27af6e3fc22da9558774d7f5148460e59deb6909 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 15:02:31 -0500 Subject: [PATCH 0674/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa3db524..812b3611 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ Add the following to your `configuration.yaml` in Home Assistant.
MQTT LXC -

+

Proxmox MQTT LXC Container

From d1cc265e013f9131baab08723a3a020d07134ab9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 15:03:06 -0500 Subject: [PATCH 0675/6505] Delete mosquitto.png --- img/mosquitto.png | Bin 26622 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 img/mosquitto.png diff --git a/img/mosquitto.png b/img/mosquitto.png deleted file mode 100644 index d67f1a7fd612466f38a98d59db1bc82759fbb0e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26622 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 Date: Sat, 22 Jan 2022 18:11:17 -0500 Subject: [PATCH 0676/6505] Update haos_vm.sh --- vm/haos_vm.sh | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a4aa4f54..ce5c6725 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -106,19 +106,11 @@ echo -e "${CHECKMARK} \e[1;92m Downloading disk image... \e[0m" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -if [[ $FILE == *.zip ]]; then - echo -e "${CHECKMARK} \e[1;92m Checking for unzip command... \e[0m" - if ! command -v unzip &> /dev/null; then - echo -e "${CHECKMARK} \e[1;92m Installing Unzip... \e[0m" - apt-get update >/dev/null - apt-get -qqy install unzip &>/dev/null - fi -fi echo -e "${CHECKMARK} \e[1;92m Extracting disk image... \e[0m" case $FILE in - *"gz") gunzip -f $FILE;; - *"zip") unzip -o $FILE;; - *"xz") xz -d $FILE;; + *"gz") gunzip -f $FILE ;; + *"zip") gunzip -f -S .zip $FILE ;; + *"xz") xz -d $FILE ;; *) die "Unable to handle file extension '${FILE##*.}'.";; esac STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') From ff863203c4fe3262d8162d32b1ac95f77a1c4bdf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 18:17:03 -0500 Subject: [PATCH 0677/6505] Update haos_vm.sh --- vm/haos_vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index ce5c6725..a19de432 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -133,9 +133,9 @@ pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},size=32G > /dev/null + -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ - -boot order=scsi0 > /dev/null + -boot order=scsi0 >/dev/null set +o errtrace ( echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" From a5d5769520e456f71e3ea3c4ea1dbfb9e3dd7063 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 21:04:28 -0500 Subject: [PATCH 0678/6505] Update plex_setup.sh --- setup/plex_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index fb4e24fe..ee5ae348 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -39,9 +39,9 @@ apt-get -qqy install \ sudo \ gnupg &>/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading Plex Media Server... \e[0m" -wget https://downloads.plex.tv/plex-media-server-new/1.25.2.5319-c43dc0277/debian/plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null +wget https://downloads.plex.tv/plex-media-server-new/1.25.3.5409-f11334058/debian/plexmediaserver_1.25.3.5409-f11334058_amd64.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" -sudo dpkg -i plexmediaserver_1.25.2.5319-c43dc0277_amd64.deb &>/dev/null +sudo dpkg -i plexmediaserver_1.25.3.5409-f11334058_amd64.deb &>/dev/null cat < /etc/apt/sources.list.d/plexmediaserver.list deb https://downloads.plex.tv/repo/deb/ public main From 77ce1f8e31541f72285f855603246f4381949f0e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 23:51:11 -0500 Subject: [PATCH 0679/6505] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 812b3611..74458d4f 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,13 @@ Now restart Mosquitto server. sudo systemctl restart mosquitto ``` +⚙️ **To Update MQTT:** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` + ____________________________________________________________________________________________
@@ -442,6 +449,12 @@ Change the recorder: `db_url:` in your HA configuration.yaml Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4` +⚙️ **To Update Mariadb:** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` ____________________________________________________________________________________________
From 636bd6fe236bc7d0ca0be7d7f53876f6e94ddd8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jan 2022 23:56:44 -0500 Subject: [PATCH 0680/6505] Update README.md --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 74458d4f..daedcffd 100644 --- a/README.md +++ b/README.md @@ -336,16 +336,21 @@ From your nodered LXC console, the following commands can be run `node-red-start` to start Node-Red -`sudo systemctl enable nodered.service` to autostart Node-RED at every boot +`systemctl enable nodered.service` to autostart Node-RED at every boot `node-red-restart` to restart Node-Red -`sudo systemctl disable nodered.service` to disable autostart on boot - -`sudo npm install -g --unsafe-perm node-red` to update Node-Red (`node-red-restart` after update) +`systemctl disable nodered.service` to disable autostart on boot **Node-Red Interface - IP:1880** +⚙️ **To Update Node-Red:** + +Run from the LXC console +```yaml +npm install -g --unsafe-perm node-red +``` +(`node-red-restart` after update) ____________________________________________________________________________________________
From 5e11edb6e576dca2bbcf0716e954849b83ecaca2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 00:02:11 -0500 Subject: [PATCH 0681/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index daedcffd..755bfeac 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,7 @@ Run from the LXC console npm install -g --unsafe-perm node-red ``` (`node-red-restart` after update) + ____________________________________________________________________________________________
From 08fed46abeecc0f39721ce2ace1e6ea9321e8489 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 03:18:11 -0500 Subject: [PATCH 0682/6505] Create CHANGELOG.MD --- CHANGELOG.MD | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 CHANGELOG.MD diff --git a/CHANGELOG.MD b/CHANGELOG.MD new file mode 100644 index 00000000..65ae6dfb --- /dev/null +++ b/CHANGELOG.MD @@ -0,0 +1,20 @@ + +# Change Log +All notable changes to this project will be documented in this file. + + +## Initial Catch up - 2022-01-23 + +### Changed + +- **Zwavejs2MQTT LXC**, created new script to solve no auto start at boot +- **Nginx Proxy Manager LXC**, created new script to use Debian 11 +- **Ubuntu 21.10 LXC**, created new script +- **Mariadb LXC**, added MariaDB Package Repository +- **MQTT LXC**, added Eclipse Mosquitto Repository +- **Home Assistant Container LXC**, added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. + - Added script for easy update of HA +- **Home Assistant Container LXC (Podman)**, added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. +- **Home Assistant OS VM**, changed disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk + - Cleaned up script +- **Proxmox VE 7 Post Install**, new *No-Nag* method From 3dde87486f2da0a484b9b5d31a833a728bcc0a54 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 03:21:55 -0500 Subject: [PATCH 0683/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 755bfeac..790c5ae5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@

Select a Proxmox Helper Below

+[Changelog](https://github.com/tteck/Proxmox/blob/main/CHANGELOG.MD) + 🔸 updated in the past 7 days From d47041211f77c33be8aebb3294596760c96eb0fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 03:27:56 -0500 Subject: [PATCH 0684/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 790c5ae5..55b2cd6f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

Select a Proxmox Helper Below

-[Changelog](https://github.com/tteck/Proxmox/blob/main/CHANGELOG.MD) -🔸 updated in the past 7 days + +🔸 updated in the past 7 days [Changelog](https://github.com/tteck/Proxmox/blob/main/CHANGELOG.MD)
From 1fe370ace005ac10ce2b95d60e0e532299b8f778 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 03:33:55 -0500 Subject: [PATCH 0685/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 65ae6dfb..8684ed30 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,14 +7,23 @@ All notable changes to this project will be documented in this file. ### Changed -- **Zwavejs2MQTT LXC**, created new script to solve no auto start at boot -- **Nginx Proxy Manager LXC**, created new script to use Debian 11 -- **Ubuntu 21.10 LXC**, created new script -- **Mariadb LXC**, added MariaDB Package Repository -- **MQTT LXC**, added Eclipse Mosquitto Repository -- **Home Assistant Container LXC**, added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. +- **Zwavejs2MQTT LXC** + - created new script to solve no auto start at boot +- **Nginx Proxy Manager LXC** + - created new script to use Debian 11 +- **Ubuntu 21.10 LXC** + - created new script +- **Mariadb LXC** + - added MariaDB Package Repository +- **MQTT LXC** + - added Eclipse Mosquitto Repository +- **Home Assistant Container LXC** + - added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - Added script for easy update of HA -- **Home Assistant Container LXC (Podman)**, added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. -- **Home Assistant OS VM**, changed disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk +- **Home Assistant Container LXC (Podman)** + - added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. +- **Home Assistant OS VM** + - changed disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk - Cleaned up script -- **Proxmox VE 7 Post Install**, new *No-Nag* method +- **Proxmox VE 7 Post Install** + - new *No-Nag* method From e4ac1d0c2828de32b20ed768b2a13690d7aa33d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 03:38:01 -0500 Subject: [PATCH 0686/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 8684ed30..ea5d82eb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -19,11 +19,11 @@ All notable changes to this project will be documented in this file. - added Eclipse Mosquitto Repository - **Home Assistant Container LXC** - added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - - Added script for easy update of HA + - added script for easy Home Assistant update - **Home Assistant Container LXC (Podman)** - added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - **Home Assistant OS VM** - changed disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk - - Cleaned up script + - cleaned up script - **Proxmox VE 7 Post Install** - new *No-Nag* method From 24d17403e02ce4d050f13a7a779a9c140aeb0e41 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 03:42:13 -0500 Subject: [PATCH 0687/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ea5d82eb..073cb652 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -16,7 +16,7 @@ All notable changes to this project will be documented in this file. - **Mariadb LXC** - added MariaDB Package Repository - **MQTT LXC** - - added Eclipse Mosquitto Repository + - added Eclipse Mosquitto Package Repository - **Home Assistant Container LXC** - added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - added script for easy Home Assistant update From 73347f16e94e52201d8b2849481229700a229fe2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 03:48:54 -0500 Subject: [PATCH 0688/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 073cb652..a0779adc 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -18,10 +18,10 @@ All notable changes to this project will be documented in this file. - **MQTT LXC** - added Eclipse Mosquitto Package Repository - **Home Assistant Container LXC** - - added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. + - if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - added script for easy Home Assistant update - **Home Assistant Container LXC (Podman)** - - added if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. + - if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - **Home Assistant OS VM** - changed disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk - cleaned up script From d880336914bf49b5fe7674fd055edc0645f1ed9e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 04:04:26 -0500 Subject: [PATCH 0689/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 55b2cd6f..74619823 100644 --- a/README.md +++ b/README.md @@ -542,8 +542,7 @@ sudo systemctl enable zigbee2mqtt.service ``` ⚙️ **To update Zigbee2Mqtt** ```yaml -cd /opt/zigbee2mqtt -bash update.sh +bash /opt/zigbee2mqtt/update.sh ``` ____________________________________________________________________________________________ From cdd187d6284ac81da7f426f9a7c034357d0ac2d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 12:33:55 -0500 Subject: [PATCH 0690/6505] Update plex_container.sh --- ct/plex_container.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index c3c8b492..db7dd698 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -144,6 +144,15 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF + MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT From f6502541f22c3015d88cfc9417b89457a1713f9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 12:36:09 -0500 Subject: [PATCH 0691/6505] Update plex_setup.sh --- setup/plex_setup.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index ee5ae348..2c43b410 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -38,6 +38,11 @@ apt-get -qqy install \ curl \ sudo \ gnupg &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* + echo -e "${CHECKMARK} \e[1;92m Downloading Plex Media Server... \e[0m" wget https://downloads.plex.tv/plex-media-server-new/1.25.3.5409-f11334058/debian/plexmediaserver_1.25.3.5409-f11334058_amd64.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" From 52386dd5d95b75fb61629472e19e8a14f930f878 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 13:15:17 -0500 Subject: [PATCH 0692/6505] Update plex_container.sh --- ct/plex_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index db7dd698..760b4da7 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -108,8 +108,8 @@ info "Container ID is $CTID." echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-20.04 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 6707791f2185f3beec61d8c84c0f962ba72510ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 13:16:42 -0500 Subject: [PATCH 0693/6505] Update plex_setup.sh --- setup/plex_setup.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index 2c43b410..124b5df1 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -54,8 +54,7 @@ EOF wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname +chmod -x /etc/update-motd.d/* touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) From 325330d94a4ff809b3af192b71cb282a0376a781 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 13:53:40 -0500 Subject: [PATCH 0694/6505] Add files via upload --- misc/intel-drivers.sh | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 misc/intel-drivers.sh diff --git a/misc/intel-drivers.sh b/misc/intel-drivers.sh new file mode 100644 index 00000000..0df182b4 --- /dev/null +++ b/misc/intel-drivers.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will install Intel Drivers on your Plex Media Server LXC. + Do you want to Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +mkdir neo + +cd neo +wget https://github.com/intel/compute-runtime/releases/download/22.03.22192/intel-gmmlib_22.0.0_amd64.deb +wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.9933/intel-igc-core_1.0.9933_amd64.deb +wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.9933/intel-igc-opencl_1.0.9933_amd64.deb +wget https://github.com/intel/compute-runtime/releases/download/22.03.22192/intel-opencl-icd_22.03.22192_amd64.deb +wget https://github.com/intel/compute-runtime/releases/download/22.03.22192/intel-level-zero-gpu_1.2.22192_amd64.deb + +sudo dpkg -i *.deb + + + + + + +echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" + + + + + + + + + + + + + + + + + + From 2d8e6b2bd8de80fa45ad9a7e1381ef36f95e81eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 13:58:49 -0500 Subject: [PATCH 0695/6505] Update plex_container.sh --- ct/plex_container.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index 760b4da7..cdd594dd 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -73,7 +73,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh - +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/misc/intel-drivers.sh load_module overlay while read -r line; do @@ -160,6 +160,7 @@ pct unmount $CTID && unset MOUNT echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 +pct push $CTID intel-drivers.sh /root/intel-drivers.sh -perms 755 pct exec $CTID /plex_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 010b685ed759427c927f5defba34907035a059c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 14:24:34 -0500 Subject: [PATCH 0696/6505] Delete plex_hardware_acceleration.sh --- misc/plex_hardware_acceleration.sh | 64 ------------------------------ 1 file changed, 64 deletions(-) delete mode 100644 misc/plex_hardware_acceleration.sh diff --git a/misc/plex_hardware_acceleration.sh b/misc/plex_hardware_acceleration.sh deleted file mode 100644 index 5cba0db2..00000000 --- a/misc/plex_hardware_acceleration.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will add Hardware Acceleration Support to your Plex Media Server LXC. - Did you replace 106 with your LXC ID? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -CTID=$1 -CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -cat <> $CTID_CONFIG_PATH -### Intel iGPU: ### -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 -#lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file 0, 0 -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 0, 0 -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file 0, 0 - -### NVidia GPU: ### -#lxc.cgroup2.devices.allow: c 195:* rwm -#lxc.cgroup2.devices.allow: c 243:* rwm -#lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file -#lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file -#lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file -#lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file -#lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file -#lxc.cgroup2.devices.allow: c 226:0 rwm -#lxc.cgroup2.devices.allow: c 226:128 rwm -#lxc.cgroup2.devices.allow: c 29:0 rwm -#lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 -EOF -echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" - -# Plex can transcode media files on the fly. By default they use the CPU. -# All Intel CPU’s since Sandy Bridge released in 2011 have hardware acceleration for H.264 built in. -# So if your CPU supports Quick Sync you can speed up transcoding and reduce load by running the -# following in the Proxmox web shell (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/plex_hardware_acceleration.sh)" -s 106 -# Reboot the LXC to apply the changes - From 7e2a83a1c09eb08283e6c35dd12d315cdf723725 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 14:25:33 -0500 Subject: [PATCH 0697/6505] Update intel-drivers.sh --- misc/intel-drivers.sh | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/misc/intel-drivers.sh b/misc/intel-drivers.sh index 0df182b4..7c8f6bb5 100644 --- a/misc/intel-drivers.sh +++ b/misc/intel-drivers.sh @@ -40,27 +40,4 @@ wget https://github.com/intel/compute-runtime/releases/download/22.03.22192/inte sudo dpkg -i *.deb - - - - - echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" - - - - - - - - - - - - - - - - - - From 7c980784eaa2182f76954058533a77da45899419 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 14:36:32 -0500 Subject: [PATCH 0698/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a0779adc..bdeab908 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file. ### Changed +- **Plex Media Server LXC** + - added Hardware Acceleration Support + - added script to install Intel Drivers - **Zwavejs2MQTT LXC** - created new script to solve no auto start at boot - **Nginx Proxy Manager LXC** From e8534b7b4314d8d53d45c256f7da31a737ecffba Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 14:41:57 -0500 Subject: [PATCH 0699/6505] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 74619823..43102ec4 100644 --- a/README.md +++ b/README.md @@ -624,7 +624,7 @@ ________________________________________________________________________________
- Plex Media Server LXC +🔸Plex Media Server LXC

@@ -641,6 +641,13 @@ After the script completes, If you're dissatisfied with the default settings, cl **Plex Media Server Interface - IP:32400/web** +⚙️ **To Install Intel Drivers:** + +Run from the LXC console +```yaml +./intel-drivers.sh +``` + ____________________________________________________________________________________________
From 15c2790f493204317fb7d1bb1229e3148668c7dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 17:09:02 -0500 Subject: [PATCH 0700/6505] Update ha-copy-data.sh --- misc/ha-copy-data.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index 9d567b7a..9b41cac3 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Use to copy all data from one Home Assistant LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" while true; do read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn case $yn in @@ -78,7 +81,7 @@ done whiptail --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: Alpha 01" 13 50 || exit +Version: 2022.01.23" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" msg "Mounting Container Disks..." @@ -112,4 +115,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Home Assistant LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" \ No newline at end of file +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" From 6d17eb22d9c9d1b28b46c2e03c432bc2a3fd4297 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 17:10:28 -0500 Subject: [PATCH 0701/6505] Update z2m-copy-data.sh --- misc/z2m-copy-data.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh index f63d471b..a2320f95 100644 --- a/misc/z2m-copy-data.sh +++ b/misc/z2m-copy-data.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Use to copy all data from one Zigbee2MQTT LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" while true; do read -p "Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?" yn case $yn in @@ -78,7 +81,7 @@ done whiptail --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: Alpha 01" 13 50 || exit +Version: 2022.01.23" 13 50 || exit info "Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'" msg "Mounting Container Disks..." @@ -112,4 +115,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Zigbee2MQTT LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" \ No newline at end of file +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" From bf8ddd641f1120d3447a73b4aaa75127a3e2d259 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 17:31:24 -0500 Subject: [PATCH 0702/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bdeab908..063efe9e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file. ### Changed +- **misc** + - created GUI script to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) + - created GUI script to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) - **Plex Media Server LXC** - added Hardware Acceleration Support - added script to install Intel Drivers From 2c1b0ef7df14cdf1069ad6701e0e369cea786d88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 17:35:09 -0500 Subject: [PATCH 0703/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 063efe9e..e0a9a152 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,8 +8,8 @@ All notable changes to this project will be documented in this file. ### Changed - **misc** - - created GUI script to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) - - created GUI script to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) + - created GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) + - created GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) - **Plex Media Server LXC** - added Hardware Acceleration Support - added script to install Intel Drivers From b23e100cffca6baa8a428083428ea2b83f3e97b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 19:01:22 -0500 Subject: [PATCH 0704/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e0a9a152..85097fd2 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,9 +7,6 @@ All notable changes to this project will be documented in this file. ### Changed -- **misc** - - created GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) - - created GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) - **Plex Media Server LXC** - added Hardware Acceleration Support - added script to install Intel Drivers @@ -33,3 +30,6 @@ All notable changes to this project will be documented in this file. - cleaned up script - **Proxmox VE 7 Post Install** - new *No-Nag* method +- **misc** + - created GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) + - created GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) From 151ec437ae2f798288967ccbe0342488bf23a735 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jan 2022 22:05:38 -0500 Subject: [PATCH 0705/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 85097fd2..a224a6cb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,28 +8,28 @@ All notable changes to this project will be documented in this file. ### Changed - **Plex Media Server LXC** - - added Hardware Acceleration Support - - added script to install Intel Drivers + - add Hardware Acceleration Support + - add script to install Intel Drivers - **Zwavejs2MQTT LXC** - - created new script to solve no auto start at boot + - create new script to solve no auto start at boot - **Nginx Proxy Manager LXC** - - created new script to use Debian 11 + - create new script to use Debian 11 - **Ubuntu 21.10 LXC** - - created new script + - create new script - **Mariadb LXC** - - added MariaDB Package Repository + - add MariaDB Package Repository - **MQTT LXC** - - added Eclipse Mosquitto Package Repository + - add Eclipse Mosquitto Package Repository - **Home Assistant Container LXC** - if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - - added script for easy Home Assistant update + - add script for easy Home Assistant update - **Home Assistant Container LXC (Podman)** - if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - **Home Assistant OS VM** - - changed disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk - - cleaned up script + - change disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk + - clean up script - **Proxmox VE 7 Post Install** - new *No-Nag* method - **misc** - - created GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) - - created GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) + - create GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) + - create GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) From 78e1f61a2743f5d8a9ceb1d4a93d0031c462c616 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 00:18:28 -0500 Subject: [PATCH 0706/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a224a6cb..2c7c7a0f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,11 +11,11 @@ All notable changes to this project will be documented in this file. - add Hardware Acceleration Support - add script to install Intel Drivers - **Zwavejs2MQTT LXC** - - create new script to solve no auto start at boot + - new script to solve no auto start at boot - **Nginx Proxy Manager LXC** - - create new script to use Debian 11 + - new script to use Debian 11 - **Ubuntu 21.10 LXC** - - create new script + - new script - **Mariadb LXC** - add MariaDB Package Repository - **MQTT LXC** @@ -31,5 +31,5 @@ All notable changes to this project will be documented in this file. - **Proxmox VE 7 Post Install** - new *No-Nag* method - **misc** - - create GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) - - create GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) + - GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) + - GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) From 90ee1ed0fe7d181f98cc523b2a08052c76230bef Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 00:20:13 -0500 Subject: [PATCH 0707/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2c7c7a0f..9106e64a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -31,5 +31,5 @@ All notable changes to this project will be documented in this file. - **Proxmox VE 7 Post Install** - new *No-Nag* method - **misc** - - GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) - - GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) + - new GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) + - new GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) From 0ed77474a1206f6695ff50f93a999a65e90edd76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 00:22:01 -0500 Subject: [PATCH 0708/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 43102ec4..492adee1 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ ________________________________________________________________________________
- 🔸Home Assistant Container LXC (Podman) +Home Assistant Container LXC (Podman)

@home-assistant

@@ -603,7 +603,7 @@ ________________________________________________________________________________
-🔸Ubuntu 21.10 LXC +Ubuntu 21.10 LXC

Ubuntu

From 8a2de8315926216e60c571bd6efa1b52c889d254 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 00:27:52 -0500 Subject: [PATCH 0709/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9106e64a..c5d5a171 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -27,7 +27,7 @@ All notable changes to this project will be documented in this file. - if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. - **Home Assistant OS VM** - change disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk - - clean up script + - clean up - **Proxmox VE 7 Post Install** - new *No-Nag* method - **misc** From dda4bd213d13b3c84feb6477fc8f7a89fc5b9eee Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 00:39:46 -0500 Subject: [PATCH 0710/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c5d5a171..ae506c43 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -21,10 +21,10 @@ All notable changes to this project will be documented in this file. - **MQTT LXC** - add Eclipse Mosquitto Package Repository - **Home Assistant Container LXC** - - if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. + - change if ZFS filesystem is detected, automatic installation of static fuse-overlayfs is executed. - add script for easy Home Assistant update - **Home Assistant Container LXC (Podman)** - - if the script detects ZFS filesystem it's an automatic installation of static fuse-overlayfs. + - change if ZFS filesystem is detected, automatic installation of static fuse-overlayfs is executed. - **Home Assistant OS VM** - change disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk - clean up From 95b228f3d7a89a9e6624c3c65375ce59e63c9494 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 00:44:23 -0500 Subject: [PATCH 0711/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ae506c43..b01dc9ba 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -21,10 +21,10 @@ All notable changes to this project will be documented in this file. - **MQTT LXC** - add Eclipse Mosquitto Package Repository - **Home Assistant Container LXC** - - change if ZFS filesystem is detected, automatic installation of static fuse-overlayfs is executed. + - change if ZFS filesystem is detected, execute automatic installation of static fuse-overlayfs - add script for easy Home Assistant update - **Home Assistant Container LXC (Podman)** - - change if ZFS filesystem is detected, automatic installation of static fuse-overlayfs is executed. + - change if ZFS filesystem is detected, execute automatic installation of static fuse-overlayfs - **Home Assistant OS VM** - change disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk - clean up From 9f222d0399218ae97d880c4ce0a0d97be8f84ab7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 00:45:21 -0500 Subject: [PATCH 0712/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b01dc9ba..35f13c7e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -31,5 +31,5 @@ All notable changes to this project will be documented in this file. - **Proxmox VE 7 Post Install** - new *No-Nag* method - **misc** - - new GUI script (ha-copy-data.sh) to copy data from a Home Assistant LXC to another Home Assistant LXC (info inside script) - - new GUI script (z2m-copy-data.sh) to copy data from a Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) + - new GUI script (ha-copy-data.sh) to copy data from one Home Assistant LXC to another Home Assistant LXC (info inside script) + - new GUI script (z2m-copy-data.sh) to copy data from one Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) From 4112cada27c5a033c156d3aca29be5fdb3055a99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 13:40:10 -0500 Subject: [PATCH 0713/6505] Update plex_container.sh --- ct/plex_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index cdd594dd..0a8817d4 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -73,7 +73,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/misc/intel-drivers.sh +#wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/misc/intel-drivers.sh load_module overlay while read -r line; do @@ -109,7 +109,7 @@ echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=ubuntu -OSVERSION=${OSTYPE}-20.04 +OSVERSION=${OSTYPE}-21.10 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || @@ -160,7 +160,7 @@ pct unmount $CTID && unset MOUNT echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 -pct push $CTID intel-drivers.sh /root/intel-drivers.sh -perms 755 +#pct push $CTID intel-drivers.sh /root/intel-drivers.sh -perms 755 pct exec $CTID /plex_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 77fa1226a458621b638059b455e19add92367fae Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 13:41:54 -0500 Subject: [PATCH 0714/6505] Update plex_setup.sh --- setup/plex_setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index 124b5df1..7c2347e0 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -37,7 +37,8 @@ echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" apt-get -qqy install \ curl \ sudo \ - gnupg &>/dev/null + gnupg \ + va-driver-all &>/dev/null /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri From ab04e8547fef70049a579659284bf7d31be2c051 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 13:45:49 -0500 Subject: [PATCH 0715/6505] Update plex_container.sh --- ct/plex_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index 0a8817d4..01b2398d 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/plex_setup.sh #wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/misc/intel-drivers.sh load_module overlay From e37c579b8432ec740d8e3f87803ae7223bf5d6a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 14:18:30 -0500 Subject: [PATCH 0716/6505] Update plex_container.sh --- ct/plex_container.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index 01b2398d..712aa44a 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -72,8 +72,8 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/plex_setup.sh -#wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/misc/intel-drivers.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh + load_module overlay while read -r line; do @@ -160,7 +160,6 @@ pct unmount $CTID && unset MOUNT echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 -#pct push $CTID intel-drivers.sh /root/intel-drivers.sh -perms 755 pct exec $CTID /plex_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 559c6506db0d71c58511330daf4f1233b3092f44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 14:26:00 -0500 Subject: [PATCH 0717/6505] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 492adee1..ee44621c 100644 --- a/README.md +++ b/README.md @@ -641,12 +641,6 @@ After the script completes, If you're dissatisfied with the default settings, cl **Plex Media Server Interface - IP:32400/web** -⚙️ **To Install Intel Drivers:** - -Run from the LXC console -```yaml -./intel-drivers.sh -``` ____________________________________________________________________________________________ From 8ad903d9227853afb795b2be7a28fa82773af53b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 14:38:36 -0500 Subject: [PATCH 0718/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 35f13c7e..fe9cf5c8 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,7 +2,17 @@ # Change Log All notable changes to this project will be documented in this file. - +## 2022-01-24 + +### Changed + +- **Plex Media Server LXC** + - better Hardware Acceleration Support + - `va-driver-all` is preinstalled + - now using Ubuntu 21.10 + + + ## Initial Catch up - 2022-01-23 ### Changed From bd9b66bac487de3e782e53307a91c8f833197ec6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 14:50:45 -0500 Subject: [PATCH 0719/6505] Delete intel-drivers.sh --- misc/intel-drivers.sh | 43 ------------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 misc/intel-drivers.sh diff --git a/misc/intel-drivers.sh b/misc/intel-drivers.sh deleted file mode 100644 index 7c8f6bb5..00000000 --- a/misc/intel-drivers.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will install Intel Drivers on your Plex Media Server LXC. - Do you want to Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -mkdir neo - -cd neo -wget https://github.com/intel/compute-runtime/releases/download/22.03.22192/intel-gmmlib_22.0.0_amd64.deb -wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.9933/intel-igc-core_1.0.9933_amd64.deb -wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.9933/intel-igc-opencl_1.0.9933_amd64.deb -wget https://github.com/intel/compute-runtime/releases/download/22.03.22192/intel-opencl-icd_22.03.22192_amd64.deb -wget https://github.com/intel/compute-runtime/releases/download/22.03.22192/intel-level-zero-gpu_1.2.22192_amd64.deb - -sudo dpkg -i *.deb - -echo -e "\e[1;33m Finished....Please Reboot the LXC to apply the changes \e[0m" From e4676da43b4d96a20befff372061114be670cb66 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:01:34 -0500 Subject: [PATCH 0720/6505] Create pms-copy-data.sh --- misc/pms-copy-data.sh | 115 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 misc/pms-copy-data.sh diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh new file mode 100644 index 00000000..42f41bfb --- /dev/null +++ b/misc/pms-copy-data.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +while true; do + read -p "Use to copy all data from one Plex Media Server LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Plex Media Server LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Plex Media Server LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Plex Media Server LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.01.24" 13 50 || exit +info "Plex Media Server Data from '$CTID_FROM' to '$CTID_TO'" + +msg "Mounting Container Disks..." +DATA_PATH=var/lib/plexmediaserver/Library/Application Support/Plex Media Server/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ + die "Plex Media Server directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ + die "Plex Media Server directories in '$CTID_TO' not found." + +#rm -rf ${CTID_TO_PATH}${DATA_PATH} +#mkdir ${CTID_TO_PATH}${DATA_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Plex Media Server Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from one Plex Media Server LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" From da3cc1313b658973331c5344ad2a632a8e3fba87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:19:19 -0500 Subject: [PATCH 0721/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index 42f41bfb..1f75689e 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -80,7 +80,10 @@ whiptail --defaultno --title "$TITLE" --yesno \ $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.24" 13 50 || exit info "Plex Media Server Data from '$CTID_FROM' to '$CTID_TO'" - +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi msg "Mounting Container Disks..." DATA_PATH=var/lib/plexmediaserver/Library/Application Support/Plex Media Server/ CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ From cdb69114345c957f432c78876d60dfb263ff83f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:27:30 -0500 Subject: [PATCH 0722/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index 1f75689e..538f59a7 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -96,7 +96,7 @@ CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ die "Plex Media Server directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} -#mkdir ${CTID_TO_PATH}${DATA_PATH} +mkdir ${CTID_TO_PATH}${DATA_PATH} msg "Copying Data Between Containers..." RSYNC_OPTIONS=( From 70c2e726f649fbf720adf400f238f493df241b95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:31:27 -0500 Subject: [PATCH 0723/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index 538f59a7..b3924284 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -86,6 +86,7 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then fi msg "Mounting Container Disks..." DATA_PATH=var/lib/plexmediaserver/Library/Application Support/Plex Media Server/ +mkdir ${CTID_TO_PATH}${DATA_PATH} CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ @@ -96,7 +97,7 @@ CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ die "Plex Media Server directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} -mkdir ${CTID_TO_PATH}${DATA_PATH} +#mkdir ${CTID_TO_PATH}${DATA_PATH} msg "Copying Data Between Containers..." RSYNC_OPTIONS=( From b6f17836b004921d29110c3d08aafddff920fb80 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:36:55 -0500 Subject: [PATCH 0724/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index b3924284..73ecd03c 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -80,13 +80,8 @@ whiptail --defaultno --title "$TITLE" --yesno \ $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.24" 13 50 || exit info "Plex Media Server Data from '$CTID_FROM' to '$CTID_TO'" -if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then - msg "Stopping '$CTID_TO'..." - pct stop $CTID_TO -fi msg "Mounting Container Disks..." DATA_PATH=var/lib/plexmediaserver/Library/Application Support/Plex Media Server/ -mkdir ${CTID_TO_PATH}${DATA_PATH} CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ @@ -97,7 +92,7 @@ CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ die "Plex Media Server directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} -#mkdir ${CTID_TO_PATH}${DATA_PATH} +mkdir ${CTID_TO_PATH}${DATA_PATH} msg "Copying Data Between Containers..." RSYNC_OPTIONS=( From 76730d99b51ce847ac9d6168fb4122510695c9f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:41:18 -0500 Subject: [PATCH 0725/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index 73ecd03c..d6b4e611 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -92,7 +92,7 @@ CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ die "Plex Media Server directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} -mkdir ${CTID_TO_PATH}${DATA_PATH} +#mkdir ${CTID_TO_PATH}${DATA_PATH} msg "Copying Data Between Containers..." RSYNC_OPTIONS=( From 9329cd920b25e13081efe7c7b26496211a3b2ce6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:47:34 -0500 Subject: [PATCH 0726/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index d6b4e611..b43fba0a 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -80,8 +80,12 @@ whiptail --defaultno --title "$TITLE" --yesno \ $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.24" 13 50 || exit info "Plex Media Server Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi msg "Mounting Container Disks..." -DATA_PATH=var/lib/plexmediaserver/Library/Application Support/Plex Media Server/ +DATA_PATH="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/" CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ From 62097ae7e3f20833f03321238fc05c86f6628c7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 15:52:01 -0500 Subject: [PATCH 0727/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index b43fba0a..c379e771 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -85,7 +85,7 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then pct stop $CTID_TO fi msg "Mounting Container Disks..." -DATA_PATH="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/" +DATA_PATH='/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/' CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ From 537f2c6d09dc7f03205a4f719c929b1849449733 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 16:04:15 -0500 Subject: [PATCH 0728/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index c379e771..4e1c66a6 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -85,7 +85,7 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then pct stop $CTID_TO fi msg "Mounting Container Disks..." -DATA_PATH='/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/' +DATA_PATH="/var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server/" CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ From a938d528c822f7bf94ffc0e0d9a75b5f1421cc32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 16:08:24 -0500 Subject: [PATCH 0729/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index 4e1c66a6..8d235642 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -85,7 +85,7 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then pct stop $CTID_TO fi msg "Mounting Container Disks..." -DATA_PATH="/var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server/" +DATA_PATH=/var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server/ CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ From f49f1fecfb204f6bf4cc2012723938822d91eca7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 16:33:33 -0500 Subject: [PATCH 0730/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index 8d235642..e948a12b 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -85,7 +85,7 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then pct stop $CTID_TO fi msg "Mounting Container Disks..." -DATA_PATH=/var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server/ +DATA_PATH=/var/lib/plexmediaserver/Library/ CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ From b868852fcd9a063766a11d808a2eeff1654607c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 17:15:07 -0500 Subject: [PATCH 0731/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index fe9cf5c8..a7818149 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,7 +10,8 @@ All notable changes to this project will be documented in this file. - better Hardware Acceleration Support - `va-driver-all` is preinstalled - now using Ubuntu 21.10 - +- **misc** + - new GUI script (pms-copy-data.sh) to copy data from one Plex Media Server LXC to another Plex Media Server LXC (info inside script) ## Initial Catch up - 2022-01-23 From 542ba61d59cdf4415378835b442420374d01c5d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 17:16:48 -0500 Subject: [PATCH 0732/6505] Update pms-copy-data.sh --- misc/pms-copy-data.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index e948a12b..ffa2340f 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Use to copy all data from one Plex Media Server LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" while true; do read -p "Use to copy all data from one Plex Media Server LXC to another. Proceed(y/n)?" yn case $yn in From 334f1acf2e8ee24cce93c5d26443be7b5a3dfbe4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 19:49:22 -0500 Subject: [PATCH 0733/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ee44621c..3f6fa619 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Select a Proxmox Helper Below

+

Select a Proxmox Helper Below

From fb44e3fc9a98ed9204a94788b0876329a49aae68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 19:52:11 -0500 Subject: [PATCH 0734/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f6fa619..ee44621c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Select a Proxmox Helper Below

+

Select a Proxmox Helper Below

From 809d218ed2f97702a406cfc3585ab2d71067c0ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 20:01:21 -0500 Subject: [PATCH 0735/6505] Update _config.yml --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 6979f9d8..6b5c8c32 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-hacker +theme: jekyll-theme-dark-poole title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From 64e40ecc6d7a4711a05f9652596b3151f12d41f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 20:03:14 -0500 Subject: [PATCH 0736/6505] Update _config.yml --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 6b5c8c32..6979f9d8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-dark-poole +theme: jekyll-theme-hacker title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From 99b47dc6dd021715bd02601bec16fd28794f7f64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 20:06:23 -0500 Subject: [PATCH 0737/6505] Set theme jekyll-theme-midnight --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 6979f9d8..ad51bf59 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-hacker +theme: jekyll-theme-midnight title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From ed46f00486d01fd2b031466186408f0fbbf47ea1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 20:09:06 -0500 Subject: [PATCH 0738/6505] Set theme jekyll-theme-hacker --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index ad51bf59..6979f9d8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,4 @@ -theme: jekyll-theme-midnight +theme: jekyll-theme-hacker title: Proxmox Helper Scripts description: Proxmox Scripts For Home Automation markdown: kramdown From e6bda52d592d82be7a1744ed62960ed0d1c823a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 20:20:48 -0500 Subject: [PATCH 0739/6505] Update plex_setup.sh --- setup/plex_setup.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index 7c2347e0..f48230c7 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -38,7 +38,9 @@ apt-get -qqy install \ curl \ sudo \ gnupg \ - va-driver-all &>/dev/null + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri From 4ebef31f2aec1534c25da0e7c82c4a53e2d0524c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 20:36:24 -0500 Subject: [PATCH 0740/6505] Update plex_setup.sh --- setup/plex_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index f48230c7..f7bd0e76 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -69,4 +69,4 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /plex_setup.sh /plexmediaserver_1.25.3.5409-f11334058_amd64.deb /var/{cache,log}/* /var/lib/apt/lists/* From e52540e11178ffc997cfb973a48feaa3976d8e99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 21:58:04 -0500 Subject: [PATCH 0741/6505] Update README.md --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ee44621c..68fadff3 100644 --- a/README.md +++ b/README.md @@ -625,11 +625,11 @@ ________________________________________________________________________________
🔸Plex Media Server LXC - +

Plex Media Server LXC

- +

With Hardware Acceleration Support

To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox web shell. ```yaml @@ -641,6 +641,12 @@ After the script completes, If you're dissatisfied with the default settings, cl **Plex Media Server Interface - IP:32400/web** +⚙️ **To Update Plex Media Server:** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` ____________________________________________________________________________________________ From af5afc8a7b5b6d55c70bbf1b2c5bd19ed6734394 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jan 2022 22:05:57 -0500 Subject: [PATCH 0742/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 68fadff3..8dec1f5c 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ ________________________________________________________________________________ @home-assistant

Proxmox Podman Home Assistant Container LXC

- +

With ZFS Filesystem Support

To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) @@ -136,7 +136,7 @@ ________________________________________________________________________________ @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

Proxmox Home Assistant Container LXC

- +

With ZFS Filesystem Support

To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. ```yaml From 076a8a7b12a75bc19950f333a6fb1d3fca3de034 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 09:23:23 -0500 Subject: [PATCH 0743/6505] Update ha-copy-data.sh --- misc/ha-copy-data.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index 9b41cac3..dfc67d12 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -83,7 +83,10 @@ whiptail --defaultno --title "$TITLE" --yesno \ $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.23" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" - +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi msg "Mounting Container Disks..." DOCKER_PATH=/var/lib/docker/volumes/hass_config/ CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ From 2450e41b37b3a0b760f40dea0ffdd9ade6400695 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 09:23:49 -0500 Subject: [PATCH 0744/6505] Update z2m-copy-data.sh --- misc/z2m-copy-data.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh index a2320f95..a698ef35 100644 --- a/misc/z2m-copy-data.sh +++ b/misc/z2m-copy-data.sh @@ -83,7 +83,10 @@ whiptail --defaultno --title "$TITLE" --yesno \ $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.23" 13 50 || exit info "Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'" - +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi msg "Mounting Container Disks..." DATA_PATH=/opt/zigbee2mqtt/data/ CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ From fb1b4d9bf4e6c4481d91f3515249ee50bda7794d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 10:42:39 -0500 Subject: [PATCH 0745/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8dec1f5c..33ce5a51 100644 --- a/README.md +++ b/README.md @@ -710,7 +710,7 @@ ________________________________________________________________________________

Webmin System Administration

-To Install [Webmin System Administration](https://www.webmin.com/index.html), run the following in a LXC console. +To Install Webmin System Administration, run the following in a LXC console. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From 762083dbecccb8b4d92560ebc98046623a7b4fda Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 11:29:13 -0500 Subject: [PATCH 0746/6505] Update webmin.sh --- misc/webmin.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/webmin.sh b/misc/webmin.sh index 0eac337b..ea8f9320 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -18,6 +18,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" dpkg --install webmin_1.984_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null +rm -rf /webmin_1.984_all.deb echo -e "Install Complete, Now Go To https:// IP:10000" From 6b3710f5e7696e3a5eea2d09dcb6330be335facd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 11:41:36 -0500 Subject: [PATCH 0747/6505] Update webmin.sh --- misc/webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index ea8f9320..4b1d5fcd 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -18,7 +18,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" dpkg --install webmin_1.984_all.deb &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /webmin_1.984_all.deb +rm -rf /root/webmin_1.984_all.deb echo -e "Install Complete, Now Go To https:// IP:10000" From 41a31bd5b890aa55196088c703e514f9fc9ae806 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 15:58:53 -0500 Subject: [PATCH 0748/6505] Create place-holder --- misc/images/place-holder | 1 + 1 file changed, 1 insertion(+) create mode 100644 misc/images/place-holder diff --git a/misc/images/place-holder b/misc/images/place-holder new file mode 100644 index 00000000..392e05b8 --- /dev/null +++ b/misc/images/place-holder @@ -0,0 +1 @@ +place-holder From 9f7ac6914eb4a99f6db4f25c2660ae3685e8db3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 16:01:16 -0500 Subject: [PATCH 0749/6505] Add files via upload --- misc/images/file-manager.png | Bin 0 -> 160849 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/file-manager.png diff --git a/misc/images/file-manager.png b/misc/images/file-manager.png new file mode 100644 index 0000000000000000000000000000000000000000..4acbe6df48995fcdf9b2fdf1d44cb00fbe799be0 GIT binary patch literal 160849 zcmZ_0by!qg+y5=yB0aQ#2uKamA|R5|NOz2McY~C~3?L#Yp&%gANH+rvA}vb8(A^!w z@NT`Y=Xsy&K91i%%yH~JvtzCETxWbgi&#x{MG`_f!aH~Fki1ZmdwJ&$7UIqwOlEvs z;7IjE&pY4)!}F!$^E>5344ZfE+`scePDaPiY$qGX&vYWCPFg_F!0z63stj%htyNsM z*nsm-O52x(Tx#w=eWua&MYHyTQ5K9~LBV{dD&EwdfdgseyNXAB;epnsms<|IQudUa zStR@O>sdFuwP({J$;%YeAMKU!CnqOa*?7t7>U?Bh&MWbKE-1ipPcCHP=BB8tt7D^$ zsxu|v#9;r3{r)w%CZ_T;0?x1y{K+q1rY3pr9h}4qw zD{yl15iB~PHudxWe}O+=dLw~Bg^-<$08ZYmBV7IjDP!mQ_gxm%Ehh1o*Vb%+2mBtQ z6~}~jvK4JP+XAlH)GHr#I8rtK?th=@?@v1p9**EbX%M`;Wic=i^mmDVUTFpoGaO27j`}enU>U@d`;{@|9iSBQ&;=(e*2vsc6LS*4>z}GCMFCGj;pjf%~p+^7FAC_NaCDsOT@OuR}FjP^@c% z*%4ULcb7%mZz8Z`s#jiZ!Y4cDF%HL;lCo2Hsh1E41w%JCcOMzKZn2tL3{e*oMK?G6 zpx|KlvmM$^W);;!LP*ncJ%71Dp<@I4lM)A>{Wv$x6Y^WnKOBW z6jFYHPf{8Ml>L``@?q++!-9i?4(42M@lYt#1MttoPhiCsaZN8 zV~>5ix&In(e*%LP@WV&?`udSkQF$$;3_a{UcJ}ru7Mi14NngHxRj|>c<_v!$OLrGO z*)cjlbT=$4e_?$ePoc!c?o03POcW&SO5)Rn0;B6-`59D%!+o!GGyva|@F$%3aVN|5L}xVSKV&8uMmrb2-e zqbo2QX{7cy7A-!vP+EihVqOaob)bDnDh^ri)#HMx6$E) z!1z*HDzqKjo0Svb=NH3$?PdrAe}$Z|0@vh;yF(+L&&sA{rWN+{=S%3<4|)oJ++l)B^67{LqAZv^a(tN7nw{O|1GI|R)!h7jT1tku+2-0_LS`o2x7eV%t_dV_fh^dy zU>)49j~GbQ1sNYm$N`bcJ3&0ED!09T3a6yS0)^6aK%^axoWA)R6AQ=>P7a>Qt%!;L zVCCiQTGH^X)JZVn2OjE8>K*wcC={C1dq7<3k_E-V#aXPQ)v&a8be4anc`wcdDWbeV zQp*0is9y9@e?MM8VEcI$WB&8!ns3u==P4XPM13>#RI95Bhc7K>T_@(+iGaCa3%p(PXKcsvMtdV1>;s^guqp*KzL9zqXX(r!9`wsT{!gE@il|KW{R zlzSOj$Fzl@xRi`26>XRUm`}^{DTp$@UpA`BJ?rGrpV{QY$XNrsFZqe@cJ}vEFzxL% z1g+9>vc{{Gl{u$ViZVf|`R*l68!~8{uhURk^pEd?By5POd5vDT-!AiNj_?_YF$;`p z`7M|E0ulU`lRM*tu#m{oDvkN;`g+lMzh&q5BP3NHKCb&(T-6jCfJ2#FW|a`=h-g*n zn}_4OR&-oK)4)<9xW{Wl2#MPu z($!TegBH8aR)Xa>xItIR{9XP1L|k0O7Z%4NVo#pT{w5oiJ{JlK4su&oAotmytAP9Y zk?59{k#D5DCWMUPMiWAaC=tJZ|MvJrjwh%Oqo@C{u($V6vftC4_B5SOYmP#CY4%pm zm){KH@U;XoFLHiU3h~5;s4EjE<@b4iOv)#rDA-HIl%2;~ba9d%ZB1CE6C@B6(V#*g z-u>JLmVinh%%H?$#^LkQZ{H}gva=VLmg2PXG2OQHsDJeLukKSIdg0?kcYAtzzLb<; zwP)k{T6dinNN`7h&8qFl=C3UTJv@#^<|sZO6NktuE<^SPtp@hP7V#CDq|R+xT^iV6 zJtVV3cSEm`6I#aR$es)dJDvMXQy2IC z10a1kh}aLIx2L7O=%sf>vWL(ztdO=}Q?(tI?XyZQ7rt0ZXHI6mogmfJ)O>A@9(G;L z_iq1bK?Dg=>Uu6qCKXTvc5-r%lL^6ap_vycjwL4>?kAGz>{L=$-}Bg?tb%Bn>nFAZ z9Xl1SV_WWJi37)F{G;6IH{+{L>-Ve&O%}r7HFNf!QE_*RC4BUoCbJhm;Rz*KnehxIAuulf_fO2}Q{h_uSx1fs4Ol@GruiV`{oWP+SY_||C zGsCd1=tS0Kn?h7J(FK3|3E9qUEj@9am}JP;n0bn#p#@YFlyNs-Ge;_zu23xln?|38 zk}73k;S<~U{^9+GH~Y8pL~D?rpJT1=02u_x$|~=*h{g6o3J+J?3V&*TLDtC!%{N`^p`&*f1(YFr(~5 zt_0eE*Jb z=sY+ukV;Cyfwyy~{ITFInu%B&SHXNDQx+8c<_-LJ4-Qbe{7gNlbo19FbfHnwC8l7i z8?8JVO4%Jx^&txHgsX}+Y01baDJySP@*Ly{RI>?^E$o zAXJQN7hQ6OC8@oJ^E`TtsXnC6$@hplY-aWs&r(feV{!js7H-Mo{l)rUKmx$R(&^^o zt{~Ityt2A_&ILoxok&%G^OUHg9YZ@*1|={vLr=HI7i^_Nclj&__66k+$224pe*Acp zfv5SM-vq3&26+EYv!hIlDJYbokIVj}b^7t^(6)2SXzw&+szwNkJxe^$3^RBXQ`K?+ zSz&r}#|i>*JDDU958!9DV)&D_ua(Ut<>X-aii$ox{zYNu>?rS}&R1PsO~$|wNjp|# zc|7h63{{FaLY97<#qJkpmYBct{66K(!1if78tdfkvhPM82a~+TvpecJPuPwV`;wP{ zDuCN%-D`KP-hB;bU#)mOdr8Fk=n*x|`SXCa))NhJ%f>e*52A^ettt1CG z`-H1=>6~xe?vLbx*RFZ)-@lh!*xlb;9+=n3cQ|cLc}7Mu4YC{%_x2jVj*L!3pd}>) zf^9IfOikQT8@5$Yn57j3VLy*B0dVSKN3a;n_q2-T1%m)heMrCS{nH+2Yl3X z7!qM0?7tM3i#!<~QdJ{EpxPo6nYa;oMLGT$cxU@EYh@pP7Q!X23MK^Xc;V?I(&s;H zHQk!;8P~Z`aJv{9HkP(|M4b+YqIlabQY!Kfd|0FoW7EKadYF7>O)%u`;_y-D^`%BA zto8aFa*9Rz-C^fE^y1NT+2;paiEYu6f#>~Og3^V(8d=@FW+=|Bt?h%k{abv0f1Hcm zid*K#uGWjKq*C3(Ay#)_7+LtWloK3{)z z42Ct4yHv3AKv(GAM_`-$41z%6ko-qw6zInI6bH)vW zAoL`3IREo!)o%300obkLWFLLd9&weuQ*nC=EV}OqPB>tOzHN$3flIV7Lc&yDsyE$% zP@wTL>^r~V%V#s-uGX(#{#?h42aPI1F2-`?rdZ9RdT$q(b3<_a#l>Qo&^^v!@&e7vC;U= z)^q7@S$Zb97caQxgRV_m&W>|q3}yls?n_<4J-_$&cNx37!udna9@Xtn#yiGN97YY_ zNK{vQ9;_L=F30vV%WG>3O5OHUESiE7GtMmPK^mEX0J~ItXG?a#)RgBXB*Wc3eQ;c<7+57je2C^k+>RsmEbyczD=S8y1 zdwZ!8mz%fqB^RYng0duh??Mo;u%c*=moHx~EN#V2rrVh`_-RE7mHmFv*JoA5B;mtQ zZqkU!Y|h-!)WFIuLDVTDgHK3^nDVq02%Uervc9eo`BD*2QBG0uMUIcp*-LZ6jX34) z%0C?yi|4bHsyTFtv$IZF65iyCkX{xxVH^k>>sxT3RJmDeWOsjBz?^gueDXbqN(Im# z`zVc>bs;A&|6|GCD4@yD_%yX!nH+TA*qigp!^1N$`>78#qNY^2%~#zy&-&_D#y4`d z&%nAB@bvN`|FOHI-^G`hi8EfQ9D`~}jXN^? zlLwyad1r_{C-{oseQJtt!%J-)K|)_8w@QPbja2rlajOmTEG>{Ug9>xMJz55-080G| z)3kG;TmPM;XiG<1?xk#^{u6Z~;)Ap(iy{d{1%WSV>@~r zD0Uny|UAq*w7VuCShTYcDc{h9tK!yBsKVjcUbO z8{~?y{zj4=5-G4P>0=V<2Y)=&k?BppVp?T8;o~mt;^Oq&$VfStwOtx2fV3x-KKg7h z!L_n&w^J=3Ri0c0PbbcUa9I4_s$E*lOz|he2+LoI3|sk3FXmwvirg1>BuC6bPU3Gb z2+`NJ6_#rQo7K7LfzV?jmwv@9dgPUc(~VnlR{rGV2xp*ACLR4@-*6ChC~EF@AyE2) z|3T4btGOoOYH}2i^k5(_*Cq~YZ!f4{jy;xp>N-+Jqz|VeRd?4I0{@^OPre$bj1}-fGfDHh1a$Y)MEk0VE`s zDb$OtrL}d>h-YQR^*GhpYOvK9)DCMwVeU+~k|uNXS{}l2E_xi>6)Zls<1Yi9<0aH3 z)NiwAT}#Ix+%$07v>0NQSLLwkF;&;|3{vZTTD_riZetWf0>AiP1!?dQu2Qrdc%qTn z{dgTZVQ8sUg+IOVMTtQ&fWdayynE|6_dR;XcKC5=@=*iHsG#6O;;6%l5XYL@+j)h!`7&&t+}D6v@mgwj#wR{yF~)_u&@A1Y z&!^fJx0k(7Wrg*~uBGsMVRP;=fztL9b8l9n-8?+@YL~BOAOrN-*`@~zvh=ILHJ3MP ztO@aI2zwG(Sytf*{;Ei=GTaN>vod4vU(R}SQjwBQ$@M(cRj86%dSDj4{<8c z2Z3TfOP_cpcBm1xvux+a=kh59ML;9ktsN_ZX?z`J5;}$^Z)|KK?VH5Q%wZ z6vd^f7*F^f!n3oxyAn0p4$grMl&Zq+GRNmFv63N#?slu?frs8iH{)exF(hT?@TIQw zC37qTe|!lbff9jaGkV-G{femi`b6U7@l@)a$tK#QQGs*@X8!BzuO(lBv|@$jXCP33 zH;7_7cML?@H-tzQ>z4?eH~jRzh$FM5^QA@v;~=+y2*`h&tnu`r3={I&0xB0F@_;FR z0FvIcUnGo;{4v}fpWS>8@0~GzI()_`#!1wAqHxW|raLjdRFEi@2!~sdA)IKi9Noiw zkH;Bz$-ZpUAN=MIWy;7fR3L&VoS~Q2(TsSc%$K9(mB1a!bH&z{TYybahJlzUEi8d?@zf*RrnY{njzt zXKm<6ftjt%&8SmS$w$U)^{)Qy=Fk9J9|YlY6f~9f@e{fnvw7AwL09V-rI15N?%T0@ zposNbGzw4biTLTPFkn;!Hxunw;!kHK53~2tcc#R}FMe^DBfe7gA2K7a_=e0IUhjvj ze^?5?zCxlCHohxO<#%tu+ApROR!(HGH=V5TO2)C_%5eK{EP zUZ>&9m*Iz1%UT9HoUA;Lo*0=(l$$ocp%pA-lVp=EOHoY=$@xowo$-!r4d_(`@1^I)hRkJn^L!Lg$@J4_CBSAK&94T+Y<2?hIKcWEo z4T>$-9J2hTC4H$#or*?m+oK?d2ZNatbxA(+4I-geZs^;4WWgT>BCq(uU3(h*wN_ra z!-D|CD&5EeBp8DH5F{qobo^ zl$b)hyOH0RPUN;U{-gnmeZ8VT&SRF6$+Ef98{K9ML3lXv8sKHuPqf z^%{%gyiG6nQ-j;R3jQ>C7K~;|Z-939QetR;DQ0F;8A~eRTwbF*%*=zd)FfLah^aq#L*qq0{E{6Mc z!h6WqS5X<-VjdR@mE;Jy0skjh!J}jA^hk70i$=&h4$^hH?l@z=TNG^OoMi=2R z`JZqRDAc*`s~>(@3~CG9Qmdq6gJsYlleGi{48Hk9fTS8%-;UmL{m_1w+?~?oSsK^; z$U+UC&RoJDy!fqpc(cU(x==0_$gR1gP7f0ot2lDW%zc`WAxq25U9;lfR@qLcD?-?q z8*kBvi3bQ{S14!U#?@kC2xe2@%>l4_iMAh0PKBb9Z?9PD_NUohR5c_o8ya*ak5SMI zq%>NA^<`+KKT*il7U}9$O^uiPvXuK)4R*`MaJCgV=en~F^i916JCRA!=&K?PHXq1s zzj85(jFF1hR&bt=hw}EO+cDO|N9dfwQ@5?MQi-SIX*H|cFHW+_EKb#o$2jZ5xis$m zH~KXqp3-g(4%Mod#GUn^XVB|XJA0eAyi(}`0s??wMV zArL&B0^D?8y1|8{+*GA|F~9fOr~YJaavSyD53a4;#-&e+_NXCz&(#4%utdM?y~rr0 z3fYfyS6fTf(QDK*kwq%h#&?ujYqT{yhk3ijZ8{QmiXRTPj>*+ zDcV9~{GkG3o%Levp?gs@>)aCA_nq9kw|l*BqDoYJiz^SW2@D%Z zw#DH$uhU7Ov8q|kAulT;etep*9~y@!wBa#sQc4iLYHx34NwplpSz6|R_`p?Tp`AhY zTvFawr3_QQl6%rQOb_t6y8Jt8Ttai&``dYC>ZjL1Y93BwyEF3S5dh3U1$3>yYiZ6Z z4z_zTAAae$BcA!zKeqW4${+Kgrt|B-K1;r$=OJ1n6fK?MSgAG;t>-)>2>JpIt5#N4 zVIQH{R&Ar)?v%-w1KG~D5STMFPbI5D1!nph2agJ%_tb{@jC4jGy3FB`G9^XXDHMb( zM%f;W-G->0gFXl?omx3Qw1@+X3_$ctO?YuLA&R)eDVf8LIy%J9WxL!rI?PlvL}b1C ziYa=5I*V^>+rfP~VCf^{ME9jLytJ|MTYcBm7)Six5<1*fUQU5UR6+%o`l`QiJH6`Z z1X^9F$0tT?OeF&_s*K~ADVCrUkdTPbLL-eCyz?gTZB7m$ULf6$%lX_x$7&G$T%caS zC-KOtl)R>O8^dt02!2R;w?Ju#u_L{aQRcN7LGzeLymIic>@z`N5yPos!FYl)}xLGJUQP2eYuen1Y+R+mEpMu5{13%BqG0Z&J!!s@R zAE4CuzQE-0FqJE?*g0MQ!}~e$j=TLLmD?54Kp)uR!9B1pD4Bq!1z%l+uRSO%q@o{qAdt-8{aKtcgG zT}`*QJKt8_V@>l^xs8(X4am4ztY(cs?Z37POlA;&QVG5HwNH zj%Sfo#VA!WMB$oqL&$x&-+gNmInalf34K86Js@FT0{8p4!m}?0$aoVR|BKdi9Nh1S z{hXUy(ZD&jH8u7_nj@U@$ET6#IfwDXZxC#Pc=OPa{nVu6H{X} z$quJ8CB{;4C_PPvoqQ1U*zubP4vf%EU(3fM*S?|9w49aBAJYE<*0Xe)j-d@N;ew56Q%GP!iDi=5>hN)$V?PKn8X9H< zGeKY7Sy|pDGM+hm%^%F(M0?aydnWr^LVjy|UxDJbJP@XaU6=;Qk^ituY;XSPXiY{@ zRltYBz&+EsUz(13GQx6$l^0f=Jd&+Jg8)f`g{i4)Xg?mZg2p8!C8eaH%BW?4?kkmj z{6Cs}6WK@b*}*Hyn}BasizYv3CTLa*3jWH%{LIWc?^80$h%r69eHF`SAqtg@QXwIn z++4ILK1w@85)xfugl^uR^3L9BX~~}h=&?_J7FU#Pdt^SVzx^mR5vgw4Fyx|hT^>OAX{1pS0jN2k}h zxzb<1mP{`Tf`%Fe3-z6*6IE7kuT-6PZNHa*MR32G3GU$6w+N(kS5N%%}eg27n(E5UYZYi7!7c zScr*YL!G{GusA^!6-3e{?n$Fj_`8;ALM~?kp40=jU@-?idH{F*wrbZw2BJ&y>8+!p1 z%2=t$Q5ZM(HL$=;(43tmM3|EeYW)`s6ox_ev1f8(m^6hdC3t>+VX0__P2!%1 zsj+c0n6Jh3HS%`&R#sa(nQ$57G;&_Z37Bf8I@2O5{eLrVcc#xl^lUIw)4792{!qqp z7Z*vwWuPo>xw>)9Z)-D)s!AwJl7AL;_||o#;4~& z)NtP3oZj}VLf0)Px<=Kul%1U+y@b6a^*ux>-sxH`cUt9Uw&>`u$;ko-EOJD7c{x5U z6``?&F(nPnr<#_N`RTxQm&}^3=Wus!ZY&YWFBdXga)MO`m<(TJFxu?o=?S6Aqtny4 zG&Hu@7XhDIs_Cdwem{);!!ynNHWK)^Pg-FAd63%8BI#=!zw3+BbaPwF0iqv2ln;B6 zDDvOBy61c_NIu7XVM&~_GG2UwyYlWY$mrVUai+Zk22V1lt99wRz$aLCc21P>qjTF+ub=`rDqgRMD9l$9jOzHfcnnxy|0y6{m`NK_aYHDamx5IX?2(e-ABKUahn_^Doq zQKnJHf{%_*6%m6vlhf0N26*<~12P?bqZl&zC^tbt4cu}W(Djuc{Pz@XBaZw-s*?Zb zD=gtDCY?9>o{-1kYvRK!cM#6+$?j zmp4N$R4f_ut_;N&Z6yxIXD{es4eIJrSYG38Qk#jXZEP%{mC1h&$n>V&2N&tF4LM$A zvJXxtKsVP14=r3>qZgiqzSq_H)Ko}qf~xxVOMp5xdwy&U@W?bPw*sM0F-6?-;w9>v%uuZD=29p=?xB z+YOA_%yv?JYzUGNf701GN=8Ms`clcFgHuOOucNn@^z_u*&c)@qqcOdMqvOIp{e8aQ zRsv^73hFM@0GjyR-aZzkUfP{O%Nlg)QD0j{HL>%-khbz$m8{bM_N-D{;dOlc<_qpd zM1L2Flo`{PGS{~PODij!F27QK*K%@|RRX$d4+94Whmi1j(6b9ouju4tL5HtuGrp3P zr#~P62XpH{VT<`L)qN{0v=O8p#}yS7)zP0wKe-XEeU2M8yx-PH&e7uHQvRi^EX7lc zS6W~wj%aHuK+5$u`SvicyPBGs)nsLAx4)gN?8F_l@t-1|H4z#I+Dsy1`V+7^nSdNF zSP4Mf?QTN1Bmh5&{2CYF4j6V4?j{@@9VOi{5*Gdqpc_f^CnpE*e)l&u8R_Wi zzqrpA_sS^V*w{$ZP?x~hm-MpPQg@_xM&E45dexe>rje$xv_%Kg=kgjauX3YK9aXk$ zD9}V@VlUL9$Xr-Ob3i-&)v`6mQq z{N=uOG-HFt9DZN_F0CM3?#vTE2m;tO#84J|aaz~}C?ieQYS!3~h45FW&C&Ryrq z42E2b@HG*Vw`OJ7xX?R2U${!%ItVcF9Azf{$7u}c{-nRBKr?I1k7UK67DO7E={*Ng zw`2fO^KpO#re^M_IV%uC1gdN43RqNq3hK)D#>NcGv&MNT>GLBF z0(IpA#bu4M9pq60`AWC_YO@GVn*I4FI_IEm&A%ZTW`YS|qQ`#ffq2m&5--j{$ap2w z;%i0`S&y)$mml6tnZO%7c{ySF4U-lnqwq;;-IP^d%>B~|Chvm1#JA|+bn;3e%YiGo zUIcuuOFPD6^^q`pBax|gg856!r>b~`dd7dU2r&L17N;cv<0b94uD5oyK)Ra@;tLM; zh1FI+W;P-sxvXPO{uwDuTHagL75(78wt1h9<-qn7-?%BJkGrSEI_{ZfdX@8H87#O< zO#DsvnBI42Q8iHKelMoHsogYdo}{$g+1i@sVoD^TquZKkoPFU$dL5(qwW*;&xit5z zn@P|o&E}T(F~Vvf0E||-K5Gc|rjOvxAWxZ{>XE6w)J&gnh7VN}&`QcLH*1;s~w zOh7GZVnPh3b0xbNxst>pKW}9^sAdY$_9imP=<4bwu7cPeHv00r{G@DXYV0EmADEfx zHBOj@<%%%kTwVf_xnr8E={X#z7`2Pk6uneS8Q65SwIkktrne$k;v&nacR8i2{GDDG zQ)%xk11}ZFCt{9YT4Fu;0wNqN(dUDpx?>xH4q2IkHY|5$>wcF$@1nFs!J*7uWiVoQ z(bZzU7cVBFnk^44&UPBzJiI%TBJe7GZg8EDO|+2SgoxH`$)96muuMUA{7#@J*j_aC6~}@{xcVBBaMR>ZLt}b z^8H5(4xx|7Tx~G7laq5i-v=UU(o(|+Qqh~S&(~MnuQ7vvXVwCkcSj18X2s9M^Wk!2 z6$u@E!<~^gcuWBdhN5Gu>y-jYll9)orKy?&=c#}bf5Q`YEn&Cdf~RxWBubtNB``gS z5kID}*v8xMcko*8ZVK=Zv^;CUnXIz@riGVO0R6_E1OU8*x2VfL04&(6j77seH ztUB|a*&Lmo_FP4a{J{3=$J@^@E%oYvr|ZqslDgbGYz~-<07(X@2AcUMq*Q+U*4qPJ zcSn6+G;4PTR15ntTZ{2oe=*;!2QKqXv2RD*266-yA6^%!GxQcfX#%MH5k$*+1L+wf zd`-#8dslkj%7J%>wl@33f%h0Fe|6L&hXj`}wIdH@>6v@(@<|E#NV=x^S0Zf(Guhzj z$M>qOatAXd=@Sx$!~#~{YI)ve`^sa6g_=+l*J_ie;KH@

@rx<}dU>|GGY{H-uaiTeC6l?MsdEs_ZL^(Jpu3Y^oU z6jFA$F;!b%6k)h=I_??Z-hsLKkiz%3o3xd^3W$7Xw$8Z zE3ZAzLkoMyF5}RvT7!{5<#RPqJrR*DBnPKefnb&cbJzC6>3g0RAZhf8VD(EC%a+wv zHAWYsCuxfq;0a{kuE`UFCMte4Lmb5V*&zSrCT5QtItKym{-ApDuCk= zHmyrvk>A}xLTlbrl6f*Q2;MMPNY%p*4FIrTuo^9`BGN_ zu~__g4O)=CD_mngA07p4v7iy~Tp7X8(U}ciJ2u6nd!5}HoZFiO^pHfKqVVfn&>u~K zNT?JX5guOU*7s6JR}VhbLyLohBj&kskH5|@6I)_pJAQJQFR!vdXCteqw2?Qst2?y?hRhYd^|jIEij~N|2W$ZPYg>$i+qFIl2Wh1@q4I(Y<|CN5&Oe28Ejic-R1tK?-rjz)@{o*@hB_{0<@|5~-TJ+6 zXzv)G0@D2%f7yH6eQkiN)TkDB|K^x6!=k>f=6=YU>I1XJpZfw_fE}E%&8d}qeI$>f zo8I5qVZA1AwE){7g2Fpgo49v~ce*&1UKZQSX&y*E*zB3!U zF=;0xB*c1o#b;(&%29SUKQF~D9O%wHoUiy+gCvG&I{T{vX z(2kZU=#yC_m%(G#`IhbJz2Wg^Q350kVfhM{t6zovu9-tAFj|(ve!nz(rSrZ93T3Jp zsOANh-G@0LdpKl>Z|i)|LR{{?d*`B*tF@vH@~L}WZN{x%fzcbsGV0Lidp;C`^_Z3o zrig=MdDE5nv9QpnbWNYn{0}=JV1Gm@r=SS!jK~S!9(V27%a#BK&IhfmuPJ9`xRa6L zlQPFs^d?$P{lIe*lq7*5sPsPkY~R#7G+qm7NYKF@DB5Mc`PW2^pF?Y4;$?^er> zdzZ)hKJ~rV=F79b>Q(L@dGpd{5s{ZnG(`a_3Iq^7;;AV%mn+rC$i$vv+3W7?kfC=e z4cTcC+_oBhsc+`r5keeqzS=hrD0eJH9)7|~7jz8^s(gZX3I?o5U@cmS7h%Ilo!R&& zlk0ed4+5lnsY<%*^Ie&X4FT5FhKck*)gp}#0A6tSQ+eH4&e>`l_vsbMWNk1#HNWYb z{Af~d?2|kt5ItGg=k1B>SM#~x)LjKLGb`~|{u2}w?%ZsqTf2*^QJ2RwOWl2tFPz-% zMRi{I%NYb#!D<>R$pN0X)kSGEHba?nFF^ax;8~3^aS3gnbq@3nU%ysu&eiWY6l=LlU=jRowGRHh#ATIs=C##%Q+A#`nAHlY_w(c=YlSrY_toY(g*4;r?#mJ;H8;00kxG1HM}T zEGB1gTt9OL@VQ;z&{_d_`uOE!EQK`-d}@k-p2=UwB(L#2hxKH-wgjFuj5l}F__oG( z;_myDl)eVDx_3+Gl21_^%hhFj9c{sn+qnGFcuW&WrTsJzgSKXu4Dz+NS#CU;kOy0zQ>5nG}(i{7l-eoK5ymJ`sRiAfpl8KiQ(y>YGFWvhHE;4A=e z7SC}xR9-kBA*xzk)lEdp_JTGs&_`v(1G&_-Ijk~OXv*Gxz0&RiA{w`28-;e4zCwIR z02TnE$Yb+T;5<0r-#piujV$-r)xU6%_VAM%BS*uBBt1P1uKRc^Pd6#~lnHs0ahAea1^I;w5v`4~tvDfId@ zl@v)s8q2Pd=1qnG7QHw44owG0KF)hY-p?%V+}%ZzN{5E3W^*Q>qo252CuzYN$88JwSYiNAfwqQr(316o@{lN z$h;B{F929TjzKTc>~_1PhHwc9@%|juxVwaJL)&g_a>6*P@kJH^MuSmYQT315udrV z-O#g!4b8{c3PFL^1~NEOUHJ4y zS94Nr5Lh2iQ9FIf231F4W>M~oyO{P8^*mWmLokomhGpHgs&=}}T5U|DdnWG%LCI$O zF6Km$_ekZ9w)joO5>ra_mS;1@zW*55@k|;3xfJ3rzYw&EO}R#_5-ll9vV`CoWoEix z4!o!ZA(6w-RF`;cfK)n`?MZwo@81|yGfnESmFefgXli)E0C8l9oqqVYN?)J=>w$c; zPG>G>#>SaY#qAc#h`1MK6Co!S6Z`a7cfF;fK5>xW5J2W-9V>a+HuKa%SEEti`8!H4KlMCw#Hw10Alu8bb zU#R{M3qY*!SROQ-BcU;*N3C90r=+GP+ZMjKc z;{;INsyp}{Pz@H{o#XQ#oP zTs#}%Wi|VNi$n0Za78vuA_Rr~fP;fzCVkRCM^~3kl*2fI<@o4G&f_I{p?Z9DbXq<3 zlYS+&U0@;&%mDFQY8a|lDr4qSw;y7^DEw^$(u<`PN70*N|oeb0jYE-@2*MVRxu z5jKQWhLjor79%y|(YrK1cjWlh`Zvf7II!m#jZQe+MEOE4X|-*&Bdb1XG^HWw`}f-S zXYtk+T13Ui6 zRq_6Gr*!Ni@qbzgo?Z!r5KqnDPyYs!u80mLY6RBir%&XUSjEN~=Kz(0S27Sd*sEh1 zRIy6Za|7h~pT6|FaRL?m(~&bke&G~vb(I68xTkr|=JXYRl(tF-AbnQbHUs)ohjib6 zKZ4;sA8gvwvUD=NDK4vG1x}WI5v=9QmNHT22-XN*4Ex+W*T`?fj2Ij z8pQI;%R@$vh4tSgB;2)ga7bNFEoGUSypxcSU}tAn^Jb0s1^orK^r~e9k@ujT@YwOd zDAm4QME%!k3s-=++W+zOhsUpRy5pVtP8*M)aBtWG%cckKtA=~vBJjhA`MZhC%2I_{ zfluF`{;dArM)Q?K^dw4ng#7OTQ-X`hnoqUyRr!M-l#O7<<=U1`^C2U%(F7QtM9Y@p zG9|_TR}2L<$36hYjjej7c61I9)5Zn+TG20EGJi~lI1|09nATWkM0 z4HQho|E)Z_aXfsBi~RWsyhQM&$FG|d1Lt2q2Z#STjP2Vda$^o`=H0gYFZGlyt>Z1h za$(^^@oGf+GNzwMc6_{AFPZ4z;GhR{XfK;Br&Yj@UN?sLV#Q^!G#auM%;r03VBQbx zi8jx5`2Prd%c!`TZEZBTyEPiz-5r8!fDl}QyA#}lLjwVVyF+k-2bad(-Q9u&hkPq% zpZ)HAe%x{Y^?=dUOKR1c^RbHl*9H0?&iL=o*20dmf>-)$Sb%mktfyxMa6f4r&o88X z-x*L5_wo|Bx^kJCpO2D`PTAfLy>?l2k+Ui#Y0dt;12Nc64cKAOXc1VV%#V@Bl@b;0 z_;qzFv0teNS;8}8vE`-7?~yRWaW)84STr;m^6{HZ{*=cVxQ$S@WuPIS-813eQH0aJDN z^hj7pNJuWgytD|k0EA;uR#v;2N;KD>_Z$v2$k&!pmcca3^ALEJ%F5h^^dX}pUQHw7 zAw4!OE~wia4nw51a$^VM)z#UMMu*Vlm6f~Zz?tP~Xg#5yKjms;^>MFmFW))5e;;>u zMZ{^ezLr>7NeYQ2MgZ7AGfRv7sw#AjodGHl9u3HoQE_0G8eno4mn^Z&oXG4Z?)$ac zu+T&pV!D8WVaUZukBEkbM$f`H_ec~F+<>hSRxmL^^m{3|1RGf%dc^5^x`OL&St1sKKKmf`A|ukXPIYFR-+f zDs0Y(jZ@uIJO*Ej1L<8@z#t?f92^;Y=j6n$ufK)~0@33*>83H*?EnC$vl>>9Y@7^$ z|IE(uk<-$`OG}5!y;s1Ft_8H8K$p0yi)@Xdq5`~f@XXE4ljkjUa|{uk*i~Y3!dxvU zQkktr8Ndux$(8y@0Ew=8v%I)G3=;A_!~}%ct@UAFJoTkuKO`nzxSa7JX4PV0@%tRl z8c2i(++AJue6ya}z0mjMWIp}nl`81hiZ};k1q9#>L#` z*1^k9ErtIEr`q78$*^sryBlzW$P7JwuReRr%;a!o#=u3xP-ZK%yu5k18{&mR&@;3| zNHCt=fA$4>DDH&-pN#cl9_3(SXj@*>f>t*@LzxuWyZv7*#{aAsVQ7D!6aoSQtbAkR z0<{nN)cBt~FjN5TBn)8C2RwP$3wznjb+{9XDJ%n1RN?))z7NyVU@|V5)e;6@)=#Y= z5fO-3i(Xz{sl4`r4y(B)3g<(!hKrZR`rs7^YrkfNM<)s znL$X}c@S;!nlD`k>hdu)8Q2*uOH388%?K)z?A4rVtt$S(AK>+9}L$TSZ>yU55Q<&F&&X zN>v7_=k}>&(Be=dFW?k9?&M7d@9y6I5Nz!B<6AsTSbOhQWf7Xr%^a@Exr=Fwq=iiHaJ^JY{@4zsq_ zW5OXC2T~}zCGPBbxhmjnN`{9EPQ9#cc0MD54D?4Tx=NZ-;WO(}YwE{#A0Z(%yBuND z_VrU7J-SWqbSr^| zQer{m2GiYP=?hXKZDhk&XqVB&T7JLnkX=P4n+Nl1lJ42Emi}Wk4oIg zS64v96~nVmSV~G$JIr8fkSy*)oL;f=oNr2CK9ii1frfKOKvBy!y6`*G%?s$T*LQ z>bASHywBl}T!DMwbZ}T}gY&@fASCAD;Yk(dF_aP%AtfOpjZgnZy|>ZorH)TE#74z} zHdR~88OC%NYHEgxIO2C=HTIuU$Ck>7*LXCNouwJK+0CtCJ3;P5`Qyj>W>>=&U&17f z`sq~`K?ZUFgy?_N^ZbcPNNAl3;zL41i{TVdmVXb)Y`LcXN>FK{gga9|2&7+;i?My` zJ5MMYae6+)8cpMS>vMOSP*tgy6;<2Ps|fuyRLEjm0!P1<4iZIvRu}_-FpIW zU}Y(c>w?LIm+mn@SqUsQUxw6+2SpE_+k^oW25(8HsgEWdI_*IvlUwJ@CL!}snBY~r zc%E{QRQbhC8kh6ysm@TqUOLa>PghG>S8a?|r5|I7#Y$KstS90qKJPX0Au5^lBv#Hb z5#YWSE=x1V+p8p|e&SH5XL`i`){_$|4rI+rgXn;c-}v*w_qh?G$nUf~Jfvi$Bcpjj zcZYTc`j<&aae_w(*i6o!;Y@V)ghC}=e+9vq`0;7?J)BcCokyMmwMM-6G_*3-1weoR z_D<@JW>#~hEM8Jz(&IuYd+c4}&<^9H>u#5fDRs5XlwcC!$M%(LZHl7+#mlh52)l@J zF|*yI#?RWkzf|mSkCc;K>CHk~B3;NrpL}8=#*u=(cJ5|p%VC|_1G3#loen-rb41r` zp%71XiPo36oVV{u#bRZ1JfWZ5FM^`WQ7lF?BMW3>5m9dC{T-^bi;if|2`~e{*0Ae$ zdTR*7dx{Vk7muYz7M?_wmRA!@M0P;4p@)0K%>PHxSMwg)0tb@$3??QBDm^@OKM~i{ z3)izWHH85H9J(sEb{bu>WM-YHoq^b4ST=I2yHZk#>EG?NR87p;5Uxb9U z3SQ=F*W0COn=Vv+ic@y%WbxT6FdYEG2ZFROhMW1CTOR=z$HYfECYljY1p9isDFT`Q zDM#%$&d#t$cwF4wrk?>bKBf>K9F>Q-kUV2!lb~Yl zV)o+Pw>*q;%i>!yTL*`S)YW+i^Hu#n9Xlcs-g;{fv#_zjR3710n;2(_8uXF3tESS0 zUMB2~^t&iF-UQ|qrEVvhBwvuUHeY)%57hAVVX}j(MsUY)FK`p|VL@WX(8wq#MPvHZ zyBpRV7UK2yM_gZXa_9nVZS17n++q+7krnrq<5g_gPUM3`sVLq_F;+e>|M;FS!Ce1L ze4-!&_@hPN>XY0X&Cm{cbm#YPD;qg&oU?-O&X>_t*i@8q(gJ6{-M(Dt-vFtG;!akj zp6p){0)Uee_i%THRNj1U_VHHuCH*NNps=JcLhB1W4++$TseS(cR(nClGF^5(sU-Zy zJB4Z6N$=_pHPh14B6HQ=VLP{0M^tByPPL9~vSAP5^J=%*5xyr8Vyp_!Bymw;peqK1 z2teAK8Z0MWEZAo3X(CgU2B#UY{@u`n2VzOXqlS@}HsnrXU^mi5NeRZYa0o7j5=%Bm z)6@akj76|F`5dW@u@b;gT+J|jF-b5)`;1gyLWl%W3mw&sX1YU~{e7oGFf)CeH)BV!+K6V^9(ah#K*F1VE z5rg5}(9D-XkK-O1MZmrk^Ze{vq2EBX(g?uWqv!ZL;bdO0mhZC@+Goq>D{&k{G#x%| zW}g?+V!gB@nR-7@t{jY(;as6@QbH3*|8=dh6y5y?R@kRD(lj28a&=(|ild*;_BZH%EWZDq$|NoJ$_VdLMKn!*ccJ0OVJ!sn-U_dNxIg^$Vay5%_Lm)cW&Tuo_} zFys6DI#w^N7lVg|Q>}Q4ioVT%YMtfe5QG1--Hw{scR@b3FS zH$p9@KIjV7^_8AoPw$*0(ZZ4Lya~4fw+~3E*fv~y@T8Nui;9iKJ7K;6S5mZ=kaLFa#%U*tbgkNp;SH_<{oRhe8kYf&yCa%9#e@@_gT3cB`i07E9 z6T6o&$@fHIpXT+7cf&nF9L%0}dy^ z1CrMM55@%|1aPl7u>ZW~tt4QMLC5;19r+*FirwX}zP-h-n&m?3@4pfLzy7UdTw(eT z(Dm=15QqMzsgZo=Rrsq@yx}jNDB*+4qO8yrg;?6Z7$vBlk^g^@KqYEG3@Byf-QtF= zYHXMF^1TuW@cZ|uU8*>n@n8#iUg3JRLuG*+mYbi{DQ+9B z$ZKDQ|K~7`JaKAVU4u@(S=FO8Ml>{p+JB(6%SaFB%cZFDb5mwX&xkQC?(vKel8yeM z1l?-@65{9Y0unL7nO;yAK4ACKZj+Py_XR*H@?iL*#kXt1O_qMmU$Fp0ayW6cHcSv2( z{H6sHW&$O%a$Qwf8CHrjJU(C;lC)Kfjz>t{P#lBzceIS=Aiy|1BURPXLIHwtBU!DK zqu;=k6ngyUsY{kJBLDju!_8YG8nY#cI82H{od54bjtu)*@+4C%Bqx1tY-r9*`sAK?Z~n?mldZ9ZY2P_DCzLYHA__EYa@X zE;$|D3Z)i~5Q-^)%6NKvQ&NeLGHF%zl;O|;36Av4s1)}M*+T2Y9`MKlgsGPoyCZ-0 z#dbMB^WLs8@?%>67*jz0uu6E4S%J)IAZw<60+P-Mwj4{N>S=B)hIhZc<-9;bM3vIf zAtWNEkJSU*5Mh5N)_ueek_xp<2m}r?U1OzayD~FQX*1SvaNUd4>MD}<<$jJEl2*D? zE8b4UHe4x)PG>iqCf#YL&(1`SS-|3O#=DLS9H8E>UJOVElT#vLiUl%8O5Q$glxw+_ z8)~evadL4^q%NmL9jIpK+=u_!f2&N`ZCep;$tDQ{vt?zAa*^n|baizsq*Z+>!em+N zh)Xh(f3F?zI)@9mCZdg!u{)yeXUDysR~A#3e^ox@8Dj06NklppUv9a{%F>0%N+AXU za#X;Qu=bGB-Da#Or|)hU-+J9lUbE51&p`vnla!R2nu^(z@huY!dGw~HE-^CkB^hTO z9~>I)5f2daeSXHw`AUwWW9ZI1%EE$$LmZ9pDS%}`XIN1&-i4D?8SOWSkPITzm+FU% zgeGaP+#u|FJs;leamSR|`I*q8MG zwW(ClTgmzB19m<>SsQP7eEj|RmuEOY(TRzNLzN>oqowgJi9(Q9lhXab!aQ>JTWUyH zsIik3CfoHjhgb>K;&*yjTxevd&_D@sid;-jJy>@|usyJjoNq<8rXRE5;r*n6lpP(h zb8?0iB;pJ!Dog^8^L>catfp3XcQ+QRgM-uEFU;tk(}M{wVQGmEoU5yAz^sb+e&r(I zw8)x)9(u|;rl|tXwn}D~@U=`k5Q0XismTij(tHa(_J&seij9pEpOO;X zA1V#B=6Ri+7zSBcltq(;$j^E+Z?N!QWt3HcwAXzLi^-XpAKq+5l;0SCk+Bqw=^lj_ zYfK*pti(x(1h6Bj)|pu~`y@1N^rbHAB-GYUaiF51~MW^guSUVplFhNB_$EKbmsK%{xdE3T@X*hKx}L*6!g@%1yocZ5|Tyi z=r!yeFqdVBaBNKM_RYh!XLed->b>WzhF0`kZg>g-vWx4Uz8s1~B!IqxZ|61j+q}`d z1eSp8!=UgKx+_hP#Y)jFw_5v#AQ5LB*TtZTo z^v@nDDgrZj`v*ZGe;yL)1S@~@;`e(?f&~~%wzosps_$~Bowl&z56_MularISSuXDG zGOA99*&;(BWoc=02=_`7CfJOO!_vL`2M2LOW%7i6BusSw)&iU^HhX%>+S|w6+dn=b z4E8ayuyk*Bz3J(pGBaY>vT}5kG&1@cqH0O1grIJy8Fr6zDN)ME#Mn2gk<=UhW=KOx zi8(47*`pF_&Cx`Oa!_EnMM)76hKg!dQzJ6&@};`tOHl*QxIuGZ*rRv+7d5I;IBFIu zn4Uo=j3hy-!M1#3kC6Oe{!_Hr&%HMBYJGCM2PM8@0)Ki12-pCQPI%zDhfU4aDA$u zN{`hM|5-^k?MF5OmTT|`T#s`~kT)DUea;{EqyThA8`&wIDQJf7g z5@c+p80kxQnHd;?>7Of1wLb?BpD+J(wz%j?@so;*DgqpZop7>s6xp&wc=P#= zoSh$}6rt>T+E-`>M0+C3vp3ap%4`vyP@Sf=%aLI>FLS8 zx+dcEXMN%4E$NzyiBdUy`W-J1cf?J!)a{F2)34_v^-MXXzL%dKG$8y)XJ_L)L>GG8 z{K%oQ8O!*@-xBo$bX=U`CRXOA!8N~}u(nkx2OjyTAiiv4kqmHcm)*+3tpRUSsttNm zasp^AxScOAJrf>07runFr?aN8WrkK(@ow&hbn`TJ0!qfuSGQGma+(6BqVmh%d4~W!{E9E?8(*4^8gjDw^V|(@Nff>ARNyx z5F;VL2kVq?@2it`kMv~57tNHD({}^W zU7nqs;g$7w8FgBLtt=GmIeDz9nTHq{t{m|$Z`WAJ9iM1p@nCdm=;%gd?>1jW+9@HY zIf;os;SKtd=S*hE?|mW^?9 z7uwm$MrJALA!iFzEV8j9+P%@xzS?!LYxwU?LM@FRzF_1}Ng)MJ{P z7%0bJde}Iz>9>Mq?=FVY^iTqa8?QaEmjZK*B7e`W%mlYC6A1*UsoUEX&ZssuH7NYj zflSr@XiB-}h;-F|Mp|56K|v@8;DYIwk&%wJ=9!4VGcUrRa%Wx;-c`@lfSXH7H^CV zV}yvKIL*z#{>%ne@4fK%)1x2EeTyry=wq|kiDuL^G$=Z%eV#uj)I0qTJe~Ee$*SY} zQmrauj!XPTb$7*H#|0(?20N@!c9(Ot+loa>*2-ggEQod*+^k=(Gv)#?scdXaD3{MK zBZrhDIad04uQ8r-8v;Z$iFj`o;^`y%oX5D9ub271hE>NEdt!o0JsAH}mN|XKTx8%V zZmFvdc%u;Qu@Bu$Y*LXW)W9{n3{qa!iR!e+Z<3GRDU69KZp%IT3>b42qNDrVSZI0Q zk5^PAE+6EluxU-W5@!kV*$f;%#A4NGeW9~G*!XQZ-*C{KH418{fXq4_b?L6Mf8!lu z_6s~>YwG}P3DMT?bgU!gC=YRz$stP2Z^Be}nPK(~n>85!B! z-=YXNfj=?f=1MnKKaqJWX%i0E;U^b1$|Ek{Tg+0lhQF-@w!Q#DPduolbypf*xQqM= zFdbyT8~r~wZb{Qa2OquXi*3DEJW3D#tL#ukY(s%{R{$>{KYC180p&*4Y|D(#?wW%G zB03V*g1GLcg7;JscYZ~9q1HxS<{=yht>?|1o4dQtRGUL)g}1Xa65gJYDu)Old=seO6}UgiFc)}tG!zk5R#pNpK?wyLMu3duP}_!&(q0!;ID z3;*lknMXYR2D-o>2&RS*T^eMdSv8%BMLhlf0{XF24^@I|Y^qQZ999fg;%|@t92BgQ zV^XYRQg8L16CK`8(5TI~g$lw@ z!TYc8;zEbRLnSc5|2EJyT;Aa&HnMg$9_fPkJoiwkWwG8}j<@DVT#h?^@E~=DjfLhA z-IgqDE&2CF_}gA>s*-mp34SLLh9(Iu%BtH=(jOiE_P9Bq+^`u4T%!9x1o3vm|6I3! zb!1L~i1aa+P+zJIE5#5``8XPDYI19TynfbhkfNxeLj=h+zJd3jiApPDJ!oV6uRBE# zi%t~O@&GqvQ=bSN*L&3ucO+i0w~3%cYIe+C-7BYEC=F6!e8gWrYwPOzW@qbfv|d-H zp?7d_qDbCG6Xpt*{d4Fq(p`g-m|-#y%D#>Nx>QffU}a@xcA=*j&9gz6?}DDpz{I)N zM*VSI_|L6Gr-7D{kx8hM$J&t;@cll85E@7cK?rU0zA%;%$J*%?_WpkM&q4DqBhs7r z)(>d?cF6fV2Xg{7=E$sJaXCb%d&>p?xs*YYF~A_<-uEAOFp#07!5GM1zt@3G1K@97 zHy>C2Sv{QU|6Ww9xa#9IQ3|Kj$l9_rLXdtS5N8c_eSQ5?W@vSlgo}%-T3A-;Ze4}fyqHc zeGo6xGrD8I)5`sk*ejJM8%k$8P_%unZ|amuy|YFA*dC4%wDTTpzQ)cM-qeJUp1#sZ zGk~j0NK9OP?zc?VGv$EexKNj|b7ImWU32 z6Mk-bnZ3O)>X+7u2G3W>KXSOVYSw&uAB*nde{}M8F@ekJv=qe7!{b+k(gyKPB{ch) ze~Df-^^>7*a$*6c-47-q&zQ-fS0u2rIsoBEa!rhonhf*kM0NJuqQ!P^=aSaA&e^iN z+okBZBUQoLZx6o3!`^maQ9)`3k|{C`GR?p8ixbK3!#X(FEZ=mEJ&}-*02U*L#FCa4 zq%(U!WY7M{j`$r7INe@3@R9|aqvPV@az4Pmb;KPmYKO>38R?8HG@=3}^zelq)((cl z24o`O3PI&_ad+amUx+vbzrY{oJ5M+tiMuc@mOm$k$Q3k&B9 zO?X=WodJ~4^0c%M1}v2XG$31z~1}8BRux@^pI4ZWr0XZ zSFo9YSfRc?$WW8^$9wGdwKYUkbbO|Y`F)Fant?EQcp&3BFtmkGcSVpxu+dEn33?$r zaMMT$97n|`gfgS9?%f2R21Kqfb8AB?8atd7ZTSHj+$>WdSjGRQV9x(5eYQXV8IXoB z=zDLp@+u(k6A)U!>P+Oc%jolE@XwmA=;~2*ZOC%Q&GK;DQv~Wj`k5|_?d(7;I!ooq zD6t!7jsXZNWMYs_@juC~-<}}Az9*`B>S!n^irPAQdG*bJ&8(5%?OZsWh{y=&gyxei zP;VR!QnK1bprM0R_3vHu?9i_%3;6m{!vjP5s6Tsnbg!+E^32U~z5$|7060b>AV4gP zPe4jrSC@i8fbhYqCD)9aQxINcZSC;n1TV5prk;o8YT1@V_)L)QE3N#Ni2ftkjgF5G^NH{YJw-`JSPYf=1t3^29U3{(y_hX!XF>s1mb#RMj~bEKj2twC80YK# zySuxL6oulM_-4z3eGSsw3Gnb=ww7OAvZm)t8)*B}_pg)>lB(nANKVi8E~jdp>+9>G z1Xqq1qB4F80b3!kSf&8Hz4cpzK34sXzb`utleUh^3OQm)Ej~T~zuW2mQBv0t<%9av z`lVOqf<`p28|sSnwyFFl0!(lQlAJuay1TCr7k~_LMnti`LZqmKDHYZgIe$*2vp)3> zKb%iD+^K4*$8>kUb1onzCGDRhUYJ^*Wmb??WMWFICaI3ur#smK2?`2O(9^?8hr&gH zstH&9ModS$5z$bBv$9CRG0MBD4ki}xJ4wAhUS4T(rM!%QG#s$0_WUSG19n7A!C35D zM8v^K{B`*o$l=BC_VJlookavzT-fjsKyU*Mph&4{S?~00nZT$qUlWqUPAdqE{3!DB zQZqBf&7}qG>`ph2_Gl(P5Q~V2gdQGh>tG(AoUjXXe=ejO%3%HQ_)0=hI#_D;Eh*W~ zTChz`EEbu=aD(rbiB^;ht)U@9*9w!*21uCQ#Zi4sOV19<|Kgh|?1s#CeT7Lx#=4;? z=_g{cvop1^5ZOcvXZ@2R`w^0s{8{Ym(z2$br-<) zQ~52mShdcVE{FgY7T+F&{}v}Pk$!Y!;AWP3n)5xEzlR%?JPO zw;)i+uS5C=+GrHyLQxG|=mAnFY<~Zo=k@vvS0g9HGg5B9g>NnKo6#b}vMObo=NQTXJi#IX^b98ao#x*MN}ZS{xm8C9~B7S?+Q(nxu@C^cXdHsPQ9aMTgjBY+#MC9lCN4I}z>b;pY%EDF%ICcggdUW@ zyWQ3EmKq1po#t~`7;rdW{<^)y@6p#%r@GkT!BD~Y?Dn~5u@9C;I`qPK{oGx&ZS2Ln zfWv}L&PG}3bK^;RvX*6W3pKSzc@KuOu>%$g;Cb>Df{+9G#5BMfU-0 zhr?$}NDh4E`eSQr56y$mV|H$Cc&p&hJm{;j4}xqxH{X_&L_P_#)njscdRSwlCO9q* zz?HD6&xDj=UwDIyve$%Qo0~&J!hmhKQ0^}L+D*AYm2k3YAlI4i8&Dj@3_P6^A%)cO z)UN825geTj$@>i}CIl%aho8Rx2B-=tXEF(imxUGG6(|c!MdFkSQ?2=t^ zW<08nlcR_!xfgt{Dtm309(ZL1@jFwlus}bf{)nc9SRpCCdU<*lQd5BzMYsFC0O#73 z7@@Sy>7mYQ!%9Tjn0+GXxubNEqBhqg{I!`*C8v92m87}3rFVH58A!GIi-`{_C~$B$ zH?W-=q9>1^O_EiyzOTOf(eA1~v*Sv@7CDF9(9<`tFrhN)2tA7^G!qeUX}9X$UO_+~(Qk z-6{_mc|jD92;uD9+-*=x`jCc`x0~kg$b5ZY%qrbo+-01sKoD8ksf`UfiOAVRy7=GE z0&Q)6)DEK~&%&9a9%L-a${=FWegJ&^nv=-l@Oc*9H4^~EYr$x6g$JzqQub~<`m3u( zKwQ&wzC>ZRlB}ep2v`}6g-sOue99amE3HV3f^vn&VaQeU^!@ML5hJ&>wAA@ndeq?I zg!w}WdudFmj0gMd@Q^-nb$E@)A>#7#^51Uw`>+B>E%^`&6O%Mx z#8}qVlQR8loIWbEj>m6lZU#(CGbCm-2rr$wIxaQQrOMp~^z=@y zZo!V?fryDM9F`(JVb>|F6bI7yz}B_S$D;yfos((qv_*wRHZBV2KkNo>Mp3~rF-E5L z(LNp*hfnotXX=QjOwcAo_V#G92tTztR6bO6bOfOxQRPfo3#@G&9I#m`*=$Jk^m6cV z1s6kPm|0oLDHwD*F4Dg%Tw0qOv0_^Z`3RxjVj#*d+5al$gA29?P$YbcF5NmgDDh7L zV*3Z5VleXCWg{*Vm8|&|XlxX-GPBtE+39r+k#9Yd^T`8s6}1SoD4hAk9zhIopnOmZzqmlJWPe#U)pt5a9V}Amgl6pu-cq zaq*Lh8^9aNm6@9GC6i#nd23kX`I$~E`3H8x5conomVHtza6H!CS}e(dMp~NRXX}d- z?)LG)+rR;g^GHqy`vC2@jPh%yFLJN%D|ug*K3)8b1zB2($l5(4wRt8)4yJ-`Zf_9P zXe}>qFR^GyL%A|#Q>xp;!|ys|hKD}aTI90tY$ug(XDeWJ$nFeG zKV~$`6phZygWBT$tY+_MA6n8x0BEqL*5;5NLFzx1`nNJ-XEMguJRUOFt-uepYDDL| zyNEC_kF=wa@?YZP^L#&2w}RIj)oN?%arL~<$S=;%DZ=3}RM@zAcq{zvbYTV44Ny4X zsXMg1mXDgknj+_vvRD=I31t%BKL(;8pf#(Uw4EcPw-=@}SwBBkzG!{4`` z*kf*POS^ipvSP%>LsCUK{9j)MDJE#+OUj^FnON|05@V1L{ya5_N?FQ=+eL-K!5!K- z4m^ycsC`r=|M1ZPv66))BG(HD+k}WXa_Jv0QGMxhrhzQ~3JrztwxdC2>@29Qb>?oc zBccC51-a4N?JNrgs^-L(uiFL?P zhPa7VfM)yiGLnr0FHRt7JVQxq9_Atz^fTGLUwV}k)qX%67@S{JX)2khodA0t|LlM7 zH=R^k-J~*J0d|{NoP5K^=GaF=ySbhvB#}C;l9fy@H+wbJU}Eg-Jmcps8{;3G!Fzo0 zYp}HWvz?6lc%~2=R8w>Ep|8H_-l&1PI*U|F2*-6d3=lHaJ-Ui&&%(0Z;e357+w60o z*pfm!G^?9nmdK66*Ae$csMTk(2dsO?$1>X&&G4HjXFGP>!C7mm6u@6oa2S!caj^Hm z5{cIE=gRUTk!_jGQ?35DLlaU0vM3)EnQW&@Z-3uL;HOzEcIV~wsBCYmxq(EC=Zf~OfHfj{9h_w3x4K06m*5>w*){B!dh-tV@4Vz$KTyLN3l6i69qX@*G6 z*3n?DlFQvK$*GSYR^)mz0ouwpu8jS0dnRW@$5e#FKP`pn^*eY(@`LQmr-aeL!^0+8 zh@B7&@w9oUxr+;O%vfbcwkx-Z{s--ddi4_O(#7Z!6>29<8(qPUjwhP+&WAi$+#)A2 z1|H>R*qJi{L4oL&+5n^6`{=}9IqgnZr*FAj*<;lt4bWnI4VkFV^C;c{ZA$zGFnwt3 zXCTtDV1e*b`a&mTr<%790sX7e^zFV^APkLB{n#zI!Lcv(t=e-W?9J_M zM5H#r8N>4C>hK`3z7)vt#?wxfboH*O%b_bHfnr)4i)GLOw{c!>vYoFT$=+U3{$&v) z)n7YPRhS-tBcifiy1Kfe2t&kt{a*S|!|n))h$!g!5xrUjI0dpYGpV~UVcgZ2WCC{9 zu*+Wz??1jgMRys~K!_MK;!R%tztIFe2{C;d{laUh$Yg4){KLKl%>h(*!tBPwkPZC?}(IlY{c57%4KZ`XHcj(!LpqJKU<%5_5_ z5pF0a9Bm#(RE?w8auz_6Pe3d>>&2>Rcx2eHFp@B{eB9AVqZS8*txBA47DiU}oi!-Z z+MoIloZQ{|hrsICGeK2!)<=ZclPS(x$2PWoV*C^WI*_k~0@`xkQ=L)&)&fYat%~%S z_b<-Ey3NgP|M-c;wn;YlQU29`ol`bd(`H7XrVUKoB>L?!93G*cJ1dA_NNDuz@~+K8AEDzX2LC(G)^clcTw@}p8^2t@mkV3JUW7eDr$vr zq21h3@Q4@;vQ=6DJhzm1pTNjv{(S0Fq{70@G4q<1i4q_xvt&z@FY%jxP*)Sw($f3+ zeSPDwcgw6`K6%+3TZct}k1lf@0VENnBj;K6FeeIPA^Ev~&X!ZiH;~=9TS#i#uTC!=5+-=s1IJKDMt2Q+#5XLS6_t8tEB(tt&x=PkY;^u<0ptnx{Ap(53AmjQS^3Q;{&=>Fk)V_f>e#|0^3Ve!N4E%oHh69Z4 zPsd)K@{jOCoZ=Te@H5Zwxn;7rf5#KZ{r?{?s8-%9w@;}5#5R9~V3fz#>pZpJW)Fo_htuW?B@SvYU-V`aE*;f+NI)D13 zKr73~JHL0mQuWn|6Jz7_bk)7-{LzD0Pp=O$Q1GLjG!P2d!aY7GgGu15zQ_M^!lM6; zxbFw-sH3&bXag-WtXTUcHy$PZUn1R1b-ux|37l%9vNKk=O!YX8Nj zEt2OJJuS1wwZIQn&G68aWNG%@FDjMnEKK!Ef#nt2+S=c_=xeA^^l<}QDH&s7B}nQs zq5XC%WoFvQ1QCNagIAg^k5mF4Wp?LBM^SNcKYO^5f(QluxirMQE8>VuxlCcS(_m!a z1zko}j7{7Le_W4TIabo6AibnYe#iTVK>@f2aOtllm6%#e$P>@!?}mQjo9sBIHlb-< znE|DwGuGqD@#*mteO~Ss7LpP2m=69oST2Tbfk_QKtwKT^A|fo*O9Kl8G7!k&(Q$$; zGa!%v%=P_UU2nqR5wLIw5CBv1M=cE`fqmESBp9%bR1g3PuW9%J_h1%jhvwLMl^X1bKLInVw9L1Vke4`R8fu`%$k$`OuVPL00(HroxB$w5ag z(!Q7V==N(=i(yTj&KdXi2Cd#`cO9+QQC$%|Oj#R=oWJ}{o#ujpd(kB%3AE|faUtu1 zBUvxnPt6BT_U2RLlFI?M;+KLO%0WdI5@uFr)P6hdBZ`9W%G~YQpe&w}@6qQSt(v1s z+C2J6mDQQ878W%t*+^hsryiT|d;3G-)J&}ID*R&auG?1+=b2dV$>uxF*FHAd{W_Id zJgsM2{$aaeYiCBiXvb@@%tdTWwOBPe_1jeuYo|T4|9h2bc$e`4sQN8CEB?*9s*Nzv z%(q8iUu|vt&fQt=+4+wkWSKv1tzM{}bUhX{ASG>NWb#tlYJ`#a*B#*?9NVsMzf`4H`TWEllU9x;4l3WWv#6WuusAhh?jbXVE}}E);%-_2hT3$X8!Q~DLu4^2H5O2 z{^5`UXot3TPpKvLd!B`t)UyoqH+K%gFKaoD5;XxRC;nSP7|_G-fe()NS-%8b)qSXi zpB-L8A(&cS44h9+X1T1Xuaf`-wn|D$?A+{u3EPyDbF2(B8jk`1K>nPm&&+!4MAtaQ z;q2t>nslf6EhVz+i<{L`enSkJp|Bt2@A$=;?;I2iND$g$Kr<}syrt+h-#dark!K8S zX)NI(JHT}50=z8hN0MxsMai8&ksJiE$HT*DFm{mufP;?a=B8%@UcfPBWlgEl@3+i( zRtl4ja8^X=p`t2cb>Ii0JnJ@jd3eeBxpDgeF+?w}e~JBKEJ#*X+UT<#YF5^o9`;WC zw?YweNMKeHga3=BFlw?@ON|CUD$El9#a?56U0J}V$jh-fQ5kzTyi-yVH4VeCygUkO z+LBxVlok~g#b%kATO$RkrfL%1^&|1`DGb2mkR^k%!AqQ;u3_hk8yZ3a&;d%;S6JrC zN`T>@nm5*uqs*t2K3r4%#OCmE$l4kR50&-tAzs$g+d4j`eG-M+laYZ~Iaqa_j&g5f zV@um=scA-)l`&ArT_Pd5sA!nO?ORyJJMUNMSJN}C)P}CVhY#Bo**O(36K!Vm`+rou zWmr{Vqpquhl2X#$A>9qq-5{Nl?(UH8RyvgKkdp2RNOwx7NK4mw{np;=eEXk2RA63% zF~1%XiL{cy&LKmL_$v&U@EL(x2MG&>u5=q%z-9FbgGdzO=A zlAW{}f;Lin=9IY zrc)FUBx%9&?9Tg+yG<7>h>;^pSa`Su{hvJ&QqxJW5y4btPs_-Z)VUa-%g+z^7?nL% zC+jcxeSEx>#7#d74A_8p<>2U;j!INt6h=r$OMbhZoV+3>wal~h-J__=A6vUrVVw({Yc zw!W{R1Co==(-aq9j;gB5#gwkg&+I{XWC*9=SOwlTsLPlF$^-@#Ksmrzq?@`AH$sUg z@Ox5{Cb>rSQHQy#0ttl42$Z-z&-W7vSK;pOO%wBBnYn2Q0G9z|%f%HmUMo^kMZ$VH zS;=6Zq|y^aW#|pSz4W7iHl{#tR%3B-jeL^*iF1zk8uDA*JlEdH?{z*i3iv%Jqd+1* z{}%p%D!cAQoA-5SVL=>)U*LtZi--*}@L~Sls|_eVRBri@_>yji!jcOKp;J)w?*Flr zx+`TL9P(z`L$KbJ4pGeIXTIk%i&;6z74RkP7E%};*{=BDeD&vy0y#cr9XgtcQEY1E zB*WniB8FRFcekXv{0k@J&bG|9saZFeb&%!?J@LVd4?zqX+{fJ(2%uitAmDb`=$|eI zkyp$h9G^|tFt~7#t4C&6bJ6pA_LEmq0B$cbRVcFrh0pD8&cLh`0f|s%);bJLvubEy zh619gOiSs|*pN3_6cUC|2RjcXCUsE}xz@U%t%r^`A1Ikj&QI6L;sSFggwjGVfchF> z2l9%_R0qkNEUhikj&33gOhN9t0iIm?lOPx_AsrTdDJibb;oZU)nr8D+&i?pV^y>lB zz}==|7MdCSKv}z;i%EqxfpdqWJ(%o@6Qx3g>2dDlce~0Oq1lvud%mz=QXhJRgoqGY z82Z`(dwW|@d|FyLa1`sOq&WciU?N~WE#jL&gWD$`Qt{lE zmTXrk9!Bc;!ZUm7Q!Jv!bH;7x6+c|=`cc6|060T_RKEd51^3`CV{+&@BM4gy(@F;! zSH_CBH;#WUy1c%$LxgE31dbgGD=Smd&&FNz#4G2sjZGVC`>?pVf7Z)zQ$@ORo#N95 zXU0KIJqPE}fq7GAt=e^m5A5Gq+~qWaP0cE)9;5Ukon_0Ix5#H-zrt`HLGDw2%CHv# zvN9icXx|KndP*u8qafr9?#2CfAO(mL1P8_AvbX1PF*Lo;lX>*B%mP@ePJGaBsbq|8!@F()TGmcn~T$wbf4^t2j-FKC=x)yHN@k&`MYN(LBq z!c&$=00f1#GlmEm8EB8-ynQbR0`LqBjN+|Tw|L3xsxK09vtvX1UvKbkB&wLCD2&!L z#5SNobanYD3k%kt<~_J6p%u@67hQrPB|if)LxH`DGXql;ugBSNDnLSYZ%*YEyq@)~ zmvJ8&lFqZr}&Fh6P?%0{sd1?{-SZ5aOYC-Y-bna9Sf6`oZQ^K4i9(Nr}F_9P5dp-B@EtW zBo6Wa?obYE5RG8b^-=T*dXqL}txT9sUn)$=iPt=fWy+9;nwocRL~8f=zR^O^TyQy* z!-Y?6ngB!D`U~#$1>;VWr0Oh4p&kz{J%i=-;8sI_GFhHC$Yw_Gtw|QKlT4hWH@=av z$`#S$a&A-V>BY<4*{KR zxhDyq>HyZaU;6cXEH)tNTiTWg6ZUDTg{ozo?FHNo+{8a0oTwP6y!PSee^@Il{sa?@rHQ~fV+@mMhDx%zP5c&g9D zhS}Rc+y|py7sPiw>SK0{q_#(3+^+n=0Z;7=@xb_)I8kuefUU`gntkn5LNWiJ+Erk? zF_@>tun7a%k@MMrj^GZds)6>JU+k;`n zfE0@lOe58?)q`S1gvkOMEd8nyw}Mh8MvtPRBJf)Cz97<+mW}%3Na$i%J9!RewiO

86;iZw_s&S%ieB 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�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 Date: Tue, 25 Jan 2022 16:02:10 -0500 Subject: [PATCH 0750/6505] Delete place-holder --- misc/images/place-holder | 1 - 1 file changed, 1 deletion(-) delete mode 100644 misc/images/place-holder diff --git a/misc/images/place-holder b/misc/images/place-holder deleted file mode 100644 index 392e05b8..00000000 --- a/misc/images/place-holder +++ /dev/null @@ -1 +0,0 @@ -place-holder From 7e8f20e75f3affdb1fa42d397f539f327da0d4a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 16:09:19 -0500 Subject: [PATCH 0751/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33ce5a51..f90cee3c 100644 --- a/README.md +++ b/README.md @@ -710,7 +710,7 @@ ________________________________________________________________________________

Webmin System Administration

-To Install Webmin System Administration, run the following in a LXC console. +To Install Webmin System Administration [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png), run the following in a LXC console. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From 664e68f024afcea38d6b617e0380522c0a33be96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 16:27:52 -0500 Subject: [PATCH 0752/6505] Add files via upload --- misc/images/pms-copy-data.png | Bin 0 -> 25396 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/pms-copy-data.png diff --git a/misc/images/pms-copy-data.png b/misc/images/pms-copy-data.png new file mode 100644 index 0000000000000000000000000000000000000000..073f90d7c0263475f5ab74298062edae12ce5f3a GIT binary patch literal 25396 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 z zlpiJJ2b>^jk)Z@NP{kMrOrhJ{P{1u?4=-_)cLZ3U$Hd~(2h#;O?cqO~M_u~5sz$0F z1_XtX5~DRT3p=@|{{FV*edt-^3O0-;2Q^H^ST9PoityOH?pRYy8w~o}(nF_A(sBYy z_#JY*$&@Y~bNg4P+4RF7z8YO@$<~Qq@VC+!a}Bu@{`Jg};p_I=9pRW6?lcx7(`g0z zrdW&BG))8ZX=B5~DHAONAGCcRehfFCJKmcGeFt;lKYt~1uG}9QNe!BxvRG@_+Ig?% zusX3nI-7+#Q^DDD)eXZr9g;>TN{M4+*BR3&k}`0Ez9dJtpQOpGB7IY1LLM|9m){ z7asS|98oUUh37;4fGU^+prXWpg-2A;dP|nrVX|r)zreec@>tHvTT`gzinPeppfKse znGIdKUp}=&P_?v1`EX1HLmz^;^A5{%GWAvWs?yuPh4s4<(M-}(lqK3kq^w5L@n(EA z;^&8a#@o!3-xG}^i_+6E$6%3En6!KWv&P%Qe`kEX!8tOnj1m-aWoBpXiU+a2oCF|J znesV1l97$$tJvjsQr)lU)Ci0TXJ=G)TrpAnzQIwPJhG!@^SyJ;UM9^?LH0;1LEH3@35kr; znI-X%O(A^a*MlqE#AB$nY^#;Y3VaNd_&wT|e~0%J&T!y^zSlW+_9^qmu6=v92M{H# z5ns(FIdZQhEnvPjnt(?Z4+8&5)(X&rpS`gK2}}#wAR={*(!R!?KJa_}{livaGH8O0 zT5^AS(Lr6OE-1%NE?1u$b++%Xz^j?<%h>!+Hb*2IM-u8q6+-I;0^7y4U_zdtdn>!x zETQB-MxC4~5uRsgq-~}c!X6hl$Xs!8o|?+0X&<}pF=)0_%5_Ka)8}*hZxz0^Tb|{7 z&CcLTCYy_1Xc503jYV$EE=J&1%o1&Pq~|Jp3f`Wv>6$}~sL9XX{XMnY)Ku>zt9`LB z*qNGS^MjaO;+Z)-+cx@ec=Au*gA?JtA^@v1<2RW!W~;lfvH3`V^=}%5j+RiLT&(3f zZk!&(1AVh@nL1u4K|bDkIZYk#>mD)T zq8Ckr460$qf>pI5hI?Ffl=>KP z*uoXjD%s%vbf9(KRWfQ%=-?P{__>9sL1D6g@OC67bRIrSYb%ci#9my417ob-EJ(XZ zQuU4%>XGk4GEp))u>X3w?*J2tz8u8)3JBN>t}=JnL`Sn^Cu#55Zvo zA#X(LW&tp29K7oelOG%3kB@z- zn$RUVn`7^Aq>B%fuhV%Q`fnqj$sa~_^W;+SwuX~L4`vNT^VK4_*6Ylk+FjtMEJk_` z)3D>H%fOHXZwec-5HQ)3@>I<~IPAnPRdfP51M0t%3#_b;g$F z@mRH^TCe}+dNnExq_V%UU+xIXAMTLOT%38o9THRDf#!Z$!1O_O);}QJMj^}9kJmz9 zC*8pY(6fKM;QUIr;i$XJYIA)nlhnZ=)Wq`SOC5}ET^`JB=s%qHYd?|BmTIEn4yTCj z4yW80ElVXb8Q?6pxYp2weCpIqN2QO7=rBZcpajtm(1>YE14km%ZBFlIh|q`#f97*} z^I42*2Vd+>Qm|EFYueWHBQ!ragO8tjl%yrIZ&G@HZTYQsP4xuLwfo$&^hIY?I28J{ zCe!GfdR>!rKRrsHP+m|^<|#yBQFn^8HjLhO)=KBG0%ZuGI0ISZVS=m%5BRm)Ox@U7Y5b>?mD%J@P8j+kbDRkUo93M13yDezTiLMsh6m&wcO0zMy3+g z;7k=ni;fX5Tpq3XonTT)f9m^1Axifo34C(*y2pZt#cN{|6LzzGy*#_@lOHsfc#IEJh(Gr;insF%+5z;!F-;|;Y zQR%+D^#{D{ZWl@&Z;9VK;vl{yk+ie~d3(1hwd+t%S8Af7e5L#=6csJ?>??F>r+xMz z)vHs&WoEz2mQI9)1N8@A1UR+X=kSJpB;x~V3ajB(!9y(6=X5KjmyPnvYX(h*n7*ik zQ_1Jae8wW>TogmCEFqtOJV9*fQ(ei0ghcQDfSzy$VuoreIz z#X)$RhqF^D%R5v0{(OVwZ*5WdtYYlehiVU%&R%MChJ=V1B)zkS?ne806Eeq13KDwu zwm(hK>S=tD+YT`f97S&3_A&&Eff{}v+_k1(t&|4xzR{&MYjZ#3PV&HYJ*%UX%(Q|F{T){WFJ zH~>{nDG$cHm?UNDI~eTW)UEr%tx=f~Gumm}U#x1ORG~*-_uPWp;!5VfBJ>;@PaWxO z*5b26YCfKd*(i>ojfUZlaj|Dd%w=wjLC8T^Z>{!8gv}OTqt24Th3m`hCWflD;Wl`K zh2xpna%O|^=g*%T(4Nqx!c1yiJT$UNR#9$e0VW#fub=aOO@pu7o#zZP1W#!Th<<(? zdvpadYL<&Dt=gyZ`tc!L9fwm&qM&pVy~rZGuAWFV5Ta-+&TWb!MfVOH!)AG+Aeh;H z4#?7J)RA{sku?syCE&+vKEI(wI@A5ent8&nIoLlS18^hr7k%TEYZ}fP+}~GLm{dCV zIr3{Sb_5>%z$Jv)fWuOeC;}3hMD*VB-3KWtqp>ns88b?n%VAal$CCjkrc~aje)s7K z>x(^J$iaqY)PX=9EASPJV%GPT#YLqzWPds^x4ct-<8!X~U9jiZx(WLaL)Ju=$9$Pa zn&GNXh_yepA;*6Pr?eV2ye{@Hh1E)wqC0ERiKa!5bY|FGZr*zek>t ztvA)82j(J4l~gPW-h9Cg2gmz^NrgQkjC%Tw)*lE`1ssqWl39mwV~)JNE=dBlIkmu( zu;U5mYfvAUDXj;lksYPBx*UX#WiD!?<;filV?iy09v0yt@W~5f4WAAQWVX`SwCp3m z^W8(H(Gd|Js}9_poi~5lHW3-N{7KcCxt?%zHJw&dz9 zsKod6qjY)`g!r*OhN9xLu0Py%Hvi7INqM_OO%-t-yKbVKrv&$K{M$kPYP@VvRJ;!? z(n-2xe1CpnsMT^PFp|ZKZm>7S_pma{Cn?<~f&!_s;G{&38GfIVKA zXOb5Jzy_X@!thCdRrcfh`g#E^OcV(lm}>8TrNHL8uQrE~rY*TQRhS^bw%MnMD1b*a zO&g22lg52wH`jr*Ped0EmWN-#AQp_^UUldyBS?tlF3tMYG!F(r)r!@imZ4;R1_Ws( zY9Bu!W@xE;-P9y+`7#n$&Uc?J2_06~xAai;SJ^@$jehgD$AvYA8IlG@1#U_`b%Jboh zJTW7#5sLPb=H;Uq?XmrzIB(7BXi%QpHIJc!$)4x4b`WBAq?WGdK^OuM9pHNEaDJp$ z85of4+tAXiFzBBi%=LIK)hO>Bu9{n#oD|BHRt#vYY=qm=#d1-56BnV;Vp7#Q4j<;obozI&r8`gC(SKS;OC2|l5#vs?k$o*Ks}Y$p^d znDh?SXMj_m?`KNqZtO=9NQEs|%7Cn1n|*fjS-`+JXwa?btL=zXA$NAE7{cH-kI#`| zr5I=Z!v2_9FzXmOg}p(HInk2cW=gAaAEzMZ|D4g^=|ZLxF`}9E!-!5J50l^Tp8LC? zM+7WKt=&cGK1`Dd7?el&|UqltR&twpUdw1 z8q?vjm`|j9o>)XYwo=beLUF?6tQGpL;kT%oKUDj9iq7^P=i4oWd7f($boG1*I0H%E z#aQV5Pc6XOLc5pn=bgcPT2S1zoP?%iKTSR{j7$MX#)AtPjJ>l7xJo9DaQAKAS!J2OVJEIXr>=Z&Y49PvTv}+?KD!#1`xlJa}MsX3Ghp#$hz;mJ#a8!Mjxwk|%C)Qv= zo$#}?k|os$ZC3Nuy60rky9sSnE_8GCon&UfR1aT^7!ubI8rnL*b;7awTm^^tmUI*9DdpHgwS-PI z3wK}VF9ewfxjk4u9q^u7|rx1Otr4#OZjh3p-yb#x!6 zgjJwmD2Rztf>6PH`>8d-w?A_JRTVU$!D=NW*jRE$xG-U2h>SL@J^~Y(#}xI>>O}`J z!z2%+2y`MaD+qwqOo$AL`6GoO(U@7ilNETN(Fzdw)x|uRB4ay+rxXmtIB0X z#CScNO!9EncXHBra`rI>Wozh%M{S5;KAccR46IlL3kadY=Hk;~X5O-_Zn)=?WJ~TV zNm$nS-1M-jK9b&u!%WM%hI)*(aC^Es#ZTfUAp1eQooRqbnsIbAg~ zKr~?{N42acjSj0(0`7m$hP4*DJKdit%5)p!R%cqEOrfXxyX@o7Eo>|D6~&Bs<-*QRVb^^})E|ik87V}6ZoDEni`N~++h_AE zx6SjB@DUO6^G87YiP@=fc)Y)i1nwvhB2!a#131507Ld>2B7%Q?1~Pk9m;B|U#F%>N z?5Q68DgKIw^Jd4;9JSM;-wD!u%27f5`|yk2AuYK@ns_#AXb$c}1l|?*_0wahhjGm$ zb*DtXg5CQ1-?0Su@ZFHG5eRr*$b726^0=DgGPPwfRKL0B^I(;3JEz5!c;^$9QtWb} zc`T*zVEoL@@gh1CQreJ1GMLYmiP{d;>k=imPkzficWVeYWis7N;PHC(na%8sE}PL& zqVJQL3Jc6HWkuKy&)T3peL0_dKR+zKUGDiyYkUo?7Th?j$onZH@-D}78%gS&b}|LD zig9qkNAYk7)eXCfr6*5jgC5AIt??nb>1Zdb(HPpc=Q;d!*`lBpMS=}yPwt&nx{P7V zyU&8EMvseMo(}o8LzqNoN|H`oTk#%@C4tMBaoW;si;-BHq~ejX(riqbZ>R=RvW>JF zjX3|VdiiT}(vTls+Mtng5Vm`{O7@~SY0lOPULNxMCIgs1eVZ1O{k<_ff|XP)&{AVD z8gIE5D(RTRAshPQT$pGFfy?Mu_uqq%(u4>;=Eq<2o9=>qg?xe#7F$EHsNmwl7_^5s zM;F=Lool1P$*k#-X2Y{5iR0o3mjNpIBvf7!33}lJL-t)}b7`FTY4mfcNFkJuVejm) z_acF4wU}DQEX!@Rc`AbC7bD@`Xp}7!l(o$uc@Yr<2oWcQ7lByT|hMZXXbGX zX?t?36vRc&;wNw)1%JzFdNKo3A4L{h%v6a5oUmHm$+{1(UKDkycme~ z${HOiP~1C(**hRLD6RtpZS%Tcq08#;cnq!f7=Bx(#jhEYK)qZ=Q%M1p35T+!P_>HQ z4R1)Eb~x=G0%D|7qutWJ$21fxE^nCz8b7@S5^5Q_eMl`GF+XHdxtkAGEWWi4FP>03+m~Y?Y zM7V4%V||@!5@8WRkwld3PymECZ$@y>?`GRSb+P|_!lZy)8U|rk$`h8QBRyiBAao8R#B(u@$yzfGw&T+TK0O#{qjT7Pj>Wg97MMQN*Uxt+`m3;YDRK@sx3<+NX+f?2!lk=;>@mOGu{A zi93>9r-@-pe$UPXwdSmUq@8Nbhr7=$^AuC?(l{+PW?VsULBAq*gm{yF%I1;9<=Ii5 z_abdqcCzHy!7!OimXIIR)t}_r?k>rxK}POndoaWBX{t%TLQrd=fD}B&MsW98DqCcU z$GOx}i_s~5vU!si*y1~~3KwHh*oazR{fo~S2R1vN8jgIgMS8ry6j|V)j`Fl%y^qfH zxL$1@Yf#~x(hu_uu1R$Z91!LC~K40t9ugyA|D?7BWdNLMjPffL90{J&v z=ZjqmIyG|tVRoNBL6GmDupg8|(D#fOn+7d3G@VBl``*!E{7GCeP3z8O4-y}ajQm)P zDG*+_-+KAp>+1EiH8%*RtTc$EaZrCjej!ZvKD=^^Zi%#Z=cktnv2~yFSf$v|dPdUf z7Ld}=RSRtCUG{$=FeIJ!ha|g*OPK2-h18d#t|49?jm41GhLTLIv|p2FvEp@FO;=TX zph!^*Ok;P36IP}x$)YsL=NJokiDcMl_kY(zU5VJ;XWu;*Q|>6?#!un_Tmab5o6@Rw zarX0pY%{WhFWw4-Rwd?RkO_7N_A*YiSy4?F8Sqgbzz=Sd10;|_TzW*os+{z1;b58$ zCCKgP`QK&4BGpzxo%#ocUi#O_iSLn^w692>&z9ri#arUu&#RUW{wGh%pDA+7{wog^ znWTi3iUJbq2&LPBuYbTT` z)ejf~i>>?D`dxXSvIFe$WC2#lDh@bbpc6n(gdH=*K{=-)Ix5SbMQ zz{*+wO?uN9kPG}pme%Ju(CbcPKVLe{em+MOmCXnPZABmfehjQhxTdLYpMSyYAp zb-=jQ-vnoh2G-w>Gwg?gs5g-$je62Azc9fL)|=)8CIUU!s%)i9Q&@eZ}`D>KMFi8z6Or>EMl`{Z|;(xXg1 zCR*uql`VqWb2p;N+{(}XBCYiLU!SOZ<}1%P77pkVP~As2J{0K=;eW77`f{l;ieKOJ z987RYtI}r7bWU*<)27EYBi0llprq) zaw8u~5I#++lo{s_4P-Kimg^g3cBdGAre zhaq?s#XJ)C9K6>OY_lsUd!5+OCOT-9IM~?>rz;!PXx`)Q>jYgs7Fy|2lP$vZ(dQaQY784@lb2j2`u0nnXK=z~J|!vj&PPlG8=C=p>3>f;!xQ74 zP*N+PNK*7En@^D#-b)PmXnw06k@bkAR2=;F9wvC|Q5zplJ{5MCHY&e&+rz!e!VoV* z0HYd&5^6i{tq9m7+X|c#e}(PG;=5-#It$whwQN zuJBfeF@Z4wv9Do#_%X?Lef7&oUF3+4!0PN+M2X>-a~?Egqmzh(FPALehM74k45DhN z1jVAN+^whS*WZ{IKfum$I)3+Wi`ghgUYLF2&Bz2lv@QMWv{D$kza%vXwmCIZ{2U#L z)F+7?(yP$tJ`i+zV86bCYIi7kJuk-g$ncRG%!b=YPP{1+CUtX1Vfyvxo~|;x7+{|3K|!Lzb$V^#`B$nzg@`bW%B=f{=C_0 z<%Jx=%+H93)93C*x;~x6%OhtQ0aj^ctg2EJ9a(b0U$Ii(T_GpZIP?v6Cz}RMcayc_ z8wBXF)aq>a6fT#Ib`z+Xe%>DY6CSs^I{nODWc5};%IYGyKXJ^%X>Y~r!R6i9zO^nh z_QyZ6k!#$%ajd!w5ZiR3H_3)U=^w|IA=tC4eYq)Q)j57f@+*!+jaj~3KNUQjw)cq? zKDMYg`KF+>k@xYtML+8W$;rAyjTU%A~ zZ0>8Bv*-brwMJXtrN3M&k21e9hgM;K(!t^|+|CU`?h~i)@6N=y=;2Jv1pYny(XHjT z%O0&ise^b}tTTwOT5G%PW2Ey)5$ohz_{qNju3@)EhS&Q(6-d7r{t$Ma{3gyOrU27DQJ$JwXdxG zt8{i>C_-8Iu)-r<9lME3NoG4BZ)HhWwRhdS$gTrA09jT8{Y|^g~1c4vP z;6vy!T=@&{xV9m8$Z<0e|G117IN_tp`Nd<&id@+>eUgu?=B6c`iL~aDRQU7I_mbW= zsGiq{y+kCRp6K)e z{mIzl*^!LZn}Z|#XCHHaE*FxWJU;ao87v{Hqj(veBbR$IM-{$4Dzy;J&M5W}+#W^b zerh3&HdGJ{x|?!WqBKjspa)=FD+&aDA>Z4OqCBc9ISeKjuvOtFC&BqhVDPoHxot<- z=l44f7FB1Xzg#)_9c6o888PMOS{AB2$>499N4d3O$OM4eN%U>x@SVys)`tf=o4Umg z4CX?2^sel4qdSvqw=fxXX~0Q}Z6q*=gQc9j(?t>*QN= zKU$}eOk61dSrTbJOavA#c_KzOy=LDwzI%bMda2;~UpHnc%%7dyA$BSHp5#q-_9F|P zipOKsmu5dagGD|{k@Mjj>pH=Hx)4p=JdkHnP)U*FD5vRK=beV@zY<_WPX-}57g5i| zfI;v6aRO~N7JKM>1G6GYu`X^H5pa5F!-9Gv08EYw3~j8<9DHn!rjB8+73oSs>N`n3 zm>EnhPC)AGMebAUW~XO${wV*RM)E09t3fg0Figd!>T~0%)8wCc?)@+>lj4i82<7!K}B^hs|?My}3U}P`aIIH-OXD08a z3)Afer~;!HVZYmOda%WMfr(ll-q2K?XNsNK8S8&n&Un?{nI(n?Jj265%yU!{x2Gr~&9wSGfV zZIUi}mzdp8xtLI9BD`|VdgUL+*!9t*-mQadBB{*;yo87sI9fKZr&uvbfj!~-e>snq z9Vw5(1~z4gGmDvD%!UVqL}EemgH0NWlt0rFM`p>7ER~NmKt|O_oRRx;(Bk!AJ{D3GDDx`tCGr;-r@R1AeRH&xYJ70i9AY!RM5ki>I9DMfKza5aMcl$B6shl& zQwp$|12CaqPc64j%s}qnpv9I$39RN_2gz;KRJn`V3K6((viJCcIsMuq)eewfhF!{g z`P*AC9Mr13FikZX9VXbYA6h#{1+xMg%nEGKRJr%&rG(TL-PJeH!#r}37j`sz8vZ4H zSUK(Y&0nid+9IKKBfXVnbIk)1SkZe(+kgBjv6rID(-q^~B>q&Z3um;G0wJ3gu`dv{ zPo@xsA+i7>f_xK=VsMXZ}W?x)$mRg8P5Ig1rt z?Ut^7AwIgXqE+?y;rmy~Y&Tg$wfkOOUqQpmgl13HCos z>SJ6k>%eS=QgaGZJ^4^WlB)kXSl6$G#g|Dq{c;4fghnBm{LPP)M`y>^ztAO1R``Zb>J@tfJ-P9#YGnM@tJ;{ncdSQ0Gu|Np* z!B<`GM2-a{gU@jbC3dgS^i3<09n0hcTy_nF1v-RJQVs7?853yd5#vHMcYniW4wjrI zcrV1Sm4c(Ek?t4}?^v2k#xe0aN#Z!7Nr~z$ApWXYXuaTfrR+e6>A(iVF4D{BE-h0@ zs;ddhmatQXKUDehE;6d7$|&^;8G9tf1XUOBbVZ^-=eRuKb!Kl!Y;SJ$E1 zxbX_r`wDKKms^XY+C{KwsKQB^-ZXaD^o}T|vpf@5z4K%i(a=>0-N1>Yaz*m|8Hawe z3aTt_4s?_X%mzVRzS8^$yhMZb*w<6(wfgGDgAiFiY}`M_9Krgw7HLoeO)rrNJbMSs z9p|39UNXI~)=ptt%Thh?AIvKj!cRkH5~Hj>Z0@DErpAz92K-a00|wu=?_;0CA<;AL z3@Uv_LAfD%5nwt5D*fzmaGpuBKUhy_9Yn-7JU0Ks7C~Omk7(RLdLckZERbM7ES8iL!}Mm0Zu4ee$xt0sk{w_I0gR>ojOIgW~cRL^9#NI8@zQD$32k zZMUxe(g-a1sR-X9^(7)y_oe=+D!OULt;iwCsD$w9tBAWo=#S*5)awHwK^UMbr%dL! zy|p=_=a}HQijLgZmFm()4(SMrD_D?Vn>^uQu)86Flu{Gx{wgJ({L-htQAqSf!W1o# z3Ggewd+`4semSWQ-Lh|Cc}$(j{kY2V8`O87V6T?KL#wsrpBoFDgxmX}G<3qC7d1-z zef?q7vE7o=EH64}NKU+q9y!FAZIUK!c}|1h(I?`DMWCZQt>sGOY!|CJkOHdIT`hs| zTjJd3o2hi7jtNXQXNAACM12j53OGS=AEscVW}lj4dk2Cgbi`O54eG#ZU=xngD8awi z;)Wtg@te~ihdjn%MK8b=psRcFjz#Z+YQVPsEDNRY8KFvOQr}<^U#4f+7OgMZylCN7 zxat4Y0x-aYNs6`qIEv@T|2Rs)8FYSvSe^Psl>D!egkFqfJ}cShTg5vb)_!>edJDTB zj|TT&r@(k|3hij#8QN2B0BcPfk^n$=pD#9s?o(Xzb( zL$pG#$3DJHuz>NOS%`w1dV@{4Bkx~ixbKdK`oV-d_HDf|i2DVcNh;Pw3do3maTt%G zaPT{EbAE(PYvleCJTuJ-Q|P`=jN|zPqUrcM)bg_2bP+V&C(MPbiF$ZEhCov6MmhrFvB1r|%{aKNC1UZR^^;f53^` z*9xOyaV}b$P8~&hPxZ3;cP`janSLfXXp?6*J4{53xG5Bak(|@bb=vnn%zqbg1=ctz zE5!IzHh<>N&AYEtKTNio$T0flUW`DNV2zkNKn0)r}MDNT_5>^}XjAn4n+ zh*}-Ou-{yP{5Bwg3LT-cEjm?k?pp%UkRa;15d#YdFP+Xd= zBGu9M?)kOjjWOuT;ER7nVbBR}-U zxUkgjROTubJ9=8qvu_ct-<+PP`g&`_oGRVN} z>eM-V?{ly&^x0Bs2Nnp}RoOMjLTUV9whFe_Wxsk6VfE)HtuhStEqZniOQ#)}>$@j=erCopPz{u zuPrjwTi{S^WwzO(F1c$~1l^iZnq~K>nPI(&-3GvngFCp8*5SK8e%xjvm5}3gl_1}) z9COq(W^k>*Cy!G#EQU`}uS{j$<3*T-nE)VN=lkJm3k?)~4T896^GgYdY)<|hPcY+FEeM<(Y_l5RO>08&GlV;$ ztmT@yR?zbtKFC_5AYYd55%F@lQy01M517tI8T4d>`j|rhc zW-=o9E1EAVo!lJoO7A~<(|Cf@JQ(qF;Ms|da7fbcwA%0azyVt%mi*V!cR@+V>Oje!Rz;rKBDCIt7pKZ7`%575cNuVet*)AW{!_ zuzU-oJ1ioK*Nt1k0iWrfSjK&tqvFBH`yF+~hyeg{8$c!|^HR1J->Yd25oIuel9r}% z#>lEe5xGjow0F*7S03bh{-woxjH$mj>Ap zQiY`t|7?ZuD;W5sPDhC~`a6F%xqZb8tGdES;py~VM=U@!PDOh=@@_O)+Y*wcjCsw~ zHSlKhir8*)r++=YpOsml5dOO#WhcFJ<0AUl8?BK~SkiCF_8-F%spCQxn3LKFGKB`F)X zTu-Be{$$dz*ubS#t0fqrj;RltI^O(gcPKja;mOkPZljqK3!P)d zjo|`qvC_HIsB0rFBgJ3e8&U%1K1U9hNw3hX774#bS?KyHG=Xucr+Zz5S=bO9{(psB zYYOK91wr>3i^cip1MThzDxZzQbv1$^5;f~n+_Gm|bkwSl=q$^BeJk+74kHsG3_Vw@ zIkzQYCo`j?e@Xjlbe&{@m#j7FvG@aN>rEMmtGy_56mk>geT#7kpp(6z4~7u*`Lyi_ z1U%-LDXklRC!CbG{+%60zFL8%?#Vs-{J9UtBSj?AGqpuu7UgcI(pQt;9z(_ej+vR8 zo$~ZNAo|Ty2DI_+h}n0mJ{elu$lGF+ZY-7u(fxy_1PI_Buj|ZLde&;3yz}uekJtGV z2{UaVjpqaCT%JPJEhigeP0klZ%+EfNCJEu11W_DU6)3uA&Y(|xRdBp8_pBy=ZoZ*w zqcz4F6?3o>+}fv;Dnx1@2*u9^pR@TkDkDDA0Og*v)PE5nN*EP`JVJ-+lC;Y^G+#%O zG|n5Td4o{OMn9E}?sNwycdSmJ%;u-EaPjI>+I% zuiUjWyJ5!$J0a>hnW0JfhbP%pVhI2-dimSMj#zVPg3(i_&~P(rLV;Xlgh~b0Mt6+AtE<4(bJ<^TE+m` z0&tmM_@Yi6SB2hpTFzW|E-l-aktBEVa9P(Boj3m|&mAq(Q2}v}yx`&L_lo+~GJ&Br zsxa*j)J3Gjr*-+ANIywBk35EsbQG))$Gcgj^2B@^8r1>eflV}_mn7BR@g?E$dc z7=S+esR^ugUL=|?@rPTFB3fH2d|t~| z!>sxU8Kk21#Lw#TeVN%6KUBu7>~BK5a)jAN_J6|QLu<0|vkLvT6|Wj zYU~g2VwCttf3w1=N1IWB-@R2Mm6J0iF;(rHx+ri9AGSCf*NXF}(`AN2YYTzrZP}Y_ zbem(G*YpCvkdj?p?q9vsTTp`VJ8J6>adWk)4TCYt>IIcPRJN+V8x~l%y4sP@jWPOL`?VlN^Z8Sh>Eq(X&*unMy89{-A73 z%qOs_ zSucXL#0>`S5_Lnbdg0jp?kdMetw)ctN7BdAPs+p^({r$`_!`q$1igF2AS~Dk&{4(M zUHmUfjc#AX;T>f!_53VSZl{2LIxgX#^36wUCDfu(m-3JcR|5}0DBvx+l{_0@+EOfz z^U>XOj&?Zzq3njf{exlR={Y$HZ!R`}LCL}@#^;gE?R4^|B?WfQMv&nr3K;l}Fn#G!5_ z=#}KZg#Ux(h@rR!s4O~L*1p55WDdAbhU{>96>LF$uFWq$o*T;ZSdpX*boiGe(J~p_S3ne zBIjPG5TZ@=Tdvb3YvRxL+~d}Byv8@bb9oS(*K6~T%)ka;VB9*?z476aQuCg zilFv^PhtfSHvSm7)HycPJRki5G?YxomjX;R+3mb6ps;K&xKvnrIA9lb0QIK)?#)Xv zXV7<588VPeqQL?+mqzflLm>&}veKoZ^0+1;fE`rpNL7KFJp~kRa8!YKvlpoBftGXE zf$;z;yTSkBvI>U=kHqzONKgr}y3A?Iqq0BKLDLkPCNnJ6(4B@3l5#R$N;!Lro_rGl z%?8oSCV$xvQ3*&yD*IPNs&iUw2b%5Pr7O_AQ?pR%B|Bi1Qy%Z&o`(FlcRwh(bi%222s_YiAx^lf!& zT>Ezzr*eUMC(qANU8>%jLLvQq-c1iD;*0OKc=lZp4p&ov$T(K+M!O+}t=V9hg@wg$ z6iT6`>6UKWBdxkOzt2Hpr!|e9H3x@wRu3ruu{c$2cQ=#$I=4P&<-|6wNs9a;JAudARH$2TRVKS-mFDRoYq z1vPISXKJ8PO}12h?&(?lSxYP7vqe65b|CJ#()Y~KfG1b+SXh^ne0?Gq3!f61AluUX z^VFou`qp`~&s74&LPh>mjtcl(YhYw_vTYuyuh9CnIB!hiV2zqi>ipWy+>?-zg0?$j zeH6MC@GIpyI(>KAU%GO>RwpFR!j+RVCuEpZl?x%Dy6BF7+bm@H=So9!qlc5lSwg1! z`7aGP>q_b{72iWKg(=~J{l}ENCeJ`sjgDyq!RaAG4@hSZLMdBd`E1xPd(JlhB02me z_naz6Ac_64<15Z%?C-TMgBNB;TiKP4NZr3RPavyl$*5OXRr`;v56NYZMI+ zo9p?7Lvg&^K1?az-J^KD(LN`Ekp*?Sb0+Z=O}zR-r9ge9F??YyRY7jiZpa+|J8^h@ zwuFb8rv%f!G5!Qci z%J71AY$=vhhU+Q@>8u|k=`#kIYYWrb=6OEbj<(nrASdIEvXPk4!wBRP@27 zIE(cl`Ja=3y#OSB)9(B&{W8Poemcnj%uF#iM95Q_Byl(XndXZtH*abTH+aaj)VgpMb3GRVHEJdd zs^DLMFj_eP{Rc1NMOp~E7R@`GJr%gr$e*Eu&3ZwL5lyTFSX8bu{?FjnpkwYrZQ_oG z%C1B?rt++RrWDDS#djnsJb9(lEeUc6jlDb`oopDQR_Hf zY}e^!DX*R!EK3-fa%_=Ze=563 zNfK3cppqy(Q(jbHSBv`j7l=?)70t;JsN6{1ZtysxWM*b&O72G;ZcFVG{EYXssdW{$?YIN#Dtrxj zbnn5el>43T&c!zo? zYsmO4nbxtkuO@AW59p+xs?&yY8PJV=Fi`Bk#NawNE}6X|<#83HZ-Bx|?K@Y$);$*4 zc`h78NbDC!D@VTt^U}?hw??KtLoD6)-AE3Be;XcNpD!;O!0O`m*`^E=bIHsz90=o= zDo|7>jPQQFpa$KsUsqzWt#z^`BbPX|St=f?K8-28XitI)f1Dg#|CZd5+s)&#cW4%d z%tBt+`e{mTjq$|Mi(jXgs#7{}eBBUq;WqzBv4*=#B1EoQ&5Zm}ibJz{C1;1SLgN?v zB!&1ys^S_=rK(tJ+d}IUH5z670_yue*A-cqpOXuO>wRMv!t8atc}HdSRgEB_(BLpN zy^xf-MC;n8v(^>&LEo&SBk7&PVsnBZ)6)`pq9u=nTB2SHig-<1lK6*az&ma0)(b&B`V_O5SKv zmXBQ7kEHj)9-wvy(o+Me_)TcKKGM*LFgCS~$njt7lcztBxut`t(!PHz&<_mX((L2R z+?FS%Gk#r<@67~rx#kbP5xUhg6X4~K_L>i!I_S-sY;f?BzL-J7ZtwTWmJef$;F71R z#|lz=^=qwAJ9sPwFBKkHe)-WMbg_Zx&t>rUeq<`=c}MfD7#k7&iDaGgu^>^aERz&UfSj+r(1ghOJ%j2 z{ns#JP8GYU{SZ=_eUX^o5eYmA2GYIbXa1Hu)j~OEA9tgB7Dvm2<#cXk-BJhBGJR>D zvS^l8HtnN4k@OKJZ0#P`ycZ7(oKDNKqQcnQ-JP)7{y7oAz+=|vsD<`kPc{DJ_sG9` zoI~f?lhfAdBe_4EL=5Q4ttTE4xBV>xhaUVi3T%rX92`JR|5EMmFYnIWlk#~=(|i;} zn#>+AptSm8j2<q6n7q*&5nq&^%gODx0=Cji2>czH4-Rckj!>L{EP2wnz6$ z>XCD`%kh5u1c5u?XtwuU%(A%9Lm--;SHMtWN?b0$Bl{gk^mQmksO3e z0jl6zegL z3JlC%Xas7qVfak)Ogd24-8atvYX*;w4C#HoH7{}H3T7YlKLWhSOJl(Jsf>QKzOT0I zY7);YD=S-zjr}U=zq^c0>^)VC;CH=g_vGR9I`vyB*??^NrXwm}X-VP1iaX%yb=;Z{ z{&9nT)&iG=>8tazg|71WaDvrCldurU0T0)9(dMxa9AGsApk)}*$-xIJs0Xbe@3rY% zuz~{63Z8K3V_;xDxLm;%_(O6G%#F(xlndtuE2sf=t)g>|1+Tv)BxHjqO_C*VB35v1 zbD-^$;H%cR;7cL$Pq1QA1zPMMR5ButK9)8V41n>-zl&+VSkyY_Cc!L>dFcW^(KVBA ze^Ylua4fPX1q+v?m>GKfYst#%7?@ZllwcziuH;l+1&t55;C0@&(RNk>J1PYljf21a zmON;1L;FHMoopKVeH&h=MD`H<4?Sj-Ot6G`(Yimx z2h8@$vpuj=lNCb1i+e$4Pb-r*%B8UMy%3Ixh5OB1zWrO9DmN=w6c%hOO_u3G`~T}7 apW{%lmJ+6mYHVKte`?CwcRnh@pZ^>7DU%lf literal 0 HcmV?d00001 From cb12dbb6cd0c0a96d77a7676ebb67b3235025d77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 16:33:38 -0500 Subject: [PATCH 0753/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a7818149..f6ee9b59 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. - `va-driver-all` is preinstalled - now using Ubuntu 21.10 - **misc** - - new GUI script (pms-copy-data.sh) to copy data from one Plex Media Server LXC to another Plex Media Server LXC (info inside script) + - new GUI script [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png) to copy data from one Plex Media Server LXC to another Plex Media Server LXC ## Initial Catch up - 2022-01-23 From d113923de78f73200bfe828fc1d3e25d2c7b6a35 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 16:34:22 -0500 Subject: [PATCH 0754/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f6ee9b59..0d95d18b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. - `va-driver-all` is preinstalled - now using Ubuntu 21.10 - **misc** - - new GUI script [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png) to copy data from one Plex Media Server LXC to another Plex Media Server LXC + - new GUI script [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/pms-copy-data.png) to copy data from one Plex Media Server LXC to another Plex Media Server LXC ## Initial Catch up - 2022-01-23 From 7617de71082097d6ec7f4fec77ec87b6c468a38e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 20:26:35 -0500 Subject: [PATCH 0755/6505] Add files via upload --- setup/jellyfin_setup.sh | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 setup/jellyfin_setup.sh diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh new file mode 100644 index 00000000..4fb4e09f --- /dev/null +++ b/setup/jellyfin_setup.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt-get -qqy install \ + curl \ + sudo \ + gnupg2 \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd \ + apt-transport-https \ + ca-certificates \ + git &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* + +echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" +wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" +apt update &>/dev/null +apt install jellyfin -y &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +sudo systemctl enable jellyfin +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From eb622e80b7ff1dea9fed12bde26ba3c0807663e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 20:27:25 -0500 Subject: [PATCH 0756/6505] Add files via upload --- ct/jellyfin_container.sh | 166 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 ct/jellyfin_container.sh diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh new file mode 100644 index 00000000..f4ed0a15 --- /dev/null +++ b/ct/jellyfin_container.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a Jellyfin Media Server LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for Storage Location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-21.10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=plex +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID jellyfin_setup.sh /jellyfin_setup.sh -perms 755 +pct exec $CTID /jellyfin_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Jellyfin Server LXC Container to $CTID at IP Address ${IP}:8096" \ No newline at end of file From d294bc9d1c67f0c2fe745f850056047c2dc3df27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 20:40:43 -0500 Subject: [PATCH 0757/6505] Add files via upload --- ct/jellyfin_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index f4ed0a15..47cda5da 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -138,7 +138,7 @@ else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi ARCH=$(dpkg --print-architecture) -HOSTNAME=plex +HOSTNAME=jellyfin TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ From 10e5e94860f165907ba45144a0c2d7633ed64eb6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 20:41:08 -0500 Subject: [PATCH 0758/6505] Add files via upload --- setup/jellyfin_setup.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 4fb4e09f..b42c2b12 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -33,7 +33,7 @@ echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Installing Dependecies... \e[0m" apt-get -qqy install \ curl \ sudo \ @@ -50,7 +50,8 @@ apt-get -qqy install \ /bin/chmod 660 /dev/dri/* echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key &>/dev/null +apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt update &>/dev/null @@ -67,6 +68,6 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -sudo systemctl enable jellyfin +sudo systemctl enable jellyfin &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From bbb40327eebb75edcde322e5d68f4d84676b931d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 20:50:30 -0500 Subject: [PATCH 0759/6505] Add files via upload --- setup/jellyfin_setup.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index b42c2b12..8079ad0b 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -33,7 +33,7 @@ echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Dependecies... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ curl \ sudo \ @@ -50,8 +50,7 @@ apt-get -qqy install \ /bin/chmod 660 /dev/dri/* echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key &>/dev/null -apt-key add - &>/dev/null +wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt update &>/dev/null From e30af5d2cb67f35f76498f0c576bf719f6d58e62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 20:57:20 -0500 Subject: [PATCH 0760/6505] Add files via upload --- ct/jellyfin_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index 47cda5da..0bdcacb6 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -108,8 +108,8 @@ info "Container ID is $CTID." echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 +OSTYPE=debian +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 504fdf9085a4702a330d3ca778e1de041bde66cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 21:08:17 -0500 Subject: [PATCH 0761/6505] Update README.md --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index f90cee3c..ca0369ee 100644 --- a/README.md +++ b/README.md @@ -652,6 +652,34 @@ ________________________________________________________________________________
+
+🔸Jellyfin Media Server LXC + +

+ +

Jellyfin Media Server LXC

+

With Hardware Acceleration Support

+To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox web shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/jellyfin_container.sh)" +``` +

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. + +**Jellyfin Media Server Interface - IP:8096** + +⚙️ **To Update Jellyfin Media Server:** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
From 1dac089e3e7219472a91a63b7835cce25b23c2bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 21:12:28 -0500 Subject: [PATCH 0762/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0d95d18b..e8dea4f4 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,7 +1,14 @@ # Change Log All notable changes to this project will be documented in this file. - + +## 2022-01-25 + +### Changed + +- **Jellyfin Media Server LXC** + - new script + ## 2022-01-24 ### Changed From c61192f51f2cd76855d3b836d683481153461360 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 21:17:54 -0500 Subject: [PATCH 0763/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 8079ad0b..b6f1ccb6 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -50,7 +50,7 @@ apt-get -qqy install \ /bin/chmod 660 /dev/dri/* echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +wget -Oq - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt update &>/dev/null From 54cbf90440a8ec02733cfe01aef0ead43f4af988 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jan 2022 21:24:07 -0500 Subject: [PATCH 0764/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index b6f1ccb6..8079ad0b 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -50,7 +50,7 @@ apt-get -qqy install \ /bin/chmod 660 /dev/dri/* echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -wget -Oq - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt update &>/dev/null From e468e738f2611e236f7d03062c7b3549c6774097 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jan 2022 04:22:23 -0500 Subject: [PATCH 0765/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca0369ee..e0546ea7 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ ________________________________________________________________________________
-🔸Home Assistant Container LXC +Home Assistant Container LXC

Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

From 01a73379bfd7610c4f0b605e4fdec86df4f6e051 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jan 2022 11:13:08 -0500 Subject: [PATCH 0766/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 8079ad0b..3c480e4d 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -50,7 +50,7 @@ apt-get -qqy install \ /bin/chmod 660 /dev/dri/* echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt update &>/dev/null From f5d39291c25e2320427582e07bae1640000a2e77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jan 2022 11:22:41 -0500 Subject: [PATCH 0767/6505] Update npm_setup.sh --- setup/npm_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 8adba8aa..78df2a23 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -54,7 +54,7 @@ apt-get -qqy upgrade &>/dev/null #fi # Install openresty echo -e "${CHECKMARK} \e[1;92m Installing Openresty... \e[0m" -wget -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null +wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null apt-get -y update &>/dev/null From 3fb4ca73609de1928892114a194a4da582fde6c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jan 2022 11:43:07 -0500 Subject: [PATCH 0768/6505] Update npm_setup.sh --- setup/npm_setup.sh | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 78df2a23..53dcb7b0 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -23,25 +23,21 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null -# Update container OS echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null - # Install dependencies echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo "fs.file-max = 65535" > /etc/sysctl.conf apt-get update &>/dev/null apt-get -y install --no-install-recommends sudo curl wget gnupg openssl ca-certificates apache2-utils logrotate build-essential python3-dev git lsb-release &>/dev/null - # Install Python echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null pip3 install --upgrade setuptools &>/dev/null @@ -51,8 +47,7 @@ apt-get -qqy upgrade &>/dev/null python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null fi python3 -m pip install --no-cache-dir cffi certbot &>/dev/null -#fi - # Install openresty + echo -e "${CHECKMARK} \e[1;92m Installing Openresty... \e[0m" wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null @@ -69,30 +64,25 @@ sudo apt-get install -y nodejs git make g++ gcc &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Yarn... \e[0m" npm install --global yarn &>/dev/null -# Download nginx-proxy-manager source echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.15... \e[0m" -wget https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.15 -O - | tar -xz &>/dev/null +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.15 -O - | tar -xz &>/dev/null cd ./nginx-proxy-manager-2.9.15 -# Crate required symbolic links echo -e "${CHECKMARK} \e[1;92m Setting up Enviroment... \e[0m" ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -# Update NPM version in package.json files sed -i "s+0.0.0+#v2.9.15+g" backend/package.json sed -i "s+0.0.0+#v2.9.15+g" frontend/package.json -# Fix nginx config files for use with openresty defaults sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" done -# Copy runtime files mkdir -p /var/www/html /etc/nginx/logs cp -r docker/rootfs/var/www/html/* /var/www/html/ cp -r docker/rootfs/etc/nginx/* /etc/nginx/ @@ -101,7 +91,6 @@ cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-prox ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf rm -f /etc/nginx/conf.d/dev.conf -# Create required folders mkdir -p /tmp/nginx/body \ /run/nginx \ /data/nginx \ @@ -122,21 +111,17 @@ mkdir -p /tmp/nginx/body \ chmod -R 777 /var/cache/nginx chown root /tmp/nginx -# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf -# Generate dummy self-signed certificate. if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null fi -# Copy app files mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global -# Build the frontend echo -e "${CHECKMARK} \e[1;92m Building Frontend... \e[0m" cd ./frontend export NODE_ENV=development @@ -145,7 +130,6 @@ yarn build &>/dev/null cp -r dist/* /app/frontend cp -r app-images/* /app/frontend/images -# Initialize backend echo -e "${CHECKMARK} \e[1;92m Initializing Backend... \e[0m" rm -rf /app/config/default.json &>/dev/null if [ ! -f /app/config/production.json ]; then @@ -165,9 +149,8 @@ EOF fi cd /app export NODE_ENV=development -yarn install --network-timeout=30000 +yarn install --network-timeout=30000 &>/dev/null -# Create NPM service echo -e "${CHECKMARK} \e[1;92m Creating NPM Service... \e[0m" cat << 'EOF' > /lib/systemd/system/npm.service [Unit] @@ -201,7 +184,6 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -# Start services echo -e "${CHECKMARK} \e[1;92m Starting Services... \e[0m" systemctl enable npm &>/dev/null systemctl start openresty From 0a36b214e58a05f61cecb3931fd714767d154704 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jan 2022 16:27:56 -0500 Subject: [PATCH 0769/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e0546ea7..dc4607c3 100644 --- a/README.md +++ b/README.md @@ -725,6 +725,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/a

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

**AdGuard Home Interface - IP:3000** + +(For the Home Assistant Integration, use port `80` not `3000`) ____________________________________________________________________________________________ From 8fd72d9bd7306934009dff75a20acb6a544c1c18 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jan 2022 16:31:40 -0500 Subject: [PATCH 0770/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc4607c3..af669361 100644 --- a/README.md +++ b/README.md @@ -726,7 +726,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/a **AdGuard Home Interface - IP:3000** -(For the Home Assistant Integration, use port `80` not `3000`) + (For the Home Assistant Integration, use port `80` not `3000`) ____________________________________________________________________________________________ From 59fe80565ecbfe0408f9916dff6b01d36539aa45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jan 2022 17:45:25 -0500 Subject: [PATCH 0771/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af669361..e8290a70 100644 --- a/README.md +++ b/README.md @@ -724,7 +724,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/a ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

-**AdGuard Home Interface - IP:3000** +**AdGuard Home Setup Interface - IP:3000 (After Setup use only IP)** (For the Home Assistant Integration, use port `80` not `3000`) From 968d36d785ea9df4ae97f6cdbacfcfff92b3369f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 08:59:09 -0500 Subject: [PATCH 0772/6505] Update plex_setup.sh --- setup/plex_setup.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index f7bd0e76..2c2dfb95 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -33,11 +33,14 @@ echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ curl \ sudo \ - gnupg \ + gnupg &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" +apt-get -y install \ va-driver-all \ ocl-icd-libopencl1 \ beignet-opencl-icd &>/dev/null From 94fe29b478943abeb6300a87daebc14b5b77f5b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 09:16:31 -0500 Subject: [PATCH 0773/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 3c480e4d..d9d9febe 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -38,13 +38,16 @@ apt-get -qqy install \ curl \ sudo \ gnupg2 \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd \ apt-transport-https \ ca-certificates \ git &>/dev/null - + +echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* From 64c0ecb36b07e7481bd7adfd89f3f79f7e3779b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 13:55:13 -0500 Subject: [PATCH 0774/6505] Update plex_setup.sh --- setup/plex_setup.sh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index 2c2dfb95..59d5cdd6 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null @@ -49,16 +47,13 @@ apt-get -y install \ /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* -echo -e "${CHECKMARK} \e[1;92m Downloading Plex Media Server... \e[0m" -wget https://downloads.plex.tv/plex-media-server-new/1.25.3.5409-f11334058/debian/plexmediaserver_1.25.3.5409-f11334058_amd64.deb &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" -sudo dpkg -i plexmediaserver_1.25.3.5409-f11334058_amd64.deb &>/dev/null - -cat < /etc/apt/sources.list.d/plexmediaserver.list -deb https://downloads.plex.tv/repo/deb/ public main -EOF - +echo -e "${CHECKMARK} \e[1;92m Setting Up Plex Media Server Repository... \e[0m" wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://downloads.plex.tv/repo/deb/ public main" | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" +apt-get update &>/dev/null +apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin @@ -72,4 +67,4 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /plex_setup.sh /plexmediaserver_1.25.3.5409-f11334058_amd64.deb /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 8d3fd7e285b473d261350b7a81caf268caa56b2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 13:57:37 -0500 Subject: [PATCH 0775/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index d9d9febe..4376234d 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 1030c0d0388bf7db73bfb214751d1f4eb06d3594 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:21:02 -0500 Subject: [PATCH 0776/6505] Update adguard_setup.sh --- setup/adguard_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/adguard_setup.sh b/setup/adguard_setup.sh index e29e9a5d..93c24680 100644 --- a/setup/adguard_setup.sh +++ b/setup/adguard_setup.sh @@ -25,8 +25,6 @@ function msg() { msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null msg "Updating Container OS..." apt update &>/dev/null From 5db5c8d4963b77b6d810063d6d4d830f4dd3586a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:21:24 -0500 Subject: [PATCH 0777/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index 0bca50d1..bac25430 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -27,8 +27,6 @@ function msg() { msg "Setting up container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." From 9a3091332bd025d4a2d74d1c154348d969d69c2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:21:49 -0500 Subject: [PATCH 0778/6505] Update esphome_setup.sh --- setup/esphome_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh index 86fb104d..9c0b8bc2 100644 --- a/setup/esphome_setup.sh +++ b/setup/esphome_setup.sh @@ -27,8 +27,6 @@ function msg() { msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." From fef7d3873fed8c8f438606aed197e5450635df2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:22:15 -0500 Subject: [PATCH 0779/6505] Update ha_setup.sh --- setup/ha_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index be213ee0..55a440bd 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 3170869e1389f8a551b73521f65635f74ab8c199 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:22:41 -0500 Subject: [PATCH 0780/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 7824e616..9150147d 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -27,8 +27,6 @@ function msg() { msg "Setting up container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." From 9d5447db08838ef1d2ac638cdff9329de157fac0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:23:07 -0500 Subject: [PATCH 0781/6505] Update mqtt_setup.sh --- setup/mqtt_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh index 31e96b5f..72c98677 100644 --- a/setup/mqtt_setup.sh +++ b/setup/mqtt_setup.sh @@ -27,8 +27,6 @@ function msg() { msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null # Update container OS msg "Updating Container OS..." From 402c47de86cf722fab4aa9a9e2491b014d396352 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:23:36 -0500 Subject: [PATCH 0782/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index 0f314261..24db56b9 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -29,8 +29,6 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null msg "Updating container OS..." -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null msg "Installing prerequisites..." apt-get -qqy install \ From 633073a410f024d9bdae2d3c5416c2469d71e883 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:24:03 -0500 Subject: [PATCH 0783/6505] Update npm_setup.sh --- setup/npm_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 53dcb7b0..1a283c79 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From d098b175deb91c5ade69d9d75eebedb84610fae7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:24:31 -0500 Subject: [PATCH 0784/6505] Update pihole_setup.sh --- setup/pihole_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh index b47a39ff..220f1959 100644 --- a/setup/pihole_setup.sh +++ b/setup/pihole_setup.sh @@ -25,8 +25,6 @@ function msg() { msg "Setting up LXC OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." From 8bf0e369c3db17685cc52921befe53e067045565 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:25:00 -0500 Subject: [PATCH 0785/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 66a70e08..08c311fb 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From afc52f825cbdcd421f7ff7c012609a433133d19a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:25:28 -0500 Subject: [PATCH 0786/6505] Update ubuntu_setup.sh --- setup/ubuntu_setup.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh index 97870853..7f40a0a1 100644 --- a/setup/ubuntu_setup.sh +++ b/setup/ubuntu_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" apt update &>/dev/null @@ -52,4 +50,4 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /ubuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /ubuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 67a668f2fc7ce954b24953864c6f9fc517f939d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:25:57 -0500 Subject: [PATCH 0787/6505] Update zigbee2mqtt_setup.sh --- setup/zigbee2mqtt_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh index fabb3dd6..683f2491 100644 --- a/setup/zigbee2mqtt_setup.sh +++ b/setup/zigbee2mqtt_setup.sh @@ -27,8 +27,6 @@ function msg() { msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null # Update container OS msg "Updating container OS..." From fea89220215e9542f05b349cbf18ebbdf16f1e0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 14:26:25 -0500 Subject: [PATCH 0788/6505] Update zwavejs2mqtt_setup.sh --- setup/zwavejs2mqtt_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/zwavejs2mqtt_setup.sh b/setup/zwavejs2mqtt_setup.sh index 02566c86..bb2db5ae 100644 --- a/setup/zwavejs2mqtt_setup.sh +++ b/setup/zwavejs2mqtt_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 3b1e43cec0e34bc25f75ebd6fa9f4b29f451d413 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 15:55:55 -0500 Subject: [PATCH 0789/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index 0bdcacb6..a76f4a88 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -148,8 +148,8 @@ LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file EOF @@ -163,4 +163,4 @@ pct push $CTID jellyfin_setup.sh /jellyfin_setup.sh -perms 755 pct exec $CTID /jellyfin_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Jellyfin Server LXC Container to $CTID at IP Address ${IP}:8096" \ No newline at end of file +info "Successfully created a Jellyfin Server LXC Container to $CTID at IP Address ${IP}:8096" From e692f53107612cee5ddd71f14674e006297e5ba0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 16:00:18 -0500 Subject: [PATCH 0790/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 4376234d..a093c31b 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -68,6 +68,8 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -sudo systemctl enable jellyfin &>/dev/null +usermod -a -G input jellyfin +usermod -a -G render jellyfin +systemctl enable jellyfin &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 0d70ba79b471d4dd077d35518ab410e1bb23677d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 16:13:58 -0500 Subject: [PATCH 0791/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index a093c31b..cade60a8 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -26,6 +26,8 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +apt-get -y purge openssh-{client,server} >/dev/null +apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From e7cd11304e0ab30fc97acbc384ea35682d0b76f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jan 2022 16:25:17 -0500 Subject: [PATCH 0792/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index cade60a8..a093c31b 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -26,8 +26,6 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 37d19c608bbf70b7cf4cd2ab338b017ec68867da Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Jan 2022 07:42:17 -0500 Subject: [PATCH 0793/6505] Update README.md --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e8290a70..45207cdc 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ ________________________________________________________________________________

@home-assistant

-

Proxmox Home Assistant OS VM

+

Home Assistant OS VM

To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell @@ -80,7 +80,7 @@ ________________________________________________________________________________

@home-assistant

-

Proxmox Podman Home Assistant Container LXC

+

Podman Home Assistant Container LXC

With ZFS Filesystem Support

To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. @@ -135,7 +135,7 @@ ________________________________________________________________________________

Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

-

Proxmox Home Assistant Container LXC

+

Home Assistant Container LXC

With ZFS Filesystem Support

To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. @@ -201,7 +201,7 @@ ________________________________________________________________________________

Logo

-

Proxmox ESPHome LXC Container

+

ESPHome LXC Container

To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. @@ -225,7 +225,7 @@ ________________________________________________________________________________

hero

-

Proxmox Nginx Proxy Manager LXC Container

+

Nginx Proxy Manager LXC Container

To create a new Proxmox Nginx Proxy Manager LXC Container, run the following from Proxmox web shell. @@ -271,7 +271,7 @@ Add the following to your `configuration.yaml` in Home Assistant.

-

Proxmox MQTT LXC Container

+

MQTT LXC Container

To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. @@ -324,7 +324,7 @@ ________________________________________________________________________________

@node-red

-

Proxmox Node-Red LXC Container

+

Node-Red LXC Container

To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. @@ -366,7 +366,7 @@ ________________________________________________________________________________

MariaDB

-

Proxmox Mariadb LXC Container

+

Mariadb LXC Container

To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. @@ -477,7 +477,7 @@ ________________________________________________________________________________

logo.png

-

Proxmox Zigbee2MQTT LXC Container

+

Zigbee2MQTT LXC Container

To create a new Proxmox [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. @@ -555,7 +555,7 @@ ________________________________________________________________________________

-

Proxmox Zwavejs2MQTT LXC Container

+

Zwavejs2MQTT LXC Container

To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. @@ -586,7 +586,7 @@ ________________________________________________________________________________

Debian

-

Proxmox Debian 11 LXC Container

+

Debian 11 LXC Container

To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. @@ -607,7 +607,7 @@ ________________________________________________________________________________

Ubuntu

-

Proxmox Ubuntu 21.10 LXC Container

+

Ubuntu 21.10 LXC Container

To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. From eed64c988685a755f2a81949d367d782d4fa9d3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Jan 2022 11:29:44 -0500 Subject: [PATCH 0794/6505] Update pihole_setup.sh --- setup/pihole_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh index 220f1959..f05611f9 100644 --- a/setup/pihole_setup.sh +++ b/setup/pihole_setup.sh @@ -32,7 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." -apt-get -qqy install \ +apt-get -y install \ curl \ sudo &>/dev/null From 219cf5ddbbf12e6394f3263157fa14438ebecbb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Jan 2022 11:35:28 -0500 Subject: [PATCH 0795/6505] Update pihole_setup.sh --- setup/pihole_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh index f05611f9..220f1959 100644 --- a/setup/pihole_setup.sh +++ b/setup/pihole_setup.sh @@ -32,7 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." -apt-get -y install \ +apt-get -qqy install \ curl \ sudo &>/dev/null From b77ed359012fd2c1820a605a4d66b7d4659203db Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 17:18:36 -0500 Subject: [PATCH 0796/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index 24db56b9..0f314261 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -29,6 +29,8 @@ apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null msg "Updating container OS..." +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null msg "Installing prerequisites..." apt-get -qqy install \ From e1d3255454c20f79038fbdbfc5743d8af372e5f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 17:43:34 -0500 Subject: [PATCH 0797/6505] Update node-red_container.sh --- ct/node-red_container.sh | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/ct/node-red_container.sh b/ct/node-red_container.sh index d287e88f..9d205279 100644 --- a/ct/node-red_container.sh +++ b/ct/node-red_container.sh @@ -9,13 +9,13 @@ while true; do esac done -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -73,13 +73,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Download setup script wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red_setup.sh -# Detect modules and automatically load at boot load_module overlay -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -106,14 +103,12 @@ else fi info "Using '$STORAGE' for storage location." -# Get the next guest VM/LXC ID CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -121,7 +116,6 @@ TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in dir|nfs) @@ -136,8 +130,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -# Create LXC -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -152,18 +145,14 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -# Setup container -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 pct exec $CTID /node-red_setup.sh -# Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Node-RED LXC Container to $CTID at IP Address ${IP}" +info "Successfully Created Node-RED LXC Container to $CTID at IP Address ${IP}:1880" From 09c095a87ab1af6f55492d048940d8c72dd2a94b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 17:51:08 -0500 Subject: [PATCH 0798/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index 0f314261..32e1a84f 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -6,6 +6,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap 'die "Script interrupted."' INT @@ -23,38 +24,26 @@ function msg() { } msg "Setting up container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null apt-get -y purge openssh-{client,server} >/dev/null apt-get autoremove >/dev/null msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -msg "Installing prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencie... \e[0m" apt-get -qqy install \ curl \ sudo &>/dev/null -msg "Installing Node-Red..." +echo -e "${CHECKMARK} \e[1;92m Installing Node-Red... \e[0m" bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi -#msg "Installing Node..." -#sudo apt -y install nodejs npm &>/dev/null - -#msg "Installing PM2..." -#npm install -g pm2 &>/dev/null - -#msg "Installing Node-RED..." -#npm install -g --unsafe-perm node-red &>/dev/null - -#msg "Setting up PM2..." -#/usr/local/bin/pm2 start /usr/local/bin/node-red &>/dev/null -#/usr/local/bin/pm2 save &>/dev/null -#/usr/local/bin/pm2 startup &>/dev/null - -msg "Customizing container..." +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" rm /etc/motd # Remove message of the day after login rm /etc/update-motd.d/10-uname # Remove kernel information after login touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login @@ -67,6 +56,7 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -msg "Cleanup..." +node-red-start &>/dev/null +systemctl enable nodered.service &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 8e962f83a28354cd82717c1b2aeb0c681fa86f00 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 17:53:04 -0500 Subject: [PATCH 0799/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index 32e1a84f..8cd812d8 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -23,14 +23,10 @@ function msg() { echo -e "$TEXT" } -msg "Setting up container OS..." echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -apt-get -y purge openssh-{client,server} >/dev/null -apt-get autoremove >/dev/null -msg "Updating container OS..." echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From dab8a7388d45064621fd5adab90bd946e6cca0e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 17:54:17 -0500 Subject: [PATCH 0800/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index 8cd812d8..a3100e96 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -40,9 +40,9 @@ echo -e "${CHECKMARK} \e[1;92m Installing Node-Red... \e[0m" bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE From 0cf3512f96003d17a7d8ad6bfd1c78cf19bfc0bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 18:04:17 -0500 Subject: [PATCH 0801/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index a3100e96..a78d78a2 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -52,7 +52,7 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -node-red-start &>/dev/null +systemctl start nodered.service &>/dev/null systemctl enable nodered.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 54f4c8077666f2f3946bda7a9940175d221565f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 18:10:11 -0500 Subject: [PATCH 0802/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index a78d78a2..8a4acd99 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -31,7 +31,7 @@ echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Dependencie... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ curl \ sudo &>/dev/null From 2f7a7b2abac6d66e16061736d3c4d26d32c93c54 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 18:21:03 -0500 Subject: [PATCH 0803/6505] Update README.md --- README.md | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 45207cdc..bad1dc7c 100644 --- a/README.md +++ b/README.md @@ -334,17 +334,12 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/n ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

-From your nodered LXC console, the following commands can be run - -`node-red-start` to start Node-Red +⚙️ **To Restart Node-Red:** -`systemctl enable nodered.service` to autostart Node-RED at every boot - -`node-red-restart` to restart Node-Red - -`systemctl disable nodered.service` to disable autostart on boot - -**Node-Red Interface - IP:1880** +Run from the LXC console +```yaml +node-red-restart +``` ⚙️ **To Update Node-Red:** @@ -352,7 +347,7 @@ Run from the LXC console ```yaml npm install -g --unsafe-perm node-red ``` -(`node-red-restart` after update) +(Restart after update) ____________________________________________________________________________________________ From e6ea0fdbf1a370ee2639836d3ab341e298ee0374 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 18:25:53 -0500 Subject: [PATCH 0804/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bad1dc7c..fb3cf877 100644 --- a/README.md +++ b/README.md @@ -334,6 +334,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/n ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

+**Node-Red Interface - IP:1880** + ⚙️ **To Restart Node-Red:** Run from the LXC console From 675635ebfa233f0d8ae9da8ac552c75c5af1d933 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 18:57:46 -0500 Subject: [PATCH 0805/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index fb3cf877..2f948534 100644 --- a/README.md +++ b/README.md @@ -345,11 +345,10 @@ node-red-restart ⚙️ **To Update Node-Red:** -Run from the LXC console +Run from the LXC console (Restart after update) ```yaml npm install -g --unsafe-perm node-red ``` -(Restart after update) ____________________________________________________________________________________________ From a9a5d1f3a2a34f51cf94e302d0022c94a5152002 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 19:55:55 -0500 Subject: [PATCH 0806/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f948534..a50eef46 100644 --- a/README.md +++ b/README.md @@ -322,7 +322,7 @@ ________________________________________________________________________________
Node-Red LXC -

@node-red

+

@node-red

Node-Red LXC Container

From 7b4cb16a30417ded4338329896b06d2e19b5ccbd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 20:27:19 -0500 Subject: [PATCH 0807/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e8dea4f4..1c190f62 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-01-29 + +### Changed + +- **Node-Red LXC** + - Clean up / Improve script + ## 2022-01-25 ### Changed From 6ef6abf47461740fcb07cc071033137bf4ded502 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 20:29:33 -0500 Subject: [PATCH 0808/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a50eef46..53d1c388 100644 --- a/README.md +++ b/README.md @@ -320,7 +320,7 @@ ________________________________________________________________________________
-Node-Red LXC +🔸Node-Red LXC

@node-red

From 30e43fecb492f60f03e9f4b43db8886bc0f6c8d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 22:01:20 -0500 Subject: [PATCH 0809/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index 8a4acd99..ac449961 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -37,7 +37,7 @@ apt-get -qqy install \ sudo &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Node-Red... \e[0m" -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" rm /etc/motd From d2b54a98e2e00f100724b51c8ac15d639231e8eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 22:31:22 -0500 Subject: [PATCH 0810/6505] Update node-red_container.sh --- ct/node-red_container.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/node-red_container.sh b/ct/node-red_container.sh index 9d205279..f2e09f7c 100644 --- a/ct/node-red_container.sh +++ b/ct/node-red_container.sh @@ -155,4 +155,7 @@ pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 pct exec $CTID /node-red_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Node-RED LXC Container to $CTID at IP Address ${IP}:1880" +info "Successfully Created Node-Red LXC to $CTID." +echo -e "\e[1;92m Node-Red should be reachable by going to the following URL. + http://${IP}:1880 +\e[0m" From 9d09ba73dcad2f8386d052ab088e6ce8c91683c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 22:47:18 -0500 Subject: [PATCH 0811/6505] Update npm_container.sh --- ct/npm_container.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/npm_container.sh b/ct/npm_container.sh index 4e6c7c64..db1c02f4 100644 --- a/ct/npm_container.sh +++ b/ct/npm_container.sh @@ -156,4 +156,7 @@ pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 pct exec $CTID /npm_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a NPM LXC to $CTID at IP Address ${IP}:81" +info "Successfully Created Nginx Proxy Manager LXC to $CTID." +echo -e "\e[1;92m Nginx Proxy Manager should be reachable by going to the following URL. + http://${IP}:81 +\e[0m" From b6f8f9e1f82a6094a72243eaab26c93f5a2dd6c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jan 2022 22:49:36 -0500 Subject: [PATCH 0812/6505] Update plex_container.sh --- ct/plex_container.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index 712aa44a..b068ae9a 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -163,4 +163,7 @@ pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 pct exec $CTID /plex_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Plex Media Server LXC Container to $CTID at IP Address ${IP}:32400/web" +info "Successfully Created Plex Media Server LXC to $CTID." +echo -e "\e[1;92m Plex Media Server should be reachable by going to the following URL. + http://${IP}:32400/web +\e[0m" From b059e633a415c9fe1a3a575e7f0a77ac14f250ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 02:30:39 -0500 Subject: [PATCH 0813/6505] Update zigbee2mqtt_container.sh --- ct/zigbee2mqtt_container.sh | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/ct/zigbee2mqtt_container.sh b/ct/zigbee2mqtt_container.sh index 1c19adfb..d3676dab 100644 --- a/ct/zigbee2mqtt_container.sh +++ b/ct/zigbee2mqtt_container.sh @@ -9,13 +9,13 @@ while true; do esac done -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -73,13 +73,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Download setup script wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt_setup.sh -# Detect modules and automatically load at boot load_module overlay -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -106,22 +103,19 @@ else fi info "Using '$STORAGE' for storage location." -# Get the next guest VM/LXC ID CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." + die "A problem occured while downloading the LXC Template." -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in dir|nfs) @@ -136,8 +130,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -# Create LXC -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -152,29 +145,25 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -# Modify LXC permissions to support Zigbee Sticks LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF -# Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -# Setup container -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID zigbee2mqtt_setup.sh /zigbee2mqtt_setup.sh -perms 755 pct exec $CTID /zigbee2mqtt_setup.sh -# Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" echo -echo -e "\e[1;31m Update of configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" +echo -e "\e[1;31m Updating the configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" echo -echo -e "Z2M can be started after completing the configuration buy running \e[1;33m sudo systemctl start zigbee2mqtt \e[0m" +echo -e "Z2M can be started after completing the configuration buy running \e[1;33m systemctl start zigbee2mqtt \e[0m" echo From 25a3ade9992db594ccb5b8b3c796ce7d83b7bba2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 02:32:29 -0500 Subject: [PATCH 0814/6505] Update npm_container.sh --- ct/npm_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/npm_container.sh b/ct/npm_container.sh index db1c02f4..efc67e28 100644 --- a/ct/npm_container.sh +++ b/ct/npm_container.sh @@ -150,7 +150,7 @@ MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -echo -e "${CHECKMARK} \e[1;92m Starting LXC...... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" pct start $CTID pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 pct exec $CTID /npm_setup.sh From 33b3cf541b13c4ae21fa284a151f2f5701715812 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 02:49:20 -0500 Subject: [PATCH 0815/6505] Update zigbee2mqtt_setup.sh --- setup/zigbee2mqtt_setup.sh | 60 +++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh index 683f2491..3490e947 100644 --- a/setup/zigbee2mqtt_setup.sh +++ b/setup/zigbee2mqtt_setup.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap 'die "Script interrupted."' INT @@ -23,38 +23,33 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS -msg "Setting up Container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -# Update container OS -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -# Install prerequisites -msg "Installing Prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ curl \ sudo &>/dev/null - # Setup Node.js repository - msg "Setting up Node.js Repository..." - sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null - # Install Node.js; - msg "Installing Node.js..." - sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - # Clone Zigbee2MQTT repository - msg "Setting up Zigbee2MQTT Repository..." - sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null - # Install zigbee2mqtt - msg "Installing Zigbee2MQTT..." - cd /opt/zigbee2mqtt &>/dev/null - npm ci &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" +sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting up Zigbee2MQTT Repository... \e[0m" +sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Zigbee2MQTT... \e[0m" +cd /opt/zigbee2mqtt &>/dev/null +npm ci &>/dev/null -echo "Creating service file zigbee2mqtt.service" service_path="/etc/systemd/system/zigbee2mqtt.service" - echo "[Unit] Description=zigbee2mqtt After=network.target @@ -68,11 +63,9 @@ User=root [Install] WantedBy=multi-user.target" > $service_path -# Customize container -msg "Customizing Container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE @@ -82,7 +75,6 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." +systemctl enable zigbee2mqtt.service &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 771a237534861a914eea7b0de089df3de019d73e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 03:04:28 -0500 Subject: [PATCH 0816/6505] Update zigbee2mqtt_setup.sh --- setup/zigbee2mqtt_setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh index 3490e947..b82d08f4 100644 --- a/setup/zigbee2mqtt_setup.sh +++ b/setup/zigbee2mqtt_setup.sh @@ -64,7 +64,8 @@ User=root WantedBy=multi-user.target" > $service_path echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -chmod -x /etc/update-motd.d/* +rm /etc/motd +rm /etc/update-motd.d/10-uname touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) From c50528e0faecbb8a988bd9197daf9302a539792b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 03:08:57 -0500 Subject: [PATCH 0817/6505] Update README.md --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 53d1c388..c78cab3f 100644 --- a/README.md +++ b/README.md @@ -475,7 +475,7 @@ ________________________________________________________________________________

Zigbee2MQTT LXC Container

-To create a new Proxmox [Zigbee2MQTT](https://www.zigbee2mqtt.io/) LXC Container, run the following from Proxmox web shell. +To create a new Proxmox Zigbee2MQTT LXC Container, run the following from Proxmox web shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt_container.sh)" @@ -530,12 +530,8 @@ advanced: ``` ⚙️ **Zigbee2mqtt can be started after completing the configuration** ```yaml -sudo systemctl start zigbee2mqtt +systemctl start zigbee2mqtt ``` -⚙️ **To start Zigbee2MQTT automatically on boot** - ```yaml -sudo systemctl enable zigbee2mqtt.service - ``` ⚙️ **To update Zigbee2Mqtt** ```yaml bash /opt/zigbee2mqtt/update.sh From 025c74b62af22f4c73743732b7ae0af508dcae1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 03:44:35 -0500 Subject: [PATCH 0818/6505] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c78cab3f..89ab0b86 100644 --- a/README.md +++ b/README.md @@ -530,7 +530,8 @@ advanced: ``` ⚙️ **Zigbee2mqtt can be started after completing the configuration** ```yaml -systemctl start zigbee2mqtt +cd /opt/zigbee2mqtt +npm start ``` ⚙️ **To update Zigbee2Mqtt** ```yaml From f73866f1980022df7be47cdb5c7eb3546c051e3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 03:51:40 -0500 Subject: [PATCH 0819/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1c190f62..99335bce 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-01-30 + +### Changed + +- **Zigbee2MQTT LXC** + - Clean up / Improve script + ## 2022-01-29 ### Changed From 1fc4377c371016c9be71ee5100b21d4affbe3683 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 03:59:42 -0500 Subject: [PATCH 0820/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 89ab0b86..a645b258 100644 --- a/README.md +++ b/README.md @@ -468,12 +468,12 @@ ________________________________________________________________________________
-Zigbee2MQTT LXC +🔸Zigbee2MQTT LXC

logo.png

-

Zigbee2MQTT LXC Container

+

Zigbee2MQTT LXC Container

To create a new Proxmox Zigbee2MQTT LXC Container, run the following from Proxmox web shell. @@ -495,7 +495,7 @@ Reboot the LXC to apply the changes ⚙️ **Determine the location of your adapter** -Run in the zigbee2mqtt console +Run in the Zigbee2MQTT console ```yaml ls -l /dev/serial/by-id ``` @@ -528,12 +528,12 @@ advanced: network_key: GENERATE channel: 20 ``` -⚙️ **Zigbee2mqtt can be started after completing the configuration** +⚙️ **Zigbee2MQTT can be started after completing the configuration** ```yaml cd /opt/zigbee2mqtt npm start ``` -⚙️ **To update Zigbee2Mqtt** +⚙️ **To update Zigbee2MQTT** ```yaml bash /opt/zigbee2mqtt/update.sh ``` From bf686e1406602fb7f2381f22dc1c9bd532e9b93e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 04:20:47 -0500 Subject: [PATCH 0821/6505] Update README.md --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a645b258..6502fa2b 100644 --- a/README.md +++ b/README.md @@ -485,7 +485,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z ⚙️ **To allow device passthrough:** -In the Proxmox web shell run (**replace `106` with your LXC ID**) +In the **Proxmox Shell** run (**replace `106` with your LXC ID**) ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 ``` @@ -495,18 +495,20 @@ Reboot the LXC to apply the changes ⚙️ **Determine the location of your adapter** -Run in the Zigbee2MQTT console +Run from the LXC console ```yaml ls -l /dev/serial/by-id ``` Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` -⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** +⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/), Run from the LXC console** ```yaml nano /opt/zigbee2mqtt/data/configuration.yaml ``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + Example: ```yaml frontend: @@ -528,12 +530,12 @@ advanced: network_key: GENERATE channel: 20 ``` -⚙️ **Zigbee2MQTT can be started after completing the configuration** +⚙️ **Zigbee2MQTT can be started after completing the configuration, Run from the LXC console** ```yaml cd /opt/zigbee2mqtt npm start ``` -⚙️ **To update Zigbee2MQTT** +⚙️ **To update Zigbee2MQTT, Run from the LXC console** ```yaml bash /opt/zigbee2mqtt/update.sh ``` From fd545a71c6653f69282786951be9ca94e42908be Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 04:23:55 -0500 Subject: [PATCH 0822/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6502fa2b..fcd842d6 100644 --- a/README.md +++ b/README.md @@ -502,7 +502,7 @@ ls -l /dev/serial/by-id Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` -⚠️ **Before you can start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/), Run from the LXC console** +⚠️ **Before you start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/), Run from the LXC console** ```yaml nano /opt/zigbee2mqtt/data/configuration.yaml ``` From bfdd398b5d6cb085193e9f9133161e00072b22f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 04:49:52 -0500 Subject: [PATCH 0823/6505] Update README.md --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fcd842d6..d8e9d669 100644 --- a/README.md +++ b/README.md @@ -502,7 +502,9 @@ ls -l /dev/serial/by-id Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` -⚠️ **Before you start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/), Run from the LXC console** +⚙️ ⚠️ **Before you start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** + +Run from the LXC console ```yaml nano /opt/zigbee2mqtt/data/configuration.yaml ``` @@ -530,12 +532,16 @@ advanced: network_key: GENERATE channel: 20 ``` -⚙️ **Zigbee2MQTT can be started after completing the configuration, Run from the LXC console** +⚙️ **Zigbee2MQTT can be started after completing the configuration** + +Run from the LXC console ```yaml cd /opt/zigbee2mqtt npm start ``` -⚙️ **To update Zigbee2MQTT, Run from the LXC console** +⚙️ **To update Zigbee2MQTT** + +Run from the LXC console ```yaml bash /opt/zigbee2mqtt/update.sh ``` From 3c51252ad37ba02ce76f6fbd823c24d395b6512c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 04:59:20 -0500 Subject: [PATCH 0824/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 99335bce..ffb218de 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - **Zigbee2MQTT LXC** - Clean up / Improve script + - Improve documentation ## 2022-01-29 @@ -15,6 +16,7 @@ All notable changes to this project will be documented in this file. - **Node-Red LXC** - Clean up / Improve script + - Improve documentation ## 2022-01-25 From 0ae3294876cf19233407493590481ada6a3312f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:12:10 -0500 Subject: [PATCH 0825/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 9150147d..5df2827c 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -35,6 +35,7 @@ apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing Prerequisites..." +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null From acbd016ecbac9d02e90a5efdb7be72088c5e8082 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:46:54 -0500 Subject: [PATCH 0826/6505] Update adguard_setup.sh --- setup/adguard_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/adguard_setup.sh b/setup/adguard_setup.sh index 93c24680..71302ded 100644 --- a/setup/adguard_setup.sh +++ b/setup/adguard_setup.sh @@ -31,6 +31,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." +apt-get update &>/dev/null apt-get -y install \ curl \ sudo &>/dev/null From b1fbbeb3429d47b11b4d13d16ecae1c2acdf6562 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:47:27 -0500 Subject: [PATCH 0827/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index bac25430..f5b56400 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -35,6 +35,7 @@ apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing prerequisites..." +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null From 977483a99b07767411c4c58268c2530b246d67b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:48:14 -0500 Subject: [PATCH 0828/6505] Update esphome_setup.sh --- setup/esphome_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh index 9c0b8bc2..520bf7ca 100644 --- a/setup/esphome_setup.sh +++ b/setup/esphome_setup.sh @@ -35,6 +35,7 @@ apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing Prerequisites..." +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null From 98901d592655eab788f25d0e89c4a4a49e27ff38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:48:50 -0500 Subject: [PATCH 0829/6505] Update ha_setup.sh --- setup/ha_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 55a440bd..5b74959b 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ wget &>/dev/null From 9281cbca400e169f8be7b2b02ce4350956c97039 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:49:19 -0500 Subject: [PATCH 0830/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index a093c31b..8d09ff0d 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo \ From d521d23c92d4a101c7653e33192fcf7560f87d93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:49:49 -0500 Subject: [PATCH 0831/6505] Update mqtt_setup.sh --- setup/mqtt_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh index 72c98677..ab57741e 100644 --- a/setup/mqtt_setup.sh +++ b/setup/mqtt_setup.sh @@ -35,6 +35,7 @@ apt-get -qqy upgrade &>/dev/null # Install prerequisites msg "Installing Prerequisites..." +apt-get update &>/dev/null apt-get -qqy install \ curl \ gnupg \ From 3b8b561963a9d78893c9b7c2e719fe15d1a13021 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:50:18 -0500 Subject: [PATCH 0832/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index ac449961..5f3c0cbd 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null From 81545056e01d69dcddd9e51ed006490c16205aec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:51:34 -0500 Subject: [PATCH 0833/6505] Update pihole_setup.sh --- setup/pihole_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh index 220f1959..fcee1e0d 100644 --- a/setup/pihole_setup.sh +++ b/setup/pihole_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null From c54b6b91f44e9c7346815290976ae57597bfde9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:52:05 -0500 Subject: [PATCH 0834/6505] Update plex_setup.sh --- setup/plex_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index 59d5cdd6..b2c31c74 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo \ From 87a17ad526872d7af012c85e64ff849c485cdf95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:52:35 -0500 Subject: [PATCH 0835/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 08c311fb..9b9e7953 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ runc &>/dev/null From c13b398a6f729414ab82108ad1a9191c9d7baf02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:53:04 -0500 Subject: [PATCH 0836/6505] Update ubuntu_setup.sh --- setup/ubuntu_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh index 7f40a0a1..dc6db27d 100644 --- a/setup/ubuntu_setup.sh +++ b/setup/ubuntu_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null From 38ba1a443919c23dd1bb684fa27065b3023a8056 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:53:30 -0500 Subject: [PATCH 0837/6505] Update zigbee2mqtt_setup.sh --- setup/zigbee2mqtt_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh index b82d08f4..dbee2ca7 100644 --- a/setup/zigbee2mqtt_setup.sh +++ b/setup/zigbee2mqtt_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null From 4446dff7df411106ad8850adaca5f7dcd86e0c22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 05:53:55 -0500 Subject: [PATCH 0838/6505] Update zwavejs2mqtt_setup.sh --- setup/zwavejs2mqtt_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/zwavejs2mqtt_setup.sh b/setup/zwavejs2mqtt_setup.sh index bb2db5ae..49dcfce8 100644 --- a/setup/zwavejs2mqtt_setup.sh +++ b/setup/zwavejs2mqtt_setup.sh @@ -32,6 +32,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo \ From f1c62b44640a8a4ae15188f26f84fb51e968ba8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 13:03:20 -0500 Subject: [PATCH 0839/6505] Add files via upload --- setup/agent_setup.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 setup/agent_setup.sh diff --git a/setup/agent_setup.sh b/setup/agent_setup.sh new file mode 100644 index 00000000..be3b72b5 --- /dev/null +++ b/setup/agent_setup.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo \ + gnupg &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* + +echo -e "${CHECKMARK} \e[1;92m Installing Agent DVR... \e[0m" +apt-get update &>/dev/null +bash <(curl -s "https://raw.githubusercontent.com/ispysoftware/agent-install-scripts/main/install.sh") + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /agent_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From eaa92e6c2921f9486a83ed508943f590b12a2729 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 13:03:52 -0500 Subject: [PATCH 0840/6505] Add files via upload --- ct/agent_container.sh | 169 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 ct/agent_container.sh diff --git a/ct/agent_container.sh b/ct/agent_container.sh new file mode 100644 index 00000000..35d16d0b --- /dev/null +++ b/ct/agent_container.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Agent DVR LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/agent_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for Storage Location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-21.10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=agent-dvr +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID agent_setup.sh /agent_setup.sh -perms 755 +pct exec $CTID /agent_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully Created Agent DVR LXC to $CTID." +echo -e "\e[1;92m Agent DVR should be reachable by going to the following URL. + http://${IP}:8090 +\e[0m" \ No newline at end of file From 9dd5f5271d7ac78621edf7c00cf63e5ab91a0788 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 13:31:31 -0500 Subject: [PATCH 0841/6505] Delete agent_container.sh --- ct/agent_container.sh | 169 ------------------------------------------ 1 file changed, 169 deletions(-) delete mode 100644 ct/agent_container.sh diff --git a/ct/agent_container.sh b/ct/agent_container.sh deleted file mode 100644 index 35d16d0b..00000000 --- a/ct/agent_container.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Agent DVR LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/agent_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for Storage Location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=agent-dvr -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID agent_setup.sh /agent_setup.sh -perms 755 -pct exec $CTID /agent_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Agent DVR LXC to $CTID." -echo -e "\e[1;92m Agent DVR should be reachable by going to the following URL. - http://${IP}:8090 -\e[0m" \ No newline at end of file From bc1ff401934bbe306b4f40c7320bd7d94c176b89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 13:31:47 -0500 Subject: [PATCH 0842/6505] Delete agent_setup.sh --- setup/agent_setup.sh | 68 -------------------------------------------- 1 file changed, 68 deletions(-) delete mode 100644 setup/agent_setup.sh diff --git a/setup/agent_setup.sh b/setup/agent_setup.sh deleted file mode 100644 index be3b72b5..00000000 --- a/setup/agent_setup.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - gnupg &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" -apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* - -echo -e "${CHECKMARK} \e[1;92m Installing Agent DVR... \e[0m" -apt-get update &>/dev/null -bash <(curl -s "https://raw.githubusercontent.com/ispysoftware/agent-install-scripts/main/install.sh") - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /agent_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 19f17137ea7ab1bfde3c7b9e03c1b559a1410b6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:29:00 -0500 Subject: [PATCH 0843/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 547c776e..e1c90504 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -140,7 +140,7 @@ fi ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 -unprivileged\ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null From 3286b4f676f38e2a975283e3bca9f8c78e57d62e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:32:51 -0500 Subject: [PATCH 0844/6505] Update adguard_container.sh --- ct/adguard_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index e1c90504..74f93e4c 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -140,9 +140,9 @@ fi ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 -unprivileged\ +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE -unprivileged >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime From c7f3b9326d19268d474734c4f92ca5f12adfdb67 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:34:15 -0500 Subject: [PATCH 0845/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 74f93e4c..6424c25d 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -142,7 +142,7 @@ HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE -unprivileged >/dev/null + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE -unprivileged 1 >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime From 07d655f807d73c0cd1911d357907b11bcb3d7d4f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:36:03 -0500 Subject: [PATCH 0846/6505] Update adguard_container.sh --- ct/adguard_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 6424c25d..f812ba07 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -141,8 +141,8 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE -unprivileged 1 >/dev/null + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 -unprivileged 1 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime From 71ef3f6029dda46aa230218447230f5d7632c1c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:37:25 -0500 Subject: [PATCH 0847/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index f812ba07..19149cc9 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 -unprivileged 1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 -unprivileged \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From a27c856fb3268817e3cdcdef80dcce3bb72c3844 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:38:37 -0500 Subject: [PATCH 0848/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 19149cc9..547c776e 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 -unprivileged \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 98fd861560ce854c9d27c28fddcbf5a191b91463 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:52:19 -0500 Subject: [PATCH 0849/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 547c776e..9c25436b 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -140,7 +140,7 @@ fi ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1,unprivileged 0 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null From ef78e7a16e2ea81624789c0803b11f66a5879c3e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:55:45 -0500 Subject: [PATCH 0850/6505] Update adguard_container.sh --- ct/adguard_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 9c25436b..0cc1ab98 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -140,8 +140,8 @@ fi ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1,unprivileged 0 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 -unprivileged: 0\ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 42e159dc416c91e99d34fbd1100a1d9c0934013e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 16:56:57 -0500 Subject: [PATCH 0851/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 0cc1ab98..547c776e 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -141,7 +141,7 @@ ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 -unprivileged: 0\ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From dae18c422e270fd708e1b487ed66033a79fcf8d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 17:47:39 -0500 Subject: [PATCH 0852/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 547c776e..79190212 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -140,7 +140,7 @@ fi ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ +pct create $CTID $TEMPLATE_STRING -arch $ARCH -unprivileged 1 -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null From 7d62942559a39855aeffd060df5ab3c5b2a87862 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 17:49:47 -0500 Subject: [PATCH 0853/6505] Update adguard_container.sh --- ct/adguard_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 79190212..547c776e 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -140,7 +140,7 @@ fi ARCH=$(dpkg --print-architecture) HOSTNAME=adguard TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -unprivileged 1 -features nesting=1 \ +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null From b84aa466fc457dca3fbd6f9c3b032260fb0d455d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 19:49:40 -0500 Subject: [PATCH 0854/6505] Update mqtt_container.sh --- ct/mqtt_container.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/mqtt_container.sh b/ct/mqtt_container.sh index 655f5f4f..2b50996d 100644 --- a/ct/mqtt_container.sh +++ b/ct/mqtt_container.sh @@ -164,7 +164,10 @@ msg "Starting LXC container..." pct start $CTID pct push $CTID mqtt_setup.sh /mqtt_setup.sh -perms 755 pct exec $CTID /mqtt_setup.sh - +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +unprivileged: 1 +EOF # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created a MQTT LXC Container to $CTID at IP Address ${IP}" From bf8cb273768d6e449eccefbcd44c7f9bd00c8350 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 19:50:09 -0500 Subject: [PATCH 0855/6505] Update zigbee2mqtt_container.sh --- ct/zigbee2mqtt_container.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt_container.sh b/ct/zigbee2mqtt_container.sh index d3676dab..b1e7bb7b 100644 --- a/ct/zigbee2mqtt_container.sh +++ b/ct/zigbee2mqtt_container.sh @@ -159,7 +159,10 @@ echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID zigbee2mqtt_setup.sh /zigbee2mqtt_setup.sh -perms 755 pct exec $CTID /zigbee2mqtt_setup.sh - +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +unprivileged: 1 +EOF IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" echo From 0e4a266b16f50410bd52f304db3ad4629f04854e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 20:21:15 -0500 Subject: [PATCH 0856/6505] Update zigbee2mqtt_container.sh --- ct/zigbee2mqtt_container.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ct/zigbee2mqtt_container.sh b/ct/zigbee2mqtt_container.sh index b1e7bb7b..d3676dab 100644 --- a/ct/zigbee2mqtt_container.sh +++ b/ct/zigbee2mqtt_container.sh @@ -159,10 +159,7 @@ echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID zigbee2mqtt_setup.sh /zigbee2mqtt_setup.sh -perms 755 pct exec $CTID /zigbee2mqtt_setup.sh -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -unprivileged: 1 -EOF + IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" echo From 1b466bd18961c0785bf9ee1a670ee268942511e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jan 2022 20:22:32 -0500 Subject: [PATCH 0857/6505] Update mqtt_container.sh --- ct/mqtt_container.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ct/mqtt_container.sh b/ct/mqtt_container.sh index 2b50996d..44c9ff56 100644 --- a/ct/mqtt_container.sh +++ b/ct/mqtt_container.sh @@ -164,10 +164,6 @@ msg "Starting LXC container..." pct start $CTID pct push $CTID mqtt_setup.sh /mqtt_setup.sh -perms 755 pct exec $CTID /mqtt_setup.sh -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -unprivileged: 1 -EOF # Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created a MQTT LXC Container to $CTID at IP Address ${IP}" From 27f968389794ed1e3fb50fb68f98d5c88101035d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 31 Jan 2022 04:26:03 -0500 Subject: [PATCH 0858/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d8e9d669..73fd8340 100644 --- a/README.md +++ b/README.md @@ -625,7 +625,7 @@ ________________________________________________________________________________
-🔸Plex Media Server LXC +Plex Media Server LXC

From 9087badfb2075c757d286155ddae0b973418b950 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 31 Jan 2022 15:33:22 -0500 Subject: [PATCH 0859/6505] Update zigbee2mqtt_container.sh --- ct/zigbee2mqtt_container.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/zigbee2mqtt_container.sh b/ct/zigbee2mqtt_container.sh index d3676dab..aa175e82 100644 --- a/ct/zigbee2mqtt_container.sh +++ b/ct/zigbee2mqtt_container.sh @@ -165,5 +165,4 @@ info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP echo echo -e "\e[1;31m Updating the configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" echo -echo -e "Z2M can be started after completing the configuration buy running \e[1;33m systemctl start zigbee2mqtt \e[0m" echo From c2b23268ae4f1276fbcc83eb685ce2d71a7eae3e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 03:25:40 -0500 Subject: [PATCH 0860/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73fd8340..b4228467 100644 --- a/README.md +++ b/README.md @@ -654,7 +654,7 @@ ________________________________________________________________________________
-🔸Jellyfin Media Server LXC +Jellyfin Media Server LXC

From c6e59d8f65f6d60f9b22ada30ac554c0180bbeae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:13:12 -0500 Subject: [PATCH 0861/6505] Add files via upload --- misc/frigate-conf.sh | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 misc/frigate-conf.sh diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh new file mode 100644 index 00000000..0c0882ea --- /dev/null +++ b/misc/frigate-conf.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will Prepare a LXC Container for Frigate \e[0m" +while true; do + read -p "Did you replace 106 with your LXC ID? Proceed (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +CHAR_DEVS+=("1:1") +CHAR_DEVS+=("29:0") +CHAR_DEVS+=("188:.*") +CHAR_DEVS+=("189:.*") +CHAR_DEVS+=("226:0") +CHAR_DEVS+=("226:128") + +for char_dev in ${CHAR_DEVS[@]}; do + [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" + CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" +done + +read -r -d '' HOOK_SCRIPT <<- EOF || true +for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do + dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; + mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); + for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do + mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); + cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; + done; + cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; +done; +EOF +HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} + +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf +cat CTID.conf >$CTID_CONFIG_PATH + +cat <> $CTID_CONFIG_PATH +lxc.autodev: 1 +lxc.hook.autodev: bash -c '$HOOK_SCRIPT' +EOF +echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" + +# In the Proxmox web shell run (replace 106 with your LXC ID) +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/frigate-conf.sh)" -s 106 +# Reboot the LXC to apply the changes \ No newline at end of file From 80277f124dbfd1f120f6cf643c8c79e0c5b48cd1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:28:35 -0500 Subject: [PATCH 0862/6505] Add files via upload --- misc/frigate-conf.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh index 0c0882ea..2353a18c 100644 --- a/misc/frigate-conf.sh +++ b/misc/frigate-conf.sh @@ -67,6 +67,8 @@ sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH cat <> $CTID_CONFIG_PATH +lxc.cgroup2.devices.allow: a +lxc.cap.drop: lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF From 09c014f17a6cbc15ca4f36ba747a696d4fba3a40 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:38:02 -0500 Subject: [PATCH 0863/6505] Update and rename autodev.sh to usb-passthrough.sh --- misc/{autodev.sh => usb-passthrough.sh} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename misc/{autodev.sh => usb-passthrough.sh} (92%) diff --git a/misc/autodev.sh b/misc/usb-passthrough.sh similarity index 92% rename from misc/autodev.sh rename to misc/usb-passthrough.sh index e96f2245..76e795cb 100644 --- a/misc/autodev.sh +++ b/misc/usb-passthrough.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +echo -e "\e[1;33m This script will allow USB passthrough to a LXC Container \e[0m" while true; do read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn case $yn in @@ -67,6 +67,7 @@ cat <> $CTID_CONFIG_PATH lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF +echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" # In the Proxmox web shell run (replace 106 with your LXC ID) # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 From 4a6d54e8b0a6d42603d79c93999472519c8354d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:40:53 -0500 Subject: [PATCH 0864/6505] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b4228467..7852c455 100644 --- a/README.md +++ b/README.md @@ -107,11 +107,11 @@ nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **To allow device passthrough:** +⚙️ **To allow USB device passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID**) ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -164,11 +164,11 @@ nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **To Allow Device Passthrough:** +⚙️ **To Allow USB Device Passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID**) ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -483,11 +483,11 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

-⚙️ **To allow device passthrough:** +⚙️ **To allow USB device passthrough:** In the **Proxmox Shell** run (**replace `106` with your LXC ID**) ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -567,11 +567,11 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z **Zwavejs2MQTT Interface - IP:8091** -⚙️ **To allow device passthrough:** +⚙️ **To allow USB device passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID)** ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 ``` Reboot the LXC to apply the changes From baa842edb25868752c151c7a0f85e93e5b6d9839 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:44:33 -0500 Subject: [PATCH 0865/6505] Update ha_container.sh --- ct/ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/ha_container.sh b/ct/ha_container.sh index 8470b815..802ac2e0 100644 --- a/ct/ha_container.sh +++ b/ct/ha_container.sh @@ -133,7 +133,7 @@ echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null From d29f2ea7d7d03bf47971818b65a01284c5b12b0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:45:06 -0500 Subject: [PATCH 0866/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index c4705455..f0a2b965 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -132,7 +132,7 @@ echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.1/fuse-overlayfs-x86_64 + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null From 5767d3b08ac251420acb98d8c09aebf61548ba45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:55:58 -0500 Subject: [PATCH 0867/6505] Add files via upload --- misc/frigate-conf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh index 2353a18c..127d3923 100644 --- a/misc/frigate-conf.sh +++ b/misc/frigate-conf.sh @@ -63,7 +63,7 @@ HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf +sed '/autodev/d', '/devices/d', '/cap/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH cat <> $CTID_CONFIG_PATH From 6c35083018e2315874300f4d5d31fa552e0224df Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:57:13 -0500 Subject: [PATCH 0868/6505] Add files via upload --- misc/frigate-conf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh index 127d3923..f159e4e9 100644 --- a/misc/frigate-conf.sh +++ b/misc/frigate-conf.sh @@ -63,7 +63,7 @@ HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -sed '/autodev/d', '/devices/d', '/cap/d' $CTID_CONFIG_PATH >CTID.conf +sed '/autodev/d' '/devices/d' '/cap/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH cat <> $CTID_CONFIG_PATH From 900d4818f5f049ed9cc5fbb3d8faba78aa093c16 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 05:59:08 -0500 Subject: [PATCH 0869/6505] Add files via upload --- misc/frigate-conf.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh index f159e4e9..553d90a4 100644 --- a/misc/frigate-conf.sh +++ b/misc/frigate-conf.sh @@ -63,7 +63,9 @@ HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -sed '/autodev/d' '/devices/d' '/cap/d' $CTID_CONFIG_PATH >CTID.conf +sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf +sed '/devices/d' $CTID_CONFIG_PATH >CTID.conf +sed '/cap/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH cat <> $CTID_CONFIG_PATH From a26ec7cee04d4e4a9888c83011129100b6d3cf8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 06:01:18 -0500 Subject: [PATCH 0870/6505] Add files via upload --- misc/frigate-conf.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh index 553d90a4..0c0882ea 100644 --- a/misc/frigate-conf.sh +++ b/misc/frigate-conf.sh @@ -64,13 +64,9 @@ HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf -sed '/devices/d' $CTID_CONFIG_PATH >CTID.conf -sed '/cap/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH cat <> $CTID_CONFIG_PATH -lxc.cgroup2.devices.allow: a -lxc.cap.drop: lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF From 90d65f47c1e41c3c7082263d65044ff878ed874f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 06:10:03 -0500 Subject: [PATCH 0871/6505] Update usb-passthrough.sh --- misc/usb-passthrough.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index 76e795cb..c1b8dfa2 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -68,7 +68,3 @@ lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" - -# In the Proxmox web shell run (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/autodev.sh)" -s 106 -# Reboot the LXC to apply the changes From 81b2991fea85ee4759238f575827e279f39b81ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 10:05:00 -0500 Subject: [PATCH 0872/6505] Update npm_setup.sh --- setup/npm_setup.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 1a283c79..42208e7a 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -34,7 +34,19 @@ apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo "fs.file-max = 65535" > /etc/sysctl.conf apt-get update &>/dev/null - apt-get -y install --no-install-recommends sudo curl wget gnupg openssl ca-certificates apache2-utils logrotate build-essential python3-dev git lsb-release &>/dev/null + apt-get -y install \ + sudo \ + curl \ + wget \ + gnupg \ + openssl \ + ca-certificates \ + apache2-utils \ + logrotate \ + build-essential \ + python3-dev \ + git \ + lsb-release &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null From 7ead53b2302638943137d95e260509e1cc9b18c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 10:05:53 -0500 Subject: [PATCH 0873/6505] Update npm_setup.sh --- setup/npm_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 42208e7a..a5b2552e 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -34,7 +34,7 @@ apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo "fs.file-max = 65535" > /etc/sysctl.conf apt-get update &>/dev/null - apt-get -y install \ + apt-get -qqy install \ sudo \ curl \ wget \ From 88a187c1588a9d677bb9decac9be990cbc9a8a7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 11:28:40 -0500 Subject: [PATCH 0874/6505] Update and rename frigate-conf.sh to frigate-support.sh --- misc/{frigate-conf.sh => frigate-support.sh} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename misc/{frigate-conf.sh => frigate-support.sh} (96%) diff --git a/misc/frigate-conf.sh b/misc/frigate-support.sh similarity index 96% rename from misc/frigate-conf.sh rename to misc/frigate-support.sh index 0c0882ea..3a26a3b9 100644 --- a/misc/frigate-conf.sh +++ b/misc/frigate-support.sh @@ -73,5 +73,5 @@ EOF echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" # In the Proxmox web shell run (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/frigate-conf.sh)" -s 106 -# Reboot the LXC to apply the changes \ No newline at end of file +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/frigate-support.sh)" -s 106 +# Reboot the LXC to apply the changes From 379ec1d0461b29f093eef1d8d8f0afde79e4f03c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 13:38:22 -0500 Subject: [PATCH 0875/6505] Add files via upload --- misc/frigate-conf.sh | 86 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 misc/frigate-conf.sh diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh new file mode 100644 index 00000000..524661d7 --- /dev/null +++ b/misc/frigate-conf.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will prepare a LXC Container for Frigate \e[0m" +while true; do + read -p "Did you replace 106 with your LXC ID? Proceed (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +CHAR_DEVS+=("1:1") +CHAR_DEVS+=("29:0") +CHAR_DEVS+=("188:.*") +CHAR_DEVS+=("189:.*") +CHAR_DEVS+=("226:0") +CHAR_DEVS+=("226:128") + +for char_dev in ${CHAR_DEVS[@]}; do + [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" + CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" +done + +read -r -d '' HOOK_SCRIPT <<- EOF || true +for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do + dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; + mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); + for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do + mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); + cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; + done; + cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; +done; +EOF +HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} + +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf +cat CTID.conf >$CTID_CONFIG_PATH + +if [[ $CTID_CONFIG_PATH =~ [testing] ]];then +cat <> $CTID_CONFIG_PATH +lxc.autodev: 1 +lxc.hook.autodev: bash -c '$HOOK_SCRIPT' +EOF +else +cat <> $CTID_CONFIG_PATH +lxc.testing +lxc.autodev: 1 +lxc.hook.autodev: bash -c '$HOOK_SCRIPT' +EOF +fi + +echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" + +# In the Proxmox web shell run (replace 106 with your LXC ID) +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/frigate-conf.sh)" -s 106 +# Reboot the LXC to apply the changes \ No newline at end of file From 5207bb3e8ec4efe53154753912cb5e032ced8ad1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 13:41:09 -0500 Subject: [PATCH 0876/6505] Add files via upload --- misc/frigate-conf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh index 524661d7..53957797 100644 --- a/misc/frigate-conf.sh +++ b/misc/frigate-conf.sh @@ -66,7 +66,7 @@ CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH -if [[ $CTID_CONFIG_PATH =~ [testing] ]];then +if $CTID_CONFIG_PATH =~ [testing];then cat <> $CTID_CONFIG_PATH lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' From 8f509d31b10b31c641a06ca28703270de7a827e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 13:42:45 -0500 Subject: [PATCH 0877/6505] Delete frigate-conf.sh --- misc/frigate-conf.sh | 86 -------------------------------------------- 1 file changed, 86 deletions(-) delete mode 100644 misc/frigate-conf.sh diff --git a/misc/frigate-conf.sh b/misc/frigate-conf.sh deleted file mode 100644 index 53957797..00000000 --- a/misc/frigate-conf.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env bash -echo -e "\e[1;33m This script will prepare a LXC Container for Frigate \e[0m" -while true; do - read -p "Did you replace 106 with your LXC ID? Proceed (y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -CHAR_DEVS+=("1:1") -CHAR_DEVS+=("29:0") -CHAR_DEVS+=("188:.*") -CHAR_DEVS+=("189:.*") -CHAR_DEVS+=("226:0") -CHAR_DEVS+=("226:128") - -for char_dev in ${CHAR_DEVS[@]}; do - [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" - CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" -done - -read -r -d '' HOOK_SCRIPT <<- EOF || true -for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do - dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; - mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); - for link in \$(udevadm info --query=property \$dev | sed -n "s/DEVLINKS=//p"); do - mkdir -p \${LXC_ROOTFS_MOUNT}\$(dirname \$link); - cp -dpR \$link \${LXC_ROOTFS_MOUNT}\${link}; - done; - cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; -done; -EOF -HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} - -CTID=$1 -CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf -cat CTID.conf >$CTID_CONFIG_PATH - -if $CTID_CONFIG_PATH =~ [testing];then -cat <> $CTID_CONFIG_PATH -lxc.autodev: 1 -lxc.hook.autodev: bash -c '$HOOK_SCRIPT' -EOF -else -cat <> $CTID_CONFIG_PATH -lxc.testing -lxc.autodev: 1 -lxc.hook.autodev: bash -c '$HOOK_SCRIPT' -EOF -fi - -echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" - -# In the Proxmox web shell run (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/frigate-conf.sh)" -s 106 -# Reboot the LXC to apply the changes \ No newline at end of file From ae2b1ca4244baf9b8b091b92abbbd33cb1186b73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 19:04:25 -0500 Subject: [PATCH 0878/6505] Update npm_setup.sh --- setup/npm_setup.sh | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index a5b2552e..d87c0e21 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -31,22 +31,23 @@ echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null - echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" - echo "fs.file-max = 65535" > /etc/sysctl.conf - apt-get update &>/dev/null - apt-get -qqy install \ - sudo \ - curl \ - wget \ - gnupg \ - openssl \ - ca-certificates \ - apache2-utils \ - logrotate \ - build-essential \ - python3-dev \ - git \ - lsb-release &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +echo "fs.file-max = 65535" > /etc/sysctl.conf +apt-get update &>/dev/null +sleep 3 +apt-get -qqy install \ + sudo \ + curl \ + wget \ + gnupg \ + openssl \ + ca-certificates \ + apache2-utils \ + logrotate \ + build-essential \ + python3-dev \ + git \ + lsb-release &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null From 266534259374a8679c5d335b028b06d772d9675d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 19:13:04 -0500 Subject: [PATCH 0879/6505] Update npm_setup.sh --- setup/npm_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index d87c0e21..35c652c5 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -33,7 +33,7 @@ apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo "fs.file-max = 65535" > /etc/sysctl.conf -apt-get update &>/dev/null +apt update &>/dev/null sleep 3 apt-get -qqy install \ sudo \ From 5520c29a01e94c4f0a5cd3103f406ef6bf9cc052 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 19:24:51 -0500 Subject: [PATCH 0880/6505] Update npm_setup.sh --- setup/npm_setup.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 35c652c5..c471c242 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -23,6 +23,13 @@ function msg() { echo -e "$TEXT" } +while [ "$(hostname -I)" = "" ]; do + echo -e "No network: $(date)" + sleep 1 +done + +echo -e "Network connected: ($(hostname -I)) \e[0m" + echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -33,8 +40,7 @@ apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo "fs.file-max = 65535" > /etc/sysctl.conf -apt update &>/dev/null -sleep 3 +apt-get update &>/dev/null apt-get -qqy install \ sudo \ curl \ From 16c09336d2a2bc542288be9c81f798d2d9587417 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 19:40:56 -0500 Subject: [PATCH 0881/6505] Update npm_setup.sh --- setup/npm_setup.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index c471c242..1df1986f 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -7,6 +7,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' trap die ERR trap 'die "Script interrupted."' INT @@ -22,13 +23,12 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } - while [ "$(hostname -I)" = "" ]; do - echo -e "No network: $(date)" - sleep 1 + echo -e "${CROSS} \e[1;31m No network: \e[0m $(date)" + sleep 3 done -echo -e "Network connected: ($(hostname -I)) \e[0m" + echo -e "${CHECKMARK} \e[1;92m Network connected: \e[0m ($(hostname -I))" echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen From 9b88ec64626d99412bd1effcc90619609b4fedbd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 20:03:07 -0500 Subject: [PATCH 0882/6505] Update npm_setup.sh --- setup/npm_setup.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 1df1986f..74bd42f1 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -23,17 +23,15 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +sleep 3 while [ "$(hostname -I)" = "" ]; do echo -e "${CROSS} \e[1;31m No network: \e[0m $(date)" sleep 3 done - - echo -e "${CHECKMARK} \e[1;92m Network connected: \e[0m ($(hostname -I))" - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null - + echo -e "${CHECKMARK} \e[1;92m Network connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 0955568fb40074d5bcd6f7e49b297aa9766db458 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 20:05:43 -0500 Subject: [PATCH 0883/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index f5b56400..59358113 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -7,6 +7,8 @@ set -o nounset #Treat unset variables as an error set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' trap die ERR trap 'die "Script interrupted."' INT @@ -23,12 +25,17 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS msg "Setting up container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +sleep 3 +while [ "$(hostname -I)" = "" ]; do + echo -e "${CROSS} \e[1;31m No network: \e[0m $(date)" + sleep 3 +done + echo -e "${CHECKMARK} \e[1;92m Network connected: \e[0m $(hostname -I)" -# Update container OS +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" msg "Updating container OS..." apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 3e1ca37cba1a1ce6c3b4e16b628f2565d1b7f784 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 20:09:25 -0500 Subject: [PATCH 0884/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index 59358113..142ca428 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -35,7 +35,6 @@ while [ "$(hostname -I)" = "" ]; do done echo -e "${CHECKMARK} \e[1;92m Network connected: \e[0m $(hostname -I)" -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" msg "Updating container OS..." apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 9da2c365a67c09e6585081858bf99f3218ac3067 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:45:40 -0500 Subject: [PATCH 0885/6505] Update adguard_setup.sh --- setup/adguard_setup.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/setup/adguard_setup.sh b/setup/adguard_setup.sh index 71302ded..1dad9b95 100644 --- a/setup/adguard_setup.sh +++ b/setup/adguard_setup.sh @@ -6,6 +6,11 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -25,6 +30,17 @@ function msg() { msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" msg "Updating Container OS..." apt update &>/dev/null From 31c84f6309e7c5268f85c28020985f8de4f63ab5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:46:45 -0500 Subject: [PATCH 0886/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index 142ca428..5b2c1f0b 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -7,8 +7,11 @@ set -o nounset #Treat unset variables as an error set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -28,12 +31,17 @@ function msg() { msg "Setting up container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -sleep 3 while [ "$(hostname -I)" = "" ]; do - echo -e "${CROSS} \e[1;31m No network: \e[0m $(date)" - sleep 3 + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi done - echo -e "${CHECKMARK} \e[1;92m Network connected: \e[0m $(hostname -I)" + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" msg "Updating container OS..." apt update &>/dev/null From 97453e259fc2f9b883837701de76f94a5fb12026 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:47:36 -0500 Subject: [PATCH 0887/6505] Update esphome_setup.sh --- setup/esphome_setup.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh index 520bf7ca..d2205781 100644 --- a/setup/esphome_setup.sh +++ b/setup/esphome_setup.sh @@ -7,6 +7,11 @@ set -o nounset #Treat unset variables as an error set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -27,6 +32,17 @@ function msg() { msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" # Update container OS msg "Updating container OS..." From 1b9a9e4de0a16cbfcded92bee8b723fbff760c94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:48:36 -0500 Subject: [PATCH 0888/6505] Update ha_setup.sh --- setup/ha_setup.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 5b74959b..ee37eadd 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -6,7 +6,11 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -26,6 +30,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 39735325109d71fcd09a3b6c8ad266843af1c79b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:50:02 -0500 Subject: [PATCH 0889/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 8d09ff0d..2e50aa89 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -7,7 +7,11 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap 'die "Script interrupted."' INT function error_exit() { @@ -26,6 +30,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 57388a3e171877407de95d0c7eae34bf618e7f95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:50:56 -0500 Subject: [PATCH 0890/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 5df2827c..bbfd9615 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -7,6 +7,11 @@ set -o nounset #Treat unset variables as an error set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -27,6 +32,17 @@ function msg() { msg "Setting up container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" # Update container OS msg "Updating container OS..." From 56659bf1118c244c1e7b84562c3cde9a811389d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:51:52 -0500 Subject: [PATCH 0891/6505] Update mqtt_setup.sh --- setup/mqtt_setup.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh index ab57741e..84008ea8 100644 --- a/setup/mqtt_setup.sh +++ b/setup/mqtt_setup.sh @@ -7,6 +7,11 @@ set -o nounset #Treat unset variables as an error set -o pipefail #Pipe will exit with last non-zero status if applicable shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -27,6 +32,17 @@ function msg() { msg "Setting up Container OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" # Update container OS msg "Updating Container OS..." From 6701d6d276b882520a744cb1b6a172efa00bb4b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:52:45 -0500 Subject: [PATCH 0892/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index 5f3c0cbd..c0c5b1ec 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -6,7 +6,11 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -26,6 +30,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From c6396b8b46495703b85fc2be6d8825e336b34d5c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:53:57 -0500 Subject: [PATCH 0893/6505] Update npm_setup.sh --- setup/npm_setup.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 74bd42f1..16838fee 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -6,8 +6,11 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -26,12 +29,18 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -sleep 3 while [ "$(hostname -I)" = "" ]; do - echo -e "${CROSS} \e[1;31m No network: \e[0m $(date)" - sleep 3 + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi done - echo -e "${CHECKMARK} \e[1;92m Network connected: \e[0m $(hostname -I)" + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 2a0df9c7b03390fd55a8fa95905bfdf15895b444 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:54:48 -0500 Subject: [PATCH 0894/6505] Update pihole_setup.sh --- setup/pihole_setup.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh index fcee1e0d..09f809b5 100644 --- a/setup/pihole_setup.sh +++ b/setup/pihole_setup.sh @@ -6,6 +6,11 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -25,6 +30,17 @@ function msg() { msg "Setting up LXC OS..." sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" # Update container OS msg "Updating container OS..." From 7bb2eb3caea358213461d5d6bf99b011cd688098 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:55:48 -0500 Subject: [PATCH 0895/6505] Update plex_setup.sh --- setup/plex_setup.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index b2c31c74..50fcc1ad 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -6,8 +6,12 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +trap die ERR trap 'die "Script interrupted."' INT function error_exit() { @@ -26,6 +30,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From e606148bad255628b67dac0c34dbd7b8e52109d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:56:42 -0500 Subject: [PATCH 0896/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 9b9e7953..e74c1238 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -6,7 +6,10 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 trap die ERR trap 'die "Script interrupted."' INT @@ -26,6 +29,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From b54ca7c8cce8871a3c432bbc946775a2aba40618 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:57:42 -0500 Subject: [PATCH 0897/6505] Update ubuntu_setup.sh --- setup/ubuntu_setup.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh index dc6db27d..b35e5027 100644 --- a/setup/ubuntu_setup.sh +++ b/setup/ubuntu_setup.sh @@ -6,7 +6,10 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 trap die ERR trap 'die "Script interrupted."' INT @@ -26,6 +29,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" apt update &>/dev/null From bae1e831d9269ebb70e641553dc8e319360f4e6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:58:39 -0500 Subject: [PATCH 0898/6505] Update zigbee2mqtt_setup.sh --- setup/zigbee2mqtt_setup.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh index dbee2ca7..6dd0aea7 100644 --- a/setup/zigbee2mqtt_setup.sh +++ b/setup/zigbee2mqtt_setup.sh @@ -6,7 +6,11 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -26,6 +30,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 7a32aa00c4049432ce79a1e878070134bc792491 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 21:59:29 -0500 Subject: [PATCH 0899/6505] Update zwavejs2mqtt_setup.sh --- setup/zwavejs2mqtt_setup.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup/zwavejs2mqtt_setup.sh b/setup/zwavejs2mqtt_setup.sh index 49dcfce8..228e1c73 100644 --- a/setup/zwavejs2mqtt_setup.sh +++ b/setup/zwavejs2mqtt_setup.sh @@ -6,7 +6,11 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -26,6 +30,17 @@ function msg() { echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null From 8a2568fd6103026dc9486faad824980250175100 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Feb 2022 22:22:22 -0500 Subject: [PATCH 0900/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ffb218de..9c8698e1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-01 + +### Changed + +- **All Scripts** + - Fix issue where some networks were slow to assign a IP address to the container causing scripts to fail. + ## 2022-01-30 ### Changed From 44f1fa28433afd150bedd77237d39bd588bf0047 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Feb 2022 06:59:31 -0500 Subject: [PATCH 0901/6505] Update adguard_container.sh --- ct/adguard_container.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ct/adguard_container.sh b/ct/adguard_container.sh index 547c776e..daada894 100644 --- a/ct/adguard_container.sh +++ b/ct/adguard_container.sh @@ -15,6 +15,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -105,9 +106,10 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "LXC ID is $CTID." -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -129,7 +131,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -msg "Creating LXC..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" DISK_SIZE=2G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -148,10 +150,13 @@ MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -msg "Starting LXC..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" pct start $CTID pct push $CTID adguard_setup.sh /adguard_setup.sh -perms 755 pct exec $CTID /adguard_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a AdGuard Home LXC to $CTID at IP Address ${IP}" +info "Successfully created a AdGuard Home LXC to $CTID" +echo -e "\e[1;92m AdGuard Home Setup should be reachable by going to the following URL. + http://${IP}:3000 +\e[0m" From 9cc5ff0d5fceeb3ad3ec7a2cf9af80d00e93ee1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Feb 2022 07:06:04 -0500 Subject: [PATCH 0902/6505] Update adguard_setup.sh --- setup/adguard_setup.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/setup/adguard_setup.sh b/setup/adguard_setup.sh index 1dad9b95..d75230ef 100644 --- a/setup/adguard_setup.sh +++ b/setup/adguard_setup.sh @@ -27,11 +27,11 @@ function msg() { echo -e "$TEXT" } -msg "Setting up Container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + 1>&2 echo -e "${CROSS} \e[1;31m No Network \e[0m $(date)" sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] @@ -40,22 +40,22 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + echo -e "${CHECKMARK} \e[1;92m Network Connected \e[0m $(hostname -I)" -msg "Updating Container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -msg "Installing Prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -y install \ curl \ sudo &>/dev/null -msg "Installing AdGuard Home.." +echo -e "${CHECKMARK} \e[1;92m Installing AdGuard Home... \e[0m" curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null -msg "Customizing LXC..." +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -69,5 +69,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /adguard_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 6b17f0d45c0787408a24f396c0e57dcc48e42743 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 02:31:09 -0500 Subject: [PATCH 0903/6505] Update npm_setup.sh --- setup/npm_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 16838fee..e580f12c 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -42,11 +42,11 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -echo "fs.file-max = 65535" > /etc/sysctl.conf +#echo "fs.file-max = 65535" > /etc/sysctl.conf apt-get update &>/dev/null apt-get -qqy install \ sudo \ From f75d65d6aab80ee5fea1f0c7282d1a8c154d2800 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 02:36:08 -0500 Subject: [PATCH 0904/6505] Update npm_setup.sh --- setup/npm_setup.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index e580f12c..3a6a4b14 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -46,7 +46,6 @@ apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -#echo "fs.file-max = 65535" > /etc/sysctl.conf apt-get update &>/dev/null apt-get -qqy install \ sudo \ From e147720f247e9ca197b556df0473e9faa558104a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 02:59:39 -0500 Subject: [PATCH 0905/6505] Update adguard_setup.sh --- setup/adguard_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/adguard_setup.sh b/setup/adguard_setup.sh index d75230ef..bd48318d 100644 --- a/setup/adguard_setup.sh +++ b/setup/adguard_setup.sh @@ -43,7 +43,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From 75d9abddcb0ffca6041786049b5e950626c516fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:00:17 -0500 Subject: [PATCH 0906/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index 5b2c1f0b..c1ca0e37 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -44,7 +44,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" msg "Updating container OS..." -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From aea631d1944317aca1b22b47c67af4569d2965a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:15:03 -0500 Subject: [PATCH 0907/6505] Update debian11_container.sh --- ct/debian11_container.sh | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/ct/debian11_container.sh b/ct/debian11_container.sh index be641145..d75d639a 100644 --- a/ct/debian11_container.sh +++ b/ct/debian11_container.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "This will create a New Debian 11+ LXC Container. Proceed(y/n)?" yn + read -p "This will create a New Debian 11 LXC Container. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -9,11 +9,10 @@ while true; do esac done -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -73,13 +72,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Download setup script wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian11_setup.sh -# Detect modules and automatically load at boot load_module overlay -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -106,14 +102,13 @@ else fi info "Using '$STORAGE' for storage location." -# Get the next guest VM/LXC ID CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -121,7 +116,6 @@ TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in dir|nfs) @@ -136,8 +130,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -# Create LXC -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=2G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -152,17 +145,14 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -# Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -# Setup container -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID debian11_setup.sh /debian11_setup.sh -perms 755 pct exec $CTID /debian11_setup.sh -# Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created a Debian 11 LXC Container to $CTID at IP Address ${IP}" From f3d4a2154cb13471c636a86ee0fa28275e6a3240 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:21:54 -0500 Subject: [PATCH 0908/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index c1ca0e37..b54b5a03 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -1,10 +1,9 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' @@ -28,7 +27,7 @@ function msg() { echo -e "$TEXT" } -msg "Setting up container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -43,22 +42,20 @@ while [ "$(hostname -I)" = "" ]; do done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null -# Install prerequisites -msg "Installing prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE @@ -69,6 +66,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -# Cleanup container -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c8e7bb708401b29aaa9886e3d828a8a42356f46f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:23:22 -0500 Subject: [PATCH 0909/6505] Update esphome_setup.sh --- setup/esphome_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh index d2205781..0594f4c6 100644 --- a/setup/esphome_setup.sh +++ b/setup/esphome_setup.sh @@ -45,8 +45,8 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" # Update container OS -msg "Updating container OS..." -apt update &>/dev/null +msg "Updating Container OS..." +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From c2ade48215a6964ac833f396b1aa4bf349afcd95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:23:50 -0500 Subject: [PATCH 0910/6505] Update ha_setup.sh --- setup/ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index ee37eadd..953df9e7 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -43,7 +43,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From 29298f31759326801e6cb27e14a4835f352e474e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:24:17 -0500 Subject: [PATCH 0911/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 2e50aa89..3cca9ea0 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -43,7 +43,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From 9391735e4d4404237e56a5a687bf28e53cc5f611 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:24:45 -0500 Subject: [PATCH 0912/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index bbfd9615..cb970ea3 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -46,7 +46,7 @@ done # Update container OS msg "Updating container OS..." -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 63c29b97da5530c93495ce7184d2002ad1cf143f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:25:10 -0500 Subject: [PATCH 0913/6505] Update mqtt_setup.sh --- setup/mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh index 84008ea8..a818a4f8 100644 --- a/setup/mqtt_setup.sh +++ b/setup/mqtt_setup.sh @@ -46,7 +46,7 @@ done # Update container OS msg "Updating Container OS..." -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null # Install prerequisites From 6b0a3266cc15ed8e5ad1fa804093d05d2c28431d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:25:37 -0500 Subject: [PATCH 0914/6505] Update node-red_setup.sh --- setup/node-red_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh index c0c5b1ec..def5d877 100644 --- a/setup/node-red_setup.sh +++ b/setup/node-red_setup.sh @@ -43,7 +43,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From a857f8c7e7a3732ac0d2731568218a8e9d605b31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:26:02 -0500 Subject: [PATCH 0915/6505] Update pihole_setup.sh --- setup/pihole_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh index 09f809b5..7d250557 100644 --- a/setup/pihole_setup.sh +++ b/setup/pihole_setup.sh @@ -44,7 +44,7 @@ done # Update container OS msg "Updating container OS..." -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null msg "Installing Prerequisites..." From a1c487e4ecde0684d6091238567bbc8e6ce9596d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:26:27 -0500 Subject: [PATCH 0916/6505] Update plex_setup.sh --- setup/plex_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index 50fcc1ad..120fbbdf 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -43,7 +43,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From 7fb18999dab12e81e44989052fe030dd22b19a3b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:26:54 -0500 Subject: [PATCH 0917/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index e74c1238..9a2f15ad 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -42,7 +42,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From 8a03e3163efe923050edbde603b329359131bd44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:27:17 -0500 Subject: [PATCH 0918/6505] Update ubuntu_setup.sh --- setup/ubuntu_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh index b35e5027..9829ceb6 100644 --- a/setup/ubuntu_setup.sh +++ b/setup/ubuntu_setup.sh @@ -42,7 +42,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From 9edfbbb4516b76bb510ed2fa7ef4c0570c25cdb0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:27:42 -0500 Subject: [PATCH 0919/6505] Update zigbee2mqtt_setup.sh --- setup/zigbee2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh index 6dd0aea7..d0ce0c01 100644 --- a/setup/zigbee2mqtt_setup.sh +++ b/setup/zigbee2mqtt_setup.sh @@ -43,7 +43,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" From ca0d03158dc871b27ad6f32c6d39bc08e342b70d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:28:05 -0500 Subject: [PATCH 0920/6505] Update zwavejs2mqtt_setup.sh --- setup/zwavejs2mqtt_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zwavejs2mqtt_setup.sh b/setup/zwavejs2mqtt_setup.sh index 228e1c73..b4cdd610 100644 --- a/setup/zwavejs2mqtt_setup.sh +++ b/setup/zwavejs2mqtt_setup.sh @@ -43,7 +43,7 @@ done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt update &>/dev/null +apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" From 74f282f83f9811fc726db6245cd4857d857d85d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 03:35:35 -0500 Subject: [PATCH 0921/6505] Update debian11_container.sh --- ct/debian11_container.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/debian11_container.sh b/ct/debian11_container.sh index d75d639a..d4a1fc79 100644 --- a/ct/debian11_container.sh +++ b/ct/debian11_container.sh @@ -15,6 +15,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT From 0e08cc81aa492b9f7a96bf13b143b72e8eeaba5d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 06:45:40 -0500 Subject: [PATCH 0922/6505] Update esphome_setup.sh --- setup/esphome_setup.sh | 54 ++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh index 0594f4c6..d62a6e2e 100644 --- a/setup/esphome_setup.sh +++ b/setup/esphome_setup.sh @@ -1,10 +1,9 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' @@ -28,8 +27,7 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS -msg "Setting up Container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -44,30 +42,26 @@ while [ "$(hostname -I)" = "" ]; do done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" -# Update container OS -msg "Updating Container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null -# Install prerequisites -msg "Installing Prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null - # Installing pip3 - msg "Installing pip3..." - apt-get install python3-pip -y &>/dev/null - # Install ESPHome; - msg "Installing ESPHome..." - pip3 install esphome &>/dev/null - # Installing ESPHome Dashboard - msg "Installing ESPHome Dashboard..." - pip3 install tornado esptool &>/dev/null -echo "Creating service file esphomeDashboard.service" +echo -e "${CHECKMARK} \e[1;92m Installing pip3... \e[0m" +apt-get install python3-pip -y &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing ESPHome... \e[0m" +pip3 install esphome &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing ESPHome Dashboard... \e[0m" +pip3 install tornado esptool &>/dev/null + service_path="/etc/systemd/system/esphomeDashboard.service" - echo "[Unit] Description=ESPHome Dashboard After=network.target @@ -78,12 +72,11 @@ User=root [Install] WantedBy=multi-user.target" > $service_path systemctl enable esphomeDashboard.service &>/dev/null -systemctl start esphomeDashboard -# Customize container -msg "Customizing Container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE @@ -93,7 +86,6 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -# Cleanup container -msg "Cleanup..." +systemctl start esphomeDashboard +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From edf9f9b2ae18933d25f604f13e24401b1ac21158 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 06:56:44 -0500 Subject: [PATCH 0923/6505] Update esphome_container.sh --- ct/esphome_container.sh | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/ct/esphome_container.sh b/ct/esphome_container.sh index 3979e7c2..4188ab73 100644 --- a/ct/esphome_container.sh +++ b/ct/esphome_container.sh @@ -9,13 +9,13 @@ while true; do esac done -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -73,13 +73,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Download setup script wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/esphome_setup.sh -# Detect modules and automatically load at boot load_module overlay -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -106,14 +103,13 @@ else fi info "Using '$STORAGE' for storage location." -# Get the next guest VM/LXC ID CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -121,7 +117,6 @@ TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in dir|nfs) @@ -136,8 +131,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -# Create LXC -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -152,17 +146,17 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -# Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -# Setup container -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 pct exec $CTID /esphome_setup.sh -# Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created ESPHome LXC Container to $CTID at IP Address ${IP}:6052" +info "Successfully created ESPHome LXC Container to $CTID" +echo -e "\e[1;92m ESPHome should be reachable by going to the following URL. + http://${IP}:6052 +\e[0m" From 75cec8e26be0ae6b63d3d0593fab82c08182a0c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 07:28:53 -0500 Subject: [PATCH 0924/6505] Update mariadb_container.sh --- ct/mariadb_container.sh | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/ct/mariadb_container.sh b/ct/mariadb_container.sh index e06fa9b9..1cf0eb3e 100644 --- a/ct/mariadb_container.sh +++ b/ct/mariadb_container.sh @@ -9,13 +9,13 @@ while true; do esac done -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -73,14 +73,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Download setup script wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb_setup.sh -# Detect modules and automatically load at boot -#load_module aufs load_module overlay -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -107,14 +103,13 @@ else fi info "Using '$STORAGE' for storage location." -# Get the next guest VM/LXC ID CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -122,7 +117,6 @@ TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in dir|nfs) @@ -137,8 +131,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -# Create LXC -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -153,18 +146,14 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -# Setup container -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID mariadb_setup.sh /mariadb_setup.sh -perms 755 pct exec $CTID /mariadb_setup.sh -# Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created a MariaDB LXC Container to $CTID at IP Address ${IP}" From 03d46eb1f6cb2e69cb90b097458e3d261340b764 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 07:34:57 -0500 Subject: [PATCH 0925/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index cb970ea3..c0647d62 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -1,10 +1,9 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' @@ -28,8 +27,7 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS -msg "Setting up container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -44,28 +42,25 @@ while [ "$(hostname -I)" = "" ]; do done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" -# Update container OS -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null -# Install prerequisites -msg "Installing Prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null -# Installing MariaDB -msg "Installing MariaDB..." +echo -e "${CHECKMARK} \e[1;92m Installing MariaDB... \e[0m" curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null -# Customize container -msg "Customizing container..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE @@ -76,6 +71,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -# Cleanup container -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 6f7fb2dd7c3cf046870de9b7444d304043eac68e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 07:49:31 -0500 Subject: [PATCH 0926/6505] Update mqtt_container.sh --- ct/mqtt_container.sh | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/ct/mqtt_container.sh b/ct/mqtt_container.sh index 44c9ff56..dc76d5bf 100644 --- a/ct/mqtt_container.sh +++ b/ct/mqtt_container.sh @@ -9,11 +9,10 @@ while true; do esac done -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -24,6 +23,7 @@ function error_exit() { local DEFAULT='Unknown failure occured.' local REASON="\e[97m${1:-$DEFAULT}\e[39m" local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' msg "$FLAG $REASON" [ ! -z ${CTID-} ] && cleanup_ctid exit $EXIT @@ -73,14 +73,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -# Download setup script wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt_setup.sh -# Detect modules and automatically load at boot -#load_module aufs load_module overlay -# Select storage location while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -107,14 +103,13 @@ else fi info "Using '$STORAGE' for storage location." -# Get the next guest VM/LXC ID CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -# Download latest Debian 11 LXC template -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -122,7 +117,6 @@ TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." -# Create variables for container disk STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in dir|nfs) @@ -137,8 +131,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -# Create LXC -msg "Creating LXC container..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" DISK_SIZE=2G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -153,17 +146,13 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -# Set container timezone to match host MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -# Setup container -msg "Starting LXC container..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID pct push $CTID mqtt_setup.sh /mqtt_setup.sh -perms 755 pct exec $CTID /mqtt_setup.sh -# Get network details and show completion message IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created a MQTT LXC Container to $CTID at IP Address ${IP}" From be3a55b208276e570d8f6375be831bdc8c791910 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 07:55:43 -0500 Subject: [PATCH 0927/6505] Update mqtt_setup.sh --- setup/mqtt_setup.sh | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh index a818a4f8..13d42531 100644 --- a/setup/mqtt_setup.sh +++ b/setup/mqtt_setup.sh @@ -1,10 +1,9 @@ #!/usr/bin/env bash -# Setup script environment -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' @@ -28,8 +27,7 @@ function msg() { echo -e "$TEXT" } -# Prepare container OS -msg "Setting up Container OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -44,21 +42,18 @@ while [ "$(hostname -I)" = "" ]; do done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" -# Update container OS -msg "Updating Container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null -# Install prerequisites -msg "Installing Prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ gnupg \ sudo &>/dev/null -# Installing Mosquitto MQTT broker -msg "Installing Mosquitto MQTT broker.." +echo -e "${CHECKMARK} \e[1;92m Installing Mosquitto MQTT Broker.. \e[0m" wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null apt-key add mosquitto-repo.gpg.key &>/dev/null cd /etc/apt/sources.list.d/ @@ -67,11 +62,10 @@ apt-get update >/dev/null apt-get -y install mosquitto &>/dev/null apt-get -y install mosquitto-clients &>/dev/null -# Customize container -msg "Customizing LXC..." -rm /etc/motd # Remove message of the day after login -rm /etc/update-motd.d/10-uname # Remove kernel information after login -touch ~/.hushlogin # Remove 'Last login: ' and mail notification after login +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE @@ -82,6 +76,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -# Cleanup container -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 0a70be2187425eaaa7a2a922169f778a0e500e62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 07:57:21 -0500 Subject: [PATCH 0928/6505] Update mqtt_container.sh --- ct/mqtt_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mqtt_container.sh b/ct/mqtt_container.sh index dc76d5bf..bda6ed8e 100644 --- a/ct/mqtt_container.sh +++ b/ct/mqtt_container.sh @@ -15,6 +15,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -23,7 +24,6 @@ function error_exit() { local DEFAULT='Unknown failure occured.' local REASON="\e[97m${1:-$DEFAULT}\e[39m" local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' msg "$FLAG $REASON" [ ! -z ${CTID-} ] && cleanup_ctid exit $EXIT From d646ecf1fd0c0735df461461ac264829b28db5db Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 08:13:39 -0500 Subject: [PATCH 0929/6505] Update pihole_container.sh --- ct/pihole_container.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ct/pihole_container.sh b/ct/pihole_container.sh index 7eb7c05a..1d420089 100644 --- a/ct/pihole_container.sh +++ b/ct/pihole_container.sh @@ -15,6 +15,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT @@ -105,9 +106,10 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "LXC ID is $CTID." -msg "Updating LXC template list..." +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null -msg "Downloading LXC template..." + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -129,7 +131,7 @@ esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -msg "Creating LXC..." +echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" DISK_SIZE=2G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -148,10 +150,13 @@ MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT -msg "Starting LXC..." +echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" pct start $CTID pct push $CTID pihole_setup.sh /pihole_setup.sh -perms 755 pct exec $CTID /pihole_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Pi-hole LXC to $CTID at IP Address ${IP}" +info "Successfully created a Pi-hole LXC to $CTID" +echo -e "\e[1;92m Pi-hole should be reachable by going to the following URL. + http://${IP} +\e[0m" From 54c145a774d1aee83f5eebf69891b92a8c3a8739 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 08:18:13 -0500 Subject: [PATCH 0930/6505] Update pihole_setup.sh --- setup/pihole_setup.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh index 7d250557..d6d7eb4e 100644 --- a/setup/pihole_setup.sh +++ b/setup/pihole_setup.sh @@ -27,7 +27,7 @@ function msg() { echo -e "$TEXT" } -msg "Setting up LXC OS..." +echo -e "${CHECKMARK} \e[1;92m Setting up LXC OS... \e[0m" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -42,21 +42,20 @@ while [ "$(hostname -I)" = "" ]; do done echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" -# Update container OS -msg "Updating container OS..." +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null -msg "Installing Prerequisites..." +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null -msg "Installing Pi-hole.." +echo -e "${CHECKMARK} \e[1;92m Installing Pi-hole... \e[0m" curl -sSL https://install.pi-hole.net | bash -msg "Customizing LXC..." +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -70,5 +69,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg "Cleanup..." +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /pihole_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From fe30a02153033ad126ddf75aae4a1aa0612a510c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 18:40:15 -0500 Subject: [PATCH 0931/6505] Add files via upload --- ct/vault_container.sh | 162 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 ct/vault_container.sh diff --git a/ct/vault_container.sh b/ct/vault_container.sh new file mode 100644 index 00000000..67fcb559 --- /dev/null +++ b/ct/vault_container.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Vaultwarden LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian11_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=vaultwarden +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 4 -memory 4096\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID vault_setup.sh /vault_setup.sh -perms 755 +pct exec $CTID /vault_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Vaultwarden LXC Container to $CTID" +echo -e "\e[1;92m Vaultwarden should be reachable by going to the following URL. + http://${IP}:8000 +\e[0m" \ No newline at end of file From 33a399a1893096dd30429da2346969bb637e417e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 18:41:49 -0500 Subject: [PATCH 0932/6505] Add files via upload --- setup/vault_setup.sh | 145 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 setup/vault_setup.sh diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh new file mode 100644 index 00000000..b3f153b3 --- /dev/null +++ b/setup/vault_setup.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null +apt-get -qqy install \ + git \ + nano \ + wget \ + htop \ + pkg-config \ + openssl \ + libssl1.1 \ + libssl-dev \ + curl \ + sudo \ + build-essential &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" +curl https://sh.rustup.rs -sSf | sh &>/dev/null +echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null +export PATH=~/.cargo/bin:$PATH &>/dev/null +which rustc &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +apt-get install -y nodejs &>/dev/null +npm -g install npm@7 &>/dev/null +which npm &>/dev/null +npm i npm@latest -g &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Building Vaultwarden... \e[0m" +git clone https://github.com/dani-garcia/vaultwarden && pushd vaultwarden &>/dev/null +cargo clean && cargo build --features sqlite --release &>/dev/null +file target/release/vaultwarden &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Building Web-Vault... \e[0m" +pushd target/release/ &>/dev/null +git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git && cd web-vault.git &>/dev/null +git checkout v2.25.1 &>/dev/null +git submodule update --init --recursive &>/dev/null +wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null +git apply v2.25.0.patch &>/dev/null +npm ci --legacy-peer-deps && npm audit fix --legacy-peer-deps || true && npm run dist:oss:selfhost &>/dev/null +cp -a build ../web-vault &>/dev/null +cd .. +mkdir data &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Create Systemd Service... \e[0m" +cp ../../.env.template /etc/vaultwarden.env &>/dev/null +cp vaultwarden /usr/bin/vaultwarden &>/dev/null +chmod +x /usr/bin/vaultwarden &>/dev/null +useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null +sudo cp -R data /var/lib/vaultwarden/ &>/dev/null +cp -R web-vault /var/lib/vaultwarden/ &>/dev/null +chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null + +service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null + +echo "[Unit] +Description=Bitwarden Server (Powered by Vaultwarden) +Documentation=https://github.com/dani-garcia/vaultwarden + +After=network.target + +[Service] +User=vaultwarden +Group=vaultwarden +EnvironmentFile=/etc/vaultwarden.env +ExecStart=/usr/bin/vaultwarden +LimitNOFILE=1048576 +LimitNPROC=64 +PrivateTmp=true +PrivateDevices=true +ProtectHome=true +ProtectSystem=strict +WorkingDirectory=/var/lib/vaultwarden +ReadWriteDirectories=/var/lib/vaultwarden +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target" > $service_path + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +systemctl enable vaultwarden.service &>/dev/null +systemctl start vaultwarden.service &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 35f3913b9136e794670c483c734a6890060f6832 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 18:42:12 -0500 Subject: [PATCH 0933/6505] Add files via upload --- ct/vault_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vault_container.sh b/ct/vault_container.sh index 67fcb559..de9063d8 100644 --- a/ct/vault_container.sh +++ b/ct/vault_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian11_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vault_setup.sh load_module overlay From f8cf049e08cd1852fe536a1dceb71175a958ac0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 18:55:49 -0500 Subject: [PATCH 0934/6505] Update vault_setup.sh --- setup/vault_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index b3f153b3..16e93585 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -62,7 +62,7 @@ apt-get -qqy install \ build-essential &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" -curl https://sh.rustup.rs -sSf | sh &>/dev/null +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s &>/dev/null echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null export PATH=~/.cargo/bin:$PATH &>/dev/null which rustc &>/dev/null @@ -142,4 +142,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') systemctl enable vaultwarden.service &>/dev/null systemctl start vaultwarden.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 4c57876b49b9357f4a99128dbadd9d104865828e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 19:12:16 -0500 Subject: [PATCH 0935/6505] Update vault_setup.sh --- setup/vault_setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index 16e93585..0d47041f 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -62,7 +62,8 @@ apt-get -qqy install \ build-essential &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s &>/dev/null +apt-get update &>/dev/null +curl -sSf https://sh.rustup.rs | sh -y &>/dev/null echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null export PATH=~/.cargo/bin:$PATH &>/dev/null which rustc &>/dev/null From 2ca240f637ab3752df1c63dedd4cd1fe53eb7373 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 19:36:42 -0500 Subject: [PATCH 0936/6505] Update vault_setup.sh --- setup/vault_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index 0d47041f..d89661c0 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -64,8 +64,8 @@ apt-get -qqy install \ echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" apt-get update &>/dev/null curl -sSf https://sh.rustup.rs | sh -y &>/dev/null -echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null -export PATH=~/.cargo/bin:$PATH &>/dev/null +echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc \ +export PATH=~/.cargo/bin:$PATH \ which rustc &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" From e7734c799efcea727d6668fa76190f35c9c505f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 19:51:39 -0500 Subject: [PATCH 0937/6505] Update vault_setup.sh --- setup/vault_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index d89661c0..184c75ee 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -63,7 +63,7 @@ apt-get -qqy install \ echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" apt-get update &>/dev/null -curl -sSf https://sh.rustup.rs | sh -y &>/dev/null +wget -qO - https://sh.rustup.rs | sh -s &>/dev/null echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc \ export PATH=~/.cargo/bin:$PATH \ which rustc &>/dev/null From ae9bd1283ba80a951d23aebab0c1877f7f6c3141 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 20:11:11 -0500 Subject: [PATCH 0938/6505] Delete vault_container.sh --- ct/vault_container.sh | 162 ------------------------------------------ 1 file changed, 162 deletions(-) delete mode 100644 ct/vault_container.sh diff --git a/ct/vault_container.sh b/ct/vault_container.sh deleted file mode 100644 index de9063d8..00000000 --- a/ct/vault_container.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Vaultwarden LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vault_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=vaultwarden -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 4 -memory 4096\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID vault_setup.sh /vault_setup.sh -perms 755 -pct exec $CTID /vault_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Vaultwarden LXC Container to $CTID" -echo -e "\e[1;92m Vaultwarden should be reachable by going to the following URL. - http://${IP}:8000 -\e[0m" \ No newline at end of file From 6429900af3a9194dfedcd9eb8d8797b3d8c8c818 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Feb 2022 20:11:29 -0500 Subject: [PATCH 0939/6505] Delete vault_setup.sh --- setup/vault_setup.sh | 146 ------------------------------------------- 1 file changed, 146 deletions(-) delete mode 100644 setup/vault_setup.sh diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh deleted file mode 100644 index 184c75ee..00000000 --- a/setup/vault_setup.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - git \ - nano \ - wget \ - htop \ - pkg-config \ - openssl \ - libssl1.1 \ - libssl-dev \ - curl \ - sudo \ - build-essential &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" -apt-get update &>/dev/null -wget -qO - https://sh.rustup.rs | sh -s &>/dev/null -echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc \ -export PATH=~/.cargo/bin:$PATH \ -which rustc &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" -curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -apt-get install -y nodejs &>/dev/null -npm -g install npm@7 &>/dev/null -which npm &>/dev/null -npm i npm@latest -g &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Building Vaultwarden... \e[0m" -git clone https://github.com/dani-garcia/vaultwarden && pushd vaultwarden &>/dev/null -cargo clean && cargo build --features sqlite --release &>/dev/null -file target/release/vaultwarden &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Building Web-Vault... \e[0m" -pushd target/release/ &>/dev/null -git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git && cd web-vault.git &>/dev/null -git checkout v2.25.1 &>/dev/null -git submodule update --init --recursive &>/dev/null -wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null -git apply v2.25.0.patch &>/dev/null -npm ci --legacy-peer-deps && npm audit fix --legacy-peer-deps || true && npm run dist:oss:selfhost &>/dev/null -cp -a build ../web-vault &>/dev/null -cd .. -mkdir data &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Create Systemd Service... \e[0m" -cp ../../.env.template /etc/vaultwarden.env &>/dev/null -cp vaultwarden /usr/bin/vaultwarden &>/dev/null -chmod +x /usr/bin/vaultwarden &>/dev/null -useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null -sudo cp -R data /var/lib/vaultwarden/ &>/dev/null -cp -R web-vault /var/lib/vaultwarden/ &>/dev/null -chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null - -service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null - -echo "[Unit] -Description=Bitwarden Server (Powered by Vaultwarden) -Documentation=https://github.com/dani-garcia/vaultwarden - -After=network.target - -[Service] -User=vaultwarden -Group=vaultwarden -EnvironmentFile=/etc/vaultwarden.env -ExecStart=/usr/bin/vaultwarden -LimitNOFILE=1048576 -LimitNPROC=64 -PrivateTmp=true -PrivateDevices=true -ProtectHome=true -ProtectSystem=strict -WorkingDirectory=/var/lib/vaultwarden -ReadWriteDirectories=/var/lib/vaultwarden -AmbientCapabilities=CAP_NET_BIND_SERVICE - -[Install] -WantedBy=multi-user.target" > $service_path - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -systemctl enable vaultwarden.service &>/dev/null -systemctl start vaultwarden.service &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 798e2ea593c9fffca464f61e799b49f55954748a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Feb 2022 04:39:25 -0500 Subject: [PATCH 0940/6505] Add files via upload --- ct/vault_container.sh | 162 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 ct/vault_container.sh diff --git a/ct/vault_container.sh b/ct/vault_container.sh new file mode 100644 index 00000000..f1f66ca6 --- /dev/null +++ b/ct/vault_container.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Vaultwarden LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/vault_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=vaultwarden +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 4 -memory 4096\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID vault_setup.sh /vault_setup.sh -perms 755 +pct exec $CTID /vault_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a Vaultwarden LXC Container to $CTID" +echo -e "\e[1;92m Vaultwarden should be reachable by going to the following URL. + http://${IP}:8000 +\e[0m" \ No newline at end of file From b5c83daf7a131aa4f63470e9673e37c87694618f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Feb 2022 04:40:13 -0500 Subject: [PATCH 0941/6505] Add files via upload --- setup/vault_setup.sh | 147 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 setup/vault_setup.sh diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh new file mode 100644 index 00000000..16bb8b05 --- /dev/null +++ b/setup/vault_setup.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null +apt-get -qqy install \ + git \ + nano \ + wget \ + htop \ + pkg-config \ + openssl \ + libssl1.1 \ + libssl-dev \ + curl \ + sudo &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Build Essentials... \e[0m" +apt-get install -y build-essential &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" +curl https://sh.rustup.rs -sSf | sh -y +echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc +export PATH=~/.cargo/bin:$PATH +which rustc &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +apt-get install -y nodejs &>/dev/null +npm -g install npm@7 &>/dev/null +which npm &>/dev/null +npm i npm@latest -g &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Building Vaultwarden... \e[0m" +git clone https://github.com/dani-garcia/vaultwarden && pushd vaultwarden &>/dev/null +cargo clean && cargo build --features sqlite --release &>/dev/null +file target/release/vaultwarden &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Building Web-Vault... \e[0m" +pushd target/release/ &>/dev/null +git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git && cd web-vault.git &>/dev/null +git checkout v2.25.1 &>/dev/null +git submodule update --init --recursive &>/dev/null +wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null +git apply v2.25.0.patch &>/dev/null +npm ci --legacy-peer-deps && npm audit fix --legacy-peer-deps || true && npm run dist:oss:selfhost &>/dev/null +cp -a build ../web-vault &>/dev/null +cd .. +mkdir data &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Create Systemd Service... \e[0m" +cp ../../.env.template /etc/vaultwarden.env &>/dev/null +cp vaultwarden /usr/bin/vaultwarden &>/dev/null +chmod +x /usr/bin/vaultwarden &>/dev/null +useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null +sudo cp -R data /var/lib/vaultwarden/ &>/dev/null +cp -R web-vault /var/lib/vaultwarden/ &>/dev/null +chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null + +service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null + +echo "[Unit] +Description=Bitwarden Server (Powered by Vaultwarden) +Documentation=https://github.com/dani-garcia/vaultwarden + +After=network.target + +[Service] +User=vaultwarden +Group=vaultwarden +EnvironmentFile=/etc/vaultwarden.env +ExecStart=/usr/bin/vaultwarden +LimitNOFILE=1048576 +LimitNPROC=64 +PrivateTmp=true +PrivateDevices=true +ProtectHome=true +ProtectSystem=strict +WorkingDirectory=/var/lib/vaultwarden +ReadWriteDirectories=/var/lib/vaultwarden +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target" > $service_path + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +systemctl enable vaultwarden.service &>/dev/null +systemctl start vaultwarden.service &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From fc49a02107eb7c28fd94a0c2bdae8cd55ef6617b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Feb 2022 04:47:37 -0500 Subject: [PATCH 0942/6505] Update vault_setup.sh --- setup/vault_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index 16bb8b05..cd7c6160 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -64,7 +64,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Build Essentials... \e[0m" apt-get install -y build-essential &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" -curl https://sh.rustup.rs -sSf | sh -y +curl https://sh.rustup.rs -sSf | sh -s echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc export PATH=~/.cargo/bin:$PATH which rustc &>/dev/null @@ -144,4 +144,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') systemctl enable vaultwarden.service &>/dev/null systemctl start vaultwarden.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 555d263e4bb030cc49224860f50f24d05ae01e4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Feb 2022 05:37:01 -0500 Subject: [PATCH 0943/6505] Add files via upload --- setup/vault_setup.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index cd7c6160..3b2ffc48 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -64,7 +64,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Build Essentials... \e[0m" apt-get install -y build-essential &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" -curl https://sh.rustup.rs -sSf | sh -s +curl https://sh.rustup.rs -sSf | sh echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc export PATH=~/.cargo/bin:$PATH which rustc &>/dev/null @@ -77,21 +77,21 @@ which npm &>/dev/null npm i npm@latest -g &>/dev/null echo -e "${CHECKMARK} \e[1;92m Building Vaultwarden... \e[0m" -git clone https://github.com/dani-garcia/vaultwarden && pushd vaultwarden &>/dev/null -cargo clean && cargo build --features sqlite --release &>/dev/null -file target/release/vaultwarden &>/dev/null +git clone https://github.com/dani-garcia/vaultwarden && pushd vaultwarden +cargo clean && cargo build --features sqlite --release +file target/release/vaultwarden echo -e "${CHECKMARK} \e[1;92m Building Web-Vault... \e[0m" -pushd target/release/ &>/dev/null -git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git && cd web-vault.git &>/dev/null -git checkout v2.25.1 &>/dev/null -git submodule update --init --recursive &>/dev/null -wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null -git apply v2.25.0.patch &>/dev/null -npm ci --legacy-peer-deps && npm audit fix --legacy-peer-deps || true && npm run dist:oss:selfhost &>/dev/null -cp -a build ../web-vault &>/dev/null +pushd target/release/ +git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git && cd web-vault.git +git checkout v2.25.1 +git submodule update --init --recursive +wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch +git apply v2.25.0.patch +npm ci --legacy-peer-deps && npm audit fix --legacy-peer-deps || true && npm run dist:oss:selfhost +cp -a build ../web-vault cd .. -mkdir data &>/dev/null +mkdir data echo -e "${CHECKMARK} \e[1;92m Create Systemd Service... \e[0m" cp ../../.env.template /etc/vaultwarden.env &>/dev/null @@ -144,4 +144,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') systemctl enable vaultwarden.service &>/dev/null systemctl start vaultwarden.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From 1b764d88a284bb22be30484952b00b9d7f165c85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Feb 2022 08:12:22 -0500 Subject: [PATCH 0944/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9c8698e1..4ad01b1e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-04 + +### Changed + +- **Scripts that Need Testing** + - Added a couple of scripts that need testing. (https://github.com/tteck/Proxmox/issues/22) + ## 2022-02-01 ### Changed From 9e148ffb6432bc97a11103bbab2eaac62c6c7247 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Feb 2022 23:10:12 -0500 Subject: [PATCH 0945/6505] Update README.md --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 7852c455..ee35aac6 100644 --- a/README.md +++ b/README.md @@ -770,3 +770,28 @@ bash /etc/webmin/uninstall.sh ___________________________________________________________________________________________
+ +
+Vaultwarden LXC + +

+ +

Vaultwarden LXC

+ +To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/ct/vault_container.sh)" +``` +It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. I've left most of the installation process viewable since the rust install needs user input (requires a "enter" key press), and the lengthy time to complete the full installation. +

⚡ Normal Settings: 512Mib RAM - 8GB Storage - 1vCPU ⚡

+ +Be Patient, let the script do it's work. Hopefully, you'll eventually see "Successfully created a Vaultwarden LXC Container" + + + +**Vaultwarden Interface - IP:8000** + +____________________________________________________________________________________________ + +
From 478cd472ad294a9c474d6bbbb917eb540816102d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 06:37:00 -0500 Subject: [PATCH 0946/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7852c455..a82b0a5d 100644 --- a/README.md +++ b/README.md @@ -320,7 +320,7 @@ ________________________________________________________________________________
-🔸Node-Red LXC +Node-Red LXC

@node-red

From 59dca09a24931114f93de3555afcea887f9f1641 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 06:45:47 -0500 Subject: [PATCH 0947/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ee35aac6..27a5db4f 100644 --- a/README.md +++ b/README.md @@ -781,7 +781,7 @@ ________________________________________________________________________________ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox web shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/ct/vault_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vault_container.sh)" ``` It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. I've left most of the installation process viewable since the rust install needs user input (requires a "enter" key press), and the lengthy time to complete the full installation.

⚡ Normal Settings: 512Mib RAM - 8GB Storage - 1vCPU ⚡

From ec16fd03019c6a34655754fe8d2e414fa33d000d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 06:47:23 -0500 Subject: [PATCH 0948/6505] Update vault_container.sh --- ct/vault_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/vault_container.sh b/ct/vault_container.sh index f1f66ca6..f4989e21 100644 --- a/ct/vault_container.sh +++ b/ct/vault_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/vault_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vault_setup.sh load_module overlay @@ -159,4 +159,4 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 info "Successfully created a Vaultwarden LXC Container to $CTID" echo -e "\e[1;92m Vaultwarden should be reachable by going to the following URL. http://${IP}:8000 -\e[0m" \ No newline at end of file +\e[0m" From 2c2200f6d22ed2f7226abaefcb497e005b1532cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 06:53:47 -0500 Subject: [PATCH 0949/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a0c5eb4..25a67656 100644 --- a/README.md +++ b/README.md @@ -788,7 +788,7 @@ It builds from source, which takes time and resources. After the installation, r Be Patient, let the script do it's work. Hopefully, you'll eventually see "Successfully created a Vaultwarden LXC Container" - +[Clients](https://bitwarden.com/download/) **Vaultwarden Interface - IP:8000** From 5d61396d4e0947cd4eda44662f14b2887a6d490a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 06:55:20 -0500 Subject: [PATCH 0950/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4ad01b1e..743bb67f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,12 +2,12 @@ # Change Log All notable changes to this project will be documented in this file. -## 2022-02-04 +## 2022-02-05 ### Changed -- **Scripts that Need Testing** - - Added a couple of scripts that need testing. (https://github.com/tteck/Proxmox/issues/22) +- **Vaultwarden LXC** + - New script ## 2022-02-01 From 53c5a145d1a35849f49402c2e3bd6379f5daaad8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 06:56:00 -0500 Subject: [PATCH 0951/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 25a67656..cbdedb5a 100644 --- a/README.md +++ b/README.md @@ -772,7 +772,7 @@ ________________________________________________________________________________
-Vaultwarden LXC +🔸Vaultwarden LXC

From 81e43e88d843372a693b5d382f06179d72163ce0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 07:34:43 -0500 Subject: [PATCH 0952/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cbdedb5a..f7eeb5b4 100644 --- a/README.md +++ b/README.md @@ -774,7 +774,7 @@ ________________________________________________________________________________
🔸Vaultwarden LXC -

+

Vaultwarden LXC

From 8877591cebe264e4f36c24304f28ec10917830fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Feb 2022 07:39:49 -0500 Subject: [PATCH 0953/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7eeb5b4..6e69678d 100644 --- a/README.md +++ b/README.md @@ -783,7 +783,7 @@ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox web sh ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vault_container.sh)" ``` -It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. I've left most of the installation process viewable since the rust install needs user input (requires a "enter" key press), and the lengthy time to complete the full installation. +It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. I've left most of the installation process viewable since the Rust install needs user input (requires a "enter" key press), and the lengthy time to complete the full installation.

⚡ Normal Settings: 512Mib RAM - 8GB Storage - 1vCPU ⚡

Be Patient, let the script do it's work. Hopefully, you'll eventually see "Successfully created a Vaultwarden LXC Container" From a2113e8df58b9a5caf626ed53827225d31a282b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:13:15 -0500 Subject: [PATCH 0954/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6e69678d..6b20c971 100644 --- a/README.md +++ b/README.md @@ -468,7 +468,7 @@ ________________________________________________________________________________
-🔸Zigbee2MQTT LXC +Zigbee2MQTT LXC

logo.png

From 6ec7674d8af0ae96b4a2c576e0c8ba712df15bfe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:15:18 -0500 Subject: [PATCH 0955/6505] Update debian11_container.sh --- ct/debian11_container.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ct/debian11_container.sh b/ct/debian11_container.sh index d4a1fc79..c002b0c6 100644 --- a/ct/debian11_container.sh +++ b/ct/debian11_container.sh @@ -146,6 +146,12 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT From e87ef4bc5ba05fff3abf437accce7b6924ad628c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:15:52 -0500 Subject: [PATCH 0956/6505] Update ubuntu_container.sh --- ct/ubuntu_container.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ct/ubuntu_container.sh b/ct/ubuntu_container.sh index dfef6a5a..3703d85a 100644 --- a/ct/ubuntu_container.sh +++ b/ct/ubuntu_container.sh @@ -145,6 +145,12 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT From ca9834801020c9bac1920fe7a0ff7d04f2b91ca2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:17:17 -0500 Subject: [PATCH 0957/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6b20c971..cdcb8461 100644 --- a/README.md +++ b/README.md @@ -583,7 +583,7 @@ ________________________________________________________________________________
-Debian 11 LXC +🔸Debian 11 LXC

Debian

@@ -604,7 +604,7 @@ ________________________________________________________________________________
-Ubuntu 21.10 LXC +🔸Ubuntu 21.10 LXC

Ubuntu

From 6acad9aff24f76068b495eea5501d14377886177 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:20:25 -0500 Subject: [PATCH 0958/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 743bb67f..ea467779 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,15 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-06 + +### Changed + +- **Debian 11 LXC** + - Add Docker Support +- **Ubuntu 21.10 LXC** + - Add Docker Support + ## 2022-02-05 ### Changed From f7a47b5d645302004c93153add05f80099754d93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:27:33 -0500 Subject: [PATCH 0959/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ea467779..ae023c41 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file. - Add Docker Support - **Ubuntu 21.10 LXC** - Add Docker Support +- **New Test Script** + - [GamUntu](https://github.com/tteck/Proxmox/issues/22#issuecomment-1030707954) ## 2022-02-05 From f3fdbe56a0f6a1268cfe8ec504f6638a9fa85df2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:57:29 -0500 Subject: [PATCH 0960/6505] Update debian11_setup.sh --- setup/debian11_setup.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh index b54b5a03..e1cbf177 100644 --- a/setup/debian11_setup.sh +++ b/setup/debian11_setup.sh @@ -52,6 +52,14 @@ apt-get -qqy install \ curl \ sudo &>/dev/null +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname From 973693351f33e072d3bec6b83feb7a0a3eadf3dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 04:58:13 -0500 Subject: [PATCH 0961/6505] Update ubuntu_setup.sh --- setup/ubuntu_setup.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh index 9829ceb6..58b67c7f 100644 --- a/setup/ubuntu_setup.sh +++ b/setup/ubuntu_setup.sh @@ -51,6 +51,14 @@ apt-get -qqy install \ curl \ sudo &>/dev/null +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin From 71728c94c9bd8881e372e87748a11ed02e9736e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Feb 2022 15:52:37 -0500 Subject: [PATCH 0962/6505] Update plex_container.sh --- ct/plex_container.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index b068ae9a..13c418fd 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -149,6 +149,7 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file EOF From e1f60455fc8ce961e8d34ed66c2464993d2da026 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 17:30:03 -0500 Subject: [PATCH 0963/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 3cca9ea0..3c26fe48 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -68,10 +68,11 @@ apt-get -y install \ echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +#echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" -apt update &>/dev/null -apt install jellyfin -y &>/dev/null +apt-get update &>/dev/null +apt-get install jellyfin -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin From 22a32a43a12cfe4437da35d9e6586e62ef007dc3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 18:03:05 -0500 Subject: [PATCH 0964/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 3c26fe48..ea8dff9e 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -50,11 +50,12 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ - sudo \ - gnupg2 \ - apt-transport-https \ - ca-certificates \ - git &>/dev/null + sudo &>/dev/null + #gnupg \ + #apt-transport-https \ + #ca-certificates \ + #git &>/dev/null +#apt install apt-transport-https gnupg lsb-release &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" apt-get -y install \ @@ -67,8 +68,11 @@ apt-get -y install \ /bin/chmod 660 /dev/dri/* echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +sudo apt install extrepo +sudo extrepo enable jellyfin +#wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +#echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +#echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null #echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt-get update &>/dev/null From e978d1ca395a0f806c5829d22986f47e310f36cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 18:12:57 -0500 Subject: [PATCH 0965/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index ea8dff9e..e58e0b6c 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -51,11 +51,6 @@ apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null - #gnupg \ - #apt-transport-https \ - #ca-certificates \ - #git &>/dev/null -#apt install apt-transport-https gnupg lsb-release &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" apt-get -y install \ @@ -67,14 +62,9 @@ apt-get -y install \ /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* -echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -sudo apt install extrepo -sudo extrepo enable jellyfin -#wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -#echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null -#echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null -#echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" +sudo apt install -y extrepo +sudo extrepo enable jellyfin apt-get update &>/dev/null apt-get install jellyfin -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" From 77f9114dc40b5feb489a236a3af18c22923b5771 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 18:25:04 -0500 Subject: [PATCH 0966/6505] Update README.md --- README.md | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/README.md b/README.md index cdcb8461..09efb03b 100644 --- a/README.md +++ b/README.md @@ -653,36 +653,6 @@ ________________________________________________________________________________
-
-Jellyfin Media Server LXC - -

- -

Jellyfin Media Server LXC

-

With Hardware Acceleration Support

-To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox web shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/jellyfin_container.sh)" -``` -

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

- -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. - -**Jellyfin Media Server Interface - IP:8096** - -⚙️ **To Update Jellyfin Media Server:** - -Run from the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
- -
Pi-hole LXC From 64624725b7a94400bc5bdadc1bf539a378bc90f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 18:33:14 -0500 Subject: [PATCH 0967/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index e58e0b6c..a52c259e 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -79,8 +79,8 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -usermod -a -G input jellyfin -usermod -a -G render jellyfin -systemctl enable jellyfin &>/dev/null +#usermod -a -G input jellyfin +#usermod -a -G render jellyfin +#systemctl enable jellyfin &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 1d83f0f77e2249187fd55b6233516fae09cc79c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 19:19:34 -0500 Subject: [PATCH 0968/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index a76f4a88..4067cfdb 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -108,8 +108,8 @@ info "Container ID is $CTID." echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-21.10 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 30a6b630785a08378cbaba5c5d8eebfcadd4e828 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 20:06:26 -0500 Subject: [PATCH 0969/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 50 +++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index a52c259e..4e497434 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -63,10 +63,46 @@ apt-get -y install \ /bin/chmod 660 /dev/dri/* echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" -sudo apt install -y extrepo -sudo extrepo enable jellyfin -apt-get update &>/dev/null -apt-get install jellyfin -y &>/dev/null +sudo mkdir /opt/jellyfin +cd /opt/jellyfin +sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz +sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz +sudo ln -s jellyfin_10.7.7 jellyfin +sudo mkdir data cache config log +mkfile jellyfin.sh +cat >jellyfin.sh <<'EOF' +#!/bin/bash +JELLYFINDIR="/opt/jellyfin" +FFMPEGDIR="/usr/share/jellyfin-ffmpeg" + +$JELLYFINDIR/jellyfin/jellyfin \ + -d $JELLYFINDIR/data \ + -C $JELLYFINDIR/cache \ + -c $JELLYFINDIR/config \ + -l $JELLYFINDIR/log \ + --ffmpeg $FFMPEGDIR/ffmpeg +EOF +sudo chmod +x jellyfin.sh + +echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" +sudo wget https://repo.jellyfin.org/releases/server/debian/versions/jellyfin-ffmpeg/4.4.1-1/jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb &>/dev/null +sudo dpkg --install jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" +service_path="/etc/systemd/system/jellyfin.service" +echo "[Unit] +Description=Jellyfin +After=network.target + +[Service] +Type=simple +User=root +Restart=always +ExecStart=/opt/jellyfin/jellyfin.sh + +[Install] +WantedBy=multi-user.target > $service_path +sudo chmod 644 /etc/systemd/system/jellyfin.service + echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin @@ -79,8 +115,8 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -#usermod -a -G input jellyfin -#usermod -a -G render jellyfin -#systemctl enable jellyfin &>/dev/null +sudo systemctl enable jellyfin.service &>/dev/null +sudo systemctl start jellyfin.service &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 915e80543c63e61f8234a5b05d9c0e006516c3e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 20:22:43 -0500 Subject: [PATCH 0970/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 4e497434..ee3c17a5 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -65,12 +65,17 @@ apt-get -y install \ echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" sudo mkdir /opt/jellyfin cd /opt/jellyfin -sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz +sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz sudo ln -s jellyfin_10.7.7 jellyfin sudo mkdir data cache config log -mkfile jellyfin.sh -cat >jellyfin.sh <<'EOF' + +echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" +sudo wget https://repo.jellyfin.org/releases/server/debian/versions/jellyfin-ffmpeg/4.4.1-1/jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb &>/dev/null +sudo dpkg --install jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb +echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" +FILE_PATH="/opt/jellyfin/jellyfin.sh" +cat >&FILE_PATH <<'EOF' #!/bin/bash JELLYFINDIR="/opt/jellyfin" FFMPEGDIR="/usr/share/jellyfin-ffmpeg" @@ -84,10 +89,6 @@ $JELLYFINDIR/jellyfin/jellyfin \ EOF sudo chmod +x jellyfin.sh -echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" -sudo wget https://repo.jellyfin.org/releases/server/debian/versions/jellyfin-ffmpeg/4.4.1-1/jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb &>/dev/null -sudo dpkg --install jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" service_path="/etc/systemd/system/jellyfin.service" echo "[Unit] Description=Jellyfin From b34be428f7b605d69e1f3b0230da5bd64be53fcc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 20:30:23 -0500 Subject: [PATCH 0971/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index ee3c17a5..0d2798d0 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -71,8 +71,8 @@ sudo ln -s jellyfin_10.7.7 jellyfin sudo mkdir data cache config log echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" -sudo wget https://repo.jellyfin.org/releases/server/debian/versions/jellyfin-ffmpeg/4.4.1-1/jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb &>/dev/null -sudo dpkg --install jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb +apt-get update +apt-get -y install ffmpeg echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" FILE_PATH="/opt/jellyfin/jellyfin.sh" cat >&FILE_PATH <<'EOF' From 1deafa9c35eee269188e8b7ccb22f79732fd5319 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 20:41:18 -0500 Subject: [PATCH 0972/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 0d2798d0..196498cd 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -65,16 +65,17 @@ apt-get -y install \ echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" sudo mkdir /opt/jellyfin cd /opt/jellyfin -sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz -sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz +sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz &>/dev/null +sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz &>/dev/null sudo ln -s jellyfin_10.7.7 jellyfin sudo mkdir data cache config log echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" -apt-get update -apt-get -y install ffmpeg +apt-get update &>/dev/null +apt-get -y install ffmpeg &>/dev/null echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" FILE_PATH="/opt/jellyfin/jellyfin.sh" +mkdir -p $(dirname $FILE_PATH) cat >&FILE_PATH <<'EOF' #!/bin/bash JELLYFINDIR="/opt/jellyfin" From b75ebbd0b302662a228ad61a5e2159daab4377cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 21:09:17 -0500 Subject: [PATCH 0973/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 196498cd..fe2fb325 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -74,21 +74,18 @@ echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" apt-get update &>/dev/null apt-get -y install ffmpeg &>/dev/null echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" -FILE_PATH="/opt/jellyfin/jellyfin.sh" -mkdir -p $(dirname $FILE_PATH) -cat >&FILE_PATH <<'EOF' -#!/bin/bash +file_path="/opt/jellyfin/jellyfin.sh" +echo "#!/bin/bash JELLYFINDIR="/opt/jellyfin" FFMPEGDIR="/usr/share/jellyfin-ffmpeg" -$JELLYFINDIR/jellyfin/jellyfin \ - -d $JELLYFINDIR/data \ +$JELLYFINDIR/jellyfin/jellyfin + -d $JELLYFINDIR/data \ -C $JELLYFINDIR/cache \ -c $JELLYFINDIR/config \ -l $JELLYFINDIR/log \ - --ffmpeg $FFMPEGDIR/ffmpeg -EOF -sudo chmod +x jellyfin.sh + --ffmpeg $FFMPEGDIR/ffmpeg" > $file_path +sudo chmod +x /opt/jellyfin/jellyfin.sh service_path="/etc/systemd/system/jellyfin.service" echo "[Unit] From 94902d1ee58782afb1897674e472d2cd0042697e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 21:18:32 -0500 Subject: [PATCH 0974/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index fe2fb325..ba841a21 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -80,10 +80,10 @@ JELLYFINDIR="/opt/jellyfin" FFMPEGDIR="/usr/share/jellyfin-ffmpeg" $JELLYFINDIR/jellyfin/jellyfin - -d $JELLYFINDIR/data \ - -C $JELLYFINDIR/cache \ - -c $JELLYFINDIR/config \ - -l $JELLYFINDIR/log \ + -d $JELLYFINDIR/data + -C $JELLYFINDIR/cache + -c $JELLYFINDIR/config + -l $JELLYFINDIR/log --ffmpeg $FFMPEGDIR/ffmpeg" > $file_path sudo chmod +x /opt/jellyfin/jellyfin.sh From dfa50871bec2c6bfb3f66e28c0cc959734f6a2a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 21:28:04 -0500 Subject: [PATCH 0975/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index ba841a21..5e505f7a 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -76,15 +76,12 @@ apt-get -y install ffmpeg &>/dev/null echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" file_path="/opt/jellyfin/jellyfin.sh" echo "#!/bin/bash -JELLYFINDIR="/opt/jellyfin" -FFMPEGDIR="/usr/share/jellyfin-ffmpeg" - -$JELLYFINDIR/jellyfin/jellyfin - -d $JELLYFINDIR/data - -C $JELLYFINDIR/cache - -c $JELLYFINDIR/config - -l $JELLYFINDIR/log - --ffmpeg $FFMPEGDIR/ffmpeg" > $file_path +/opt/jellyfin/jellyfin/jellyfin + -d /opt/jellyfin/data + -C /opt/jellyfin/cache + -c /opt/jellyfin/config + -l /opt/jellyfin/log + --ffmpeg /usr/share/jellyfin-ffmpeg/ffmpeg" > $file_path sudo chmod +x /opt/jellyfin/jellyfin.sh service_path="/etc/systemd/system/jellyfin.service" From 037255b668853922336c9fc8842523c0d836bf8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 21:36:43 -0500 Subject: [PATCH 0976/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 5e505f7a..66d31c3b 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -96,7 +96,7 @@ Restart=always ExecStart=/opt/jellyfin/jellyfin.sh [Install] -WantedBy=multi-user.target > $service_path +WantedBy=multi-user.target" > $service_path sudo chmod 644 /etc/systemd/system/jellyfin.service echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" From b99e52c73218fc04972054ea7dab694bd44d83c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 21:47:36 -0500 Subject: [PATCH 0977/6505] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 09efb03b..a313f1fe 100644 --- a/README.md +++ b/README.md @@ -653,6 +653,35 @@ ________________________________________________________________________________
+
+Jellyfin Media Server LXC + +

+ +

Jellyfin Media Server LXC

+

With Hardware Acceleration Support

+To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox web shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/jellyfin_container.sh)" +``` +

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. + +**Jellyfin Media Server Interface - IP:8096** + +⚙️ **To Update Jellyfin Media Server:** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
+
Pi-hole LXC From 6d5f2602eb7b7f64c7ee5cecc7bf74f8b8c4a93d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 21:54:06 -0500 Subject: [PATCH 0978/6505] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index a313f1fe..3bcff426 100644 --- a/README.md +++ b/README.md @@ -671,12 +671,6 @@ After the script completes, If you're dissatisfied with the default settings, cl **Jellyfin Media Server Interface - IP:8096** -⚙️ **To Update Jellyfin Media Server:** - -Run from the LXC console -```yaml -apt update && apt upgrade -y -``` ____________________________________________________________________________________________ From b7fe2efbf3c4511af0d3a9fec04a8ccbfc5956cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 22:02:34 -0500 Subject: [PATCH 0979/6505] Update ha_container.sh --- ct/ha_container.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/ha_container.sh b/ct/ha_container.sh index 802ac2e0..40c7652e 100644 --- a/ct/ha_container.sh +++ b/ct/ha_container.sh @@ -73,7 +73,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ha_setup.sh -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/misc/update.sh load_module overlay @@ -166,7 +165,6 @@ pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 info "Using fuse-overlayfs." fi pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 -pct push $CTID update.sh /root/update.sh -perms 755 pct exec $CTID /ha_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully Created Home Assistant Container LXC to $CTID." From 0e51f668b660c6acd535d11f3b4b6aa9aeb9d762 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 22:06:47 -0500 Subject: [PATCH 0980/6505] Update ha_setup.sh --- setup/ha_setup.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 953df9e7..cd560b24 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -94,6 +94,30 @@ docker run -d \ -v /etc/timezone:/etc/timezone:ro\ --net=host \ homeassistant/home-assistant:stable &>/dev/null +file_path="/root/update.sh" +echo "#!/bin/bash +echo -e "\e[1;33m Pulling New Stable Version... \e[0m" +docker pull homeassistant/home-assistant:stable +echo -e "\e[1;33m Stopping Home Assistant... \e[0m" +docker stop homeassistant +echo -e "\e[1;33m Removing Home Assistant... \e[0m" +docker rm homeassistant +echo -e "\e[1;33m Starting Home Assistant... \e[0m" +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro\ + --net=host \ + homeassistant/home-assistant:stable +echo -e "\e[1;33m Removing Old Image... \e[0m" +docker image prune -f +echo -e "\e[1;33m Finished Update! \e[0m"" > $file_path +sudo chmod +x /root/update.sh echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" rm /etc/motd From 4c62543c6de478548818f0b83839b79fa662ce36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 22:18:10 -0500 Subject: [PATCH 0981/6505] Update ha_setup.sh --- setup/ha_setup.sh | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index cd560b24..cdd3961f 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -51,8 +51,8 @@ apt-get update &>/dev/null apt-get -qqy install \ curl \ wget &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing Docker... \e[0m" + +echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) cat >$DOCKER_CONFIG_PATH <<'EOF' @@ -60,12 +60,10 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' "log-driver": "journald" } EOF - -echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" sh <(curl -sSL https://get.docker.com) &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Portainer Image...\e[0m" -docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null +docker pull portainer/portainer-ce:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Portainer... \e[0m" docker volume create portainer_data >/dev/null @@ -79,7 +77,7 @@ docker run -d \ portainer/portainer-ce:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -docker pull docker.io/homeassistant/home-assistant:stable &>/dev/null +docker pull homeassistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" docker volume create hass_config >/dev/null @@ -96,13 +94,9 @@ docker run -d \ homeassistant/home-assistant:stable &>/dev/null file_path="/root/update.sh" echo "#!/bin/bash -echo -e "\e[1;33m Pulling New Stable Version... \e[0m" docker pull homeassistant/home-assistant:stable -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" docker run -d \ --name homeassistant \ --privileged \ @@ -114,9 +108,7 @@ docker run -d \ -v /etc/timezone:/etc/timezone:ro\ --net=host \ homeassistant/home-assistant:stable -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m"" > $file_path +docker image prune -f" > $file_path sudo chmod +x /root/update.sh echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" From b2730823ea6595c2ed3bff5e9a29e110a2a278a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 22:20:07 -0500 Subject: [PATCH 0982/6505] Update ha_setup.sh --- setup/ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index cdd3961f..b3a74f0c 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -50,7 +50,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ - wget &>/dev/null + sudo &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' From 8df67dfaaa22f0623290e956dd899e24e33edeaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Feb 2022 22:31:35 -0500 Subject: [PATCH 0983/6505] Delete update.sh --- misc/update.sh | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 misc/update.sh diff --git a/misc/update.sh b/misc/update.sh deleted file mode 100644 index 232ba95e..00000000 --- a/misc/update.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -echo -e "\e[1;33m Pulling New Stable Version... \e[0m" -docker pull homeassistant/home-assistant:stable -echo -e "\e[1;33m Stopping Home Assistant... \e[0m" -docker stop homeassistant -echo -e "\e[1;33m Removing Home Assistant... \e[0m" -docker rm homeassistant -echo -e "\e[1;33m Starting Home Assistant... \e[0m" -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro\ - --net=host \ - homeassistant/home-assistant:stable -echo -e "\e[1;33m Removing Old Image... \e[0m" -docker image prune -f -echo -e "\e[1;33m Finished Update! \e[0m" From d36ecb90e03c6a2f1a2d0af4d5905886ffd1a564 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 01:44:40 -0500 Subject: [PATCH 0984/6505] Update ha_setup.sh --- setup/ha_setup.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index b3a74f0c..9b8387e3 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -92,11 +92,17 @@ docker run -d \ -v /etc/timezone:/etc/timezone:ro\ --net=host \ homeassistant/home-assistant:stable &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Creating Update Script... \e[0m" file_path="/root/update.sh" echo "#!/bin/bash +echo -e '\e[1;33m Pulling New Stable Version... \e[0m' docker pull homeassistant/home-assistant:stable +echo -e '\e[1;33m Stopping Home Assistant... \e[0m' docker stop homeassistant +echo -e '\e[1;33m Removing Home Assistant... \e[0m' docker rm homeassistant +echo -e '\e[1;33m Starting Home Assistant... \e[0m' docker run -d \ --name homeassistant \ --privileged \ @@ -108,7 +114,9 @@ docker run -d \ -v /etc/timezone:/etc/timezone:ro\ --net=host \ homeassistant/home-assistant:stable -docker image prune -f" > $file_path +echo -e '\e[1;33m Removing Old Image... \e[0m' +docker image prune -f +echo -e '\e[1;33m Finished Update! \e[0m'" > $file_path sudo chmod +x /root/update.sh echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" From 6d78576bda0d51a52a6589cb0c657c002731ecfc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 02:03:32 -0500 Subject: [PATCH 0985/6505] Update ha_setup.sh --- setup/ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 9b8387e3..027f7880 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -89,7 +89,7 @@ docker run -d \ -v /dev:/dev \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro\ + -v /etc/timezone:/etc/timezone:ro \ --net=host \ homeassistant/home-assistant:stable &>/dev/null @@ -111,7 +111,7 @@ docker run -d \ -v /dev:/dev \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro\ + -v /etc/timezone:/etc/timezone:ro \ --net=host \ homeassistant/home-assistant:stable echo -e '\e[1;33m Removing Old Image... \e[0m' From ea196ebb7cd5c6d4541c934cf2b3f153afb81b0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 02:04:21 -0500 Subject: [PATCH 0986/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 9a2f15ad..8414086e 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -49,25 +49,54 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ + sudo \ runc &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" apt-get -y install podman &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null +podman pull homeassistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null podman run -d \ --name homeassistant \ - --restart=always \ + --privileged \ + --restart unless-stopped \ -v /dev:/dev \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ --net=host \ homeassistant/home-assistant:stable &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Creating Update Script... \e[0m" +file_path="/root/update.sh" +echo "#!/bin/bash +echo -e '\e[1;33m Pulling New Stable Version... \e[0m' +podman pull homeassistant/home-assistant:stable +echo -e '\e[1;33m Stopping Home Assistant... \e[0m' +podman stop homeassistant +echo -e '\e[1;33m Removing Home Assistant... \e[0m' +podman rm homeassistant +echo -e '\e[1;33m Starting Home Assistant... \e[0m' +podman run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:stable +echo -e '\e[1;33m Removing Old Image... \e[0m' +podman image prune -f +echo -e '\e[1;33m Finished Update! \e[0m'" > $file_path +sudo chmod +x /root/update.sh + echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname From 5b12bfce32d8f76b20c7d5012f47c6344f31cbb0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 02:13:13 -0500 Subject: [PATCH 0987/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 8414086e..c0d48d19 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -56,7 +56,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" apt-get -y install podman &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull homeassistant/home-assistant:stable &>/dev/null +podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null @@ -75,7 +75,7 @@ echo -e "${CHECKMARK} \e[1;92m Creating Update Script... \e[0m" file_path="/root/update.sh" echo "#!/bin/bash echo -e '\e[1;33m Pulling New Stable Version... \e[0m' -podman pull homeassistant/home-assistant:stable +podman pull docker.io/homeassistant/home-assistant:stable echo -e '\e[1;33m Stopping Home Assistant... \e[0m' podman stop homeassistant echo -e '\e[1;33m Removing Home Assistant... \e[0m' From 705c95fbde633a6a8f7a51dd51440e1dba3b81b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 02:29:40 -0500 Subject: [PATCH 0988/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index c0d48d19..a6995514 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -62,7 +62,6 @@ echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null podman run -d \ --name homeassistant \ - --privileged \ --restart unless-stopped \ -v /dev:/dev \ -v hass_config:/config \ @@ -83,9 +82,7 @@ podman rm homeassistant echo -e '\e[1;33m Starting Home Assistant... \e[0m' podman run -d \ --name homeassistant \ - --privileged \ --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ -v /dev:/dev \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ From d1857fa6555aeef0b37bc692b8be162ee7c2a672 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 02:50:10 -0500 Subject: [PATCH 0989/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 66d31c3b..267305f9 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -65,7 +65,7 @@ apt-get -y install \ echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" sudo mkdir /opt/jellyfin cd /opt/jellyfin -sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz &>/dev/null +sudo wget https://repo.jellyfin.org/releases/server/linux/stable/server/jellyfin_10.7.7_amd64.tar.gz &>/dev/null sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz &>/dev/null sudo ln -s jellyfin_10.7.7 jellyfin sudo mkdir data cache config log From 4b199256824f5b2f4b5763c86ffd0c188cd5322f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 02:56:46 -0500 Subject: [PATCH 0990/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 267305f9..57711c13 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -65,7 +65,7 @@ apt-get -y install \ echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" sudo mkdir /opt/jellyfin cd /opt/jellyfin -sudo wget https://repo.jellyfin.org/releases/server/linux/stable/server/jellyfin_10.7.7_amd64.tar.gz &>/dev/null +sudo wget https://repo.jellyfin.org/releases/server/linux/stable/server/jellyfin-server_10.7.7_amd64.tar.gz &>/dev/null sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz &>/dev/null sudo ln -s jellyfin_10.7.7 jellyfin sudo mkdir data cache config log From a9a3364307262d49530230d63fb1bd78ce56ed8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:04:12 -0500 Subject: [PATCH 0991/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 57711c13..66d31c3b 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -65,7 +65,7 @@ apt-get -y install \ echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" sudo mkdir /opt/jellyfin cd /opt/jellyfin -sudo wget https://repo.jellyfin.org/releases/server/linux/stable/server/jellyfin-server_10.7.7_amd64.tar.gz &>/dev/null +sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz &>/dev/null sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz &>/dev/null sudo ln -s jellyfin_10.7.7 jellyfin sudo mkdir data cache config log From 35f35f7baad877fe0bf9a9de48c2dec47780ee41 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:21:27 -0500 Subject: [PATCH 0992/6505] Create jellyfin2_setup.sh --- setup/jellyfin2_setup.sh | 91 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 setup/jellyfin2_setup.sh diff --git a/setup/jellyfin2_setup.sh b/setup/jellyfin2_setup.sh new file mode 100644 index 00000000..16d8c5b7 --- /dev/null +++ b/setup/jellyfin2_setup.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo \ + gnupg \ + apt-transport-https \ + ca-certificates \ + git &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* + +echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" +wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" +apt-get update &>/dev/null +apt-get -y install jellyfin &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +usermod -a -G input jellyfin +usermod -a -G render jellyfin +systemctl enable jellyfin &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 600d9af8dbebb05d30d47360132ffcc4cb971902 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:23:53 -0500 Subject: [PATCH 0993/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index 4067cfdb..a5003c75 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin2_setup.sh load_module overlay From 4392265c01b8d159462089b317db515c3257e679 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:30:15 -0500 Subject: [PATCH 0994/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index a5003c75..6815ecfd 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -159,8 +159,8 @@ pct unmount $CTID && unset MOUNT echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID -pct push $CTID jellyfin_setup.sh /jellyfin_setup.sh -perms 755 -pct exec $CTID /jellyfin_setup.sh +pct push $CTID jellyfin2_setup.sh /jellyfin2_setup.sh -perms 755 +pct exec $CTID /jellyfin2_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created a Jellyfin Server LXC Container to $CTID at IP Address ${IP}:8096" From e7120fdde20292d825b0bbb37916a6a3200e5e1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:30:46 -0500 Subject: [PATCH 0995/6505] Update jellyfin2_setup.sh --- setup/jellyfin2_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin2_setup.sh b/setup/jellyfin2_setup.sh index 16d8c5b7..d82b81dc 100644 --- a/setup/jellyfin2_setup.sh +++ b/setup/jellyfin2_setup.sh @@ -88,4 +88,4 @@ usermod -a -G input jellyfin usermod -a -G render jellyfin systemctl enable jellyfin &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /jellyfin2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From b274ec87e5e635cc5ba4ae211f43aebf5f5ad91f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:41:55 -0500 Subject: [PATCH 0996/6505] Update jellyfin2_setup.sh --- setup/jellyfin2_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin2_setup.sh b/setup/jellyfin2_setup.sh index d82b81dc..950b386d 100644 --- a/setup/jellyfin2_setup.sh +++ b/setup/jellyfin2_setup.sh @@ -71,7 +71,7 @@ wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt-get update &>/dev/null -apt-get -y install jellyfin &>/dev/null +apt-get install jellyfin -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin From 06466b47c8c7115e49ead16ee0c1f83e4a8d447a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:48:01 -0500 Subject: [PATCH 0997/6505] Update jellyfin2_setup.sh --- setup/jellyfin2_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin2_setup.sh b/setup/jellyfin2_setup.sh index 950b386d..9c916593 100644 --- a/setup/jellyfin2_setup.sh +++ b/setup/jellyfin2_setup.sh @@ -68,7 +68,7 @@ apt-get -y install \ echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt-get update &>/dev/null apt-get install jellyfin -y &>/dev/null From c665358d21ab0e4349db6bfd495cce514113a9f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 03:49:21 -0500 Subject: [PATCH 0998/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index 6815ecfd..58e90ef7 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -108,8 +108,8 @@ info "Container ID is $CTID." echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 +OSTYPE=debian +OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From aa3d4b2cd9077f64052ae80878ec2b08754bcaf0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 04:01:43 -0500 Subject: [PATCH 0999/6505] Update jellyfin2_setup.sh --- setup/jellyfin2_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/jellyfin2_setup.sh b/setup/jellyfin2_setup.sh index 9c916593..99f94bc8 100644 --- a/setup/jellyfin2_setup.sh +++ b/setup/jellyfin2_setup.sh @@ -84,8 +84,8 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -usermod -a -G input jellyfin -usermod -a -G render jellyfin +#usermod -a -G input jellyfin +#usermod -a -G render jellyfin systemctl enable jellyfin &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /jellyfin2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From fed185db3072f815644cf34e69a11e15e476bd14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 04:06:13 -0500 Subject: [PATCH 1000/6505] Update jellyfin2_setup.sh --- setup/jellyfin2_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin2_setup.sh b/setup/jellyfin2_setup.sh index 99f94bc8..815bf213 100644 --- a/setup/jellyfin2_setup.sh +++ b/setup/jellyfin2_setup.sh @@ -86,6 +86,6 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') #usermod -a -G input jellyfin #usermod -a -G render jellyfin -systemctl enable jellyfin &>/dev/null +systemctl enable jellyfin.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /jellyfin2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c5670c4f674b10dc817a8bae0dd31af304278da8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 04:21:48 -0500 Subject: [PATCH 1001/6505] Update README.md --- README.md | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/README.md b/README.md index 3bcff426..09efb03b 100644 --- a/README.md +++ b/README.md @@ -649,29 +649,6 @@ Run from the LXC console apt update && apt upgrade -y ``` -____________________________________________________________________________________________ - -
- -
-Jellyfin Media Server LXC - -

- -

Jellyfin Media Server LXC

-

With Hardware Acceleration Support

-To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox web shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/jellyfin_container.sh)" -``` -

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

- -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. - -**Jellyfin Media Server Interface - IP:8096** - - ____________________________________________________________________________________________
From 3f9983e4b90ab77b279eeb0a9c108f7e45840179 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 04:26:38 -0500 Subject: [PATCH 1002/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index 58e90ef7..a76f4a88 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -72,7 +72,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin2_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin_setup.sh load_module overlay @@ -159,8 +159,8 @@ pct unmount $CTID && unset MOUNT echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" pct start $CTID -pct push $CTID jellyfin2_setup.sh /jellyfin2_setup.sh -perms 755 -pct exec $CTID /jellyfin2_setup.sh +pct push $CTID jellyfin_setup.sh /jellyfin_setup.sh -perms 755 +pct exec $CTID /jellyfin_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully created a Jellyfin Server LXC Container to $CTID at IP Address ${IP}:8096" From 8fef9a56b5df202541dfd911531a3e3b71185aae Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 04:55:23 -0500 Subject: [PATCH 1003/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ae023c41..92b389c6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-09 + +### Changed + +- **Jellyfin Media Server LXC** + - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issuecomment-1033567284) due to issues. Changed install method. + ## 2022-02-06 ### Changed From 3bc12f0bd55a05080d1c964edcdc19f5288fb737 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 04:58:51 -0500 Subject: [PATCH 1004/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 92b389c6..d2128ad2 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Jellyfin Media Server LXC** - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issuecomment-1033567284) due to issues. Changed install method. +- **Home Assistant Container LXC (Podman)** + - add script for easy Home Assistant update ## 2022-02-06 From 17d449ecb92c43ba7e97fd10fd7f3c029a0404e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 04:59:49 -0500 Subject: [PATCH 1005/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d2128ad2..c34fe6d2 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,8 @@ All notable changes to this project will be documented in this file. ### Changed - **Jellyfin Media Server LXC** - - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issuecomment-1033567284) due to issues. Changed install method. + - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issuecomment-1033567284) due to issues. + - Changed install method. - **Home Assistant Container LXC (Podman)** - add script for easy Home Assistant update From 44d13c753901f565431610ca4a0bd8e865c8839d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 05:03:46 -0500 Subject: [PATCH 1006/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 09efb03b..ee519f5b 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ ________________________________________________________________________________
-Home Assistant Container LXC (Podman) + 🔸Home Assistant Container LXC (Podman)

@home-assistant

From 215e04200d05ad2b38788bd3218b5cd5bccffebf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 05:10:56 -0500 Subject: [PATCH 1007/6505] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index ee519f5b..71ca2885 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,12 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. +⚙️ **To Update Home Assistant:** + +Run from the LXC console +```yaml +./update.sh +``` ____________________________________________________________________________________________
From b3708852cf8ec9f9de1803a2b6eccde1f10fd911 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 12:08:28 -0500 Subject: [PATCH 1008/6505] Add files via upload --- setup/gamuntu_setup.sh | 108 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 setup/gamuntu_setup.sh diff --git a/setup/gamuntu_setup.sh b/setup/gamuntu_setup.sh new file mode 100644 index 00000000..fc268275 --- /dev/null +++ b/setup/gamuntu_setup.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo \ + libnet-ssleay-perl \ + libauthen-pam-perl \ + libio-pty-perl \ + unzip \ + shared-mime-info &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" +dpkg --install webmin_1.984_all.deb &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" +/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null +rm -rf /root/webmin_1.984_all.deb + +echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* + +echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF +sh <(curl -sSL https://get.docker.com) &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Docker Compose... \e[0m" +sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose &>/dev/null +sudo chmod +x /usr/local/bin/docker-compose +docker network create proxy &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +rm -rf /gamuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From df681ada8c73c009844eeb9068e32f44fb7e9bed Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 12:09:01 -0500 Subject: [PATCH 1009/6505] Add files via upload --- ct/gamuntu_container.sh | 188 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 ct/gamuntu_container.sh diff --git a/ct/gamuntu_container.sh b/ct/gamuntu_container.sh new file mode 100644 index 00000000..9e3df0dd --- /dev/null +++ b/ct/gamuntu_container.sh @@ -0,0 +1,188 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New GamUntu LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/gamuntu_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-21.10 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=8G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=gamuntu +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +if [ "$STORAGE_TYPE" == "zfspool" ]; then + CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" +else + CT_FEATURES="nesting=1" +fi +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/uinput dev/uinput none bind,optional,create=dir +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +info "Using fuse-overlayfs." +fi +pct push $CTID gamuntu_setup.sh /gamuntu_setup.sh -perms 755 +pct exec $CTID /gamuntu_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully created a GamUntu LXC Container to $CTID at IP Address ${IP}" +echo -e "\e[1;92m Webmin should be reachable by going to the following URL. + https://${IP}:10000 +\e[0m" \ No newline at end of file From 86daec34f60166a3342361e6239cd2ddded23885 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 12:13:00 -0500 Subject: [PATCH 1010/6505] Add files via upload --- ct/gamuntu_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/gamuntu_container.sh b/ct/gamuntu_container.sh index 9e3df0dd..d0fbe6fb 100644 --- a/ct/gamuntu_container.sh +++ b/ct/gamuntu_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/gamuntu_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/gamuntu_setup.sh load_module overlay From 758d85184a523e2dc54424911e81631709d1839e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 13:02:55 -0500 Subject: [PATCH 1011/6505] Add files via upload --- misc/images/gamuntu.png | Bin 0 -> 17177 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/gamuntu.png diff --git a/misc/images/gamuntu.png b/misc/images/gamuntu.png new file mode 100644 index 0000000000000000000000000000000000000000..2e8fe68617d470e496f6a86f960881c7786fcde5 GIT binary patch literal 17177 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 literal 0 HcmV?d00001 From 1330383e64833cdd2bccc9120ea9a577e9dad044 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 13:06:54 -0500 Subject: [PATCH 1012/6505] Add files via upload --- misc/images/gamuntu.png | Bin 17177 -> 1071038 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/gamuntu.png b/misc/images/gamuntu.png index 2e8fe68617d470e496f6a86f960881c7786fcde5..b29f215865c839beda3fce5218517c7a63e27a2a 100644 GIT binary patch literal 1071038 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
wv(2u9pB$mKvcALC{7UlrOS>KNuL|Ag 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 z z$k_}S)_)PWDthYnc>@hb(d_}tDrzO`ZvG!K6I8ecns?F+0(NJp8FgpFbS2&#i)G1p zWsU^|>Fakhc6^sFQEiwS(poEYA#FvPAFin91i6yZFMp1d4hRsZ_qAX;2=WCTtUUeT zy(;suVO2PO^;%8F*UysF*W;y;ua|+1Z(7Jvk(JT2h1R-v`LPL12Y*}DL+VB$cJJlt zhex%YGK1@ynZmm~TOwqk2%muw=!&$)=s%}ahC-LspTz&rn&lFOd_FZ?22gj0I`QO{3iboE_5n_v z^($m@1x>#p_77ODVXToFzEvQ0E9IsRmS6{##iTKQ_;3?NB@Osw$nvKc2|=+0Sa7B{{CxuiqGbPe1;!6-7MGT8*TQ|=uy1+fEne~{RERWw2qBh|qWyr) z{IH1Yi|OgMnX|;jV_fq4>$2CS39mXUZt&DVaP??Z$lGE8iIZTFKyI5QdkWH-6AlYGG9M7NT({{Uip+=Q##YGE~_!u^l!@`#RDw3f8~7uykmJ@OdwY24$_yN z7Hm1oRCgmCLyc>{mi7vX4^IwAvrc!3HEF$hI*BK~ZEv^_zOT|ODa*+@l=(d4QQ_5z zl6!pTVq^R4SuqvFwSJ#&-SUs_1d5KSPfzEV2P{%7_MDU z?1ys~<}wtVS`i;r@^d94Gpjy6IfgTJ%>~+3KT;=n-&}pcc(-#sUTHgN^Z~fpSFV!S z_oMntF{~-jd7D&^zIwGnGMe2`d(pH{Hqi7qUN2`tldRe8;eAA+?4UofnMlIfgqRyF z)+RXGg|1{-`O(nX>voxDeiP+Kks<2D*vOFw{i+qVTqC3+&acD9iJ|?%Q~mtq0d>zU zEqTcSCWJcw5sPTl!xSAPN&v3Cg}=`Q6=D^bqAH(}#SeLq7^z+f>Rf19ve368iQ)wO zC#i#}sH<>S>Z$^ICBDY*ij&UNRJgNLb4&3+vOEQfIuzKPsO;!q+F5pA-xPMS7R5NsoahlZxltnEM z;}LVPl9lKX7_0Cnh{duJsR4F_S_An$lj`9vGZdmWbp)FHj1CSv=)f$_G_3{MChHXo zG;nv@BW*M2g{+WAYX%)LHC;d+)I5c+j5z{r88z5KC1rZy5t? z=#;QAoX&FMv8q&ggoTZ-*d7CjS~a_v2Vl#36WbgnApOw`IC?A(?DNc0g0I3isB}YQ z>7T7>SA@k1K}76xm(->&he036gJlXJujs=TWyPXty(a$fMwvhSOH9>n`nUt)pbILH z&A^t#4eP)Q@h+{aQI?)}(V?E?jcR~&Qa@(H3h>6I!3`<4wzF zU>d;aA63`f^~?$i66gSd6e;Uy2HCx|Inev_@-(J4G(GIIE=41_`B;(rqqnS%tEHhJ zfVY=NIUI$Dm%=xxnXeeOB*yyQ0t#&kCei^Glp7-IQ5!G-hDE%IqgZ!6#ysk!1Hr+y zD#e^NhiAewf! zpj8>kvS9`Cr{7pblm1x1d+~3W3_PF2Y6i`On=LJ5GuSNnRU@Lax3+yA^F1NjunzAY zg@k2nE%6mwP$r14wxwNx`|_;#P^YOw4%dM3%L zi!A-Aw0Y*&>${g2zvY;3f$*Eim<{dbB?cc zf^+2qQ6X~AAQ%IPF=gw$4ycA7O+UlVfCLY^aW=V&y-3CXkvYhi#3`R*{7>1HuUY*5S39CB;} zPvRsw7C+n`m%_E6%rTn%s;NWhw)$(C4iZLUBDFlEyFz+9k=Zgc6q9YL?HQ^f~C%-kh5m^|@=R%qRO)^`rJYAa+!$~vVO z4cN_(OWGYS z7(X(gTtk*&H1uy246@Yhb#me!1pe1n`k&{26oQHvO=tP@umRPNh5CsB<~xuf*N6M?P-}WX{Z15A%-qND5qTPa`cIer=D@ z4>XqeXVRCxIs16ulDNkS19-O8b~ILSM-*Rg`6vH03TwO|5Sq&g zF<7sQ%QRvc&)1}&tco(MeJ86O4CToOrb=77ccGVc>~FGz*F(RjB}%%4*TsxAy?yMp zpQy3BN?}J3CXkxt4A-tHi3q8c084bk2hZzmV6Bg*yM7fq<6wXk7WISIa5@P5cbPs; z5mbO(07?Rso83V$MuJdhv=JzUPB9p7gC7mej=to|Q+q51c5n z$p6acud*9$qVTm_$=NM&ktvEgX51}FVDbF(lV9Tc;NjKZeO%A2=m5{X1@EgrgD*UP zY*OzIOJ(d{oOMi1@?`8B?N{tXgoq|3H*rH<@Fp-Xk+b+Aor?U*-q#DK3eQdpU`Cuh;3tb=FQ~k<%^*sMCgc zQh-*UlSzJk>$|6~XW%;~p+Xa-?OdzGkRxj>CW>yXs;`p+Y8}Xpy+^l1(0Y?b`&KP1 zXJLv~x2uM5DI_`4b?AW^KE^UBy|KF*Yi~2PLAzeRUTMv&h*AYx?)mwPy*xUH%$7Fy zOhfXw&Gy_4*A#Fi4!eiKYA-mvCQI~3+?4QVIz`8dDdG%Vn@k(K#e>VpTSSW_W46n-}vi+-j;bJM<@YJOFQ85+>q{`o5MZV z^w8cO=W?+hsEHpzHj+orRSQ&u0f*>%AJ*Aw0meu%9w zUikuAnBcF8IguXRzU9xM#znDEbT>|4NCqEnj^Dp6#oS!2ejS&kUqXKH_(;H$L6Q<` z5V9b|+X(8Z1E=0zQ%VFvptS4pKkk_`o?z~STo#{(@Kz-#^jxt{iMj|-FvOJ*o4&)Du5w8`C%lRr#p5Ad;%Sh$UA=Vh!98zvhy#n(U!)tjU>^WId#qI?1YoytsDy zIBB6vSnNP5<~vn?(hauLVkg(&WXcy>+;xsNTe zmt7R}Y}o7+N!nbPzdIvSN#LZ3P`U6n)=v`FkHu;#R$>YH$Az;f_O$|yWA1lFOZ`d(L3&XO@fZ{3Jlu6nU?T9I2St3Qi zRR1<|SRirZ`tED1vD|J2kX0jM3a3|d3>R=6;FtrfLA*chgMESdh3m8h+;a~iN6p@h zUig&U)Z*5aO(_)c^7$t~U68-fpcxwGzX@L*9Oh`v>>7{-ZOEBXaYpED(+2)#4UCiY zk#u~;xb=_C=T^M^&_H@?S%$&WvB>4SWTW)_F}c>aUqvZ5tGeKd#u)psi9Z5MM~B#$ zkBTsnjE6_lRupn&;s1ENpzsB(Z~-NNSpigT{2=vwarbd|v7n@gXek70E)6XBfT_QU z&|ifH9#affTD=46XBSC)`MnTRcBk{4XrHI;(ESs?hy+O? z3F1o@v^ByHva>!q#76_eBxeT8B?Z8~nZ!i_;eFAdK(tH=DSsAePm-VPrk)2I;O5{) zfk&nf@=R!ca-!fP)K;#%J?nI!&gXTgJIJ>znJo8h&5|$=o2k~t=~DAUUJB1fXiw^# zEJ6JzxORO!XA%^es^lbZ=bs@P-&mg_q9X}&w?aVOy+(n%RiEPRSD!?=g=uD<0&#!Y z)ahmBT(Q~=J&IoGgOxgWZ`v%G)et_;i0LpgGiQ~&Z&eU=e_7+d*yhkbZa}eTra#ke z!LEF0T@2ICYFePg#TBSLSoLE1jpy0Sw&$N~vj4<`h#Ki)y_|!*1m(37@(8n%nll-- zoCE*VsI{*N(r+Db>3yuk4}zSr4}2X#PC>3XZEp_QeYg2=cVlDcr?~d7C!#A_COw8F zr>7O^|4RgK`Tu$nWlRVg_%5SW5&8w~InIrbelzl{q(hycG|ZM6y&hgh1e(_(idr0Q zr3-KA3zQh9-llfdAu-s7n%qo1(f1!0q=#L|oqEbX)9+@ZE}kYQmYb5evUQGU*tlj$ zr!KtS#_J*4c+yc9S#1S2<$~{6rXF!(WkSQdlV;Z^*oKofh2eHEQ_iEGdPgE-odwb) zJ@d4IBed;pN^@@s;dNCn#)VgFu=PVqg4t&j-)h!B7|+Wl7~iHum|CqEUJto*uR|wx zX4Ss@scN7fFyS|B%Pz9j5_T=ccH3>LwFj06c1-kTJv9zQS)KzA;>!acv4M^Z^CNdk zntPrKp+g*(u=qw{J676y<=IF8NrF*6!^h%H94PgoW9B0m&{K1eb}Iz+evoc64<7H~ z>f}1f741G!8f6}PRBiHX8$vv_{>OPQASpV#eT74YdxGueFrusGN4)$}bp@=J^T>tB zsen@mukJtu8mh`Vg9v~UE5;D=QjmwiaDV_D%tSJ^;oXAv0r1YEZml)mAzSdSP zAi5FjMjD6BO}=dPmrTk7+VYML&M&>HY-#>>Lo=W4FcLFcU*-PK3y^B7hmDWCKjgriopaJs zD4_-YP;F`F(ViTAUR2f1>by)6&8{y&=i0boXAP6KNLU$kDQK_}ZIKT;{MpMo6J=4G zgc-LqL};$_nKj0VOsZOhI@3EXEmT7}FC5BbYm+FIA69%<`ot##tVCXSxxfpo{S+$4 z9*(6*SUg`EbzX{4IUchgx&2!Skh5h{wK#?C;W@^?%DQ>KsmPWl0i>@E)W@F2?o>u zR|MBd5yfMg(Mc;Yo2xB2NM}LT$BIhiPk$Z`?m-NLrxDBS{U3bVNKlMPii6zx-2DD# zea~EJy~=hXU-AD^NAwFw%+-YGfGZTW5E&dw9?$y)(l_vkhI=?S4j*4?NsctdOphEo zo?aXl_3^6FLl})glm;LG3Fa_#gAz+L3$Cr~oh&sCrPx61sRJ&uSJb8+Q`~TFx5w@{ zE;w{b9|k5v&JRYG|5{^%YqoxQEj4(t*D#}99WQm}6;^}ncXhD4n{QGTTe*K+1Fb#| zNj#M&nt`oiF~?-QKoqjt=%Lu#Ez1FKiOt2!nU&F~jK2By;K9f%MB*nCC5Mb1LScDW zm6Z@JG~Me#Fuzv?!OZZ;x?(Uw1P5#>1nu9ult%nFnPuO%+CDYOIC;yL9hFeZU(kc;NXf zisi>+dlLmp=y8BH9u1h9x=W1JygrhOn`~RV?j6<7@sd!*lisJSE?smwIMgE&c0`0FE7dfbSoM015uTL`z{%aDaGe*tiDviLzbp{-T) zYxBI!u@(RaCzTbsz~94x^chVeY02g@A@GzPE{zU9bBz>8ohIPKcG(BPdv6)`Ji;QP zic6;6D=+I<{Ss?A(vT@%n$k7tcV+Sm!HzmBo}{i3v+EKo#Yl6~t%c96EJT@^yb(sP znYC!2F=t8L0(GGLX)HGzy-X6fm(o}5uO$OchL%rf2l%G8{c>_Gm;aP#t=$sS`#bRj zoXR~scxx{ma5SjD|jd;aIc>6R1j?(Boxog(3Y-R7i~o!uhftlmvhCti~^26NOn zSF2QDU6FdklMev^+Tkz|8aVR9oib^GBR{^~?N4ChlgZ1I<$5vlC^p!G@xV9Ue4Zij zCF9?|KTH(*AN3`I2GtIwrs5bZq5dGAf>wWs2Ou72YztD15m12ez=vrxDER4QOQacy zpe8sMxq*kwFp|&HD)SPh1)si{Xprk!JpKehi~7J4VG3AAn{Bj%LJQb9Y!{S}WBz&d zqrtyck;|L^Ja)ECoPtl39^^G_o0lc2a{qb@p<9xDc&^bIKzj=5-7~Q(O9>=4o^8=$ z_~PH1t|N5RWIE3KqkafdPzM0ZIit?hb3)}npZb*O0hT#*>z7Z{cgPzC{-`v`#1Plq z7c*UpknocTKiHfQ-tjH*KS*ww{j;NFP{bVh z&10v#nXde*ojU8jg>j{=MKHFbU&XR!bNu(LS-5QCixzw$XOgMyL)p>SKDVjnxQXgm zOhIE64TUPpw!fB5TeW5h?DXRfgWuEDox4#3;bqw&4ZWd#x3aW>x+8H($BC_rN9%l_ zNA?@!ErhKQIG&KsNY#bMk$2i$kwk24I+uU&@+~#X#TH{r-LdGu&qpXhJo)ihBXv^` z^s4gHvK8*6H6KR^OTM#zRsW8aHMJ?SR=^Icul=sZ5XV86z#+7Iu(jLvc}Pbg*$)C7 zAJKIQ$h@^Sq1&UNXxlwhp__UkuAOigVzP3-L8tQMt?0HrM=^hF4`&{hMW(P?>4;S> zRAdTSYRNtVVUkCwNhvRU%o|TX_KM07_0%7gVFv?-v;2 z2V5jG@@g%Z@+%_YzIftG~ao?UZ%N!xHA1;MbWY}6cdi#@qX5;17n_hhULMNvzXivK&` z@}zoNeVX`xOA>+uI+6e39z@^@wCK2OS5}8)dq{(BeukQ&7W-K_54YiC)|?=`f?XkS z0)&avqKp>%<{Uit1%^nMu*J@!m3s~6Rstel;y`>fg*_}Dp#B(Cn3kcvRHNy^MK*BH zUev{h#)56(4~J;AIC}6)RVGjTOJe|~D6#Z6kpA+_!2j!u=bv6f&6qFgS$G#3NVp{T zFtPi_tNktw3tz{6E)U*!GFpBDb$i|9i*mpzG8UA5=*1s@l=az2Jz3Gark5<8`LcON zsWR|rwyje4F&hlLZ|42nV8!IKbJ)}ixUI`0;k;8?u%*2~;=`i~5)4kTwI4>{0=OB; z!oZKB-7(Ew6bLz^) zSW+>g0w4CkO%*(5E8#|g3_a`l%@B+>$YwhK5&+dd#Yby{wgsVMmH@Wqos(z`4BnZ7 z?-g&s7u{9k1zZhO7fqc)RVgtN3!3_JMN|#L&nRJz8EL9UM`YjNxwXuEU+df^W`VH~ z?ZT`I`m3ZJyZpvcw&u6pSocT?vC;}%a7}x+;-zTO)DYUKG%BR_$5)4o$F*T24-K5c zm_WcqVV$`9w(N9-mhHhIwmfOOarXE0Kked4XVM)Q)$!~fSIHqqVp+HCseux1sblX{ zn=;zD3^_NbuX9R(KG&ij=l7~P0N6a>^q6z$#1Z?z{}qW-fDfnB<-VBj{urI_!5lUu z{dVWlplv7Z*UIitzUHa1EP=0Bjg(YshQ|50!3VPQk)gt`*4FF>@v=vAW!OtXES(5g z?h7Gkbz0@;tHkF~fW`8aZTgRb8Z(swV!w-5Frqlq5lKakr_C~1t4;evfPYap7kHWR z3|Z8#;1Jb}Jt;w83k}5X7KUIP*vgY9g++mnS#n4xN1y8`Ue%u=r-IJB+m9jfOnx-f zGYtmp*p0ylFf;sglMsEijK^;aL?O{QB@Ayhu@$g&zHfaD5MGZZMsE;RL8~W#Aj)0q zq*_m*4%uHHEJm|o_bP^JItOzcyf&ORwNWypSU7f!1+?6hN#3oCos?1lOogO>9Xvdb zOeNT{L}f_Ms7(_z+g@Q&kJ9{jxYOfZ1ZjCYbTqhM{=M8MNAU`V)$aeL_ph?O7~KZd zMehkNYW`@=ee}uQ@+vIXD}2ma^H#6}9ekn=NI0I2uf8Q&+rT&0KzOOY$2P#^!jCiOadnC}^6 zD$)`S14rofEi&o53qUn8)3g=raVj0l-m zGzw(%(+nUv84ryAkp*o&k#??N{R?@c@j4D#l^1FIXtr43KRfAUzuOP8sD{Zc5sx&g zzx{5BT~H*9AZ5}xi^(>hg;u3iVY>f86)Z}@Olt-tsIf^w!5S$611SjVv9k)g{quTc z7l18GE@`m^%II4H=;bLDKtKU)2oG4P6#zqDW2sLRS%V)y=Zc$#t)4ID&RN}DEG50E zR+T0Z5gP?caoF{mf1x7Sy2vE@|7cpokSS<^p}dCw(H+VNx>?D?3{n9LDGHXQ2rib* zG!wO;w`QbeZTQRxX~d)3QYRNIrlGF zc?ymKABF?ahiC8@ZScVfnzhXg^uX&UhOnq{NhxUjI#e2%_Z)pD;iH67Nm{<`5Cb?3 zBn2A755;wUs6K@2e;^0Umr(0OjuiSpJyZH&)BtB!tY+Y}>CKk7256&p>eV)T>(EWA zN^5JHgQ2+GE+7ret4bew`NwGd`o=&d^67o4OffkPrsm|+s??>$k|yW*A5$@@y9%{? z*RrV0(w7yVtLviYlD#MG_i{zz%3M&|Xmd0e?r2LO_XwOmrz0o`v&8KV2Sl4C1tt9H zO`y>60cMJqmRwJR36rO;dSX43)}b%)#t>?o3sn;{k^OJ!&v#jIW=Hc;U8k69Oc>}X z;%wB!=9KQ4AW8Pr8ZXz4*7> zZ_vtBR$qSD%(vVzQXxbW9>TcP28Wo65U<*}9O+s%MrCS}3Zw+I@rjT1{Yn$@(H`tU zU3A~35lybux*(4{ppk7XL)gF`yGDynFjK;sfW0S$6S*J(u$j}V^>sjBCOOlyzadh~ zlXr{p?{i7=73t{LV&7wmyt%4gu=l0sui68vhKm1R90;vK5 zjx@@fv{h}!{Z(YLp0YM$WC8=;X$CdtXfmv+tkEsXnbZ4cNiSb>C;j%pNC(`TU0wW( ztvf8DtlQu9Uuu8L+jibb;d`C!cDiI9K0W-1VCux-dUAT$Z*o&{WoI%}6ObV$aGMWy z?%pm!&{hAHt!btXsB4vI=%MS}RJBpAQq)M-e@{|d@f0{-ur9u_1t3B{_XFzQrlH52 zG$<7dk1eZv%JO$6*fb?R31(!!oJ?m(+b?0G!rvtXbt`WZ6y`#u-z87dV7E9$jcKl zIwYm~E3`%Td(4_tu-V1<8VXLMMX-L@BYx>OR^8J9W9H4mQ~> z!P!RX-d)Ouw{19^6sje5JT!juJUGQAIapmh`2{-HDDFl4W_{fIU$4S-OS5p!Z$w{; zE^6(w`B^Cm1yQIwwU)y;2hL8kJF1<1-4o>RZYP-T&U+Li^k78Og`6_#l$OP+cQ>XB zV>!%qFaP{-y4KtMcYS%XBodq6_$=X461$9|Q;Vpmu-rE7wA{-uH6)vga|i<6xs?dpo6Iv-CEF zu$o`|_%5;>iz&D!N@hFh@Mzx$SFH&4Lm0`Tptk!qkbVoO+~}R?Dw6YI{d;e_m2e`4MBV^8I!<@^H`9JY5V$BnA8qla z2_#{z{WZqEL??|)fhx~T#Hnyu@gF45p1P{UKsHG>73B`jBbl2<8JjOD8gN*}BV-2S zjcHz#cpLN#+Z*sGohqcg*&e#Jlk6fwg$qzh<@M}(o#F|G*Md^z`&NF1D0V(Uk&m)l z3V(r2L(mtk4xJ*u$SNXyq>>cDpeb(541SIElUiNXW(BR_yeI87k=9&du_6;A1|_W~ zr+C2=k*-&35zC4%@1Hx9mb`xl6Y9^uH>9Fbt;s!FyTIxY6vVVLyK~>^HOAa!A9fVh z8IMAfhgHOKp=Q;lF6)TB7#<@w`tf~OI7ZGk80uZ_%xc3p?G%4L&Q1N_1`sFlcgqtX zIw(Xgd{O<0$H?fi<=QS4b%=%xyEIq=dwbLM&yy?NY6Jg!U$fP*Z7&7x>w57F%XeXdvTu5SV!Fs+dsbk-Vqdp-8PseYso-P zi2mS#K6~3`+jT;X{tx`A5I$zEPIL3Z26Wi6&l@5eoZGqX)Hq!g+_kKpvBUF`>0RyR zAi#Y{u=RqO9t*;_$rh$NQ##^_Xf7tGS{(WFStz)HU;=jc4Su3|t{_Mlvc;3?6tdpk zJWYdF@*E)+G&d>~v_+9FxyhO?dSaa}vJ2Xq3b|kLH4!)xFN>84`;4oN{{VtRq4$~) zDx?O?&M7Iq;$0fGv~-ZEb_8*5z?-U1FfoF?N>NF>ip^I;BMWHityZt*pf9 zSk~!AMdQROb@KEW+lk#i^OxNf0_S|uKeTE!s}h;n=4(0G&%GW6T3Ax4*k_vTb-)#l)$bgF7Zj_l!Hq1Xo1pZrOZFJl``s)RU;dDZyo9R8e?l@}v? zE5#LY!-&9bbr>cH5@tw916KB>=#15e5_ka?QDy86B=smpVz7}q7VD;YM)%AkV*c{e zTf^wm7mUhlqTjxkWHa*(usD^g^_Mmn-AK)2gNs^^Ma{a8(lZK7^tVZE*y;E3vJYMg zIhfLBEvDrowdE~X^yR*99T*&XY(zwmHhCk04^)a0AQ2fvy0D+RmpCS}X7)r#PDOcL zSTX?E3DAXeDO#VWH`*#nwczi}h{_i^QJ{?f2Jq!izuZa4YGZf73B)^|(7yYv_2;no zK0=}XN;T7G| zw`zQsH)j0pUCl+dP=KsyFL^jKv)3qmG-Ts&kh=`p}TLuu(Sea+#Ioi9Kagqz0w) zb|X|6>q_kQqr<5@e2yY6R`x*QWNDqQ>Dgt zth639WguES%h{)SIt195PvuDz?^WiM1gw)Mn%=9z+tN5@4hp6u%9#)}&1mC!RBGw6 zqQUUaFPwLOX~7u?Fe}V5&9}ZHT?l#FYh~bdryb4uAoe;=6JWbN>?A?~>7c>K6eW`c z6feYF<|{uD0rUs#Xm)_ogAIhoz+VtwgDv#^89sxv0>0^2no%Q27fMWZsZ7(l6_i;5 zWHXh71?!>Vuab2IF(ZZ}#weZxAzyKr`lr-=ts?u(Loy3tL`G9gxDB|=yG5hUM69hY zW{F2RR_+~Vn4B>;Z^1WxKr98?&h|WC>T>cH47RzxG&FqdUgQqr0fx(5RA;3ot98M( z5E=|wlWo{kgwOqmz_7*4TNWcDvj}2R0dUPPtDsdIgv+C`^R9kM@9Kn0X{-%Lr}HS8 zezMhusPS{ERqsa~WpDOnRxMlC1pV*TTK!LcKODHeiRfqaGru?EFX6k?!pHpJjq;vc zs>cR;jUG4xB%29jZZo}C-~^TAUqN{qzd019r!*k2_JbXHRm~<_(>j6{)E!PH`EY!h z78iUeLoF8V{d=KH7mSVZ_L^AbwI?kc;4>5!kGV@%@5Dr7ZSegfx%=q1>taXKN6k#p zohKh*0<{%=Up9o?atV>e4F%Xfcw_ffh>JH~Sh1nS^Y%q}`56{+ z6$Jeqk8K6~=P*i4zvBUi6$e?uGl`yf{*04tJ&c1AcB^hT=yn8L|P zmQW@+YA~0>WPiy(ioY>CmtO_*;jR6O?mkB$5*|}y>LkO){<qbt}E5d2|-Ud6SmWKPV#Z5saH5|Q|!~`6U`sa z2$6nI1nkLq@2Abs*jej9m#X^nY;jt=hRs&Lwb5(KfHOOftxTFx+o0{nxhtu6U&dF$ z5`sAU9(62783ol7@yWDe@qHI14{G589tqNDC9g&fG{*K?W`u8SI}ogg7~CFxv1)T2 z@BSm!luLXzx*sFuA!#8hYw`S3H8r;_Wu5Ul1=4x0`+<7XTfhr3n_IYZW@wyrAls)$ zqJN@r`($NboXviGm+)ATkGJDHu9o8gMmeRfyI>ehlv39xkB1@UwU5miwF_(OgAniH zSdTevc}_fZ^DYy+kX`ZHUC)=h_BrB4W-TPQnf@_^ zIPC`@Dh~*Jsx;&cmn?kkP$?2pmh(EvwMU3?PD^XR#KbJ?SHh`AcvF&ID~_WY>t(I$ zQ|yJTUE`;d5tLq?<0aUD4wWpf;aRlGTb9SFD5QtIp&Bk1I-c}=kIvysVid=2hsi%4 z4t?Q#D?t-g>cv^zgw*Oia=XllwFo;r<3p$rA?l(2tXb}QdbeQRfkA}7v#~`@K&-Sf zBo5EiCTP3+rw;EER>|Fa3iNwi%?O|v&UaZj_-8OP*qAmoQ#C|Qqu%m<_3o9bIe>me ziM>plp4aSKGy+*nJ`pV@J>Mu3a1Pw0xTuiofez32!k=|2&l~zBSEn_SHxc1Us|~bw zuHkyhc=BPll-S>8H^ql|1RbFkkRlZ>=(#F!t^pqH9aqeZtQYVV-bQXox-}B;<$&pz zk#&pCUoD8ihc5qc^fgf5HF02mptDMQjU151A_|fgTUmc4o*(Imi4)%S}Z@$rxSl4J&g$}-EMv)&$O)j#5i~Y z%O+sdvHQ_PYU1RR=+9}1rCVMfMbbM*t<)`PC?h4T>cWsrsNf&O;#C zUn-HmGAKx+S_*tz-7Hf2-as0oMDJKF8KZhWxkY6zR|G9KHju*&g@m|Kc_BpfwNmqA zcMQnWz&KstXtq3T`4t6L)i+da#o_T)Y_tVopL3vJBNte8^ntjSfiRi}sJYlz)*%ea#ZNNg5S8I%G@#Q#|I#1=1 zff=UPGieEpD1?Sr65MMHg{=lvOeT}NBbzavGzJ_6{qbf|6!-GmC7&e*oircqg(|g| zT6;2aTYk>uV89sskloSvKvFksDBmVFgWFNfamn`kQ7hs7t!;bI=nNpvINF+#{^6E^FJRDo|$ zsZybhYQTBkynie9eoYd$#4Mr8Zm_Ap@>1KZT}HS;QpO} z?H;Hq_VwO>+2)J)-RlMKrLU?qwtHr~9P|{=wSRa2k+M={;^vY~!^%4&<6dMC%CSk( z#@=8pqi+>4&=-z;&Uf|@SdPF(JU!(}(fE*NGuO6YRH?P=XcUX_sPzdBIvNkJ8NG9? zNDK06TYnYW)rW_U-Wud(9^fyNVd7Fg9WaAfNdB0`~C>cbPZm0jJEQ30|IzntA+D^U==N$yI35F>D z`)jfFnwnR794SU9Y{bf`cd#iWUKp8s&yvn=AC?==iV@rBO&eHAm13g5WS;sY-obM= z?i@XkT;KP#Bu7r;pMmM^Z+X+pnB1cRBLBOTXj-E88#UCV8*N{L`X$+N9<%#Hs7Yml z1;^=o%SzsCEVzhnCYe|Ds*&>be!&aVT1%4G7NgWkj2YN`p}hGaR{rmLx@?n6Uscl^ z6_@XArEF*8hjA+&Us3bl$Jn!G2_>!Ts5{ygd!~-_(QG5EN9u&FTK_I)<=d99-Mw62!&Pu4P#UzDJ> z;oyh3DI9#q${#dv2&aocgYJ=j{6jo0P*oKUMmmILvDjjy(DTpW3E}S~fzp}Cn3mx% zdx%KJhf^IhO{4iIc{$5iMNgGmde8R5!eu>P`nN-&Cf!KOY*6p|XB{$OERQ|*m6Kve zL#2QPgw)HDSTg8TQ!=F-F_d<2lVUP#vkea;&7HL~{Vj*D^sY)|AB2To7Eo{#D##So zi|7Pq8eX3CFOKzjY*j4w;gHV~O@2yTztbm8f|K^ijZ_OVlG$NdaYM{)KAWP>4={M@ zl@Rx`7O(o^#4p$=)r<1c$7ao~ErggWUSE0vxny68kBe~Dc<5byjO z8ek?pRd#qow)Bv~+UFxnpT2OM4ir|d2GOFv&0*ZADSJ+OP9x+>wQAbG##>U^Lqce0S269}mK+C1l5IMDPwyl9dO?fdZA4SU3hi%Q}ED@yc)hDnGe9L#8aI;=n<)}BvJhj^0$#+vRqxz$pPU|rIcgmIMRiDZe`x5RKN zPT*jcVx$+5d1uV(lS=>cAxf!Z`5GUfi$ccAgOlAr%d(y2iruO8tX-X50dgAjfWK1f zXA)`T1N*g;Pyc!?tU=ZU)?f>uPuH4w6lT>;N9p)x`vo(%oO*s0n{nMYOY6zs0%reZ z2ZDhOB-JbNAD&>mb)I)RP_QT7!EzPICC zA@BW_$Di(tt(93NRLHQv9p~6ztGet8MS-V{`={)L7TjiDsWVm;XrgHx@bcmx%N50e zfQ>ee)v7K|whc!~g{J5OGpBCaWHd)WBF;cejOXdWJZT%Cj)kI{BnHi&&Rxj@Df)<4 z2Z$>TuTW9l8yKE=cgC>4p8pHnYv5lliWKwyZ5$%)Fp3J`$OnFlN1FK?2wUU?5xO{| zR0mk$VI=6a*F0Tt;~W71qN9@|VJrg>ym>kav*KipAH`3s05GLUGWU3@xrAUF+Nr zLV@i7Z=2#(UL1=@G~#a@)6P^>ZcUY5aIM3O2$SL+r7kEtd|@mkyY9U*ei%s=L_!}5 zKilg>?(|MDXntQEkCi06VkH4?9hOAc7OZ`zd3Dm-2alAmmCpa>x@HoWf0DF+zg9ISsy_xiR$e`NilM;l;0H$)ky@ji#Vk`1h|jhTrR(NYD6o z!d5(53Ov1yerGPyEJsVca|IBE%@@Nw>a(sz=h&qWXxx1&qtgir4(rv6j25yI|WDi ziKsFRHuqWyGOp8BncnqS$A|EvKhBF~cYhpo1`Qa$#ec8q#`D&gPu2DXVV7wn(#H7c z1V2R(Pxb8!JBA3Y_x>8vq4JdePRl24S0+r}LjKi%ysNm{mJrwMVswBdzGV|RN!XQ&)L1tMl;65T^)m6^Z0K1P~x(`|R< zORg9z4Of&vZ#4dXyPHi2;4H?x8l^DM8;oyaoi5p!RNL0y+$&=+IV-)T$ZYtk(J3Jx z0_Q^4wY~_BUvt18E1rBHTA3!(h5n0v>hl9jl*PR?{V7Nuhf}5k9YKeO5jtL*%PNOtFGz&*v90A|G!CF{Q%(y^}_f^MxS-XK(mM5 z1OG$Qdxo>Yzwg6FL_`of_Gl3lvA5c-z4xd+Yt*K8g4?D>?Y(LgHH#v4?OBQ{ReRK? zDF1w)=lH$O8_99FKIe6=Yw%U&M%sIt-@D$yrjPlBr3aE)i(g0Ao$+0!s%FC8wUTy$ z$GcySP0dKFAZbjW%OBK}Qji_~^5V|>Ys;a|u*h&EaV6V%#V}oM-yxJqnlV?tj`=SV z4!ygxLEOAhefE2Jejor_qHQcm#7)w6?3bDLKL_gdeh5zADb9o}X~Dw}X!F%m*8U7Y zrL@lY6#32RT-Wbe}PT6s)g?=K!Q+QIin8WUZ zH-DQmZcI6LtFV$V(3WBO*KSP7V`IW*M;Hf-kjIM#-`x|+MJ3^lCoSzgYm{V?d4!u`2Q|+$J zjL`iMsj~bwWkbsaga;(R`5vQP%PwE+0-{qJ5O#g)i{fFW#ak+p`BkC3yYO*up=nBd zYO}t(bTlYZGBK!-Dw;Xds-nu!&ksLan8N!;gdYitho&KN5g2|6f#H|n(bk#Pbkaa}2GXx~jb$=G=Fmde#En|IJ$}YG4?UfWiM- z*}5%TsP{Y^14!)_HG2~IdgSCzH5oI7-mS>0L1l-$CF-NOIcFyMmdr6iA}jNIJ<@4e zG_&fhjs0hTmrHx5yC4dv{Z!fTcugkt&$h^+79Wk=%iN~iD~9x|21=RG^QGs%+nVoR zn1*hgHx)d&dA7N$rnSTufeXZ#+kCw1_(Qk#2==z*6 z7%6YnKv0<^qSJ!<)~r*?NSiS&lpCu*{H6nrYn_f|jVeo3Rmk4mwOYo+>Up+|*joz_ zm~cpn9+|ozjiv#}1K$72*wFqYXtZEK3qk)I2C%iU*{?#0M#?rl-h~$hcIklrGK$&z zTZEeWuW8CJmM5`{it7wGh_ z5z=vI)-$Z$2hxDlA}h{-IBfs}G>_SmOkY)`t3ow%WyHq?VPwsFa>#yCu?<6`@%I0ef3RNAB)TfTc;Jh$Xs|xTgRD;kSG4)bS=%rbZxk{P2_heZw3pJYTQ_thp2A zX(+72HLwbsaHTlQ2tGc7Dia!2cYA*lP%Kh^P8A>F*f;y0C(`biL>I$Y5K~ha_FpyM za~9@c5+j*Fx>vzI1YwWs^fIA$fQO(xgRblC_<)@YrZ;;_Y3(=rd~c319T{ieamB7; z1nB=xuy@^$2?snBv)ycdX*!wj4!(C-6uNgAR=l^FgGsf!1CH6?QVq4wujUjze%=>c ztp3muXyR_2+C}k1F*I=YFnqIb%e;^+=<>!NwWo*|zx0fxJ|DKX+BRnLQl2Rb4ae8| zqr2}oq0=#}SDQ5*ki;=TtRnpOd@BFsfQaFA{oY5aeI%xH`xZbp3INh9gVw-OI4B$& zfFc_`KvmNB5K$cQ#x?2v`iMf&Z#E~^tdb>_vEbJ#AF+L_$3 z4dyyCKu}cM6a5$b(BPs%A6<)rm*}UxlFVVrwULdo z#1+NdfpMAjyEy|vlNNoVT)(SFZdQ z2ippsp;-LZ3P7vt;OFF%%Dn2CjhFpjB+bx|r#w~ncA)!0B3v1!q-uZ3jrtd_ZxSS< zEZ2KHFb|Jfp26br4wLNUG9|R2VJrl&W>r+~#)qJowY8irdW)KryVm>KO1E`%I$6AC zEK>Qrkwpkcgh^ zs2&#_Y-@h(4f?K|Lr}91TW@yef9ZCYOH_{}vfsn}jhoVIg+qt@B9S}Bkcj)zu59F~ zM1L{okBtyzw%?zZFDWd!!=r~2BT_!5QJUlQ%~R!x(ALn64M3qoPRy@0&p*Kov|idq zE-Az3{!+NfPl1c(DdLV4y>&49k=q*`T3{)Xv-E4@s1ZViZk`YtCqL4HN^PcR!L%Fw zW9EBNWgpr5l;M-K=>i^CE&&m$792*$)n`Yof>A2eZm(77+@7I1OIMwn zm70{RH=UZ4AN~Up%?vG+?N5_CQ=d8y={Vs1-`ZdeZY&TRsYQ<$FDWQ~po~-LI?vL{ z!q||qEV8Uo_FPX7-oONjo01$DkMsLN^dIX_60~AiA@IhE!YaPTH|XehGMFCg zb5Z?cP;tS+oK9TYtVz8$$B0^GH^8<2Jf*o}elf5%3g$2OP#CijmmBt}7m+pIIN*~t zK4#DyTSiU`rnYL7+ct3yAXB~(fI{M(1MvnWBr;cej?28KbDw6CE1oKzZ^_uIJ`V4< zh42OYEuYhNy98c*#n^zzBsFzOzri?pYS@q--w!9%ed5-7{NgOG6c>jbg3=k-kXoq>|Udi9PrniJn zFI&&w;$6GxO4qIQN1P}(_)D9`{h{5^aJwN)b>oO8Vd4!RmJRqqF>~Tx5**ylV8DR6^^*(W9POGYL&!{VEePLuRWU@s2 zGBSQguYv2OZ2L=nG|n>$=JEbuu;o;?1W;P??=*kE^2v^3+c&@1V~3~AhijSr#gSMI zozcCPI4Gg7cD@Z?EK2IJ`^?PWQAwnRd(O&6qU9Lvbkynk!mF+{VCzE+0MwlF(wpB# zfS?RpopWFI`#-IfUyC)$b-ESF`*s*y1mJ1r_|?R7jgEO@mxR<{_iNT%&YH?if52V0Ch<(NY&rSWNz#AGVjdogH)_? zecAc5)slxm-v9u!Kb6z^*!6;Uf+*<2S@3qCF9;&QjHgf&D%DDOG*s2_F2ES1%{7q{%ftv-bx929?hufsIJz@ z5Aw)qTSkH&t{PZfW$de}fZqoOpaW-l|K?qT$gt-=u#z0FdB0yqy&F-BOAV>VVCf6 ziZQ!O?ww0cc(Gm&7&dZOC}Jmk=*7(JD6xxQ3@`oJS%ginV}pX@8_pkHV+<&T&WXtl zFDJv9d!C!W>sMudL`-=jEJd`Plpo#{ybtUau^WM&CW|OvZcMmBE=)4eC+Ru|mst+a zPcyG&OmfEHQ3$2*6uPeim=aS%EA1`iPi@sNRI&F*4k1NKOuY-UolwFu#R}>@k6-H#UD9T^6L!iLi5d_5e?5uoD zJDwVwOV~AR&=d!iClVysWSpT%Q#ZSPu|VY=G~rcC_8==*;Fob?`kG_3Zs?+W8hh)P z!D)}YANiVu>`Q8Ot$o+3<$N-z;fRuw{)hOdL6^>YL5+D0Gn@223AygNflxzuRKwY) zHt!6d@1%OSp$qa8zvlQOGhfWfi1^qsC97Zl!Yl=b4L|YULT?Rq8}K(AmNjKZ9+~e^b?h2=1{H_EKIb2cyqyE9g z3t10AVC#nds=;K$vW@r~w>F&&8Piw8IzV~XG@1+n+K87T)yW9iDk%^RXr`3%KeEn*;XbNV+f8n0j5lUz8 z_+cZ}qY>^|Bb4&JXnaewCI_7&P<0Q`5S{UL&77;6Ra~q!<{B-EKyT%NM=dcEzD8gB zn4-gqIFm1j4kfoB=Fr-j4$q9{kKdU{amSEO-h_%o<_JkGn}=HSaqdY{#IwY{&BHaHj_phiJCmVm?r!HJg(13b!4Vd0WC4ntZ4L#opDuq3g zuSQ60&2aD%RY@NZ+^MJE_ZeWk62H9Bi-G?hauSnY?wPAyyV>FQbTW^>8G=vSz`?g0 zO2P8lH;ZxPH|xJhyZj$8*Qc+<%_UBSc)PCvlZ>Gh9ECk39`|paC*8MF@ICLQoRa=T z8`c#@8v53gnDM8@f3FV5`xMOB*SmdfJs0Chm)d*~SI>5n-vzc=9n=;q36x5TQ27kr zcJUg&pCjNFSW*4KT-nMC+hK!^7r9>AY{RG>pwR8)6YIk|$RIC$_f+h@(VTWa`QJ2E z=?!JN2tns}WX2D{uJ;aVl81%g$vTZc2##7s;Cv(_vdufj)EiD1<9D4=__$$?UhD7E z)Hp#*AaTKrfzQzS;mk@V*xb>Uv^?QXu|*QbRytt9eff1_+<3IFhxX@H8phAosni{z zh7`!_cct&W`!a=%-RDLt;ZfqMlv}A0p5)lY5q(4^j1ltXWF1KDc2!Klv~0VRR1MO- z?#jfV7rI;b^Fqu8D3Q=d7uHok_(B)kkC%r_05CfuH~(cMjFG zswzqu6(W`tKaU5^Be%7Zm)Qn$DAB##^v-~2Q-{S)7=9;2=5SJ@hwB!f6Es|J{0gl+dth-J@?5YQVK_> zY*O$PzEn7JmUP+sQ&61RgMa^GubrCH@@3O1liV-<&fD=kSCTGoZq3KQry)Cu1HE$n z({*Ogn>~JF@9oi?J^$`rzteFkqN&uJ8Ibk({U_(eqXrOY`1Fn(rJgOt;K4M3C&L)I z%oh{4Sp9SAGDGe3UeI=fjahwm+Qf+M?vK&_gJh}9RuW61-t)j?`)#WY4F7`wosnF; zR-ZZ-jz(MeM}HOZKEB^C#*Ce$+vCT*s1~6cZ$TAT!5sHLRWtwvB z@;ENRTZ|M*Y@+dUUI*eqT#>5!pXySUthR7w>>@M#Ln$DdV1o9p)afJBT)XvAh-BK& zp+yMlcrlBHLb8FHr4iE^F)GugW?X7Mz9%Y(=`3|(&#n*GHfA$hih@O(C}%}~uZRr! zro?hMeAtgEqkalzX-qw1eQHSNa3+B&E^AES(`lsSr)tbZ7~#dgk+GMSQ?FPW2czUd z(=bWmqi5h^hu*V}p^HaGDOpPT{dAp=OptF-uYc=W)#b><8w;WNI?Y^tjIxS3wvMJA z`@~Mi$)$G-=DTxlcm8fvCk?7u^56VaDadnOWN$C7b4;gQZdpruk+tI7rKi3(Ht5Cr zp3%&>E?8z;?^*e9ZS^;>b;}vvhUlIWiU#qY z|C`Zx7<&B94E=5_kpOfBJ*nMij&f!v9~}EOlf$bzEY!mY75P8{ItU`mSw_Q3p(1*+ z@X;bRdwq(&ml?dHdu0Ut{1{+ZXeO1Vc>;y{C=gq?_E=g(%J~V+uXexbve>f`D2A?~T@xDuqcECpOEnUM;Ol-UKJvq) zoUr@;EqTz6Kq1H0uxH$aed`}xXB87A+G$o=-{kB9Rmg=ul+ZOd-b>8s%p1RSf|+C3 z&@(m`X7i4eqN#b{(mE= zx<~sQxQx~*s|HzMpBnkkoF~oy5`}^_()y0hr2yHM&vNI<*aRi49uIw_nwzD083O?e z2Cp{vjS7G5XC%M5JWoEM6wUj4cXxBa_x|L4+-AUIAB(xnU&xvrv(yD#Q~D7@{fA)j zJqB?XJZ?!you8=Q??sf~{E#L*8Ho5E5IhBul6SXl_`hC&4#C_aPp;#iVx<1{pK?@MPzx9ddh^%t~T_*@M zmLQ*1+3V(5@FGU%x70i0jwc{BMjZJzT@V4d4WCj}CWfPGH)D2l3_kB2&=Aj(T98)y z>{W8tWG}pEcV=U5aZ|?@5$u)7_Lnhs+PB)uX%(G3(90Ov(LTi-Wt zq2II8$J5uJh0P)wu!_qPgBsrC#9hv<;=Dc(bJIsM)I^MNcvV-?sSV}&Xc^$bN%e95 z2DHUJ!%YZg#7%J*-!TnYbzyMb3lz2I7H&zv3NvDPA7qY!TtOTAQKUB$A)EZA zp3i_pG_l9hw*+uIyPL9Bgwv~{`jyO_YAXZ_1ZbA^n6@3Zd&%60m!LbMp{%Q`J5y># zosgRn_4b+%z4(U;x9~!t$c6Pjf)%IlF9<;OE8;G?Kb5LpG95FqDIwAG!(lBq?CT=K zQKH!!Ui8t=1s?@U_cnV+i?HSO`ugwMY1T(lpCBjf$;ik)eqgy5;Vk`>mj!)&QM$$y z`jc$y-{!V}^Qo_aydiMYiLr84IX7ND3)3^??Pgd{v}TxsLRg`^CiNY}l$@-X~%EE+!B+9}BB6%uth6k}T zqGm3HJo`nck1Xj!0*TPYvNz#w@ElQh3a4*H#bF1(P$XHT-OPqo4%3Gxk`rXfPM8L{ zr6=R)!(s~gD^_#Ux`FEN<6Ps<#(DpT`Af4M6f^#_9FQ1wsBc3+n^LY==M#RDJG^tq zv&?NsKVyB(k}z1ywtazv(x@IJx6C?Zw-&Myo_PJ5`lcspOP^q!B)!h+zrT^-VrS9n z`~xC!0UjWwJP}eo%e)K@wiec_;xDg15iaI%Qnt0r!nc-(g2sfQmRFbuAufee`iCru zsl)el=WNTTL5*BpPn`b}OH^JlUpN?y#UEgZAj-8U3bj4{(e!Tl<(^M`BQmVsR|J9K zzo-|s&e$Ich8(-Qe~0|tH(M*cLHxVv%3Dfyzn#&D$n{{w`u!Xgo!B0#9j+}A@4_Ts zN^B~bXjvcK@b@z3t5CVUAt0B_UOW4nXbo-*5Lh0aVjx!s^NN`n0p$yD9k4{D91xQe z^e%hf+5C`-mcuBxhQ29bfi}#)`JQ2jo=3ZJ>Z!!;n{EP7Kg)^o=z3!KNvBXMftJ}8 zpAtqR&Pc>gqLc^rdcvA>Cc~&<_v~|jJtEP6W)-({=M+hd!#(-X>x}k1jh*V8NOQsV znzAGbm@eLTS8ac?A00Y1NNZuF+}qd;IfE1h7ocy>F4qrXpYjMfLwuTB7+{B6FEAP% zb?y_geoym`wId=^r&Kv4$F4e+2Z( z-})DpWCg^B#g!Sim|R>T?~_z_Pvqd6HVIFTLF9@XC^(q#-at?1E>v{BKm%tfI>LI_ zVEMXB7ymxSi7dcaBfN$HEJyy;|G{Z^HP*Z^D`{blAU$ryCajT~qm0-A}B?=FW$NT%WRadl@Uor zvfr4YGOmLT6{1qXn7cEK}k^oVpJ-`MM+POGUbgqv8g$)RX`)I${+D z?nf{WN2^mF(9DC@F@6gCG4}Qbr#wQn;ZC0)MbW*Skhi>baF_M8nK~CzL2;smj)}V7 zlwtK~m1KC@idXulG1-w8WGBJx6(*|e3eQW8z#WvK&)Os3N|DTn`}J}Po#@^=;lF-h zwBXnmmLx`Pyd-k+S8(#pcsT%VNqtA?z18nvox~ z#OSEhwfcu4QNs*XHocv)ivg)aZMzTP>_$hU-_Lh4;wx zhzTxVrHX|3ZUJsR7vlGy*qlWgnHB6mBz>LJ5M+zxfyZC4+xDMU6|U1M+P5aM%nkHT&&hHco18-fy>C#X^Tvk! z#DwwQ2>4`uiXE26y>Df(^_pVKkGML*hKKZVqT!;Rg239j#1JO*Tsb$jsXk!RURN>j zcVJd_Jk0?gP@XXn4{vJf=0%7*Z@-CVEg~mSBVgI7-8m#c)w!gVe4{5;F}imkppLBi zKs{BnRFy?Nbx1&!%?_^bE&jt?d6A5Z5S+m^%2|?hv(1tg1ndjIi{bpm4XgVHDlIoe zsEDS=Qs3xtSqC>85|p;6!ey79l|e;}WV2v{2pEfOl?(op$ZBTMbQR)nR9-?lm(ep7 zGvgEJ`34x?6U9A`vH*h!&VhF%W_x2_DX-%%aI+5K=&>-OD#d zA%Q_A-7op+%22MQSXb zfvuk}i)hcCzm(V}rX8Ny%)qx6e+xAY*M19~J+)EQ8cv^;=ux@WkH;_mqqBTXCo%lT zc}39Z=NWx<=*r#lf?5Ij+^}Mp*Icp(_&?5&P32IWJ_&H~M-Iq0BIR$T#LA}gXgW+w z2bOhJzmp;eREKE?QKe24$s{j<i11WR001UU9pL zvx@ykY~5cSr+ckJ_SdgJ&@@-Xs^Vt<0|E_lc8>+}*-cyZSOG}07717+S{pZ8I|oiT zhMzlv(MEc$0w&hIR4DW74{&x=tKt3YzXAmfB;apBWKiC$%A7$@(_P(2ba@`D#H$4e z@3%{gC5S=}mdDTF9amxPXU!hLl8BcL`_{uP(V|Wz+)&fYyhyH#pxED)TL~Je%A^6l zH7n7Q%*E+T@`LQ#3^RmK9P&do*|EkkZKJ;xMX)!TG38CfDl`mQ!wD6({=6-lV{v{b zMp|-5F<+bovZ`F-j8()mWpBtddVk{FYD*-J<=-mlkLvEG=7^n85ByJYlR(ODBmNdVgbtm^d|@YF97B$~IQX zMSdq}DEPdl?Q)N7(~oX%4&#NYE-CTY!JA!`_*<1|Gq);!l{&grNo7W>Mt6zs-GYGs z{#5jbaca1L|2ggkX=!(%!7O!!pE#pVo+XRmp=zIc<+IczK;G4_VBKnhx?Zl3?A=vP z#XVjM&C_d?O(o#B&lB7n!1cRiD3e$7)qWPvc@8g~wjZ^!Ts-fhUT${Q2+xbAaJx?F zeY{KHf+GSpiPM1Vzs#P##E4*)opbkAv-2N}d#s-%^>mR$^zdQyVw|vrd=S8)gvE0Uby0rU+dn%nMipOiS}vW^ZWM078PL2)!Vf$l?`rI0A8n1jW7Cgnt0 zwqz}k9#g%eKj}v@pq@H;-8CsrpCWc26)ni%#Y_MZ>f5}I4gmpi8qL+O47o2@*6~ni z+&@4KvaxyvZl+N-@(dZL7{L0A_Oo1IL0Yi;y#B@?E$@X``N( zLo>}HrgH?UtufSikT?KkP~E?)RXvctMh8T#IrzLTn{=a$O1Wz4`Wjf@>XISAg>m#B zHoeIvf`#M@K|kSJGi7S+iDz(zMEO%N)NAYwddY`t-%E3Kc{}}-kF#%fBf{&UImFjh z9zLoOU_?>=qB{c&&Nbh!8c|EdU>vPqu1=k=_h#CZLj2~E-R0+iv+By2r^YK%5>pY1 z=$o~k-&YDql)vE#N0?$fI)(&DPuL-1R2xQ9%aO3bEmmwm)!^Vsn#pH?IWyVrqzMHQL3vqs%|@um0HK82ls4V-K(3q3A^!OG zw5ndK0vtIaq_?A;+Bj!U(sw{)69}*~UexHxrA)LRJ6WeYol*4BOtOyHt9f$Zq&irnbGVB`orp9WHB#m1Ekal{uDTzY^cu^o{v7(?pd^r1B~1cK<~Hr)ImfA)sx zbA-YI(%Ih#Z)*Q*>lUJUU0g>!{~KBxBvl`|5Mlc9iOtptoZGp%kUb&UqkM;UedzuT zPa{jEuxi|jm4D-lbq{|z+AFHh4IULFcRS5P5ucA5JpAYmvlnPP9a`o0AW7fgJT8e0 zQKQ_+A%`M6c2?fJ8Ux;fyLmi=g6>B?N37YhjF7i;p5V zvzaLqF_tRF&9w7Hli~C!Wm_~@sXC4`{!Fr(=0Ic#jz{e&=;Iq6cSy7rl7Ct0M7S3* zX#Hv2bnTc@%{f^-kuGRfv7oH{w&4T*SkSOJPrlb4hW8dsrcF9>%w@-HbK?yTH_;PP z1HDu9eImPz@x44*;Te-eGVdDdtP{&IAmhpeJ2<7t?3>4Rs*%a55(?Z9svP?^;&Kr% z1r=QE8UNJqqQQD*(91pZ91jgjB3wB&Rp$^=iAmXF6()P($+Dy%MTQ^aR$_@ouV$4g zDcnbd*0p5CzAF8xBUghPYKXWn9~HV_%a8|!NUs<{jlID8x6ZsKh8x5wV}H|X zMz4Kht?wH0m2Ft!XiT=@dz_dY?|rZ_ApE)(n-|v+5q{nG1fUY5M-T^3D&zD$$M->0b?PhFFM4z9cpknF}FK&!@KGWNc z1y5l^1rN1~H9R$(HzymQ8PfVUYgtrJ=iHFXg|ECXEcN(3Q$OM+@&WxajKkBd`0JV2H45k>=)xxXb$)`IMC9fBCs_{5;%*{n3f?Qw9H~KPosjW}USgZ#{**R3(+w zegI#NuAKWXEuK;2>LOfc|e*H z5lJ@rX2N$D^Ri1S|0C<|9I6c;j`HlYOR}q@9BN?>yw-f&P(x2Wn!DT9J_@IfCjyt{d_k)QgMOnOs_iJxHSNiaPK-hwbBc^x;&vWdjEEN zdW538%algmy~OrL$@yaU`v`6N(bhhXydzPp*t&c7Zp&H6yk0^tYK$pgIrQW(T>1i=5=*!6i_bL*ex~r zQ7Z;!JA2P=UCc=rDllZ5{A9~I^i9$L&N1WYio;e-(Enz-gZl7l-(CrLl5>=mIge}e zHSI9uDDk5k2q-SyoR5tuAfkmfS4V=e?u;X?8$9qSkrIN?W&Z9ShBVM?0elHWVo{1U z!m(YKfWvbXK4`ZrTJoOG_EysKL5mlsZ$;<)t1MuW15a<%?srGYdnd1(XQJ;LRD$wy zu;u`%?C6J0V*Ob=uPIiE9V|X74fm)-fF~Ou05iTzofKxM-V$J4kB_D-X)w3vMx^vM z)>aYu&9-|ho5g(tpz0cgdoql1UXM=p-tNiNPU?OLHCJnml*M%VkmY7Hl`Be6&5TUg zwmXj>@>`D69}SJKe901KXJ{I7u)1m&$&&o=WLx7n(qvPT*~16;DLN=cd;s|sDV>Fw zM)J2wym|2|vagjGvUfC4YBqZ!u5s8?aaR{)AjeWUzu@KiKrX~DlO5?__-1o)rJWnT zIQALTZO#=X^xk?*X=7##qQQ&9_MU!tFJ01$LaedRSb2qJ8RLU9Q(#s~#qT8KIiSb; zc2dRvxQv0hx4{+1DfJ)5$;xm48f3Y4i@*ZZ#!o-*7u2G!jjGX}F`5iNQV*zLb~jsZ z*OZyNl!mwWR2fzWn5!1#k}mb~-w{`bPe<5O)R-{XDFswVe!k3}3_?yd6-=d-8*EvL z5diaz)y7=yd(5yhHUipui;`%-;Oof~8>Sch{Y51Bj)9(5t@~vi1(+mZ;e&My!z;Bk z%3M`SX&ds4XD30l51NG;j>oD>e|SGQrCL34vVIhaY}PL&e(**k7J@YSiFbmO%3(t- zFZ&N;Ma=Jgx#U7Q>DgWm5%>t!p`Rw4~+U6ToBSYeksTUpjPT3o5SkB2Z zA-6V5|ILhWXUYBimwWQNJ~Z0@XK;$FCoYcBQ0ex8uma)w?fZTDI8N(jhdLwDP!7 z&O9ZNiS{s%o_d>(+e^L)TM#kZGhY-0by^WUjT2tnJo8@>1D*mC-2!(HMnI3A?{i== zKy)})#j2O>A*$2+6iZ?I+X4{en^E^jx#@XwFy;aWW8hZ)qJ`uC&#nA#u2bj*Fgaj= zxz+y%%&n=c*{wxp5_HGM`wmN#>Q3XFjStDZgB0X}@}sC=euKqlP0EE9)FPI(0Svk?HOFKK zjF`T*_4Tq<<;x^bRAi|=5y5z6yzEu$BM@@0f~#F}xj0MLT&W09Yv|{X~gK*sxuABpfFgTW_DOfkt?b}LDHwODw5q`eqY*YR_Oq@FYGsU z(+O|sV}`@Uq8{k)syX#nPv3|8z=$5Y>`5~{MIwmhlw}_nIpp(Dh=)8BcCwldUndFy zUUS>0XzUCI$W%cx;XQJ0JUSSVKC!-yVN)h(fuePe%uk`_ZLCXD(RFMC0ij#EN5U@= zBb+5RJp5W#+QO;XrJZpCkjeQ88~q=cG)yg+H_P4%VPxgG2FV~B{ZM@FJF$NM%UKST zr#F(S!jIQ<#$oHQW;Z@r7&xh~!^gWvkR z#CQz`!!2lJgOHEX0v=op6+%)7=q3Mj@zd{e+Jo zfGehW`+P>|yZ4+T!l3Ibj$@!YBG+B@9t>q`ygEM{#?%yU)bi z>zUemTS}%=l0zpC!jXiMo5zDc-uyXRyZK)I(C#q-U2XFdJ2sP!w0T;WJS1JCyit(x zuUh^Es@kHe}^4CB4w%t6uzvtE%tjhf?dpC_Yop9*0 z?;MOou86Mb_{54`X#-AuMu0k3Zcmk5jlb97(GhBu1`oCNH7ET#vRy1t2LYJ9hL$ocpkY++^MgQ^qiQZXUDoH2TuY z=_Ki1sGjFZfXciK4o7@#-XMTql(jGYWT=IBm7E}rB_Xfr!u-gHA83ys|IzSO${$| z^QhpmPtA~vkgp>XfLZDn;&+EV#tW%}KZHtyl0MTlK0@SJ(AEp5b|3l&J41B5|N7k@ ztqSD@xHB?-@gVhkZIWQG=1?4s+7;g4H=-wZH#ecIgz~^~cn%}$dx9W=ku;o=U8|+z8R#bQxql*g_u5rZk z`%wDj);H6S3jvV?=RKLlzaF2%nkNPOFlopr`#PfEzU1t_^EoZ{y2|3NV+r?2>8T&> zBsi6cpDLTP3!_BS`4KmD5z}X-&qV?6nrHmy!Jq%n3veU0CswV#PXkhLE^X}isvZwp zFlQInERU!d;)Fv!pt$UXgbn@agujswC2QB92+-Ql03N6^@Blvz`9HNcUSI@)A>s+1 z9JJ*lSn`#hh||X0gX(~n8V0u6OYDiHYPRteiT4ws%g`UDqF-*e$0ohU!A6s@;{UwI zp>b?Wc?C<6Foi}SKYnA(m7FNXUo9AyH7D4Kz!dl+Fa`dIO~e7>9C3%h<)k|MPh47% ztVuURq>{u`3tpjGC9r+5HJVpIqfQ}@L3lxZSjC?Ts`O=V`l}JlwH+VjVdHFD(E{B} zUhqHQa_Fb~mt&7An2b^twtQ=z69$^X)3vASVtzTt^h0rav3JUlT*Dx)>cbOAHImdi6s6PQ zFuiOX{l4ysTxYSj7-s-Z_*B`s1yPYb7{t1(;^fTL&sj>biimRKXy2?V%hJXCu_2vS zlO5P{=k|90er>$U6SJ82fo+AwZG0&CDN@T>^7t~CI{aS5%K13LKt8&HkeU~C@$U)3 zNjSeJwM8)mfmtDF00)8vqRg<581rNb%QR}iQCkYwveBgj^#Aj%+R7QO)ND8GcbL-9 zx2|k2(c_Gal*L9110r1k0C6S#bTlFvy}PN7iH4&~0iGJk~#LTy%VXI9JuD4O*3T^2WU7H1rD|9Wj#EPOKiKaoSo6-wwyjF?H1463w#DM}aWpTh3(ib!!{f#9U) z2Qb1rwp#jMHbrAGD6fQosd7lVv{yTmq_Qe@ea23olwuPrM!B_6R-pL<_o08oJ2r2j;TyP)m&szd+ z(ZT`yj$@~}xN4_0{|HYELqi<u9j--iJIc$PY)ljA*M07UZs*0m$2(4;HTb@+U+KhMHwN2EnWd0UP1 z_(2YAho=jObzCIdRQltj=q9CdBI}b86ct5RmlQd>vjI81DeV1u@}^2@hiY1HPnLjf zy=zH(v?Ypx-cAVpyH-cZhO`n?rkdA$_a_`j(CSl)`=gSh&OLe{79N&@UYu5&$f!i^rI1+_Uy z5`Znpa`%Ln^U8};hKTeSXh96dGUz1xO$K95gcCTeKxMY5YZw0tL@h(3H2Up&@w>ep53c<}cYBO5c7~U-v5ryH}~0 z3jUOUy%tuG$%#Yl{5v2%Q=GQ~MDa~P|LiswGSHkj$q*oJ()Y*}CR+C2?e25sm87AP z?UwDTP@aNy!Gdrh+<>=G7jEVCu`%(0yBjk45I>@VKo`P-pkRE)5GOjuc1OYEBG z>(_l#$ID4EfB5?A!veAR?oTcA#Dka~{PuYD!1Yr|)c*q9~X7Jvq zw~!sP%pgq;W3ZN_pvhS??(0uTx5lKLW{_B$K*M})dFLn zr@=|o9XS`2$?Qz@vZc{vus5R&l}Y<*-#dLP>K29ez-u*EQ@!pZvY&0PQ+y|s>8uG| zqHoN!Vos<$QlUN3Z6+I8A7+L%7ceiWEu_{eNF)v^M<2462!n<^ZL>kKD66`nGrDy5 z(g|Ntohz1vMn7sd2W(ke`Jaj_nnDDAlmDNVysK)Gelblf}s9h()fAULZq&7K1 zHfcd&bA=+ZW6ilWn$RZ*Zp`p+RA@P44c6ty!!5qaV}fooUtt=0sC3j>w=d!hg8$}N zEWHT95hQBTC=VbF!WTSuy4ou@d8w-$m6{%~ZSQ9jU0sWd8aM7U1%kxw|JMsKzgVQ2 z6MEY${zV5=F1Jf!@N#sw#~D`pie+BB{IP=IEXH8gUf;K>*zI{{v;d~1D2KDTZ&+)R zx>yRtyVc<^%ZmLs$#4GG7gN*VC*m_+ zW?%8T#OA+$k1(P%Fy@Gksstk1UU<}@0<7E>jATR&)vgJ>|BQ_>KUrTkIAdrPSs__W zbppSQlC_mK&9@h`L3WB|Rj6MIa3V)m3h2;KaY$$Dty-lm158NPDKta?W5LfFeI;~> zy^+{E4YoF{ijR%`%ZJ-{`2?svvY?M_>XaaPgz5X=Mb28~K_Ct$aSDhcWkJHVbx`ojn48B;2m1 z(9tB^vhtl4iX)|LU{=c+7#}a>@*`^^tQ@`ioJXrVh6!m^9MwVuAXJW81LLbISw44e zyE8-4AM4%$9y$aex)-n2u;AKRtm}(vFFd|{v_hDKr!1h&01&)?jcYu{wE%rvUb5d$$PWC{uYo6Yv<5uWhE3_TgF*%hARF6LsD&$(cX> zox=Vlg4)UE`gNQt`CCi{^E2&{7C&kRvGW7NrFJXGF{fD~b-`*3`P9!u(d5A=6 zlqyEB**&))&)145(L=u~=r&w7diQ5K{2(R7p@)V>Xbb@PE0eE^QB%hanY;3b+;E}* z$T|8Y`9|j)YjG|qjh!A5*44+OCPCEj4`$hC#nh+C(CL!SZD>w9XflqG;Iiob| zn5&z0WJ2F!egV7%E;fI@FPXYK68&u84Q$i3SBGeHHXvH5R+Wr?(zodTy+}mCvVuxg z2%AYb6d;}PLhp3On{%m6ipEcJ@j2VvV+ph&_ExSa^I|Gmu0V>=iCs;@!prL&upj#W zX!`1~rv5ioqvad(f2kBe-?=&9_B53GJ2l^$D`%p@F$X zul|q~m=dT^5rA6pKe6QXOjAuyA9j(YaKG@OmcyvZ~JzPJ;uu;B;9%cH4@>-Qoi(h z3DX2?0~GL_9>*dVIkYrcHJ?R@D0X_B&8wQ7VDjiI76LgGj6Dz}!dBgSa`p)kC_iir z@XDH?f($f+1mD@idrjSM8kL)s?FgeRA zBs(!$0i|lq0O(5HRGu1nmUsG~4FU^JgRYXIV_u4toxPl19uc)>rd=-|HOCHeba5{9 z4#KJK}#sAC&SaOUwl|xAe>ngkQ%1ft{ttIYP689c&n!5(6z_@&RpM zHez7bEP8q5W7YM&ozf&_yb`gwT!|eVS>Vl*0Q)(CfL4qv2Ru~|N60h&z;AuhXXQUg z86bZ)x;lGX6090TX-oTpL)HG9psGTCt4Qm^jG8bxkjn2gUg{}PKtq{2zEVL#X9Vnz zN|-})!B~pTRHA7J#hw@*?YXO>w~$G3X1{qGvxg{ z0f>)BuN7q)_rSoCo-RN^6z}QA3r+14B#9v3*)BdvTzThTUyfSD$s*kzHfqL zy|ltW;Ome5V}~S~48m_ZMxy_b;PZ4`-#QwMnX1$@0!UJJl!F?o?k+|} zU*WoY>vEVdKA|vwO)W2rQ{9#7(ZiAPOE21yiAMSq-5_H^ba>%<28KH(cmEW}3xC$k znxB?lxQ!7aS+F2%ks|dElF+&a5U&wO{1CZ#RQCDz{m(sP>F;<4+;IhUk*9{>0^7v@ z;g&K?hUxE?eu$?puL!?C=sY;_-`NjjzUr2|-byy~w^uhFkaLph*xI&l=FX_VENgHfNvM%a!_P{Os#D4tfbiC zDMPO*l45@F8ne*Caw;PYdlI<8*S3{wS~-+_JKCff;6(4=(G`qf$ISfKHA<~^%3R(c z@V_$8usVf;eS%hZzad`@&{kmJ;5_+X5=;dFp=G#XXEzB}n9SE%t>;)-{I#vO4J3)1*h`Dljd=XORiG;q2fe}m$K&?79_IU z2_1{gop)-_&!2rIZLpwFa>X0Hy)WZH{pdR)C5cc1hFd~}9drBF&R4so1YNB_g@vXt zUUs#+umpNTHQuO7%H4K+%w0aqO!nPxAfOuJux`p-<%GM4SRg>3C!LfQzZw~GEGnII zSZoVf+nX44@7e)sLDLY@4WgaKNj*HOmF0gYkl#cxjh~Gx?ypLA78{?k;b+!|NN8Ea zo2ExFmk--y)@g*T-cZ-hielYD>X!-(xXr*=$)gQHT7j6R@h7!CcDZ!TH!9#C2 zIjAv9HD0K);6FENk>dNljG`2_Jq5RRj<9YY3>Z@d>{D^L>$DpPlxO@7jY8qw=13^B zMW~A|?ZidFJ->g~p4Q!br#pXqyDUV{5;L7+oUl4qpCErA%dX z@Bs1EAv&{1v)iRRzUaRVv0m96E?yAYen{C>aFsfXM>!Fca;qo`4)-xWt1)mw$nD*4k>$Ntw8*hix^iwvtE zab{cSD8%d}Wc&*d*!tZkytWH37v?ct-jz?!N zV2{)3|0Bk^+olO&ZS(^}^-od1l{T8&w?FPtNuI6LU(@EMFAmbznC-VjCrvC$eC9ov z&t?)ScRf$Z2L59t$pQhVwHO-su*vTN@!-uv{F2_Wf?Z@s7eJ)M?m|t{QC`X}5#PoN z0q83|toIDT7RU3=k=g2vAb(2hi599A3h=sV3?YBwWaKPW=+=LHBfwR#)dxbNv&X~e zqY%u;ZmF_P^Y)WH?uWeB+|Rl%KP0t7vPXAb7#MI4*>q+1Po{G-nhQ8Y$vuLE>SsAf z;FlKGqaCpK_;0w3^cR1R0RR&kdfHk+0E{`NWTqS=g(nnw)6PFee5;F^>V$zmbSs}S zts3aMN(gKhd|(p6UwmqK zEPcll$CLe9O^kp1i$Fc$!e8V@>CtnrLV@&si`;xnlJ=9Hxtb^av1QNy_}%}|@nUY> z@~V=#D#wS%&X!Vn`7`S`ruhf@uL1?%q2IvvPfekK2}E;xuH|Snx^=e@Lb>gxaK|rp zylazkR$d}S$EqR(>MQ-zi}`+jb@ZJiS|n3eenl_~m|rjx$vqPa%2DfjUQ@Dkyh176 zxWJEW@REFlbtF*}BP@L@{dMwicO3OOyJ!?w@Fv`rO>U`8z6?b4u2tmaUtUE2B->YS zvrjdnInOk?>U;iOHg53xi-N5FL;YGE<3H>AVXOR)r66}xux!RZVjMHSJj!GznCGJpgZ=WVzwvfV(Pk~3Ja5=oP_O;M= z$J!v^?di9jtv++2j#lB{5~y$6u!K)$pMxk_6n3(=n#0;8DfVRK_Rl~!A^Nr3YcmM{ zw1umrEwBCaL>up&H`t8NoVu&jG>$^q2JOqIVQR*C`T8ncZ}k-$G*wlVKYgS1cFB!o zAx}A&-b?W~Nw6`c7A0`mikz-T=Lqr1C|WU!SGC%E{rNfw z`k!k<9DA@1nLYyV>wL}jZ&*q@PH65bNc^`ShJ=ONmr}TRiyLHxRMLH^{dNV>G5Cfg zxfq^7NUToX-K^%fx9;s{Xn=%3P;#Vc41QCh)gQ<*^R{I7E^?2gr$k*x3jQtZwC%BN z92pos_j~?aXGVJQGWSTTi*Y=M^>5vS$5t6OQRvjD=>O~(qB9@kyN5N@z7}y`Pq`C0 zC~sMaJ%0~{RedMvGKRXWO+r9kY3m>iLlnftPDmno=pq+u=XYx_>1yzEm=s%AFK_%F z-#P_bGX^-Fa#F|K9eeJC=P{_in$_}ft*xmw^P?{0*yws`mhM*EByalhuRmXh^a6&SKpMYM zVgVqp1j&p&Mi!;f;`sHi`pUv|T}Ds0%(3>LBOs7XbtWG|90k(SJhV-XX(-+9L`BaCo^x(sSf=5l9|VYEc^nh+U7$WmVDU@4^uB=rG}gKRrp zHCH1PW&_1@*}DzKq~;O+@9W>yB4Y3pz5AEg=|vaI(JANszMTm~#xHvm*v9Bdnc?$C zVDqnCm64@(5VyiYFu#WrApJ?+`)W@98cV3=8LehnETfOdKX92WgtzDcfPOGf@rdLa zN`U8{2a`@V50zCPY2Y z17F&>Cqla03s+IREG$Xv>O@uVj;-8Jip3?gxYsexO0$Xf6Rt(@#J`e}_FVOUw|oHU z|0L1o3yu+t?xh45g+Lv6CSC~)7B*2nDea!C!99CcANOz3xITv+!r<{!GM0g%P=x1T0JV2+$t#`88I%D>M%GP)uRdWD3CQ-U4 zW$OhP@HIfFl^z9zfpzEQWS<3_sXh!zA`Bcko13`*VY>eNoE^eAEgfN*1}9NZuymds z9Bs@*QxuVQR)alao)}g$fS&sQid?q)RhAH5^n!l>eJ$jtq_a(wk~nHut?bQ$t=uR< z!6z5G;a||mqe7N^MV3jW2&HHOSM_Qtf)%R{lZVqd?PN18%`qFSjVqBV=c?WzB4VZXoS zulU|FhZ#TD+`HqgM8vco$T-^W_v9g3kNh)2LxM5_b7>wx<8Amb%Oj;-H#OL+*0IGW zHYSo8=I-IsksQV8(GGv!AY}YCG8Td#ceUeyTs^9Qb{)1UwxjpBLET%H!{(^YVne_a z$gC?t*9Jxr>|0?kK@f0{f#{47{M1(%{10og`FzUbReI-WSw#Q+b6SuEsut_0Rau&< z2gX+T1?sAYdqAgn`ZTI7D}6b}zSpJ7H*fM3RooIsceLmB&eXuC+Giuq+Og(~EI3b$ zv;m$zvf+34j8Y^VNgi`oQxTQ@sxl*OFhzIPHzdOtae04< zHGw@oST9>1C5B<0GI-+HC*{hqa_O=0^#ztck1|c=iUL2o${Eoq?#WfK)52Ub2i(V`4Mz(D4yV&1#5ae|Vj68e}2#E~nkR_{Nk9Wq~dlr4L z(m+AgJWeiNm!Dm=?^9{(DW~;z*i=Fyr(6W&5jovnQ>D?h>_=qep-&7acAZN# zZo+=DOxha6-5+a`H;|wB!GSN_bY1Vr>T{6Riuha8?>p0S74xIf^2_@gwWyLX#m}?ZfKk?e7-vltX3P zz#=ifUw%|>D`q?NC6o{S$956IDs!OjV!wMZ-g+E(JsQWim;IzI$mHYNj_!o}|K|dn zE%6N?{Y`{jRTrx=#ftrAAa;}B^)HRK#PW_x%X&cJ2vm-8^%uxH?_o)-1|8C6L+I=tgoIYY^JHqVQLEZCzl;NRg(U zd5ddD6y3!cfh2T*;PyAnpU)OCp?iD;$2f7EFVp=N#)6!oXv)l4lH(Nk6&UK2hJ0-gyP3@wrmwG5a>6c}2f zBla1yxtot)CPrxwErAGdc&8tRfdVN*Z_l*pd!<8GRYE{fRGJ*YvNXZ+;DLx=pRIIa znt^V-A--aRqlF2u^91;8TzNvgnKhX>FfY@Hm<1@}$*aI&If`$j1X!x90i=XA5*vX~ z|HJ@z1O;qRTEkbvui$#>Whbw)pry<7??xL%Wh;ZKnRMz)^<;E9-m2Urjwx=(C{v^S zGkBc725_9iiANu*vaP8dY8&e45frxfz%OPbxSVH?UIrDm_rXv2bhgbMhdK%TtBmzV z-wL2VeoyJJCKRmc;1qGxA3-&FixltOgUMJCiK?r__0CU3C?U7K%mLjTl`G|8i9FTd zls^vV>N<(b$6Iv=$G2XF-m7D_$8&oE#R=j=g==1AqgCG(D*k>n7qL~fXY|C!8g^}< zI|8^S+wI9ttf7B{d}HC*@(C=li_Yzb;eWKaMroYeqNHZg)vK*r=ZD9$dzSpvr8-bb znk$1RRZ`#PC=t^82a__G=4ymYV+r=3sfm0O;X7!&*oY%OV=Okp-7Bi^K?IWZ5n+TY zEy*Jd|Df2!7XGB8%jtn>P(rxsUx6Zi_dhd4%-aq{3CMKpm9wL$5%0OO=ixkLFJ+*gVKU6M8eJ-lP%H@r(45Yw>;FoT3 zbYtl%Q?QJGO}^rG13wYQh>F&5RE>dx49uOhoYmRB^Ux8hXae6|ISG;E&Og+b!JrS- zNEK!oASZ|@pYkYhk{Vfb?~PJ$TdU%=NyUbLJ3Ucgf&{Dmru9+~gLraeU^i&ymA(JP z7kSwSZLBR`RAW~mn-LANPBUUXuqCb??(HMntHr9hPxBc!eu;x$G`S(oXG1Pe(CE?9 zpjleoCZV5D+S!}mTSX6mPk^&yxnh!bgHSc5hEl;s_K?O}5KhMKf_eCQ_?Yv!LLPo3 z@i-`i_QcVYj2tVQM1-rvk}7lAz>XO=P=e`#$jwj5D%B;VN^O-<;qoen&*J6c~uFEXJ-He+-ZG>Q=2ZSm3 zw6P-K`*6HVX9ptMmIT--5$)3}eJV=?nNG>@Jm(9<;x5zF+X? z^|=qfR*XFKRlHKHGXt9nw3WO|c@TlhX-Xt1ceHH=nr(SzDTTkEf^`K@ks zsAK#3$=&*fi~aaw@6~Q~km&8;Z(gN6k-K5X3Sn)0&V308M}#wF$67gTljcgw&jb=j zjoQLjeCeMIZmJl+Nft8MBPm$h1i)dCBKauNt(Xz@Rab}S(AYTYy$Dl{zd?7 z*UT#Sp&0^T%JcwxtsCYO!J*lF7*h&xp`FJ{?l1J{8uxa`l1Wr&!v_)Fh)yO3fV(BM zMV1CIrD%5|`hx+G?nnT5ZpI7y>~vw(9C*P&*hxpwS#sp~EA7bfg6_!SqVUVOnR#00 z(?p?7ZMrCo10$e}37XTj9NkG)Njc2CL11b43o86_5UO?Le--aZOact@1tCb3H@o=d zwx>uzI0{llHTvCBYj;4$!UOPEVX*IgT{bvY1`1>Vy~-a!`m1G>o+O|ch!+RtsIo*Q z)aeuo4MZQSr*#*#Q1F(hGTC~phA5jsN|Yudk1rP*6&t$CZ}%|uvZ}w8A69}vsRtws zyv602#3Zs^buyYhIvqaAJRUW^C9D12yceAa_1mKMg|WMSqH zm@>Q(430(75(oYk@Zpi1PIpSu!indZBZI=e#<2c2Q+xkFt0a@=)kORl{n&X#uH#Ro zU5AdRT$4>Isc3|J>&Unf8@>0VQm?OyTRGb7(Orn%Ih9_{V(Z76pZXLx&-}2PY)SWc z4-8^t<#K=F-b~U>%jwF{(juzXPO_dwZ6*&@Z?)OFPJT~ecXT!sbj^KTr)a4yR})(< z;<2eH=vo0E>k#U{YX&VifMs<|G8#U zs*;Zg$eI!Ibimup)Xs^Pg7eP}!TW5b09Osak*UwG*!S}SviM(1ez!26$x6Hv;)4LW zYTfQ@V$b(n^1GJqNp&Az=6Bbh@ZCx+E!yFDIJNWsz!`P|Oy1sWvppVq61_OzCPMu@eCn zXT6-+d3-=n8Cv;}V&})AZn7bO zn4c7}sYg0ba57aE9GWRH^}BDE+X+2N@$#3ZjnJo$kY5F(Htz+S;tRLxw0t&jf4=!Kr7_`P!C%NC~Bv{%5g3MFN9qkHFl!ccZW0M7&|xEj9!;yt)p{I*nKqayj!^VJlh}qGoA3 zZAj6+DbT$qS~fWe$@12nd)ZYS|FXbRkOp|mq` zp1`mo!ApE@L%B?Yh)ibyTGO0g=%3%n&3tn9eCce!zWRCK_~vsgo9Rf+5E8l}z!S>0 zcl0ncH~+x8T^APbdbheZ{vx)$?<`k>HOTicCh|=C3hyuDrwjeQTFy~Ev_(fr3YdSw zgFjc;|B{T)0-R9NW;M%Iunj(a_(EqBRKX*%ZP^?>+L(hgVy~@R0!Xt z4#Imtof5EJ*0*3Ps7s~WzE@{~8eMBpc0}is?56}6EjZ@GDRt9VOOI+Mfctos92_IQ z=#dc7X;|tuI&W_E^u;HqioPi$hI+@s^oapmaz#3`x=8|D5!k4CT=7#m=Exod=J&Pq zXfBSCL^v392CPXBGYgESM|TJsJhkTRhgarEMy?Nijat^JH>}}H1jYcln>nkO5 zFuoJfodlV`G(sU!;rmsHleIecqyk-_;YoI1tvDWD8DId~69Zp8AcqXInLpl1VE~r& zK^%+d(?(-ncOReMZ&743NBXcOl+ZFhKf*h4+nS>qv{U7?Wd}S`0(1IR7#3KU$(B2* z^N@+f29=R|u`ku9h6)UBG}WhdHclK$yLE+1v@`jnTQ0hrU`mj)lyc>$hXFi-M*dac zF^89>v*v5HxA}>^Xn&_f=3Vw@(M=PCS*Dk;HCQ zB~ooOC!w;b%jKyYSw8wZW!$!qSwc&7^1%~ofLKli#d$(~)AJn0k(}T65a5X-rq^34 zkD$tSg4iLWpI?JMBv=tDMs+kMQfE*=2&1x}5yx`zdp!1aZBn-~B@-8M6KaUhb{!-{ zR95=V*u!dzBRb*&e)EK=!MR7m;n z(7CewMc-+erKEKe0}bOOqrB2@+irn5NAd1e*3huqJiRN-+sfQOXPT@6rI+m%>OSrk zs;2I%dk>)ng@rBzbchDbRwIo?!|d4zUzAp-l^E1}hQcJn>ny+*QxJ5!7Tu+phM#!- z1x!_9b~hCyJeH8UWCzmB=}f>e@dMPBe%&NKte%u{K}C_=j!0bX6JE{P@_cp_ zi|Rz5kOu=r+!swr+sSEiD;XFFr%U#PQ|Ox16#b>d`td`GEiaQdd+`%ou9MEGa#Dd% z%4A++vF80&nwp+GQemJJLIDc9PN-E%h|xY{SpQjoAFipmsbC^iLiGO+H$lvWdv-`# zvew>*e$xeZDi5j-s2@<0nJVBJ7eiZ5AP*SU2b_V}gLO-hY$1@ZzMO!YrY!;1iBEsW zCc5vI`0;szjxIe^qbo?eJ~c#-5}pYPYqG-`{yGANAi{x3C>q-}U}zS2KnMR~&zDp80bnD{XZ7dtWwyt>7M7 z`$z;L&#u_)kZ8*8Jww$TK6?6a&_yqQ1JE^5jf)pdd-{+G(kP_0<5Q2!a35E4og>2s zeE2|Q$c`HB<4EOcuYF_EKqS7q;|&oBb*3!d#O!gYo`M(Br9xU$r?!l}!T3x_i~1Yv z{Gxg7Cl)5z``bWt9}$d%K&%980>2h=EDY}mqXWAs1jSaHo_}sCFM?YlvV|OeD^37} z8e6fX^63$S34KWA)K0@fFvs}7k|7c1{qrYf&LwuJ9l&#(+o<51|5SgZ^MXHoe%V$W z%WomAgZ9vk!dt&Z?Z=U>F$+76T??6D+akx+t(rf_nez`UajG!n2*4yFRH8c%>m`k! zhJXz{4K(ps?}YMb4sW-^zxXi&F}HAn{)^n;ZTPIHD*el2N#Sqd-^S<$*!y7J1$|ue z5^p$W=dlE6ltEV;IIcSok8W~>w*tG(v33;k<2jvFmCV#=SUeD7L@7ss%NkBSTJd0E zd1)RK>QAgwzp$%z!o#C`*dTl|eD|7)*zVt?R?*;r4H%hmy~m;6I-bmv_=z`dwcH+B zMNE=dHmTALzcA7XZB0y-e=%|(q4QYdLUc~elw2@>={xiGp5DC+pZkZa|6r4%!mPlo zwE}5nRdOlX@sRwnSW7)+VcuXdc(NiQxP(%LmNj`hPy%@}a#(!uUyZc#NYTH2`N|-) z^o{L|_vPL_yNRjSWfSq=6&!!RA$L6Ive#S8+uaPlO(ej`NGY)6dBVz@kE1*JV~k_| zxOUT$ISnj*dC_ek%F1UMvtW&qt$PHImWnN#3g$kEmuEjX$o)-U+_CyUE!(7l6aFMx^$rQ?Ym-q_4jd(pUPjmYQDfZTND>b>RJ^h{MS@b%9t(O zrAzflxTwd){UIc_Sw--xU`2_O7$#6&YogwBZqQ1Li4NwXwPQzg97p=kEoT5G@g>7Z zCw`nlzv{AVd)WjY3rulxYWnUQ&JphvFE=!ssT-<=L`(7b(2gj$K8&|&JbXGQWkenXLpyuIpLoLeY(T$ZPdCHcD;Dy@3O2Aa73UjCh2561&XI8fL`Mp({{ zD(Q(~v?(T^)36hV63V^{|MZW!CZ2u!C%baUB}HkryRqt>za#6|j=kmE2r~O0x~fW0emu=%&A^1Q!~e2LM{^4cW2Ta7#$7%2&e^no;88 z1EHsuKp#9wS*McEVTU|LO4oVQ5G6ubBKU7#);`1Z( zL7)&2xp}_+v&|DeiOrwKElYQ4-^9W^MxG!{N`|MezGRQsS7Lryj#h?ds^d(#>MKfp z^P)optyp}pAy=m*o-2K1%(J(c2PA@j`a({+w zPWsAJ6gxmy3N%%kKZq6>;`A7EN;8`Rapi%6$r}Vi%18O492-!Ro!4ge-rHn#g9K2I z8S?cKG-A_D29L)QSHJAhRMxUJVAm{5Y)qY|X{5(3!lN7%mVY>+bCq>jZof>y_%g?Y@55P2ak!2f0UYp^l?}|LOd`gA0$1c2D~?dRi&kljoS@4d8S^3 zm_oIsl!JfN<{AR-6b!r0!@@}e6v}G;lXuC`XS|B$MW&V>$8L|iACVW9<^ACr45SZ znaCVGyFCBfNNy#M{$;=*4MQV$qXE2yJ34hN+bOAEZo}{J(kOKJW<0e`^46jtV8J3{ z-+1faWqa>g`vq`y*rJO3nXDCAAIn$uHgOGcw zTv?p^#fDPdcS$hqY1Q5X*xSQZV)?nrA(`n9E#FmHBx3k`pshE5FRaB4r zt3|A#ZDq+TNtj(Xq*x&&Y7L+9kisOa;pZ{bQXcKRqM%UZpm=6VUua-W!#wH2^ z*;uq{_HvcO&O;fh%@FVUl2}z0E>DZ)==}=G1M5pZNu_&WD}u_bwx`+o5I?_!#7NfP z*Kc`|F`Kr}Iaf2BI4>FHu-pT2U1Thrxq}qaTnB6u&|eX}q6!^}DNg?LS$qFfoRxAS z;$Ga=^BFo}@VglKrm^zqvq9$~-o&H$KzJP5MCLb#b!^cC(2`-==Z?`xEB!a+SMEM} zWtBxV3|DR+T;`FUSoUG=BIbqv#!NKrU1m2~3aJa<)fyL|I%)@r@=C)NBuW|xmb27) zy(cEEDxQ%1jJ*KE-kd4y;^42r$%kgdaXUlK)wyFvmQ*`U`?BI`bmSfjCJQEsjyo-4 zdg5?p+2DoHw&o0Te}sJg-_>@8Yl_`hPpNPF&fVX%r-GWf5t(>ak5# zPu2bCCdNghU*5*uH$#*(ea;BwEDs;S$M%rjYO$^R_Z7dEt&SEVatksft>5QCeV(YP zdz8yjxs4OeK45|!mrV8WOf?vMcnHRj{FH{ineDw?38n~WXX7%L%62nlC`G9A7w=h) zItm=zy-sn^Pu3Fb3I5(y;7YR`E!Xtb!LGTS3BMj~#vz1VCwCD}&cJG+Utj&)1>eaP z1={#7yH9q(h)SNh!Cf{*X1$97Gle}#7)}YXCK|?y>?>m1_)ym5$Mj?nK*4oppaK%d z1VnRKqY)fvrm2lDIm$<(qV@0*!8Ey>f|>$$h&-3(BkY&b6KoXn`7B&dam-C#)7Ax4 z(U`A##xC96f!0`9&>OOQsYIn{9oX+UNe*+F;_&J7%O2}E@_Kf8MPBl%6Kr{pwCgh* z+x1{P$GoSkx{GxX*2OW%nbit4tz2_G2pHh66GAiCG1@YrbJ)r7+{lpBhz|L>qYhLa#cu!hrpl+*#0z4ANy>s(fumfG_%EsZ(u_{@P_vyssM+XY}vO0PEH+ z%{Vzr23JoL;I>rGPrT=1GXzr!A$?#-m#xUcU`w4L&?~{^zi(GUkUo3|u@bed7riH| z8PB%U@#Fl>8--*cr*On{cGHPm1Xn*QbU~GMtb>Zjoo`QA7?+xm@-@bq!ToDizvv;C z0TZk$@xQ2jo@?`hbBiOfNr>#}fi9q{N%C*lmB&`Hmt^k2cR&1NX7PBLX>BPnC|;I3 z3MX#~W$h(uLI%fE7YMtQ@pBo|L|Ew>R`lKX9}ZINjz!H$?FHep!b?6|<7tvUe9Dp96Q{w%T)>jg22PmB4ebV7)b0B(mlGDelwr|DxUF{aAtOtaVKF^?aNt@ETK#4 zZ6CXsK;OeSzL?s$rC$4HWNi>CN2yn9k}e!+2vC?jb18!4-Gjv={wh@j6HIoNS7Pu5 znE^;oxv}JV3j0g59s;F(rQ&d`#3ge6hd|~6rt?{LOM@qw!{|k!*uGvny@+TKFfW{i zZ1a%4*tH^3pu>v9tt{SEIwHhjzeJ{dgj6u1>mSQQZ#!xE7a9-2SgMFl z%3XO{XPVMeSNX|O3HWHZn!iePA48G+@kF+Q_g{JfaOkt>E}cB9C4ZA7H3OZz$!Qsu zg0pikwwoHr%|#>P#?p~&UbrbkEKL|96zrPKW-IZy)D>*wM?A|H*Rb%0?dw;e0i0v0 zpGGdajz-MZ+qr~s%*BzDahf};xtmYx>5!({e7vhyVM|i=a}l4IPYu(fS$KQGcl7VS zfRl)#z%(W;nTl zG{2!_;mXs*6dDrmS|2hyOB0vV`i$0BAzeAfJ8_h4)47}7gx=@L5-+?zq=P{93y&>L zG|%rSEO*10K!WWa-Ims(7_BJ^yW#fVmKhWv*V*zXyLAs2Xpk|C^2G^%L_IKFe3*Y@ zmC?T1etb}GVw^=dYC`#;EHT!c9#WWBTZ=!xM@aKm6e*EXJa;9AsItS;(*Zr3mK!g_qMI@x+Q=K|A2erFUgL(r7br7h=e~-9%i=sPGZ8JhR zyZoW}3h*q6(||+6BU=M4+cq~-N+)j*#)KcE`W8Na>0(1^ZPP{A+4x(=E8f+ua zB%%GMLoMg~o^EnEZ|+FalMgbirhSt^qVA^MJ8y+dob{9gEXH)Q{i_Ho>%N`2-|%c4SG-oXc-wadudzKUhW;oJ43YE^siwAT%>RbS_&$P2|L!G# zXY!4Vrt1FcLu9=25U*IiH>vp+E->~{+3Pm7j4*&i%Hi(Y4zFgDOd?tXJwN^BFqW7fWmi+}S z1i!(5LSl!{1c5oA5vKD?6_%rsmfT=5RVt;{rN$>ttPckYN@Ltwe)QxrZE6!^{1zfa z#!RQA0kCg%p}RvS0^eY8PjX9C_V6M{!p4irCB_MFR?i_&v)j~5lWy4OEV=#Jv@DLm zlek_G<_Et$WRi9)O_jOcsIAwoHk%zI#Y zx*UrSh?s@Qa)umJJG4iA$C4SKqq5>*xz)BuBHEx6ArW+FS-HCQ{ULuL`B%VZ3#F1b z+Wy&#pS>!r&6it+!V{jJP2q~}i5krpTjRnZ-n@PP2)F0vN03lU#Om6o>yNU>Ed*Mh zB~&LaqsyzpGVJby_1BgVh7@EIEjYAEhvnyRLXY8sS^{>1o{Mhz!Uw0;<=3|-tcC3s z$k-lEPbMvv6Neu_iR(_AXt_6(JBqcp0ePwHlur4A$54%b`;TgOEfK#vM}mkR99^6B zth5X!2mgNjEZWCBH2!P_Mq}LPOVQrew{j`T8=$o?67L)I^3^mw8RtJE3`l}e((b`k zu;M+U@uNXyY8XK`eciVWvTgPnz~tABAk_R3@n*@Z{)tl2B8Nj;g>s#}*X3a~{N8Re z)Z2{DeQNdR5WTbA70E@Mio5DWlVXg8jlHPkV7;={1Cnwd5oG$w{n5U)(AleyXE&In zuc7VvvUasM-bu|urFqLEKB%jYxj$J7+GUt6J;)~9-D5`Yr(+#|`=oGqPo$PlQ-F>gtL$NB z&seM#-_daoSqo2GeMk=>jOf*KFNZiLMkKBAM|Y{XQ%q#Hi|;o*gKLfNE~>pHTwj@& zyS$fwm32osD&VeQ3h)sg6qr=AhtTNfJ0`O1+ecN`FrS;zYyx(;J$|2C{3_~yDuV7Z zxIAcm#Cy_5tA5L+eG;}KSD~XE$Cpu+&F|B}8$O*JT+J3d_M@GmMt;dl`lTx9R5)DD zJiXoGrnSW7??K!aZ9H0!xxV|6`0H&y^zk<_q~*)>{^D1cHcYH3+3I$8lPQR|2XTMk zHSLR!Dk{ofRMo`l%?E|RFQ%V*-&l#p^U6nSbv&Z@Q7wNyve0tl7uRPtI)B7Cm?9)M z+GSbFw;A1`3Gp83bon_=o#_gH44Gv*o2Fu&<8RrQ-=3+-uOF8@`|XvRs!JY;0zLuT z@nN+HYiA_;14C910-^g*pwh)eDoTwZjr-)nz`z(81rB6o4Php%;2KOZK*1wWgs-&( zx~9QlT!pmj2fl`+)tQ>5AhLEihB<(sn>o>l+KByFgU^9dz{?nzI#!I$GSDrv z8+GOA-oJ;Ug$%knrpix*a;WS8skWwRhAKAW*LlO-j#jr89hK+RN6u-h-UNT`zD@cc zG&1-gjJnjak-$1!R5NonH(GAV{v!YnjS%A5B3OK;tCQ%Q=i853!JNh$#nX^Nvk&6N zKuu2GqCr(lE;M)QTm-H|PcNFsDx0k;4Iq!MWkzIv%tT}n;HDvc4fHrQ2GW&?liz>s z87KPN){EneUSl1;ja5U$NaQCnSUKawM+A9`F0NZRb`_vU&J<|rfrrGn|9K4b9V|D4 zZt$H%$J`DUe`fT{Alw7KC&lNPqhq4Q8}7k)Z=xZ`fV6A-{N;kLPj$}q&!KCxUe!oiY*#c%NnyuUTl&XtugWZb{yOco3Oh4 z`@YbAiId2t;vLc_z=dF$>ed5E;>h<(EG`A054upZZp7!yEZcg3W8ot_!=$9=<%Bgv z6!QZw5lsVQpF3p1C-L|GfdjvkKuEBy3kq+6wnU9fI}vc+!ZZ^B|BD>8`Zs8g<;SF5 z0m^ha_f*C{3W_BC?{BBGgj5uQv1#B)uTrorlv(~04`pc_9`HTfe_j5Z{#ou~T?`%? zA2x3;f3JhCWs0}E21VKfXo*NkTnR`5NPt;Tj|btSIyC%N_-VZGkdPhF1u;Z`jVO#@ zW)kt%Hdwv@h7RLt0r?{+WP>tx^o^J9!?m)R(~{}C2Mn+5p!(JkMdAej)x#ao8Jn?aG#66LMC67*siRiC|owp1ip&OFk%JQB4(ZkQ3TPpnFXz9SwOp+Gr0C!8{)fOCr7lakb{&I~$j z3bhLNovi=D!tBAj8f6z-8$0J_cY>;9fUYE{&9gp16NEI01Q<1c3kmr)dVVOtQ6Hp{ z8tS8k{bvjO4FKj84J^qV6;d+0y^kAhRF6`GPJDw`q61}UsP{e?jQ-}>Nsdl>u1E(R zS|NH{{vU~mky1iY1qG=BsXWq{lLA{vt-R$6=$Nw;f^ZCU5e4Amddx@gDqo2-cDLpT zBq8!Iz2HvxH!Ge3M4WX6i2{53dUNI&01@CEposJ&&(Bsc?N0T_jy$?m_S>N#z6c7Z zStooJ(wr_AlAiB7zgMQDe|}N7o89PdC&)LJCy!aSy z{eDvi~v!E(K*H+Ldo7+}N~ht+8|8-J;e+QvnD zGo=O}#g{eDVf?mBc+w0S2>ItB)7afG4=_*&=bG#bDfNZ4k8NChm3pVq;C{+k$)c$v zJ()GU?CcSWf{S0`%hTs-;)nwZuhrN#6rvO3w-+uWRLo<# zFQ$y)p)epH@*b2p4O4oj3Dbw30S-^g0;hqrzr4IfS*kw_Gb&7F#2e|-^hzO)gFJwQ z&p|u?rJkB+r%kurkC3rynCVEBHgk*&${|HDuz*Qxi?iM1pqby6)=fg9ewT?~zX;ZM zHoU4?A`J(1JFz@x@vU~q0msBw;x$`e5Pc{k?Or{=FoIX<0S8NcEv?B+ZzN|*UjKo! z_S&(dY#Ie@rg!}?DAw2ap@Kb~!flJ`^<7IoPlo?ZA3jVsq`7@qdzboy_#b zT^xk_M^Q=ITT0uZi3GUBqRiSKa~^ZHm*xZ#1o$sTfX-sWQRcQ5r$`3=lqo)5ZAJoC zW&Ak>hBDdiy(u$CQeyu+M@BW>{q(c0Z%Zu02sF99lI3iS1mDy0swjfqQ}vpLNWsi& zP|XIDD#jX%mUPtwP@x)eqyy8aFi#ohp`DXiv@Zl}Z1CgcuKwmh%m5V2M4`%>Q&3U( z->T!yP`!AEi@-2HF*M-{3N_MV9YIN_@RdUG4~cMCI5={w7|(ztxY!EQRwW8+YeB+9 z;if#Ty}czYfl$~z#M%*KAuN%b|iF07DLz}K$C%4RCJz_-JZ zgvp@&%DZi@RzkY$q z;2=642wXI2WTpa}-**XFPz$AYekPu%Y}i?e|p*d^uVi$&WH>+;R7 z97Eo?#Ep#_scwdTMb8UVWI^mhy8YKhY43eBK%sx#K{OAC;EP0!=$OI1GI{Kdu#g@> zI?Ri7k-xG{&+ZA_N8I5pVI~FNZ+xpvtAr-M4~;;FcfAs0LOiENtTp?ZW?+z-Qkqng z^Nx~oDb^A4LMvdN9LDK7C(BHtq6Q%+jLPC;-_~$z%8q~4o=QhUlJbd(dk<5yDdj87 zlINQOuRg^dse!VCk?t-n^Ew-cyU=RL0R<6}Zb(>|``a-w~^v9olwp?^a{jn7?` zlt(j9PfelaB^~Edmd=2;pZ?+k1A4m`uEAxmSJ|GUSMj6uTJ~mVBQx!;yhz&Hw7Zdp zth9$2_C5=f=GBZpU;2Y98yw^iZs|Z0Ug@N2ve21l$S6^fAtcueE&J~dLUZT1bXxsL zGoU`|U2Rj*MaL35F=aNU7`F)N| zYH*QqHQPxTqpz|Un77DV=vL=Rj5j2&J}d{scFf-`^Vah|{o18MNC%v`Gl^K?T8)6o z2|wm4u-ZPJU;W^5=omk0^U!bV;Z#*MClL`25=KS)sxy$bj%Qu85Vjs$RgOZat5_lv z6-A7pwghqR%pXx15#2^ys#77Bc|cS)7Pv%}F`eC*Jf{9ABJf!Q1V5QLHUo3IRV<^% zP;~;@fNOU~E#^Tm*iZ8hxkc4FFAuIdP*CUJt#Y>Y5f$+-z`MnbJY6AbSIxBeUH$85w={A1q8*rXZ;z2M~0xg3aNRP_j?|{=+Y$T{bU_65%dpT zmx@f|!R_C(6?VKNqt_2lVjQlU_ogX5CNa^@)Sd>oIO~XO7KFGfcO}5hg)5rhlr~RD zmx_8c<{*K0GB9PTQq7P~h|#nGSLb*4ZpHgwC0Wjp4t3wyg+|y#XI|*5S)c8Jz^j4h zugM@1v(gf{O5iO1?rTx{cY>7L`M2?&r2LP4XCG#5`F7mGd5_E5DM9t>Q@YE<*%#iq#c@PLc)+=+LO^o+$+9lgcSv&5+C5e> zN4*V!(hc1cB2_|z7)f4Q>=Iyq+@w2uL*vyf~Ekb?fb&DC`N}d<9>s} z&fb=@9HuW9B<=e}TXd5CM3)#{`ye6Q--VCgJez&NtcZ5MqAr8}h~#I>tU5v8n#_DNBjl(~_{|MMDsT6h?P-I~Ck2wcXDB>YJ6(UyshNU5`tfB?)?vc!65!ZoD?DZ ze%tbHspcrMmGuL1Gj;jtAP-hgs@cq$DA&)5V1;IBv^@Oy5p!kO6Lkroct?%HE2W<} z=wZ#&cS4QU#n{A;3Oi>aLF#Nz=;)%TdEoO*O0~1AM7F`$+pk*Jx7XgfSE7o@$+3|( zR!(s@z!(hN6=S7=rVQRvV7sidXUN8np>7-K?1*j2w1L*QiGgE@uu{=vF0FSPgkX`# z9uMmwJAp}pE2d{BjEEG^z73AQf`w7k5@FB)RX}+WW{IZ&2j(>@!6mswDT!h&n=oCW@1~8DG8)A!d%y7kdh%>(`sG}BxnegDBCEGKrZSxKF{w0YZdKy~M zX=Eu-mxd9lOXtB+!89oGz%d-YI3a<%b)3`2!w@F9CrOS;qA}0)%E<7tp! zsjeXkzb1-yIr=Z=y1FP^TU#rhWGyG5fb=k z+F?2=v>_RP*)v=BjN(WmO{VVqJuAJ6g|LxK@u)t^zxawm*=R+-&95&A!pvJp5OdRU z1l|9@wS=hrPD=%W)4fR)+nwu&pyNF!%3rF4pl*UxYB2IB+~FTAo>Z4i-8~L6`3~JG zABTS%>LHZ)T{w0u)mlk>uazhM-$q$aaMa!D#DW&;K3xqaJq9$S@2)OMzA=)vWY1Us zkxd*s%V{U8WV`{PX4fdUZhFAasv=ZjSRui0Yav*pCC}&~-{Tf7o;OTIU)N`ct--}0jv)W(vq~>H;3Vuf=#*mT_6Zzv|SfK3)1)e6NF)Sl&n&l3hF#XS; zce!YEYrac|Zk6~b)~wa*Oi^L_YDWFmM``C6U1VsFN~PNN+tHW5NE)52>L8yGQ-Dn9 zFDM;VN!)398AQI=fw%{2_N8(HP5Y=#Jgq8tP-?x>Bc*rQd>yEgaDV>X9pQR2~%E?h)wn=s-IVfO;#nk5n|K9*gkwi&^TMnh)P zGrjbPLt0o;_az%zmp*Fg>kNN*LLGj8OCmX}(dI!uw#xd*yE#I%b?Vp4ElllCmJob& zvFJa2iROe++a1rVYqsNw*N5m&@y?>1-I`-}UU@cDbLb_FOKT`N@}|mT<+Z(o?46 zJ6yW`vMD~*G}FQ28S(+`tb!Tq9171><7L3G-c$S8k7;97PWa`VY_5X6Dm^MO4q?xP zB=Wd77DK88db(Q$y|&JR;~CiwO+nayUgMf|4ek!7T{n`p;**Y3|6)HgFBKWrnu}X@ z5-=$Q$>s*%oWB|ZtcbLBmAD_Y-J_j&Vx0W>PK0KIZ#j<8gI+MHMKQ6{Ql9Q0XHY*x zMhT?k$cbJF>y}mLRMGc)!bq2@i-%oOz?4`8G-vNt)kb#Z+wn!gRO_V}ti2fJ zVDj5r&BgDr3GopAug4=3l?;_1HsN&;u~Ld#WM}SeDe?df9>#+Xn)+(azjK{Z{l17j%)c*z+ZOdB zPb{#Jf4KjvH6d9dp?~0NNjkd0=l$C3v(AOIoc9UU<%Z#VeoH}5m9|(?+IMVTUlE!I zC7oV#?q2!_3AOjK=C`se#0sDGdq?Ga0Uel&GjM7wLGSo1go&2B7L}hti@=d$Xqm;7?!}1nRa_ zj>>q;*YeAtq7Vd{T}-KARxz!GJ=EKr!r4<|_%EUv1ZYEj$~ zixM9ngu*rXu}{~fa9v-a*w`d4(`Z^Wn|;}&$|TYu)Lp!vM~hB%@_eh*ZY)%>91Fpv z>VjAiERWNV74#=nzFchH1$8`yLxs19;75#ya4L|Z%CcJ}=$@Q`DsW^`r=6;{GGX7*$D0hwfbnil+EmyW%)2>6L0O{yL6d5wC-g=NXz$z)H)rB^o z43bZwa@JTqdbF@B;)Efq^#Aw#V&H-e8opSrPo~B0N<&U6uiE-dE~1l!?^PzoP`33BICZTU*3jgrgS<8hjWR<9!l`3nL| z=pnOwUNW@f_!7#()@i@?L^Sx{DLla9wkXm3yd?3>Pr8ET_f!+L#*tg<#u4!C?z?7H z-9*u58+%QVB_n)+kFYYw_TAlF`?MFw(FDrmMY2RpyES8`%EhT}c{HV3(9mp~xQV`J zU%j}oOh9Xn@>0YBY*9q47YV25d9EO*DW&zxGQ>qvpuI}*$=->m zMDci(Bvjuy3dQ<6wTP%O;5qKiRb7gnFsb-RV;8}o81)x>4o_R}@FP3$dF>8P5Q;7+24TCSqa3Ta++J>_gP%E5>ScIPxtX zI8-a*Y!wW_t3bZej%rjcf;(suJ{ZCmuLRfO$JL~u&Fy63vs2LGCH-A}-B&&y)j?4w z(W|;(YXGw*=x*>~MES_G+Xx3)6vv&cZczTdK7TMUz~p_<+#IL9(QoHrP^lD^%;HUm zc}}ZjzTA7c+_Oq7E8n{+OmlWnX`Q&2-mu#Hy~Ka3nu@Gxk>%>?%@!25EH6j{ZkT~d zB2z`K$rn*)wFY3bF{E-%+&WkiZ|%=rkDM1BNQpZeoQG+;L3ocj@|Ol>5Bz3 z23ZdJs7+AYXtHFM7Kh8WQ}TeLcw0%vvaKGKJ^KdUi1?va+)$7<#&c`N}SR&F)5+^q_Dw;lwE z#J>5Vg;YwsM-xe&t>W$JI<(zCh=~nIN!=Zi=%JKj-M)uahO;BFjP{p=H2gd*DzH7FCpL{!-6|fofiBx?B>}K=r9_BdgMj4 zsd?ezR7QaBCzK;+IFpFlaYL+~s>J+AI8v#{Z{bF#xP2$v2BEauB-2wdc=HEA)Di8#Wp(lWc)LoNHAZl2>x{3jQ7yg4=$zKjflCu%S&%D?tPv{s~=^9rK2d91<9S>U;8nf#$$OeyziFO z6!j`Z=pOXCd(fy7U)VU+Ou@L8<|9TB_nwS@*Fh-~~z(a~&$AyysQ3)HaZLq}Vw^5~@q5A4Ys|r;E{BYdyt}T*R=k&dH^{-J_Gq(7 zd(5z$aDSf@;krN&41eDD zb?Ia5wzw0m5=F>687EWiwe@BewfK7u^Ez{`lJD!|MjcgNI*|=aIzA5eJ4`Xoo+uhY z0x3zbA!l>%+xZoXPC#mmBrzeeI{M&snO=rvTGXGEemQaw&6ML1B^`3~mFLOyMw8l`K}O9dKq&zBYRBD?Xb&YNlMmJ;#43H`cH->FD~>z3Fb%q4 zm36bT0$kN6#DLNv;Wj4ywlh(#+oF4frj`fh*37kM>h|64c(|QdRo6_b*-RTu(vl`f zvMvEkW`D@jMb7|9G6fM{B&|LWl5GS&qywKv{%n6?7NJm0=fxlXe`jj5yZFqTduB1J zP5pltn_P6yd_(pO##0J2cBFRzDI>uytM^Y1LGGX0g_+1X1LtVrWWMdrf~u{nnJ*vR zV3h^kD=)NwkPE=EVU*hSdYh-^UmCN6V9$yvn$$SRv-jsA%(436u!L z%=GQONtiq~HNJc0E(0{C%7Lz6j1sFqfdtq}XGBA1adf3-UH%6)fi7H`H8Nc4T@RQMjHMPoIdaD8b2w>-866 z5FG*8$=)Cs!7?PW_MCvj35*rDM}@3Y{e~B=cz+I81a*}ZDK)xyp=LG?t)KScHn;ch zM8Dl2+X@p3x>!uBJ9_ZGDi`%S_>bB^x}22|$46}WeInX+hxf}RFEiAgF8(eCbHA8E zL#lt<{{gqv_$e)N@fIcm`|px=t9IhTz`Y^ofWDfgN^s2+dk`$pkbcdD!cCz)$FMXsqfy=|_qOKI6{ber_#eqf8l__%iCAF>j!pv0yCR;Q<| z^K`K?4u+7-sQG~ykrR~oS@ri#`_8>T50-3;+&D-oe=+*9RJTsGWZZK3`8uB1%C|Vm zvpj9{+T>tw>*)`Emw4RE#vb@>gA~EjC;j*jjqcI6hvloD2jmJjGx^sB!%03@3_*T3 z+(GjVoR5RsA8H1-ifD9v5qaEUPE(lwg07T|9tjrx>1sXqCGywq(m5vja$QwLm4wzU zhpzMyKS-)Fv*oXgtOyRFzAU`Llw1A9FRf&l-A0*&bddH%=)dKk^k{q+h?=*4WKgrFPrXn{8Hl z$+PKUpePVY1PSS~ROW%gtq~oji?w{Cp+OEpQ+A_7YSK?-bUHD{KS>~h9i zP5p=1q8?_V1GH2QTl{rM|$N@mHSiu=7RBTH-E%6LPt*fqz8lDL-9L>r5J zSv{r^|7kEtYqKq(UbB7X4m}bEnflN1GFlUHiP#?;;$eCG5KO$T$l64sk_jtw&nPA)L1$eTL1H^g0Ol0-=IogLcr`~! zgqyB^tyxenn6_O7C3;~W*upmF#ru3ya_SSukW#;NEsi#e6LO_~G2r^bFW22JQ zg#cI;rg(6-5JclvVfg2V??jzKk-`)(`t=?IuKWOk?l7e-)j4@1z7>1IG1mvym(=&< zM{|pXiGh)oq9d+iD4kU4i|fCipRELl&l--y@{Ji?prC9Gn&H0^Q2DF8uHGkJCqAZ~$Y%F-X;Y+FHPrOAu9l73 z*iXlvT!Zn!0cBbeKtq;8PVD39-Y>S-be(LcNyer+2XVXcEFOBAgN35d?f9 zfdGS95P(M;l}JI-Muf$VoJ@>)0@4JEF_zAil@J2<2~|9m5F=wTKO9`UW+KmpdfHFo zc&EvN-UbdG-zLA~s5AaYbLnMe;*!kRTONtDZ3Vc-6Y=Vxf%~pJE>Wguas5xIi!>P& zi{Jj6h-Q;30bwl;X_}i0S;rBaMWHVZKLMg%0>}`&734tQWn@0DR*ObT%(nw;5`~yoO885C9Va!|+d##%+0Gr9U_>}8MgK|@es!uXr;9}W-()Rq?LzojD)(1U8YuD&FjjY{9qZedP z=Kp@2-8?$oGJ@Tzcekcrf{67vng3b)Sr(p%Y!=nLXqm|P-Zy!1JUh7%>>m<5S+%C7 z!}m;aU`6u&({#sD_^2WWXJY2^=^-02R{na}5+@UteUFS5JWy)4+BcvN z`u$wW%{}>>NJ2d$u@&S$ow8JBn##t?awmMUP)zp2=JVcV``@*T(ekXQ(U&ikmHipM z?Q#h8X%V0ji7da_&$Ml!-6nikkX}EnuFH%dw`GQ1F1ypTFe|pOb1KwOw|`gXOa5w~uKZJpG&ntV70(9cYzSC7Fc8ufeXY7_^Wo1szzK^v&Ar zka4PRic%*4Ag~O-1mn!VxLm+MId5pTY&}>7zu}XfFdv(#)=e{RBeSZuib8XaBwy3J z4!|6;CqE&#IcU4>^ps7;h+KKHxMzhNC5+7;u)~$AnYmNs!EV_^>^5@^7O}>~0_- z!s{3@L;|b>zB3N%hchs{*Nnp@g)Asc&18=Gye=FuB!M!q3>iz#7j`TPI=UC9QXyxd z0;CH|LG4QE2|(4V^=;AtcMwCZUs8VHo&fQUK>Ay8G?g8gUpOgl)9aj50E(w?ab4Q)SI14{OaUI zvQIuYvA}zgDD~4>FTD<8j&1nXbe3bg{2GJL=8=)Sj9fo=jM0-`b=IeWUh=m)n(*Hx z&iq$LV}kNBXG!ViH@WGRw<{&HH-Af{&RcJ<$vb8^Nx4|s+1*ZOH*CA9t4%a-Y@y}qlk3s<-;&pW+nW4rK4OwYTu zCc7Beh7+4Vo>F!+Mvv4<#m?eo)6{L4x2fx2u+iA+vT73IoXf%;&*umP+1QF73B7z8 zyx6ro@SUv^`$(uq>wxa&^2#|yPXaBX?pQu1R5krvan$GK;JaSnx$l9M#{B#HfG8DpsH##E><;$8+Ad z_dq?T7rLy$CoM&)DY8tk`+(9#@oJ>xbVbasruUh_w$sk8W+?JMP&ez=%-s{Ux7Ttd zvw`zPUXkcqZ{G=&!$cG5+v%7@`c0h( ze8_;zbQlRwmW{97usgI=(Og<~a1j?cxh1v4YM?x|zgrhObdef^NKR zfNJT(K(r}GZ_DT;(pKDtc`6pK8Pp;o2TZ+!98g=OrYCJvcUx$?Wz8Nr`~iECfB~1@ zWX2MFkmNvX(vMKFnnPu=V2XA4b~=E;3S-1R>p}M0A)_#FnLD`#dA`}j3Dds80J+K`jyTth z|H}vJk#|EFgzq&ID%qBu4C?J$^%!y4(hkw_mm8wBnI`#R8uS~E-7Z6JgYE$Mx0akT zu1|#b$O@&asNgU#X4=8rxlGt{_F(Fe-b@Zfz5%g6ubO8f#!c&jR{;jGSOTZ?vA|5% z%|2aet{@^QpX^79jfBdqFX+!%uj|U( z(D&1WCiVksh5rJBheyxvzobE|^`DMs?<+sGqiYMiIMsei4m)7TpM39&O+lmZlh`p* z9Hpi$ltAVfE41QV4qF#@(9BOy9?!TD<1K<>A6By<8YOVy(9mnyvb}3gZV?S_I-ZYRg_rS?o=9YTYm`9-)cyK3kfFQwEi{?$RaZ zyP5;(#IlYjPo~%pH9Va>PQ9Ei;>1>j3}+@PbB+I;#ATOhbxnC`=hs(C@fLiU7-UD) z-H6myt@FHiS&Z8BEQ#|Q_RpO9cnxt&SS_Ero_=t#fer;|1o?-PwNNhl5AaF&P#GFf6(IpK@c<=W&~>WvY__jY0M4K|=-2 z*O&71mj&s0mnDe_HzVq`q5|#vb&>L@m;F6K6}3h8k#zeSE3I!y!#8AGSQ8a)gMaw% zN`J28UkF~xUJ23Nd@g11+TdRrPIu(lga2|kAK-JsAK>mi2H(*_(i2&a&drIJ++r+Nrowc~*KKReM&n~GafIz>m$hJK7c=}pBMmCO~U5^h{Aj75?@=Y{T8K|?Yg zwX&g_8#U~hYt!reBfyk!b!Z^{9{7U8J0LjBQRNS;A88HZd7xqGtKTxTSP0+G!?zH z_2fu{QNhCFHGN>8nr6o6U^3GrNB(`WM;RW6)1#ltw@$=d6#65(HCub}V~*q!mv7Y0 z%oVZ}(?*-3vtY+>6&m`_u2Zil75b=0N^jdgCV);(Y}cDgl|ljW6vrhrCPb+dPpA^w z<&!WFXGmT&ns~Wd7bt%#DTW)So1rvmXhu5NgFI8aej1GjY+K6HFj9ooC~aOyH`@hE zk2b~smjAn2=ZR}>uY&#lP*Xp&Hjw=hO*9%>I-2&Z0mT*HbUs03tuOj!pM5nm1REx_Wz>4|?ph3d@(|3Y*60X7?HHbIiyysx>%0H&=7aT#Rkkl3tHkNv76&#K#1rF~^emni z7+Os!g)06aBJnkgOS<@Z7H!3Ab7#H@Efov%#HB{#*kCe^_GixQA7N{0x$ItAwm-3b z_Hr;Y6YRaY=Mw4qXV3oF;3wpT;NMqn7dwI#I3i(t>5s%RssQ1yY@R3>=AzBmy2TaV z#Z0|a{tWwUaOHJoj-toi>zMK|88IJUNvL^^YvEnlj$rB+^$I$%n_ok^SQ+6zOF*I- z46Qz7Jq7S@E=IOvJYj_pw`WzZh1ufPNM}1(Lg63LLCa)Gbmt0W0SK{hmn7y;+VBnL z#je~1DGG(Gm<~}1WerL^OI7rs`M6I?E&Ts;0q(9g0vZQJ_a!(;i8!nfnm2%yHce3s z`Bhk)Kt}w@uyQLV8XkMgUpMSy%WmR*M4M|E(S9a1yVFl zGXJ|W;d8jyOv-D|RV?$!DaTbTAD2z>dt|bzd9O z^w2@GJX&61g;5b-AJCWAe7&~#02748R292@9iQTPCo;;A%w*sQEhxX_fi(57yY^l#idTk7IEM5u|${oCvzrI*j_B)8=X!G$$)m|C= z*~{f<8y+PL`Oh4ci;0YCbBQm@XB z%e54rL+y~k>#Ng*1U6;DAFGi@T#si9UQVr?E9Xe5_0ZXqgE(B-CBH07d zC$^sUYKiB{TNrjtN%9h4WIjePEwQPpTkMQinEi(oebplMt(9tB{HpmrRnZxKQzS@X-~Yk6)x&Xr z<*jl5i-|QcMxwLZ8X;pE?jZ^zu7C!#{34jGbo_H1~ravo%UYkr3P+<-OeYOqxt&HCQ#iJNOdZ4y1m(ZvW5>u3IG zu>XE-)wYoZS_fKCytz#$f6%*)&Po__#yB82lwVE6nA4GOtcIFD$z`7~z`VVeyo znC0fe8#K*Bbfuxt!rkyL(Z(ox3WDzEYL!zizJe_DfHP3_PUGcWVRV5jetg+gbf@sH z?(Q0u+PY}WC+B};JX{b_`h0-BG`=zFoi1vnzXLJ96&}V zhU<=G#U}`6$FE1|JM??OACENA1Rk6<c&aAu~w~EzENqLZh_Sonc4vrMvIsU~&yTZ9*rSO5ELe0rQD)k?P^k90 zIr_<85>vJRx(2Z|^p$eYBZEsR@*{&2LhG7RcK;Rkxt-aoCoG-@OqsV$$}LK54GmEa};3zFAxG)0Hg$ z71w_Ram3^+{Or*ANl!Bk1?SI}TYT^OFF$nJYCL_)nYcHGS0?iRJZLEo_fi})1RYj{ zF~VDa@L>C7*9k25B3R(!j98+uZ}8Tb_Jh>#lu+|NWV6LKq%jKku!$R?0GnIQE1&)= zetH6jHy(yTu?)MdAwpKLpC1F0o1)E|qu-bV_Kim*BqGAiYIdZ6DX%rADQ`Cnk(Gj(DL(*%@Kmk%Irl;jGZ>z8BBk^2 z?kv?A3g)>gj3DEoN9ys`_h7Qvv{9M+L`qk3FO@808g#dwrk4*Dcs9`P-1u|xac+VIEj0s zY)xi9EiE8N_^?=b$7$T^$b&e&^-Oc#XxhRlJG1g_>q|TEe#WNaA8Ft^YSxksqQH%= z1pn^eV|mGGbsskNba@qhQ5NvX`&@=B`s)sd{7#V0Kkk_3l?B(e1@)*aZfM{4GExJR z_ihmr>&M2XmVU2f2U6G+Tzq{`@mv`C`sS(hrb#1LBAJh`A6vNH(N(PHhJ1H?9m*qW ztwth#{x_sFe{1qXCP#H9!^Gf2!s@(@$#8z+7Mo-phFXfv-^YY6>Zi+UcgQy*+Q?fl z77~H37XB?kI&?c7on>v%;q+H>doS|kZzMwQs~x@Kl)ET$^IFY1@nThGE7)^>TG^XR zn;9X6;w6ChMjV~hNv(9T8s`DNE@>gL*R;9f$uTdq89J}H%rRli{BiuBXWS@#!kvD$=~1q> z>G-@0Tk5Pw(Z6I3_Ns(Vp=XTXUPoPWN~lrHWO-=kt8(YLQx#qV@R3gy9b{@@^sB}0 zu~*0H;-%Lt_sOdeE@r{E*%BGd*Y1T5PaDdOn&qpZ#N$x*A`LNyD8}yQ=q%Kc%KNz4oVkOn z!PV=|Nlm~asRQ1tl7y906{#A04R^JD|9D>gdx&w$4n$`yrbGtvqpvoP2(H3x$_gDX&V-n<_`aFLifVtkN(%^Tzx2$UY0s1 z?H{{9kX$5C@l87fz}{kcZ({4n#K0!K$bqljJcE49okD}i*FR7^@AajO<{}xv0wi2| z;lR;c_YSG=%79GqGIMJ3=Y&(dw=KL$QZ=zMd5`)bFe%FS*Jw9m&?LO>h6I8)Nn%3C zW)Uh$#|70ZdV=w=CI@#@HD8MGI$SOD>g2Ura~xX*ahp*V;kP%MpLM}sP&aFrzk)wB zjgDUkgu5FQ!z$w{Q9K8H@|KrjD7!h zwZIh7-b55A**Zn4XeOB=FBLgR zsR|ylJyg&b^-mws>XqMJK#N`BWY`c%#K2YNWJ7fAKqXpJ-7BUZG^8-Mf=!#uUKQhINL6W`%NwP++)<*1A&crjJO{ z_=Im)YN;wM5+1tp9t{GiYb?~te1OQOT)v3#+oy~=Lqr0H`Nfhk1IxjCbg32gpgND^zcEmAEf7vja z;Pk92zW#T`OXsD1OS0J9mh!ISkGf-)PK9?w<-viMCVk|=pSE~!4ff5(={qnB1%98F!wR%pBPBwTt(l2fGUB&w_?!hwdgfKm6p zfC0NCk|%MTrjurR--9?)$M<&*&rYEZ^G6yK*p}SWW|SWV0pF-hcQ+2G7W*6C(K1_6 zF=JkKTgA2y{b(CZXCJA3QbpvdIyve-W`jSS&bK?r)in7OQM`U zuh58{ifW>Zg9^gy#aqbMUkpcEP%Ym`e_s4}*{H!-u9P>;?09V+pr?jKY4+3#{%1vS zHU9zfP^;6uLh0AdIi1zJ#@9{~fu|p|kH#lmd9MQ)S(Tj+pI)`FMvFm>#Gp+Zt_&KA z99P${h+fm6;571#;`q=f2X_u{I;ly8FOIf;xv2#IeR>0*wE!NzG*$=!V;b#04qd24yA`w~ zzJ@&KC?1QXhiR$H-?)uH!x`C=(4;F~`QWM?3Q~qoPyKcy98Sg^SN*(Ug`{fC11!-sVRh!>cE05Jc z7otO;0?{;qe8!&^6sS;QO&IRC&pTWv8oxklo=xC_DvrG&~qbQgmU#yILAS*J! z(3_KD(+yiBynpgv-lt=1%g1N|)rS>lx$nW5WIwT#s8*R$P5!;8C^Hsl<=IlyfLBTQyFMwJjj*BI0IWeM!G2CrpkX!u}qzW*dp^?$FxYQ zaH+w%tda3*q4-_3vS8m(V# z`Qh+K7IEkA;iYkFTka0ZhE8OpIymbWHJq!QF?#=1hMWZ|*lxOM;-BtGso}#n{A4TT zMqX|X!bRxVi*%vu7;+dhurwZWeC^IkL9Xs3ZU&gs6}Cx%eXjB=C4S5%A)XDD>W?KP zlG4U&7dB!+JcynY#WG1_@W?E7g~CO=z!fOL*yJ46!V9@!%2>&QI{#oyjX@QIP)3t_tcZr7^q zkd{5@Cg`KW@U9bka)_u1e>L#sx1t_ZFs3P(Z>ozP7IWQ&)zdlqTcY|O2{&8M=+1hN zMnK)czYr{Yo-gvK&<@2Ik*~p+@B)_F6=(U1@>n7&0w|Z1sb=GvQy* zNY$&DZ%p~0LYI=57?P{xCE50?n+lgN(L-^=Xb`@10y%jm-Z`8#?^;-M+n z+}oJfClWFx>GnK1``u+l#35H>lViKXyRJ@Kc4 ziQ`QUoKX^r|1y`f6)n^|LaM|=p6aoj4qT&YQLKYy#WGo@8Q54n_csW~Me|3q3`h6~ zca%Dtj9YymT$klA`27v@1<#r@@~4|Go{>aJ8~&bgi&2c}I-C(GLkX-izGv5!UXK6Vzm zk7P2S>1bS#qns+}EvjhJ*sV~m*ny87zwn-Ilg-cLJle|nsN$NOJ}MLXGf?x3Jb%=^ zNiLwmiRuSki2?Jajv0Sy$AL^&iUv3B74-NL+!rGr45C6=+W2*>kG`Ox5V z(_18w0kssQ;a>`2q@afPM#QFe#alzkoMzQU1>T%AOtg-)U)yW?A{v8B!}jtPAYSrj zR~&TU!(nQ!QF%U_y?%U3T6`@VEk0wKIGebN+mQ!fTCl#nXQ`aqmls(yi z?S`1Ajrp++TYdadvoin3c)7=c4?QUcMco!fn+ig4W-yE?5o7w3kl;3*-x$Y+CWk*Z z7CSahXO{CQQe%_&)f8`zA}2pBq-EZk=Et)s;v&X6^Rn1e$4(e>SP}qEp>C`!N{!WV z%!$5G&8V|3k%Xvh47m&9NmY&^5=B1bQ!r{R6-n>pg5-h+U?f14CL+VN3Vl z=JUdq5r=RBSd&VcPq)Q%#Mu+brb!MZ97u2r%SEp{!{4=V+4A8^bq342btNj4ku2*B ze@UZ6<3(R(?cGP4#{;#C(JO8pwwbz7TR9v=Co6S!iMHIWcfuXY{ZEKzLV>sL;Az-m zAhHz2b}?w-qoB8q&#z7zEjf?h=L8O7OsP>nzv(Zr3KfAN?#~WF5@dtkCgr8Jyo-6w zQ%VZi&>rN^9r~pFjh(GQbf%mlVX|C^+$35k3X&;u7bsWhdS$j5)sP8OK2C{g6 zg`IE%W#4c|G^z3%C6|8%@D`z>k-q^L)0fnEif@=1BOVFiBJ5z9yP!Q2ks(4^GQCTO zXI@>qCmMl)L}dwrTiF1Uxa57**usb1!e;2oXVA(4Eq~t|9(nrtABN;UANt~JAww*! zX90C|nmtMfL~4<@PxqQN!s)j2*@X_WQk7!5JV8KJtUh>nX!-ul@Gke-cPNPC{s5mx zp%+6N11g|gUE35%@F+Zk!7Ic93izW~2o@qcs%To^A5xIz*)K$=#*IHT_01A=wc;=mWzwKz#PaS6wn4^ z#JXtZdUDa1!~2Bpb05Ne-&|wLQ8>~!!s}bY3xaPir2L2Fq`Gh6i-o~%RIf3`$_=+U z<-V5Pf{+UcxbNSeCImT21ZmU-E4aA?2E-wTU?DG*n*4*ar2u=_TWTi2+9w|EEMiNZzF-gf4DbCl_~{vuiBB+&>;+awiOiWL7SoNtF=A+C^g7A9E3Y<8&ADlb7}AJPbJE)@Dv3pR{W~GLHuU( z{h#06sP9jswuVasdFHqe@uHzWz1S1AC0lD;)eC3^oj>Vd8CqJG60a?C z?ljDM8vGBZq~JFToAo*13OWvr>6((}&$6uL6C-53+{#JSwduw*z0z|=zV$o$dr0Q; zDf=2&s6DhVyhR-3ztd^^P4unsE{TmogELx{W}7kAeK*2`ue zDQ4K)&FK07>hdoP;j|8^%r+xJ!R^o(E9!_nc^uNI(Tuj{H=FcD(x@@b z#pu4d^plJE8dTMtx@m9R*dw0}ieyTBfai=*r-;q*`Dai8byOdjawUU#DfR)jJA{r) z-ZUF%00Htf240I2{<#|~yK}gFeR7jjxz%J-HN}N?i2hWRr0sF7YUCy$3PgyAYnWae zXQVRxAxegag@370hM;_@1%W;#aXq9+Jvx9Cg@8!BV?@95Ugc$YQLeM2DVb{4b*&Q7 zm?X&W=4uQKjr8|_pkkQVi%5}%d^3Bk#nKNg@+1JRJ;SOjnuhB|SCOoHg{Ne76A}a~ zr#wI(!*K*h!lU;0_p7mxonEdl-pyEB9`uVkdSsm0z07;xs9;}6ba)>YTV)=AC4Up3 zxPs3yo*qb{TICrROLdx^9K3SCjR!ncXLeCB>~6FLu-nsSD7=o@z?ma6gk2nC`bjSa zw1Vx={WBpp%XlWB$Qrmu>~mouHq{~I(3K|op0M)?#o#RX-4_&iA#(>Z9wVhn zq^y%z9~se3gJ-B)&(xk(gK3C_m}v}&Pf*Sz!;?na2^I+zk>aOKdn@pkX$R!SAF2yp zy9v2-*+-03L^bAgdI-p{qU0A({FBh!$n`g5=eL0fBVqD&GUbn+-0ZXJ-te}=5jl$U zd6&3g^vwLwvUEomCg4!WcW~H7T0Cm{p3#mw7>s2GcLcS$qkR18JqjOKm!JchKeNtv z{JK^Sfv|$b#iQJ~>M3;#<**j2Jo61!KHw*88snUN&R!brQsajiqeaYd zVojgf`ZZg-*e8AGeZ&cXRMPb6jFvKoi7+=;4}I* z4Gd-?|6+_7Sbo3t$#sjcQo*3ht@SE~P=sC3?vXSK*SAHZ(VLDSeRGv4807EZ5Y!x= z-A_FwKt>wTRZeyRfqYF6D*dy@NT7nQI2cokWSi8~N0H)x5aL-TTv*i>=Y}hNg?A=S z(g>bPl2$GG&o4vtA{QxR@9v7ig52_dr(kEfu=^yI7c05pxtG#;d(EQx7XHx$*HFxw z2Dxw02LAl@QVpAK`0R*rmcHXXV!{1N6H*_&f<`~wxXGst`|+=BBc)r;6ojxey{kY! zOmfK0{H3MDOfqX#;w4wSKlTJRf0r!$(4iO0aeKV|G(|9L+EF5r*^nQ@5Z6hKeK+~< zS{mFUoY!0(7yL5DEjl)FWB4bJ`ATR7#Z3d(Xu0ni`uvy!^g5MF#PE_RhIS`jN_(k{ z&MgSe$v$r%jomz7u2<@&0+^uqLzRCQmLb{nULR()-i4xf3;|?8C6j&ohC|KTqRAdz?B77zAN5nagh#Nb$t|E+oRT)=4gZCZmQ=1@`S)v*FYbA; zIHI#=h0vKLiK^U5rN6AW4X$du*?i44o&QF!c}J=r!CY-Wqy+i@WrdMdcyQ})_($-^ z7@wc)&MLfBunIPpmCS$h;mr5!i$Ytl1t#qKXm{U}$}YwQIvLgImau-%5|5&xu3lyQ((SL;;fI;#3Q5cF2(^F9Ig{utC4U4}b-pVW`ebXdIK6*B z<`Zqqq+Z@AR1Awq1H%gtCU|oTHxkd7e(kJ0C_gS`nF* z`u|)2@S~#U`uM$zLh+$>9cin2iqyG@IRr#9o9j-LHwafAq0Eo>kEw$R7tEfT36mVj zYM7=`LT+6{-DXB5Xkg0DgyB#C5g~SproB@aXTB8MEvhc+r+Oe@99-6mcub;)|;p>fY~>U&;(E!T=68}a+kl2F(qqs8v^V!wFWp*P(f3|v>WXTy}O`c zMm3!4&b?@Tk+)q(y=h>h6Sc)qGZ)4ZF*jE?9|*l1cGlJhl00<~m3nC+zxi6d63+Eb z{J&X!y00i5uJ^16Sfd7?ehWSgc%>p^WueXl@fdVjd%=N{zovI-OhXTMLMUI~S?w`I z1t&(N*v!|*AVT(gIuxUoL?|IX9O~5fnSQW+4hExce=dTjBM@xGXkhnfAw;-?FQ$d3 z1ERZW(aix+5`#8YM}b8-rxFwnKJ~)XVO((V(q<@57|vCzhM=VVS~7Fd^O>T{5+9r2{dN6IJPh`F>?DoPH#C~KtRB-=#@kRXest>x1jm*_X^O<0gGs4dVU2MlHBDI~-@DVoM_)^$g zDzeJ01TM#yyeYD^ADU*oO=dSnooRP+29fl!z?gL%v>YBo+TXPekVB#$n0YkH2p3{Pa^tD*rc>Tx z6Q^Ky1Q4Fd1bvrgGQpzkooUoFCLc=3ziVes3Pi7`Vv%{YVvmYO-9DB*Bq4X zCu<(3eL^`!#E3H${}3{IVn}E)<5ztnxYSpjQ6U(6M;=pv$+vnKRB`H1u9e3KH%AV+ zi6kJDsNb5r@XDtxr7*cT%rO)?dX0SZ_ zffPYh55m3~BJq=3J2^dD5*H(=9G>7XiQ-F{^q1Vpr8id5Tmr=ssmc!b6;|)5-us<} ziJaX^`#W_!*9GA98*BQKOv=2eO_BKU`i!%4+0hH!VmpMs2jiwfwj zQ5uakk?XZOVHP{_r>hx9JkMH)2TtjTPQdhH|%w2W>an<7%CZaAKj|bLdI&D@+!&% zstdv1UYJ?rMMI=;49bCgH@ zbb-NIV~+OBUz-EG5f&;nANX*vmUtSMgItssjB z_FP=32=^}flhiB}>NwVzGAlK{ssnF}nfM@8QwV*w2g7|A6Fgw7HmL3h5WJ7HK93;9 zEnIi{sS}~!Hx7eOQ^BE8v3d7s;ez!tLPbQ0`ZVulF>`4ypi#vDAW!V1NUu}f;_+XN zB`v5+MW@AjXg-eBxPu?E?R5lH^DdV^Qkm8>yYT~$`7$pZ9z%R0^j+WYQO5{(%$L1m z^r~_Fd?u#Sf7a8Qd})k@B+sUg2fdJVPZ;`^B{CQNVWBx_pwl6QlRp5Grx2;f?!h0J zojEY|^*)Q)AISGFvpvDwgIRT7_x-Qug_10>sAa@S4qpXX8XMm;PBW%ImV98s1AKoWSn285@bC@!MI~7l zQoSj$Q?m`q!wcmAc@$xTME{^;Z{cIcUeg+_D`m9o3~mnzXWga`jNm9Xp@@Y4ehz6VD;}vN z`2x7oRYWnm{vlEkPA$XpD4TMVxi{* zVM$H`P<_|6WBd@EHCpXUmxmWiv{-+`Q)aT2D!i($W&K-a1ks)4%UHwUt<6jJ)guAo z>Otj2n>FGn^e7_ya-Z6G`_VVnv28Pj#Gixl%7l@?i0=_3=duUH>U0)gzg=bLH{~N9 z;&UUC5hrrOU&=!)!{0HEZ0z`dKa@4{G2U_}yuFd%bysD!{l?p?_TJJZG*U|JyQJMg zQs5_N30V}?DqQ*-@Yb9l;Q<&4?QzSyVcM2?f3O zAo9s@;>Sd6Z=1Tnd0JLw5JWuHYxMg@0?Ffbvv95_2QEo+x!Ad+!{#d=LEy3Wn;=y` z{Q4wKXUFB+yx(r<`h!!x{jEkhJFGK8D>DS+UAgl0_$KB3xxM;|qxSQ`N4|$8fauXo z)#7T*yFlRB9WHy^a@nfY5};e$+VM}Qrts8enxPH3_7yFBz;guX9U^^Gjz?c~Q%`AB zxC;%*A(V!v7ueLxeGaWKiClxSuWqd02g!f-TrmH7b@Pv;9?zR!!+X9z7wC_+*vVXn z%E%i8meu57PQ-u`ny)8Um#NKT>&aJ1+s~s#SVAGYUn&8kxu``u9aj_Gqr#;EqsNS2 zgS94Q!I;ivVXbj%tzwZ9hoD=SLCbGkw zWfCUuT&zm8JkeD7NICT(iG*O^>D8Zi(Aa+7Klx65I6rVb>CT$*Zty#WuFr!{cEEpLoscZ7!4k>xn6*?c;&pNxi;#;kt16Pz|T@wplzh zKrzK06kb1+kHnZojDh*5*Vso1uPx)aM%bmSwtZNGt!53N6dW6+)7>2NjZOvLOG_#NE=M_ z0kec@dZOX&CT9>N>FolYh;;06>XamjGWuTB>w%vjpcMu7@%DrC@pP;sM_rO2-WKJ^ z<8;mGI-0?hYRF;co(14-6tm})g!0T#!}xB4Z8Czk77>P7>cdG_@5Qp~=JP1=%4xy& z=P0itJHbg?3-ukx@OP$QHlXP>+}wM5@)}Z?;1}_w0KC*b0jy*rT zek^wGAcKJfDOk##m5soKrF`4cJ$EWC$-7g9|wJAk!HfS;-QMZSR;4NwFk_Q{00`kcXGNN*yDW6!HK)NN- zpwy8-Fg*kYJ3?#F<%MkGH4LG((2|z)c-3dn7+fv8IRbC#KsD!YT!yq_01DVD z0K1NbG|Ee1lCR|(uwbM|T54`+@5_ge5tliD4MuBMKgKBr*ly@g}J;$e|F%}AmserK|IXuJR zK#9Xs7chAN1Y7}OgA*uFs>AEiIfR6y_{kH-f&0idKj!;mNm<^r!+r-t-WLcgV0Q`w#%QPjoI z!zdQFWq+^MwN(Tk^L8|PWJd^dMR4WU)r449#19EXm#i9C$*mqWmBIaXReadPwc9Rq zVM(0sMpoS{VOT7tE#O^K7EAiSMTQCPFxq-*VS=ARHShKcHCs}W*W;C$<@ZXCy118rM-W{Pgo_v!UqvW?)&fTK&ETn0J?`nczjL)~ z(Qd^WypB%k=sK-8IXvfsEr#a&1by5u#aQOIteT0olI}|*@9$Kbg{~hBh5We8alJE4 z+K-Bzy?0wV_i&kl*#N?kJsX_I0NfwJ$eo$D_t8h?>|ADbJt*X(=3^kD2dofxd7UG1|yyFi+G z=b1aNJ34Jq0F|lx3#U1+-j^iA6BNeZ=I1HkVPi7fnUOCLwI<=JugQ3PEUMH9eFh?W zlQ9_BlhZQ#`Y(|u{wxn&0O~|0*KtHAV;TCP?Dy zy?X;f6Wl}Qdhm1T>+bYo#+}~W2JdaFjQmBbV+Gk~qva8xN^hNiPpeF zm*f4F`{rf~ca&Km3x6yRp#`6>eJ6!!4e~$W$C##zri%&{(Ziq1n%;)u9CcJSc|!|7 z!+>^_YY{}e>zyxNK{N#)Fi3U4kBv~S9>Wwod_zH;HpB3rMSB#&h?uBNf!i)nJQqS4 zOfOc_g4bRoJ=TKQi5bbR>BSWg06)bc%?0D?Jn! zBBUtb7w~xh#(httjByI(FCgOe2KQr6emoREA?C(JH1}g=GOuk*`$sSLf zSz+h{1AaV7m_A7W6Yc(wD3yP$j3fnsQz5!~J}OWc-qMV37RQIV{UBX&KH;Sg#H+-> z==-BS@f#^)3M5nRSWo90Q*`WQ_H(q3Bl}~;0#vw=t$bur56HkGgRj|J2LKp5Fl&TH zt8%mW8#>@~?ylRl`loN2;($1i_u%nsP^9mysxhl&rFc~1{nQAr9WZqiI>p-=OfOV0 zkY5(HDkz&LRr6YdT~yrV8sD_WKz`$MtwmJSvN>5)Wn#q8Yac%+eOs^gBG^bnQlYZ| zWW96waksW+A{?SB^hPSRzzb4si^}#>XOaErtaJT_PG|62=-dvHAef!QGQ%08J{G^rpog$=|i?l0=cFTXd z-mYiLe||m;J*ka%_vXgje-2C;^)7(0x;n$rMD1TMW z6n}iY3FXme#{SMvI?k*izb!3V4%e-Hca{00fK#tyF(JWPq2pzv-o3FAvozmdPd@6O zo@912g039|mD>EiAuWCpBp1`Qml|3rJ^qUoa)r*;o>MD;l_+v)ZzcC)w8PS#&VEJ%cnher8_Achc$m+e8W8iM?{Uv-`a$m0-QqZ@uk6a&65 z$#sV)Jl)+YT#?*Y8QC8alD~W%6W0q(CfVoHlB_A2dPe~Z+d)F<6*{c0^BJ%(7C$)* z92EHTOo>7E>d@0tF4=svI%ot~B2eGbZM9Q>R`VtrmPCp8eK~V!d9ga7 z8>HKTAL2;bW}T?p^JW{P3GYYs<@sbz`tEe6%#3GnhoPflP4;OEkBc}Fd9HaaV&^Lw z1(PR-VL_#s#*pIxbU064SVs8i<3BYtWpdnnZv1-%?U#i)QH(T$|9u1s>k{0horyq^uCSoNC&jvc`$Byot1^$Ct}P4pm@+g zZcmMs1W+5S3N*Y~%S&Y^&DDSHbM!v#e{r2R-s|%GWJ2NjVDs{J1%5xVPPb_I(-SFp zZ!im_!9xO3ijD4k7+sf2il5BLO2^h$OJPhM-$NGCv2q%j-t5Et_-`1~Oe`e+Hwbr6 z0rl|Jf*4yv92@GkZ^YPlAQDpoXrC%HDF=F_uAc#i*Kq_SO$dl>Va*sf2au2qEE#_2 ze=bFJ9)}WFU}A0Aa-!*GO0gerJfmhT?|2U4$t=hA?aJQL7BvL?ihV{UFyQRUr^APt zsZgT9bUn<=Q{HS$ka8K^EVrzFILPlg{=xk56bNVkUCjK!H_+>9$}iJ?>9(iWQxtc| zA<0~O4*?gyEVFt95C-5=gNPIfnMWG;%P zeI_MF%45oSg^GGW#8sCV{l5ipW zLakUp;v`=XFImCs{`{K9PT<rWuHUgN#fhfrXGwrPoy%4%L9Sanog-hbfn;nQRT#xzxqI>Unv>nnHSAE zo2IzBuPy2}=YTuizE~<-cW^7EyJ!aB+M3*HJrgI|U9{YNrijyUIo$|$9hZ8KYFH3 zW!N6`=^EX0t3);h&`b+K4-HDE9@-)mc@(+@1n6Icv~&l)U?~l?Vw|egjy(1MLfmTm zXiKfuiMeJ&mjX#a^nIeunx52^Y>(ub)jqjwGf0#-m6XfB*}gV8euji`8^cpwsN}d~ zvy_{3iMPQ*MKHVr%Nc2e^><;x3{jM(R3uT|Ql3#OpgEk#Ll)i7f8M-a!TU@4+e5mo zq18V0Xh3wqX+=s!Ac=*+y7Pr;vHsB&iS1csnxBj@g&1Bm-q>2XOp1ie7Inbgmz&Jk zwmi0}Mf?|iK1Q4la0K!^;F@PMo0GPM>+g4Bp)_~1D0-491)B1Huig8- z6Y$fEf_I5khr4w;V_ok#wsP9rx~f;L?eM1RN!tI znqTy#U9dQG$<~r&{-s|*@Z!_2F_zvD?Fzy2n}d>|7%3|iwxJBpU~~R~wfsl0Xukpw zPpFLYQ@1`r4^|4Kf7Rb+c?FuocuSBf8NN`}Zi$e-Ee{0umyI6aynFwR&b zF2HrmsEdk`Z!D66y4xF(+~?uh0N@Wq%hK@@_YXg3s1kGcZ#)|l#2-K)qAI3*?&YRb zI*wYL(RD_@A-6mR%dnJ1w~3jJ@vFgQQA|!r`VsmC=v-=iF)(E-5ivc}M!f*mMuz95 zg)=vdWDY?f=K2pmhi`p{L*b1kPsXQ9p-8ZrkYVYiJvG~6<-R=`J~@(yjn|(@Lge>X zwo>o97IW_}q=^48n9y4_y&w1?VIXlz+8EMfw64jyXKAj^{y2OL7`R;PVXJlL z;{6jYg>Z8e;+xT#>rH76QJ{Ims#F}$4B2@@Nd%MO6aU;1Dx!t|-8I=CSG-)vpn%LZ z2^FDVxQ<^NG%ATx-XtxEAUZ|V-48|Gz6;czd@RF4+6o`~uwtoRXqZ-Q=L>x`>J?E} z{J^4=Z_$i$(fiPuVeyxxczs^uu)!1PMO^px@Pv{(9i?jhHNo0mPSPWQ$eQ=^71s6cwwuVqs zfT3Fw-DC*ty`&{mfcv}CIyfU%w#hLkqDwM<=qGAkbt5ifsJF}*(RB!o%zDj-Zjy>r z@}Re>_adz}M=Rm>f!bpV`<&*k`lgXo13$RBSP?ntgCPT?rIb(R)Z>V*0!wJrOs;e} z-F;Ted-g#+Ft`&2zFWw6S|KP?(80)ybE2r01xl^~Ukb-tCoyqwpv2Qyjd*nmz?IE^ z81<&~207$~T$6iHHc(zVFD}PZaJ18xF&W|KefnuPLgrF(aWLf*>iBbrLfge;c&PU) zjSbx?o2kJyf37hWxat`nLT(QF+<){@&MKHxg#;6!czaKWMqY?VGQ2YELsJv`-?hOb zQGJ)LIu;S+Q@SBmHXGJQyQ@C{cTmx)JjHV>WF(SjO0!Hbc&GSEqtchPzD2xG~Rd;$LP(l51w zKcAnm)`jhkKZDIrj?$L8>Cb$J5e2S4;GU*c_q8=Y`%ydn4%e?nlT6gVhbpm9Z zmyR;aOj#zgeU&lnCS#joW^VgGiS5NN8+}9JSXSAq$vir06DD#*`c1(A+(H_kPPWb) zX&cOk1%K+c!}Vn3UtxP>_9wJV{7Xo#Uf$?FP+x0hP(G!WT9}wBEBmV8*cVI5-BSIM zIXV7Nl>hDLPYe^nvVLBgJ{o*3mzy#VG!KuFVox2iooMx9BV_{7Q_3KoPBahNrC|SI z46*(+##h&7A-88v{A|B5d4%ir1zq3&vjEC!9A9qfUJsOOeI`KCmlBhk^n5a9kLN)r zdULX~2KpS-x5ufn1=%z$a+1m!O4etF$|3n5=21ke^AdF5QYjixH>5SV8mofEAMLm_ zY5@=F!d0sRyD1~6A|GZBA2OyqjIdSkL)%nter|fsHLBSgnN1T$ zPD3OQI??9>peVy#0N`yYT=k^J_xZ35*9@^~J3#`g@s>(dr5`Y+>wphJ%f(!M@OizC zqu_ixRzqM&DkGvmhlea%U3ca-u@#Doqfpl1LC6f%!nc>8coR+-^=$-ODYnmhsxjfz zgy-Rc7$Sc#Lzn%nXzm{%T!|xa2K;moUZ+5YC!&YM5@-L&XdpLYV{O)8XTU*N z5FeA(5)L#(H#$yH5W!hI-80r!qM150iarS9>8J(ILsI-TZRTy1y%o^IEL7ws$oK>9 z|A3Vs0Jp3A&2O&0<9^eA`K2DEn)YDXm|utxKf7LyH|vj^RyvOR*E9z=6D?u*)pN4w zeT~GFC&^P6^8kxEAhP!=WP3LFoG$DiZ_EcnCJ4QB0neXr02OZWFaZ#R%^LJ|2VJ>^ z{JZp*$G$UM%Uost)Ts}Sf#**@A1SEN3IPYG zuzY0Sd~kjFo6USzMzyD9s@kfk08XngPTMgLdOsgEcZN?|Iac^X~ zMA8ja)OE;u6YEOvh_w6wd&dyoxdn~fC>P^LA)DiL$2tQu`(leWWuh_esOuFdpx>H4 z#~z_Xcs3G#O~w)ff5$NR7D?(1Gja4f#h8oQ^9yl&RblE{%tZ`2s4}Gr+3_y(ZBxOu z-nfM6L0>SuqQBK8>5;E7iDiaRJ~a?$1v}H2M0>4h=1nI6iyxP4;cT{2&dF6fzItco zW%S!Gums9!@X=y&;JXWy?HJ&ZnLLv}9oCaSUHQ_Uc^Cf^|bemJXWy%uM zJ&Byq{RMFpfyzdXOTMyOO;wBvLBtKbm=c~Jx7NTKInAcA*R?aXbe`{{LK&hvm) zfLMuv;>(K+1Lf|8qradNUy2wV?mXbb@PozAP2V;gQ{)K9`{N7tKPesUl5v*5ZPGEH z?pFKjbK0ff=u-S6+N&cp#C1A5kl^`?_b5JZQH#6vimY&o%k4aMC5>C8I71Zn$br8V zGo{q6-T%|p?G@pLo%KuW>Owkhp(6H1-nSP%vt!|WG{U8EWUS{gF@$iOS65ledNRzV z{o$H~r)u`P*DzPoU^fNFxUQ^jI67sH1d=<93XrmVMH1b5x9Gzt(`!5Q&mR5$(!`%k znpHiqTrfN{SnruEQj=!Yo(NKi$#+EbkrLAU-3I%(Me9fqL16NF?K$g)wILO&+ zeAbdiNAA%KpRtU0sSyllWgfR=WPLzCG#stIBLAPn2~eM;1#JqC7?a8DMf8EaLnd#x zeczwmtCf-egiqOD$L`Wq)xIIdy?w@cd2^3nDaDfR^VpGk6pGe}2^dp_WKrB^R>^u? zZ){vQLscTe5XBm9TliMfQhhM-S}f5O=fGFAPpMXSkI9t+go)|sBvI2-8W zoq8J~VG#m$HBw|mf97&TBz*V`TVeZzMuu5{8tHp+{~0X4lPG`EyqlIa1jB{+54teJ zxv++;j_*5cfp81+G^ak@*lGbWh&#QOCxSRDj{&ar(|%t1{fto%cduOVY0_^NX|GKaWha^Ub4rIKwhEfQVFiPCmx%e5h;>66 zMeSy<6SF~Ux@5X-LCo>*K@k=dIf#_p2dB@ZBqtIu2AoKr+mc7=gKIzXS+I5wEgNUt zf;<;&%KP;yVl1=IvfWdUJSt;v;r>~(Ee9DAfs#N6ydXTYwjHvU5{2h_W~+X^r}n7u z%^TvfNkmt1QW1aDa!U`vaoEn4?(ULoTunCjojBkmscoT};TpdgBmh*Jn|J0DVqX6p z^I;-?Af)f8FAf$LDg;s|?)*zAyX#9aWbfqmw)=h7C&1tguw4}7l=t3j8i07nRwL^_ zPTXnJQlsJ!87Tyl)4+6pZe+<&MR%5gdtC&-O4MwT6+nZq!yp(f81|Uvz(vXvh>B!| zNbAK;QoK@W0dj-nzK*c|Aov7jo8&T+fnTXBUHhnXMtAe+w~1WB~& zb=ssBfKbf#b(xe9yN<@{7MPtbL_Dlb)_JyLj895`wqq4bv&t5}?PjC|e4dnwmopaO zXkqG3t{gG}5~cPKhvWh^rWhux0B;B=kwa_FjoR!?OR}=F3Xb?hj0```*_-72DhjB0 zQbaQ&7>=Wk48~<5two3^$yJLlEG;c^M3}{h1VCd)+5G@&O1<2Ul zB+S2bU?hb|_M-m4RsOBP=AN8LEc@c$oFPbK&qr%_malSu*Z;MD_jB^yajzXM_5M}M zi#%=cF&HGb%DsJZCwNn$#Zg7TN=jNO`BMBn^Egru^SMjCp-owyuX+Z{PQ^A=TH}=45T}O#N@YxfpqO^>H*~)a3b}t6$yJhuEUy zfcjtx&ej$4pzU|R7$rmF`J2;{4%Y5VjuiU-mXGPAfrZZ@K_9k$qO#Ri(67xk%k@h3 z567Nu{tye=RwOkS6L?Dn^O=ls(cb*dLo&?HI?)V^pa$w{6LisVK61#$;g$^D_R9PV zXiR-fk1P1oN~%)u1qm#cEMLm55p64D#1Fvud{L-QFW+C`w}jDU7-X4NKicIBfC(Dt zQ+=d(Y`HZtvbJ_#$99Yqr@;U4!HP1ErG`B;hDnq{g;4{`nar9t#%Qenn~D+oj0qMN z*Q$>kBvqk~%o^Ylz4Pst_s3+2P^Y1fSyYW|X6;>x2TZ^fzPi#y7&coyOf}?uZ4DU1 zXqWo@>PddCXB4KuUP%Way5jptP#oe;350}e@ne^If5YmMnUX2Lc3s$3XMFS@wCZ!b zJ8J0-m~}VCnnY7Rcjl8Q$K~>uq!iHU^V^zMh)1S@$#2m>fL3}im?RmJm3&>VuG^cz zFCt}SG(Nm8krammF7%CY*LVRPA&fFw$ng)3Jgrngo`Dn1e zh%Krr6%4K@ru66u#y7b|wJQQ0)lo0X~Lj-9!B1N(ckX#MM_ znOT`RfPm;!QG(gb96-N{7-o}X9*fI4=D6<&Xtb3O2(N#k4-lMrF`!;-7MHVp=oq7K zck?xca)Bcj!mi4bN}`j)Q>DTEsQUH5RD2X28E&C?LM-TQ`hWRgPBC@Z$SqD(aN9Hp zm!#Z}F(pS0d9XG>3tTyeCDW8N?{?PCWZk^|hyo5s!3yT#w~5m)HINawx6s$$lope{ z1NkzoKW*J--N1(1mSa$}>eawXE+vx!-^2TOKk?a#g^~}+yF1Zi6hyvyxjUdOF3ZQb z{X_kKKRuc#Yey$cRu!b?X&(oJ@Q(o7ZjPV|yXRa(2zlDOje zrZM)>Qj7H}ufHm~Ot&yLy$K{9)z3O_Ypzx;*7S(p!`gk=KA%>&e}EOBoyShHDgb{2 zKM?X1Upg_XX6Ul3Yz*f0%5~pucCrR$Uz#6-??XPZ$>r-&+q(uxh_yV6HrleurC zWMkCzt&B(1l_lp>gO?Fzr&kQF3)_k;FOW&tvxU$1>Njmy$ymuN>T0xaXd`{sMnw;M z>xh4Z$%d0_e^AVWth)Ux4uF8u$S?2A*LcRRL5pd7MOxLreW=5aLa{x43W~#_egY7_S90xSTP(p)Mw)5Jz);HU(>N9)R`}ByRIUY z3nL4RVIhq7ft9cy;{H{n=b5m=6-)4JNG=HXIs$%@7+ZLJ#1lPa>|+b-8THm-xzvYT z&F;Pl`#5m>?VkXrq{I=a^(~GEIIPap;&sL7wX)H%(pvVm$u#S`zOom`FT+F64)rk` znfy=AEjzkvBUJC>VUbq+f7C~HkayQ9S$|LD>D(Ya4@qc>6McU_O!l5F0Q77Xi5v0i zj4-8W-34wH4CWf5Pft@z#oq>p^(7gJJJ1$9;QDp%;^~Qz{&(!1LjH4|ZVh!B4~2^U z#xb`l4Ga_0kJijRUBFINFl-_GcJA^IUr^hnB9h$G7GkOVx#&EAeM10N@)doq#7Yj^ zOUaD$brTktG|7!D#+v$;aUVGp@{^!e6T_pEe83z2Pz4CZ~|5jg1w=RCL zlF<|Z)5~1b^E*etl*sr9jy&2owb@yOb%jlp!*dB3qEXK~aXX zTiPO19BgG2WGh3KvMCD6UV;n-9%QS4EM@5X{k_RQA%qYTf-(1f-Pbwia~|Z0fMH1_ zUv`28n_RIxurl2>Yb{^1GP`jZNK~E=Ml=8&KsH%@;t$XJAyhz04jnibh7~qAL|kxs z44IJQh->%-GzcG^Tsn%>KGI50eRP+!wpT&=bIvf>n>l#S;ETN;*7|3gOZBt$#7Vtr zY_ByaP*r&tkfyA`PJk7w^uBC%hJm`aqtRnSFs%1Lj@Q9G#}PSr#27mj>>ukwbEryj zR#40!;?1NeTrl8R^_99?Yb~}9r#r(0o>`Ur&xHTnjw39xm#0ZS*%?EIHxKWRoUd>DOCd4(AX59R}JJ)FQ)Dv{YG!x&^gp`5b* z5NhkC$p~aX1{=BH8P4a1kx;#(5#oP=13)Dz^|a!p@eIN8nP4UZ>yOJldHp95nVrW`H)vveD{;SBqb_0DnP3ik*-?Q-YKZ?ub)8%F zGP;GBKs5lEa!$Gu2!|QjN zNq$p{Eruv}kqb&Bgc?3aKv{`o{z;EVOV>X=ozlHR(1Z7x-NOdWB6U)en@!6&7JpzJ zFu(>?cq+5^AW;ga`KT-mKbBIrp4C5tf;q+yEz0AR&ci3)cF*V|Ko5?U1>}m0 zqa2i`%7&gYw$Sw>-7dbFN=cls0rfb?3irFDJp9tbHs^et9@X{qZTEwJ6umuYS`xwr zoyB4ZqyG9)M_08g0b&3U87cJd4h;Q$)B@R4C$YXf=Ib^tu!qD-t1u*7 z0LIHQ{_u`9lcrCoBGS&=#HIF?4u7E2r_o3{u~`Qyw~aNE)lDGmDZFCDEI#FEY~VEe=9ck(H>~As%0W8$y>jcr&Pc6=9|pc18CE0HfAk$|q924Q zNBu@SGz76ag}?U<+5XZzezN`5D81$R!)T4HCxn?^;H(>yY{|5Ix5E-@;R4%S^fDA^%iIwXk!kvkg6nCPSQLm(kH;Z)yOWkrM3 zjbCL)@GF{rE}JTwn2nq?)Zpd?Yfj$>S~x{1mUiw`wDU>1D81_qz}{(1GcePMEjJOe zyG?}Qc^_M@d#BU7e1$`$r>&dbZg0&`?6h;fp+~=cScC!uCTo^wjI^gY0)yTFR%(>} z;Rt)dJt80;$wS??7^tavLG|EZKAh0i*eQGOvFDe9i)3-9*P595|Mevj&^0*tz~5cr z;i8OiUYcDF&BeElnRedyVrnw3JWC*SbijsH#+<|T1xy1APji!mye5q5a=_vZhZ<7^ zk>q3_E<$aI;D>DFF)*coia44YHeGB6%9&{~PQk?5pKHMB*Yv1Pc^LztJVF@UFjC0K z9J|ouxjzC}BTKh$waBDRV1U*;;L~R_Kpx7=92+qdJB`I=D`qA(-Kz3=_%>r9Am&fVr z=L*9Cr0l3$MMD+juxD&Ze+c-F(LXxxDVyppN6ielIaP?vYT#T`Vg+ef5AA0ic@1B06Ap69_ER7H}$8 zB7yT3h?q;HY@voa?p}PzG&As$wN>-w1E7r*Az7%rq9jH`31D_f^T^eWv*#5Isa*f0 zSIzzq^CoQ9%Axr_8O-$J`3hD zs(A=n&M=XfqLBoM1Z2#csEAmN+qi4Fqq>s_y<%{sGCV>3%eomNs$BdZ%SMiSY33`ON|42CJ(d!4YzmIZhHuFan)?H(Y z+f;{uze{oP5Z@&Dy<>9F*Jq6DV2q>EcUu(6O}eIwHEOtv&|lX3mR8|QmfwV-+5L~> zXoS@i_Kj3gCDaEkDyz0yz1M~vC+hDG2sMGl7ObLrCzY3DwRlGf6VcMrVUu;AKSuxkx2<3+7kuNVEU&vz zzbcGTPG@R2?)0+rr|FViV*!)s`yA27V~!CUOON-vI9tXwM~*H;Y$;nu8uERwtOp#q z9~Tb!;bw|ZZUStElr3P;iX!YhWlaZ6Q3h|vp>a&1wRcL($s3bzG481PQqD|nv4S0Z z_Tc)<3RIs$242wO_eo4cXdru|PdD3W(i=MJY3$9tnpf85ceMKI+Pu?#D#!fiG5f}s z?aT2i#{Kbn-NJ8uYFsMSWxdyaD~hc2-3#E-1vcdofo$ftOT-ynlbV#^w-)#K{RjM) zWn-#)x!Z5*e=O@?Z<4_&KFI0s1LMIgRWufuV~7!Ij#B&|q9mxHlDzl3A^bw4ENobW z$_#%#)U22+76f8kgo3&^+VXS^sIV^IV2%<{(R<}|_a(b!%cPkerATIF!Ae(7m5dGI zhomsYO84JYz<)POI{_jUSQ66Xh`8^q*aSHYn@mG!Lmv4wfWUmCFCQw*Pt{3g*)d%cMNV7H5n=kF#VWPN%Orb9I^)b65Z@HX${_0 zcSOGX=R$-v``+#Ycu|08Wku^Iv3S!{DGmUN+Z{7RPd#%5T=W*MaXz9}ba6s!3`IA4BAzu0N z=Y2Ni&i}HuxO3TJ|C}@W@uTH2&(H3XOO%~!ucEN`U;nWA)5W!lS?*0Op1aj*zRINH z4y1HgSgCtzID~=cdlNgxoSJOau~Ia^-IVz;h;%S?MP3Ldz3pF=AA-02#s%_Fq~Ew# zbrqsW*@*f4VxV?%OkNuOrgCGxuxrtBLK=wrJoiM_`!)_krJ=*gZW5~U6FJ>xRply= z=)qU{;Z{gx2$hlKh6IqaejPk=Vo3E|n<6?=y^4+7A833xqUW8gk()%3D!!ZqM5t)My2_N)A_iNO+~C8+JPDoIkqGKoI-Y2T5jZ3440EuW<2f_9+Sy$hmTs zg#gD+CtKb=a$lEGyF`x2=jGMIE+&^sJQjPB@-YRKN{B1d&XdzOl}_>ad1xSE_NDAr z@m)biF_XKjqMSZ^=NnSJyguAb3;Z`>BBq#0uRo_Dcv-0Q8Yv>&D)wH=!}h7vC!#4A zOyrBM{Y5_$IlXhc<){-hda+ZJw4O(wetZ_BXmO=eDdEZOgQ9P9XP=B$&$!b0ujg<< z;zX-(@J0a3``$IACC+L&;Om;-bN!8PQ9w%GiXeLDd_s}2Zg0)T1V1GD50&tB-Qc#) z7m^VN`^IGE>DMZZB5z0T>NkIUpSXm9nIF65w(#j;{B__|;*ET6CODa|83O(7~}LmnVJkez1#ynZ!c4XJ7j~z4a~T@(sgL?Jr*J z4zQ3qD(QNF>&xS-^7*Pde#|bl3${JYBb>TydE_ zau7%zh9;v#5kl&pQ){?0r`QP=@G}S91v! zX1tnQ^sdj&QAPWutIX5ZP$njNB;E9$X5-?B3k#+%aVTH#Ngi=|K|k& zz)WNFfbrSy*}Cm{Scof7E(>A@=h}=7yd;`^L$%!S0_-s!ur{Bn+z;x3MXk*n^NY8> zK?RZX68%UQw3>I2gcGd0Fc0AbHpWAxpQo}&chv>!cg5ICs(s!)ZabW4L!Xm#xv_k{Vga`?wW^M+1-{iSiKXrE!k z58tQ-OzyeH#E2rO7t!S#a`O^$U9&!}R~?{gyF&>#OXGWeM5a$&6&;i@g(~j278euj z+BJypOwOH|*k3p3$Hd~X>aIB9Q)?tg_DIY~nM72KZ=yo?7(vF~F)=Y^c&GcXunREo z0E5}dv$t4l1};(R(xe5<&^P*1vO)0Er*CWw417#IP;e6)rc`lUuz$x^ z*h6-Oo$35wTmR>ew%Lz13>bbA746?F?f>if`mC=H@4WGKTl0n_d~UY2vPB|%p|xG% zm-NSzhpG2wUay!pHQryK6A~gRdLY@vgzmi_6wi?r&za8=e>yKDNhHI-j|ejic5bXU zz%J+}iO{3)k>KHNTk9{kW+b2HoW%V6mbOsVa^s6-RjYO7ZS9e8k-jBTub#-+aTPQ; z4U?|TFA;%zMYRA=)THogy8c?>D&iiWpg%1ssMAyOir?|&G1+UVD7imNKo-K9@F2>! zYX}as>2Dq^weBGebNr|>J+L!u-y&|4Z;#z+q|8B$OpSH*DMG?kzI?D;XU;C=V zMSjeEAN!NlJND-&6Aca&F9IE(ZD)>lM!Q3`!(vs&awzFq+G&>Ca*Id7(j^OY$gBL; z=(C^at{dw*{mjDUuFn`6cnk0#fIB{0qcd(iunG=AbkNxZ`m^)iLPq$Cmx#zd{`PsF zlusTswi|m|8b{WZ+3$5Z{`iGdaXH)|&LiU2+6Z5(k1`VnaiCa1)GVzAeoZE;rijGC zF{T@RARlq~aT~oKlTW-QATc6a`mi2K684wMo9*A3e#b_SIg!v)&g;0^h0d7mg#q9m z8C~a@YAy-BO_#Z4uH)W7?e$G5KQ1TxkE8K3-J9^h=k~)`Fr{|z0gat1F@ zcYV|umumllKqoTidZSOu{R=HzgMx0`W@-pI5^-`hNBi$Gb1p)kT>cY*@-XVM_+CuU z%K!>=ZI2(qe!9NpWAqD^$w{iV$BQxqM-S7h6ZFKBX067Ohd8}%7zPiq->h^vpJlB) zC!hNY8vmnc2A$1L{w>&1z>Mn>iBSU-4Uwj6u(bElyC)1_e?LEQ-;mY8935Ev8dwfC zd-wSJ^4mckxt|p5I_=n(F!~;DsS5LZV`eADq<;8qP8_fN0ygV{U?XcQ5o)p5jgmEi z2Vdq#HEi~^n5_0Tp6&#%Q+X6mB@Au79&}Bu;}btqc3#eo}kGb_J;bO-2q!Z)hC|% z^Z!KsF4FuM@`dufqocLIL?3LxEfSqmhj#D9=2$rA$pZE4}4Zgw`{=V8kKt98+c?`kwc zytIY|kTDc%VY;~ z9>|wJshzTDm1V;5IkJQX`K3>p@0DN8G(DIoE`t5+)G!*_8z{eXQ!0ATM=GyXLHhlM z)PAdW*WxeJNi&0uxn|!a)NrmTlC-fWIA3N}DdDnqPWy#b(sJL4jYX@WvDx4?NX86S zQ&j!U+Apugi11~gL&pc{bZkv3Y>kW;jUiJs?*WyeU(FzRtiLxz4pw>I z!0VZ^pKJe=4IN}#&G6vpJ_Fe!Y4bW~?tA1eE$#PWQ|HAc%$RNu66jzY^C_SIGNEka z-g>&GaOfU%!)R^flM?uo5`1cG@1pkv=U-pt_S1Q-j*hq|+k*lsXlA;oNXe3~Ird)l&XtQBW5%p6x=@Vp<>uxK!(MHvAKj{ z1!%a-$S-+QjyH4Z?qn<7anHY+-A+Ll_bmxpG|3hG-Awp96s&2=*KYUT01m1@0oC_- zyxx+e{qO9V0xG6qou;a=*{`^$z~SeYo}gR8_q=koBb!e1@3Zf;#uG<%R0UvOt>rW& zGFM+o_Erdld^OSjal&U~_gjx0jLZ+ns5n)tULeFD%sO~Cn@b)M9tA-ee~EbF_4~sldQrGD*Yov1NO*iVALimZ z1U%(2#5&6~=D-G2r9cU7Q|@9?kETKKJwr-bv)#xy!LD!5?Fd&$m8^AsgfXK2Trrd8 zrX#;&X;6q(FqsZ?L*H@Z9*(=JOSeS#bo~JdQyxiZyQ6wek{Zet6G+CoNTv4TjLqf= zi-mSRI-_)jL~LYG*3PFcOI;PKo`9Vw_+KWb;=5tamIjd#MqErxy&iwd9d+$`b6_r{UXfcbv_F*pMvYf<1o_R%|dwLXj zv*qH(>n9q=>IAf;Z`uA`(TKB(?uNTDX0M91P2Y<^%HqH)Fkih9R9|I(6)PgCBw2$!h5a!cu3BSjEf>2gF9KXGOR_ub_Twj3*L>` zz$dW+=@Z4l=)|?C2>BjgXN?md*0bfryAGBVL}xbL90b&$a@`#$D9aaKjyA}_vzo3n znb(`}ap)^iDtR;g*bPzPR;#R@6*xQ6C7K_5x;?&vax@^V(zUwzQSpkplQ`=OyaRF% zD8GS{>bWG9&YLXPF2Dw6QA2t5jGf5QQL%h=Ubr}lAwmg)#k~d!8>wBWSHI%eJ zCVNs&Ps2)tFrN6#NN7NS-&wa#>ARpFPp3@(gpT~Sf32S6p<}!o6;|m}J=5)|Iu^7P zRh^Xh9i8+2Pq$+xUhCh^cKlk}+9P)I8&PD?N`J;(oX{TG71KCHXX;ffq=r1d32 z$Q=4NKVbX_qf=K62Jf1LRHH4xsV4B(DIm(eA%e{X>{;9Pd6=8uYZ%7Qd`8NDRRFd( zaxV=#Z<8%b9^{ROY_Ks5`1tlhUDbUXc#z7CJgCxZXK%ARcqp|h95Z!ny4}?p`q>|r zOtfBwGl(2JJA(jJiHFdkGDO)Vp3!sq$QfqE&dU^qKS^nlZ z@SMI9Iq?3312cG=m2v6C<4PER=++bI^>GTZR)+64^MQt%k2UST?|dfb`7&!6rN@*Y0Q3r$DM8ouH)~-U{5$DTlUkd3l7R+gXlt{oW80xhX zp`>(wGILn;^VJ7OYKhVbeu@5`PIl^@3w8!afeYA3i7O!_T_rGle(uc_i(Ux(&l$H> zX7j$nxI)ke=N4T6+ypqXR=Q$-FjUYLM5ub`10Z4ORUFx3(Yz zK^PZ3tU+1VUi7Z;lwYyZ19h(~m%G|CtH=sp-ty)wdcW)hpd}ij7y^o_Wp5~V#_0k1 z-`9D3-v+EXURB@qq}nj3j?J3bdNIF0uVF1$wDso~h+e-#E0uG{t7Q^BT^tx?F^yI; zan|N72|mI+pC8#F`7y9du3WP`>}I(2k(A?udG~}Yzv1q7C2q@9u7F~S975# zbpP)Snf3hbtEJBKn$OCY{WgF1C^PGUF5p4el)xR$7L0E2CKq--Lv|$+>cxZOJ}hcw z-zy$Qmu(bCqQ@~rHSW3J6xOeJkR)|B0574Zq|yCyYE0AdOsCoQuP<$9j6b56=gUgB zT+msG>e9+Cy;fD)=&v?9=B_r{-1+Bd|CGnMY_Dwlyhdl*I#gdcUsPIRc5|?8G3+Lk zxDg!{t)Rc8W5WHt$UI%EIc{6`8dg;*nA9r`DS2Ape!Ri0@#hO%MM0ss1nTNvig~H{ z{F9ZT@7X^5(}+|_1RWLFLJs}!QD=I>3Q*Ibg%&Q4ni)vYOqI5gilyz;|BkIC9le-) z)_zrH(-zaqD@jj_+8(J2mQZ+#pJ4o4gL-|^$6A&B3QaE{PL1~O`QDGcXu)#w_BHow zWe>@(EK~TbqYG`vZ}fzjzZVnqtSojsnFiKrP^y0mYhw&;TT;2o`|Z~BH9J%TTQs?D zv_q1AcEO{j@PQ?1gAPNuPzAjyi-%+oOXCuz2jyb|U+cz2<&bz3dQnDym*;5@m z8;QZDlrU9&A6M?IJHQp3#3ut7^F|7`_3Ii_-4 zdd!#1VTO%lp|KsD2bwo)@$Tb!Nhfk!;eN(52iDHmQOOjOY_r;a)9*MxA7W)($9X&0 z>x9+a{)@Kqdv0|5kd$NF7oWHl8A;ukoi#?6W~7;<^Ms+H#9(d8%^WYdcyr{mvi^C- zB|a6=ENY zt}(hAi;+F|Z8vPWJ1frR#je);E0BS2%EE5?5`Z%}40zAZUd0iR-;1*)JU-X&kvsAx zE6HL=tI$#D_&<7lhG2$deaZpXb{qZ&pq+t?L5y8u6_ z09?f|cZ&}85`qOXlQhGEht=zQYMdO$f?$8gST5TuC8+Ox*Wi*~o%a9K&$rL{Z^sbe zkj#7Quk79Xs#nm$qfIJ6S0XDV;2_(a+npuX;SJg(y6$B)VORL%e}9%G&G)mf z@GwI~_^g8phS`ezcQhIkL@vE~${`w%ncuB{5-{!J&JPt#Mt!G3<4&4xzi6LROVoJN ztVrnAPW86}8bDoOD|=8fUH2C#vB?`X||f>xWW(?4rR1@mn6jj zHd%r!4^FHE`N7G<#|HXbyHQI5u(Re7N$J7A zKds81X6au~SVe39^@eb}X^UR?k8xc*=>t8x!o}Z*I1^m~rC@Tk&DB%>voK?!)LqX$ z@y9Lc-{clC(c>B0QeVi~LZ=Im#fpMf2#Hgjq4>&Rfp%}rnK#~|hD9+po@OeW!hT=z z$N%^-E3w(bNV{v>c{c~>KFBo2-_&kQ=r|dY);Jh+>*z?BUC7nnI9gMJVt6|S7DGVN zOHr&DyMfeNn|$Y@DKq*G2ck57?*8K%*wlw<)=FV%>HIDIeY#52@95|cpG5i>7GDr# z!oKZKaEzJakLT}zX#b(ibF}iOUcD+Nu~Zk=L~UG+IDOo@F(}$$5b_f|cG8$mj!67= z{qyywTb`1@3QgjFm02EsX;{~!u)W|4o)V?-h|F0>geBFBn~_TQ^M+F5)q_H%&b#Xm zNh?p*-{u~1sX%>t5cFY83CIgWhhUE=jX>s*Y3{1%@_sICMY)8Kw6 zFXTi9E)COoO-F93jj>R8&|J+wwdeWSNU6|b9`uliV^61t9!dw_7hUdWy_hGqk14b` zyrih6PS3~Q1#8;2Qx3uP(~13czJLgxe^VDTUD!y8v4DSkweXXA;y;~l?&l9iJO zKQSCinsJL@BqFdMWTfYQGLS1d!Z_(&)!fB?ND7k~68<=ywIr5TJWE*Fm>TB5K>Jnw zcxfAa6mKZ(F9hn!hZ6;#rH?VqC*Ff3(}8o$$#@6!*WSVN-?`N?@vQxh7gBm&UeL=O z)S+SDS{g~*qs&}ENcUi7`7OcSE;Kiq$G^nPu`qH!^0jh(SkbdTROUcQt9XH^m-w42 zQ8Udczj!{)vi>a@F2G*&qxM$bLTw`%qE#pZ{>P_~!4!q1E^E zGgHzEKlS$97CszxellqPI>SMMG3EmUbr0tFCBUHxuIl4^{s$-yotCeNVkA>+!_4)C zWzz@RzH3pf8QGcmb3Dar)!7)72xtW+@)vgA)dvF`=FF50i9seB?$xu}X|`7;cF08m zDd|UqoTBsAU@mzQEke^BoPoCS88=emfXzeEo6uvLbE_R|wETe2{i`FOfm11*=efRJ zIrf=O{b42NTj)+7(W*VvaT*It&;22z)N|d)dvP86B_k8U_oB3{v~E{P=-hJIao<Z9ab?ipqL59Kx2~d+Y39We7oe1`{w|`r( z!uzIc2nNm{fk2Awnksba0nJ?%4%`@ISGeN<+D<>R`PDDI(E`MLgO)x5IK(y8{0J$7 zkpB6_xJQPQ<#GOv4mcN}5Xm1otnhj$x6eJ>l4J}--eaOgL81WAh_ z?J423)Oxp&lT1|mZZrs|<758SA2LCG1dO{AQD@a#zp)orP0o8SDFf*vGxR~3Zg?#iyzvrCnm|f$nk1~A3`Ss=b zY%0X)$3hYa^2SDDU%C860(GaZX1DwJc7PN4a>d$(^q5d_iG_Sgy>k_6y;nM)hj8kY zHI0k^+>@;lV6iy9*CX|1Jh?^_@M|cMErhNKc12C`Xo@MqO8@22FL_r_M!tyIFo9oT zx%uy+Q^dN^Y2+cz{=4o7>}JTn2S=lIE}|u;Q4e~p_e;wPJkai7zsTEs_$RJ%PM0r= z-ZWk~IWz+q4o=9GJ_J?rAOKZpkwKeu7gV0uRqyN@iQJ!Bmj5xYMdp|Pij9q(?pt4Sj!OL+ zv$Ay>bxTa6^>OD2ZUdM8RiD0Ft}Rz84`>Ip@~fc->i<~zr|*>lSoMliZGPVoB$8hV zz^Z*aGHcgLSg!z|{a1x|(57r?LDVsibj#6 zL%fV7(g``1m7Yl6fpsf33SrpNTqt9v`w`9#p@dDi3Sb7-MVVkW-T$$j3&UkqZJA6cgh0P+TLbYLqpY>zJ9HVOCnpr&>7B`cI%0}yNI zkSQlvROXls8<}?Q9#JpdF#C!F6o#p4*nlowMMLdCW{gd~({<_z&VC4HMnyJO9%AYs zR4n^rg0GL?4gdrLn&8m3rYNiUoWWZAX4UJOW7Te73)HPjt)t3oQ!t?z;EyPux+lQ=Mdbm| zYKrH+k?>-AIv#{84Jiq2yRz`#Rzm!l+TVN#`LvX~^R3cF{*EK+zaxnBCeZW)&cegL z7h!!Yje=(kqfvtlw1kSH9e=4`d-^UurW<>>%EBv%Mx}Ti7{6CJ`JuU}oMmgdJR7;i zMO1EA-#ZD1wfj%s#ZF={zBF0te?WPq`-99$u5&(iUryYuy8|dYB&I2*&ax{?d-uKj zYM4RucbeG#JrZmRq$D0z6n z_{Sva_2^tBRFcej`Nux~9W0DKxT6lUCRxbJD$?vX%7~ATJ3-aw}JXyEC z#@pSxwz}&gz??!qX>t7A1$oYk5cF-)r;zE_RAwLNGNZabt2N9@CCC^A?v4A|H7a{; z0S4|T=5)DOwRYp`wY1H%^<|^tzv_bb7$VEFwzd=geHEr8y|$AQMW>Gmq-F4E_p>_0LR8}VS=!Dl zZNxS4v-b5s8SyugIrHyE`?^?|(Vj1L=rZ^~@3}>s zC+`iqrHCrttG4RURTf|Xk(3sjq-9u_l#*bXV=&m&q>rbIKu-_uvthV(YRdR;F_F~O z=#MBY6%T%8qRt>qt>OK(=}!fM4Gx!IMJv{MhN2G5pAVg{6@>|w?(cNLJUJFHmmY^fwcc z$q{CwaXX{?yTMp34qPH1fEZ#Xt6G6NIrDF;!u~sI#J&mLvZ)w>$Rw-UNeY2``hs$> z>w?ITyL7HVwCsGJ89j_&3YO`?=t|X zq~M;yJ*7q-d#sP%XeC8#pd3XGclx;TRb}W=_U0i~#y7@uEYbyp2j_@&arg6%-}x)& zs|>Ss!^r}`M08?pqNVUA)pjAehC{Ri|;#4rG}WWK%T*pu~AQZnniXZ*Wo7Xpi5Nl_oK zSrTiV@}n5620~XsdECNAC)clZXjVy9M8T9nm$2RF`b>q&!E+QNR)u4Sy~sRb*aO2I^ll0qN2A zm=OObh`ZMMQYzyhl-k6HODdVfAgHM9LD3426MHIA!v`STV1QR-ts$>cToE|eUa#Uw zxefSb)z5QGROqezB`~ZS^YKOYh12(W)m_dk8oNKOk?B~3PEhpLf|G__8NU{}0Sqhp zfM6|-R{8A-4=5zL8L_4u4@eVhDGUtDOEXNUJo?o2p6gWBhR-intbbz^Rck`-t``yX~jf*-ly<^gjCT~w~-nW0Ml{hT~S&BBwIitu}WJg#y|I7OOrFgbVYx8Cy%i~-8-`^rm2m^Gl z&qY_{<)K>PJ1ZI=!z#9q3SK*o*xtvFP+7urrw~$ONBaZLxhCnACH3BZ22vMhjcYpE z;yU&|nfP65jH{_BIXuer&qaN;W93ruMWsKp>L%^>ul62+yL_)#p{&ev0=2Z0*9|Al z)b}%PxHa5A|DBpY%wbcZ@#c=C{-T!ESh^)+SI{jwGCxGko6dDm;nf1t#MR6Smm~39 zMCpLXNaCe@hBVvhxvsUl9c}Z2up}p5f47usLD6DnKE>Pt|J7``x!~$}c6T)$RTk8Z z_wtmX^c;u(HFJ#8lEPQR0|>mAF%`HLDd8;V{I+^_&6PC<5CJ~c4d;p;uJ9X>YS z!V5Cs7<%!y%X;>!G8pPayzlenz}l3bvGJUyqc5)T`2J@gev2VQ{$&POhSYSoyVCvb z%OZhiLT$V-z-i-3K?m?OO6&pOb8Q8Z5`gk_dUeT!{Zz+BY%pI8P?W#7B>e-!yc~>z zrN|ok_k98L6Bw@iem@H!dQt4r<*;@B)o05tn)=|!20R8Tat)DmWCVnYXOeJLwgAh4 zjjR#hmcRe}wtCN8Gu-yq4?0?P#jV&0N_DQoel;iACBcSHOo>?#nyx5MhwBknYr4Wo z{gy|tZxV{1@yPB)krO3cL~1$V#`Xz02{Yxd-cMddD-rX$ENGVe;2Yv^>dmr~Xa0u) z?=_o}Y$Oc&AR2jSL82J5d*Rp*3m@oQPZh!u6!a}`u&!*(qzxUlE~Tj`8AiqICj1a1 z*EBleJilEzT5-Ng*l9B=!@%MqsIa7KnM5>Ez_k=bezjXQToC7}To{rd<11JKz8vB`c+op;ED6+6ZMyc#RGn`1e`tOJHO?s74Iw~N#tuWDs89d>~ zEwk_Npq5*zp$*S!_#NJlhVdpvPujBVF@etPX>mv^$=bwt1%W@p6b91x6}v@7>L8Z` zl5CRjVhjz7xEa*+dE<0ZTnH50y->nS+ercLwQP1mRve8JLVi2kzx5F4uv{)k1k&gx zcKw=f&ToFIPdWVY#r)rL^++Oj!cKPDgN*L9uU_K@jIe#z9Wrh4)kRwWB9{i2CCKw8 z40-=dC4}*b0jDBVWLDsHA`UTc_@H{`$^(w?FM3Xzyt@`vP6XF;+m{}8%auCN(uaE_ zXWPb5B!6Gg%+Ch4Rpue4lF*;k&QiWb8cJ`hR+;YwIs_1Qq;Co$C)&P#HkkHpGzk83 zj+y3gLqnI;JdvuQ{%H_u^UO27+xof(;4%l969!-Jwh1fPj2Xr2y#&Q~10R9O@mpF$ z;*8{{c@}x(t*SUe_b1m#A8R_&R*JTA0DEJ7+_PxdH{1U*kOXIyRW>6;XGT|A9AY zKY_mZu@#Ts+$E-;rWOM@<3d7vv-cI(a7dFTi1v+#V#JriBNnoHz?vSB$Jy^JR3)Zd z`>>hSRpPuGN1yBc% z8{0=Lvgc9tl#8P6NgaC!h>)N28buFFEWH#|c!X!AvKi>YUQUmPv$_+3t7xvt;fqQC zx}P)OV78c6XEya#NeH5}VAFi#N!hc6 zaZQy=>3WZt=!QIbNA&Yf&zQ97cgMj*TKc4y?3032B%&glt~~#3?s&~ZKDNCJ3wJAG z?nrIlF8nW?`|x#yU%En{&)hsJ@R@)oTz1X6vC^`m)ONu}V08NBYl za{v62uNB4UYMt&ks3mq7Iq+L!%JS>N#;J?d_afU=1y5kP`n*oWTxe;G{DxsETMuwM ze3&Ep3A3lukRC=T+&yAIO@`w% zP1j9~Gnj_bbL>~km$!?9or^Wn?|8vVq)z{P(ZUGFiHRLwvYMNaPlh9?^nOvTE`i?zlq^xr67gNN6y?=QJx z{g_*_#ju>eW$1W1S4V<{T=5g{C#>W_S(V$5~0ZR=LD(03^c?tt{AJ)X8O*U(_06*|4Px9BTkFuC)k;6Iy zEHE8|8jiD}*E8?8qkh*^yMVs~gFGNdY0%TSuV2Pb%JE9OCvWW0#g(RaM5=XW)vD{( zCYyAbb<{mP?sp*;XhA$_DWQNEjB?zj)ai(SU~AfOPNvryl)nRjB@nLE7l9P>mY;e)cV`h!39) zT)EzBbfMoYFnuV;-2ZF~LV%8Lk65uB`Lr9*k#D@P`45Z2^P+wHB`{SIeodG@{-lf7>lDz&ZR+$)`&xg2$e z@UZj}bV39xxsMLq?4rpQ#ClS3p?~>elhMY08Wk21)8ZrOn-w)`!Wp?ge9bN7#m#^5 zL0uEA^9ORpq?G@%)&+(j@vJj?sec^6MxNzj>i)KoY0*Gr<^$MO!7j+>BJ9SUT`9B zOw=b1D^QhcMyO90w)JmoI}VOclV)#RPO?@wo3f(xPV7k?{0xxOh;57$)yxI!DFZu$ zsC>P}@Ii?dOM|qxL*JrL&)!!Lbp0kUgwOTJGge%_7}l~s9Xr5Mb`~+(^*6fwqHZ7R z5J3I5vr&hX+N1chi;T2ev-|H|YIYva+lh6XSzDQfDcYv%ot+h1jkc4UK5>>DeRUYd zzRA>>-DCpK4F|sXcc5^6qeFCLWvdFFZ&M-1tHSYFQcW;4h(y%Q<1=e!CSn*o0%cx2 zgMH$CXJNc%>kDJQ^%R@McRG`e-MD<-ZJ;+wKA>Cb?=#aRlk$RB59>`!1moa1`~|VR zIAf0YPoxviEYSskm~Rp7uTkOhvbx11bug@a$zE^GCc99`TCwCZm(AGq zm3_h3;fDc4?e_F3dzp)c>>EAMDD%DhLvkfXH|JLM#8N)asx}Wcr`=*Dy4p!W31~Yy z{e3PR#qqkZHKkTVGD&>0dnIEGY322#GSl)B5p%4F&&3RuB#Bis^`{7b>pv&f1w5ho zA(zSNw578U_N}VSF|xVn520MC?^P=Yg38OsE}umY$MWsPl(cbsqzEoSyv)sih5+5Jf0dbG$q-;B~xZ+@_prQuT#?lLTbry^RSuvJGE>ljZ%BkKf~ z4adFIATqj=6LYUhH1j*wJ)^{i7odqlv`#bXj&Ar-&=A|qU@o8|09RLX!TOs6mS|T5 zJ8Wo+>v~eQk0D{;qXa&5%4dGTk7)Au-h4zX4bTQ0E(A3?f)Me^Es6J}p@e7YCM-dn zH-0OqHqq-Ax>NU2Ze8by4EZ4RNrFaryi?Dq=)r~n&zKX?a<+X!|IjgJped#cLJN-m zOc+xWplOL%>UpU>r`p! zo#`CUXRUX_tC=2ie)9&0d&#Z;Yh@zDm3d(Mci-y{G0fg{^oh36VBP8lGzchLH}zR& zPjFc17^?t3(3&B#ydd-T4JGz@5G~k^BcnB>*G3lRM+pN#h$eIi0CYmKh{X?}_nFow zL(YzIWZDDfStGa(;xk1zt|0MxG6#();21OW?}8Gqq}SH7>icJmQV2*C3UPpiEK6_& zF!VY*cRFmq_Q8zPn_ShShGDG3+w`7ciNYoW`9(*O6zgHi;ofl6sk^DaIso|oNp{om z;$64_nbjHLlMbDO_^;gwe|$SIQ~A71apQ0nL3OS+_E0trLy56&{Ql&%z>aY9!I3m8 zpZA0*ZOTQi+w&cqW+?t|GmF_87rfI=U9YIq)Yd_JY1OokYzw%AZ z*9nG^p^CC&r-gpisi$F4|0hSl<0iZ2+STR2soxySh5R0y70DZJz@gX0-{zDulG*Q86hHZD0`ZA` zwn9u27RbeCzj^&DJjlf({Us4H@Y>cF#wS?5xZlaw9MJ5R)KW`tQOUa)uJ-o-WzJH@pv=HK_dSWgFTS6JC2>7HL zQrG_#=h_dUrTLV)jzoSHa?((M$X(|SH zn)9XXeCU3b&^aP!P^8O8ER@VRw7-D}3UYWaBzBbCtp6Hzzvzd5v**z1hQ( zV{m&}b~=C81V87O?Ypu5bWq!DdtdT`q_K&DT@#!{Y!4OvU35YObwhOBdc*?6LrkqSo6I{*AiZo@h9}~uq!aj+K`k1d zevBa#Or>GN+?>T5g?F>%*wE{Sy|z9uF`&b!()Ma+zsaHW?$nFQMHoa^0xO1Yv2K za)sO05njvwg^V-f0eWM<+#m0xY;e^L*iH)v-oeP^n&|$};iw-JBP`wN1}@1a?I>7` zGx(jGh^wpX6DooB(D!J#@}uqTDX+x7{sa#2pltXk@KUzv25McfvMTFjndu%w_yo=U zm-1rh%xd+0b#qxl?^hWv3j74X*}|F?Xctm+xM13u2xFv987|qwF>-xsyklKOc!8P5 z^BdXKvV`D=GkD}s$FffOL!N+#Y*?pf-sP})>Jrq73oKXnx7sxtf)*k@_+^hRdyfPl z^P;ZY*DwwD?YwJy6_r{8lN}2vghc{kZMVKH^8ep~Y5S<$BHk0)I&Cc!iSELQem?_% zMVgmDbj?p0Htg{=Bf+!cv!o~D1aSIu1oov&d4?fWPNrCAS+9&ZW&K-{MeIw*Z?;f` zqG~35?hX2OMD;0p`i)dPl8|b2>{fAnTIn{$SsNkc>B*|{c$p%McR#7?^TQdr&4ZW0 z$KKZ#8u~iAr?xrx*#d4s32`>nHWqu&ZiIQ${(Sl#Cs2noTNEdlX5Yc0ZB0S#Z(KQ} z)$1NUxYMQw|C}iRwPK_eutgb|U{xIYIKFTLn$K0=V8@!yaH6#oGrz=FuPp3CvuZ#w zPsc^ns9mm~n-hoe<+9Nz&R@}!J-=q3lo8$=cO{q@`G8X1qxZ1&|GNt)-h#{O5R*D? zh<}lcH+>~#B|%?U6Cb+o_we>r#+0ts#s4C@SfNpkJR@~+Vn8$44zT?4g+|gDv;Xk@ z(Hx>6|FGtfAOg%UIxlHw8_ay>6)f+~erl}?NcE94EYC)%CLRw-#+iVX}FH=HV+l&<8Z zHLMhXB5t%HzS{Za-McX*1x*-@B^JPpISrBU+IPoKT#-=Lo2wI`c{^dx7?lO-#@s_-Q5 zY~hGES@Fm1WHk3g$LcW%9DAh zVIM5ai_1#L`DpSG3w4xV3@(2CS%4fqRuHmu)FfgHM)Gh!prmP7n{ON48gep=>cPG=oIp%OA`>)vHztjIb{9|JNx6kIz*hTFg*pb2dj1vyx(uN!%uG*!cj%A zj5T9$LUI4`a>kflXls2U2ydK$Z+MY=FS__+34@R^2qF+( zBh;=hQCPL>(V9Jro-K{BjoGR3390))Nof2Vf&j1N|LhNq=s0A*P+o9EsJ z1WNo3+h3KP^LgpbnY8;UwTXTWGQ$I!2k5E4R6nna$ud}@Y=k%z$%JBK%hw}{<1}+0 zasNIkDi8C6;jIT$0HL?_SR-eRGLf} zumW3Wd;t((6>v-i?#`Is2zP7XQxBZG`2#`RrZQkV?bt;6RPzTIJ+na~Gwws6jpA1sy5vjNK+ImYB+95q1%9#iJ_@l(ivl z@5sm(TwF#bxF|ch*Il6v zQ8zH#-3ZLT`{6G`?rX8j@ep*g?xsIhY|V`DVi7XP(E3e7NT51Fo>F4sQa`8O7_+P0>W?rKIqg?r zM_!mpxKVq5&r}iIyra?PQy*{FlYQayXP-qO$d6UX2v`jLAs!wo?SBb!U7x>NUF<*? z?yeZ-krVSi7TaW9fRfxG$(#G6TlTr*XN52NbD zG*F>#=8OizHMy+Q{U5Jn>f||d;V@@u2i?sq7W%cC@eiP`_ ze#MF8ksnSl6zq0fc4~4%6{ERe5F# z#l{g{B+Ud7mx7_h=X`oP6f~1E7L+KSU!zR|IIvQE3ZqXjYUlyIW_D`U()o87TXr6{ z_PIuJjWRepF1!20iIWl#cc;hC{pecLmGlXo($q{gyL;`P#40m~@4i%?$d3{zhd~Uw_ z48>a)z%-g=m@LPlxu$M=0{3gjkE*ud+QdjvHFuq0)=J7%*r6?mG662kJV?f~55eTc zdw}b>DgQ)mlTi0v+x!RgUtdFnskkGa6VeG;%c@<#(8iZ@uzg9unu!h39@>FqC7js0 zn_>p)bjU-`qL&Cim&3kfP!c%x5J}XKOOn-3wfaOIF}*WY7BPU`Uz0SGHb$k_5XYJC zseOA5Q=waxDywIzarNVCk84kbS#;kE9&JGh^dE`%Xs?)RSc4NK(L!U_jtcy=!ci`C z+9xEu?^sXkdzTF`_`@QkqGpaiL!1B(=CiwM)mP3B4i*0Wo4aVZryxZQZYg019wg7G zCb%;R*p701c_t>JqbuEpws}h1nW&EiSOB|QBFzapX6~zWLdGQpozHq$Udn7j*kuo@s46bca4-Ngyp?XTX;yQTnMr_O(ua@!6|5O_KS6Atxjwj2I1+r4Jlblj zg}D14Yi{Sz;(yk+cn9x;D5IV^I6k9|9GFB{Rd_St{1GTrKaWef_*Hx>@<3`QH49vNT)y2U^fXvf5Ek}BXO{?)y+pr6jqRWkY{_PS9KL+Bb= zlb7@WEt)6>vm4$Jh*mqPzt?f@m)4h(X!zkjbzVXet9B4To<6C&hIRI|rArS$+cW%j zt}Jk+GdZYktdEM}$DL9aYS0^l6F<>IPmfI~60=8q<)_V2LpN2X-%q0cwofz0iMaGt zzTZz8*@-xKXOgC1Ub#^qb%nUED7%mD00_{3BmS**CqYr1O>jfNs*6X0mo1uC7ei;7J?K29o1!zM zDu{Rft{NRoJdz{YUAwBrSQ-%p8lbdH*^>#&PY-#kQ%xt5^_E!k?%nofzeJ(%qlv#N ztT+ho+e5=&ObH38XkOw-sO#Hl)rGK*xP=_0;A4um3s=^VOU1#BMgtG&dPY5qv%I>$ z1TK`IfDAI`)jUR$%y|>G^K7K=)RdLjy?n0T$^pwYm&lDFN!$w*?O7IIQA4DuneVf< ze+G{J3xq4H-ng~(>~T9ZuR4VjmNxU!nJ3p#sTXzJO`&67a*z}!^DbLnDSABaWB%vs z4bGpxFUlI8%o$iIyuGPWQIbL5iD4$VHYN*PakcJgm6^E#Gb<5WYRxo+*i%Jckud;j zZjD@sxC&(CW2_;h=N*BhwHKO1^wMk4F-x*V&~{gdXgG%Mh=H(#PsS-bE_U68^z;>s z%^CtepWliR>w#hBgH?*oqr^sc<3W%WfJL=MR^S6=r6MA*9r>uVyEB46yi&8e(W0#s z(7}m4>*SX;tv1|>Pv9n|RG|LB?7Q@0=Fx`Werec)QGc2Nc(m8|CTYYc5*|LJ&wg(2 zOy?c_k?@!(i~w1QJnr@wnUk3r3l&G7fizL7XbNnO z92W?XL#EA#Rge4`L<^;rt$+2N#xO*T#tc}32~GJ!OjvfGo4O^he3&`1fy6|#5Ri0@ zD-7?xX2>uppPdE#ee5kZ)XMSB)Ldioi7Y{xW^*rMbe^L;Z*+j({1KfjVXmd*9vobI z=)NB+1;ldiQeX|itgxJRQD9cv9>RcGje41x>;sH&pkm!!R)Up6Abx`yn3X0#JPlZ} zsc;Ql|HWpeaSDDIx6UC&>m32;9m0-v=x@5NBK(V4xU42UczW8HAA&(`U>z_beASHx zdeqnIzjRONlO5AKq+LaDv9V9optm#j9NB~qe|XpsXE;h`GyJjFjM>5cWmtHAw@tdtS58G*uUj&(u;8HN|fB-ma^)?3z=WBHFYc8H(-xr?WB!%{OM0ZV$vR13hZ zdgj(SE-T}M(wYI#9}y2++(ScbEB=9OYfhiF6fqp@jch+D&JtlmvGGf=Rk%DDCreh0 z=f0Kx$ljTueyqSQ6w3uCOu8`c%{c_0OGZmEusj|j+qETn6DMgFR^94;a zONUc1gWfp}i&*{(?6V!My<(72diCJctP}kWs|?XQcb2JkD+F0R>W#C^;#+y|>#SGP&?}vN$cM8dDTu}ao~F)0*La;U%d_rEiu9E*!JuR@3upW0`d3r7Xz}=I?=_JGdrucA;d;Q$`-}qpPPjI>`(G&?1}44hzIyimT-it-izl4n{65D_Tu~MNB`o`E77SEHWGNIgh z%SPw-mv9wJ`2pLLpW8>)N}bvIPxfoc`b|(4#;}S7EOgRJ{jhnGUBAJrQ-2-uFKzc2C80>eV*po?Y|l z_hpo{rY7)Ik%C5TIs4an=qKV~XgDkU`|!OqY>cu5B_IzsO;Rjzm}~JS4eV7F zQbj=s*>YUP3Nc;v&y5_AU=T@v3dMmP_=O%;6}(D8NT*Ja?}w`GNGI-l+HsFAb43O?(5w3!xX z{E6bWqg{08Vo}@*+_g`8k|wQd7aGA1qUleHHrXE!iMm>3L3#(v`jypX34`mie+H}~ z0y2J-G_|%?{a-C~deCsj^ax1o0>j7@l>i?rsJq^63g9c5)pXKfJFkbss_8d~CRA)qEQ)@b=8lNW ze8asfHDJE7C2_^i4kU0$@FsLCJ~fsS%U6^4T&HnLUb$Orqzd1;7PCZEe+I) z@}_L;yiP?+0N03D=n{Vv2t6$(MP;3Mr`5_f5WH(At)8&JAw>c%amE7f?9n@L8|AK) zj-v)LuJ| z4pg#H1XB{gL<~kLek0*1P~dWxZP(+zaf&U1Owi(%G_G!>Al|vXGZYaiNOy%ujS(?Y zZ<T5R89QjhpH`b(9>vJFOjIlWW7N+a01+tGU5N;iEjE&`ex1|+5z{^xDgKQ1RO>(BrL%KpUya2JFsTt2>SVn#*K$xXRBZ{?|T`OlGXTP>v&pS@fE z?RLCmn0y*>kAdMivIpl`{-(Sn$=7XTXa!0bf#TuzM+%dslXnYuV3VWvOhcvTH>@zD8Db<(Q`B7) zPphTDwn}44UfU)3{D)2Q*sBh&w8xhpeSP*vt!L^BpMR}hK$}Wc5d#=9Ml0|9CC6i! zX}<|-KnssxJaT&&i-q~%0+WH$W^$_(*e>;-fSsvY!^Q7cZP;+W=08p$zoSA_=IJzl z*(+JS$&!*t9%VOW8;?n%58R%!(D8FGZtz1dS#PdSYyMj>z4!0Tg*|GSQP$vNxKmY! z9j_JZ(3NW#HXZ)71z8YiA?uz`Hs&(-j!et5<1RT{m@mur(3b#Z!Wh5T>L=^8<$t;b z?+W8ylsX%2rW?+f2gENi!H!xByQD|dkO!|dH#pfrM%5;`ld7ye#EbV`4e6nKqD$}3 z@#O@L`rWmagj>>HCNf2zDL$yH*ZvP4?P@yW1%O)K^Xn*b^wEGCM~qPJF*>(RC%a<; zGOw!fs_U-O7suP(u!Zq|MBf(YO8d&q|D7MbzA?h$J9-nnevEDkep^bEc}ap0SS_<< zhl@7>?>s$i_pT}%_&)?t4AUb((G5=Gb^v;VleiXRv9|*Y^mu83|Fd92P3fU&^-1|n zIKPk3f5w%CA=jW0%+%4~SN}QCva>Z)M1V6lOy9inyNt^!f1=Oe^Bj42O(&XRq?HbigA^QMghzSBK#~x8TGJFy}j>j`Lv8p^W`#}RF z;?(bJJY{G>^@KZi%5}?E0lCG$@WU*;nN|cW(MN~s_A_oju1X0ZC4z0mlbVbL)sIjo zGu^oIhN{tyKg_atF-Z_>jRQ8h-XJE4EQVQ(t?NV&xUX9PH9`j6bsmis+d zIM*55&k(@5(mwL)xOSm4r!R#Xb^-TXeZThXZtSgpA0oz0M={d}p4G5uRLT+)`eOp5 zIp&21Ewtqb<>Cyv_oj8cF?j}+<<4Ix8?A1RgVUR9N&<8M4y^-%=T%zRDjnJ-9osKq zrp>FU=~7up6^)}e)HK8uEy?!DbJdFpbUW4vcJjns$w{TMr;bQo%m3LvZAol?h9;&u=l26OSK$N4GMzO%mo-Ne^GmstY!{_I z%YB9WwX=^W-yT1FydSaiAqg7QZ_L|DuT8RJR=PgG4|p1RmH7`?G_OF*)qOa5foZMZ z{HN2;NOH^_vZm(`?OD93*dPPWwus}+d32eq$Hn)>xZh2whyOt?5LBG3bIXb3Z>D7j zA!xQMnJ0GOS?rb&*hE%WU$G$h(I+o!LGn_0ld(!=13%ceM$GO7 z@ZNe(K~q}pSohdf%~gnvO0YEv41LU!gEa1nEsvlgFuSJygh1sfA0?5O3--1vi$_dD;lt%Z4hoV0wJ*MQ0`Ue~!RP2fPW z%>~TLZ~8w@?=;yIRpt+qenWQ@yqGk;YwRkibW~{W^Q9aaQq+)`JoSP6U%RHa_}%P} zbZ^oH?R>UwyqZ4|>hP<^i2jK3D`Pb)#mIuM;={EVV2lp@62g(#SQH|BsqjoT?DKY4 zp&68F9jm59iH3!PaSmuUoZPG8oeTOlJ$7|a@5|`cJ-EVAz+J_7vM<2eV2HD}(*N|T zactYb`ku&kOGM~i)XIKUHE*d@=pRt?%Hh^}Nny~Vf5XBSrltn>Oee;dg(_TzzegLJ zD5W#mitJ!Ek;*$f-E{6;6l3q4ncgiVY!2nkRSyJl8fvk+_?%BEvK-snO6|`Nd=2*O zZ`=8i)sf$SaYw_^v3MdO-x+9HCD+xJ4jIiKY|y_@2>f#<3{s8mzO~>|bT!0NDEI8Z zsWzEJ2g75?q|_%*4QWl0ge4kERsJ@mXN}&*n3%oOXF6Ay1D`gK2{o`%TftE0n9Dma z?w>Y_ABVszIhHvCPL12cud=upRY}u!EnpEolfoy<6gq8pU%#j}UAL#mURQK~*yol$ z^McvoFJo9$x{B%9xAQ+DRxw@3s@yj^3#;bRhJPrca1d$nrUZ=F6jgNBDlHJ*VO(2j z9%hTTh&9K?boaflN!bHx&q2OkH|}dtMr)x~2W5eNRKp)PzpUgJN8I%NlIk#UdiUb} zxVl+10t@OEOUWQ*hQ1I%`?FtO`ONcs^aq|fJ1rK)CI%H_({Ks4bOwumkQsPIC(Xv_ z6N0SMSwa@FC9@TemJ^y|W&vx60JS}jETJa(aJ7npIHOK?a39Ij*?7>{U>JeXoahQ& zCd3|z^wK~nql?XsY#w4&L5KFR*XT(TRrprimCgWu_flP|(MOpRX8pKct?B+XZi=2w+iBpTlCYK!D69P9=#4ZXh=6-O?ySg<3T6f?O8B2`JBq*E+9@2@Iclu`A-DqBi5ihA{uj?i zp)T=UN51kdZP(ddL%LqZ_}Md3AUU#+!y=VexNx9=(*h&iMx$GTfEr!BV|D^*liwfn zrUb^ct^oRDqCjQW5GA0S;W;Q@0#{12S;`&>y>3($J-3)qVIuWcZ3*1rCyMU4b}X1* zE@Mo-HcK+Egusn?!y)gEqf|NEj{(x3aAd{l$$R{$IX2fw@C;^(7Z#~j21slVs# zT`7P{NwM^8O)Q6oVo!eSYgrAlg}{PSFce1FIU70?isMXk&de* z9fu03|7U&ML1S?99t03$D;Q_2u~XG0NJyk3#8{ebiyVP50VfniQr%=2Z3x#*_))4UT@!Z_{PA=HK&+tIXatdhb9xbSz zRhw!2fS=D9MLcx>W~})%_)K0Qc`=g}La<|1@>6>t47GNKtg(YqES=p+twlDen4Oa- zWNxGUn3JqHymK)k7aFCw$xhSQbFDe+@bQ#+S4h$pJD9uPf1YaTjYoy!1FtC#>ZqJa zVFNuGg8Py z9Cak##LMj?U$Y*1^f@f6@6MZW+rK>F#IMF+nErnb*1LZSp&=b!Wz@JMBV~BHEy9!{ z8s<;QA3RNL$bawC`l*n~_a}8hp0I`$n+jX6B3FTJB-_4h$vau9NCXVN>voN_`d6&H zA?QE1`WbcE$@Y8ZWm5M<_xJfJ>6p`vgpEFLChdQ`eC*_J=M_kb9Upl$_&Q_y949hb z8`J2vei4?Xkw1;odAf7*q3?ck)eVi)>Q(BQIKw-(x#rBpEuK9*{M2)9g`xq0#Nq5> zd70qK!t0yJ`IY>!@n@7ZYHRY8%S>u@*%aG!<>((u;r9n^p2eTWQmPv=vV%5?EcALG zoD@0#D$b)Bx2>r8sIsz4rK9{cSAkF5?r8m{eBr9ptkj-ITPbeA5R5v;b z(^+o$KQBOi4hnxaiCZ>9V;8ef^8pvn6lZivd4BzUJzYopPe-6xRn0LmCNlW$FGa_t zw}PjR{Rde6qer5biF^~KQcfu#Tx5jr2Q4zQ{ZWDUwa=M% zUUJy9rMbFIjg=(jJQ`c(DzEOyw#ch+-kH_;z4ldSj%G|h@G$H1e$VCmNb3OY>e3en zGIV0-6l~x`92h$6JepJJO>9NkXNOi;^h93ZBpU~@w}iw5YT#g#v4>T>5#&VwUpn*& z+A2N3lZ?Y4tt)L>{WwI)M3_=$^4~aM$A-omRz>^PWk=N9&!2+K-^l$n_TtkG$-Kq!*4i6- zyhOjTPXJgTMu95Yj{E0te>9OWXvR=hPN;d2?1bcTEC8JU5CSvTSU#qv+Wv$d0X>Z= zz@=d|E0BQ|zCJa-h4zV~(%OZ|odCw<>kX-fG4O%t)3Xm_d}DT86V)Pmc<}27N^#}l z{Rs+Yan1Cg?oU)v&3&ec(!Q)30z9%hU(JvN3hV_>3M|^ofowtgyO?SDH}d_&|4^#K zn?e#rKO?){!9%o!BZNN?EJgF!4$ml80r|8$mQPYnSGF>_zt=rty=?oM5K>oOu2TRk z%VQ#NuKrlrsBamD$0{suJ2lk=p6C~Q^t!NKICba8!R2EaL@cPF(~>P^(n zMM1)qpwNuta)J9Az^kIe`r7RaU&vqNeHfX*aYj0Pf`4iwRChS)m716_#*HGh8Mn~U zvLsm`|K}!JjK2|ldE=8}N_v|v@Y4D5>o4X1Li+B+MCQx4_~a2T5G8D0!o53@6d*Dr zF>vEym&|}%92Y7XpG(^f;I6u{MuemSn2fk6tnUg;7$zoI&uWL5Y~?_i(g1a&`K~v2j}3E=O)Y(PS3JCTG@nGuBO+G}kyIU5brVHc^!<+!$(*&jvLIrB%&RJ)q?2hK*dpAD}9kvI* zR-K)i$?D3QXbl8v671Nml&m7{)ev&Me=`y84U;V5K2ETTu4i5JFRnwt?iNl}K*$#O z#tsB>q#jjN4|#W!2)thqRe1hN^;q3vLr{fPnDuD4t(C8uGw5^c;;Oy`2{_Sm*4_Kb zk$IgqUx1Pld0E(>MafQ}zD~gBrs|RkFR-i#HKqKqaJrc*0EkJZ?sWt59fX_Ft z9)-sh5^&*MK9qsVF`pb?k9I8xzR@;B@<08@(m-#We1ASGaQ@p= zcbLt^h(_knVnpy_EkU1WR<$&L2D5*cjT_X>8Mqe_%w9Yy^33Oxv1D%0(<|re4EF0U zxk>w<9%N9chCMlj^%gY5XCho zCL%<6>FAaEO*OO6FAeF-v{jgiKUj|^{*y@w3%#}J-Gu2o@|CfT^TCq8=ijAp`3}L=}}}-@pXK>cu?q=4gJ7MDYvUOo(aT!T^i$FW*?9wU3-GV#xR-I+fVP{iFeBQ zZ&TBS+4m)8^kb_&VDKg;LZ36GfmK)jh>9m-@{RcjUFyL^O;w!VpYQkR82L)NsTLd&VMX0)zqFwA1e{}9{?hpI@6rZJ(XjdijBFa zjSMJK0#4P@7Gb5f|E4w^n-tVy@x`7p%2VI2Ny9d^902nLXL<2jrIoG?#6?_>|1)NA zWa(LZQj#a>2=)mp;k=2aiA3j|=t_fRn$<`30U#+e`v;gN}%GWpUO!TGX z-tJv!;XL2pnPZe(4x?L57aJ1b0hut@_}p;jr{Q^AHvDr*Fg(@S-Zz%3f*r~ZQhjS0 zTZ4G0PNb9-@HXBeQ!KI7C%@^_h2~fRI7cL5WkRM|H+<9{!Rr=YBZ0o@7+TJ^Q5x5C zZfy7w4QCj20d+nBb;)o-C*{lK$I;m#KrdA1oG8z#3H_-!Tem!rE)7kN=mr{&>`H5t z*toV_q-c96e;44oaEJ6Qr*q?hCXlEJ*ya{mm*+@m9zou)cqMO1LV23yB6?sJoyywjG z(rb8a29Ii(!W}L<@>2A-xA*)(uxuru8Mhfij8HKZV&flzF+8Hd%iICXy^|2Gp|_MW zX8G9Lh0&O3)rjt2Z^k9zbzL&%8j|~L!z%zSIdj8=VN%Q$Kf3XRvX8b~>oD4*(dNsF z31v5+itCM0+tQQ+wd~Z7)Y-RCsQZQGe52izWM2;^(f#8SZ?AXQ> zD#IdYB*CyM*CpO>d63yY-r#HcND>yw3r~(it1}6#*OwM0$}>zdF8@W^45Q)HFpj^R z4Ez#nTjGh93USr>eN#O$3f1gV*}{93%Ui&@C>c1J7kHRp8pk=Xo?9z)!QZNMe?8qh zo(rB`sG|Vq*oUpGL>Q!q!!FJ`g7WsAE&0)zKMldMN!ZMd+Qd+NGyse)fz6!6{bCHq z1%X@Mqcc}TOJ6BtTkd5#nqXd5rV%^%BYx?c3ZyAxQ?QxokN$y^Dm`ssLI(n!0`q49 zI^^9|smw#u!grK-O8SIQFlXl9T3xrfVI>tplpR$3%}H2F6SJbI(N5bBv_0Xq z@g?Y*7DJyv!ugBjuS#ixk6gA)s|vO)PbEP;=RQA+%Na`oL6QK1xqQ*FCU%bkR4a?5 zlxg`NGgnFv;p0IH@6y|{bi`GW+)M-<;NQR1MEaRI);#z}d&_gQc3@Gs0($MP({D>4 z=jOnlMu8ZLH?N~dH;sSQ8NvYuV4n?R5T+Su)#`7V` zh_%c`xC!-?MGjI-C{fJpmUb5t8f@ZKm`DW_qola0x^bkPZY0l98eU%4THS8e%w(G- zTfkq|B<+nF(tdE`qMj&|J*4ZgL)1TTnA1Bb6}$GmturnCTY04G6{Qx(odiOcPZ3*5 z{%o3V*rNL)S+n)OvT})1p~0_T3d80#_h;0hdeHy0e1h#Wr>RzIR_ZOU1H0VTJNbXw zgJI|Y_F!|Z?TT|v!dMks{(*!_N~GP$mJ~SoQPYz;nY(;dH}&yt zZQi8n=dR&LWf%zIEhjnkRj_WCLB#0TW37w!>jm@54t{rO8PE65YpD-#l_drbdq+Xz zC>pGEuzpps1DjeWeh*IlkwNR`742~SS??@p95jB!0k`!fIC+-W-sR5xtB#mZXgqZs z&VGj@?=<33ouhssa!B?YhBR1Mncl~&IL)R6Ww+*Jo+d7(K{12RS%Dv0=REJ{;pQP<@RW<`AS`=l~UEihy80?0j`hE zPXaAEh{^Ih?%$`i9v&$x`u!?MkZR97{C%om75I(aXYy9N_QJ*R({;_p1+|WoNss+f zmGewKg(L64%}*^GAH<)2QCVnBP`+4S+y7RoV(;Ia+jWrx4Lk_8ykQ$X0RFYuyCSa6 zezqPJc+#KGF}Cu|RBIV2{ec12AW1rM{vsNogt-XSxm*Y;WIvl<`TJDEaL)tO{dC~R zllK?-?2uT`lov`pO>BKqg-0ry_m|B$dai~sWgi8NvyqO(LtUw%d(X24(|$}T{^uH7 zG9G$cTW8~C{%7f%oaIn}u9q=+3l2&--WUrCt_#l2ch%{kic0#TIxgDe_hLqEN)Pgd zquu?q66N6t28cgRSxa8Bz{z#%b8My;BBrZMz=WPM`ir*`j{FW|i&AqdfKlCc%!lP` zvSSlt1_`s&03JaGmdrT*eGf*BPc2E=`O+j1%0&&A@S*{0avqt8CLUXzlCeZX$lpl? z3-|PHOoX3e^t1?2D=+L&QY`{}NLJAS1YrXpVe&)&M431zBnQDi)l5;M684zD--a4K z+Qnt#0P@OMp+6hAKTQ;h6_OAaEivQ(QHBe~>_P8!0gMRpEv2#5tUIPgMuHJC6%VRN|E=^H znwX?h;F}%UYy|%>HHQDYOijL@)+S({JVHSn(PYjC4K!sKzEcEmk#CP$@=t_k{?TAg zYr}L1Cms4o7M6qJb&ywcl(C{EQ_POIUj@9snVei}66s&j15B^lM9^#0=1MS=*va!1f5>{Hb%IPurL%KbHEiSnA9d%rXG?pS~D4Zc(`0Sh_$NG%-R7aRcqpXF(x;v>1&*5ozAJ~v(} z<*(!%Es99V!rCA19JMw6dkk@U`uO+$PrnSqw-9_uW5GNXp3^{z$O-l!>vF+P6ezll zui}IFeG)c2?u3-kr+*3;%Umi+Y-mi(zR~S|C3`ncT@L7mu1$2(-Xj}aKXh0w=!7#R|@`&zlC9&7!1qz0muJP_U0+-o5&5J#elF0+V>p_SJ&#^A(+zQYh{ zpEvxnM8G-($}?eY4l>5%>1djC#T$DK4Tu@IBxAS!d$ zpFXAC5>b33hD3i{gAgz?x9Ptc%^6wB^cgS=ocRn6Q{*bcU=%>GMx|i!zmG*JT+^{V z*b_p&{`n^Z*(2%pnLB9e6N2aq?yqk;Q&&JeWTCo{kA?#$r9qBs5WYJ(THz|H+ruIy}SPhLi*>1NahMSygy6#%5dw{bk|ZZzvI&C zWUY*QV{%2M;8kAB^Srx(tV+j6lKT^^xBh8gS#o;0tJ=JMwQ)S; z-?`S>)u*H9Oy4ndd?yH{;~z@<-`_p`!Z5O+TB<*H&$D$`{A4G}#>j29x~%Hw4Nyz| z-oH&h9pT4Li!BkzP|^It3;SBJx>6}Sa*nD;{seBh?%SHGEwl&!|7be%V5lGekF!{d z#bUART)CE#btdOpXU<)BBGyerxysG1Be`;ya$kuM3YB9KIdWEx2qi}(NABbI{(NVC zGsa(L7`wBt_v`t3KA(>Z(Pl@w*95|w?yH?H&BgBaKb#b|yO>P~fPNrQvA#fi7x^Y< zHV*#`<%C9*a30NFUKqGP=Qbbu=IP=l2yQ5m@*5@#caV&<>rh8Ud}22~;Zf8{aO76| z^qtj4H!pOSnd8(QOb*$Dv`1UCKpH+=b4zeIKMNdxlS?}F$YEfl=cHydFqBZvJg zD)ct7-y945-jfGtIT_Wkxn>N*w3LS;7T{=E>iVSONWZ&;s1IDSFfK_5Bb-Ya%t+%N zPf`7Ec=g;w^ZmTSWkwT=XG}J*Sz&&nS(kK+Kd>>bI8`k5f{R;WG)0pO(j&WuMgT0A zDe-lnXf%C6=84U96M&7Br3#95MlcQ-{yd+QDeD2nE{O_P258G9H&&q>0XQ>lm&=_; z6ae#yRmzO^gGANU%~$_p=c0X&U76)IvZf#YBA0uc;~)6ry?yX_P4UeEkC4J7Ivn|@ zVO1RGbL=D$b9M^9XTA4)KhbS8ffPo-dkDp~Ap=7mZ zOgGN`^ftvXG?Ua&qRryIBNHaB4xHPCCOfhb*+`4i~y~s2Kc!bUrZ1Kl_25^sv?FgPxjW>^^XpAP+4@8 zpUbTbkWl31zA~eacu0xd;j61*$eZ#uy4Kq*)RdE3J(o#Q{afp0#SiX?AZ%s|ffkQTrbqcI0Cd=77=e2-4FK<>*l^*u%9voLd-3{~z zs@FT(K4J&>otpE+(KjN<#G*-<;2!I1aI=10F25f(c5<2O%(-jay72AFR3U%!pt2<4(( zN|o}=$*Z430g911!K{$K7R>=<>2wM*wZ2H+&G1<+vqVi;1QB_XhUdabsxgmD-^)UIetgMMR`ivuqT$ z;lNuSjC{4~BAs~NkhloRVxzi#QPO<72P0Z)LMcshvL1Q&C!iZE(D4^GF%tz4j5D2qPwkYM@;~%()wsw%>N`B zX&0d&S~d~R&#Fv={Fb&hUH-k{V3|o`YYG(C(=#TFeozaI_Bjyfw)QB~F1C70pOJTv zpx*Ipg6q5SuzE}W+26dD-QhRcJNx;9za7ROPyvk;r7{Pjyj=-%l3cEsEt8gMo$pA^ z2X7F&-}x>B9=7h@2f+gYk(jopi~783pK3)Je?5{slI{Oh#2&Q#^|her&7q2)d0ptU zGY^IrkMcD|GMpl}c5xeg-Olf?T?8|GtQ+R3zR+MkJu!bjTe&c#AdG zN}^FE_U7?QS~M3U4Ug=&MwZg_?E-w^$RCcQ*BiY5{#G7dT|R2v!HB(m__!O z5*SNO85Nc1vLYl=1f1(4+&0#)`M;25Y-~MCF#Wmx zu%jMklF&r9=3hta|FW|h4G0|h!#YhS+_*~Z%Bm8j$Opu|GfkNSng!LbpxCICeCJfF zYHKT&26C976aki{5x~9hHMLfnA2R;T@%g^ZNo3UUBl0MfX>hwK7@NR?YfAF^9$2+J zElIxWnN64#TzBnX4Ltx%&DS~$C$$?UE=#JA>mD9?7eYynCUJSPYhO&7KYJrVG10db zT_^s)Y^fTT%kQaoWse3E@;u^pnae-D4J4q}zg+!@&0X1RVyd*Br)1OrSv_Wa&l}3O z-m$)gvY}vlYGY+`6*~AFQ@H{qZZeBe=S2}REw?!#kBJ?!6!}3#ijpJ0n*g!EjfQLt zA`3GMGjq6kWn({SvP*UuEqyV;+(P~Wg)Z3)RK7yOal|GQ%I&#nh7#E8Nv9BEyN7|0 zwvUa+-9P7c%+&r4pH@B-_}(+SLiE zCpx`M*eY)FyOW-8}i(tf> zoD;eU1q@lyxZE|72|wh7Dfw0SHj}R=#?eb$q;Z~)abYT5Tk52&A~D}5=dVT+seDtZ z#n z^-f6D_dAyDGAlM?m8LDhqS|iJy@2)MX#r#EqghRI?*tWXJQBu-V=iWqg~-Cb3?~x0 zo`NDuCiH^#z5SAs)|rotr&JSvnRm+Eelt(o&WjM1>m(qay0B|A1B(^cs6+~AeuBzp zv1HI9UeT1=16&pYs`?qTO=bV)DppW%1orsgJCgD26Y6i2Lzin^FSrg1k~kVmp<+CI zZ5qGAZB73?vfVE6=U#C{c9Orz>Edhz!6>e=Rff@56MD-2e9iutK$H zW$^FL`e3cM^wOg1Q~*6CqCpMUKAmo;VJG)~TLO!}sp9CFPt;thOM%2O zfmH#a?_ExBc~t~Hr@@2CHgh%(x3Z+rPJHA(Q0(O+&~QkDB`#wV@Eq%nTlJ4S%bv%V z+qHcdKL00_iT&64TgITxO8=v|)?w4d@}D@UD;tPVW* zdNlY31g-m7ZZ2wx+;#dOhu->EVB(yRckNDPaE-rt7ULa@;7c4g+*RA+7MM|QbS>WB zD^97sH7`u!uez}K`|zKAZ-W*1jUnTu?Un$hFP5-5(I{hjurA}Sn1gg7E$Ifx;W$s{S0LiDpg8f08=7o}Se|ig zhm~y|IAa&>+h&<&104P~J9NTocRs2{JS!)e22Xz#d>lUbcR!Mk z#xrw;Q{!|?QDf*Cy!5)T7RcuYVq4L2c}zF%?a_11>5h)quDVe{gHWJx%DiT%E}4<< zlf`kRiFP#1plC`cfX1!7B8Z_T5bjy>Ta2Dg`D?2rab-{qM@{joiuaR;<1Fbb;Pf6R zu=pzQ&L$J7kd6}MMbu=37}__D_*R!Z567*d`ARdU#djb21XNDy@motY0zcr;UXcQl z6sj(vM$+Nhr^I)GbdZER*O+>XIuHAAQ;sSFPs*fhbmtw;5-2PM50rFeheW3>RJtf7 z(?V1510EkCy^OwKv-`|5LgNx zvQeyv|6pZ81@Q^g*28*O>P#An8|7k|xGup^+T22pF#J75RQHZ*aADH@)TQw!e3@gy zj=-*_1_hkaKnJ(nj|0^|a&NU(=yx^w2W5+7r)0;}JSff~SmdCI1i9tc5B(Iehm26S z;BkA3cf*A&&pim6B+xEbR7t-6nuM1sB93dW#C;6FbPh7rNTM-_SJASw@~&`3Vot3c zHXO&DuYS}UAsvnEU~z;H88ESRbaMZ#FQh3FQrm{s2&Cv4=fOG40-z6GeX1K|C-S=S z)umuk>rxY(I2|w4JtB&{fa%5-*$sFYT`Hm24%+qK9OdhBVk8fG#C=wdp7mx08f&5f zrAe3hxP_6}FY9GNk$wyg{q~WH2<_Q*kc*gLItWS=X7j0H6v~I@!^b5f2`fE)3hLGe z_QyNWpS>S_o3NAJ4&EG57_VqQzR0!*CtDU;L;g2RwI3JnSPFS3zRcool6d`~cIHz< zy!6a)j(umr@tW14+utioWNM0ASc6mh&)<=~Ur%FGS;NATqW>1qrM~xboUfmI#AF)z z@BHcTNOn0a=ucQ2Zj#7dRPpqtcL|kxSki!6HX#}tRU%cjKdIX=)O$UjA6M|a(C;ln zgAr>H@0&cym#o`?ngF>R5aB??lnv2AtC`9(9ldD0Pf4q3u7JiF1!_O7!k|Cw`qx!b;V|0T7iTonrsDv4HGbe(PQ zTF$qAQ6@Uz!D~#q*)*&3G&Fcb{Te$^y3&#*;pfSYbocu{~E(vtp)kIf*y8I^@zV@Ml)rfH+2U_1dLlJdlqlc`~Q_*hNm zM+8Lm4b@M^9I?u1ei9QW|>^Zvs6cw5Ul_1O!`qD|7x1Qe!F z7`0L{1dY!-3^TS|^BwBa2IKfJ*I)S)q5^j|!@ef8Pc zG90pU`3DNn=FP?Bpnr?UIC`^!e{-#Lrg|E!v5`1~B8isik#`YVulG*^}Oj!lrCX^fLuDCC@N zoqezP_5KIX9DaDU=`9Pj82g>898mv>QGOgcEWSxRz3|J0gXJ_F&>M&rSw{%SQ$==k zEKoa3&`oN1ybSFlbVS;W8*-$Eu1V#8={BoRZz~j%*MCpGi}uW^?V#ii6poov>7$mV zz&up2e3kV_o7rsFTE+HOB}H85f@ZqoGY%B;s^~T#TEw(Rt#PJ)PkVBP*#8-(q(6CJ z8!yWKH{IjL$J#>!2{L^j0fg%9=tbp}f{TBO#kESEY+1EE6@M-)>5yKVGusXn%xTV> zx(jzLxV4=Jfi>FHwt8tX)#g211?LVN$Vr5E-cG{7@B2SKPwn=8A1)34UMY0sA>Y(y zi$W#I4|jjmg!YD=v9t?RFeVhHwB4+%1(ut#AlgDiq?AKVfzLphE93D7jID}9~0{lY{7h~(Fl%=c=~Lp4%t^eUcA z5NOE!nnhN4n^=s;r4q(iL*xFHMMgB4`pFHh(#OIi`8&A|V>-Re3}%)9HB~UjGmTrr&{%0*ow55$Ut6GCA7Mk3O7ah3tMhB(??!WN+ewT(~#T`eNacBQF@I z{e6Yh1O~wURDd{d6q19Q&{Dl}+~Ox#`2gsPDHk=&#@pNTOW8Ho0Y(C;5-!M{?*XXB zbMC7tr{}%y>%|fM3k*k8PU0$X`&3D;;LfzdU-E{`502b>?Qo06WO z9y{u~OY@1HhVc?04a(xJ5oH|AYoklM_3>Z<8o4O`4p^LMM1?moDh)W+j7k<~CYW18 z@*pMMubCR;AG!wAwDRxdFwS6ppnq#uFam1XlXVs$8e#^h2*c5kAq#KFl;wm|?1)lm z^5D&y3;jLSu8q8in$PR7nAyw)ZK0D_*BLB6HQ)-lA(le&*Gi0%D_j@wW*%*qdUidr zlVdKNxLKi}y?rtQRtML+YPMad$)j^&fQ4xit3Dim@^M+~@Eu?ete0(Lr6FcUV-&X< zLBv3&l@LtB{tf3YBh1oN`m+Uc94?*=sqPu{5TF)+i$ssRg;f z{7wtlG^q@gSG!8EwF7kXx0LMui-gYrd0J z|KMd+5tt#Bh_WL{RTai|PJBX{>2QL7Uw(pKkQtNl2my0~6fEIEqspdDWR@{)DQJpC zXeC4H^MV^dnAk=qz8@>(orXd-Jzzv^-}&(rXRA_HOK!Q><@~OR{e>C^JsY!;shM|S zjUhE!@;?xoqhI0_H$1d5y3-R6bgmyZyM{!)HnLnIfNtIUl|#3Z{+T+29@~e9oy(Cr z91ur;7OiQ-Y4_5teLLV1Aj1r;& zE@M}8bJbeRXkwh@?dU9-ifK)_5F*h}rdn%*c~*0wRs~y+#D#jVY8MO(r_VO`z@^MVNO*xVedAde)~Jo{wQk{QF`kKG1mDV z3p575%kI1VyAzu;pUP2j5PDLM^Ir^%au%T3hBL!MQX{|IT=@W-%t#jxH9v6?OlCU*lp4BZ^^BC z00X*+Yk~=u!t^$jY*-eL(SIn}802IkQ6+W)B~$ZUvCwjrq<03%IwM&ws(vBd5)Ax} zcA~B+)wgD}&%(?{<0@mHhf|93(~vjxiY(#Ok}I3R(fD*d``;dg_LI;chMnW3vF7as zdDpP3$$~2BACfHtVUj@12MHQ@=xKDlzGHsn(M=TJr}OVsKxx%RaWRa=4ROgL7JsP( zO40&8HoF{c(~R^uIe=l(V$H8={i@Ou{2ss3lvutA$!CIW{J6JIUk|ifH)azmWAV&V zFxyzzKDBDG8^{U(1=pqEWPtE!0IK_R>**(2%3h@W#JZ24`_nqzJ>o|ZQ5 zs-C3y?rCX;)m1h&gv9}ke$ep8FLy%-Oy-@kvg&kQcH-kTPap%z=GoN>nn(-OdO2g! z4P9Tj7O!eoT16;XnYuv_(uASZiAT$pm#R+=+3Ep}*_^m_m?SI?2`PfH@Q!Tkm=7`n z=l)z^d<=3$vXwi&rgDw~R56OcAgccY70!)=2nXZbvaL89sK^&PGvDDQAj*i=NDfc%-1 z`pscIFl9w5Y?l9|Ie2S126u3yZGAXw=J+u0$nRt$resq!WB*%U%|=NEfD2$s5SQzs9dNl9<03ng3@WnKDLV7K z7G4#1VFn%hWoIKd3duy)EEwjHEb)KMPl>d?x>W!zWJ_g5seV11Z{eh54we~1 zCB^kYuUL&1eGpT&iE;LFzX(;F==Km!Y1l>{U3e+m{7vM+%S@5cJ&EF1(n>=}b?g}gjJs5_r4=WPH{Q5negotXd)pJ#EP<0!6gJN`C!uF{%^Gy&TYQH)x1 zr&PH7cCTimlc?Eia?f*|1ea!HF^w`JuLU+t0xs#&|G8A&GHxiLVRgyZ;0Q63LZ^8; zu-=lPbMD-s5+5>2NT5>Q4B7u9?5ocuebXSvK8OyuFAI(?i`R-PUwu5CKj4H&z|1EV zcK2p9ITZ&o^xU{t7rZyBUA#Xaah6#i@Ls{_O7*(to3HUJ`NnJ^QN+Jzr^Hs@NOHtm zHR~Wo-xm-2A{LB)`yYm~7xz<8v#lCAwgsOShI^_0)_R`AMYaa8iD^8o%+?H`Q?F4W zuL!{PRjMUx(4k_gx~bFzh9Z`9I_$Lz|2hh0CA1UQsb@8eCO2233tI+hlB@z%UCfM( zTdP&MqqQe&|N4jJcOKd#EL=5uV11x)>yPMX2nYw&d=QLGnY%cyrh*j$5!CZ9f6*gA zka5IlZLA?XDj`DGM&btd{0v_@H^1QgEGk~ zSoIPFwnoqGva~V`K=SoU`t8kE4GP*PNGn-JiC6YzzD!kq!9C?MxihIxkY(kS0+H$* z4yLKvE)}E~3_4BPcaJF9;9SzFM%>yqpXYwFTDyoaarNbdh1&*$IVOp8s&Y`VIb;_G zQF4VPxMFjIVdP+uYDj>yRH`ogOXYNhB0lyiI);1r!N|)gp=nEwpUyU5zh+X=9d~2> zOQm=wDHu+okyGQwz`hniKhEAa1mA%T@l7rr*gVK~)q=7FJUs3s)A0 zk?A21&9M+b+QRTyst%Gr+63aGVJM}ENu60d@~iCho#jGnq|uv)`882 z88Y1Tgw*-TF_9wNF3GPf2=tyUqyRV0iq|qZSd@+VYmF*!9p06+5CirC3pj<#7}+B}ET2s%5O)Pu zi7#Dn^qxvh_9$B8Bd9IEUH_}BR}{vIZmN-!k?3FjMDUiPAot%(S8FWZ$N8G~j`zL! z-v4HHD94`i=IztXotkV8FeL9VkH+gw_GtOa`>;@8a)cMObz=|Q)>lG@mo-!(Tz>UB z9FHABBcCC_Di3fTdk~57l!}azSgm#T@*4ohbpnvH)I#H?UZ?&|TK!@o>K&Q?*bFlJ zarY_jZ;$L%w0u;8npVM-g7$T_D)Copjw^Bta$md{n?^RR(K{;cZJj3 zzdBMZ3+{eQ9rEkVl=dcb#h2bz^OG}ggR|=#dO!A$<=<&jbxK}Kfl>?>^}+&<2od99 z-jHV}Gl=Ooo_v;8No7J>h6l{o1pY0aKP|d#SU3Rex<|u4pWV->dqUrz3LEWzvrFXE z_FVfZF)>*ed%Jbvc(=Q=z-;EZFPnlTex~6%dm($IKU%9xp5UCW??+pRfhRU?E#+$u zFX3m#g+g|-QL~MbM!^%YD_3q%pd_}qPK;W|&Kou2k&bh2M5EB4BclAq;k}`|;XmHK z63e-HMB`l|#E`=#y79i=jF_f$74LZQFiBX^q&|83R({9t%d=#YlwGBBR4>jdj@2Aj@-FDuTej`(uFieLC@BU&x?~aNuxJdKI97-@flo#dfR2u%R z?zF8f&7gPfUAdyc`m`vUED8Q8SdXw>uv8`K6rU!fdU#!dX2hFDb4Nj^VdDb9OO#)} zK5@Y}8Ok8?gkQ5X^7Wu|^HWnYRW@tY!Sem27za7hcf*#}i-%APeEcFP^15nRn3A5w z*g+Ah{ie{FGO0NK_4X}neE9B9{)j3hhl?M?Os4C@%7WU;m*3#AieWjt;Bb+W!H+!u zGHJ}AZQG<$5s#S58^1~$Jr42Ezpi2Y6d(0xlF_PnuotS!CKbYJV^&BE+66|Ih!YFT z36}xy!&XOLpDvbPp-b8o+XwD_rZZNwmEL|)zjA2iamBlx;8y12XlTd{cj_}xWAM#{ z%lXW)X{pf2x3@rzq}rLzWtAdWzdCUQx<_wG_~z8V*3_u3omWnGAH+yqz$u$uQIrmZ{%^p+eRupM#(F%eEVQwx)?%h6iuIoa%QHhaX zmzP0(iou|fqqu9OhXzs7?IPe)=toZu*yze74~U$+Ob5 zxfz|l90r)%z0Wvj4j*@1%1l_3A zNQQ%N-)r)4L@Td?5#Ja$`7(L)AOeQ4u zxA;2i%LT#v*IX1kV9z~gX^`@@ZjAOpA1^mO{If^yqoNJ=E}gv{W%Pa>`e*u;3D&Q- zJg~9LnJti5cl)Z(b5}?;kjm|Ah>-A+?YP8k2#bZE~plWCQfu@WKQd{Hm!bj8%EVy@ycJ4m0$VIieBP z+zEB8vvN#xzscs4E0?4=C~%={C(!>Av`Vei8?X@cp`$f1M|_j9 zPyKzkRre-A`Jt$DSR+|*vq+^OL7mTdE9ZduSYDN1Sq%ue?Ca7kPSo!Nn6Vf~6C+aoao9?euMMz9atq zRDtvJeQ)!^2fcg9E7(*4yM>mG|MvpSO7IL-^!GE`z79j$M=WIpY}Q5?`SQJewlZW7 zWdy8I-e6J3^H9?FX6LWWp|&eQa*3Ag&+gQns6D#YT{nKzs1+XpE4*PHzxwG2Gy7H; zN8k1mbAV#~bY7QHd&|+Wnt7C;7YB_MI*R~5_sT6eyO&Y0vg92%?1ZE)i!@H>Z|tt; zvz*UoNmSNPm4uI#fcpghNrdqWJy>0MskA++6mi?*mpIDXMku(|f z=2(6Da4=M1Ue~8OxA3a+uT-!)vcqCgCSM%RlR@>N;_!$2!Se6xX9riqYOYo(wvlD` z&Y%W_a5XA}SMj~rSbkM(Mr_}{LDN1fQC={Kvsq+!mq=gxU}2LkVh(!npaQv<|MUJ+ z!GcI#j(Gn7`f;q3mj%0Q)oU;P)IZlh2tr|MD;2|M3nP}l>l(O9>$PO4CI1u{{}>1v z@r_W5igZ9QIxGy|iP;o?7X4oP)DXKxLt7wOsC22UmnI#NSjDi)5vGtDITyF~wF}D^ zf8ms2kFEk>QwB-YJ14egnAS-vrBDZ>n*=ru=_7cGEk8q5N%-%D*{0MgFOG)HvV6aP z!)z3Am%sOq0S+PY{s^%9McALk)L`4PIx!J^rKa5Tss54<^?xB>)2FC+trER@hueI^>eLv|EmiP5Hob=ATsK9{1AqQz*01}C#TR;gndw*bqW*bi>3 z7Qjr>V^>OYV{z&L!%dP}E~S!86MEx$rQbppl!-TQrd(-sBhu73V%^AR@=j|5G()>JDdSb zZ3d|`gZXMVlp$BVCsD^hZ-R~P9e&3#Ch~#pC0O|l?U{3-n?wx#^2r>d&Th*~d-;bk zx@_9d9`ifARvxD!Q*{EUY`80CJahCSd=Ka`1oWa?uRKIv(4e&Ik}}7F6}SjYBzxCj zydxgx+RB691qqpH%~T}D5sZfaa`yrK2cODGBTVFG!Kl9=j?3d$A7qZUWZYFh;%)%t zQm+?c5vOvwxJevB3ve&9Vj%zX6Hu3+UqBirc;c?JlvB?{-RV#kvv9kBfBh3|>pfT)Y8wdNYhkKbU6t{I4;5_Vfbd+&@b=gtgRY4@_Lz@`%Yv!w@CuT=GNmOXh z635ORlbLCT94<9`a$S<*3s;LENM6~N0HOTZp(Y%Xr&B&?HQ)i=7IngJxr8DHJTz8^ zJraL4MFr&n$1&iUX33w9@@tazl8r2b^_%=O?pwe|q`&vo$TJ01-h)@kVN+b{f6N%K zWRLz@`FAq;U1b*j_HnAl;><~s;Bq8(M@j;vI(cNf-sfJcU2s$R;_|79gL*-$49v}b zM1qbirvJebQh&o^pK)9g{c7-L(T13+aO^}?+)Gz^wZMsKeNL8oJr9x_UxxgX49_)j zyI73*9(|8&;(H2|Cf136NS>ig%ueiv3g9~sCmM)OSeO~3hq5b)y{Eq)Ij_5%&nbJ= zYTRHY>V?Oyz8(#5tt)A_n*#0)0)hDT;$M|k1P4jiOkZAxBcp5g7-@xxf`O@MND%9> zU0_}O3l>@0?cLRv<8R)60RBREbK*_k>4~~0Z4n<$z#Ybo?(~iT-h~Ui4}pFGn)M`` zY5Gx)bwnv2Uz;D4`RvxLVyG?RTa5FDjsyz+a7EQC^DiQENDlh)u@LmAS%orlSclN!J}{%nv@(;X*pi zj0^qdw}6EXMR9iI;B*~v&(v%Oezzsfl^LqXo)OcGfqt#Ani{5n{pjz&kCJ8Bv$%_r zd`||3H(0OygoWdEx61QR%GLDtCRU`?ukn=~^D~G&5FEKO5TKMceYGovS9#|kIg(e) z;G|w1s&^7jfqwJrX-Y(BFC>{~C3 zoq7(FThOE$CJ|$c>W2_+z;jMf%Xi0y_Oqc>ha5I(&iTt{zQnDHL&GD#Ju?Idj79N# z@hkIXMCE(e$$#F8;LaNqj5J=djy?+vQ&GQJkJgvdrCrT71WoK2iABz-XWpxi&rXlT z5VX8a0^A)JzaDuu3d0e!2G6q?@(;Q`m|e1x6_AC(T5k> zvrXL-kGS1ej8s1kuQCWs#mj3H=ou&XE=0X}y{KSO_Bm{0|| z!oQuzNAdK~#5IjE`+=VoP*Q=l`AGv${YYZgUc+_xIm}Dku`X9V?1GU-t7=|(3d_h! zXI0zAO9JHEP~DqbCN>sWs>QSWnyp@hgv-wa%hgU!_A&53M94Qay-paad8VVVDb04K zvNFku_aD_lQWSMpS_e_sv}+=bi7X4mN$4P_0GsfLsLxbGH zp5Ml;iUdr^dKvs?ljPt4n#!ub{y?d-tUuQ3i4FJk`iy>JR)$r2K=gC!(SL$ECW*dO zwzcYPhIfYF&TuHGZx z;@8h*R;OG_{(QSB#|8xQzHG<+MUK97!9K`Q4~UT(sH*4F%zpy+WB+Nz17IgCe-PFC zEDj~mw)YY($hDB&7S+9U^R2{$-V8Be`6nH&7FP*G?^wcPtRe*sfD6^vFR1g5*m`P%UV)h)!YgM3+tjdt!&b|Ro5COdLtpf(>8>~=bp zDnzAqf*|4$m@IH`A}7;AIt>=92FKO+Z8R{JFC@uqu2RIy1sIzKkkBMF=}WOh$?_YU z0gr|&7P=S3zp;emkK3vc9Mg40?S2{7yu=|C7=`**nc>?c!%RQiQI{FTk=g7FTSEAY14U_tktC1C&RDfDXNUkTBA@vb?I zSn}57p{qQ2VCBkTi(PMy3{2PeSMMPk5HJm76^wj=MZDc?_%TYV5ig0KG0`oka#)Mp zkEsnX2vRGEuJgD32Na~uOzBWZzb>6454eG8#O-ia^?f8qk0}P&FsAI%Fbtg5mwo&OrS%8mXiuw@AtekZp^~J&o1Of4~@PtGKz6D^Iw^HtPY9AEuwj z*h5{hd8rH_BX8jc|l`H|>z4y)-0Ygn+M}Uq2Qoj1O+)>?XsCLB~vLg{8-)c7V5Xz~~ z(ZlN>A)N0Kd!c#KMu))Hp2=Q`Rmy%L$*sks_Pc`hP~o6!sg5kWu0UQH=8j((9e^{k z+H(O`?k?5H7A2g<41$f5ZT{X5#+m#HB_hU4AGr&nT%>P=V^1_~| z3K0LUNpxhXDkQY)r9{c=rkgLN!oy}tynMJ;RK3^V;H{-P)V-q)gu-iR!GeDWZZCnh@g_`Y90zNNd!u>tTm#?Q?EJ8cS$7*}pHq=SK-=(7Y&d?^U%vS_gJPgzz>@hu3 zo;HnfW-k~V*&Pc8O5!Z}*qi0FZt01HbN0{kP1Pht+8O%@nur|vLC*(S%9hXhicWd& zdRRmxd|+laJKc?vjPSn@u=TAjTGf(DI#003_a?mjA`&9ahG@hh(xSuRj0?9b$qLlb zI7Y)PYZ@rsv-hIJhzz)kdQbS!8vnVqTsQ0m;y$| zZEgNbR4`d62(p8O>}-F!sqCA&dKz;x&m*LGWh!x5 zQQS}P+xHt+>+fwjQR8R_j2_FziWxuo31AvnQ*Rlr`Yd&~Y!qL08#JIUSiWE{uQ$F@ zZ!2<2no?|;v(ZJ)m1f?oE}p7_g`nyxZpaX^BeT4Nj;M99$gk$WY=)Df0Df)Ksg4=Z zTlWcG$NInR3dAcR+=I&R$$WMR_95hc6vid@Vucz^_ifau(MI>-6KalzvRwy7?|o4Y zv{x36*twHFq(jxQGkxD6Ps9eSZr=BBZtcO2E1~{zG~VUf^_xI5strqOfgsI$#EHw& zwVjOAJ%v-`{jl&Phw9F-L%%j}GEnu?D|vXt(CUbM_NkYrEli+5dhuBLmJfUDT*r7v zj;{>1IaQ-ANkfB%XcU#U{A+w@bms8DyzNAw?IiNBEpl;qCw2Jd1NH9xt40-0rhlHZ zwgoO&51R%YR?$&DNeomXU$BE{XMYlA2p--gtD)pMKcq;?(MAjMO~Hs{JQoI{pp{uPU4p(v}uF1C_o74zkrWGah>U zigT$O8p^AQj;+P_Ui&@v-(Y@it@ds$0aUbyRu%{x5r0d{{njw8!wmaX9#!|=a)P#> z3VisZO)YG!VIt>zXJC`N{OGe`Swh6u*C7OOaF39-@1$rT}tD>N&*0(%SWIOetcNG0jtz>B7UxhTg|vzl!EDQ$5tzrpk^F>Nr$ z<{B@TRXJSqt%_3n;H35d^1$HvO`r*jMQhrrfK3k4dz@qp7n1ejs0q}>lrd5+Os^2= zcq@*Q6fB}gD1}W4(?BK_@$LG?$R97dYwHq;lGm3ikiw?{$7h!=?DlqU?plW??{?QK4 z(drQI>f$rz#-I(aCs%ycEtB(bWv*Ek7IseF8YGXAsJ4k(Q{T05?)s&JTX&?_271q+ zsicEs<4ci+-F2x5ne_gF-jU`l4v!CmQzvmmg^kG;(#w`#JV%GAz9sbMd;ZF2KYeyR zcLGn!L+EI{*qYS%OAq|H%}$iG=AKuIIbAqqe-`!X#p{GcJb1=xi+9H}U5O`>&%jcD z@5jpZ___NiY_KoWNGftS;tQg@eUo`~;o{xZktJx1we|{ITu+xZd9|aAc=Y*8LdU%6 z8fkZ2m-)91M%{>h(`5zQLu;^7ujaZLhhVVZuLVvg;0Z%8&mUFAHrKU1Ly@Y4_8P1Y!_0h!35;_XJ@93X$ z{Uha#Hi6TwnBk-n4gb{NU-R!hsSW+|sC1k*h}{9(FHvwMR=#v8nV7!z7%M*iT(v1* zebvLE+>$nxr|fUSeSy>!|Lo-^ZOt!~%J zFR$~I4{*hKAhkXr;N0rAJaO!2z zZiuKqmi))dUgytaE-d(Fp_TQ695j2}U3z)c*B3Gt^FWDJKMc;nZqs9@ zN^gKdVT`PI{7=55!|dBo`o{>`{ZGt)(eOWIfub)<7c6TDH@KGfR6G^0ah*T%E4Ftg_&c+g8XUErl0HJ=`Dr2M{z|!b+)TACPzGeH+NOu1$)`J8eP1~(eKgU{74>26I(Y1T7d9q#1-KwE>KuDYenKKB2b|1 zCrNSzLgMiMqv^flss8`}|6?5oCk`DPS?9<&_A#@abFA!ROW~YkM(LG359gQ}Wk>dm zhC)QvQ4}&lR>~+Ot0zM2`B2wmp$cHj|Y7grT z5cRPjzMTCJ91ct=AVrErk^Kom3=1W9|f+#6C2*#}f#lf{d=J#~f94x@x)wI}ywuE_n=t1! zpRfo}`DevM!&aH|{-p;_aFXlS=Pjkh{h~^rwt>J-$Lr(iXj6f}fJ&-QYDF|d8Zd2S5_CX@9+3Z_zsRBDD-NqOb@^3Go^dTO=h_oa7V`}SUErGJ}$ zoi=<{kbdd+_9e-G=XF?Ne|~cu??>xKiX6f+PdUTd=96y9v3HLCIJQV)@>i zMKLWvEkxZ4D@64|U_B|@$$;PfGognyzMFf(wiD`hQ>@A)(X7x4Oghhv)F-D*8JH&y zmPy6qhQH1qE672d049PHOC2l+0!!9VlRpPufld^5=cB~6#Ko~Sz~te5_mw#Jq=tUs zNlatLH%8+SU?BZ4j_ccZM%WhA6q5+DWlb&!{pa&HB-}X*GhWH7y>m2d$GnHN^b7@{ zDbToysMe4iS1zM>MN-`=0Nin*nm=e6I5HX>8@63~_hKdP(!%iLmw0ro(Vtb_kj>z? z8u?uXUN#QMX7%gqsf19o1NES0C%X9bu3OUut3OzMBBR9HLjf}8-EXRgC(dm@<9`K@ zPVND?w1QvWbNLgE#D(km_S(7PmIdaSRi8(`KW^}z*?n!ReN*n^qo(`IgU*J$vd+d$ z{A*sbX&V6t?yl8aQAY&UyIb=CFxH4DGzn<5&o$*b?QeB8Qx z!dn~GS4qP%r$Lfpr|-HFwlh@Waq^!caq-ESggFVg`0W*)cLnNjxeO*-%R18j?Z@Q0 zf}PzG;l?+F2}{6G>G0;XK!;iBWfzCKTY~W#3EStJ{u6%^ITqg$GGFi9lJc;HiI!lU zO#EbbPCLlD;a;BFydCo6lJI{s((xdD2TA4HtD1o$5fN|EW2LU zj)9sGQ8a0mX)mkXtN<6NI}4QcK8O-N3%DQQo-aS=}(5lt#{+s=FlKl9>hqG!~N zH)u?BIS%JIT;_={DFdYrvW?cVKyN`K+d}_+bf4;p0uVMUTt&CHcUo_SCU&d5Um>*y zL?!+kW?A*)1F+l4*VQydi7f+yQR~w#Xeb)d>hD$JABL4FFQ|%3F{w!^545pqqt^6Z zS)nK0w?~m0O}OzD(&f?qLulQP=pZi>&R%(jN?;r6IR>*vJ`1$f1GKwHJgBs}zGK8q zFjb=}cVzVUl+lF7nv(yj0~#RoKP@2#j^DP$H`t&FtGokVxHC|yv@m`m({L=SmMgy> zlUQyCVFEKj?s;obh<2fzc7Q)79k_Pz%6cMY+>kPY3IJb=g9jFq83!aT2yy?gpK_5g-K~s(M&5#MKq0z zRcwSF#f1lMUJ{IG`qgc%jg|Nr=Bc`8&#JPe9X>68EbtzBq`tz4FTmuVM#&07Y@(@? zcX!Vj4t4?5(HC*M9?<}>*k|zC0GdoNSvF6uaVsH+>-mT`CSZD|3{uGhiU-H^@6D zU*Gc+nf?#ZgOVvVyOU0Wf)>oP|u!MZD;bc z-0kYP>=mCWFN7ltP@l>epCO2+_G7LpxOsB`zCJt&LsGco7sP4Uz*<^gz>nT>=RPu% zj7&bDGL=G$Cf7DOd#}Zf=x5GkS%CnQkLJVcVQ8xJ)rv<#C%gyh%O6Myn8EakLV3@8 zrior~VqKmAweS}MLJ)AM=g z@8^rJbA~$y`uIa{W#0arG$p_PBD!YF>!bNZy|8E-&x@M-@+ z*4%3wt_8(8#I}DUD36qdGv`&oDQ?)}z%)5YB!K4Qq1OgBr~oULw4Wdd6Kgv*&pXpl zX-u43q&)5~hz4zbKH_93Xro&y_E+-kk`x;FXBAV-(`8>!JTNMAi-X1e{lj5e?}pVX zkjjg?5+iHM`gxwWgUKk=&O>G}4n1zy5R8zpEZm$R)qQ+Q|7Mx( z0M=3S{2H;ShEkK~=q^)MR~K-5q)i^ZR2vIe&_6iof9xo^$vI)sZEnaHAX_GG9MHx_ zsb$^F=PYrC#44b5~B7> z;<>C-a3zeeniy%@wNNtM88*Jz%C!Hn9bdZMsm-~3>EE&VfdZMtQ`pP?#j3bAUOsi{ z(!s>;^p5H3M~R@329Bsgp@W|6-D+1C^Wc;Hu-2o#Z>7awqXg%|mQ(_cK2DAfM;&V) z{%~#vF8+6eXra_TQFk6wG29#9yoBXKk=D+ipv;N_|U+enrZT+)9r+ zJSc)i-s@g#tHWzS;|6*HPE6wQ@o#VDEVB|PvX~y{m0l+W%7-1w6Btgedvl|2_^0ZL zQOgd#di@mAKgS$<(h&!%Rhokd?*5gO%WBHS)edDi||Q?@wAz<_~X z*;`F-G9bQ79U4W(fsoO+7<<Pk&#H3dfr-Hi_8nEJP$I6LeK!4F0m@#7T$i;l0z6ibN1evW_=Q5EXNqO6H(@NIW zSz%#85Z*L)f_YML6>pt;fK=Cr9SiW9jabAKvgl1HI=OF@tKKj)`Na)2x*9iQT+`|HYU%ff$pfp4l3@WMoc4*#z~Er7!0#0z4pU7cjGLo$vG*tM=F=7$Si{ z2wZBtTvZ#;Fwy~|^5VaL9s7u8gO6`#nr?b8^`>U1t})@SrS~!VF8&h~O9`rg`Os=CgCl$ z$6}>I;-*2%fmH%}qtX{Jh`&l7sY<=>iLsgJu3zU^>p+$e#_p>Zz(o}Kd-00uZhUnBN~3L+*e`nC>@+!=*Pu@sOx2)? z0$>RM>d!3tw`&fApTbG#V`;auKqodfbB_6A zw;^fP9251xg%%xr@|w%2-PrL@`h`!tC!fV@yZKN*1$Wokz{k&|YI3ZMj+lGGUfY{t zAb&srT)xSt?6#b5nMW`XNYDoO=5d#;^}bmbUsknC5s)d2o#Oj~ss(%pZ!j(SuT-8@ zJq2po!E}@XZyQ-3u^hg-n%daZGU!mXd7X`S85tMTWoHN+sjLL!aV+4!DvjH{s6K!#ya zq72u>I)4`H?_O8wSrjN+VmmnZ_rl@+)UCt)AErNda+?)ayZ^nWu4cc}V%vA?m`i#X zG0hks7n2pDdNo6A7EwP_G*q(R01^IB@m>0LR)}mmSB)BR70>qu+$Ur4cdW^~oh}Hx z)F+aEIaE}%BzA?vk@NC``aw7ot=JDbb~`x!od__)w;_7SG^6KG7KBa|cd?S_X_Q0W z<_w}N{1tVzFOX#Ac58NPq>sa=Pk8MD0H0-r#%Cx>f%=PgSePWjrtUl~2pC!a_nP2k zt2f*yN#1Er=%Ku-qUFvA@7h};q#s{$R<2}SbGy${YAj$fefg<|7sZJyBi@HT@rk=_ z*7xz@%U@E^{Qw4CFaY?8scAJ6A68!6eN0F^Onj>lb*;w#GS836XXorVYJ$lde9jr^ zN7vk~vnGuGs*6F*dI0GDWRTh`ZQ^j z`9Y?^{Mw z+DM*uGnyRVBW*V*SUddQzkM`%+BB`4U+Q_oC66cloU!&>opSok;^77m5|QybqkBse zT66YscuP}ja%YEjIuFDep96@E;skAg#YXqAos6$YOST5gM09bUwNy@L}LVOLC zjGxr;c~YKjF9}EPen?5Xg4wNHLx1|m(vF4v@_NDYkPgl+NPG(LR@B~BrTyC}(8fo7 zDWg-qd!6rN9>yeyxmp2k@$`amrnKn|ebje8S30CjP)t3Sjp`TB0^x$THK~5EhC&|) zjS)K&_S+H^c8IJz+Y(b$@xB2n)DWCDC!DhR0&JS^3Xs>yO^sArkxgcXm#r+!% zk`)ms?fZ;)Hafg-7g58piV8#Wzx?1KdnJEIb69=l?pEQ84=<0xPEOUHhkGiUUnDI* zT~Qx)YXg!leWvwh+^K@u+(`Ie<$4uSV zaV{DB5CpjwL*N3Cp&}&ZQcRu)#th6-J~}#_V?2wZYScU~^Wgv61ADl-%OKEeVqgp< zkKD7hXlYG)34!Ir<&1_fLe9U#I&w{;WE7AxcBWpvcn^Kl`rJ|lE2)gv)%Ej5*UwKi zxr{WoTHDX8>S@u60Nf!36$P#WT}8V=Zbk^L(*ZpY=u8mgp;a1SW_L~@SpffkhwCPo zv=>8o_u_T4`ums%FGmq>l_E%Z)tYoloPC07i(=)U=K?a~W*)4iFE1z+ywdmTuc7u| zRygS^8?46Wr2<9`_p25+C1!wLJV`+Uvr3^M-aSR5jX$RBUOoK3O87;gkG-?$wRkUJ zHu}Sc2|B`~rOs59<2<*0wIWYN-C^4(0Y}4??G2u7nT0;bURO8dAi$hc-CnxAxZ@Ym zwh?i1<=C*er@3u}yuHSLjQO6BairyX#;tQ^*mgYf^4nGy#|znD*S=q`6VCob{5Zec zoX@Zq9lc%m!ErCm#!@}|x^`ROl@n^t*wTA48l^~pyc1^~@Jf#*@(p9HdfdaP27g~! zuF91E27$w^V$+ir7Y{)YJthSn>L8UHPJr1d$c#2xQ9o=0+GLe%>khw2SA3o`y1DCSC@+CsPPrq`(!usds0Q;%K=#{I=R<@KIaBy&eJuqCa#Ve%GDJ^5`kOeaaLYk zKe5gRyrStolA&LD3U71;y%FX;(Vp2D#WgKQTJz73T~qhAChw(d9|S?FAB%)Ni(j4Y zJ`Rk3Ly2fNv@$ss7aZpX4~F{XV#Q@+wVr;#q(ytwl>Y~4|> zP;KiAwonk76#eM!Hzhq}>(6@r&=I)!o73tD1{z~~fM@ciRvR9})P%j%3=bUZn4!?;L*1u$?p4-NV^Lu*FApx?E0FQHo|n z$wfAP+uE~(x4>=+#X#xaCy6hprC#O_Jfe_j*5l%`ujoa!d-cYTy>{k^LL zB}cC2$a=T>-Hq>gT{$Y{TK-HNrC3WwPi`@^#p%T zGQrwVV&u)w^KYdt)KF}CO}tOcgqW!|5~)DV5ci9F_5)@D4q`#0cgppU0t|>O>_d}U zg*Z$f5+OzH;e*Vvm(nk6ll17bw|iQ_mSC#Yy&6gzAZ7}7qahmEBQfO^oY}Zsa=m<) zuq}>U#DK5fevL(FHM3>m^3ngmrR-&S9UUE~6=`r+KK)Y4sEb&jT`+XOh?jj{#;)7eSGuSDLg=HpVIw2 zmb(i|WF|p8{;!S*u_R3s5HVzdx%gp2PzVFZA2qwxw;6zPajJKh>Yy4;V^E8xGl(Uk zFc0b<W-HBar%cBm1$D1oXhmS zM^AdIc;SB8COjEmBSj+ePpl=WY9)Z{>ql`;|0h{}yDnu11G5LSE-299lT6)_ zgB}MR6M}x(Zu{rP{yQwkzccH5sR#U)OGh$GN6+Rb={h&OBhHjUUzN>2c>b+tk`5w2 zzhipv9-GGii;C}z;&(lLd0bDhh*sW<)H##X-D($n?kT(|ym|X4WsSjdPItGG6dB%B zey{$G(Vkp2RK&gU3v$HHV)eA70SGd+f$v!xPH6PspS1BSm$MZYV#!W2B4TQRhXZan zh=q=-5a0UeQ^sY9QYZaU%~c->e>2{=0cz#nA6&>K-|}0<^-P`{`jUJw;6|bfhm*5>Kc?n7mOIA8|A803%OsZdjJFQ!N^VA@!GR zve)7fR?J6YULj`{HPmcMrgDX)x;a86B}m~5$_$Kc5nh`g`dG#;1-(_#{uBiTZcfF$ zFo3}wSlBhc>1W<}^JXS_UWg7?4OP7WRR#CY2hq_qbn+ELE{x+ElIU3{huuJr%KPV? zm}nl&@`+164%p{^xnv=kSKJpApmDNX0!#nE&XXl#$*O5d>(Des15EXYGA^Oa%*gJI z`b5>$q4}X+&c^mANTIrfm~(Uig7K1i0s4Q@7FWN5TBxCq7!NQY!$~!OaC8CDT6XY` z(;2`jRXl5=W(wa!H7ZT=3iMbs z*s&VaE^hFfYCax5#CSo{Dg9RTu$|vFi8a<~lQ6jbtvsAsX!*yj z)2SP)X6bVGv?+?Ui8-@dNNA1!TAZE(F}M+v^$l+6wF2#5xp)-qT!jWB_xZyI`!+(q zSd_529+)q<1sImvVn?N<9{KHB9Wiv@-uNrx|GrlIk%8?V(?Q4e^D1?#V^zsu0^;DL zL6;CPEsU-JGmh;2XJ)IWkx@Ey@z~{+9Y)~K@afZq@uVWX(61GzrHgm=zKYVcKU_Yn zt)<)v+cPq5-HC>y={9k*mygKhyZ7R|hLQ z)?3UU$0k?B{mxab{HX};k`8_5WP@{f(k*=6IwK@`GH5mjYRMFt<~l4}e@_wi)j!N> zP5c=V@+Ko@`{jgj44#jIpE6?eEgzUrm6Afy+;gt3d6hHZ1*eP(O9 z88)@(;KpiILIaXF&a=XoMX-?U`Y8;j0Hu7~;z{X;^F{{a-BM2<`3H@T+Eu}p5v+U=KE}Ei zx`>Jt!x;aT4H$bi9gJO2qXGo6^x&3#_Hf^bY4;r~$yO}I-dw-uM%m9Y&?S%n7KT|N z!zT4`j9RUeF?T`VGsH|quLPW(o-{_C0Po`mTFFN}ipjIDsa9VmBju#O3Tr8JJ8J^v zw-a*t|6~c`9;~E60S|?ybn%L`*ce!lmCn}EL+$ZEj{ec?@w!6W^M-|f$^z38GS7<8 z>{*h5*eU5L;Q&FZ1ezLQmTSmmcn&hBFIzr?dyk!J^DJ7hBG>y6xBgXc3IF4A1R|0_ zAU%jF#HJ+6g}gmL6Brbt0nR)347M(GzZ5<7YBuR*bqp|8hyW!ORQht*%&pXzc#$MZ zs`TXnPDmP6*eTZ-Sc=#a?yZqy9vesl>?iW`Uzq*adaflk$m)j%>CLMVzA$>&%w~yr zs!4whOtiv)0S`3IeS+hoUOr)8NJSuNOAp6T`33L!0qKfIr+|Du`sHCn$J3?DIp4ml3+d?2e%&=4Jt761dPfN!_j~}> z9stmN#_r0Tec9fgRm+*Ngd zAV`aCWs$DgE3YL!z$3`SB#RMCN9+F$THouMUGF#c93GbxOga} zw8OZoFSAPYBzYybmS_2C4t{>|H-_-`@8FM8u=eAP5Q>UQq$hUg}JRU zS*bJN7h`z|sehSVOIS>-czr_?4~$9=jxrAz_O7oT9+^ny82NZj-ihyWi#YvO7n+ZN zSmrw8UZiy>r3p81bS_)RA?iNC5N~hsKPj_}OUe~Io)JE|7T?is6U-1D$f@`3FDrQ% z1Jb!$Sm@ffGU+gK7fS7HlhV_jF7`m0jiv8H!oLN6^bR|)0HLBgr$T%7ejEL&3ipHQ z7FT0WLJ)(o)X~`Sp}rH)Ozf^%^;d(vW1({kvW%S}j&1YL?uG}kFUw?)&57SGnfg(p ze5i$6tcg2U8cWk)>Dlb2e)f7Fesw>AeyvVfYM)`GuCzkm#S-EKdXM@M~LWx$uE zjbBd?d9+f^>29ffAx@hYIJR0so%HnXxLSVVy$Xr|c8{C+ zI(;L5Kh8z2_N~~Ca10GyZe3qtguH0Z&DkAgL)5QHREu`q`0?g+ci=XM#C5gGOP|K$ zZVfwR>I;u^olMfN?JwDCgq6f^wge(JuDAkU+J0}Sp0VE3%_S5Fe4hpKW+u(y$;XlG zn;8Ko-jbo(u3z#?huL5rtM*Z{#dGiPzxNMopE4MOQjBA0()QH|*0EYH9?3Y~r)Ey? z%`!+MU4-Oce9(__th1}r=RQDSG>!bKb{@>dSEFJ-fmhqK;nS$=Y-jw<-p_JAJuiMx z!JWA@j_Iy$Wx4b4kcBnwoJS2nq4?bBiEfa{CkU_73k{?EFf~XZEZT{b8(|i=+{0pVT&F;vff5yBd zIE18WfILSW6H95uK3pU`Jl}I;Fzy{P@$E#V9VE zA~hiH5rrKOvPP4y|8L9qL=?3Zr>A~+`3b2HR<+`5HbQfAw_eIii7mNen8{9GUPx`d zbXgKUY7_*aqkhN`auzFIH*B&Ki;n*NU_qYDecJzj69H}dy+hu&JEinV_h9$>DC*|T zPdGHzE9E8gAbk)WuxUKWief@AKVev=JA%Mifn?CjrS8i_F-+!5n;}W+2}2y=$^ac| z?aU> z#^;?t{)6Ame-JSH&6TACPUM@I+dJMJ5wkB|ec9+s^EfLU?i@p5^LjXb=SH+KpB`HO zaC6?W6%0A)N?chnlQ{vpa9?g-kfLbg)#H=OZR;(k#@5Tp_)B2Qom@33qGO)c1=-q! zr^=t()V!*4*U$CJB#leP0 z6vrj!mYGo&_IzI6I4J}rz%y)Q#i=W$#k0k=_{RTEzD}!jB z$nOi!_i`b@iT}?FV0!df+bfwQTpTmvFn|_j-aE&PQq(&-DudEP6F9cr4cTv~t@D?! zmGaGm9ZG2=#Q1Lot+U1RSlNLmgj)M-yPdCo{_~`?@Txr7V1=~7LD-!n^DsN3uc9hmfOeEKz(*%`3v2o*NH zXL`S{c$BjbrKkq7#;ttr7GJwLOr#8BR@ndz2KoK&;Jbl{Rw}^ZFOIoiOc8Dl6w;N~ z{TBaIXT$l&SOIz|sySbSV~5$x*7E%+k8ecBW|N?*sqnLe>%H4#SlZB0#I*dN?*022 z0SDxh8j1D*+}e$bh(|@QjxK)Oy)U2s{6kfT*6r;t`}1dyBr|KSV=;rKPy_UT(PHm} z8%x1<)~6?uGh6Z2TmPCqU-XKMCF_VL;W^heD1Q!8FKnHi%0xXuLD9!~>F@T#jW0kC z!7l)}rZe-LOMyJ$zZBH(OU1^c!NHZQL+z4b^NUcy4wSj2Yc3BY;$N7~pC2m-aB=%k zM=yDQXJ-t0-}`W(Lpd^3IvU|xP+`=Ob-z%9uDEAaUqHX`cG}1mf9(QYgJbLIn^4;h3*6gm7V7c({%0v_O8329dcyOb zIbE3|OU9(KZh?_+%%Rc0+v$`2z6bZ5L@{=9bR46wvF_V_pecplMr7TTs$*dZ>(h4c ztg|s_(c|MIjCn2k&lH~@zu5srfo|*>(k?6d+sM29`wc07w$}8HwK4G14VU80HWaQ{ zy8-W8)_lu&Yy+AQys@RHtKJ+N6=IRUIpctH^?v6}`7Ct4gAtvR0lH8e_DJ1RIwC-^6J=4%%G=F%!j(g}ky_8c-dNuSRq z?0sIn)-G3$X}J&{;~g_B@4KPbe7mkhUZEzc$aQu_wfd)h$0-jTe#*cmfLm`qyN)YB zouNcDl@%~skH4nkwlla{TJt1U#eL1DFmOf2B6)0{D&qTN%g283cIsbf9J#xdabtPu znV95@d$(K@V>I%{1q*%+EY?p=d|9k^X z`#=ESghM1GVHOtvgKi-#iryz73vvB`M z?pE4AC$!5E4A!j`LB#1EqhQ--wkB%pvH9iopTJzq8om3rMl!A*0iIi_%?pImZ_3Nv^L)v6&?!wyrQJkuq$wkH0i;z>B>CkSRgYV9ew z;XI;;ez$9{fU>Dz^f`zarYRnNby6?w6ACq>4V`aqTcM+}-5fYQ1S{buHD5Cj!SxIX zdcY?4;DjB)@Puv|6i&v8U_&|-Sl>#67VLqbtKmcOHax=Uif7D=VJNWQ^cxZ@e6#;g zH8Z(lLaw(Y@@b0z-P@F=o09Dev`s-em_{6dyq)D{fDN$*^34UK+O%|U^~gXNST7i7fwI@~9}CVb)3;^(~7YHH>abS;qFPihRFx@lrv0 ziTl1!?w^eV^QB8$UP0~c579xsKYj)8tgk#T9H!7;K88J8xr?SY|JfK}`?D2s>esO; zr*leW2Al`c?bi;xR<6GO)*c-4eWCZ@1qX;K_EL9B*7d)&$LtU`(tVr)BzIxJ`Vz@z zL=SN;FNr!h@3=`Ese(cLOx6zpT?`lLC6St&*N+fQ=b;h5bQ3|;ADl>;%(MI23^YY- z>CsI~P@DooPhORU7`!z(_kQ_V{qgOX?dVv1v*~Kd$cfvJ(}n-M%RAbi0a5xTEA;OE zoe@1ROkOO$2Cyu`VU6W@fK-A6vH)?VPiNZ z;lV_|w=v~A!BuJ=5WI8PCDM9x$7$yEL(+Yee?m=cojx~Jq$RSP(hcUH5z9gl|=e)D}G?BoJnR*$aCCmrTO+QEU4==Aw zVuji(9lsW}(osc2UnO4v{0K_1-9Y(H6vVG6w=`8rJFXje*g*PEOXNw4PszA=EaL}I zf6&k#94ux953(x$w|&Qwk#UcK{>3GP`T0OBB=COsR%|7dqWBxc$PLzx={DtG3Yh-S zPVo1!CPHWU(TA0YVu$D<;pA^h$VQH(15dx;G~N4SB%AH~c-H&jGcu+1@?~#}bj|KL zC2IF1aAO4oApTk;!hRMV8R+7oE4D*sahwjLlE!V7;Ax%k@?+`a{IuP2xpl@4rJO%o zpRFgEm73Q1-M{t~G};OomkOHaBl}klEWp^AL1bdaLFoA3gb(AA$oJoR%74`Q(1FEZ zeROQm=T?~gisdEVlTxhk$HdM@H;tz_s@tLj_yq#4w3;j5^WnLu|(? z*Mh$pc(-Q8Y%@ct!P}90f0%!5T`Ma2*Ox($E0p&@`1V>&@?Sh?-+n76-T$4=W~^wN zp(~?{r+QmmEnp?2(=S(v{2l~9k3uKYR+!J%l1KXjmx^yJc6WFQ(P@qTlD$?l&}I3L zaid+70UOqzb=~UT-#z5*wz`A)VAQSh&hsE#P3%GLetW2jf%9#513M)%AudcOtB;^3dBZO_4&!8@ar~TXv0=&Z9>@56-U{#DRkc*X3*`^p6dP}k zfm)+H)tz4}>3QyK*zZK2kyA%0D%y8@)+Wmu->sPAq`6t;6@LNM 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%0DK{-4o_8s~Srp#qjk^5r)Trv>|D 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

5Bv-(9tmmh0Nnmbi61des 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/&$U7NNWBx?YHP;K2>`;M~3aHSuIlr1FyIT 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 From 74eed1c62749c1af0489a32ee78965d766b76a65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 13:30:55 -0500 Subject: [PATCH 1013/6505] Add files via upload --- misc/images/gamuntu1.png | Bin 0 -> 25791 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/gamuntu1.png diff --git a/misc/images/gamuntu1.png b/misc/images/gamuntu1.png new file mode 100644 index 0000000000000000000000000000000000000000..3502838d710d1938a697515d0d2967a85acdcd32 GIT binary patch literal 25791 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 O0000 Date: Wed, 9 Feb 2022 18:13:02 -0500 Subject: [PATCH 1014/6505] Update ubuntu_setup.sh --- setup/ubuntu_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh index 58b67c7f..ea116c5b 100644 --- a/setup/ubuntu_setup.sh +++ b/setup/ubuntu_setup.sh @@ -10,6 +10,7 @@ CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' RETRY_NUM=5 RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT From 97f2f6ab43d90cf532a36263c430b702c20ac16f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 18:14:22 -0500 Subject: [PATCH 1015/6505] Update gamuntu_setup.sh --- setup/gamuntu_setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/gamuntu_setup.sh b/setup/gamuntu_setup.sh index fc268275..4930a0a0 100644 --- a/setup/gamuntu_setup.sh +++ b/setup/gamuntu_setup.sh @@ -10,6 +10,7 @@ CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' RETRY_NUM=5 RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -105,4 +106,4 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /gamuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /gamuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From c37e0f77d3878086ff212821bac85978681375d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 18:16:32 -0500 Subject: [PATCH 1016/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index a6995514..19f052b3 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -10,6 +10,7 @@ CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' RETRY_NUM=5 RETRY_EVERY=3 +NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT From ca3e275d0ebd01a237d4f271548940c7b1298c26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 18:46:35 -0500 Subject: [PATCH 1017/6505] Update usb-passthrough.sh --- misc/usb-passthrough.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index c1b8dfa2..96a45ec3 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -36,7 +36,7 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - +CHAR_DEVS+=("166:.*") CHAR_DEVS+=("188:.*") CHAR_DEVS+=("189:.*") From 6c66c52ecdc449cf16cff36ad5f65a92781b4d61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 19:30:52 -0500 Subject: [PATCH 1018/6505] Update zigbee2mqtt_container.sh --- ct/zigbee2mqtt_container.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ct/zigbee2mqtt_container.sh b/ct/zigbee2mqtt_container.sh index aa175e82..4e7d8c65 100644 --- a/ct/zigbee2mqtt_container.sh +++ b/ct/zigbee2mqtt_container.sh @@ -149,6 +149,11 @@ LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file EOF MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 3915ac6ad20ba39d52f9dc37046b5e952006ea8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 19:42:52 -0500 Subject: [PATCH 1019/6505] Update README.md --- README.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/README.md b/README.md index 71ca2885..1f8c8822 100644 --- a/README.md +++ b/README.md @@ -487,16 +487,6 @@ To create a new Proxmox Zigbee2MQTT LXC Container, run the following from Proxmo bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt_container.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

- - -⚙️ **To allow USB device passthrough:** - -In the **Proxmox Shell** run (**replace `106` with your LXC ID**) -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 -``` - -Reboot the LXC to apply the changes ⚙️ **Determine the location of your adapter** @@ -533,6 +523,7 @@ mqtt: version: 4 serial: port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 + #adapter: deconz ### uncomment adapter: deconz for ConBee II ### advanced: pan_id: GENERATE network_key: GENERATE From e9e63c858d8539e13217946edc2cabb0d4d85df9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 19:58:24 -0500 Subject: [PATCH 1020/6505] Update zwavejs2mqtt_container.sh --- ct/zwavejs2mqtt_container.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ct/zwavejs2mqtt_container.sh b/ct/zwavejs2mqtt_container.sh index 3d42e6a5..2e908b54 100644 --- a/ct/zwavejs2mqtt_container.sh +++ b/ct/zwavejs2mqtt_container.sh @@ -149,6 +149,11 @@ LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file EOF MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 7ebc1ede6045515f09dd7502d47624dd14d185cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 20:01:56 -0500 Subject: [PATCH 1021/6505] Update README.md --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 1f8c8822..b32b7d93 100644 --- a/README.md +++ b/README.md @@ -564,14 +564,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z **Zwavejs2MQTT Interface - IP:8091** -⚙️ **To allow USB device passthrough:** - -In the Proxmox web shell run (**replace `106` with your LXC ID)** -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 -``` - -Reboot the LXC to apply the changes ____________________________________________________________________________________________ From 04e4dae0c67806f17d7a2aa67753f97959b7ada1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 20:09:07 -0500 Subject: [PATCH 1022/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c34fe6d2..fface5a5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file. ### Changed +- **Zigbee2MQTT LXC** + - added USB passthrough during installation (no extra script) +- **Zwavejs2MQTT LXC** + - added USB passthrough during installation (no extra script) - **Jellyfin Media Server LXC** - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issuecomment-1033567284) due to issues. - Changed install method. From 34bd3e39f04681f9ec98d3a7c068ad57fb42f2f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 20:12:01 -0500 Subject: [PATCH 1023/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index fface5a5..bb77ed4c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - **Zigbee2MQTT LXC** - added USB passthrough during installation (no extra script) + - Improve documentation - **Zwavejs2MQTT LXC** - added USB passthrough during installation (no extra script) - **Jellyfin Media Server LXC** From b69b13c908d24b0f145eead3ab47c9a9dcfac5c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 20:41:56 -0500 Subject: [PATCH 1024/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b32b7d93..e1545170 100644 --- a/README.md +++ b/README.md @@ -474,7 +474,7 @@ ________________________________________________________________________________
-Zigbee2MQTT LXC + 🔸Zigbee2MQTT LXC

logo.png

@@ -549,7 +549,7 @@ ________________________________________________________________________________
-Zwavejs2MQTT LXC + 🔸Zwavejs2MQTT LXC

From e1aeb13ac0810d309f47f02d6974bf4d9ed66f30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 21:44:07 -0500 Subject: [PATCH 1025/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bb77ed4c..b7269b16 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file. - **Zwavejs2MQTT LXC** - added USB passthrough during installation (no extra script) - **Jellyfin Media Server LXC** - - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issuecomment-1033567284) due to issues. + - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issue-1120593435) due to issues. - Changed install method. - **Home Assistant Container LXC (Podman)** - add script for easy Home Assistant update From 655a768dc48eb136e6f541da5a35df02e5c5b116 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Feb 2022 21:52:54 -0500 Subject: [PATCH 1026/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e1545170..9cf5ca4e 100644 --- a/README.md +++ b/README.md @@ -523,7 +523,7 @@ mqtt: version: 4 serial: port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 - #adapter: deconz ### uncomment adapter: deconz for ConBee II ### + #adapter: deconz #(uncomment for ConBee II) advanced: pan_id: GENERATE network_key: GENERATE From 06550a59e00da3f9d79562961c4c79caa1e9b358 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 07:34:06 -0500 Subject: [PATCH 1027/6505] Add files via upload --- setup/motioneye_setup.sh | 103 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 setup/motioneye_setup.sh diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh new file mode 100644 index 00000000..e19c982b --- /dev/null +++ b/setup/motioneye_setup.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" + sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen + locale-gen >/dev/null + while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + exit 1 + fi + done +echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + +echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" + apt-get update &>/dev/null + apt-get -qqy upgrade &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" + apt-get update &>/dev/null + apt-get -qqy install \ + curl \ + sudo \ + python-dev-is-python2 \ + python-setuptools \ + libssl-dev \ + libcurl4-openssl-dev \ + libjpeg-dev \ + zlib1g-dev \ + libffi-dev \ + libzbar-dev \ + libzbar0 &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" + apt-get install ffmpeg v4l-utils -y + +echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" + apt-get install motion -y + systemctl stop motion + systemctl disable motion + +echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" + apt-get install python2 curl -y + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py + python2 get-pip.py + +echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" + pip install motioneye + mkdir -p /etc/motioneye + cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf + mkdir -p /var/lib/motioneye + +echo -e "${CHECKMARK} \e[1;92m Creating Service file motioneye.service... \e[0m" + cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service + +echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat << EOF > $GETTY_OVERRIDE + [Service] + ExecStart= + ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + systemctl enable motioneye + systemctl start motioneye + +echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" + rm -rf /motioneye_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file From b26992134d18ebb0382f76918917cdd158e752eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 07:34:31 -0500 Subject: [PATCH 1028/6505] Add files via upload --- ct/motioneye_container.sh | 168 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 ct/motioneye_container.sh diff --git a/ct/motioneye_container.sh b/ct/motioneye_container.sh new file mode 100644 index 00000000..fc487969 --- /dev/null +++ b/ct/motioneye_container.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New MotionEye LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if [ ! -z ${MOUNT+x} ]; then + pct unmount $CTID + fi + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function load_module() { + if ! $(lsmod | grep -Fq $1); then + modprobe $1 &>/dev/null || \ + die "Failed to load '$1' module." + fi + MODULES_PATH=/etc/modules + if ! $(grep -Fxq "$1" $MODULES_PATH); then + echo "$1" >> $MODULES_PATH || \ + die "Failed to add '$1' module to load at boot." + fi +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/motioneye_setup.sh + +load_module overlay + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content rootdir | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Container' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using '$STORAGE' for storage location." + +CTID=$(pvesh get /cluster/nextid) +info "Container ID is $CTID." + +echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +pveam update >/dev/null + +echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +OSTYPE=debian +OSVERSION=${OSTYPE}-11 +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) +TEMPLATE="${TEMPLATES[-1]}" +pveam download local $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + dir|nfs) + DISK_EXT=".raw" + DISK_REF="$CTID/" + ;; + zfspool) + DISK_PREFIX="subvol" + DISK_FORMAT="subvol" + ;; +esac +DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} +ROOTFS=${STORAGE}:${DISK_REF-}${DISK} + +echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +DISK_SIZE=2G +pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." +else + mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null +fi +ARCH=$(dpkg --print-architecture) +HOSTNAME=motioneye +TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ + -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ + -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +MOUNT=$(pct mount $CTID | cut -d"'" -f 2) +ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime +pct unmount $CTID && unset MOUNT + +echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +pct start $CTID +pct push $CTID motioneye_setup.sh /motioneye_setup.sh -perms 755 +pct exec $CTID /motioneye_setup.sh + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +info "Successfully Created MotionEye LXC to $CTID." +echo -e "\e[1;92m MotionEye should be reachable by going to the following URL. + http://${IP}:8765 +\e[0m" \ No newline at end of file From 8a4a00703aecbe9515e5f6419b0e6ca374053733 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 07:50:09 -0500 Subject: [PATCH 1029/6505] Add files via upload --- setup/motioneye_setup.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index e19c982b..267083d7 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -62,20 +62,20 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" libzbar0 &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" - apt-get install ffmpeg v4l-utils -y + apt-get install ffmpeg v4l-utils -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" - apt-get install motion -y - systemctl stop motion - systemctl disable motion + apt-get install motion -y &>/dev/null + systemctl stop motion &>/dev/null + systemctl disable motion &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get install python2 curl -y - curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py - python2 get-pip.py + apt-get install python2 curl -y &>/dev/null + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null + python2 get-pip.py &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - pip install motioneye + pip2 install motioneye mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye From 3f682792c2185f2c3616173b18a5529e8f5e6487 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 08:05:51 -0500 Subject: [PATCH 1030/6505] Add files via upload --- setup/motioneye_setup.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index 267083d7..1c0c4a04 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -64,18 +64,19 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" apt-get install ffmpeg v4l-utils -y &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" + apt-get install python2 curl -y &>/dev/null + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null + python2 get-pip.py &>/dev/null + apt-get install python-pillow &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" apt-get install motion -y &>/dev/null systemctl stop motion &>/dev/null systemctl disable motion &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get install python2 curl -y &>/dev/null - curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null - python2 get-pip.py &>/dev/null - echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - pip2 install motioneye + pip install motioneye mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye From 78c1a7b438d30faf8c9df813a55182e188b40d7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 08:48:34 -0500 Subject: [PATCH 1031/6505] Add files via upload --- setup/motioneye_setup.sh | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index 1c0c4a04..b051fc8a 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -50,22 +50,13 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ - sudo \ - python-dev-is-python2 \ - python-setuptools \ - libssl-dev \ - libcurl4-openssl-dev \ - libjpeg-dev \ - zlib1g-dev \ - libffi-dev \ - libzbar-dev \ - libzbar0 &>/dev/null + sudo &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" apt-get install ffmpeg v4l-utils -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get install python2 curl -y &>/dev/null + apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null python2 get-pip.py &>/dev/null apt-get install python-pillow &>/dev/null @@ -76,13 +67,13 @@ echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" systemctl disable motion &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - pip install motioneye + pip install motioneye &>/dev/null mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye echo -e "${CHECKMARK} \e[1;92m Creating Service file motioneye.service... \e[0m" - cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service + cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" rm /etc/motd From 86118da405af4b0525c468e6bff3f9229046513b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 09:02:09 -0500 Subject: [PATCH 1032/6505] Add files via upload --- setup/motioneye_setup.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index b051fc8a..1961524b 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -59,7 +59,6 @@ echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null python2 get-pip.py &>/dev/null - apt-get install python-pillow &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" apt-get install motion -y &>/dev/null From 743b01a4b06d7f1a22150c6000373fe6b508e2ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 09:04:00 -0500 Subject: [PATCH 1033/6505] Add files via upload --- ct/motioneye_container.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/motioneye_container.sh b/ct/motioneye_container.sh index fc487969..28a88567 100644 --- a/ct/motioneye_container.sh +++ b/ct/motioneye_container.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash while true; do - read -p "This will create a New MotionEye LXC Container. Proceed(y/n)?" yn + read -p "This will create a New MotionEye NVR LXC Container. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -132,7 +132,7 @@ DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=2G +DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." @@ -163,6 +163,6 @@ pct exec $CTID /motioneye_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') info "Successfully Created MotionEye LXC to $CTID." -echo -e "\e[1;92m MotionEye should be reachable by going to the following URL. +echo -e "\e[1;92m MotionEye NVR should be reachable by going to the following URL. http://${IP}:8765 \e[0m" \ No newline at end of file From 69a492ad1b188cd55181ae5ec6fe693a466fb2bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 09:18:57 -0500 Subject: [PATCH 1034/6505] Add files via upload --- setup/motioneye_setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index 1961524b..32070c8d 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -66,8 +66,9 @@ echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" systemctl disable motion &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - pip install motioneye &>/dev/null + apt-get update &>/dev/null mkdir -p /etc/motioneye + pip install motioneye &>/dev/null cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye From 921796807d12c6eea7d11bb04e68da7c352525c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 09:32:41 -0500 Subject: [PATCH 1035/6505] Add files via upload --- setup/motioneye_setup.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index 32070c8d..8fdd2176 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -52,23 +52,23 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" curl \ sudo &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" - apt-get install ffmpeg v4l-utils -y &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null - curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null - python2 get-pip.py &>/dev/null - echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" apt-get install motion -y &>/dev/null systemctl stop motion &>/dev/null systemctl disable motion &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" + apt-get install ffmpeg v4l-utils -y &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" + apt-get install python2 -y + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null + python2 get-pip.py &>/dev/null + apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - apt-get update &>/dev/null - mkdir -p /etc/motioneye pip install motioneye &>/dev/null + mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye From eef95d73501bdf08361858ec03f0b081acfe1cb2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 09:46:30 -0500 Subject: [PATCH 1036/6505] Add files via upload --- setup/motioneye_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index 8fdd2176..265c8613 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -61,13 +61,13 @@ echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" apt-get install ffmpeg v4l-utils -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get install python2 -y + apt-get install python2 -y &>/dev/null curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null python2 get-pip.py &>/dev/null apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - pip install motioneye &>/dev/null + pip2 install motioneye &>/dev/null mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye From 60ef518c845c6fbb745c74895eeb73697ffc2658 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 10:31:25 -0500 Subject: [PATCH 1037/6505] Add files via upload --- setup/motioneye_setup.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index 265c8613..c59709b2 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -61,13 +61,16 @@ echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" apt-get install ffmpeg v4l-utils -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" + apt-get update &>/dev/null apt-get install python2 -y &>/dev/null curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null python2 get-pip.py &>/dev/null - apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null - + #apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null + apt-get install libffi-dev libzbar-dev libzbar0 -y + apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - pip2 install motioneye &>/dev/null + apt-get update &>/dev/null + pip2 install motioneye mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye From 2bacfa2e2faf570f2fc4a72d937a3a67a46ed148 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 10:47:53 -0500 Subject: [PATCH 1038/6505] Add files via upload --- setup/motioneye_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index c59709b2..a55d61b3 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -70,7 +70,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" apt-get update &>/dev/null - pip2 install motioneye + sudo pip install motioneye mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye From b51c9d7c98ce57c72ef36c5b95ead3412165204d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 10:50:41 -0500 Subject: [PATCH 1039/6505] Add files via upload --- setup/motioneye_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index a55d61b3..bc9060dd 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -66,8 +66,8 @@ echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null python2 get-pip.py &>/dev/null #apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null - apt-get install libffi-dev libzbar-dev libzbar0 -y - apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y + apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null + apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" apt-get update &>/dev/null sudo pip install motioneye From 0482815a67f0bbc521cbef98ac39b95977a7027e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 11:04:39 -0500 Subject: [PATCH 1040/6505] Update motioneye_setup.sh --- setup/motioneye_setup.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index bc9060dd..00dea1b9 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -65,12 +65,11 @@ echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" apt-get install python2 -y &>/dev/null curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null python2 get-pip.py &>/dev/null - #apt-get install python-dev-is-python2 python-setuptools libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libffi-dev libzbar-dev libzbar0 -y &>/dev/null apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" apt-get update &>/dev/null - sudo pip install motioneye + sudo pip install motioneye &>/dev/null mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye @@ -95,4 +94,4 @@ EOF systemctl start motioneye echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" - rm -rf /motioneye_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file + rm -rf /motioneye_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 85277789f9faac0fa004d88c92f1ff940c1293b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 11:17:56 -0500 Subject: [PATCH 1041/6505] Update motioneye_setup.sh --- setup/motioneye_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh index 00dea1b9..ee7a6301 100644 --- a/setup/motioneye_setup.sh +++ b/setup/motioneye_setup.sh @@ -90,8 +90,8 @@ echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - systemctl enable motioneye - systemctl start motioneye + systemctl enable motioneye &>/dev/null + systemctl start motioneye echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /motioneye_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 94657af20cbc38553a8cd6cdff02fcb55fa9ad75 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 11:20:13 -0500 Subject: [PATCH 1042/6505] Add files via upload --- misc/images/motioneye-256x256.png | Bin 0 -> 5256 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/motioneye-256x256.png diff --git a/misc/images/motioneye-256x256.png b/misc/images/motioneye-256x256.png new file mode 100644 index 0000000000000000000000000000000000000000..2f0fbaf37a0401dcbd764c13e5d11c59b27f599d GIT binary patch literal 5256 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 QQw5} Date: Thu, 10 Feb 2022 11:36:08 -0500 Subject: [PATCH 1043/6505] Update README.md --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 9cf5ca4e..c5e72967 100644 --- a/README.md +++ b/README.md @@ -692,6 +692,43 @@ ________________________________________________________________________________
+
+🔸MotionEye NVR LXC + +

+ +

MotionEye NVR LXC

+ +To create a new Proxmox MotionEye NVR LXC, run the following in the Proxmox web shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/motioneye_container.sh)" +``` + +

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. + +**MotionEye Interface - IP:8765** + +⚙️ **Initial Login** + +**username** + `admin` + + **password** + ` ` + +⚙️ **To Update MotionEye** + +Run from the LXC console + ```yaml +pip install motioneye --upgrade +``` + +____________________________________________________________________________________________ + +
Webmin System Administration From 9422e310d1dfb76eb9f763b6edbad2f9af1dec79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 11:38:20 -0500 Subject: [PATCH 1044/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b7269b16..ff2ac3bf 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-10 + +### Changed + +- **MotionEye NVR LXC** + - New script + ## 2022-02-09 ### Changed From 8546b810b094addceaad21b986a41271b823cbce Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 15:14:16 -0500 Subject: [PATCH 1045/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 102 ++++++++++++---------------------------- 1 file changed, 30 insertions(+), 72 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 66d31c3b..7b62469d 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -28,9 +28,9 @@ function msg() { } echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do + sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen + locale-gen >/dev/null + while [ "$(hostname -I)" = "" ]; do 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" sleep $RETRY_EVERY ((NUM--)) @@ -39,80 +39,38 @@ while [ "$(hostname -I)" = "" ]; do 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" exit 1 fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" + done +echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null + apt-get update &>/dev/null + apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" -apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* + apt-get update &>/dev/null + apt-get -qqy install \ + curl \ + sudo &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" + sudo apt install extrepo -y &>/dev/null + sudo extrepo enable jellyfin echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" -sudo mkdir /opt/jellyfin -cd /opt/jellyfin -sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz &>/dev/null -sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz &>/dev/null -sudo ln -s jellyfin_10.7.7 jellyfin -sudo mkdir data cache config log - -echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" -apt-get update &>/dev/null -apt-get -y install ffmpeg &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Creating Service file jellyfin.service... \e[0m" -file_path="/opt/jellyfin/jellyfin.sh" -echo "#!/bin/bash -/opt/jellyfin/jellyfin/jellyfin - -d /opt/jellyfin/data - -C /opt/jellyfin/cache - -c /opt/jellyfin/config - -l /opt/jellyfin/log - --ffmpeg /usr/share/jellyfin-ffmpeg/ffmpeg" > $file_path -sudo chmod +x /opt/jellyfin/jellyfin.sh - -service_path="/etc/systemd/system/jellyfin.service" -echo "[Unit] -Description=Jellyfin -After=network.target - -[Service] -Type=simple -User=root -Restart=always -ExecStart=/opt/jellyfin/jellyfin.sh - -[Install] -WantedBy=multi-user.target" > $service_path -sudo chmod 644 /etc/systemd/system/jellyfin.service - + apt-get update &>/dev/null + apt-get install jellyfin -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -sudo systemctl enable jellyfin.service &>/dev/null -sudo systemctl start jellyfin.service &>/dev/null - + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat << EOF > $GETTY_OVERRIDE + [Service] + ExecStart= + ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM + EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + systemctl enable jellyfin.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* + rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 48399658b3624ef1829662229e8a4936a2a2e598 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 15:17:11 -0500 Subject: [PATCH 1046/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index a76f4a88..f7ca1133 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -146,6 +146,8 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir @@ -163,4 +165,7 @@ pct push $CTID jellyfin_setup.sh /jellyfin_setup.sh -perms 755 pct exec $CTID /jellyfin_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Jellyfin Server LXC Container to $CTID at IP Address ${IP}:8096" +info "Successfully Created Jellyfin Media Server LXC to $CTID." +echo -e "\e[1;92m Jellyfin Media Server should be reachable by going to the following URL. + http://${IP}:8096 +\e[0m" From 1de4d6a7d2c1afadea2ff9cc888f84685603c9fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 15:17:25 -0500 Subject: [PATCH 1047/6505] Delete jellyfin2_setup.sh --- setup/jellyfin2_setup.sh | 91 ---------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 setup/jellyfin2_setup.sh diff --git a/setup/jellyfin2_setup.sh b/setup/jellyfin2_setup.sh deleted file mode 100644 index 815bf213..00000000 --- a/setup/jellyfin2_setup.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - gnupg \ - apt-transport-https \ - ca-certificates \ - git &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" -apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* - -echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -wget -q -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian bullseye main" | tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" -apt-get update &>/dev/null -apt-get install jellyfin -y &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -#usermod -a -G input jellyfin -#usermod -a -G render jellyfin -systemctl enable jellyfin.service &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /jellyfin2_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 765f0f76a70ce64ad881cb216998a991c287e33f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 15:27:56 -0500 Subject: [PATCH 1048/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 7b62469d..bf42ac14 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -51,10 +51,8 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get -qqy install \ curl \ sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" sudo apt install extrepo -y &>/dev/null - sudo extrepo enable jellyfin + sudo extrepo enable jellyfin &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt-get update &>/dev/null @@ -64,13 +62,13 @@ echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) - cat << EOF > $GETTY_OVERRIDE - [Service] - ExecStart= - ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM - EOF +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') systemctl enable jellyfin.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" - rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From fad259b59276ca400d5cf0739cbb8b6eb7623488 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 15:43:16 -0500 Subject: [PATCH 1049/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index bf42ac14..bba8df45 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -67,8 +67,7 @@ cat << EOF > $GETTY_OVERRIDE ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - systemctl enable jellyfin.service &>/dev/null +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 4379c5204590e292206dd15ed3597dac3ea45a0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 15:56:50 -0500 Subject: [PATCH 1050/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index bba8df45..e11f7e76 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -55,8 +55,8 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" sudo extrepo enable jellyfin &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" - apt-get update &>/dev/null - apt-get install jellyfin -y &>/dev/null + sudo apt-get update &>/dev/null + sudo apt-get install jellyfin -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin From 5473fc1441accf0cea9410237f582548094c6e3e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 15:58:26 -0500 Subject: [PATCH 1051/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index e11f7e76..851e2962 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -56,7 +56,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" sudo apt-get update &>/dev/null - sudo apt-get install jellyfin -y &>/dev/null + sudo apt install jellyfin -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin From c399f5dcbfe21dd0ef772e8802a696afe0923fb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 16:54:38 -0500 Subject: [PATCH 1052/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 851e2962..fc8eff05 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -28,9 +28,9 @@ function msg() { } echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" - sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen - locale-gen >/dev/null - while [ "$(hostname -I)" = "" ]; do +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" sleep $RETRY_EVERY ((NUM--)) @@ -39,29 +39,35 @@ echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" exit 1 fi - done -echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" +done + echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" - apt-get update &>/dev/null - apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null - sudo apt install extrepo -y &>/dev/null - sudo extrepo enable jellyfin &>/dev/null - + sudo apt install apt-transport-https -y &>/dev/null + sudo apt-get install software-properties-common -y &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" +# sudo apt install extrepo -y &>/dev/null +# sudo extrepo enable jellyfin +sudo add-apt-repository universe +wget -O -q - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" - sudo apt-get update &>/dev/null - sudo apt install jellyfin -y &>/dev/null +apt-get update &>/dev/null +sudo apt install jellyfin -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) cat << EOF > $GETTY_OVERRIDE [Service] ExecStart= From a7d0c3ec271ab9193d9d177812292ab83547f155 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 16:55:42 -0500 Subject: [PATCH 1053/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index f7ca1133..cd6e7437 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -108,8 +108,8 @@ info "Container ID is $CTID." echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 +OSTYPE=ubuntu +OSVERSION=${OSTYPE}-21.10 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From c5f3fe6b75f02190547782bf2c8ca622369fa93f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 17:03:35 -0500 Subject: [PATCH 1054/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index fc8eff05..ac6fc6b2 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -55,14 +55,14 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" sudo apt-get install software-properties-common -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -# sudo apt install extrepo -y &>/dev/null -# sudo extrepo enable jellyfin -sudo add-apt-repository universe -wget -O -q - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +sudo add-apt-repository universe &>/dev/null +wget -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt-get update &>/dev/null sudo apt install jellyfin -y &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin From d2c31d806f7af8df906a80740ab7ed82606c34ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 17:04:31 -0500 Subject: [PATCH 1055/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index ac6fc6b2..26d748f1 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -55,7 +55,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" sudo apt-get install software-properties-common -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -sudo add-apt-repository universe &>/dev/null +sudo add-apt-repository universe -y &>/dev/null wget -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null From 84b77fcfeaa58f93324023246d95879b25145d54 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 17:11:18 -0500 Subject: [PATCH 1056/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 26d748f1..e7877beb 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -56,12 +56,12 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" sudo add-apt-repository universe -y &>/dev/null -wget -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +wget -q -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt-get update &>/dev/null -sudo apt install jellyfin -y &>/dev/null +sudo apt install jellyfin-server -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* From 5617e7a765e89d9664d719ef73a5c31a4760657e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 18:07:10 -0500 Subject: [PATCH 1057/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index e7877beb..8528934f 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -55,14 +55,33 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" sudo apt-get install software-properties-common -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -sudo add-apt-repository universe -y &>/dev/null +sudo add-apt-repository universe &>/dev/null wget -q -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null - echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" apt-get update &>/dev/null sudo apt install jellyfin-server -y &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Creating Jellyfin Service... \e[0m" +cat << 'EOF' > /lib/systemd/system/jellyfin.service +[Unit] +Description = Jellyfin Media Server +After = network.target + +[Service] +Type = simple +EnvironmentFile = /etc/default/jellyfin +User = root +ExecStart = /usr/bin/jellyfin ${JELLYFIN_WEB_OPT} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELL> +Restart = on-failure +TimeoutSec = 15 + +[Install] +WantedBy = multi-user.target +EOF + +ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web + echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" chmod -x /etc/update-motd.d/* touch ~/.hushlogin From f02579ad9209bd585370697f007fa9fb277c3db8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 18:08:27 -0500 Subject: [PATCH 1058/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 8528934f..2588e6e4 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -55,7 +55,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" sudo apt-get install software-properties-common -y &>/dev/null echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -sudo add-apt-repository universe &>/dev/null +sudo add-apt-repository universe -y &>/dev/null wget -q -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" From 7b9ea6831a00b478e9a769ac1fd5701ff6b65605 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 18:18:33 -0500 Subject: [PATCH 1059/6505] Update README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index c5e72967..3db23e55 100644 --- a/README.md +++ b/README.md @@ -642,6 +642,32 @@ ________________________________________________________________________________
+
+ 🔸Jellyfin Media Server LXC +

+

Jellyfin Media Server LXC

+ +To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox web shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/jellyfin_container.sh)" +``` +

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. + +**Jellyfin Media Server Interface - IP:8096** + +⚙️ **To Update Jellyfin Media Server** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` +____________________________________________________________________________________________ + +
+
Pi-hole LXC From 39e9f6aaaa5a56d3491aa6bc744c4d218321752a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 18:28:44 -0500 Subject: [PATCH 1060/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ff2ac3bf..f5c6c09c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. ### Changed +- **Jellyfin Media Server LXC** + - new script to fix [start issue](https://github.com/tteck/Proxmox/issues/29#issue-1127457380) - **MotionEye NVR LXC** - New script From efdd4477b11bcd6e63f1df2fb55dd7b7b3d8ce7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 19:05:26 -0500 Subject: [PATCH 1061/6505] Update README.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 3db23e55..d61e0436 100644 --- a/README.md +++ b/README.md @@ -612,6 +612,25 @@ ________________________________________________________________________________
+
+ 🔸GamUntu LXC +

GamUntu +

GamUntu LXC Container

+ +GamUntu is Ubuntu 21.10, Docker, Docker Compose, ZFS Support, USB Passthrough, Webmin System Administration and Hardware Acceleration all baked in! + +To create a new Proxmox GamUntuLXC Container, run the following in the Proxmox web shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/gamuntu_container.sh)" +``` +

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

+ +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. + +____________________________________________________________________________________________ + +
Plex Media Server LXC From 577e7465059cb9672d1c22a5baa7c4c20f0e544e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 19:06:45 -0500 Subject: [PATCH 1062/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f5c6c09c..090a39c1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. ### Changed +- **GamUntu LXC** + - New script - **Jellyfin Media Server LXC** - new script to fix [start issue](https://github.com/tteck/Proxmox/issues/29#issue-1127457380) - **MotionEye NVR LXC** From 88d9a4724feaab87beb4fbd28af5189d256a5fad Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 19:09:03 -0500 Subject: [PATCH 1063/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 090a39c1..1d959a7d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -23,7 +23,7 @@ All notable changes to this project will be documented in this file. - **Zwavejs2MQTT LXC** - added USB passthrough during installation (no extra script) - **Jellyfin Media Server LXC** - - Moved to [testing](https://github.com/tteck/Proxmox/issues/22#issue-1120593435) due to issues. + - Moved to testing due to issues. - Changed install method. - **Home Assistant Container LXC (Podman)** - add script for easy Home Assistant update @@ -36,8 +36,6 @@ All notable changes to this project will be documented in this file. - Add Docker Support - **Ubuntu 21.10 LXC** - Add Docker Support -- **New Test Script** - - [GamUntu](https://github.com/tteck/Proxmox/issues/22#issuecomment-1030707954) ## 2022-02-05 From 9f7c81b4b04e4c568f396b49b013c2987ea1c8b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Feb 2022 19:17:37 -0500 Subject: [PATCH 1064/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d61e0436..03dc9c14 100644 --- a/README.md +++ b/README.md @@ -614,7 +614,7 @@ ________________________________________________________________________________
🔸GamUntu LXC -

GamUntu +

GamUntu

GamUntu LXC Container

GamUntu is Ubuntu 21.10, Docker, Docker Compose, ZFS Support, USB Passthrough, Webmin System Administration and Hardware Acceleration all baked in! From 8ab12ffa391ae11593411abcc624105b0874f78c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Feb 2022 07:42:33 -0500 Subject: [PATCH 1065/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 03dc9c14..3fae9189 100644 --- a/README.md +++ b/README.md @@ -815,7 +815,7 @@ ________________________________________________________________________________
🔸Vaultwarden LXC -

+

Vaultwarden LXC

From 1a46e6fa3287cb764b0a6b5222027ab874f2a045 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Feb 2022 15:11:39 -0500 Subject: [PATCH 1066/6505] Update README.md --- README.md | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 3fae9189..03e76bd1 100644 --- a/README.md +++ b/README.md @@ -321,10 +321,6 @@ ________________________________________________________________________________
- - - -
Node-Red LXC @@ -469,10 +465,6 @@ ________________________________________________________________________________
- - - -
🔸Zigbee2MQTT LXC @@ -708,6 +700,11 @@ Run from the LXC console ```yaml pihole -a -p ``` +⚙️ **To Update Pi-hole:** + +```yaml +Updates from the Pi-hole UI +``` ____________________________________________________________________________________________ @@ -733,7 +730,12 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/a (For the Home Assistant Integration, use port `80` not `3000`) -____________________________________________________________________________________________ +⚙️ **To Update Adguard** + +```yaml +Updates from the Adguard UI +``` +__________________________________________________________________________________________
@@ -762,7 +764,7 @@ After the script completes, If you're dissatisfied with the default settings, cl `admin` **password** - ` ` + `Leave Blank` ⚙️ **To Update MotionEye** @@ -804,8 +806,13 @@ Benefits include automatic daily security updates, backup and restore, file mana **password** `root` +⚙️ **To Update Webmin** + +```yaml +Updates from the Webmin UI +``` ⚙️ **To Uninstall Webmin** - ```yaml +```yaml bash /etc/webmin/uninstall.sh ``` ___________________________________________________________________________________________ From f5d23aed0a6dd879b29c1d066834044e09f490d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 08:14:10 -0500 Subject: [PATCH 1067/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 03e76bd1..97ca022f 100644 --- a/README.md +++ b/README.md @@ -820,7 +820,7 @@ ________________________________________________________________________________
-🔸Vaultwarden LXC + Vaultwarden LXC

From d4dd3458d6abc83b97d9e7f7e9a4b6db0bc80d48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 08:54:07 -0500 Subject: [PATCH 1068/6505] Update README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 97ca022f..64d9441a 100644 --- a/README.md +++ b/README.md @@ -579,6 +579,13 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/d After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +⚙️ **To Update Debian 11** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` + ____________________________________________________________________________________________
@@ -600,6 +607,13 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/u After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +⚙️ **To Update Ubuntu 21.10** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` + ____________________________________________________________________________________________
@@ -620,6 +634,13 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/g After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +⚙️ **To Update GamUntu** + +Run from the LXC console +```yaml +apt update && apt upgrade -y +``` + ____________________________________________________________________________________________
From 20aa1b7761074b50c2941adcbf458155ffc5a4d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 09:42:16 -0500 Subject: [PATCH 1069/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 19f052b3..d5e6a1be 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -56,8 +56,23 @@ apt-get -qqy install \ echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" apt-get -y install podman &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Pulling Yacht Image...\e[0m" +podman pull ghcr.io/selfhostedpro/yacht:latest &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Installing Yacht... \e[0m" +podman volume create yacht >/dev/null +podman run -d \ + --name yacht \ + -v /var/run/podman/podman.sock:/var/run/docker.sock \ + -v yacht:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + -p 8000:8000 \ + --net=host \ + selfhostedpro/yacht:latest + echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null +podman pull ghcr.io/homeassistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From 78ba2c7586204cf3341fc132e24edd809c0592d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 09:42:57 -0500 Subject: [PATCH 1070/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index f0a2b965..9a28cd82 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman_ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/podman_ha_setup.sh load_module overlay From 6905cd2d09c56655356b5419c43577b7c72f9eb0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 09:51:15 -0500 Subject: [PATCH 1071/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index d5e6a1be..147b158d 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -68,8 +68,7 @@ podman run -d \ -v /etc/localtime:/etc/localtime:ro \ -v /etc/timezone:/etc/timezone:ro \ -p 8000:8000 \ - --net=host \ - selfhostedpro/yacht:latest + selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" podman pull ghcr.io/homeassistant/home-assistant:stable &>/dev/null From c6f0e4d65df895623de325e1ad34777592ef27dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 09:54:41 -0500 Subject: [PATCH 1072/6505] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 64d9441a..fa613566 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,8 @@ ________________________________________________________________________________ 🔸Home Assistant Container LXC (Podman)

-@home-assistant

- +@home-assistant

+

Podman Home Assistant Container LXC

With ZFS Filesystem Support

To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. @@ -94,6 +94,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/p After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. **Home Assistant Interface - IP:8123** + +**Yacht Interface - IP:8000** ⚙️ **Path to HA /config** ```yaml From fc9f2252343c4e185974a24d5685d6074df34e4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 09:59:56 -0500 Subject: [PATCH 1073/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 147b158d..563f88f8 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -71,7 +71,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull ghcr.io/homeassistant/home-assistant:stable &>/dev/null +podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From a5985dafc65b339f59a62b70e67655b8ae73925d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 10:23:30 -0500 Subject: [PATCH 1074/6505] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index fa613566..42235204 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,20 @@ Run from the LXC console ```yaml ./update.sh ``` +⚙️ **Initial Yacht Login** + +**username** + ```yaml + admin@yacht.local + ``` + **password** + ```yaml + pass + ``` +⚙️ **Add Template** +```yaml +https://raw.githubusercontent.com/SelfhostedPro/selfhosted_templates/yacht/Template/template.json +``` ____________________________________________________________________________________________

n@m8YXQEz2*`HIz>xy#$H$Ih7aN1ZFO$sH&g` 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

From 94b46d16f23d3bd2e47f6bc4f0c8f0766ad7ac5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 10:26:37 -0500 Subject: [PATCH 1075/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index 9a28cd82..f0a2b965 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -73,7 +73,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/podman_ha_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman_ha_setup.sh load_module overlay From ec900d16a60a669bba45dd68291419c0a5c610d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 10:31:46 -0500 Subject: [PATCH 1076/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index f0a2b965..161caabf 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -168,11 +168,9 @@ pct push $CTID podman_ha_setup.sh /podman_ha_setup.sh -perms 755 pct exec $CTID /podman_ha_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created Podman Home Assistant Container LXC to $CTID." -msg " - -Home Assistant should be reachable by going to the following URL. - - - http://${IP}:8123 -" +info "Successfully Created Podman Home Assistant Container LXC to $CTID." +echo -e "\e[1;92m Home Assistant Container should be reachable by going to the following URL. + http://${IP}:8123 +Yacht should be reachable by going to the following URL. + http://${IP}:8000 +\e[0m" From 988c5178dacd681ae1d69e3125750caf4ef79222 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 10:34:07 -0500 Subject: [PATCH 1077/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42235204..54234a2c 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ Run from the LXC console ```yaml pass ``` -⚙️ **Add Template** +⚙️ **Add Yacht Template** ```yaml https://raw.githubusercontent.com/SelfhostedPro/selfhosted_templates/yacht/Template/template.json ``` From 203984d61eb325ee1684e127f2cf7b5da116c3d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 10:54:57 -0500 Subject: [PATCH 1078/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1d959a7d..91e8b05d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-12 + +### Changed + +- **Home Assistant Container LXC (Podman)** + - Add Yacht web interface for managing Podman containers + ## 2022-02-10 ### Changed From c913d0d9dd66a2aeec9d1692419428ee22184b11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 10:55:33 -0500 Subject: [PATCH 1079/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 54234a2c..a6d451b5 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc Reboot the LXC to apply the changes -⚙️ **To install HACS:** +⚙️ **To Install HACS:** Run the from the LXC console ```yaml From b58c8358fbfa86cffde09207d55650a0c2f70f06 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 13:36:39 -0500 Subject: [PATCH 1080/6505] Add files via upload --- misc/ha_copy_data_podman.sh | 122 ++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 misc/ha_copy_data_podman.sh diff --git a/misc/ha_copy_data_podman.sh b/misc/ha_copy_data_podman.sh new file mode 100644 index 00000000..19dc6915 --- /dev/null +++ b/misc/ha_copy_data_podman.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# Use to copy all data from one Home Assistant LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" +while true; do + read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Home Assistant LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Podman LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.02.12" 13 50 || exit +info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi +msg "Mounting Container Disks..." +DOCKER_PATH=/var/lib/docker/volumes/hass_config/ +PODMAN_PATH=/var/lib/containers/storage/volumes/hass_config/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${PODMAN_PATH}" ] || \ + die "Home Assistant directories in '$CTID_TO' not found." + +rm -rf ${CTID_TO_PATH}${PODMAN_PATH} +mkdir ${CTID_TO_PATH}${PODMAN_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Docker Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data_podman.sh)" \ No newline at end of file From d2c70ffd47f332225131b5f1fb175b041e526b91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 13:40:10 -0500 Subject: [PATCH 1081/6505] Update ha_copy_data_podman.sh --- misc/ha_copy_data_podman.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/ha_copy_data_podman.sh b/misc/ha_copy_data_podman.sh index 19dc6915..a7195bf6 100644 --- a/misc/ha_copy_data_podman.sh +++ b/misc/ha_copy_data_podman.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Use to copy all data from one Home Assistant LXC to another +# Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data_podman.sh)" while true; do - read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn + read -p "Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -112,11 +112,11 @@ RSYNC_OPTIONS=( --info=progress2 ) msg "<======== Docker Data ========>" -rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH} +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${PODMAN_PATH} echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data_podman.sh)" \ No newline at end of file +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data_podman.sh)" From 670fe2e972b41f9a6bc3a77f9e5818bae4f3d529 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 13:45:47 -0500 Subject: [PATCH 1082/6505] Update ha_copy_data_podman.sh --- misc/ha_copy_data_podman.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/ha_copy_data_podman.sh b/misc/ha_copy_data_podman.sh index a7195bf6..d0f7e345 100644 --- a/misc/ha_copy_data_podman.sh +++ b/misc/ha_copy_data_podman.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data_podman.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha_copy_data_podman.sh)" while true; do read -p "Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. Proceed(y/n)?" yn case $yn in @@ -119,4 +119,4 @@ info "Successfully Transferred Data." # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data_podman.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha_copy_data_podman.sh)" From 94ae4d4ebf33ec7993710902b2ef377d4e3f8ab5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 14:04:32 -0500 Subject: [PATCH 1083/6505] Update and rename ha_copy_data_podman.sh to ha-copy-data-podman.sh --- misc/{ha_copy_data_podman.sh => ha-copy-data-podman.sh} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename misc/{ha_copy_data_podman.sh => ha-copy-data-podman.sh} (97%) diff --git a/misc/ha_copy_data_podman.sh b/misc/ha-copy-data-podman.sh similarity index 97% rename from misc/ha_copy_data_podman.sh rename to misc/ha-copy-data-podman.sh index d0f7e345..a37c9779 100644 --- a/misc/ha_copy_data_podman.sh +++ b/misc/ha-copy-data-podman.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha_copy_data_podman.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" while true; do read -p "Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. Proceed(y/n)?" yn case $yn in @@ -119,4 +119,4 @@ info "Successfully Transferred Data." # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha_copy_data_podman.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" From 5bbfba5eca5310e86a18116793d17befec9e0f6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 14:11:04 -0500 Subject: [PATCH 1084/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 91e8b05d..4a56e61d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - **Home Assistant Container LXC (Podman)** - Add Yacht web interface for managing Podman containers + - new GUI script (ha-copy-data-podman.sh) to copy data from a **Home Assistant LXC** to a **Podman Home Assistant LXC** ## 2022-02-10 From 1dfa05af3a8e6ee88386b387b7c096825be96361 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 14:34:21 -0500 Subject: [PATCH 1085/6505] Update README.md --- README.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a6d451b5..f697f8d5 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,13 @@ nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” +⚙️ **Import Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** + +Run From The Proxmox Web Shell +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" + ``` + ⚙️ **To allow USB device passthrough:** In the Proxmox web shell run (**replace `106` with your LXC ID**) @@ -185,6 +192,12 @@ nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” +⚙️ **Import Data From a Existing Home Assistant LXC to another Home Assistant LXC** + +Run From The Proxmox Web Shell +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" + ``` ⚙️ **To Allow USB Device Passthrough:** @@ -550,6 +563,12 @@ Run from the LXC console ```yaml bash /opt/zigbee2mqtt/update.sh ``` +⚙️ **Import Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** + +Run From The Proxmox Web Shell +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" + ``` ____________________________________________________________________________________________ @@ -662,7 +681,7 @@ ________________________________________________________________________________
-Plex Media Server LXC + Plex Media Server LXC

@@ -685,6 +704,12 @@ Run from the LXC console ```yaml apt update && apt upgrade -y ``` +⚙️ **Import Data From a Existing Plex Media Server LXC to another Plex Media Server LXC** + +Run From The Proxmox Web Shell +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" + ``` ____________________________________________________________________________________________ From 558fb31e82499e992048bbfc95396750de6f88fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 14:45:56 -0500 Subject: [PATCH 1086/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4a56e61d..45310e29 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,8 @@ All notable changes to this project will be documented in this file. - **Home Assistant Container LXC (Podman)** - Add Yacht web interface for managing Podman containers - - new GUI script (ha-copy-data-podman.sh) to copy data from a **Home Assistant LXC** to a **Podman Home Assistant LXC** + - new GUI script to copy data from a **Home Assistant LXC** to a **Podman Home Assistant LXC** + - Improve documentation for several LXC's ## 2022-02-10 @@ -122,5 +123,5 @@ All notable changes to this project will be documented in this file. - **Proxmox VE 7 Post Install** - new *No-Nag* method - **misc** - - new GUI script (ha-copy-data.sh) to copy data from one Home Assistant LXC to another Home Assistant LXC (info inside script) - - new GUI script (z2m-copy-data.sh) to copy data from one Zigbee2MQTT LXC to another Zigbee2MQTT LXC (info inside script) + - new GUI script to copy data from one Home Assistant LXC to another Home Assistant LXC + - new GUI script to copy data from one Zigbee2MQTT LXC to another Zigbee2MQTT LXC From ae8e8c0f7873f288101da93909306f774ef7e78a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 15:28:07 -0500 Subject: [PATCH 1087/6505] Update README.md --- README.md | 112 +++++++++++++++++++++++++----------------------------- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index f697f8d5..e9af945a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) and attempt the *No-Nag* fix. -Run the following in the Proxmox Web Shell. ⚠️ **PVE7 ONLY** +Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/post_install.sh)" @@ -37,7 +37,7 @@ ________________________________________________________________________________ A dark theme for the Proxmox Web UI by [Weilbyte](https://github.com/Weilbyte/PVEDiscordDark) -Run the following in the Proxmox Web Shell. +Run the following in the Proxmox Shell. ```yaml bash <(curl -s https://raw.githubusercontent.com/Weilbyte/PVEDiscordDark/master/PVEDiscordDark.sh ) install @@ -57,7 +57,7 @@ ________________________________________________________________________________

Home Assistant OS VM

-To create a new Proxmox VM with the latest version of Home Assistant OS, run the following from Proxmox web shell +To create a new Proxmox VM with the latest version of Home Assistant OS, run the following in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/vm/haos_vm.sh)" @@ -82,7 +82,7 @@ ________________________________________________________________________________

Podman Home Assistant Container LXC

With ZFS Filesystem Support

-To create a new Proxmox Podman Home Assistant Container, run the following from Proxmox web shell. +To create a new Proxmox Podman Home Assistant Container, run the following in the Proxmox Shell. ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) @@ -103,7 +103,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ``` ⚙️ **To edit the HA configuration.yaml** -Run from the LXC console +Run in the LXC console ```yaml nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml ``` @@ -111,14 +111,14 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” ⚙️ **Import Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** -Run From The Proxmox Web Shell +Run in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" ``` ⚙️ **To allow USB device passthrough:** -In the Proxmox web shell run (**replace `106` with your LXC ID**) +Run in the Proxmox Shell. (**replace `106` with your LXC ID**) ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 ``` @@ -127,7 +127,7 @@ Reboot the LXC to apply the changes ⚙️ **To Install HACS:** -Run the from the LXC console +Run in the LXC console ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman_hacs.sh)" ``` @@ -135,7 +135,7 @@ After install, reboot Home Assistant and **clear browser cache** then Add HACS i ⚙️ **To Update Home Assistant:** -Run from the LXC console +Run in the LXC console ```yaml ./update.sh ``` @@ -166,7 +166,7 @@ ________________________________________________________________________________

Home Assistant Container LXC

With ZFS Filesystem Support

-To create a new Proxmox Home Assistant Container, run the following from Proxmox web shell. +To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ha_container.sh)" @@ -186,7 +186,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ``` ⚙️ **To Edit the HA configuration.yaml** (Recommend Using Webmin System Administration) -Run from the LXC console +Run in the LXC console ```yaml nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` @@ -194,14 +194,14 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” ⚙️ **Import Data From a Existing Home Assistant LXC to another Home Assistant LXC** -Run From The Proxmox Web Shell +Run in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" ``` ⚙️ **To Allow USB Device Passthrough:** -In the Proxmox web shell run (**replace `106` with your LXC ID**) +Run the in the Proxmox Shell. (**replace `106` with your LXC ID**) ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 ``` @@ -211,7 +211,7 @@ Reboot the LXC to apply the changes ⚙️ **To Install HACS:** -Run from the LXC console +Run in the LXC console ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs.sh)" ``` @@ -220,7 +220,7 @@ After install, reboot Home Assistant and **clear browser cache** then Add HACS i ⚙️ **To Update Home Assistant:** -Run from the LXC console +Run in the LXC console ```yaml ./update.sh ``` @@ -238,7 +238,7 @@ ________________________________________________________________________________

ESPHome LXC Container

-To create a new Proxmox ESPHome LXC Container, run the following from Proxmox web shell. +To create a new Proxmox ESPHome LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome_container.sh)" @@ -262,7 +262,7 @@ ________________________________________________________________________________

Nginx Proxy Manager LXC Container

-To create a new Proxmox Nginx Proxy Manager LXC Container, run the following from Proxmox web shell. +To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/npm_container.sh)" @@ -297,9 +297,6 @@ Add the following to your `configuration.yaml` in Home Assistant.
- - -
MQTT LXC @@ -308,7 +305,7 @@ Add the following to your `configuration.yaml` in Home Assistant.

MQTT LXC Container

-To create a new Proxmox MQTT LXC Container, run the following in the Proxmox web shell. +To create a new Proxmox MQTT LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt_container.sh)" @@ -341,7 +338,7 @@ sudo systemctl restart mosquitto ⚙️ **To Update MQTT:** -Run from the LXC console +Run in the LXC console ```yaml apt update && apt upgrade -y ``` @@ -358,7 +355,7 @@ ________________________________________________________________________________

Node-Red LXC Container

-To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox web shell. +To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red_container.sh)" @@ -369,14 +366,14 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/n ⚙️ **To Restart Node-Red:** -Run from the LXC console +Run in the LXC console ```yaml node-red-restart ``` ⚙️ **To Update Node-Red:** -Run from the LXC console (Restart after update) +Run in the LXC console (Restart after update) ```yaml npm install -g --unsafe-perm node-red ``` @@ -385,8 +382,6 @@ ________________________________________________________________________________
- -
Mariadb LXC @@ -395,7 +390,7 @@ ________________________________________________________________________________

Mariadb LXC Container

-To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox web shell. +To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb_container.sh)" @@ -486,7 +481,7 @@ Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8m ⚙️ **To Update Mariadb:** -Run from the LXC console +Run in the LXC console ```yaml apt update && apt upgrade -y ``` @@ -502,7 +497,7 @@ ________________________________________________________________________________

Zigbee2MQTT LXC Container

-To create a new Proxmox Zigbee2MQTT LXC Container, run the following from Proxmox web shell. +To create a new Proxmox Zigbee2MQTT LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt_container.sh)" @@ -512,7 +507,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z ⚙️ **Determine the location of your adapter** -Run from the LXC console +Run in the LXC console ```yaml ls -l /dev/serial/by-id ``` @@ -521,7 +516,7 @@ Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if ⚙️ ⚠️ **Before you start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** -Run from the LXC console +Run in the LXC console ```yaml nano /opt/zigbee2mqtt/data/configuration.yaml ``` @@ -552,20 +547,20 @@ advanced: ``` ⚙️ **Zigbee2MQTT can be started after completing the configuration** -Run from the LXC console +Run in the LXC console ```yaml cd /opt/zigbee2mqtt npm start ``` ⚙️ **To update Zigbee2MQTT** -Run from the LXC console +Run in the LXC console ```yaml bash /opt/zigbee2mqtt/update.sh ``` ⚙️ **Import Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** -Run From The Proxmox Web Shell +Run in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" ``` @@ -574,7 +569,6 @@ ________________________________________________________________________________
-
🔸Zwavejs2MQTT LXC @@ -582,7 +576,7 @@ ________________________________________________________________________________

Zwavejs2MQTT LXC Container

-To create a new Proxmox Zwavejs2MQTT LXC Container, run the following from Proxmox web shell. +To create a new Proxmox Zwavejs2MQTT LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zwavejs2mqtt_container.sh)" @@ -596,8 +590,6 @@ ________________________________________________________________________________
- -
🔸Debian 11 LXC @@ -605,7 +597,7 @@ ________________________________________________________________________________

Debian 11 LXC Container

-To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. +To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian11_container.sh)" @@ -616,7 +608,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ⚙️ **To Update Debian 11** -Run from the LXC console +Run in the LXC console ```yaml apt update && apt upgrade -y ``` @@ -633,7 +625,7 @@ ________________________________________________________________________________

Ubuntu 21.10 LXC Container

-To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox web shell. +To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu_container.sh)" @@ -644,7 +636,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ⚙️ **To Update Ubuntu 21.10** -Run from the LXC console +Run in the LXC console ```yaml apt update && apt upgrade -y ``` @@ -660,7 +652,7 @@ ________________________________________________________________________________ GamUntu is Ubuntu 21.10, Docker, Docker Compose, ZFS Support, USB Passthrough, Webmin System Administration and Hardware Acceleration all baked in! -To create a new Proxmox GamUntuLXC Container, run the following in the Proxmox web shell. +To create a new Proxmox GamUntuLXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/gamuntu_container.sh)" @@ -671,7 +663,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ⚙️ **To Update GamUntu** -Run from the LXC console +Run in the LXC console ```yaml apt update && apt upgrade -y ``` @@ -687,7 +679,7 @@ ________________________________________________________________________________

Plex Media Server LXC

With Hardware Acceleration Support

-To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox web shell. +To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/plex_container.sh)" @@ -700,13 +692,13 @@ After the script completes, If you're dissatisfied with the default settings, cl ⚙️ **To Update Plex Media Server:** -Run from the LXC console +Run in the LXC console ```yaml apt update && apt upgrade -y ``` ⚙️ **Import Data From a Existing Plex Media Server LXC to another Plex Media Server LXC** -Run From The Proxmox Web Shell +Run in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" ``` @@ -720,7 +712,7 @@ ________________________________________________________________________________

Jellyfin Media Server LXC

-To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox web shell. +To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/jellyfin_container.sh)" @@ -733,7 +725,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ⚙️ **To Update Jellyfin Media Server** -Run from the LXC console +Run in the LXC console ```yaml apt update && apt upgrade -y ``` @@ -748,7 +740,7 @@ ________________________________________________________________________________

Pi-hole LXC

-To create a new Proxmox Pi-hole LXC, run the following in the Proxmox web shell. +To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/pihole_container.sh)" @@ -757,7 +749,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/p ⚙️ **To set your password:** -Run from the LXC console +Run in the LXC console ```yaml pihole -a -p @@ -765,7 +757,7 @@ pihole -a -p ⚙️ **To Update Pi-hole:** ```yaml -Updates from the Pi-hole UI +Update from the Pi-hole UI ``` ____________________________________________________________________________________________ @@ -781,7 +773,7 @@ ________________________________________________________________________________

AdGuard Home LXC

-To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox web shell. +To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard_container.sh)" @@ -795,7 +787,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/a ⚙️ **To Update Adguard** ```yaml -Updates from the Adguard UI +Update from the Adguard UI ``` __________________________________________________________________________________________ @@ -808,7 +800,7 @@ ________________________________________________________________________________

MotionEye NVR LXC

-To create a new Proxmox MotionEye NVR LXC, run the following in the Proxmox web shell. +To create a new Proxmox MotionEye NVR LXC, run the following in the Proxmox Shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/motioneye_container.sh)" @@ -830,7 +822,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ⚙️ **To Update MotionEye** -Run from the LXC console +Run in the LXC console ```yaml pip install motioneye --upgrade ``` @@ -846,7 +838,7 @@ ________________________________________________________________________________

Webmin System Administration

-To Install Webmin System Administration [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png), run the following in a LXC console. +To Install Webmin System Administration [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png), ⚠️ run the following in the LXC console. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" @@ -871,7 +863,7 @@ Benefits include automatic daily security updates, backup and restore, file mana ⚙️ **To Update Webmin** ```yaml -Updates from the Webmin UI +Update from the Webmin UI ``` ⚙️ **To Uninstall Webmin** ```yaml @@ -888,7 +880,7 @@ ________________________________________________________________________________

Vaultwarden LXC

-To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox web shell. +To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vault_container.sh)" From 5aad3929f99f33c7db64a79b2ae9f84e45658436 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 15:32:26 -0500 Subject: [PATCH 1088/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9af945a..9c1d2228 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc ⚙️ **To Allow USB Device Passthrough:** -Run the in the Proxmox Shell. (**replace `106` with your LXC ID**) +Run in the Proxmox Shell. (**replace `106` with your LXC ID**) ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 ``` From 28cad506a66430a530d80b146160d7601922001f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 15:38:05 -0500 Subject: [PATCH 1089/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c1d2228..29bfe351 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ ________________________________________________________________________________

Home Assistant OS VM

-To create a new Proxmox VM with the latest version of Home Assistant OS, run the following in the Proxmox Shell +To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/vm/haos_vm.sh)" From 49eb6c7310bf9ad0afaa255b71e1fe4a7fcb5e2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 16:44:12 -0500 Subject: [PATCH 1090/6505] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 29bfe351..65e49f8f 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/vm/h ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the **_Memory_** and **_Processors_** settings to what you desire. Once all changes have been made, **_Start_** the VM. +After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the settings to what you desire. Once all changes have been made, **_Start_** the VM. **Home Assistant Interface - IP:8123** @@ -91,7 +91,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/p ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. **Home Assistant Interface - IP:8123** @@ -174,7 +174,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/h

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. **Home Assistant Interface - IP:8123** @@ -604,7 +604,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/d ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. ⚙️ **To Update Debian 11** @@ -632,7 +632,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/u ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. ⚙️ **To Update Ubuntu 21.10** @@ -659,7 +659,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/g ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_** and **_Cores_** settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. ⚙️ **To Update GamUntu** @@ -686,7 +686,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/p ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. **Plex Media Server Interface - IP:32400/web** @@ -719,7 +719,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/j ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. **Jellyfin Media Server Interface - IP:8096** @@ -808,7 +808,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/m

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the **_Memory_**, **_Cores_** and **_Root Disk_** (Resize disk) settings to what you desire. Changes are immediate. +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. **MotionEye Interface - IP:8765** From ebd59e8f96b0e7cf82f56f78965181147ca93fa3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Feb 2022 21:27:44 -0500 Subject: [PATCH 1091/6505] Update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 65e49f8f..77ef7893 100644 --- a/README.md +++ b/README.md @@ -149,10 +149,6 @@ Run in the LXC console ```yaml pass ``` -⚙️ **Add Yacht Template** -```yaml -https://raw.githubusercontent.com/SelfhostedPro/selfhosted_templates/yacht/Template/template.json -``` ____________________________________________________________________________________________
From b4467dd8d2cf47ad51463cce7604901e6b2cde35 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Feb 2022 10:19:39 -0500 Subject: [PATCH 1092/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77ef7893..8fba31e8 100644 --- a/README.md +++ b/README.md @@ -587,7 +587,7 @@ ________________________________________________________________________________
-🔸Debian 11 LXC + Debian 11 LXC

Debian

@@ -615,7 +615,7 @@ ________________________________________________________________________________
-🔸Ubuntu 21.10 LXC + Ubuntu 21.10 LXC

Ubuntu

From 722cc313f8801b94d4c58dd74da8b2b3dc45a534 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Feb 2022 16:54:01 -0500 Subject: [PATCH 1093/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index c0647d62..455e6e34 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -57,6 +57,11 @@ curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/ apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" +sudo apt install adminer -y &>/dev/null +sudo a2enconf adminer &>/dev/null +sudo systemctl reload apache2 &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" rm /etc/motd rm /etc/update-motd.d/10-uname From fa452f0cabd6213f13ab226a9690eda81a285e69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Feb 2022 17:16:16 -0500 Subject: [PATCH 1094/6505] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 8fba31e8..968f0699 100644 --- a/README.md +++ b/README.md @@ -481,6 +481,9 @@ Run in the LXC console ```yaml apt update && apt upgrade -y ``` +⚙️ **Adminer** (formerly phpMinAdmin) is a full-featured database management tool + + `http://your-server-ip/adminer/` ____________________________________________________________________________________________
From 316b2f0ba3ce7aa673105aef2675d74789e63535 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Feb 2022 17:19:55 -0500 Subject: [PATCH 1095/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 45310e29..066f59d5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-13 + +### Changed + +- **Mariadb LXC** + - Add Adminer (formerly phpMinAdmin), a full-featured database management tool + ## 2022-02-12 ### Changed From ea091efa63e67ee1f541b9fcfe61161ae0078c2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Feb 2022 17:21:52 -0500 Subject: [PATCH 1096/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 968f0699..4a36a0e8 100644 --- a/README.md +++ b/README.md @@ -379,7 +379,7 @@ ________________________________________________________________________________
-Mariadb LXC + 🔸Mariadb LXC

MariaDB

From 30b0240f5bf8c1bf836e8bf66626664bda71b328 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Feb 2022 17:24:05 -0500 Subject: [PATCH 1097/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4a36a0e8..d5e2e64c 100644 --- a/README.md +++ b/README.md @@ -484,6 +484,7 @@ apt update && apt upgrade -y ⚙️ **Adminer** (formerly phpMinAdmin) is a full-featured database management tool `http://your-server-ip/adminer/` + ____________________________________________________________________________________________
From 0538a5f56b0ac935150630d3181c19c8bb5c08b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Feb 2022 17:27:11 -0500 Subject: [PATCH 1098/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5e2e64c..72fb9c1e 100644 --- a/README.md +++ b/README.md @@ -483,7 +483,7 @@ apt update && apt upgrade -y ``` ⚙️ **Adminer** (formerly phpMinAdmin) is a full-featured database management tool - `http://your-server-ip/adminer/` + `http://your-mariadb-lxc-ip/adminer/` ____________________________________________________________________________________________ From adf10bf927d544ab9d70f91ac7d57d6c3a610f20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 07:43:11 -0500 Subject: [PATCH 1099/6505] Update ha_setup.sh --- setup/ha_setup.sh | 51 ++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 027f7880..be05712d 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -52,6 +52,9 @@ apt-get -qqy install \ curl \ sudo &>/dev/null +echo -e "${CHECKMARK} \e[1;92m Installing pip3... \e[0m" +apt-get install -y python3-pip &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) @@ -93,31 +96,29 @@ docker run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Creating Update Script... \e[0m" -file_path="/root/update.sh" -echo "#!/bin/bash -echo -e '\e[1;33m Pulling New Stable Version... \e[0m' -docker pull homeassistant/home-assistant:stable -echo -e '\e[1;33m Stopping Home Assistant... \e[0m' -docker stop homeassistant -echo -e '\e[1;33m Removing Home Assistant... \e[0m' -docker rm homeassistant -echo -e '\e[1;33m Starting Home Assistant... \e[0m' -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:stable -echo -e '\e[1;33m Removing Old Image... \e[0m' -docker image prune -f -echo -e '\e[1;33m Finished Update! \e[0m'" > $file_path -sudo chmod +x /root/update.sh +echo -e "${CHECKMARK} \e[1;92m Installing runlike... \e[0m" +pip3 install runlike &>/dev/null + +echo -e "${CHECKMARK} \e[1;92m Creating Update-Containers Script... \e[0m" +UPDATE_CONTAINERS_PATH='/root/update-containers.sh' +cat >$UPDATE_CONTAINERS_PATH <<'EOF' +#!/bin/bash +set -o errexit +CONTAINER_LIST="${1:-$(docker ps -q)}" +for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike "${container}")" + docker rm --force "${container}" + eval ${DOCKER_COMMAND} + fi +done +EOF +sudo chmod +x /root/update-containers.sh echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" rm /etc/motd From 007b80fe3850ee3cd410b7b500f5a9f69fa60354 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 07:59:39 -0500 Subject: [PATCH 1100/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 72fb9c1e..d28ecfd6 100644 --- a/README.md +++ b/README.md @@ -214,11 +214,11 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **To Update Home Assistant:** +⚙️ **To Update All Containers:** Run in the LXC console ```yaml -./update.sh +./update-containers.sh ``` ____________________________________________________________________________________________ From 240b7dab2e2e489b9e1a7479e45ff9420488e2c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 08:16:34 -0500 Subject: [PATCH 1101/6505] Update ha_setup.sh --- setup/ha_setup.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index be05712d..43a6641a 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -96,10 +96,8 @@ docker run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing runlike... \e[0m" -pip3 install runlike &>/dev/null - echo -e "${CHECKMARK} \e[1;92m Creating Update-Containers Script... \e[0m" +pip3 install runlike &>/dev/null UPDATE_CONTAINERS_PATH='/root/update-containers.sh' cat >$UPDATE_CONTAINERS_PATH <<'EOF' #!/bin/bash From 2b8f069c2fb89dfca10a2ed2a400a61d2d9930f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 08:46:45 -0500 Subject: [PATCH 1102/6505] Update ha_setup.sh --- setup/ha_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 43a6641a..4f2399a0 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -114,6 +114,7 @@ for container in ${CONTAINER_LIST}; do docker rm --force "${container}" eval ${DOCKER_COMMAND} fi +docker image prune -f done EOF sudo chmod +x /root/update-containers.sh From a9fd2ccd8a9137fdca74dbd63a9e39f54a6bc789 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 13:54:15 -0500 Subject: [PATCH 1103/6505] Update ha_setup.sh --- setup/ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 4f2399a0..400f05cd 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -113,9 +113,9 @@ for container in ${CONTAINER_LIST}; do DOCKER_COMMAND="$(runlike "${container}")" docker rm --force "${container}" eval ${DOCKER_COMMAND} - fi -docker image prune -f + fi done +docker image prune -af EOF sudo chmod +x /root/update-containers.sh From 3255cb6901b97e4bf876bf3785c6b57ff8c0ae8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 17:34:05 -0500 Subject: [PATCH 1104/6505] Update ha_setup.sh --- setup/ha_setup.sh | 85 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 400f05cd..66d515e6 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -96,9 +96,92 @@ docker run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Creating Update-Containers Script... \e[0m" +echo -e "${CHECKMARK} \e[1;92m Creating Update Menu Script... \e[0m" pip3 install runlike &>/dev/null +UPDATE_PATH='/root/update' UPDATE_CONTAINERS_PATH='/root/update-containers.sh' +cat >$UPDATE_PATH <<'EOF' +#!/bin/sh +set -o errexit +show_menu(){ + normal=`echo "\033[m"` + safe=`echo "\033[32m"` + menu=`echo "\033[36m"` + number=`echo "\033[33m"` + bgred=`echo "\033[41m"` + fgred=`echo "\033[31m"` + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" + printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" + printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" + printf "${menu}**${number} 4)${safe} Just Update Containers ${normal}\n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" + read opt +} + +option_picked(){ + msgcolor=`echo "\033[01;31m"` + normal=`echo "\033[00;00m"` + message=${@:-"${normal}Error: No message passed"} + printf "${msgcolor}${message}${normal}\n" +} + +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + option_picked "Switching to Stable Branch"; + TAG=stable + break; + ;; + 2) clear; + option_picked "Switching to Beta Branch"; + TAG=beta + break; + ;; + 3) clear; + option_picked "Switching to Dev Branch"; + TAG=dev + break; + ;; + 4) clear; + option_picked "Just Updating Containers"; + ./update-containers.sh; + exit; + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose an option from the menu"; + show_menu; + ;; + esac + fi + done +docker pull homeassistant/home-assistant:$TAG +docker rm --force homeassistant +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:$TAG + docker image prune -af +EOF +sudo chmod +x /root/update cat >$UPDATE_CONTAINERS_PATH <<'EOF' #!/bin/bash set -o errexit From cdc6c52a2156c3302fc91c5b31813c473aaaba61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 17:50:29 -0500 Subject: [PATCH 1105/6505] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d28ecfd6..a6df5457 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ ________________________________________________________________________________
- 🔸GamUntu LXC + GamUntu LXC

GamUntu

GamUntu LXC Container

@@ -715,7 +715,7 @@ ________________________________________________________________________________
- 🔸Jellyfin Media Server LXC + Jellyfin Media Server LXC

Jellyfin Media Server LXC

@@ -801,7 +801,7 @@ ________________________________________________________________________________
-🔸MotionEye NVR LXC + MotionEye NVR LXC

From 965b0bb399a8d6233c60e173463a49c86348fd65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Feb 2022 03:37:33 -0500 Subject: [PATCH 1144/6505] Add files via upload --- misc/images/adminer_logo-cl.png | Bin 0 -> 14993 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/adminer_logo-cl.png diff --git a/misc/images/adminer_logo-cl.png b/misc/images/adminer_logo-cl.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3b6bd4c90ec7569dbc3f6ef727d4f8d0b7a6d8 GIT binary patch literal 14993 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 Date: Thu, 17 Feb 2022 03:52:33 -0500 Subject: [PATCH 1145/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 0d6a2ec2..1bbe2239 100644 --- a/README.md +++ b/README.md @@ -388,8 +388,7 @@ ________________________________________________________________________________
🔸Mariadb LXC -

MariaDB

- +

MariaDB

Mariadb LXC Container

From a17e808c845f9cb59fd420ef24328fe77cd32358 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Feb 2022 21:29:39 -0500 Subject: [PATCH 1146/6505] Update haos_vm.sh --- vm/haos_vm.sh | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a19de432..106bdca7 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -81,7 +81,7 @@ fi info "Using '$STORAGE' for storage location." VMID=$(pvesh get /cluster/nextid) info "Container ID is $VMID." -echo -e "\e[1;33m Getting URL for latest Home Assistant disk image... \e[0m" +echo -en "\e[1;92m Getting URL for Latest Home Assistant Disk Image... \e[0m" RELEASE_TYPE=qcow2 URL=$(cat</dev/null set +o errtrace ( - echo -e "${CHECKMARK} \e[1;92m Adding serial port and configuring console... \e[0m" +echo -e "${CHECKMARK} \r" + echo -en "\e[1;92m Adding Serial Port and Configuring Console... \e[0m" trap ' warn "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then @@ -146,10 +151,12 @@ set +o errtrace fi exit ' ERR + echo -e "${CHECKMARK} \r" if [ "$(command -v kpartx)" = "" ]; then - echo -e "${CHECKMARK} \e[1;92m Installing kpartx... \e[0m" + echo -en "\e[1;92m Installing kpartx... \e[0m" apt-get update >/dev/null apt-get -qqy install kpartx &>/dev/null + echo -e "${CHECKMARK} \r" fi DISK1_PATH="$(pvesm path $DISK1_REF)" DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" From 64859bdc1704efa2c4492ea122f9b5227dd00d8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Feb 2022 21:36:39 -0500 Subject: [PATCH 1147/6505] Update haos_vm.sh --- vm/haos_vm.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 106bdca7..bdea0f5f 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -8,6 +8,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done +clear;; set -o errexit set -o errtrace set -o nounset From 016ec7deb00edb73a5c4c58f55216e0998b45a82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Feb 2022 21:39:35 -0500 Subject: [PATCH 1148/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index bdea0f5f..5a52f883 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -8,7 +8,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done -clear;; +clear set -o errexit set -o errtrace set -o nounset From 530cac244da1e6a13a95ef8f3cf21da0524a58d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Feb 2022 21:54:28 -0500 Subject: [PATCH 1149/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 5a52f883..a4c235f4 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -109,7 +109,7 @@ sleep 2 wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -echo -e "\e[1;92m Downloaded .qcow2 Disk Image... ${CHECKMARK} \e[0m \r" +echo -e "\e[1;92m Downloaded ${RELEASE_TYPE} Disk Image... ${CHECKMARK} \e[0m \r" echo -en "\e[1;92m Extracting Disk Image... \e[0m" case $FILE in *"gz") gunzip -f $FILE ;; From af6f443708130bf4083cc964eb3c184772a8ced1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 08:26:00 -0500 Subject: [PATCH 1150/6505] Update haos_vm.sh --- vm/haos_vm.sh | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a4c235f4..a95b2f49 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -15,7 +15,10 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` trap die ERR trap cleanup EXIT function error_exit() { @@ -79,10 +82,10 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -info "Using '$STORAGE' for storage location." +info "Using ${BL}$STORAGE${CL} for Storage Location." VMID=$(pvesh get /cluster/nextid) -info "Container ID is $VMID." -echo -en "\e[1;92m Getting URL for Latest Home Assistant Disk Image... \e[0m" +info "Container ID is ${BL}$VMID${CL}." +echo -en "${GN} Getting URL for Latest Home Assistant Disk Image... " RELEASE_TYPE=qcow2 URL=$(cat</dev/null set +o errtrace ( -echo -e "${CHECKMARK} \r" - echo -en "\e[1;92m Adding Serial Port and Configuring Console... \e[0m" +echo -e "${CM} ${CL} \r" + echo -en "${GN} Adding Serial Port and Configuring Console... " trap ' warn "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then @@ -152,12 +155,12 @@ echo -e "${CHECKMARK} \r" fi exit ' ERR - echo -e "${CHECKMARK} \r" + echo -e "${CM} ${CL} \r" if [ "$(command -v kpartx)" = "" ]; then - echo -en "\e[1;92m Installing kpartx... \e[0m" + echo -en "${GN} Installing kpartx... " apt-get update >/dev/null apt-get -qqy install kpartx &>/dev/null - echo -e "${CHECKMARK} \r" + echo -e "${CM} ${CL} \r" fi DISK1_PATH="$(pvesm path $DISK1_REF)" DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" @@ -174,4 +177,4 @@ echo -e "${CHECKMARK} \r" qm set $VMID -serial0 socket >/dev/null ) -info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." +info "${GN} Completed Successfully!${CL} HAOS VM ID is ${BL}${VMID}${CL}" From 3e6bd9b15728c510f5fce6c9c57cfe7719fe0062 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 11:20:26 -0500 Subject: [PATCH 1151/6505] Update mariadb_container.sh --- ct/mariadb_container.sh | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/ct/mariadb_container.sh b/ct/mariadb_container.sh index 1cf0eb3e..3f5e35d8 100644 --- a/ct/mariadb_container.sh +++ b/ct/mariadb_container.sh @@ -8,14 +8,17 @@ while true; do * ) echo "Please answer yes or no.";; esac done - +clear set -o errexit set -o errtrace set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` trap die ERR trap cleanup EXIT @@ -73,7 +76,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/mariadb_setup.sh load_module overlay @@ -101,15 +104,16 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -info "Using '$STORAGE' for storage location." +info "Using ${BL}${STORAGE}${CL} for Storage Location." CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." +info "Container ID is ${BL}${CTID}${CL}." -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +echo -en "${GN} Updating LXC Template List... " pveam update >/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +echo -en "${GN} Downloading LXC Template... " OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -130,8 +134,9 @@ case $STORAGE_TYPE in esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +echo -en "${GN} Creating LXC Container... " DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -149,11 +154,15 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +echo -en "${GN} Starting LXC Container... " pct start $CTID pct push $CTID mariadb_setup.sh /mariadb_setup.sh -perms 755 +echo -e "${CM}${CL} \r" pct exec $CTID /mariadb_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a MariaDB LXC Container to $CTID at IP Address ${IP}" +info "${GN} Successfully created a MariaDB LXC Container to ${BL}${CTID}${CL}" +echo -e "${CL} Adminer should be reachable by going to the following URL. + ${BL} http://${IP}/adminer/ ${CL}" From 4acfba62d6cae07e24095ff14fde8b03b82615a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 11:21:18 -0500 Subject: [PATCH 1152/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 2b56d74e..bbf2c626 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -7,7 +7,11 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` RETRY_NUM=5 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -27,42 +31,48 @@ function msg() { echo -e "$TEXT" } -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +echo -en "${GN} Setting up Container OS... " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + 1>&2 echo -e "${CROSS}${RD} No Network! \r" sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}${(hostname -I)} " +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +echo -en "${GN} Updating Container OS... " apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +echo -en "${GN} Installing Dependencies... " apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing MariaDB... \e[0m" +echo -en "${GN} Installing MariaDB... " curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" +echo -en "${GN} Installing Adminer... " sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -75,7 +85,9 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +echo -en "${GN} Cleanup... " rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* mkdir /var/log/apache2 +echo -e "${CM}${CL} \r" From 3037e9e1f02e3eead8286e185ae8c986a052ec0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 11:30:56 -0500 Subject: [PATCH 1153/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index bbf2c626..d0ff3180 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -45,7 +45,7 @@ while [ "$(hostname -I)" = "" ]; do fi done echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}${(hostname -I)} " +echo -en "${GN} Network Connected: ${BL}$(hostname -I) " echo -e "${CM}${CL} \r" echo -en "${GN} Updating Container OS... " From 901e02e0ac2eddac8d97fec832e4c499c00eab94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 11:33:12 -0500 Subject: [PATCH 1154/6505] Update mariadb_container.sh --- ct/mariadb_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mariadb_container.sh b/ct/mariadb_container.sh index 3f5e35d8..c3f09991 100644 --- a/ct/mariadb_container.sh +++ b/ct/mariadb_container.sh @@ -76,7 +76,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/mariadb_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb_setup.sh load_module overlay From 3735132b7c4c5fe38c8b0284de2b350cc4dbadd0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 12:18:30 -0500 Subject: [PATCH 1155/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index d0ff3180..b3d8b445 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -45,7 +45,7 @@ while [ "$(hostname -I)" = "" ]; do fi done echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I) " +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " echo -e "${CM}${CL} \r" echo -en "${GN} Updating Container OS... " From 24939e2724185651fd1f6c72eeac54aa4ed41104 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 14:01:49 -0500 Subject: [PATCH 1156/6505] Add files via upload --- misc/node-red-dark.sh | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 misc/node-red-dark.sh diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh new file mode 100644 index 00000000..f0393226 --- /dev/null +++ b/misc/node-red-dark.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-dark.sh)" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +clear +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing midnight-red Theme... " +cd /root/.node-red +npm install @node-red-contrib-themes/midnight-red &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Writing Settings... " +cat < /root/.node-red/settings.js +module.exports = { uiPort: process.env.PORT || 1880, + + mqttReconnectTime: 15000, + + serialReconnectTime: 15000, + + debugMaxLength: 1000, + + functionGlobalContext: { + }, + exportGlobalContextKeys: false, + + + // Configure the logging output + logging: { + console: { + level: "info", + metrics: false, + audit: false + } + }, + + // Customising the editor + editorTheme: { + theme: "midnight-red" + }, + projects: { + // To enable the Projects feature, set this value to true + enabled: true + } +} +EOF +echo -e "${CM}${CL} \r" + +echo -en "${GN} Restarting Node-Red... " +node-red-restart +echo -e "${CM}${CL} \r" + +echo -en "${GN} Finished... ${CL} \n" +exit + + From 752d253ad3d6a2aca340a5daf184eb8ecb506019 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 14:06:34 -0500 Subject: [PATCH 1157/6505] Add files via upload --- misc/node-red-dark.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index f0393226..813f1e10 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-dark.sh)" +while true; do + read -p "This will install midnight-red theme. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + set -o errexit set -o errtrace set -o nounset @@ -74,9 +83,8 @@ EOF echo -e "${CM}${CL} \r" echo -en "${GN} Restarting Node-Red... " -node-red-restart echo -e "${CM}${CL} \r" - +node-red-restart echo -en "${GN} Finished... ${CL} \n" exit From 96f6ef09f4415bdbb8462046c49df16e46afcb39 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 14:59:12 -0500 Subject: [PATCH 1158/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 522 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 492 insertions(+), 30 deletions(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index 813f1e10..eabf2f16 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -1,14 +1,5 @@ #!/usr/bin/env bash # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-dark.sh)" -while true; do - read -p "This will install midnight-red theme. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - set -o errexit set -o errtrace set -o nounset @@ -22,7 +13,16 @@ GN=`echo "\033[1;92m"` CL=`echo "\033[m"` trap die ERR trap 'die "Script interrupted."' INT - +echo -en "${RD} Backup your Node-Red flows before running this script!! " +while true; do + read -p "This will install midnight-red theme. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear function error_exit() { trap - ERR local DEFAULT='Unknown failure occured.' @@ -35,7 +35,7 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } -clear + echo -en "${GN} Updating Container OS... " apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null @@ -48,36 +48,498 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Writing Settings... " cat < /root/.node-red/settings.js -module.exports = { uiPort: process.env.PORT || 1880, +/** + * This is the default settings file provided by Node-RED. + * + * It can contain any valid JavaScript code that will get run when Node-RED + * is started. + * + * Lines that start with // are commented out. + * Each entry should be separated from the entries above and below by a comma ',' + * + * For more information about individual settings, refer to the documentation: + * https://nodered.org/docs/user-guide/runtime/configuration + * + * The settings are split into the following sections: + * - Flow File and User Directory Settings + * - Security + * - Server Settings + * - Runtime Settings + * - Editor Settings + * - Node Settings + * + **/ - mqttReconnectTime: 15000, +module.exports = { - serialReconnectTime: 15000, +/******************************************************************************* + * Flow File and User Directory Settings + * - flowFile + * - credentialSecret + * - flowFilePretty + * - userDir + * - nodesDir + ******************************************************************************/ - debugMaxLength: 1000, + /** The file containing the flows. If not set, defaults to flows_.json **/ + flowFile: 'flows.json', - functionGlobalContext: { - }, - exportGlobalContextKeys: false, + /** By default, credentials are encrypted in storage using a generated key. To + * specify your own secret, set the following property. + * If you want to disable encryption of credentials, set this property to false. + * Note: once you set this property, do not change it - doing so will prevent + * node-red from being able to decrypt your existing credentials and they will be + * lost. + */ + //credentialSecret: "a-secret-key", + + /** By default, the flow JSON will be formatted over multiple lines making + * it easier to compare changes when using version control. + * To disable pretty-printing of the JSON set the following property to false. + */ + flowFilePretty: true, + + /** By default, all user data is stored in a directory called `.node-red` under + * the user's home directory. To use a different location, the following + * property can be used + */ + //userDir: '/home/nol/.node-red/', + + /** Node-RED scans the `nodes` directory in the userDir to find local node files. + * The following property can be used to specify an additional directory to scan. + */ + //nodesDir: '/home/nol/.node-red/nodes', + +/******************************************************************************* + * Security + * - adminAuth + * - https + * - httpsRefreshInterval + * - requireHttps + * - httpNodeAuth + * - httpStaticAuth + ******************************************************************************/ + + /** To password protect the Node-RED editor and admin API, the following + * property can be used. See http://nodered.org/docs/security.html for details. + */ + //adminAuth: { + // type: "credentials", + // users: [{ + // username: "admin", + // password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.", + // permissions: "*" + // }] + //}, + + /** The following property can be used to enable HTTPS + * This property can be either an object, containing both a (private) key + * and a (public) certificate, or a function that returns such an object. + * See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener + * for details of its contents. + */ + + /** Option 1: static object */ + //https: { + // key: require("fs").readFileSync('privkey.pem'), + // cert: require("fs").readFileSync('cert.pem') + //}, + + /** Option 2: function that returns the HTTP configuration object */ + // https: function() { + // // This function should return the options object, or a Promise + // // that resolves to the options object + // return { + // key: require("fs").readFileSync('privkey.pem'), + // cert: require("fs").readFileSync('cert.pem') + // } + // }, + + /** If the `https` setting is a function, the following setting can be used + * to set how often, in hours, the function will be called. That can be used + * to refresh any certificates. + */ + //httpsRefreshInterval : 12, + + /** The following property can be used to cause insecure HTTP connections to + * be redirected to HTTPS. + */ + //requireHttps: true, + + /** To password protect the node-defined HTTP endpoints (httpNodeRoot), + * including node-red-dashboard, or the static content (httpStatic), the + * following properties can be used. + * The `pass` field is a bcrypt hash of the password. + * See http://nodered.org/docs/security.html#generating-the-password-hash + */ + //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, + //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, + +/******************************************************************************* + * Server Settings + * - uiPort + * - uiHost + * - apiMaxLength + * - httpServerOptions + * - httpAdminRoot + * - httpAdminMiddleware + * - httpNodeRoot + * - httpNodeCors + * - httpNodeMiddleware + * - httpStatic + ******************************************************************************/ + + /** the tcp port that the Node-RED web server is listening on */ + uiPort: process.env.PORT || 1880, + + /** By default, the Node-RED UI accepts connections on all IPv4 interfaces. + * To listen on all IPv6 addresses, set uiHost to "::", + * The following property can be used to listen on a specific interface. For + * example, the following would only allow connections from the local machine. + */ + //uiHost: "127.0.0.1", + + /** The maximum size of HTTP request that will be accepted by the runtime api. + * Default: 5mb + */ + //apiMaxLength: '5mb', + + /** The following property can be used to pass custom options to the Express.js + * server used by Node-RED. For a full list of available options, refer + * to http://expressjs.com/en/api.html#app.settings.table + */ + //httpServerOptions: { }, + + /** By default, the Node-RED UI is available at http://localhost:1880/ + * The following property can be used to specify a different root path. + * If set to false, this is disabled. + */ + //httpAdminRoot: '/admin', + + /** The following property can be used to add a custom middleware function + * in front of all admin http routes. For example, to set custom http + * headers. It can be a single function or an array of middleware functions. + */ + // httpAdminMiddleware: function(req,res,next) { + // // Set the X-Frame-Options header to limit where the editor + // // can be embedded + // //res.set('X-Frame-Options', 'sameorigin'); + // next(); + // }, - // Configure the logging output - logging: { - console: { - level: "info", - metrics: false, - audit: false - } - }, + /** Some nodes, such as HTTP In, can be used to listen for incoming http requests. + * By default, these are served relative to '/'. The following property + * can be used to specifiy a different root path. If set to false, this is + * disabled. + */ + //httpNodeRoot: '/red-nodes', - // Customising the editor + /** The following property can be used to configure cross-origin resource sharing + * in the HTTP nodes. + * See https://github.com/troygoode/node-cors#configuration-options for + * details on its contents. The following is a basic permissive set of options: + */ + //httpNodeCors: { + // origin: "*", + // methods: "GET,PUT,POST,DELETE" + //}, + + /** If you need to set an http proxy please set an environment variable + * called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system. + * For example - http_proxy=http://myproxy.com:8080 + * (Setting it here will have no effect) + * You may also specify no_proxy (or NO_PROXY) to supply a comma separated + * list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk + */ + + /** The following property can be used to add a custom middleware function + * in front of all http in nodes. This allows custom authentication to be + * applied to all http in nodes, or any other sort of common request processing. + * It can be a single function or an array of middleware functions. + */ + //httpNodeMiddleware: function(req,res,next) { + // // Handle/reject the request, or pass it on to the http in node by calling next(); + // // Optionally skip our rawBodyParser by setting this to true; + // //req.skipRawBodyParser = true; + // next(); + //}, + + /** When httpAdminRoot is used to move the UI to a different root path, the + * following property can be used to identify a directory of static content + * that should be served at http://localhost:1880/. + */ + //httpStatic: '/home/nol/node-red-static/', + +/******************************************************************************* + * Runtime Settings + * - lang + * - logging + * - contextStorage + * - exportGlobalContextKeys + * - externalModules + ******************************************************************************/ + + /** Uncomment the following to run node-red in your preferred language. + * Available languages include: en-US (default), ja, de, zh-CN, zh-TW, ru, ko + * Some languages are more complete than others. + */ + // lang: "de", + + /** Configure the logging output */ + logging: { + /** Only console logging is currently supported */ + console: { + /** Level of logging to be recorded. Options are: + * fatal - only those errors which make the application unusable should be recorded + * error - record errors which are deemed fatal for a particular request + fatal errors + * warn - record problems which are non fatal + errors + fatal errors + * info - record information about the general running of the application + warn + error + fatal errors + * debug - record information which is more verbose than info + info + warn + error + fatal errors + * trace - record very detailed logging + debug + info + warn + error + fatal errors + * off - turn off all logging (doesn't affect metrics or audit) + */ + level: "info", + /** Whether or not to include metric events in the log output */ + metrics: false, + /** Whether or not to include audit events in the log output */ + audit: false + } + }, + + /** Context Storage + * The following property can be used to enable context storage. The configuration + * provided here will enable file-based context that flushes to disk every 30 seconds. + * Refer to the documentation for further options: https://nodered.org/docs/api/context/ + */ + //contextStorage: { + // default: { + // module:"localfilesystem" + // }, + //}, + + /** `global.keys()` returns a list of all properties set in global context. + * This allows them to be displayed in the Context Sidebar within the editor. + * In some circumstances it is not desirable to expose them to the editor. The + * following property can be used to hide any property set in `functionGlobalContext` + * from being list by `global.keys()`. + * By default, the property is set to false to avoid accidental exposure of + * their values. Setting this to true will cause the keys to be listed. + */ + exportGlobalContextKeys: false, + + /** Configure how the runtime will handle external npm modules. + * This covers: + * - whether the editor will allow new node modules to be installed + * - whether nodes, such as the Function node are allowed to have their + * own dynamically configured dependencies. + * The allow/denyList options can be used to limit what modules the runtime + * will install/load. It can use '*' as a wildcard that matches anything. + */ + externalModules: { + // autoInstall: false, /** Whether the runtime will attempt to automatically install missing modules */ + // autoInstallRetry: 30, /** Interval, in seconds, between reinstall attempts */ + // palette: { /** Configuration for the Palette Manager */ + // allowInstall: true, /** Enable the Palette Manager in the editor */ + // allowUpdate: true, /** Allow modules to be updated in the Palette Manager */ + // allowUpload: true, /** Allow module tgz files to be uploaded and installed */ + // allowList: ['*'], + // denyList: [], + // allowUpdateList: ['*'], + // denyUpdateList: [] + // }, + // modules: { /** Configuration for node-specified modules */ + // allowInstall: true, + // allowList: [], + // denyList: [] + // } + }, + + +/******************************************************************************* + * Editor Settings + * - disableEditor + * - editorTheme + ******************************************************************************/ + + /** The following property can be used to disable the editor. The admin API + * is not affected by this option. To disable both the editor and the admin + * API, use either the httpRoot or httpAdminRoot properties + */ + //disableEditor: false, + + /** Customising the editor + * See https://nodered.org/docs/user-guide/runtime/configuration#editor-themes + * for all available options. + */ editorTheme: { theme: "midnight-red" }, + /** To disable the 'Welcome to Node-RED' tour that is displayed the first + * time you access the editor for each release of Node-RED, set this to false + */ + //tours: false, + + palette: { + /** The following property can be used to order the categories in the editor + * palette. If a node's category is not in the list, the category will get + * added to the end of the palette. + * If not set, the following default order is used: + */ + //categories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'], + }, + projects: { - // To enable the Projects feature, set this value to true - enabled: true - } + /** To enable the Projects feature, set this value to true */ + enabled: false, + workflow: { + /** Set the default projects workflow mode. + * - manual - you must manually commit changes + * - auto - changes are automatically committed + * This can be overridden per-user from the 'Git config' + * section of 'User Settings' within the editor + */ + mode: "manual" + } + }, + + codeEditor: { + /** Select the text editor component used by the editor. + * Defaults to "ace", but can be set to "ace" or "monaco" + */ + lib: "ace", + options: { + /** The follow options only apply if the editor is set to "monaco" + * + * theme - must match the file name of a theme in + * packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/theme + * e.g. "tomorrow-night", "upstream-sunburst", "github", "my-theme" + */ + theme: "vs", + /** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc. + * for the full list, see https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandaloneeditorconstructionoptions.html + */ + //fontSize: 14, + //fontFamily: "Cascadia Code, Fira Code, Consolas, 'Courier New', monospace", + //fontLigatures: true, + } + } + }, + +/******************************************************************************* + * Node Settings + * - fileWorkingDirectory + * - functionGlobalContext + * - functionExternalModules + * - nodeMessageBufferMaxLength + * - ui (for use with Node-RED Dashboard) + * - debugUseColors + * - debugMaxLength + * - execMaxBufferSize + * - httpRequestTimeout + * - mqttReconnectTime + * - serialReconnectTime + * - socketReconnectTime + * - socketTimeout + * - tcpMsgQueueSize + * - inboundWebSocketTimeout + * - tlsConfigDisableLocalFiles + * - webSocketNodeVerifyClient + ******************************************************************************/ + + /** The working directory to handle relative file paths from within the File nodes + * defaults to the working directory of the Node-RED process. + */ + //fileWorkingDirectory: "", + + /** Allow the Function node to load additional npm modules directly */ + functionExternalModules: true, + + /** The following property can be used to set predefined values in Global Context. + * This allows extra node modules to be made available with in Function node. + * For example, the following: + * functionGlobalContext: { os:require('os') } + * will allow the `os` module to be accessed in a Function node using: + * global.get("os") + */ + functionGlobalContext: { + // os:require('os'), + }, + + /** The maximum number of messages nodes will buffer internally as part of their + * operation. This applies across a range of nodes that operate on message sequences. + * defaults to no limit. A value of 0 also means no limit is applied. + */ + //nodeMessageBufferMaxLength: 0, + + /** If you installed the optional node-red-dashboard you can set it's path + * relative to httpNodeRoot + * Other optional properties include + * readOnly:{boolean}, + * middleware:{function or array}, (req,res,next) - http middleware + * ioMiddleware:{function or array}, (socket,next) - socket.io middleware + */ + //ui: { path: "ui" }, + + /** Colourise the console output of the debug node */ + //debugUseColors: true, + + /** The maximum length, in characters, of any message sent to the debug sidebar tab */ + debugMaxLength: 1000, + + /** Maximum buffer size for the exec node. Defaults to 10Mb */ + //execMaxBufferSize: 10000000, + + /** Timeout in milliseconds for HTTP request connections. Defaults to 120s */ + //httpRequestTimeout: 120000, + + /** Retry time in milliseconds for MQTT connections */ + mqttReconnectTime: 15000, + + /** Retry time in milliseconds for Serial port connections */ + serialReconnectTime: 15000, + + /** Retry time in milliseconds for TCP socket connections */ + //socketReconnectTime: 10000, + + /** Timeout in milliseconds for TCP server socket connections. Defaults to no timeout */ + //socketTimeout: 120000, + + /** Maximum number of messages to wait in queue while attempting to connect to TCP socket + * defaults to 1000 + */ + //tcpMsgQueueSize: 2000, + + /** Timeout in milliseconds for inbound WebSocket connections that do not + * match any configured node. Defaults to 5000 + */ + //inboundWebSocketTimeout: 5000, + + /** To disable the option for using local files for storing keys and + * certificates in the TLS configuration node, set this to true. + */ + //tlsConfigDisableLocalFiles: true, + + /** The following property can be used to verify websocket connection attempts. + * This allows, for example, the HTTP request headers to be checked to ensure + * they include valid authentication information. + */ + //webSocketNodeVerifyClient: function(info) { + // /** 'info' has three properties: + // * - origin : the value in the Origin header + // * - req : the HTTP request + // * - secure : true if req.connection.authorized or req.connection.encrypted is set + // * + // * The function should return true if the connection should be accepted, false otherwise. + // * + // * Alternatively, if this function is defined to accept a second argument, callback, + // * it can be used to verify the client asynchronously. + // * The callback takes three arguments: + // * - result : boolean, whether to accept the connection or not + // * - code : if result is false, the HTTP error status to return + // * - reason: if result is false, the HTTP reason string to return + // */ + //}, } EOF echo -e "${CM}${CL} \r" From 3f74ab7fb6a5095c0495d2611804d54120f48771 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 15:03:07 -0500 Subject: [PATCH 1159/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index eabf2f16..ecb1f64b 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -13,7 +13,7 @@ GN=`echo "\033[1;92m"` CL=`echo "\033[m"` trap die ERR trap 'die "Script interrupted."' INT -echo -en "${RD} Backup your Node-Red flows before running this script!! " +echo -en "${RD} Backup your Node-Red flows before running this script!!${CL} \n " while true; do read -p "This will install midnight-red theme. Proceed(y/n)?" yn case $yn in From 6adb1a7615ac7eecad474b5bb832ffb2a12a040e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 15:12:29 -0500 Subject: [PATCH 1160/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index ecb1f64b..5717ae9c 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -13,7 +13,7 @@ GN=`echo "\033[1;92m"` CL=`echo "\033[m"` trap die ERR trap 'die "Script interrupted."' INT -echo -en "${RD} Backup your Node-Red flows before running this script!!${CL} \n " +echo -e "${RD} Backup your Node-Red flows before running this script!!${CL} \n " while true; do read -p "This will install midnight-red theme. Proceed(y/n)?" yn case $yn in @@ -127,7 +127,7 @@ module.exports = { // type: "credentials", // users: [{ // username: "admin", - // password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.", + // password: "", // permissions: "*" // }] //}, @@ -172,8 +172,8 @@ module.exports = { * The `pass` field is a bcrypt hash of the password. * See http://nodered.org/docs/security.html#generating-the-password-hash */ - //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, - //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, + //httpNodeAuth: {user:"user",pass:""}, + //httpStaticAuth: {user:"user",pass:""}, /******************************************************************************* * Server Settings From d6cd362dd2272b64adf0dab759a7b0436a8f2068 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 15:16:40 -0500 Subject: [PATCH 1161/6505] Add files via upload --- misc/node-red-dark.sh | 501 ++---------------------------------------- 1 file changed, 19 insertions(+), 482 deletions(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index 5717ae9c..fa1e4b2c 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -35,7 +35,6 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } - echo -en "${GN} Updating Container OS... " apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null @@ -48,498 +47,36 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Writing Settings... " cat < /root/.node-red/settings.js -/** - * This is the default settings file provided by Node-RED. - * - * It can contain any valid JavaScript code that will get run when Node-RED - * is started. - * - * Lines that start with // are commented out. - * Each entry should be separated from the entries above and below by a comma ',' - * - * For more information about individual settings, refer to the documentation: - * https://nodered.org/docs/user-guide/runtime/configuration - * - * The settings are split into the following sections: - * - Flow File and User Directory Settings - * - Security - * - Server Settings - * - Runtime Settings - * - Editor Settings - * - Node Settings - * - **/ +module.exports = { uiPort: process.env.PORT || 1880, -module.exports = { + mqttReconnectTime: 15000, -/******************************************************************************* - * Flow File and User Directory Settings - * - flowFile - * - credentialSecret - * - flowFilePretty - * - userDir - * - nodesDir - ******************************************************************************/ + serialReconnectTime: 15000, - /** The file containing the flows. If not set, defaults to flows_.json **/ - flowFile: 'flows.json', + debugMaxLength: 1000, - /** By default, credentials are encrypted in storage using a generated key. To - * specify your own secret, set the following property. - * If you want to disable encryption of credentials, set this property to false. - * Note: once you set this property, do not change it - doing so will prevent - * node-red from being able to decrypt your existing credentials and they will be - * lost. - */ - //credentialSecret: "a-secret-key", - - /** By default, the flow JSON will be formatted over multiple lines making - * it easier to compare changes when using version control. - * To disable pretty-printing of the JSON set the following property to false. - */ - flowFilePretty: true, - - /** By default, all user data is stored in a directory called `.node-red` under - * the user's home directory. To use a different location, the following - * property can be used - */ - //userDir: '/home/nol/.node-red/', - - /** Node-RED scans the `nodes` directory in the userDir to find local node files. - * The following property can be used to specify an additional directory to scan. - */ - //nodesDir: '/home/nol/.node-red/nodes', - -/******************************************************************************* - * Security - * - adminAuth - * - https - * - httpsRefreshInterval - * - requireHttps - * - httpNodeAuth - * - httpStaticAuth - ******************************************************************************/ - - /** To password protect the Node-RED editor and admin API, the following - * property can be used. See http://nodered.org/docs/security.html for details. - */ - //adminAuth: { - // type: "credentials", - // users: [{ - // username: "admin", - // password: "", - // permissions: "*" - // }] - //}, - - /** The following property can be used to enable HTTPS - * This property can be either an object, containing both a (private) key - * and a (public) certificate, or a function that returns such an object. - * See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener - * for details of its contents. - */ - - /** Option 1: static object */ - //https: { - // key: require("fs").readFileSync('privkey.pem'), - // cert: require("fs").readFileSync('cert.pem') - //}, - - /** Option 2: function that returns the HTTP configuration object */ - // https: function() { - // // This function should return the options object, or a Promise - // // that resolves to the options object - // return { - // key: require("fs").readFileSync('privkey.pem'), - // cert: require("fs").readFileSync('cert.pem') - // } - // }, - - /** If the `https` setting is a function, the following setting can be used - * to set how often, in hours, the function will be called. That can be used - * to refresh any certificates. - */ - //httpsRefreshInterval : 12, - - /** The following property can be used to cause insecure HTTP connections to - * be redirected to HTTPS. - */ - //requireHttps: true, - - /** To password protect the node-defined HTTP endpoints (httpNodeRoot), - * including node-red-dashboard, or the static content (httpStatic), the - * following properties can be used. - * The `pass` field is a bcrypt hash of the password. - * See http://nodered.org/docs/security.html#generating-the-password-hash - */ - //httpNodeAuth: {user:"user",pass:""}, - //httpStaticAuth: {user:"user",pass:""}, - -/******************************************************************************* - * Server Settings - * - uiPort - * - uiHost - * - apiMaxLength - * - httpServerOptions - * - httpAdminRoot - * - httpAdminMiddleware - * - httpNodeRoot - * - httpNodeCors - * - httpNodeMiddleware - * - httpStatic - ******************************************************************************/ - - /** the tcp port that the Node-RED web server is listening on */ - uiPort: process.env.PORT || 1880, - - /** By default, the Node-RED UI accepts connections on all IPv4 interfaces. - * To listen on all IPv6 addresses, set uiHost to "::", - * The following property can be used to listen on a specific interface. For - * example, the following would only allow connections from the local machine. - */ - //uiHost: "127.0.0.1", - - /** The maximum size of HTTP request that will be accepted by the runtime api. - * Default: 5mb - */ - //apiMaxLength: '5mb', - - /** The following property can be used to pass custom options to the Express.js - * server used by Node-RED. For a full list of available options, refer - * to http://expressjs.com/en/api.html#app.settings.table - */ - //httpServerOptions: { }, - - /** By default, the Node-RED UI is available at http://localhost:1880/ - * The following property can be used to specify a different root path. - * If set to false, this is disabled. - */ - //httpAdminRoot: '/admin', - - /** The following property can be used to add a custom middleware function - * in front of all admin http routes. For example, to set custom http - * headers. It can be a single function or an array of middleware functions. - */ - // httpAdminMiddleware: function(req,res,next) { - // // Set the X-Frame-Options header to limit where the editor - // // can be embedded - // //res.set('X-Frame-Options', 'sameorigin'); - // next(); - // }, - - - /** Some nodes, such as HTTP In, can be used to listen for incoming http requests. - * By default, these are served relative to '/'. The following property - * can be used to specifiy a different root path. If set to false, this is - * disabled. - */ - //httpNodeRoot: '/red-nodes', - - /** The following property can be used to configure cross-origin resource sharing - * in the HTTP nodes. - * See https://github.com/troygoode/node-cors#configuration-options for - * details on its contents. The following is a basic permissive set of options: - */ - //httpNodeCors: { - // origin: "*", - // methods: "GET,PUT,POST,DELETE" - //}, - - /** If you need to set an http proxy please set an environment variable - * called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system. - * For example - http_proxy=http://myproxy.com:8080 - * (Setting it here will have no effect) - * You may also specify no_proxy (or NO_PROXY) to supply a comma separated - * list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk - */ - - /** The following property can be used to add a custom middleware function - * in front of all http in nodes. This allows custom authentication to be - * applied to all http in nodes, or any other sort of common request processing. - * It can be a single function or an array of middleware functions. - */ - //httpNodeMiddleware: function(req,res,next) { - // // Handle/reject the request, or pass it on to the http in node by calling next(); - // // Optionally skip our rawBodyParser by setting this to true; - // //req.skipRawBodyParser = true; - // next(); - //}, - - /** When httpAdminRoot is used to move the UI to a different root path, the - * following property can be used to identify a directory of static content - * that should be served at http://localhost:1880/. - */ - //httpStatic: '/home/nol/node-red-static/', - -/******************************************************************************* - * Runtime Settings - * - lang - * - logging - * - contextStorage - * - exportGlobalContextKeys - * - externalModules - ******************************************************************************/ - - /** Uncomment the following to run node-red in your preferred language. - * Available languages include: en-US (default), ja, de, zh-CN, zh-TW, ru, ko - * Some languages are more complete than others. - */ - // lang: "de", - - /** Configure the logging output */ - logging: { - /** Only console logging is currently supported */ - console: { - /** Level of logging to be recorded. Options are: - * fatal - only those errors which make the application unusable should be recorded - * error - record errors which are deemed fatal for a particular request + fatal errors - * warn - record problems which are non fatal + errors + fatal errors - * info - record information about the general running of the application + warn + error + fatal errors - * debug - record information which is more verbose than info + info + warn + error + fatal errors - * trace - record very detailed logging + debug + info + warn + error + fatal errors - * off - turn off all logging (doesn't affect metrics or audit) - */ - level: "info", - /** Whether or not to include metric events in the log output */ - metrics: false, - /** Whether or not to include audit events in the log output */ - audit: false - } - }, - - /** Context Storage - * The following property can be used to enable context storage. The configuration - * provided here will enable file-based context that flushes to disk every 30 seconds. - * Refer to the documentation for further options: https://nodered.org/docs/api/context/ - */ - //contextStorage: { - // default: { - // module:"localfilesystem" - // }, - //}, - - /** `global.keys()` returns a list of all properties set in global context. - * This allows them to be displayed in the Context Sidebar within the editor. - * In some circumstances it is not desirable to expose them to the editor. The - * following property can be used to hide any property set in `functionGlobalContext` - * from being list by `global.keys()`. - * By default, the property is set to false to avoid accidental exposure of - * their values. Setting this to true will cause the keys to be listed. - */ - exportGlobalContextKeys: false, - - /** Configure how the runtime will handle external npm modules. - * This covers: - * - whether the editor will allow new node modules to be installed - * - whether nodes, such as the Function node are allowed to have their - * own dynamically configured dependencies. - * The allow/denyList options can be used to limit what modules the runtime - * will install/load. It can use '*' as a wildcard that matches anything. - */ - externalModules: { - // autoInstall: false, /** Whether the runtime will attempt to automatically install missing modules */ - // autoInstallRetry: 30, /** Interval, in seconds, between reinstall attempts */ - // palette: { /** Configuration for the Palette Manager */ - // allowInstall: true, /** Enable the Palette Manager in the editor */ - // allowUpdate: true, /** Allow modules to be updated in the Palette Manager */ - // allowUpload: true, /** Allow module tgz files to be uploaded and installed */ - // allowList: ['*'], - // denyList: [], - // allowUpdateList: ['*'], - // denyUpdateList: [] - // }, - // modules: { /** Configuration for node-specified modules */ - // allowInstall: true, - // allowList: [], - // denyList: [] - // } - }, - - -/******************************************************************************* - * Editor Settings - * - disableEditor - * - editorTheme - ******************************************************************************/ - - /** The following property can be used to disable the editor. The admin API - * is not affected by this option. To disable both the editor and the admin - * API, use either the httpRoot or httpAdminRoot properties - */ - //disableEditor: false, - - /** Customising the editor - * See https://nodered.org/docs/user-guide/runtime/configuration#editor-themes - * for all available options. - */ - editorTheme: { - theme: "midnight-red" + functionGlobalContext: { }, - /** To disable the 'Welcome to Node-RED' tour that is displayed the first - * time you access the editor for each release of Node-RED, set this to false - */ - //tours: false, + exportGlobalContextKeys: false, - palette: { - /** The following property can be used to order the categories in the editor - * palette. If a node's category is not in the list, the category will get - * added to the end of the palette. - * If not set, the following default order is used: - */ - //categories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'], - }, - projects: { - /** To enable the Projects feature, set this value to true */ - enabled: false, - workflow: { - /** Set the default projects workflow mode. - * - manual - you must manually commit changes - * - auto - changes are automatically committed - * This can be overridden per-user from the 'Git config' - * section of 'User Settings' within the editor - */ - mode: "manual" - } - }, - - codeEditor: { - /** Select the text editor component used by the editor. - * Defaults to "ace", but can be set to "ace" or "monaco" - */ - lib: "ace", - options: { - /** The follow options only apply if the editor is set to "monaco" - * - * theme - must match the file name of a theme in - * packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/theme - * e.g. "tomorrow-night", "upstream-sunburst", "github", "my-theme" - */ - theme: "vs", - /** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc. - * for the full list, see https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandaloneeditorconstructionoptions.html - */ - //fontSize: 14, - //fontFamily: "Cascadia Code, Fira Code, Consolas, 'Courier New', monospace", - //fontLigatures: true, - } + // Configure the logging output + logging: { + console: { + level: "info", + metrics: false, + audit: false } }, -/******************************************************************************* - * Node Settings - * - fileWorkingDirectory - * - functionGlobalContext - * - functionExternalModules - * - nodeMessageBufferMaxLength - * - ui (for use with Node-RED Dashboard) - * - debugUseColors - * - debugMaxLength - * - execMaxBufferSize - * - httpRequestTimeout - * - mqttReconnectTime - * - serialReconnectTime - * - socketReconnectTime - * - socketTimeout - * - tcpMsgQueueSize - * - inboundWebSocketTimeout - * - tlsConfigDisableLocalFiles - * - webSocketNodeVerifyClient - ******************************************************************************/ - - /** The working directory to handle relative file paths from within the File nodes - * defaults to the working directory of the Node-RED process. - */ - //fileWorkingDirectory: "", - - /** Allow the Function node to load additional npm modules directly */ - functionExternalModules: true, - - /** The following property can be used to set predefined values in Global Context. - * This allows extra node modules to be made available with in Function node. - * For example, the following: - * functionGlobalContext: { os:require('os') } - * will allow the `os` module to be accessed in a Function node using: - * global.get("os") - */ - functionGlobalContext: { - // os:require('os'), + // Customising the editor + editorTheme: { + theme: "midnight-red" }, - - /** The maximum number of messages nodes will buffer internally as part of their - * operation. This applies across a range of nodes that operate on message sequences. - * defaults to no limit. A value of 0 also means no limit is applied. - */ - //nodeMessageBufferMaxLength: 0, - - /** If you installed the optional node-red-dashboard you can set it's path - * relative to httpNodeRoot - * Other optional properties include - * readOnly:{boolean}, - * middleware:{function or array}, (req,res,next) - http middleware - * ioMiddleware:{function or array}, (socket,next) - socket.io middleware - */ - //ui: { path: "ui" }, - - /** Colourise the console output of the debug node */ - //debugUseColors: true, - - /** The maximum length, in characters, of any message sent to the debug sidebar tab */ - debugMaxLength: 1000, - - /** Maximum buffer size for the exec node. Defaults to 10Mb */ - //execMaxBufferSize: 10000000, - - /** Timeout in milliseconds for HTTP request connections. Defaults to 120s */ - //httpRequestTimeout: 120000, - - /** Retry time in milliseconds for MQTT connections */ - mqttReconnectTime: 15000, - - /** Retry time in milliseconds for Serial port connections */ - serialReconnectTime: 15000, - - /** Retry time in milliseconds for TCP socket connections */ - //socketReconnectTime: 10000, - - /** Timeout in milliseconds for TCP server socket connections. Defaults to no timeout */ - //socketTimeout: 120000, - - /** Maximum number of messages to wait in queue while attempting to connect to TCP socket - * defaults to 1000 - */ - //tcpMsgQueueSize: 2000, - - /** Timeout in milliseconds for inbound WebSocket connections that do not - * match any configured node. Defaults to 5000 - */ - //inboundWebSocketTimeout: 5000, - - /** To disable the option for using local files for storing keys and - * certificates in the TLS configuration node, set this to true. - */ - //tlsConfigDisableLocalFiles: true, - - /** The following property can be used to verify websocket connection attempts. - * This allows, for example, the HTTP request headers to be checked to ensure - * they include valid authentication information. - */ - //webSocketNodeVerifyClient: function(info) { - // /** 'info' has three properties: - // * - origin : the value in the Origin header - // * - req : the HTTP request - // * - secure : true if req.connection.authorized or req.connection.encrypted is set - // * - // * The function should return true if the connection should be accepted, false otherwise. - // * - // * Alternatively, if this function is defined to accept a second argument, callback, - // * it can be used to verify the client asynchronously. - // * The callback takes three arguments: - // * - result : boolean, whether to accept the connection or not - // * - code : if result is false, the HTTP error status to return - // * - reason: if result is false, the HTTP reason string to return - // */ - //}, + projects: { + // To enable the Projects feature, set this value to true + enabled: true + } } EOF echo -e "${CM}${CL} \r" From 5a1349291ef4d8161404de991471f6d00c3523bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 15:23:26 -0500 Subject: [PATCH 1162/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index fa1e4b2c..1d4eb699 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -46,7 +46,7 @@ npm install @node-red-contrib-themes/midnight-red &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Writing Settings... " -cat < /root/.node-red/settings.js +cat <> /root/.node-red/settings.js module.exports = { uiPort: process.env.PORT || 1880, mqttReconnectTime: 15000, From d3952e50974b383961ff642010fac709aae89494 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 15:40:36 -0500 Subject: [PATCH 1163/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 43 +------------------------------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index 1d4eb699..2864fed8 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -1,19 +1,12 @@ #!/usr/bin/env bash # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-dark.sh)" set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -trap die ERR -trap 'die "Script interrupted."' INT -echo -e "${RD} Backup your Node-Red flows before running this script!!${CL} \n " +echo -e "${RD}Backup your Node-Red flows before running this script!!${CL} \n " while true; do read -p "This will install midnight-red theme. Proceed(y/n)?" yn case $yn in @@ -23,18 +16,6 @@ while true; do esac done clear -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} echo -en "${GN} Updating Container OS... " apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null @@ -47,28 +28,6 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Writing Settings... " cat <> /root/.node-red/settings.js -module.exports = { uiPort: process.env.PORT || 1880, - - mqttReconnectTime: 15000, - - serialReconnectTime: 15000, - - debugMaxLength: 1000, - - functionGlobalContext: { - }, - exportGlobalContextKeys: false, - - - // Configure the logging output - logging: { - console: { - level: "info", - metrics: false, - audit: false - } - }, - // Customising the editor editorTheme: { theme: "midnight-red" From a6359e4972320ae02ec14642e52ccbf1c14d4524 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 15:41:41 -0500 Subject: [PATCH 1164/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index 2864fed8..8c1e25a2 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -8,7 +8,7 @@ GN=`echo "\033[1;92m"` CL=`echo "\033[m"` echo -e "${RD}Backup your Node-Red flows before running this script!!${CL} \n " while true; do - read -p "This will install midnight-red theme. Proceed(y/n)?" yn + read -p "This will Install midnight-red theme. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From 121388aaf2bf47ed530b456d731096c3ab86ec7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 16:11:09 -0500 Subject: [PATCH 1165/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index 8c1e25a2..152a45a8 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -6,6 +6,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +clear echo -e "${RD}Backup your Node-Red flows before running this script!!${CL} \n " while true; do read -p "This will Install midnight-red theme. Proceed(y/n)?" yn @@ -27,7 +28,29 @@ npm install @node-red-contrib-themes/midnight-red &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Writing Settings... " -cat <> /root/.node-red/settings.js +cat < /root/.node-red/settings.js +module.exports = { uiPort: process.env.PORT || 1880, + + mqttReconnectTime: 15000, + + serialReconnectTime: 15000, + + debugMaxLength: 1000, + + functionGlobalContext: { + }, + exportGlobalContextKeys: false, + + + // Configure the logging output + logging: { + console: { + level: "info", + metrics: false, + audit: false + } + }, + // Customising the editor editorTheme: { theme: "midnight-red" From c06698ad9955120cadb53cd46605893ebffe2640 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 16:30:43 -0500 Subject: [PATCH 1166/6505] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1bbe2239..6c191c47 100644 --- a/README.md +++ b/README.md @@ -380,7 +380,14 @@ Run in the LXC console (Restart after update) ```yaml npm install -g --unsafe-perm node-red ``` - + +⚙️ **To Install Midnight-Red Theme** ⚠️ **Backup your flows before running this script!!** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-dark.sh)" +``` + ____________________________________________________________________________________________
From 9f4b2490777ec000e94355a2c3abd419c2163bb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 16:32:41 -0500 Subject: [PATCH 1167/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c191c47..2e74ff7e 100644 --- a/README.md +++ b/README.md @@ -351,7 +351,7 @@ ________________________________________________________________________________
-Node-Red LXC + 🔸Node-Red LXC

@node-red

From 247a3a34291fbc74bd1a20a51b352451faba685b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 16:36:21 -0500 Subject: [PATCH 1168/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 43140b1e..7f714e25 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-18 + +### Changed + +- **Node-Red LXC** + - Add Install [Theme](https://github.com/node-red-contrib-themes/midnight-red) Script + ## 2022-02-16 ### Changed From bbcad55c68e39581eb1d40211729d3da3ac76d83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 16:41:04 -0500 Subject: [PATCH 1169/6505] Update node-red_container.sh --- ct/node-red_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/node-red_container.sh b/ct/node-red_container.sh index f2e09f7c..ebd544b3 100644 --- a/ct/node-red_container.sh +++ b/ct/node-red_container.sh @@ -8,7 +8,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done - +clear set -o errexit set -o errtrace set -o nounset From ddda64d6de8abb5d37eac86be96f6fe2dd607712 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 16:57:04 -0500 Subject: [PATCH 1170/6505] Update node-red-dark.sh --- misc/node-red-dark.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh index 152a45a8..514cbb49 100644 --- a/misc/node-red-dark.sh +++ b/misc/node-red-dark.sh @@ -57,7 +57,7 @@ module.exports = { uiPort: process.env.PORT || 1880, }, projects: { // To enable the Projects feature, set this value to true - enabled: true + enabled: false } } EOF From 6d5d432829ae5eeee10cb37eb6e9dc57d2e25129 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 17:16:50 -0500 Subject: [PATCH 1171/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e74ff7e..cd9b686b 100644 --- a/README.md +++ b/README.md @@ -381,7 +381,7 @@ Run in the LXC console (Restart after update) npm install -g --unsafe-perm node-red ``` -⚙️ **To Install Midnight-Red Theme** ⚠️ **Backup your flows before running this script!!** +⚙️ **To Install [Midnight-Red Theme](https://github.com/node-red-contrib-themes/midnight-red)** ⚠️ **Backup your flows before running this script!!** Run in the LXC console ```yaml From e1e8ab39742a9ad91493e582cfcd7977e32d19e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 19:31:06 -0500 Subject: [PATCH 1172/6505] Update and rename node-red-dark.sh to node-red-themes.sh --- misc/node-red-dark.sh | 72 --------------------- misc/node-red-themes.sh | 136 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 72 deletions(-) delete mode 100644 misc/node-red-dark.sh create mode 100644 misc/node-red-themes.sh diff --git a/misc/node-red-dark.sh b/misc/node-red-dark.sh deleted file mode 100644 index 514cbb49..00000000 --- a/misc/node-red-dark.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-dark.sh)" -set -o errexit -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -clear -echo -e "${RD}Backup your Node-Red flows before running this script!!${CL} \n " -while true; do - read -p "This will Install midnight-red theme. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing midnight-red Theme... " -cd /root/.node-red -npm install @node-red-contrib-themes/midnight-red &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Writing Settings... " -cat < /root/.node-red/settings.js -module.exports = { uiPort: process.env.PORT || 1880, - - mqttReconnectTime: 15000, - - serialReconnectTime: 15000, - - debugMaxLength: 1000, - - functionGlobalContext: { - }, - exportGlobalContextKeys: false, - - - // Configure the logging output - logging: { - console: { - level: "info", - metrics: false, - audit: false - } - }, - - // Customising the editor - editorTheme: { - theme: "midnight-red" - }, - projects: { - // To enable the Projects feature, set this value to true - enabled: false - } -} -EOF -echo -e "${CM}${CL} \r" - -echo -en "${GN} Restarting Node-Red... " -echo -e "${CM}${CL} \r" -node-red-restart -echo -en "${GN} Finished... ${CL} \n" -exit - - diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh new file mode 100644 index 00000000..59a19aa8 --- /dev/null +++ b/misc/node-red-themes.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-themes.sh)" +set -o errexit +show_menu(){ + YW=`echo "\033[33m"` + RD=`echo "\033[01;31m"` + BL=`echo "\033[36m"` + CM='\xE2\x9C\x94\033' + GN=`echo "\033[1;92m"` + CL=`echo "\033[m"` +echo -e "${RD} Backup your Node-Red flows before running this script!!${CL} \n " +while true; do + read -p "This will Install Node-Red Themes. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +echo -e "${RD} Backup your Node-Red flows before installing any theme!!${CL} \n " + printf "\n${BL}*********************************************${CL}\n" + printf "${BL}**${number} 1)${RD} Dark Theme ${CL}\n" + printf "${BL}**${number} 2)${RD} Dracula Theme ${CL}\n" + printf "${BL}**${number} 3)${RD} Midnight-Red Theme ${CL}\n" + printf "${BL}**${number} 4)${RD} Oled Theme ${CL}\n" + printf "${BL}**${number} 5)${RD} Solarized-Dark Theme ${CL}\n" + printf "${BL}**${number} 6)${RD} Solarized-Light Theme ${CL}\n" + printf "${BL}*********************************************${CL}\n" + printf "Please choose a theme from the menu and enter or ${RD}x to exit. ${CL}" + read opt +} + +option_picked(){ + msgcolor=`echo "\033[01;31m"` + normal=`echo "\033[00;00m"` + message=${@:-"${CL}Error: No message passed"} + printf "${RD}${message}${CL}\n" +} + +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + option_picked "Installing Dark Theme"; + THEME=dark + break; + ;; + 2) clear; + option_picked "Installing Dracula Theme"; + THEME=dracula + break; + ;; + 3) clear; + option_picked "Installing Midnight-Red Theme"; + THEME=midnight-red + break; + ;; + 4) clear; + option_picked "Installing Oled Theme"; + THEME=oled + break; + ;; + 5) clear; + option_picked "Installing Solarized-Dark Theme"; + THEME=solarized-dark + break; + ;; + 5) clear; + option_picked "Installing Solarized-Light Theme"; + THEME=solarized-light + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a theme from the menu"; + show_menu; + ;; + esac + fi + done +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing ${THEME} Theme... " +cd /root/.node-red +npm install @node-red-contrib-themes/${THEME} &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Writing Settings... " +cat < /root/.node-red/settings.js +module.exports = { uiPort: process.env.PORT || 1880, + mqttReconnectTime: 15000, + serialReconnectTime: 15000, + debugMaxLength: 1000, + functionGlobalContext: { + }, + exportGlobalContextKeys: false, + + // Configure the logging output + logging: { + console: { + level: "info", + metrics: false, + audit: false + } + }, + + // Customising the editor + editorTheme: { + theme: "${THEME}" + }, + projects: { + // To enable the Projects feature, set this value to true + enabled: false + } +} +EOF +echo -e "${CM}${CL} \r" + +echo -en "${GN} Restarting Node-Red... " +echo -e "${CM}${CL} \r" +node-red-restart +echo -en "${GN} Finished... ${CL} \n" +exit From 73bf34eac7de4dbcd8b8c9540ef44558e5a83752 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 19:32:18 -0500 Subject: [PATCH 1173/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cd9b686b..f8507168 100644 --- a/README.md +++ b/README.md @@ -381,11 +381,11 @@ Run in the LXC console (Restart after update) npm install -g --unsafe-perm node-red ``` -⚙️ **To Install [Midnight-Red Theme](https://github.com/node-red-contrib-themes/midnight-red)** ⚠️ **Backup your flows before running this script!!** +⚙️ **To Install Node-Red Themes** ⚠️ **Backup your flows before running this script!!** Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-dark.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-themes.sh)" ``` ____________________________________________________________________________________________ From 93aad25a912f6deae9a17b6712ad93f7a2ccef4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 19:33:04 -0500 Subject: [PATCH 1174/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7f714e25..5edb00fd 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Node-Red LXC** - - Add Install [Theme](https://github.com/node-red-contrib-themes/midnight-red) Script + - Add Install Themes Script ## 2022-02-16 From 6ae1ff66fef938dfb5a69fb22d669b3ecd9da1b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 19:40:15 -0500 Subject: [PATCH 1175/6505] Update node-red-themes.sh --- misc/node-red-themes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh index 59a19aa8..5700a0b1 100644 --- a/misc/node-red-themes.sh +++ b/misc/node-red-themes.sh @@ -71,7 +71,7 @@ while [ $opt != '' ] THEME=solarized-dark break; ;; - 5) clear; + 6) clear; option_picked "Installing Solarized-Light Theme"; THEME=solarized-light break; From 912501d8860464c1374994b02146ad6819b019df Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 19:59:15 -0500 Subject: [PATCH 1176/6505] Update node-red-themes.sh --- misc/node-red-themes.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh index 5700a0b1..19e3d941 100644 --- a/misc/node-red-themes.sh +++ b/misc/node-red-themes.sh @@ -20,12 +20,12 @@ done clear echo -e "${RD} Backup your Node-Red flows before installing any theme!!${CL} \n " printf "\n${BL}*********************************************${CL}\n" - printf "${BL}**${number} 1)${RD} Dark Theme ${CL}\n" - printf "${BL}**${number} 2)${RD} Dracula Theme ${CL}\n" - printf "${BL}**${number} 3)${RD} Midnight-Red Theme ${CL}\n" - printf "${BL}**${number} 4)${RD} Oled Theme ${CL}\n" - printf "${BL}**${number} 5)${RD} Solarized-Dark Theme ${CL}\n" - printf "${BL}**${number} 6)${RD} Solarized-Light Theme ${CL}\n" + printf "${BL}**${YW} 1)${GN} Dark Theme ${CL}\n" + printf "${BL}**${YW} 2)${GN} Dracula Theme ${CL}\n" + printf "${BL}**${YW} 3)${GN} Midnight-Red Theme ${CL}\n" + printf "${BL}**${YW} 4)${GN} Oled Theme ${CL}\n" + printf "${BL}**${YW} 5)${GN} Solarized-Dark Theme ${CL}\n" + printf "${BL}**${YW} 6)${GN} Solarized-Light Theme ${CL}\n" printf "${BL}*********************************************${CL}\n" printf "Please choose a theme from the menu and enter or ${RD}x to exit. ${CL}" read opt From 20bd85ee388af8e7c6472077fb57313357bd6baa Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 21:51:12 -0500 Subject: [PATCH 1177/6505] Update node-red-themes.sh --- misc/node-red-themes.sh | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh index 19e3d941..82f030f9 100644 --- a/misc/node-red-themes.sh +++ b/misc/node-red-themes.sh @@ -20,12 +20,13 @@ done clear echo -e "${RD} Backup your Node-Red flows before installing any theme!!${CL} \n " printf "\n${BL}*********************************************${CL}\n" - printf "${BL}**${YW} 1)${GN} Dark Theme ${CL}\n" - printf "${BL}**${YW} 2)${GN} Dracula Theme ${CL}\n" - printf "${BL}**${YW} 3)${GN} Midnight-Red Theme ${CL}\n" - printf "${BL}**${YW} 4)${GN} Oled Theme ${CL}\n" - printf "${BL}**${YW} 5)${GN} Solarized-Dark Theme ${CL}\n" - printf "${BL}**${YW} 6)${GN} Solarized-Light Theme ${CL}\n" + printf "${BL}**${YW} 1)${GN} Default Theme ${CL}\n" + printf "${BL}**${YW} 2)${GN} Dark Theme ${CL}\n" + printf "${BL}**${YW} 3)${GN} Dracula Theme ${CL}\n" + printf "${BL}**${YW} 4)${GN} Midnight-Red Theme ${CL}\n" + printf "${BL}**${YW} 5)${GN} Oled Theme ${CL}\n" + printf "${BL}**${YW} 6)${GN} Solarized-Dark Theme ${CL}\n" + printf "${BL}**${YW} 7)${GN} Solarized-Light Theme ${CL}\n" printf "${BL}*********************************************${CL}\n" printf "Please choose a theme from the menu and enter or ${RD}x to exit. ${CL}" read opt @@ -47,31 +48,37 @@ while [ $opt != '' ] else case $opt in 1) clear; + option_picked "Installing Default Theme"; + THEME= + JS=// + break; + ;; + 2) clear; option_picked "Installing Dark Theme"; THEME=dark break; ;; - 2) clear; + 3) clear; option_picked "Installing Dracula Theme"; THEME=dracula break; ;; - 3) clear; + 4) clear; option_picked "Installing Midnight-Red Theme"; THEME=midnight-red break; ;; - 4) clear; + 5) clear; option_picked "Installing Oled Theme"; THEME=oled break; ;; - 5) clear; + 6) clear; option_picked "Installing Solarized-Dark Theme"; THEME=solarized-dark break; ;; - 6) clear; + 7) clear; option_picked "Installing Solarized-Light Theme"; THEME=solarized-light break; @@ -95,9 +102,12 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing ${THEME} Theme... " cd /root/.node-red +if [ "${THEME}" = "" ]; then + echo -e "${CM}${CL} \r" + else npm install @node-red-contrib-themes/${THEME} &>/dev/null echo -e "${CM}${CL} \r" - +fi echo -en "${GN} Writing Settings... " cat < /root/.node-red/settings.js module.exports = { uiPort: process.env.PORT || 1880, @@ -119,7 +129,7 @@ module.exports = { uiPort: process.env.PORT || 1880, // Customising the editor editorTheme: { - theme: "${THEME}" + ${JS}theme: "${THEME}" }, projects: { // To enable the Projects feature, set this value to true From b73684937a58388226da9d498149cdfadcb72837 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 22:06:20 -0500 Subject: [PATCH 1178/6505] Add files via upload --- misc/images/node-red-themes.png | Bin 0 -> 31933 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/node-red-themes.png diff --git a/misc/images/node-red-themes.png b/misc/images/node-red-themes.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a7bdb8a2aa3ef4af5496a4e964c4d9c4344a1e GIT binary patch literal 31933 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 literal 0 HcmV?d00001 From 71d87e82793fbd017576de05f8f371e863a665a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Feb 2022 22:07:50 -0500 Subject: [PATCH 1179/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 5edb00fd..70cd586b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Node-Red LXC** - - Add Install Themes Script + - Add Install [Themes Script](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/node-red-themes.png) ## 2022-02-16 From 684978c0b840140f0dffd7ec1b4a2b4f859ebeb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 03:45:12 -0500 Subject: [PATCH 1180/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8507168..cfff3c60 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ ________________________________________________________________________________
- 🔸Home Assistant Container LXC (Podman) + Home Assistant Container LXC (Podman)

@home-assistant

From 8d376920551300415ebf2b3268fe376eae24e3d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 04:38:20 -0500 Subject: [PATCH 1181/6505] Update webmin.sh --- misc/webmin.sh | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 4b1d5fcd..ad441085 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -1,4 +1,11 @@ #!/usr/bin/env bash +IP=hostname -I +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` while true; do read -p "This will Install Webmin, Proceed(y/n)?" yn case $yn in @@ -7,19 +14,27 @@ while true; do * ) echo "Please answer yes or no.";; esac done -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -echo -e "Loading Script..." -echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" +clear + +echo -en "${GN} Installing Prerequisites... " apt update &>/dev/null apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" +echo -e "${CM}${CL} \r" + +echo -en "${GN} Downloading Webmin... " wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" +echo -e "${CM}${CL} \r" + +echo -e "${GN} Installing Webmin... " dpkg --install webmin_1.984_all.deb &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" +echo -e "${CM}${CL} \r" + +echo -e "${GN} Setting Default Webmin usermame & password to root... " /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null rm -rf /root/webmin_1.984_all.deb -echo -e "Install Complete, Now Go To https:// IP:10000" +echo -e "${CM}${CL} \r" + +echo -e "${BL} Successfully Installed Webmin, Now Go To https:// ${IP):10000 ${CL}" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From 13408d96674ab6e2b9c2980682dcee341e323f32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 04:40:19 -0500 Subject: [PATCH 1182/6505] Update webmin.sh --- misc/webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index ad441085..b7c49f4e 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -IP=hostname -I +IP=`hostname -I` YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 3c2b85192361314140d3b73cebc816a5bfe5cf2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 04:42:07 -0500 Subject: [PATCH 1183/6505] Update webmin.sh --- misc/webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index b7c49f4e..b8bb7c3c 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -IP=`hostname -I` +IP=[hostname -I] YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From bb6d40bdaeb9d10c6aaf80f2bfbcf2d30e52800d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 04:47:36 -0500 Subject: [PATCH 1184/6505] Update webmin.sh --- misc/webmin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index b8bb7c3c..c815ecaa 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -IP=[hostname -I] + YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -34,7 +34,7 @@ echo -e "${GN} Setting Default Webmin usermame & password to root... " rm -rf /root/webmin_1.984_all.deb echo -e "${CM}${CL} \r" -echo -e "${BL} Successfully Installed Webmin, Now Go To https:// ${IP):10000 ${CL}" +echo -e "${BL} Successfully Installed Webmin, Now Go To https://IP:10000 ${CL}" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From 4783767563fb0fb3b82d7244da72b0ac8871e781 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 04:50:15 -0500 Subject: [PATCH 1185/6505] Update webmin.sh --- misc/webmin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index c815ecaa..69594305 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -25,11 +25,11 @@ echo -en "${GN} Downloading Webmin... " wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null echo -e "${CM}${CL} \r" -echo -e "${GN} Installing Webmin... " +echo -en "${GN} Installing Webmin... " dpkg --install webmin_1.984_all.deb &>/dev/null echo -e "${CM}${CL} \r" -echo -e "${GN} Setting Default Webmin usermame & password to root... " +echo -en "${GN} Setting Default Webmin usermame & password to root... " /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null rm -rf /root/webmin_1.984_all.deb echo -e "${CM}${CL} \r" From eb137725b15fcf56959ec5ba9d70c70ab7f328b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 04:52:09 -0500 Subject: [PATCH 1186/6505] Update webmin.sh --- misc/webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 69594305..2056eaa1 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -22,7 +22,7 @@ apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip sh echo -e "${CM}${CL} \r" echo -en "${GN} Downloading Webmin... " -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null +wget --show-progress http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Webmin... " From 39f0fe7c1119f08c19b628391a41dd8001ca6ed1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 04:54:43 -0500 Subject: [PATCH 1187/6505] Update webmin.sh --- misc/webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 2056eaa1..69594305 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -22,7 +22,7 @@ apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip sh echo -e "${CM}${CL} \r" echo -en "${GN} Downloading Webmin... " -wget --show-progress http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Webmin... " From 6be1f084d6b433ffe14f862ddb3fe85ffd9ebf8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 10:03:10 -0500 Subject: [PATCH 1188/6505] Update webmin.sh --- misc/webmin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 69594305..f0050597 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -33,8 +33,8 @@ echo -en "${GN} Setting Default Webmin usermame & password to root... " /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null rm -rf /root/webmin_1.984_all.deb echo -e "${CM}${CL} \r" - -echo -e "${BL} Successfully Installed Webmin, Now Go To https://IP:10000 ${CL}" +IP=$(hostname -I | cut -f1 -d ' ') +echo -e "${BL} Successfully Installed Webmin, Now Go To https://&{IP}:10000 ${CL}" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From 24e13ac931c6ed5bf8897d52afd44db3ac036a4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 10:15:00 -0500 Subject: [PATCH 1189/6505] Update webmin.sh --- misc/webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index f0050597..3beaeaf8 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -34,7 +34,7 @@ echo -en "${GN} Setting Default Webmin usermame & password to root... " rm -rf /root/webmin_1.984_all.deb echo -e "${CM}${CL} \r" IP=$(hostname -I | cut -f1 -d ' ') -echo -e "${BL} Successfully Installed Webmin, Now Go To https://&{IP}:10000 ${CL}" +echo -e "${BL} Successfully Installed Webmin, Now Go To https://${IP}:10000 ${CL}" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From e09fe60781d796feaebaf478a0abd8f031ce9ba0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 10:31:25 -0500 Subject: [PATCH 1190/6505] Update npm_setup.sh --- setup/npm_setup.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh index 3a6a4b14..c3917d44 100644 --- a/setup/npm_setup.sh +++ b/setup/npm_setup.sh @@ -87,9 +87,9 @@ sudo apt-get install -y nodejs git make g++ gcc &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Yarn... \e[0m" npm install --global yarn &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.15... \e[0m" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.15 -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-2.9.15 +echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.16... \e[0m" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.16 -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-2.9.16 echo -e "${CHECKMARK} \e[1;92m Setting up Enviroment... \e[0m" ln -sf /usr/bin/python3 /usr/bin/python @@ -97,8 +97,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+#v2.9.15+g" backend/package.json -sed -i "s+0.0.0+#v2.9.15+g" frontend/package.json +sed -i "s+0.0.0+#v2.9.16+g" backend/package.json +sed -i "s+0.0.0+#v2.9.16+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") From 875b192c87ac4793429da40be7608430cb7d61fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 12:49:15 -0500 Subject: [PATCH 1191/6505] Create npm_update.sh --- misc/npm_update.sh | 161 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 misc/npm_update.sh diff --git a/misc/npm_update.sh b/misc/npm_update.sh new file mode 100644 index 00000000..6bfef651 --- /dev/null +++ b/misc/npm_update.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +while true; do + read -p "This will update Nginx Proxy Manager LXC Container. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +T="$(date +%s)" +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +if [ -f /lib/systemd/system/npm.service ]; then +echo -en "${GN} Prep For Update... " +sleep 2 +echo -e "${CM}${CL} \r" +echo -en "${GN} Stopping Services... " + systemctl stop openresty + systemctl stop npm +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleaning Old Files... " + rm -rf /app \ + /var/www/html \ + /etc/nginx \ + /var/log/nginx \ + /var/lib/nginx \ + /var/cache/nginx &>/dev/null + echo -e "${CM}${CL} \r" + else + echo -en "${RD} No NPM to Update! ${CL}" + exit +fi + +echo -en "${GN} Downloading NPM v2.9.16... " +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.16 -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-2.9.16 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Enviroment... " +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /usr/bin/certbot /opt/certbot/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx +sed -i "s+0.0.0+#v2.9.16+g" backend/package.json +sed -i "s+0.0.0+#v2.9.16+g" frontend/package.json +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done +mkdir -p /var/www/html /etc/nginx/logs +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf +mkdir -p /tmp/nginx/body \ +/run/nginx \ +/data/nginx \ +/data/custom_ssl \ +/data/logs \ +/data/access \ +/data/nginx/default_host \ +/data/nginx/default_www \ +/data/nginx/proxy_host \ +/data/nginx/redirection_host \ +/data/nginx/stream \ +/data/nginx/dead_host \ +/data/nginx/temp \ +/var/lib/nginx/cache/public \ +/var/lib/nginx/cache/private \ +/var/cache/nginx/proxy_temp +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf +echo -e "${CM}${CL} \r" + +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi + +mkdir -p /app/global /app/frontend/images +cp -r backend/* /app +cp -r global/* /app/global + +echo -en "${GN} Building Frontend... " +cd ./frontend +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +yarn build &>/dev/null +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images +echo -e "${CM}${CL} \r" + +echo -en "${GN} Initializing Backend... " +rm -rf /app/config/default.json &>/dev/null +if [ ! -f /app/config/production.json ]; then +cat << 'EOF' > /app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF +fi +cd /app +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Services... " +systemctl enable npm &>/dev/null +systemctl start openresty +systemctl start npm +echo -e "${CM}${CL} \r" +T="$(($(date +%s)-T))" + +IP=$(hostname -I | cut -f1 -d ' ') +echo -e "${GN}Successfully Updated Nginx Proxy Manager, and it only took ${RD}${T} seconds,${CL} + ${BL}Then Go To https://${IP}:81 ${CL} + + " From 3f73724fe40a9b535ba6ce733b4768282541a43d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 13:27:04 -0500 Subject: [PATCH 1192/6505] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cfff3c60..9cb006d6 100644 --- a/README.md +++ b/README.md @@ -258,7 +258,7 @@ ________________________________________________________________________________
-Nginx Proxy Manager LXC + 🔸Nginx Proxy Manager LXC

hero

@@ -296,6 +296,13 @@ Add the following to your `configuration.yaml` in Home Assistant. ```yaml changeme ``` +⚙️ **To Update Nginx Proxy Manager** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/npm_update.sh)" +``` + ____________________________________________________________________________________________
From 24e96b62e4e40b4320cab8991a27186c6c979795 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 13:29:46 -0500 Subject: [PATCH 1193/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 70cd586b..02a69c5c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-19 + +### Changed + +- **Nginx Proxy Manager LXC** + - Add Update Script + ## 2022-02-18 ### Changed From 031fda90411d9726918228752c2cb3a7ecdcffb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 16:15:31 -0500 Subject: [PATCH 1194/6505] Update npm_update.sh --- misc/npm_update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/npm_update.sh b/misc/npm_update.sh index 6bfef651..8570f566 100644 --- a/misc/npm_update.sh +++ b/misc/npm_update.sh @@ -155,7 +155,7 @@ echo -e "${CM}${CL} \r" T="$(($(date +%s)-T))" IP=$(hostname -I | cut -f1 -d ' ') -echo -e "${GN}Successfully Updated Nginx Proxy Manager, and it only took ${RD}${T} seconds,${CL} - ${BL}Then Go To https://${IP}:81 ${CL} +echo -e "${GN}Successfully Updated Nginx Proxy Manager, and it took ${RD}${T} seconds.${CL} + ${BL}NPM should be reachable at https://${IP}:81 ${CL} " From be1018ec6179a2fbd97d75fb3b3184b8db6b39dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 22:49:09 -0500 Subject: [PATCH 1195/6505] Update vault_container.sh --- ct/vault_container.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ct/vault_container.sh b/ct/vault_container.sh index f4989e21..a375185d 100644 --- a/ct/vault_container.sh +++ b/ct/vault_container.sh @@ -8,7 +8,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done - +clear set -o errexit set -o errtrace set -o nounset @@ -16,6 +16,11 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` trap die ERR trap cleanup EXIT @@ -73,10 +78,10 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vault_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/vault_setup.sh load_module overlay - +echo -e "${RD} Patience is required while Building Vaultwarden ${CL} \n" while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') From ddc580acbeee103a395352e6fbab1109be7cc87e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 22:50:15 -0500 Subject: [PATCH 1196/6505] Update vault_setup.sh --- setup/vault_setup.sh | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index 3b2ffc48..4826d660 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -8,6 +8,11 @@ shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` RETRY_NUM=5 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -64,9 +69,9 @@ echo -e "${CHECKMARK} \e[1;92m Installing Build Essentials... \e[0m" apt-get install -y build-essential &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" -curl https://sh.rustup.rs -sSf | sh -echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc -export PATH=~/.cargo/bin:$PATH +curl https://sh.rustup.rs -sSf | sh -s -- -y &>/dev/null +echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null +export PATH=~/.cargo/bin:$PATH &>/dev/null which rustc &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" @@ -76,20 +81,25 @@ npm -g install npm@7 &>/dev/null which npm &>/dev/null npm i npm@latest -g &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Building Vaultwarden... \e[0m" -git clone https://github.com/dani-garcia/vaultwarden && pushd vaultwarden -cargo clean && cargo build --features sqlite --release -file target/release/vaultwarden +echo -e "${CHECKMARK} \e[1;92m Building Vaultwarden (Patience)... \e[0m" +git clone https://github.com/dani-garcia/vaultwarden &>/dev/null +pushd vaultwarden &>/dev/null +cargo clean &>/dev/null +cargo build --features sqlite --release &>/dev/null +file target/release/vaultwarden &>/dev/null echo -e "${CHECKMARK} \e[1;92m Building Web-Vault... \e[0m" -pushd target/release/ -git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git && cd web-vault.git -git checkout v2.25.1 -git submodule update --init --recursive -wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch -git apply v2.25.0.patch -npm ci --legacy-peer-deps && npm audit fix --legacy-peer-deps || true && npm run dist:oss:selfhost -cp -a build ../web-vault +pushd target/release/ &>/dev/null +git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null +cd web-vault.git &>/dev/null +git checkout v2.25.1 &>/dev/null +git submodule update --init --recursive &>/dev/null +wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null +git apply v2.25.0.patch &>/dev/null +npm ci --silent --legacy-peer-deps &>/dev/null +npm audit fix --silent --legacy-peer-deps || true &>/dev/null +npm run --silent dist:oss:selfhost &>/dev/null +cp -a build ../web-vault &>/dev/null cd .. mkdir data @@ -144,4 +154,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') systemctl enable vaultwarden.service &>/dev/null systemctl start vaultwarden.service &>/dev/null echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* \ No newline at end of file +rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 3ef44e9656995897b1f0ab3f228cc55a1fc9abac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 22:57:12 -0500 Subject: [PATCH 1197/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9cb006d6..a1dc584d 100644 --- a/README.md +++ b/README.md @@ -905,10 +905,10 @@ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vault_container.sh)" ``` -It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. I've left most of the installation process viewable since the Rust install needs user input (requires a "enter" key press), and the lengthy time to complete the full installation. +It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. + + Expect 30+ minute install time.

⚡ Normal Settings: 512Mib RAM - 8GB Storage - 1vCPU ⚡

- -Be Patient, let the script do it's work. Hopefully, you'll eventually see "Successfully created a Vaultwarden LXC Container" [Clients](https://bitwarden.com/download/) From 77f13498112786b4ebf9ef8e0737390e6b226cbd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 22:57:43 -0500 Subject: [PATCH 1198/6505] Update vault_container.sh --- ct/vault_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vault_container.sh b/ct/vault_container.sh index a375185d..3c3653d2 100644 --- a/ct/vault_container.sh +++ b/ct/vault_container.sh @@ -78,7 +78,7 @@ function load_module() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/vault_setup.sh +wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vault_setup.sh load_module overlay echo -e "${RD} Patience is required while Building Vaultwarden ${CL} \n" From 8dc820bfc8c8ec1b76e53730ae8d0df181dd9f79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 23:07:13 -0500 Subject: [PATCH 1199/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 02a69c5c..e5183e6c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Nginx Proxy Manager LXC** - Add Update Script +- **Vaultwarden LXC** + - Make unattended install & Cleanup Script ## 2022-02-18 From 5547ffedce0c8c81c70cf3e6af62e65eac60abb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Feb 2022 23:07:56 -0500 Subject: [PATCH 1200/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a1dc584d..20958102 100644 --- a/README.md +++ b/README.md @@ -894,7 +894,7 @@ ________________________________________________________________________________
- Vaultwarden LXC + 🔸Vaultwarden LXC

From b29c001495a7aa5550e27514ed1260b239ae79d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 00:20:57 -0500 Subject: [PATCH 1201/6505] Update vault_container.sh --- ct/vault_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vault_container.sh b/ct/vault_container.sh index 3c3653d2..6ab85226 100644 --- a/ct/vault_container.sh +++ b/ct/vault_container.sh @@ -81,7 +81,7 @@ pushd $TEMP_DIR >/dev/null wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vault_setup.sh load_module overlay -echo -e "${RD} Patience is required while Building Vaultwarden ${CL} \n" +echo -e "${RD} Expect 30+ minute install time. ${CL} \n" while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') From 303c4d6f6b26ae4ae034b16c0b2e2befa1117a9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 08:20:57 -0500 Subject: [PATCH 1202/6505] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 20958102..49b8e9a0 100644 --- a/README.md +++ b/README.md @@ -905,10 +905,12 @@ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vault_container.sh)" ``` +Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. + It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. - Expect 30+ minute install time. -

⚡ Normal Settings: 512Mib RAM - 8GB Storage - 1vCPU ⚡

+Expect 30+ minute install time. +

⚡ Normal Settings: 512Mib RAM - 8GB Storage - 1vCPU ⚡

[Clients](https://bitwarden.com/download/) From 34b0dd06df140cb25cebd686476ba72fb7c2b91b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 08:33:44 -0500 Subject: [PATCH 1203/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49b8e9a0..a977017d 100644 --- a/README.md +++ b/README.md @@ -400,7 +400,7 @@ ________________________________________________________________________________
- 🔸Mariadb LXC + Mariadb LXC

MariaDB

From 046718428eb7e3aac26f7085dd4b56936125e3df Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 13:17:27 -0500 Subject: [PATCH 1204/6505] Create ha-update-update.sh --- misc/ha-update-update.sh | 194 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 misc/ha-update-update.sh diff --git a/misc/ha-update-update.sh b/misc/ha-update-update.sh new file mode 100644 index 00000000..1f40a052 --- /dev/null +++ b/misc/ha-update-update.sh @@ -0,0 +1,194 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Update Menu for Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +set -o errexit +rm -rf /root/update.sh update +echo -e "\e[1;92m Creating New Update Menu Script... \e[0m" +if [ -f /usr/local/lib/python3.9/dist-packages/runlike/runlike.py ]; then +echo -e "\e[1;92m pip3/runlike Already Installed! \e[0m" +else +apt-get update &>/dev/null +echo -e "\e[1;92m Installing pip3... \e[0m" +apt-get install -y python3-pip &>/dev/null +echo -e "\e[1;92m Installing runlike... \e[0m" +pip3 install runlike &>/dev/null +fi +echo -e "\e[1;92m Creating Update Script... \e[0m" +UPDATE_PATH='/root/update' +UPDATE_CONTAINERS_PATH='/root/update-containers.sh' +cat >$UPDATE_PATH <<'EOF' +#!/bin/sh +set -o errexit +show_menu(){ + normal=`echo "\033[m"` + safe=`echo "\033[32m"` + menu=`echo "\033[36m"` + number=`echo "\033[33m"` + bgred=`echo "\033[41m"` + fgred=`echo "\033[31m"` + hostname -I + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" + printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" + printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" + printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" + printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" + printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" + printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" + printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" + printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" + printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" + read opt +} +option_picked(){ + msgcolor=`echo "\033[01;31m"` + normal=`echo "\033[00;00m"` + message=${@:-"${normal}Error: No message passed"} + printf "${msgcolor}${message}${normal}\n" +} +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + option_picked "Switching to Stable Branch"; + TAG=stable + break; + ;; + 2) clear; + option_picked "Switching to Beta Branch"; + TAG=beta + break; + ;; + 3) while true; do + read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Switching to Dev Branch"; + TAG=dev + break; + ;; + 4) clear; + option_picked "Backing up Home Assistant Data to root (hass_config)"; + rm -r hass_config; + cp -pR /var/lib/docker/volumes/hass_config/ /root/; + exit; + ;; + 5) while true; do + read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Restoring Home Assistant Data from root (hass_config)"; + rm -r /var/lib/docker/volumes/hass_config/_data; + cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; + exit; + ;; + 6) while true; do + read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Editing Home Assistant Configuration"; + nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; + exit; + ;; + 7) clear; + option_picked "Restarting Home Assistant"; + docker restart homeassistant; + exit; + ;; + 8) clear; + option_picked "Just Updating Containers"; + ./update-containers.sh; + exit; + ;; + 9) clear; + option_picked "Removing Unused Images"; + docker image prune -af; + exit; + ;; + 10) clear; + option_picked "Updating Host OS"; + apt update && apt upgrade -y; + exit; + ;; + 11) clear; + option_picked "Reboot Host OS"; + reboot; + exit; + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose an option from the menu"; + show_menu; + ;; + esac + fi + done +docker pull homeassistant/home-assistant:$TAG +docker rm --force homeassistant +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:$TAG +EOF +sudo chmod +x /root/update +cat >$UPDATE_CONTAINERS_PATH <<'EOF' +#!/bin/bash +set -o errexit +CONTAINER_LIST="${1:-$(docker ps -q)}" +for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike "${container}")" + docker rm --force "${container}" + eval ${DOCKER_COMMAND} + fi +done +EOF +sudo chmod +x /root/update-containers.sh +echo -e "\e[1;92m Finished. Type ./update in the LXC console\e[0m" +exit From 3e123a25e8bf06eb930526b1416fa745217264d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 13:33:38 -0500 Subject: [PATCH 1205/6505] Update and rename ha-update-update.sh to latest-update-menu.sh --- misc/{ha-update-update.sh => latest-update-menu.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename misc/{ha-update-update.sh => latest-update-menu.sh} (99%) diff --git a/misc/ha-update-update.sh b/misc/latest-update-menu.sh similarity index 99% rename from misc/ha-update-update.sh rename to misc/latest-update-menu.sh index 1f40a052..d6656c2b 100644 --- a/misc/ha-update-update.sh +++ b/misc/latest-update-menu.sh @@ -10,7 +10,7 @@ while true; do done clear set -o errexit -rm -rf /root/update.sh update +rm -rf /root/update.sh update update-containers.sh echo -e "\e[1;92m Creating New Update Menu Script... \e[0m" if [ -f /usr/local/lib/python3.9/dist-packages/runlike/runlike.py ]; then echo -e "\e[1;92m pip3/runlike Already Installed! \e[0m" From 12fcb846a16bfa8ffbd628d0973409505221c113 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 13:38:51 -0500 Subject: [PATCH 1206/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e5183e6c..0500a00d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-20 + +### Changed + +- **Home Assistant Container LXC** + - Add Script to migrate to the latest Update Menu + ## 2022-02-19 ### Changed From 45ad960a5355af8be135dbb3f7ac5fb41194fff7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 13:41:30 -0500 Subject: [PATCH 1207/6505] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a977017d..35235787 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,12 @@ Run in the LXC console ```yaml ./update ``` +⚙️ Migrate to the latest [**Update Menu**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/latest-update-menu.sh)" +``` ____________________________________________________________________________________________
From f5f41745954b9a61e4b94c63bfa71d8e6c04e248 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Feb 2022 13:44:50 -0500 Subject: [PATCH 1208/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35235787..2fed06d4 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ Run in the LXC console ```yaml ./update ``` -⚙️ Migrate to the latest [**Update Menu**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) +⚙️ **Migrate to the latest Update Menu** Run in the LXC console ```yaml From 02b4453d2d03d0400bec43517e88befe76ca439a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 11:25:19 -0500 Subject: [PATCH 1209/6505] Update post_install.sh --- misc/post_install.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/misc/post_install.sh b/misc/post_install.sh index c890bc8e..bb53f446 100644 --- a/misc/post_install.sh +++ b/misc/post_install.sh @@ -1,8 +1,6 @@ #!/usr/bin/env bash -echo -e "\e[1;33m This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, -Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) -and attempt the No-Nag fix. PVE7 ONLY \e[0m" +echo -e "\e[1;33m This script will Setup Repositories and attempt the No-Nag fix. PVE7 ONLY \e[0m" while true; do read -p "Start the PVE7 Post Install Script (y/n)?" yn case $yn in @@ -11,7 +9,12 @@ while true; do * ) echo "Please answer yes or no.";; esac done +clear +echo -e "\e[1;33m Disable Enterprise Repository... \e[0m" +sleep 1 sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list +echo -e "\e[1;33m Setup Repositories... \e[0m" +sleep 1 cat < /etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib deb http://ftp.debian.org/debian bullseye-updates main contrib @@ -19,6 +22,8 @@ deb http://security.debian.org/debian-security bullseye-security main contrib deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF +echo -e "\e[1;33m Disable Subscription Nag... \e[0m" +sleep 1 echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" From 317ce24cbda39a0a619b4b2c073a75f330e03ed4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 11:26:58 -0500 Subject: [PATCH 1210/6505] Update post_install.sh --- misc/post_install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/post_install.sh b/misc/post_install.sh index bb53f446..f6dc0947 100644 --- a/misc/post_install.sh +++ b/misc/post_install.sh @@ -23,7 +23,6 @@ deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF echo -e "\e[1;33m Disable Subscription Nag... \e[0m" -sleep 1 echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" From c0c642dc0d262cddc572605fd18057cdb8ce84f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 11:52:07 -0500 Subject: [PATCH 1211/6505] Update haos_vm.sh --- vm/haos_vm.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a95b2f49..cd9abd13 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -176,5 +176,8 @@ echo -e "${CM} ${CL} \r" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) +echo -en "${GN} Starting Home Assistant OS VM... " +qm start $VMID +echo -e "${CM} ${CL} \n" info "${GN} Completed Successfully!${CL} HAOS VM ID is ${BL}${VMID}${CL}" From 74778cab8041f92e877bcc5b7a36db893b1e917a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 11:59:26 -0500 Subject: [PATCH 1212/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index cd9abd13..1b4a6071 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -180,4 +180,4 @@ echo -en "${GN} Starting Home Assistant OS VM... " qm start $VMID echo -e "${CM} ${CL} \n" -info "${GN} Completed Successfully!${CL} HAOS VM ID is ${BL}${VMID}${CL}" +info "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL}" From cf96013c9d3ebcf96cd86b326088af8fcc2e3578 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 12:05:28 -0500 Subject: [PATCH 1213/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2fed06d4..886aabf5 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/vm/h ```

⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

-After the script completes, If you're dissatisfied with the default settings, click on the VM, then on the **_Hardware_** tab and change the settings to what you desire. Once all changes have been made, **_Start_** the VM. +After the script completes, click on the VM, then on the **_Summary_** tab to find the VM IP. **Home Assistant Interface - IP:8123** From 609bff936b2b184b1bf04e458fbe1ce228b09aa7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 22:29:39 -0500 Subject: [PATCH 1214/6505] Update haos_vm.sh --- vm/haos_vm.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 1b4a6071..bdb57f2b 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -9,16 +9,28 @@ while true; do esac done clear +CL=`echo "\033[m"` +BL=`echo "\033[36m"` +function header_info { +echo -e "${BL} + _ _ ____ _____ + | | | | /\ / __ \ / ____| + | |__| | / \ | | | | (___ + | __ | / /\ \| | | |\___ \ + | | | |/ ____ \ |__| |____) | + |_| |_/_/ \_\____/|_____/ + +${CL}" +} +header_info set -o errexit set -o errtrace set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` trap die ERR trap cleanup EXIT function error_exit() { From e97d145de56cb0aac78396daeb3472d8b44da86a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 22:55:37 -0500 Subject: [PATCH 1215/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index bdb57f2b..059f957a 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -192,4 +192,4 @@ echo -en "${GN} Starting Home Assistant OS VM... " qm start $VMID echo -e "${CM} ${CL} \n" -info "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL}" +echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" From 93b998a06c7027b1289ee53b85759f8fe9ff6ebd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Feb 2022 22:59:57 -0500 Subject: [PATCH 1216/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 059f957a..f312617a 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -192,4 +192,4 @@ echo -en "${GN} Starting Home Assistant OS VM... " qm start $VMID echo -e "${CM} ${CL} \n" -echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" +echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" From b0540af12d6b9b60035a07a833cde273da82107c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:27:48 -0500 Subject: [PATCH 1217/6505] Create homeassistant-install.sh --- unprev/homeassistant-install.sh | 282 ++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 unprev/homeassistant-install.sh diff --git a/unprev/homeassistant-install.sh b/unprev/homeassistant-install.sh new file mode 100644 index 00000000..9468f7ca --- /dev/null +++ b/unprev/homeassistant-install.sh @@ -0,0 +1,282 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing pip3... " +apt-get install -y python3-pip &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Docker... " +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF +sh <(curl -sSL https://get.docker.com) &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Pulling Portainer Image... " +docker pull portainer/portainer-ce:latest &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Portainer Image... " +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Pulling Home Assistant Image... " +docker pull homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Home Assistant Image... " +docker volume create hass_config >/dev/null +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Update Menu Script... " +pip3 install runlike &>/dev/null +UPDATE_PATH='/root/update' +UPDATE_CONTAINERS_PATH='/root/update-containers.sh' +cat >$UPDATE_PATH <<'EOF' +#!/bin/sh +set -o errexit +show_menu(){ + normal=`echo "\033[m"` + safe=`echo "\033[32m"` + menu=`echo "\033[36m"` + number=`echo "\033[33m"` + bgred=`echo "\033[41m"` + fgred=`echo "\033[31m"` + hostname -I + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" + printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" + printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" + printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" + printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" + printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" + printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" + printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" + printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" + printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" + read opt +} +option_picked(){ + msgcolor=`echo "\033[01;31m"` + normal=`echo "\033[00;00m"` + message=${@:-"${normal}Error: No message passed"} + printf "${msgcolor}${message}${normal}\n" +} +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + option_picked "Switching to Stable Branch"; + TAG=stable + break; + ;; + 2) clear; + option_picked "Switching to Beta Branch"; + TAG=beta + break; + ;; + 3) while true; do + read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Switching to Dev Branch"; + TAG=dev + break; + ;; + 4) clear; + option_picked "Backing up Home Assistant Data to root (hass_config)"; + rm -r hass_config; + cp -pR /var/lib/docker/volumes/hass_config/ /root/; + exit; + ;; + 5) while true; do + read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Restoring Home Assistant Data from root (hass_config)"; + rm -r /var/lib/docker/volumes/hass_config/_data; + cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; + exit; + ;; + 6) while true; do + read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Editing Home Assistant Configuration"; + nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; + exit; + ;; + 7) clear; + option_picked "Restarting Home Assistant"; + docker restart homeassistant; + exit; + ;; + 8) clear; + option_picked "Just Updating Containers"; + ./update-containers.sh; + exit; + ;; + 9) clear; + option_picked "Removing Unused Images"; + docker image prune -af; + exit; + ;; + 10) clear; + option_picked "Updating Host OS"; + apt update && apt upgrade -y; + exit; + ;; + 11) clear; + option_picked "Reboot Host OS"; + reboot; + exit; + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose an option from the menu"; + show_menu; + ;; + esac + fi + done +docker pull homeassistant/home-assistant:$TAG +docker rm --force homeassistant +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:$TAG +EOF +sudo chmod +x /root/update +cat >$UPDATE_CONTAINERS_PATH <<'EOF' +#!/bin/bash +set -o errexit +CONTAINER_LIST="${1:-$(docker ps -q)}" +for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike "${container}")" + docker rm --force "${container}" + eval ${DOCKER_COMMAND} + fi +done +EOF +sudo chmod +x /root/update-containers.sh +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" + From 4d378e50b40db38ffe2ed875d940162bee177ae8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:29:51 -0500 Subject: [PATCH 1218/6505] Create unprivileged-homeassistant.sh --- unprev/unprivileged-homeassistant.sh | 122 +++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 unprev/unprivileged-homeassistant.sh diff --git a/unprev/unprivileged-homeassistant.sh b/unprev/unprivileged-homeassistant.sh new file mode 100644 index 00000000..a83e042a --- /dev/null +++ b/unprev/unprivileged-homeassistant.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + _ _ _ _ _ + | | | | /\ (_) | | | | + | |__| | ___ _ __ ___ ___ / \ ___ ___ _ ___| |_ __ _ _ __ | |_ + | __ |/ _ \| _ _ \ / _ \ / /\ \ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ / ____ \\__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___| /_/ \_\___/___/_|___/\__\__,_|_| |_|\__| + + + + +${CL}" +} + +header_info + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname homeassistant + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/homeassistant-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Home Assistant Container LXC to${CL} ${BL}$CTID${CL}. +${BL}Home Assistant${CL} is reachable by going to the following URL. + + ${BL}http://${IP}:8123${CL} \n" From a382f6566e17e71cca66c7b4fca6bba138a2425d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:30:55 -0500 Subject: [PATCH 1219/6505] Create create_lxc.sh --- unprev/create_lxc.sh | 121 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 unprev/create_lxc.sh diff --git a/unprev/create_lxc.sh b/unprev/create_lxc.sh new file mode 100644 index 00000000..509a73d4 --- /dev/null +++ b/unprev/create_lxc.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + if [ $((${#MENU[@]}/3)) -eq 0 ]; then + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then + printf ${MENU[0]} + else + local STORAGE + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." +[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." + +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using ${BL}$TEMPLATE_STORAGE${CL} for Template Storage." + +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using ${BL}$CONTAINER_STORAGE${CL} for Container Storage." + +echo -en "${GN} Updating LXC Template List... " +pveam update >/dev/null +echo -e "${CM}${CL} \r" + +TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + echo -en "${GN} Downloading LXC Template... " + echo -e "${CM}${CL} \r" + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture)) + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +echo -en "${GN} Creating LXC Container... " +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." +echo -e "${CM}${CL} \r" +info "LXC Container ${BL}$CTID${CL} was successfully created." From 4af352beef661563e5c37a7d4725129f53ccdfad Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:31:59 -0500 Subject: [PATCH 1220/6505] Create node-red-install.sh --- unprev/node-red-install.sh | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 unprev/node-red-install.sh diff --git a/unprev/node-red-install.sh b/unprev/node-red-install.sh new file mode 100644 index 00000000..18193e2a --- /dev/null +++ b/unprev/node-red-install.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node-Red... " +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul +sudo systemctl enable nodered.service &>/dev/null +sudo systemctl start nodered.service &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 7c00e881edae1c266cea122a20c9149d6a2f535d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:33:34 -0500 Subject: [PATCH 1221/6505] Create unprivileged-node-red.sh --- unprev/unprivileged-node-red.sh | 116 ++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 unprev/unprivileged-node-red.sh diff --git a/unprev/unprivileged-node-red.sh b/unprev/unprivileged-node-red.sh new file mode 100644 index 00000000..e826c840 --- /dev/null +++ b/unprev/unprivileged-node-red.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Node-Red LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + _ _ _ _____ _ + | \ | | | | | __ \ | | + | \| | ___ __| | ___ ______| |__) |___ __| | + | |/ _ \ / _ |/ _ \______| _ // _ \/ _ | + | |\ | (_) | (_| | __/ | | \ \ __/ (_| | + |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features nesting=1 + -hostname node-red + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 1024 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/node-red-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}." +${RD}Node-Red${CL} is reachable by going to the following URL. + + ${BL}http://${IP}:1880${CL} \n" From 4fcb881d60815cd04c45d60ffc6bf73637960a6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:38:46 -0500 Subject: [PATCH 1222/6505] Create mariadb-install.sh --- unprev/mariadb-install.sh | 73 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 unprev/mariadb-install.sh diff --git a/unprev/mariadb-install.sh b/unprev/mariadb-install.sh new file mode 100644 index 00000000..553053fd --- /dev/null +++ b/unprev/mariadb-install.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing MariaDB... " +curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null +apt-get update >/dev/null +apt-get install -y mariadb-server &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Adminer... " +sudo apt install adminer -y &>/dev/null +sudo a2enconf adminer &>/dev/null +sudo systemctl reload apache2 &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +lxc-cmd apt-get autoremove >/dev/null +lxc-cmd apt-get autoclean >/dev/null +lxc-cmd rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" + From 19621adaa8956dd0f3ca92e3abb3c81c2897379b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:40:50 -0500 Subject: [PATCH 1223/6505] Create unprivileged-mariadb.sh --- unprev/unprivileged-mariadb.sh | 116 +++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 unprev/unprivileged-mariadb.sh diff --git a/unprev/unprivileged-mariadb.sh b/unprev/unprivileged-mariadb.sh new file mode 100644 index 00000000..01def92a --- /dev/null +++ b/unprev/unprivileged-mariadb.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Mariadb LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + __ __ _ _ _ + | \/ | (_) | | | + | \ / | __ _ _ __ _ __ _ __| | |__ + | |\/| |/ _ | __| |/ _ |/ _ | _ \ + | | | | (_| | | | | (_| | (_| | |_) | + |_| |_|\__,_|_| |_|\__,_|\__,_|_.__/ + + + + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features nesting=1 + -hostname mariadb + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 1024 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/mariadb-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. \n" From 7296a7bcb2f610d421ddd40aaf5a8852d59b3036 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:45:24 -0500 Subject: [PATCH 1224/6505] Update unprivileged-node-red.sh --- unprev/unprivileged-node-red.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unprev/unprivileged-node-red.sh b/unprev/unprivileged-node-red.sh index e826c840..9b8e19f8 100644 --- a/unprev/unprivileged-node-red.sh +++ b/unprev/unprivileged-node-red.sh @@ -93,7 +93,7 @@ export PCT_OPTIONS=" -memory 1024 -unprivileged 1 " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -106,7 +106,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/node-red-install.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/node-red-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 581a304129c1b4db23bf61130a210c967af5c26d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:46:00 -0500 Subject: [PATCH 1225/6505] Update unprivileged-homeassistant.sh --- unprev/unprivileged-homeassistant.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unprev/unprivileged-homeassistant.sh b/unprev/unprivileged-homeassistant.sh index a83e042a..3faa55a7 100644 --- a/unprev/unprivileged-homeassistant.sh +++ b/unprev/unprivileged-homeassistant.sh @@ -94,7 +94,7 @@ export PCT_OPTIONS=" -memory 2048 -unprivileged 1 " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -112,7 +112,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/homeassistant-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/homeassistant-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From b15989b1acd5fc439ff5c6a7da74043aa9702945 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 10:46:34 -0500 Subject: [PATCH 1226/6505] Update unprivileged-mariadb.sh --- unprev/unprivileged-mariadb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unprev/unprivileged-mariadb.sh b/unprev/unprivileged-mariadb.sh index 01def92a..032c50b5 100644 --- a/unprev/unprivileged-mariadb.sh +++ b/unprev/unprivileged-mariadb.sh @@ -96,7 +96,7 @@ export PCT_OPTIONS=" -memory 1024 -unprivileged 1 " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -109,7 +109,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/unprev/mariadb-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/mariadb-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 25ff5224e7f16d6a6cfec051c596b4ceb4b4a5fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 12:56:28 -0500 Subject: [PATCH 1227/6505] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 886aabf5..dac2276c 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,11 @@ To create a new Proxmox Home Assistant Container, run the following in the Proxm ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ha_container.sh)" ``` +To create a new Proxmox Unprivileged Home Assistant Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/unprivileged-homeassistant.sh)" +```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

From 62de8a7a4912ce2ceb8b3561319100a5e1e1814e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:17:25 -0500 Subject: [PATCH 1228/6505] Update README.md --- README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dac2276c..6a5be2b6 100644 --- a/README.md +++ b/README.md @@ -163,12 +163,12 @@ ________________________________________________________________________________

Home Assistant Container LXC

With ZFS Filesystem Support

To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell. - + ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ha_container.sh)" ``` To create a new Proxmox Unprivileged Home Assistant Container, run the following in the Proxmox Shell. - + ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/unprivileged-homeassistant.sh)" ``` @@ -381,6 +381,12 @@ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red_container.sh)" ``` +To create a new Proxmox Unprivileged Node-RED LXC Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/unprivileged-node-red.sh)" +``` +

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

**Node-Red Interface - IP:1880** @@ -411,17 +417,23 @@ ________________________________________________________________________________
- Mariadb LXC + 🔸Mariadb LXC

MariaDB

Mariadb LXC Container

To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox Shell. - + ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb_container.sh)" ``` +To create a new Proxmox Unprivileged Mariadb LXC Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/unprivileged-mariadb.sh)" +``` +

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: From 65130e7e07b9a2057c0f3745703030eece08173e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:17:41 -0500 Subject: [PATCH 1229/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0500a00d..708e9fb9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,17 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-22 + +### Changed + +- **Home Assistant Container LXC** + - Add NEW Unprivileged Install Script +- **Node-Red LXC** + - Add NEW Unprivileged Install Script +- **Mariadb LXC** + - Add NEW Unprivileged Install Script + ## 2022-02-20 ### Changed From 295031553e7b771c38df571b6d8489e83077710c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:43:17 -0500 Subject: [PATCH 1230/6505] Create unprivileged-homeassistant.sh --- unpriv/unprivileged-homeassistant.sh | 122 +++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 unpriv/unprivileged-homeassistant.sh diff --git a/unpriv/unprivileged-homeassistant.sh b/unpriv/unprivileged-homeassistant.sh new file mode 100644 index 00000000..3faa55a7 --- /dev/null +++ b/unpriv/unprivileged-homeassistant.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + _ _ _ _ _ + | | | | /\ (_) | | | | + | |__| | ___ _ __ ___ ___ / \ ___ ___ _ ___| |_ __ _ _ __ | |_ + | __ |/ _ \| _ _ \ / _ \ / /\ \ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ / ____ \\__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___| /_/ \_\___/___/_|___/\__\__,_|_| |_|\__| + + + + +${CL}" +} + +header_info + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname homeassistant + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/homeassistant-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Home Assistant Container LXC to${CL} ${BL}$CTID${CL}. +${BL}Home Assistant${CL} is reachable by going to the following URL. + + ${BL}http://${IP}:8123${CL} \n" From e6863452dbfc6d875bd48398b54024cf8c49f385 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:44:17 -0500 Subject: [PATCH 1231/6505] Create unprivileged-mariadb.sh --- unpriv/unprivileged-mariadb.sh | 116 +++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 unpriv/unprivileged-mariadb.sh diff --git a/unpriv/unprivileged-mariadb.sh b/unpriv/unprivileged-mariadb.sh new file mode 100644 index 00000000..032c50b5 --- /dev/null +++ b/unpriv/unprivileged-mariadb.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Mariadb LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + __ __ _ _ _ + | \/ | (_) | | | + | \ / | __ _ _ __ _ __ _ __| | |__ + | |\/| |/ _ | __| |/ _ |/ _ | _ \ + | | | | (_| | | | | (_| | (_| | |_) | + |_| |_|\__,_|_| |_|\__,_|\__,_|_.__/ + + + + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features nesting=1 + -hostname mariadb + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 1024 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/mariadb-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. \n" From 241ab4dc745028314baf351bd3f582e50a523742 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:45:03 -0500 Subject: [PATCH 1232/6505] Create unprivileged-node-red.sh --- unpriv/unprivileged-node-red.sh | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 unpriv/unprivileged-node-red.sh diff --git a/unpriv/unprivileged-node-red.sh b/unpriv/unprivileged-node-red.sh new file mode 100644 index 00000000..18193e2a --- /dev/null +++ b/unpriv/unprivileged-node-red.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node-Red... " +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul +sudo systemctl enable nodered.service &>/dev/null +sudo systemctl start nodered.service &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 668f44741c0d7145290070633395834d78a7f30b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:45:35 -0500 Subject: [PATCH 1233/6505] Create create_lxc.sh --- unpriv/create_lxc.sh | 121 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 unpriv/create_lxc.sh diff --git a/unpriv/create_lxc.sh b/unpriv/create_lxc.sh new file mode 100644 index 00000000..509a73d4 --- /dev/null +++ b/unpriv/create_lxc.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + if [ $((${#MENU[@]}/3)) -eq 0 ]; then + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then + printf ${MENU[0]} + else + local STORAGE + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." +[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." + +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using ${BL}$TEMPLATE_STORAGE${CL} for Template Storage." + +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using ${BL}$CONTAINER_STORAGE${CL} for Container Storage." + +echo -en "${GN} Updating LXC Template List... " +pveam update >/dev/null +echo -e "${CM}${CL} \r" + +TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + echo -en "${GN} Downloading LXC Template... " + echo -e "${CM}${CL} \r" + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture)) + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +echo -en "${GN} Creating LXC Container... " +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." +echo -e "${CM}${CL} \r" +info "LXC Container ${BL}$CTID${CL} was successfully created." From 343dea03b1f69d8e46ccb3c3340582ec3e734371 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:46:10 -0500 Subject: [PATCH 1234/6505] Create homeassistant-install.sh --- unpriv/homeassistant-install.sh | 281 ++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 unpriv/homeassistant-install.sh diff --git a/unpriv/homeassistant-install.sh b/unpriv/homeassistant-install.sh new file mode 100644 index 00000000..76713df6 --- /dev/null +++ b/unpriv/homeassistant-install.sh @@ -0,0 +1,281 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing pip3... " +apt-get install -y python3-pip &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Docker... " +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF +sh <(curl -sSL https://get.docker.com) &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Pulling Portainer Image... " +docker pull portainer/portainer-ce:latest &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Portainer Image... " +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Pulling Home Assistant Image... " +docker pull homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Home Assistant Image... " +docker volume create hass_config >/dev/null +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Update Menu Script... " +pip3 install runlike &>/dev/null +UPDATE_PATH='/root/update' +UPDATE_CONTAINERS_PATH='/root/update-containers.sh' +cat >$UPDATE_PATH <<'EOF' +#!/bin/sh +set -o errexit +show_menu(){ + normal=`echo "\033[m"` + safe=`echo "\033[32m"` + menu=`echo "\033[36m"` + number=`echo "\033[33m"` + bgred=`echo "\033[41m"` + fgred=`echo "\033[31m"` + hostname -I + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" + printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" + printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" + printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" + printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" + printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" + printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" + printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" + printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" + printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" + read opt +} +option_picked(){ + msgcolor=`echo "\033[01;31m"` + normal=`echo "\033[00;00m"` + message=${@:-"${normal}Error: No message passed"} + printf "${msgcolor}${message}${normal}\n" +} +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + option_picked "Switching to Stable Branch"; + TAG=stable + break; + ;; + 2) clear; + option_picked "Switching to Beta Branch"; + TAG=beta + break; + ;; + 3) while true; do + read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Switching to Dev Branch"; + TAG=dev + break; + ;; + 4) clear; + option_picked "Backing up Home Assistant Data to root (hass_config)"; + rm -r hass_config; + cp -pR /var/lib/docker/volumes/hass_config/ /root/; + exit; + ;; + 5) while true; do + read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Restoring Home Assistant Data from root (hass_config)"; + rm -r /var/lib/docker/volumes/hass_config/_data; + cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; + exit; + ;; + 6) while true; do + read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Editing Home Assistant Configuration"; + nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; + exit; + ;; + 7) clear; + option_picked "Restarting Home Assistant"; + docker restart homeassistant; + exit; + ;; + 8) clear; + option_picked "Just Updating Containers"; + ./update-containers.sh; + exit; + ;; + 9) clear; + option_picked "Removing Unused Images"; + docker image prune -af; + exit; + ;; + 10) clear; + option_picked "Updating Host OS"; + apt update && apt upgrade -y; + exit; + ;; + 11) clear; + option_picked "Reboot Host OS"; + reboot; + exit; + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose an option from the menu"; + show_menu; + ;; + esac + fi + done +docker pull homeassistant/home-assistant:$TAG +docker rm --force homeassistant +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:$TAG +EOF +sudo chmod +x /root/update +cat >$UPDATE_CONTAINERS_PATH <<'EOF' +#!/bin/bash +set -o errexit +CONTAINER_LIST="${1:-$(docker ps -q)}" +for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike "${container}")" + docker rm --force "${container}" + eval ${DOCKER_COMMAND} + fi +done +EOF +sudo chmod +x /root/update-containers.sh +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 63f79998f272b5d96cd213a848eac00a38702554 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:46:49 -0500 Subject: [PATCH 1235/6505] Create node-red-install.sh --- unpriv/node-red-install.sh | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 unpriv/node-red-install.sh diff --git a/unpriv/node-red-install.sh b/unpriv/node-red-install.sh new file mode 100644 index 00000000..18193e2a --- /dev/null +++ b/unpriv/node-red-install.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node-Red... " +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul +sudo systemctl enable nodered.service &>/dev/null +sudo systemctl start nodered.service &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 02f614d20972e6de96bf0d491982a75a888900c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:47:24 -0500 Subject: [PATCH 1236/6505] Create mariadb-install.sh --- unpriv/mariadb-install.sh | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 unpriv/mariadb-install.sh diff --git a/unpriv/mariadb-install.sh b/unpriv/mariadb-install.sh new file mode 100644 index 00000000..ec2afc16 --- /dev/null +++ b/unpriv/mariadb-install.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing MariaDB... " +curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null +apt-get update >/dev/null +apt-get install -y mariadb-server &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Adminer... " +sudo apt install adminer -y &>/dev/null +sudo a2enconf adminer &>/dev/null +sudo systemctl reload apache2 &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +lxc-cmd apt-get autoremove >/dev/null +lxc-cmd apt-get autoclean >/dev/null +lxc-cmd rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 1312b256f28657f5993fad645c2fe518d983b35a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:49:23 -0500 Subject: [PATCH 1237/6505] Update unprivileged-node-red.sh --- unpriv/unprivileged-node-red.sh | 155 +++++++++++++++++++++----------- 1 file changed, 104 insertions(+), 51 deletions(-) diff --git a/unpriv/unprivileged-node-red.sh b/unpriv/unprivileged-node-red.sh index 18193e2a..9b8e19f8 100644 --- a/unpriv/unprivileged-node-red.sh +++ b/unpriv/unprivileged-node-red.sh @@ -1,63 +1,116 @@ #!/usr/bin/env bash -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` + BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi +while true; do + read -p "This will create a New Unprivileged Node-Red LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +clear +function header_info { +echo -e "${RD} + + _ _ _ _____ _ + | \ | | | | | __ \ | | + | \| | ___ __| | ___ ______| |__) |___ __| | + | |/ _ \ / _ |/ _ \______| _ // _ \/ _ | + | |\ | (_) | (_| | __/ | | \ \ __/ (_| | + |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features nesting=1 + -hostname node-red + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 1024 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID echo -e "${CM}${CL} \r" -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +alias lxc-cmd="lxc-attach -n $CTID --" -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/node-red-install.sh)" || exit -echo -en "${GN} Installing Node-Red... " -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul -sudo systemctl enable nodered.service &>/dev/null -sudo systemctl start nodered.service &>/dev/null -echo -e "${CM}${CL} \r" +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}." +${RD}Node-Red${CL} is reachable by going to the following URL. -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" + ${BL}http://${IP}:1880${CL} \n" From 4df51d520919c5af6bb16484e81edfcfaee60db8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:50:54 -0500 Subject: [PATCH 1238/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6a5be2b6..ad1393bf 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/h To create a new Proxmox Unprivileged Home Assistant Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/unprivileged-homeassistant.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-homeassistant.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -384,7 +384,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/n To create a new Proxmox Unprivileged Node-RED LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/unprivileged-node-red.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-node-red.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -431,7 +431,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/m To create a new Proxmox Unprivileged Mariadb LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/unprivileged-mariadb.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-mariadb.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

From 030885bc904f197ef422d7c1e6b80e7fc53f0de1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:51:44 -0500 Subject: [PATCH 1239/6505] Delete create_lxc.sh --- unprev/create_lxc.sh | 121 ------------------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 unprev/create_lxc.sh diff --git a/unprev/create_lxc.sh b/unprev/create_lxc.sh deleted file mode 100644 index 509a73d4..00000000 --- a/unprev/create_lxc.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=( "$TAG" "$ITEM" "OFF" ) - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - if [ $((${#MENU[@]}/3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." -[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." - -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using ${BL}$TEMPLATE_STORAGE${CL} for Template Storage." - -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using ${BL}$CONTAINER_STORAGE${CL} for Container Storage." - -echo -en "${GN} Updating LXC Template List... " -pveam update >/dev/null -echo -e "${CM}${CL} \r" - -TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - echo -en "${GN} Downloading LXC Template... " - echo -e "${CM}${CL} \r" - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture)) - -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) - -echo -en "${GN} Creating LXC Container... " -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." -echo -e "${CM}${CL} \r" -info "LXC Container ${BL}$CTID${CL} was successfully created." From 9847f812a75e4719cba314e060f5c0473b61c96f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:51:54 -0500 Subject: [PATCH 1240/6505] Delete homeassistant-install.sh --- unprev/homeassistant-install.sh | 282 -------------------------------- 1 file changed, 282 deletions(-) delete mode 100644 unprev/homeassistant-install.sh diff --git a/unprev/homeassistant-install.sh b/unprev/homeassistant-install.sh deleted file mode 100644 index 9468f7ca..00000000 --- a/unprev/homeassistant-install.sh +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing pip3... " -apt-get install -y python3-pip &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Docker... " -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF -sh <(curl -sSL https://get.docker.com) &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Pulling Portainer Image... " -docker pull portainer/portainer-ce:latest &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Portainer Image... " -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Pulling Home Assistant Image... " -docker pull homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Home Assistant Image... " -docker volume create hass_config >/dev/null -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Creating Update Menu Script... " -pip3 install runlike &>/dev/null -UPDATE_PATH='/root/update' -UPDATE_CONTAINERS_PATH='/root/update-containers.sh' -cat >$UPDATE_PATH <<'EOF' -#!/bin/sh -set -o errexit -show_menu(){ - normal=`echo "\033[m"` - safe=`echo "\033[32m"` - menu=`echo "\033[36m"` - number=`echo "\033[33m"` - bgred=`echo "\033[41m"` - fgred=`echo "\033[31m"` - hostname -I - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" - printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" - printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" - printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" - printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" - printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" - printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" - printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" - printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" - printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" - read opt -} -option_picked(){ - msgcolor=`echo "\033[01;31m"` - normal=`echo "\033[00;00m"` - message=${@:-"${normal}Error: No message passed"} - printf "${msgcolor}${message}${normal}\n" -} -clear -show_menu -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - option_picked "Switching to Stable Branch"; - TAG=stable - break; - ;; - 2) clear; - option_picked "Switching to Beta Branch"; - TAG=beta - break; - ;; - 3) while true; do - read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Switching to Dev Branch"; - TAG=dev - break; - ;; - 4) clear; - option_picked "Backing up Home Assistant Data to root (hass_config)"; - rm -r hass_config; - cp -pR /var/lib/docker/volumes/hass_config/ /root/; - exit; - ;; - 5) while true; do - read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Restoring Home Assistant Data from root (hass_config)"; - rm -r /var/lib/docker/volumes/hass_config/_data; - cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - exit; - ;; - 6) while true; do - read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Editing Home Assistant Configuration"; - nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - exit; - ;; - 7) clear; - option_picked "Restarting Home Assistant"; - docker restart homeassistant; - exit; - ;; - 8) clear; - option_picked "Just Updating Containers"; - ./update-containers.sh; - exit; - ;; - 9) clear; - option_picked "Removing Unused Images"; - docker image prune -af; - exit; - ;; - 10) clear; - option_picked "Updating Host OS"; - apt update && apt upgrade -y; - exit; - ;; - 11) clear; - option_picked "Reboot Host OS"; - reboot; - exit; - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose an option from the menu"; - show_menu; - ;; - esac - fi - done -docker pull homeassistant/home-assistant:$TAG -docker rm --force homeassistant -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:$TAG -EOF -sudo chmod +x /root/update -cat >$UPDATE_CONTAINERS_PATH <<'EOF' -#!/bin/bash -set -o errexit -CONTAINER_LIST="${1:-$(docker ps -q)}" -for container in ${CONTAINER_LIST}; do - CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" - RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" - docker pull "${CONTAINER_IMAGE}" - LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" - if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then - echo "Updating ${container} image ${CONTAINER_IMAGE}" - DOCKER_COMMAND="$(runlike "${container}")" - docker rm --force "${container}" - eval ${DOCKER_COMMAND} - fi -done -EOF -sudo chmod +x /root/update-containers.sh -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" - From 6eb8c015244de99ba3a388eaec643a5a00c2d6be Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:52:04 -0500 Subject: [PATCH 1241/6505] Delete mariadb-install.sh --- unprev/mariadb-install.sh | 73 --------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 unprev/mariadb-install.sh diff --git a/unprev/mariadb-install.sh b/unprev/mariadb-install.sh deleted file mode 100644 index 553053fd..00000000 --- a/unprev/mariadb-install.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing MariaDB... " -curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null -apt-get update >/dev/null -apt-get install -y mariadb-server &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Adminer... " -sudo apt install adminer -y &>/dev/null -sudo a2enconf adminer &>/dev/null -sudo systemctl reload apache2 &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -lxc-cmd apt-get autoremove >/dev/null -lxc-cmd apt-get autoclean >/dev/null -lxc-cmd rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" - From 3792cc7c6d9419cee29f62cc4fae06a51d0420ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:52:12 -0500 Subject: [PATCH 1242/6505] Delete node-red-install.sh --- unprev/node-red-install.sh | 63 -------------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 unprev/node-red-install.sh diff --git a/unprev/node-red-install.sh b/unprev/node-red-install.sh deleted file mode 100644 index 18193e2a..00000000 --- a/unprev/node-red-install.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env bash -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Node-Red... " -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul -sudo systemctl enable nodered.service &>/dev/null -sudo systemctl start nodered.service &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 24a2f8f8ab485656c17a2fd78b3ded54249ce021 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:52:20 -0500 Subject: [PATCH 1243/6505] Delete unprivileged-homeassistant.sh --- unprev/unprivileged-homeassistant.sh | 122 --------------------------- 1 file changed, 122 deletions(-) delete mode 100644 unprev/unprivileged-homeassistant.sh diff --git a/unprev/unprivileged-homeassistant.sh b/unprev/unprivileged-homeassistant.sh deleted file mode 100644 index 3faa55a7..00000000 --- a/unprev/unprivileged-homeassistant.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - - _ _ _ _ _ - | | | | /\ (_) | | | | - | |__| | ___ _ __ ___ ___ / \ ___ ___ _ ___| |_ __ _ _ __ | |_ - | __ |/ _ \| _ _ \ / _ \ / /\ \ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ / ____ \\__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___| /_/ \_\___/___/_|___/\__\__,_|_| |_|\__| - - - - -${CL}" -} - -header_info - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 - -hostname homeassistant - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/homeassistant-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Home Assistant Container LXC to${CL} ${BL}$CTID${CL}. -${BL}Home Assistant${CL} is reachable by going to the following URL. - - ${BL}http://${IP}:8123${CL} \n" From 5c0bef2277be89656bbdd746e7be2d8119a4aab9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:52:29 -0500 Subject: [PATCH 1244/6505] Delete unprivileged-mariadb.sh --- unprev/unprivileged-mariadb.sh | 116 --------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 unprev/unprivileged-mariadb.sh diff --git a/unprev/unprivileged-mariadb.sh b/unprev/unprivileged-mariadb.sh deleted file mode 100644 index 032c50b5..00000000 --- a/unprev/unprivileged-mariadb.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Mariadb LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - - __ __ _ _ _ - | \/ | (_) | | | - | \ / | __ _ _ __ _ __ _ __| | |__ - | |\/| |/ _ | __| |/ _ |/ _ | _ \ - | | | | (_| | | | | (_| | (_| | |_) | - |_| |_|\__,_|_| |_|\__,_|\__,_|_.__/ - - - - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features nesting=1 - -hostname mariadb - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/mariadb-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. \n" From 0d4e882b3aa716c50414143e1e4302f070c14024 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 13:52:38 -0500 Subject: [PATCH 1245/6505] Delete unprivileged-node-red.sh --- unprev/unprivileged-node-red.sh | 116 -------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 unprev/unprivileged-node-red.sh diff --git a/unprev/unprivileged-node-red.sh b/unprev/unprivileged-node-red.sh deleted file mode 100644 index 9b8e19f8..00000000 --- a/unprev/unprivileged-node-red.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Node-Red LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - - _ _ _ _____ _ - | \ | | | | | __ \ | | - | \| | ___ __| | ___ ______| |__) |___ __| | - | |/ _ \ / _ |/ _ \______| _ // _ \/ _ | - | |\ | (_) | (_| | __/ | | \ \ __/ (_| | - |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features nesting=1 - -hostname node-red - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/node-red-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}." -${RD}Node-Red${CL} is reachable by going to the following URL. - - ${BL}http://${IP}:1880${CL} \n" From f1b95178cc3925bb81235e242db6c1d828e7e288 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 14:59:27 -0500 Subject: [PATCH 1246/6505] Create mqtt-install.sh --- unpriv/mqtt-install.sh | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 unpriv/mqtt-install.sh diff --git a/unpriv/mqtt-install.sh b/unpriv/mqtt-install.sh new file mode 100644 index 00000000..7f5e9e3e --- /dev/null +++ b/unpriv/mqtt-install.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Mosquitto MQTT Broker... " +wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null +apt-key add mosquitto-repo.gpg.key &>/dev/null +cd /etc/apt/sources.list.d/ +wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list &>/dev/null +apt-get update >/dev/null +apt-get -y install mosquitto &>/dev/null +apt-get -y install mosquitto-clients &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 8f3e278133b88a828545bf8f116745f1bdb9c29c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 15:00:16 -0500 Subject: [PATCH 1247/6505] Create unprivileged-mqtt.sh --- unpriv/unprivileged-mqtt.sh | 114 ++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 unpriv/unprivileged-mqtt.sh diff --git a/unpriv/unprivileged-mqtt.sh b/unpriv/unprivileged-mqtt.sh new file mode 100644 index 00000000..b85c323e --- /dev/null +++ b/unpriv/unprivileged-mqtt.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged MQTT LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + + __ __ ____ _______ _______ + | \/ |/ __ \__ __|__ __| + | \ / | | | | | | | | + | |\/| | | | | | | | | + | | | | |__| | | | | | + |_| |_|\___\_\ |_| |_| + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1 + -hostname mqtt + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/experimental/main/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/experimental/main/mqtt-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created MQTT LXC to${CL} ${BL}$CTID${CL}. \n" From cdc1d1ee86370d2dc89aa044f9e87de25d501036 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 15:01:31 -0500 Subject: [PATCH 1248/6505] Update unprivileged-mqtt.sh --- unpriv/unprivileged-mqtt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpriv/unprivileged-mqtt.sh b/unpriv/unprivileged-mqtt.sh index b85c323e..166cb0d6 100644 --- a/unpriv/unprivileged-mqtt.sh +++ b/unpriv/unprivileged-mqtt.sh @@ -94,7 +94,7 @@ export PCT_OPTIONS=" -memory 512 -unprivileged 1 " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/experimental/main/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -107,7 +107,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/experimental/main/mqtt-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/mqtt-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 6565b3051a4aad81cf2e44575af0ff09a804a7ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 15:06:07 -0500 Subject: [PATCH 1249/6505] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ad1393bf..e8e4b6a5 100644 --- a/README.md +++ b/README.md @@ -319,7 +319,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc
-MQTT LXC + 🔸MQTT LXC

@@ -331,6 +331,12 @@ To create a new Proxmox MQTT LXC Container, run the following in the Proxmox She ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt_container.sh)" ``` +To create a new Proxmox Unprivileged MQTT LXC Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-mqtt.sh)" +``` +

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

Mosquitto comes with a password file generating utility called mosquitto_passwd. From 42f1679d554d33ec2c1134b077b23cfafbbe7297 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 15:06:46 -0500 Subject: [PATCH 1250/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 708e9fb9..6ef95df6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. - Add NEW Unprivileged Install Script - **Mariadb LXC** - Add NEW Unprivileged Install Script +- **MQTT LXC** + - Add NEW Unprivileged Install Script ## 2022-02-20 From 7f7db931461661246949450e7afce66a9b88ab50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:16:04 -0500 Subject: [PATCH 1251/6505] Create debian-install.sh --- unpriv/debian-install.sh | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 unpriv/debian-install.sh diff --git a/unpriv/debian-install.sh b/unpriv/debian-install.sh new file mode 100644 index 00000000..fe9ef62a --- /dev/null +++ b/unpriv/debian-install.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 9edb58ae364e6509650f834708c5fbda3d1ea6f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:17:05 -0500 Subject: [PATCH 1252/6505] Create unprivileged-debian.sh --- unpriv/unprivileged-debian.sh | 116 ++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 unpriv/unprivileged-debian.sh diff --git a/unpriv/unprivileged-debian.sh b/unpriv/unprivileged-debian.sh new file mode 100644 index 00000000..73562de0 --- /dev/null +++ b/unpriv/unprivileged-debian.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Debian Bulleyes LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + + + _____ _ _ + | __ \ | | (_) + | | | | ___| |__ _ __ _ _ __ + | | | |/ _ \ _ \| |/ _ | _ \ + | |__| | __/ |_) | | (_| | | | | + |_____/ \___|_.__/|_|\__,_|_| |_| + + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname debian + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/debian-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Debian Bulleyes LXC to${CL} ${BL}$CTID${CL}. \n" From d4cd3a474fa5c7b0ea54ee5e232efa04b4187fe5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:21:12 -0500 Subject: [PATCH 1253/6505] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e8e4b6a5..7602aca7 100644 --- a/README.md +++ b/README.md @@ -640,7 +640,7 @@ ________________________________________________________________________________
- 🔸Home Assistant Container LXC (Podman) + 🔸Home Assistant Container LXC (Podman)

@home-assistant

@@ -155,7 +155,7 @@ ________________________________________________________________________________
-Home Assistant Container LXC + 🔸Home Assistant Container LXC

Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

@@ -214,11 +214,11 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **To Update All Containers:** +⚙️ **Update Menu** Run in the LXC console ```yaml -./update-containers.sh +./update ``` ____________________________________________________________________________________________ From d5d66c1b8dcd3f123edb30bf1af2a32deae2d6cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 17:52:30 -0500 Subject: [PATCH 1106/6505] Add files via upload --- misc/images/update-menu.png | Bin 0 -> 17827 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/update-menu.png diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..7388b16dcdb47b379a345a55249a46e703e80984 GIT binary patch literal 17827 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 z zKC-mQ+#1bIK)@1!Hf?1*vjIIE%EUccfeWg3Q?1qa{Ah@GRQJ)7c-`G?Z^kU4hb}?H zG!FZa!nedH;rw8c3@!q`5%EX=wWB0dtEAhIZdTu1%O9NW^@^Lkw>^o6=~g+fhss2j zTI?5%{FjadU2k@Z-$g-H#P6S7%vw>|FF?505>4SNJ%pL$!k>Q1FiM={CrIWH1{6UG zQc0f|3CBcI#fN&t;-r&cz_bCyVnm&Ljt3`*UWAdvW zKiqSOPQ438U!sX158+?-$G=?k%B{mWYJyAkYXlgPg4iX{>Il{`6|%;WcDGkroFm!n zxzFWwpl`<=uolN(E}hgFlPagjfZ#VSP5e6KXf=kj_h+dFd+_C6?dY3*L+_QaDTGw) z`LzV`r8j%muz9#Ka|hmeF9hE1_cXrHG4%O7sp5Kj)P>DHN_{)B@CmM{(>(A^N*uS2 zJVbkb^Ysp2kB=_yE1C~#TJnnEx$v}#!QleMEd>$+U80oyAP(Hk31fS zrEM}D>Z=uRf0b1pZ5Je@^sn&LF_Hxozp}VWJk1n;CLr#8{AmSEj^oMO`}5TEt^%La z&8e(UGi&)bvsSsJ!?|Yhg1t91&Rf}DtEonT)dyvax&C;E?T>BGjau`6IxQ#)WG)cT zLR6G)Eq*wYu06NrSr61A07f50)qqTLl6~OId8gfDmtAgeQ}m+^f_x5 z@!OtL6KNGh;&}4|lZpB}q||f8EP?S8P$8P=G0?voSJwFP{*seJ3iw_6Aq1VH>VeN{ zgxpSTced8bg*2M|!mj=Pf|ny{uq`QWx-Q3_P5nGuk_JB^3YDtfW5K1*q_Xvb<-+^} zO_%d<#&gz9`3~t9^%Kg%*S_{dY`Q`3>10!I^@}c^l3gm^DvuE8m+4g22fkFy5fR+^ zR@jib8Y?dLaJ81e18+dXJ^7_3X7tS%S@pyYYD`L_KUU2Th>^aR|8hc%9Y4H?N(-U!jl1awkP)*q` z=)|LQe}I13m=jlTt-{*ZH93unx&$yziTd<;U@UWz3|h_X3Nb{2HYcxsZ}kOO@1xL8 z9MOuJ5=5x@{%XXLkOgdc&snx30U)z^MrVoi`1Mdym?r!QsgU4qc`fv%s-ga? z>)p7R#aL2awin&1(0u8b@=>Mv6Ea<2No!sy?E;xN`PW(4#&as8*?y+HLNyMq0Q3;Z-k+t&#*9^BbJ@}5dw=mUM1Hb(`i_pTTVFFD8hP&}^w+GF7IX1qijblf^$tDjw z#Z128!+NHN1t+!hOtSLt>*+A7L{`X;b31sbk#V@5-Shoci>p2~buayC#OnC*e)*BG zz_bZjgHlmczi3nuUo7x4&qlADaWU&MllX37z0G;zHOpMebdDHc#P#J+0Yf+gbCPn} zSmrYd=sjTR$p2Ck&;YPDA<;J1{oo~{v+)DukVHq>`j&q`6|7_V&Ty5SW0N6yWJO-b z;7cN{6fImq+@g@*=_O?Pogep6>GAi&tv!xjAw}2J93I!F9z79LZz+5skSovau?{?= ztt_|r64R&bEV~8oBnEcEZJ?ADa(DBWe^J)nyxz)f==_;Zj+ylJHl{CPY)#z% z>S&d@Lqs$@O9?S`hj$`0As5EuFi5Chy4kXPI!~z2aOui72k(MM`k+8x07&+%N=AOp zukR=2!tzy3QQoiiw!-le9lTE;;|X_7Bvty^Y;MVxvT7A?=sPTUgz+uv;YiTk>1fAd zeC)DcSHwX(bH(<4)2}aO(TG^Ys1Lt5*dg+aBoi9lMzIH`d($b*SaZS_0|feTpK2kQ zW9XE!+}T+*Tqu_`Rv??O>PwR1F!_bh`vGs4hgquGZQN_3nkxWsd(5{ZJfEK$PV+qV zKJUf5a`GA}Y|(F5PL4~9@xlkX2Z{NmqJe7%(@vLe8XY}PeKw2foA2yL>R~5q_B{MG zF1Z@H_uyG3*uXV#5%^s^>4j zf4>op95kvV|lSZ1M zj#smP-9u-L8+@(8Xf>p{eq3IT2sk+VnPjhH%5X2w2w$rW3)Q95rY`}n#z(uPIph4e zUv`ALC>t8yg}neQ81y_f@TE>$>(JKx}B#M+q7 zkL(78_{BsGpA{WX3%xb@A>%uy+gr$5%fW0Ql;fyNnbI>R~F5BAnjLG~KqUXC=8 zotv$(P+(;n_Uyo2l;|UD!=tqx_eFGrDCJPW3 zZAW5$elCoDE&(t86H}70VWoo06x7GA@Z+?$ZvE$V#VjAicgq0)MCsqp1wiEx&r}MF z>i4dWrLszDd>?oF^P3TaL;B2+h@#js)7f=-^ZEw`w(71dW{nPun{wXj2uj0;R~xOz z_m|6h;#fNrn{LnWJCfPO7~HxFzuKd6z~!EOIE$mNs80oiu>jlvkBEyt#!lpUw`0Y!kB9=YyE zJSe`hD8v0K-_uK76oz5mwT%2k;-ve<3Gn^RM#cy^&s;Y}Zu(ioa^+OWZVYEzmFwr0 zK1uJs3DN5LOym9gtZSpY<+21C;=yd9)@^Rs*zri+Xrl2G>N$(qiO=fZ()6EN2^lr8*PSoPkmck zu0_qevfcf;PF`U|lO7D2zZ!4-XPtg{;g2u`c%7~?WnH0Xl>00ZwT3UbSXoCIM)Hmb zbfL+)T~hVMxWy6Uk1R_0D$L6y(47V-?jMtRCAHOJY;h-$uViiB$$P4a@U(mw=-RNV z-CbF|AE07B3xR7djr3+U{4IdL^-dsjBrbZXIQ?v}k{v(udhG*kYryTr)N36&nb@iy zAjtK`dXmb;`IjdDT93EfAN#FP-x?pSCg}R!UYo(-IpXvBzV&PS&WQ7?Va%j@-Cn1W z%pooKDt;}EW=1{ts=vfA8~u$NXRU{CObB|D+qRM<6w|$E>_kHw*l! PD*!oZ<(Czb#v%U?S{qZZ literal 0 HcmV?d00001 From 2f4504c2e5be61859624accbe12ab3fe0974f8e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Feb 2022 17:56:32 -0500 Subject: [PATCH 1107/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 066f59d5..d15648e7 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-14 + +### Changed + +- **Home Assistant Container LXC** + - Add [Update Menu](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) + ## 2022-02-13 ### Changed From 213e0c9b33fbbab7395c2988f98838712c67cd59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Feb 2022 11:07:56 -0500 Subject: [PATCH 1108/6505] Add files via upload --- misc/images/adminer.png | Bin 0 -> 95067 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/adminer.png diff --git a/misc/images/adminer.png b/misc/images/adminer.png new file mode 100644 index 0000000000000000000000000000000000000000..803c9e622d9a91648004399f94858078c1256831 GIT binary patch literal 95067 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 literal 0 HcmV?d00001 From e1dde2826d7be4112eb364b295e0fd18f7df317e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Feb 2022 11:08:55 -0500 Subject: [PATCH 1109/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d15648e7..f01f0cca 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Mariadb LXC** - - Add Adminer (formerly phpMinAdmin), a full-featured database management tool + - Add [Adminer](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin), a full-featured database management tool ## 2022-02-12 From 257f7e8ce7bd5de46f7147a51422514d3c58d439 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Feb 2022 11:51:13 -0500 Subject: [PATCH 1110/6505] Add files via upload --- misc/images/adminer.png | Bin 95067 -> 146572 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/adminer.png b/misc/images/adminer.png index 803c9e622d9a91648004399f94858078c1256831..b457e9a0eea4a53baf383f8127a6cef30207da10 100644 GIT binary patch literal 146572 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 literal 95067 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 From 3f431e100a0477d00a03d8864b338eb5a7232dd4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Feb 2022 13:01:51 -0500 Subject: [PATCH 1111/6505] Add files via upload --- misc/images/adminer.png | Bin 146572 -> 139371 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/adminer.png b/misc/images/adminer.png index b457e9a0eea4a53baf383f8127a6cef30207da10..bede27577be12d9b28646562fdd8ebec0e7e67c6 100644 GIT binary patch literal 139371 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

AnF0 zgaGrxLKO zX>a!fJ~%Zs6=s)l#?DUt_;~EX!mC>h$-RAj?Zkss_p_A^b}b^H*8&6wWVv72yL^BT(Co$I-2IQs zdZnV}xh!ftLm>gX`eX|ipp46E)3v3ajZ30`f-QrfwOuWS?j)iUb>KZye-!Mp!iTPQ z%l)%8Z!vF*x<>)I`1bXyClpDL?a(wBfd+$+cHxYrlAlK(EN53=7qGnt8_H?X9T=D) z(3tBtZcHsNOTT&Z03`pWfq_t1AvBRhOY?}5`=6jzKvGQW&QQ-+6zyLQ3=Dh(c^?Gg1W2n; zlD8&mF-OP7#_b3GmOs(``1#6)^VB+Ssv$!~bqX01=G>uqutm z2|M~L!@_c053K>o@BjT#y1O1j=+YB?B7L&{^(gJ1$b}{E21HS2zY1TeV0u^0?b5Ri z`u|?EKUi>`r{Imis4G{qf+C=z$)_qNLhBhi>HmG*MFcbr&Bw}up?&n%>!gAiCzqEs zmR1?j_6zCC|NX^Y2jn;SUR{3rNrwB6n9hGc1oolF=l`o&;vWF7H`k!xPvb+N=IzjjL7>~|l`i|NRvLirX!-fW3w{ikIg) zm`*&IS~PgD5L=wk+lSxAd<$ zCeW%(PfzpPEs+Qa2ymJ8<2`=-7_}AHjIXk~vLclkfYsC8Eha6ED=XVE;Ld#e$s*_( zb-xn$r9;;y+SrVtrQZ;AKcU2FyLDtO;_A8(P|~cd7_Wa*)aE;00sURTQ=qU#aGQC* zeT&i9*a)~EY#BbKrA}4HGk#pSbV5Q=z%U953LbEBCV=>U_(e@tT6!9A{8J5$NT4q^ zpr5g7mWbKfqG?)RhB~?kC#0sf0Iax-k3S2&v7bpv`cTgR%%v(Mc)y_e-P?NzE%)x8 zo=I>SA^l%;tgC^4;tnGtj)jEb`s!CK`P|M0yL)*detldtHR zT79g?StA%ZdIs1Yf2YqpobshmPLWr)7@67=9e9g5ayT9E6#D8BUS5uVeljTvzdj_% zYV;N^-)e7fo#pTRotO{3&pQG~R}9;3OfD_ee!U$F8h`M*lcN)I_D^MGfyFTqE}1#& zhAZy(@bH!*3$wwTNnTbR5fBvUcbB*)VHYT5M%Yvx-xMea4Q86RK0CP|7QuOU~{KHVYRo^=5Zkp8QWem zGM!M`wzF$IJDgKBN5A3b-r89G>2Wat=Z2ATT4MV4`oTfvLOF%;;(x+SA&i$S1AuTS zNJ@GyUxM7ZivfDp1sv+!8z5vQ$wop;@S&h5DYHj z5)wXO^*{#=IGv7;j=;fi74%_CW(9-4W zv9boxf+5q&FJsm~@tgeFfSE-3kr&hXkUVz zzw+ml!P)r;>@T2^L_d>pZG=uIbYZ3^YPGaoUxQ;281z<#P^-ZRN?vuWMxvG>TFVQd;8T0-zBw zaP3?d5GVtLMnp;~Dc?;E4LI01_;~pKsJ+A8f&1;zf~1fGzkg>kG9uHgcK?J*pU-#M z7gxy^@k}sS6>2K8qKzuDi2n4&{atSEeZ$u4AbZQYpKRh%i+;Jq${JxY(*Gkq{w)-f z)YSV?!Y+Xrn8Udq9((}hkY?E>11z_1$B3S5dPDRT6_Em|z>qS;9?15|cR#%bJJGA! z<1#7JaQfc;&PpNM1vYPj)sKqd4?804QnkuOHaFR$L}}{aqB-r{dsk}1Te0IVU0od- zn27ElPjQjLNQ3DpQP1hAt*EX{bV9Qm0XP>tar01AxJ>�y9l*#eHdLm}}TZhK>R# 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≻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 From 30ea3a4ab2e6b334659172088e4a66f53f3f84a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Feb 2022 14:55:02 -0500 Subject: [PATCH 1112/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a6df5457..ce57998d 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **Update Menu** +⚙️ [**Update Menu**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) Run in the LXC console ```yaml @@ -481,7 +481,7 @@ Run in the LXC console ```yaml apt update && apt upgrade -y ``` -⚙️ **Adminer** (formerly phpMinAdmin) is a full-featured database management tool +⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool `http://your-mariadb-lxc-ip/adminer/` From 6103a19cd366408fb1fbbf3963ba5a13de697c28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Feb 2022 19:49:17 -0500 Subject: [PATCH 1113/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce57998d..edf163cd 100644 --- a/README.md +++ b/README.md @@ -490,7 +490,7 @@ ________________________________________________________________________________

AnF0 zgaGrxLKO zX>a!fJ~%Zs6=s)l#?DUt_;~EX!mC>h$-RAj?Zkss_p_A^b}b^H*8&6wWVv72yL^BT(Co$I-2IQs zdZnV}xh!ftLm>gX`eX|ipp46E)3v3ajZ30`f-QrfwOuWS?j)iUb>KZye-!Mp!iTPQ z%l)%8Z!vF*x<>)I`1bXyClpDL?a(wBfd+$+cHxYrlAlK(EN53=7qGnt8_H?X9T=D) z(3tBtZcHsNOTT&Z03`pWfq_t1AvBRhOY?}5`=6jzKvGQW&QQ-+6zyLQ3=Dh(c^?Gg1W2n; zlD8&mF-OP7#_b3GmOs(``1#6)^VB+Ssv$!~bqX01=G>uqutm z2|M~L!@_c053K>o@BjT#y1O1j=+YB?B7L&{^(gJ1$b}{E21HS2zY1TeV0u^0?b5Ri z`u|?EKUi>`r{Imis4G{qf+C=z$)_qNLhBhi>HmG*MFcbr&Bw}up?&n%>!gAiCzqEs zmR1?j_6zCC|NX^Y2jn;SUR{3rNrwB6n9hGc1oolF=l`o&;vWF7H`k!xPvb+N=IzjjL7>~|l`i|NRvLirX!-fW3w{ikIg) zm`*&IS~PgD5L=wk+lSxAd<$ zCeW%(PfzpPEs+Qa2ymJ8<2`=-7_}AHjIXk~vLclkfYsC8Eha6ED=XVE;Ld#e$s*_( zb-xn$r9;;y+SrVtrQZ;AKcU2FyLDtO;_A8(P|~cd7_Wa*)aE;00sURTQ=qU#aGQC* zeT&i9*a)~EY#BbKrA}4HGk#pSbV5Q=z%U953LbEBCV=>U_(e@tT6!9A{8J5$NT4q^ zpr5g7mWbKfqG?)RhB~?kC#0sf0Iax-k3S2&v7bpv`cTgR%%v(Mc)y_e-P?NzE%)x8 zo=I>SA^l%;tgC^4;tnGtj)jEb`s!CK`P|M0yL)*detldtHR zT79g?StA%ZdIs1Yf2YqpobshmPLWr)7@67=9e9g5ayT9E6#D8BUS5uVeljTvzdj_% zYV;N^-)e7fo#pTRotO{3&pQG~R}9;3OfD_ee!U$F8h`M*lcN)I_D^MGfyFTqE}1#& zhAZy(@bH!*3$wwTNnTbR5fBvUcbB*)VHYT5M%Yvx-xMea4Q86RK0CP|7QuOU~{KHVYRo^=5Zkp8QWem zGM!M`wzF$IJDgKBN5A3b-r89G>2Wat=Z2ATT4MV4`oTfvLOF%;;(x+SA&i$S1AuTS zNJ@GyUxM7ZivfDp1sv+!8z5vQ$wop;@S&h5DYHj z5)wXO^*{#=IGv7;j=;fi74%_CW(9-4W zv9boxf+5q&FJsm~@tgeFfSE-3kr&hXkUVz zzw+ml!P)r;>@T2^L_d>pZG=uIbYZ3^YPGaoUxQ;281z<#P^-ZRN?vuWMxvG>TFVQd;8T0-zBw zaP3?d5GVtLMnp;~Dc?;E4LI01_;~pKsJ+A8f&1;zf~1fGzkg>kG9uHgcK?J*pU-#M z7gxy^@k}sS6>2K8qKzuDi2n4&{atSEeZ$u4AbZQYpKRh%i+;Jq${JxY(*Gkq{w)-f z)YSV?!Y+Xrn8Udq9((}hkY?E>11z_1$B3S5dPDRT6_Em|z>qS;9?15|cR#%bJJGA! z<1#7JaQfc;&PpNM1vYPj)sKqd4?804QnkuOHaFR$L}}{aqB-r{dsk}1Te0IVU0od- zn27ElPjQjLNQ3DpQP1hAt*EX{bV9Qm0XP>tar01AxJ>�y9l*#eHdLm}}TZhK>R# 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≻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

- 🔸Zigbee2MQTT LXC + Zigbee2MQTT LXC

logo.png

@@ -570,7 +570,7 @@ ________________________________________________________________________________
- 🔸Zwavejs2MQTT LXC + Zwavejs2MQTT LXC

From ded7b69826ed0210509ae972116dbf476f934c53 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 07:12:24 -0500 Subject: [PATCH 1114/6505] Update ha_setup.sh --- setup/ha_setup.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 66d515e6..76c1d3d9 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -115,6 +115,8 @@ show_menu(){ printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" printf "${menu}**${number} 4)${safe} Just Update Containers ${normal}\n" + printf "${menu}**${number} 5)${safe} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 6)${safe} Update Host OS ${normal}\n" printf "${menu}*********************************************${normal}\n" printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" read opt @@ -155,6 +157,17 @@ while [ $opt != '' ] ./update-containers.sh; exit; ;; + 5) clear; + option_picked "Removing Unused Images"; + docker image prune -af; + exit; + ;; + 6) clear; + option_picked "Updating Host OS"; + apt update && apt upgrade -y; + exit; + ;; + x)exit; ;; \n)exit; @@ -170,16 +183,13 @@ docker pull homeassistant/home-assistant:$TAG docker rm --force homeassistant docker run -d \ --name homeassistant \ - --privileged \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ -v /etc/timezone:/etc/timezone:ro \ --net=host \ homeassistant/home-assistant:$TAG - docker image prune -af EOF sudo chmod +x /root/update cat >$UPDATE_CONTAINERS_PATH <<'EOF' @@ -198,7 +208,6 @@ for container in ${CONTAINER_LIST}; do eval ${DOCKER_COMMAND} fi done -docker image prune -af EOF sudo chmod +x /root/update-containers.sh From 40e175b09ea91073223a2665b0d1d1625787ba34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 07:12:54 -0500 Subject: [PATCH 1115/6505] Add files via upload --- misc/images/update-menu.png | Bin 17827 -> 23319 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png index 7388b16dcdb47b379a345a55249a46e703e80984..e16d40d6e8a720ae8f6889b36a6441be9b28d05a 100644 GIT binary patch literal 23319 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 z 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 PD*!oZ<(Czb#v%U?S{qZZ From 0c0c940367db99bd3a0daf904f3d94bed3610a20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 07:15:40 -0500 Subject: [PATCH 1116/6505] Update ha_setup.sh --- setup/ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 76c1d3d9..523f03f3 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -115,7 +115,7 @@ show_menu(){ printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" printf "${menu}**${number} 4)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 5)${safe} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 5)${number} Remove Unused Images ${normal}\n" printf "${menu}**${number} 6)${safe} Update Host OS ${normal}\n" printf "${menu}*********************************************${normal}\n" printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" From ad904dd1c8fe478fe46b00e9bfb871a86fe3dd42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 07:20:37 -0500 Subject: [PATCH 1117/6505] Add files via upload --- misc/images/update-menu.png | Bin 23319 -> 23180 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png index e16d40d6e8a720ae8f6889b36a6441be9b28d05a..e996b4a7bca650f10c535ba1218e5a1d7f8eb277 100644 GIT binary patch literal 23180 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 Date: Wed, 16 Feb 2022 07:37:49 -0500 Subject: [PATCH 1118/6505] Update ha_setup.sh --- setup/ha_setup.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 523f03f3..0c5f658e 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -114,9 +114,10 @@ show_menu(){ printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" - printf "${menu}**${number} 4)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 5)${number} Remove Unused Images ${normal}\n" - printf "${menu}**${number} 6)${safe} Update Host OS ${normal}\n" + printf "${menu}**${number} 4)${fgred} Edit Home Assistant Configuration ${normal}\n" + printf "${menu}**${number} 5)${safe} Just Update Containers ${normal}\n" + printf "${menu}**${number} 6)${number} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 7)${safe} Update Host OS ${normal}\n" printf "${menu}*********************************************${normal}\n" printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" read opt @@ -153,16 +154,21 @@ while [ $opt != '' ] break; ;; 4) clear; + option_picked "Editing Home Assistant Configuration"; + nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; + exit; + ;; + 5) clear; option_picked "Just Updating Containers"; ./update-containers.sh; exit; ;; - 5) clear; + 6) clear; option_picked "Removing Unused Images"; docker image prune -af; exit; ;; - 6) clear; + 7) clear; option_picked "Updating Host OS"; apt update && apt upgrade -y; exit; From 34c47873f73902ce780847666ef5cf61bf297d6d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 07:40:19 -0500 Subject: [PATCH 1119/6505] Add files via upload --- misc/images/update-menu.png | Bin 23180 -> 26558 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png index e996b4a7bca650f10c535ba1218e5a1d7f8eb277..2266abcd745e0ba871c4b3a9e877588fcab1940c 100644 GIT binary patch literal 26558 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 z Date: Wed, 16 Feb 2022 11:22:54 -0500 Subject: [PATCH 1120/6505] Update ha_setup.sh --- setup/ha_setup.sh | 68 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 0c5f658e..e03d7fda 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -114,10 +114,14 @@ show_menu(){ printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" - printf "${menu}**${number} 4)${fgred} Edit Home Assistant Configuration ${normal}\n" - printf "${menu}**${number} 5)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 6)${number} Remove Unused Images ${normal}\n" - printf "${menu}**${number} 7)${safe} Update Host OS ${normal}\n" + printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" + printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" + printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" + printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" + printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" + printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" + printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" printf "${menu}*********************************************${normal}\n" printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" read opt @@ -148,31 +152,77 @@ while [ $opt != '' ] TAG=beta break; ;; - 3) clear; + 3) while true; do + read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; option_picked "Switching to Dev Branch"; TAG=dev break; ;; 4) clear; + option_picked "Backing up Home Assistant Data to root (hass_config)"; + rm -r hass_config; + cp -pR /var/lib/docker/volumes/hass_config/ /root/; + exit; + ;; + 5) while true; do + read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Restoring Home Assistant Data from root (hass_config)"; + rm -r /var/lib/docker/volumes/hass_config/_data; + cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; + exit; + ;; + 6) while true; do + read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; option_picked "Editing Home Assistant Configuration"; nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; exit; ;; - 5) clear; + 7) clear; + option_picked "Restarting Home Assistant"; + docker restart homeassistant; + exit; + ;; + 8) clear; option_picked "Just Updating Containers"; ./update-containers.sh; exit; ;; - 6) clear; + 9) clear; option_picked "Removing Unused Images"; docker image prune -af; exit; ;; - 7) clear; + 10) clear; option_picked "Updating Host OS"; apt update && apt upgrade -y; exit; ;; + 11) clear; + option_picked "Reboot Host OS"; + reboot; + exit; + ;; x)exit; ;; @@ -230,6 +280,6 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - +mkdir /root/hass_config echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From b43530d7325b74993ac3f4f699ff51e0192a936c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 11:23:22 -0500 Subject: [PATCH 1121/6505] Add files via upload --- misc/images/update-menu.png | Bin 26558 -> 39462 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png index 2266abcd745e0ba871c4b3a9e877588fcab1940c..548730b3fd46ea76bca7bbe7839f05304f2bc806 100644 GIT binary patch literal 39462 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 Date: Wed, 16 Feb 2022 11:43:05 -0500 Subject: [PATCH 1122/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f01f0cca..43140b1e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-16 + +### Changed + +- **Home Assistant Container LXC** + - Add Options to [Update Menu](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) + ## 2022-02-14 ### Changed From 65b892e4bdfc830c24357e479b7e4469628e63bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 12:45:56 -0500 Subject: [PATCH 1123/6505] Update ha_setup.sh --- setup/ha_setup.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index e03d7fda..87e21393 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -239,8 +239,10 @@ docker pull homeassistant/home-assistant:$TAG docker rm --force homeassistant docker run -d \ --name homeassistant \ + --privileged \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ -v /etc/timezone:/etc/timezone:ro \ From 7cab561606b0b89adad2d7a994aa0e7e04922e38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 13:16:57 -0500 Subject: [PATCH 1124/6505] Update ha_setup.sh --- setup/ha_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 87e21393..343dfb08 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -110,6 +110,7 @@ show_menu(){ number=`echo "\033[33m"` bgred=`echo "\033[41m"` fgred=`echo "\033[31m"` + hostname -I printf "\n${menu}*********************************************${normal}\n" printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" From 9f7c8e2235f0ed9dff6376ee908fe9bb831c348f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 13:20:29 -0500 Subject: [PATCH 1125/6505] Add files via upload --- misc/images/update-menu.png | Bin 39462 -> 36240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png index 548730b3fd46ea76bca7bbe7839f05304f2bc806..51bfc89032122940fb44445cff17783a5d59f32e 100644 GIT binary patch literal 36240 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
~M8;j^$v+6zSM0{DsSG)BJz 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 F{{jd+))xQ( literal 39462 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 ykWKsAg#Y}q7cBzVE3q9>t@)F%{68Fb`;a|@ Date: Wed, 16 Feb 2022 13:58:56 -0500 Subject: [PATCH 1126/6505] Add files via upload --- misc/images/update-menu.png | Bin 36240 -> 41752 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png index 51bfc89032122940fb44445cff17783a5d59f32e..42e65b98fe8e4dc539c13caa6d24c2e119c0afd6 100644 GIT binary patch literal 41752 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 literal 36240 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 F{{jd+))xQ( From 473ad88788ac22d02d85f7146485cb41eb4cd16a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 14:01:08 -0500 Subject: [PATCH 1127/6505] Delete update-menu.png --- misc/images/update-menu.png | Bin 41752 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/update-menu.png diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png deleted file mode 100644 index 42e65b98fe8e4dc539c13caa6d24c2e119c0afd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41752 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 From 3b6ade484c63dac924f50dc9afad29a950b588de Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 14:01:27 -0500 Subject: [PATCH 1128/6505] Add files via upload --- misc/images/update-menu.png | Bin 0 -> 41752 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/update-menu.png diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..42e65b98fe8e4dc539c13caa6d24c2e119c0afd6 GIT binary patch literal 41752 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 literal 0 HcmV?d00001 From b7badade56c4e49636edf3baa1d8b55038d3d6d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 15:52:54 -0500 Subject: [PATCH 1129/6505] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index edf163cd..ded9f5ab 100644 --- a/README.md +++ b/README.md @@ -244,6 +244,13 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/e **ESPHome Interface - IP:6052** +⚙️ **To Update ESPHome** + +Run in the LXC console +```yaml +pip3 install esphome --upgrade +``` + ____________________________________________________________________________________________
From 890a74e09a848fd6dc301a6118a7266295552f44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 17:31:32 -0500 Subject: [PATCH 1130/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 455e6e34..b73ec487 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -60,6 +60,9 @@ apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null +mkdir /var/log/apache2 +chmod 750 /var/log/apache2 +chown root:adm /var/log/apache2 sudo systemctl reload apache2 &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" From bb0bc8eef6a04fddbcf2b8dcb400f0c92dd6e397 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 17:39:23 -0500 Subject: [PATCH 1131/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index b73ec487..af8d80ee 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -60,7 +60,7 @@ apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null -mkdir /var/log/apache2 +#mkdir /var/log/apache2 chmod 750 /var/log/apache2 chown root:adm /var/log/apache2 sudo systemctl reload apache2 &>/dev/null From 2d001c10fa090fcd05edfd71fb74e42d6f6a846f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 17:53:11 -0500 Subject: [PATCH 1132/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index af8d80ee..5f838497 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -60,10 +60,11 @@ apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null -#mkdir /var/log/apache2 +sudo systemctl reload apache2 &>/dev/null +mkdir -p /var/log/apache2 chmod 750 /var/log/apache2 chown root:adm /var/log/apache2 -sudo systemctl reload apache2 &>/dev/null +service apache2 start echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" rm /etc/motd From 860c0bc2ca8631bf5a81549cbdc1a8a6c2717637 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 18:03:36 -0500 Subject: [PATCH 1133/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 5f838497..912213e5 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -61,10 +61,6 @@ echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null -mkdir -p /var/log/apache2 -chmod 750 /var/log/apache2 -chown root:adm /var/log/apache2 -service apache2 start echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" rm /etc/motd @@ -79,6 +75,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +service apache2 stop +mkdir /var/log/apache2 +chmod 750 /var/log/apache2 +chown root:adm /var/log/apache2 +service apache2 start echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 4eb3d6d406758b0a015d0a5296cef37ad29bb911 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 18:04:58 -0500 Subject: [PATCH 1134/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 912213e5..74b7f0ee 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -76,7 +76,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') service apache2 stop -mkdir /var/log/apache2 +mkdir /var/log/apache2 chmod 750 /var/log/apache2 chown root:adm /var/log/apache2 service apache2 start From 7fdadc252ab6af7d2fce16639e2f0d21e458a208 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 18:12:24 -0500 Subject: [PATCH 1135/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 74b7f0ee..211aa86a 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -76,7 +76,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') service apache2 stop -mkdir /var/log/apache2 +mkdir -p /var/log/apache2 chmod 750 /var/log/apache2 chown root:adm /var/log/apache2 service apache2 start From 86a0e98f0708d06138c134653b2016741e357d46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 18:22:59 -0500 Subject: [PATCH 1136/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 211aa86a..71b45c60 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -58,6 +58,9 @@ apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" +mkdir /var/log/apache2 +chmod 750 /var/log/apache2 +chown root:adm /var/log/apache2 sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null @@ -75,11 +78,6 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -service apache2 stop -mkdir -p /var/log/apache2 -chmod 750 /var/log/apache2 -chown root:adm /var/log/apache2 -service apache2 start echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From eb28b2cea701719f744a7d9f49fe244bd9f9cd9e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 18:27:44 -0500 Subject: [PATCH 1137/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 71b45c60..c527715f 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -58,11 +58,12 @@ apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" -mkdir /var/log/apache2 -chmod 750 /var/log/apache2 -chown root:adm /var/log/apache2 sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null +mkdir /root/var/log/apache2 +chmod 750 /root/var/log/apache2 +chown root:adm /root/var/log/apache2 + sudo systemctl reload apache2 &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" From 01c543697623674cc09f22c76538670e6b6e2bd9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 18:40:14 -0500 Subject: [PATCH 1138/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index c527715f..b63171ec 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -59,11 +59,11 @@ apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null +sudo service apache2 stop +mkdir /var/log/apache2 +chmod 750 /var/log/apache2 +chown root:adm /var/log/apache2 sudo a2enconf adminer &>/dev/null -mkdir /root/var/log/apache2 -chmod 750 /root/var/log/apache2 -chown root:adm /root/var/log/apache2 - sudo systemctl reload apache2 &>/dev/null echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" From 4d4ba2d98d9b327fa8536dc57f79e34fa86e4ee1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 18:48:13 -0500 Subject: [PATCH 1139/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index b63171ec..a074e6c9 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -60,7 +60,7 @@ apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null sudo service apache2 stop -mkdir /var/log/apache2 +mkdir -p /var/log/apache2 chmod 750 /var/log/apache2 chown root:adm /var/log/apache2 sudo a2enconf adminer &>/dev/null From fbe5802ce4d867632fff2b4970130ddb6cdb2db1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 19:06:57 -0500 Subject: [PATCH 1140/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index a074e6c9..f53229cf 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -60,7 +60,6 @@ apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null sudo service apache2 stop -mkdir -p /var/log/apache2 chmod 750 /var/log/apache2 chown root:adm /var/log/apache2 sudo a2enconf adminer &>/dev/null From 07912e124a80df824ac33cd94d09d459ea59ab1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 19:14:47 -0500 Subject: [PATCH 1141/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index f53229cf..455e6e34 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -59,9 +59,6 @@ apt-get install -y mariadb-server &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Adminer... \e[0m" sudo apt install adminer -y &>/dev/null -sudo service apache2 stop -chmod 750 /var/log/apache2 -chown root:adm /var/log/apache2 sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null From af2215a6f93461512e7d64613f6efb62f241532d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 20:05:08 -0500 Subject: [PATCH 1142/6505] Update mariadb_setup.sh --- setup/mariadb_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh index 455e6e34..2b56d74e 100644 --- a/setup/mariadb_setup.sh +++ b/setup/mariadb_setup.sh @@ -78,3 +78,4 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +mkdir /var/log/apache2 From 65e2b6b931d87b6f3f992f62e6ba5be04ffd6ba2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Feb 2022 20:32:21 -0500 Subject: [PATCH 1143/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ded9f5ab..0d6a2ec2 100644 --- a/README.md +++ b/README.md @@ -653,7 +653,7 @@ ________________________________________________________________________________
- Debian 11 LXC + 🔸Debian 11 LXC

Debian

@@ -651,6 +651,12 @@ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run th ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian11_container.sh)" ``` +To create a new Proxmox Unprivileged Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-debian.sh)" +``` +

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. From e2f1a945de4eaa30adc99e702fdb452254110d5e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:21:58 -0500 Subject: [PATCH 1254/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6ef95df6..a4aba019 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file. - Add NEW Unprivileged Install Script - **MQTT LXC** - Add NEW Unprivileged Install Script +- **Debian 11 LXC** + - Add NEW Unprivileged Install Script ## 2022-02-20 From a70da7d0eb7f2fc1e65f7e604a395424fc1b0372 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:24:45 -0500 Subject: [PATCH 1255/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7602aca7..198fd516 100644 --- a/README.md +++ b/README.md @@ -654,7 +654,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/d To create a new Proxmox Unprivileged Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-debian.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-debian.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

From c4a27d1a895df004271c7749d199943bd5c057d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:44:04 -0500 Subject: [PATCH 1256/6505] Create ubuntu-install.sh --- unpriv/ubuntu-install.sh | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 unpriv/ubuntu-install.sh diff --git a/unpriv/ubuntu-install.sh b/unpriv/ubuntu-install.sh new file mode 100644 index 00000000..58674399 --- /dev/null +++ b/unpriv/ubuntu-install.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 1bf85a4479b158af5caa8375179487da3b7ddf5e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:45:11 -0500 Subject: [PATCH 1257/6505] Create unprivileged-ubuntu.sh --- unpriv/unprivileged-ubuntu.sh | 116 ++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 unpriv/unprivileged-ubuntu.sh diff --git a/unpriv/unprivileged-ubuntu.sh b/unpriv/unprivileged-ubuntu.sh new file mode 100644 index 00000000..a54c8e19 --- /dev/null +++ b/unpriv/unprivileged-ubuntu.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Ubuntu 21.10 LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + + + + _ _ _ _ + | | | | | | | + | | | | |__ _ _ _ __ | |_ _ _ + | | | | _ \| | | | _ \| __| | | | + | |__| | |_) | |_| | | | | |_| |_| | + \____/|_.__/ \__,_|_| |_|\__|\__,_| + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=21.10 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname ubuntu + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/ubuntu-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Ubuntu 21.10 LXC to${CL} ${BL}$CTID${CL}. \n" From 77525d3c491854b384fcebddaf1fdb56726b4dea Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:47:39 -0500 Subject: [PATCH 1258/6505] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 198fd516..48f5d0ad 100644 --- a/README.md +++ b/README.md @@ -674,7 +674,7 @@ ________________________________________________________________________________
- Ubuntu 21.10 LXC + 🔸Ubuntu 21.10 LXC

Ubuntu

@@ -685,6 +685,12 @@ To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu_container.sh)" ``` +To create a new Proxmox Unprivileged Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-ubuntu.sh)" +``` +

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. From 8fe7eef385cf6a942fe0eaebcc948f2ce76a1402 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:48:37 -0500 Subject: [PATCH 1259/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a4aba019..400728a4 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -16,6 +16,8 @@ All notable changes to this project will be documented in this file. - Add NEW Unprivileged Install Script - **Debian 11 LXC** - Add NEW Unprivileged Install Script +- **Ubuntu 21.10 LXC** + - Add NEW Unprivileged Install Script ## 2022-02-20 From 1b2ff619ac99fe09985a7693a71b96f4090716f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 16:51:11 -0500 Subject: [PATCH 1260/6505] Update unprivileged-ubuntu.sh --- unpriv/unprivileged-ubuntu.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpriv/unprivileged-ubuntu.sh b/unpriv/unprivileged-ubuntu.sh index a54c8e19..c35e96b4 100644 --- a/unpriv/unprivileged-ubuntu.sh +++ b/unpriv/unprivileged-ubuntu.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' @@ -15,7 +15,7 @@ while true; do done clear function header_info { -echo -e "${RD} +echo -e "${YW} From bca829ff68d37da307bab82e5e8d7c31a5d6f089 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 18:57:19 -0500 Subject: [PATCH 1261/6505] Update unprivileged-node-red.sh --- unpriv/unprivileged-node-red.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpriv/unprivileged-node-red.sh b/unpriv/unprivileged-node-red.sh index 9b8e19f8..82e98afc 100644 --- a/unpriv/unprivileged-node-red.sh +++ b/unpriv/unprivileged-node-red.sh @@ -93,7 +93,7 @@ export PCT_OPTIONS=" -memory 1024 -unprivileged 1 " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -106,7 +106,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/node-red-install.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/node-red-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 51a82e3581bb6ecba7e9c9575ba53205f3b23a7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 18:58:01 -0500 Subject: [PATCH 1262/6505] Update unprivileged-mariadb.sh --- unpriv/unprivileged-mariadb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpriv/unprivileged-mariadb.sh b/unpriv/unprivileged-mariadb.sh index 032c50b5..7db3ff84 100644 --- a/unpriv/unprivileged-mariadb.sh +++ b/unpriv/unprivileged-mariadb.sh @@ -96,7 +96,7 @@ export PCT_OPTIONS=" -memory 1024 -unprivileged 1 " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -109,7 +109,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/mariadb-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/mariadb-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 5e5a2d1a8159f1a118d6dd4d93a8f6f6bcdeb9c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 19:00:32 -0500 Subject: [PATCH 1263/6505] Update unprivileged-homeassistant.sh --- unpriv/unprivileged-homeassistant.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpriv/unprivileged-homeassistant.sh b/unpriv/unprivileged-homeassistant.sh index 3faa55a7..881dce63 100644 --- a/unpriv/unprivileged-homeassistant.sh +++ b/unpriv/unprivileged-homeassistant.sh @@ -94,7 +94,7 @@ export PCT_OPTIONS=" -memory 2048 -unprivileged 1 " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -112,7 +112,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unprev/homeassistant-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/homeassistant-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 7e4627424372f8448c3f9c7737afead523f5b806 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 19:05:22 -0500 Subject: [PATCH 1264/6505] Update unprivileged-node-red.sh --- unpriv/unprivileged-node-red.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpriv/unprivileged-node-red.sh b/unpriv/unprivileged-node-red.sh index 82e98afc..2142aa65 100644 --- a/unpriv/unprivileged-node-red.sh +++ b/unpriv/unprivileged-node-red.sh @@ -106,7 +106,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/node-red-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/node-red-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 24b4fd672ceb5e3a85e02b209b9e08c2aa0823bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 19:19:55 -0500 Subject: [PATCH 1265/6505] Update unprivileged-node-red.sh --- unpriv/unprivileged-node-red.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpriv/unprivileged-node-red.sh b/unpriv/unprivileged-node-red.sh index 2142aa65..5664a5a8 100644 --- a/unpriv/unprivileged-node-red.sh +++ b/unpriv/unprivileged-node-red.sh @@ -110,7 +110,7 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}." +echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}. ${RD}Node-Red${CL} is reachable by going to the following URL. ${BL}http://${IP}:1880${CL} \n" From 97dd52a47c9ab84485b5bf54d115e22c8658758b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 19:21:14 -0500 Subject: [PATCH 1266/6505] Update node-red-install.sh --- unpriv/node-red-install.sh | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/unpriv/node-red-install.sh b/unpriv/node-red-install.sh index 18193e2a..f9794196 100644 --- a/unpriv/node-red-install.sh +++ b/unpriv/node-red-install.sh @@ -1,4 +1,50 @@ #!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 5ea42ce7cc7f69ccdb97be32476876014397175b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 19:28:46 -0500 Subject: [PATCH 1267/6505] Update node-red-install.sh --- unpriv/node-red-install.sh | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/unpriv/node-red-install.sh b/unpriv/node-red-install.sh index f9794196..b6519e12 100644 --- a/unpriv/node-red-install.sh +++ b/unpriv/node-red-install.sh @@ -31,20 +31,7 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From fff3b929d8add71e9621ee72b8acebb502c69da7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 19:51:43 -0500 Subject: [PATCH 1268/6505] Update node-red-install.sh --- unpriv/node-red-install.sh | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/unpriv/node-red-install.sh b/unpriv/node-red-install.sh index b6519e12..b0b65809 100644 --- a/unpriv/node-red-install.sh +++ b/unpriv/node-red-install.sh @@ -1,36 +1,4 @@ #!/usr/bin/env bash -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` From 834b9ee63604af3524923f591009abe73883eddd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 19:54:49 -0500 Subject: [PATCH 1269/6505] Update node-red-install.sh --- unpriv/node-red-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpriv/node-red-install.sh b/unpriv/node-red-install.sh index b0b65809..bce542ef 100644 --- a/unpriv/node-red-install.sh +++ b/unpriv/node-red-install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +set -e CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 070beeadec845b8300ee49f13beb5b39ddbb2c0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 20:19:08 -0500 Subject: [PATCH 1270/6505] Update mariadb-install.sh --- unpriv/mariadb-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unpriv/mariadb-install.sh b/unpriv/mariadb-install.sh index ec2afc16..c9a18f8a 100644 --- a/unpriv/mariadb-install.sh +++ b/unpriv/mariadb-install.sh @@ -66,7 +66,7 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " -lxc-cmd apt-get autoremove >/dev/null -lxc-cmd apt-get autoclean >/dev/null -lxc-cmd rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* echo -e "${CM}${CL} \n" From 01eb345f22867166dd61839460da6a24c07ad797 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 21:27:31 -0500 Subject: [PATCH 1271/6505] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 48f5d0ad..b8e79ab8 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ To create a new Proxmox Home Assistant Container, run the following in the Proxm ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ha_container.sh)" ``` -To create a new Proxmox Unprivileged Home Assistant Container, run the following in the Proxmox Shell. +To create a new Proxmox **Unprivileged** Home Assistant Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-homeassistant.sh)" @@ -331,7 +331,7 @@ To create a new Proxmox MQTT LXC Container, run the following in the Proxmox She ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt_container.sh)" ``` -To create a new Proxmox Unprivileged MQTT LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox **Unprivileged** MQTT LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-mqtt.sh)" @@ -387,7 +387,7 @@ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red_container.sh)" ``` -To create a new Proxmox Unprivileged Node-RED LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox **Unprivileged** Node-RED LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-node-red.sh)" @@ -434,7 +434,7 @@ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb_container.sh)" ``` -To create a new Proxmox Unprivileged Mariadb LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox **Unprivileged** Mariadb LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-mariadb.sh)" @@ -651,7 +651,7 @@ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run th ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian11_container.sh)" ``` -To create a new Proxmox Unprivileged Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox **Unprivileged** Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-debian.sh)" @@ -685,7 +685,7 @@ To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu_container.sh)" ``` -To create a new Proxmox Unprivileged Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox **Unprivileged** Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-ubuntu.sh)" From 07d529793e74a19eb882827ead9c5b5c4b05e6ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 22:30:21 -0500 Subject: [PATCH 1272/6505] Create adguard-install.sh --- unpriv/adguard-install.sh | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 unpriv/adguard-install.sh diff --git a/unpriv/adguard-install.sh b/unpriv/adguard-install.sh new file mode 100644 index 00000000..c894db5d --- /dev/null +++ b/unpriv/adguard-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing AdGuard Home... " +curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 57ef0ed0ad67dabbb90407418c64b6ebe4008d8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 22:32:37 -0500 Subject: [PATCH 1273/6505] Create unprivileged-adguard.sh --- unpriv/unprivileged-adguard.sh | 119 +++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 unpriv/unprivileged-adguard.sh diff --git a/unpriv/unprivileged-adguard.sh b/unpriv/unprivileged-adguard.sh new file mode 100644 index 00000000..b5b528db --- /dev/null +++ b/unpriv/unprivileged-adguard.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash + +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Unprivileged Adguard Home LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${GN} + + + _ _ + /\ | | | | + / \ __| | __ _ _ _ __ _ _ __ __| | + / /\ \ / _ |/ _ | | | |/ _ | __/ _ | + / ____ \ (_| | (_| | |_| | (_| | | | (_| | + /_/ \_\__,_|\__, |\__,_|\__,_|_| \__,_| + __/ | + |___/ + + +${CL}" +} + +header_info + + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1 + -hostname adguard + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged 1 +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/adguard-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Adguard Home LXC to${CL} ${BL}$CTID${CL}. +${GN}Adguard${CL} Setup is reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" + From 899d3dd671d17cdfa27c5e18b765b83a228f2716 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 22:40:27 -0500 Subject: [PATCH 1274/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 400728a4..4a88e41b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-23 + +### Changed + +- **Adguard Home LXC** + - Add NEW Unprivileged Install Script + ## 2022-02-22 ### Changed From 66cb97f5b09e5499c324fba5f0957a42d3d8f8d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 22:43:47 -0500 Subject: [PATCH 1275/6505] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b8e79ab8..52026a4c 100644 --- a/README.md +++ b/README.md @@ -828,7 +828,7 @@ ________________________________________________________________________________
-AdGuard Home LXC + 🔸AdGuard Home LXC

@@ -839,6 +839,12 @@ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard_container.sh)" ``` +To create a new Proxmox **Unprivileged** AdGuard Home LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-adguard.sh)" +``` +

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

**AdGuard Home Setup Interface - IP:3000 (After Setup use only IP)** From e9a575dcb9d43eac5887d1f0894c5b7632afa4d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Feb 2022 23:11:56 -0500 Subject: [PATCH 1276/6505] Update unprivileged-homeassistant.sh --- unpriv/unprivileged-homeassistant.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/unpriv/unprivileged-homeassistant.sh b/unpriv/unprivileged-homeassistant.sh index 881dce63..6998b93b 100644 --- a/unpriv/unprivileged-homeassistant.sh +++ b/unpriv/unprivileged-homeassistant.sh @@ -98,6 +98,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpr STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf @@ -108,6 +109,10 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +info "${BL}Using fuse-overlayfs.${CL}" +fi echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" From 0433f9062fc98d8c6081480cd1f61708b61a03cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:41:01 -0500 Subject: [PATCH 1277/6505] Create adguard.sh --- ct/adguard.sh | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 ct/adguard.sh diff --git a/ct/adguard.sh b/ct/adguard.sh new file mode 100644 index 00000000..6b9b2b37 --- /dev/null +++ b/ct/adguard.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Adguard Home LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${GN} + + + _ _ + /\ | | | | + / \ __| | __ _ _ _ __ _ _ __ __| | + / /\ \ / _ |/ _ | | | |/ _ | __/ _ | + / ____ \ (_| | (_| | |_| | (_| | | | (_| | + /_/ \_\__,_|\__, |\__,_|\__,_|_| \__,_| + __/ | + |___/ + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1 + -hostname adguard + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/unpriv/adguard-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Adguard Home LXC to${CL} ${BL}$CTID${CL}. +${GN}Adguard${CL} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" + From eace419149ea2c3b61ecfbb0f449cd8cd8758f4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:41:58 -0500 Subject: [PATCH 1278/6505] Create debian.sh --- ct/debian.sh | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 ct/debian.sh diff --git a/ct/debian.sh b/ct/debian.sh new file mode 100644 index 00000000..87c720e7 --- /dev/null +++ b/ct/debian.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Debian Bulleyes LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + + + _____ _ _ + | __ \ | | (_) + | | | | ___| |__ _ __ _ _ __ + | | | |/ _ \ _ \| |/ _ | _ \ + | |__| | __/ |_) | | (_| | | | | + |_____/ \___|_.__/|_|\__,_|_| |_| + + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname debian + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/debian-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Debian Bulleyes LXC to${CL} ${BL}$CTID${CL}. \n" From bebe826821796f3ef4da703f88fec9c8f85349fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:43:35 -0500 Subject: [PATCH 1279/6505] Create homeassistant.sh --- ct/homeassistant.sh | 170 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 ct/homeassistant.sh diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh new file mode 100644 index 00000000..4445d8af --- /dev/null +++ b/ct/homeassistant.sh @@ -0,0 +1,170 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + _ _ _ _ _ + | | | | /\ (_) | | | | + | |__| | ___ _ __ ___ ___ / \ ___ ___ _ ___| |_ __ _ _ __ | |_ + | __ |/ _ \| _ _ \ / _ \ / /\ \ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ / ____ \\__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___| /_/ \_\___/___/_|___/\__\__,_|_| |_|\__| + + + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname homeassistant + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +if [ "$STORAGE_TYPE" == "zfspool" ]; then +pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +info "${BL}Using fuse-overlayfs.${CL}" +fi +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Home Assistant Container LXC to${CL} ${BL}$CTID${CL}. +${BL}Home Assistant${CL} should be reachable by going to the following URL. + + ${BL}http://${IP}:8123${CL} \n" From c15d503144c18a3e45b9fa0c97993c2588a84fd6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:44:41 -0500 Subject: [PATCH 1280/6505] Update adguard.sh --- ct/adguard.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index 6b9b2b37..fdf6a9b3 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -138,7 +138,7 @@ export PCT_OPTIONS=" -memory 512 -unprivileged ${IM} " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -151,7 +151,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/unpriv/adguard-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/adguard-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From fa916c37ac3561430a6481b304d8cc2276cfb105 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:45:26 -0500 Subject: [PATCH 1281/6505] Update debian.sh --- ct/debian.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index 87c720e7..5a6aa2f2 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -138,7 +138,7 @@ export PCT_OPTIONS=" -memory 512 -unprivileged ${IM} " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -151,7 +151,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/debian-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From bc7e3107eba1734be0a2b2a4f17ae25ccae16950 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:46:06 -0500 Subject: [PATCH 1282/6505] Update homeassistant.sh --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 4445d8af..f6fbf8a6 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -137,7 +137,7 @@ export PCT_OPTIONS=" -memory 2048 -unprivileged ${IM} " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then From 08fdfad88e24269322c1d9f7c3217f0cd6dd7757 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:47:28 -0500 Subject: [PATCH 1283/6505] Create mariadb.sh --- ct/mariadb.sh | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 ct/mariadb.sh diff --git a/ct/mariadb.sh b/ct/mariadb.sh new file mode 100644 index 00000000..6e258e68 --- /dev/null +++ b/ct/mariadb.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Mariadb LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + __ __ _ _ _ + | \/ | (_) | | | + | \ / | __ _ _ __ _ __ _ __| | |__ + | |\/| |/ _ | __| |/ _ |/ _ | _ \ + | | | | (_| | | | | (_| | (_| | |_) | + |_| |_|\__,_|_| |_|\__,_|\__,_|_.__/ + + + + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features nesting=1 + -hostname mariadb + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 1024 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. \n" From 2ba9626487107bd981c9a21f498ae352c1f89d17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:48:30 -0500 Subject: [PATCH 1284/6505] Create mqtt.sh --- ct/mqtt.sh | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 ct/mqtt.sh diff --git a/ct/mqtt.sh b/ct/mqtt.sh new file mode 100644 index 00000000..2664dffb --- /dev/null +++ b/ct/mqtt.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New MQTT LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + + + __ __ ____ _______ _______ + | \/ |/ __ \__ __|__ __| + | \ / | | | | | | | | + | |\/| | | | | | | | | + | | | | |__| | | | | | + |_| |_|\___\_\ |_| |_| + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1 + -hostname mqtt + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created MQTT LXC to${CL} ${BL}$CTID${CL}. \n" From 6eaa538673182f67bbe2d81d4a02d2820675c3a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:49:35 -0500 Subject: [PATCH 1285/6505] Create node-red.sh --- ct/node-red.sh | 158 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 ct/node-red.sh diff --git a/ct/node-red.sh b/ct/node-red.sh new file mode 100644 index 00000000..4ed8b967 --- /dev/null +++ b/ct/node-red.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Node-Red LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + _ _ _ _____ _ + | \ | | | | | __ \ | | + | \| | ___ __| | ___ ______| |__) |___ __| | + | |/ _ \ / _ |/ _ \______| _ // _ \/ _ | + | |\ | (_) | (_| | __/ | | \ \ __/ (_| | + |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features nesting=1 + -hostname node-red + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 1024 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}. +${RD}Node-Red${CL} should be reachable by going to the following URL. + + ${BL}http://${IP}:1880${CL} \n" From 1bd258678744500f7327634218fb9391e902de79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:50:54 -0500 Subject: [PATCH 1286/6505] Create ubuntu.sh --- ct/ubuntu.sh | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 ct/ubuntu.sh diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh new file mode 100644 index 00000000..bed96ac1 --- /dev/null +++ b/ct/ubuntu.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Ubuntu 21.10 LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + + + + + _ _ _ _ + | | | | | | | + | | | | |__ _ _ _ __ | |_ _ _ + | | | | _ \| | | | _ \| __| | | | + | |__| | |_) | |_| | | | | |_| |_| | + \____/|_.__/ \__,_|_| |_|\__|\__,_| + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=21.10 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname ubuntu + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Ubuntu 21.10 LXC to${CL} ${BL}$CTID${CL}. \n" From ff969880df6a4be40ccc6462d1fe5170c0408e83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:52:01 -0500 Subject: [PATCH 1287/6505] Create zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 168 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 ct/zigbee2mqtt.sh diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh new file mode 100644 index 00000000..c35dcae7 --- /dev/null +++ b/ct/zigbee2mqtt.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Zigbee2MQTT LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + + + _________ __ __ + |___ /__ \| \/ | + / / ) | \ / | + / / / /| |\/| | + / /__ / /_| | | | + /_____|____|_| |_| + + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features nesting=1,keyctl=1,mknod=1 + -hostname zigbee2mqtt + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 1024 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/zigbee2mqtt-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Zigbee2MQTT LXC to${CL} ${BL}$CTID${CL}. \n" From 25b5ded2598f2d51568498a357a902e69f878e11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:52:49 -0500 Subject: [PATCH 1288/6505] Create create_lxc.sh --- ct/create_lxc.sh | 121 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 ct/create_lxc.sh diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh new file mode 100644 index 00000000..509a73d4 --- /dev/null +++ b/ct/create_lxc.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + if [ $((${#MENU[@]}/3)) -eq 0 ]; then + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then + printf ${MENU[0]} + else + local STORAGE + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." +[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." + +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using ${BL}$TEMPLATE_STORAGE${CL} for Template Storage." + +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using ${BL}$CONTAINER_STORAGE${CL} for Container Storage." + +echo -en "${GN} Updating LXC Template List... " +pveam update >/dev/null +echo -e "${CM}${CL} \r" + +TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} +mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + echo -en "${GN} Downloading LXC Template... " + echo -e "${CM}${CL} \r" + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture)) + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +echo -en "${GN} Creating LXC Container... " +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." +echo -e "${CM}${CL} \r" +info "LXC Container ${BL}$CTID${CL} was successfully created." From 0480a0e23e10a83f5d94296671fa2c46c97125d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:53:43 -0500 Subject: [PATCH 1289/6505] Create adguard-install.sh --- setup/adguard-install.sh | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 setup/adguard-install.sh diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh new file mode 100644 index 00000000..c894db5d --- /dev/null +++ b/setup/adguard-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing AdGuard Home... " +curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 0e63f2c371f22b66433030875fc001074f8bf2e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:54:17 -0500 Subject: [PATCH 1290/6505] Create debian-install.sh --- setup/debian-install.sh | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 setup/debian-install.sh diff --git a/setup/debian-install.sh b/setup/debian-install.sh new file mode 100644 index 00000000..fe9ef62a --- /dev/null +++ b/setup/debian-install.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From ceff105ae73eeb8dfd28775ddbbaf70593f1c980 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:54:52 -0500 Subject: [PATCH 1291/6505] Create homeassistant-install.sh --- setup/homeassistant-install.sh | 281 +++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 setup/homeassistant-install.sh diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh new file mode 100644 index 00000000..76713df6 --- /dev/null +++ b/setup/homeassistant-install.sh @@ -0,0 +1,281 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing pip3... " +apt-get install -y python3-pip &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Docker... " +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF +sh <(curl -sSL https://get.docker.com) &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Pulling Portainer Image... " +docker pull portainer/portainer-ce:latest &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Portainer Image... " +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Pulling Home Assistant Image... " +docker pull homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Home Assistant Image... " +docker volume create hass_config >/dev/null +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Update Menu Script... " +pip3 install runlike &>/dev/null +UPDATE_PATH='/root/update' +UPDATE_CONTAINERS_PATH='/root/update-containers.sh' +cat >$UPDATE_PATH <<'EOF' +#!/bin/sh +set -o errexit +show_menu(){ + normal=`echo "\033[m"` + safe=`echo "\033[32m"` + menu=`echo "\033[36m"` + number=`echo "\033[33m"` + bgred=`echo "\033[41m"` + fgred=`echo "\033[31m"` + hostname -I + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" + printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" + printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" + printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" + printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" + printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" + printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" + printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" + printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" + printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" + printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" + read opt +} +option_picked(){ + msgcolor=`echo "\033[01;31m"` + normal=`echo "\033[00;00m"` + message=${@:-"${normal}Error: No message passed"} + printf "${msgcolor}${message}${normal}\n" +} +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + option_picked "Switching to Stable Branch"; + TAG=stable + break; + ;; + 2) clear; + option_picked "Switching to Beta Branch"; + TAG=beta + break; + ;; + 3) while true; do + read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Switching to Dev Branch"; + TAG=dev + break; + ;; + 4) clear; + option_picked "Backing up Home Assistant Data to root (hass_config)"; + rm -r hass_config; + cp -pR /var/lib/docker/volumes/hass_config/ /root/; + exit; + ;; + 5) while true; do + read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Restoring Home Assistant Data from root (hass_config)"; + rm -r /var/lib/docker/volumes/hass_config/_data; + cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; + exit; + ;; + 6) while true; do + read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Editing Home Assistant Configuration"; + nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; + exit; + ;; + 7) clear; + option_picked "Restarting Home Assistant"; + docker restart homeassistant; + exit; + ;; + 8) clear; + option_picked "Just Updating Containers"; + ./update-containers.sh; + exit; + ;; + 9) clear; + option_picked "Removing Unused Images"; + docker image prune -af; + exit; + ;; + 10) clear; + option_picked "Updating Host OS"; + apt update && apt upgrade -y; + exit; + ;; + 11) clear; + option_picked "Reboot Host OS"; + reboot; + exit; + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose an option from the menu"; + show_menu; + ;; + esac + fi + done +docker pull homeassistant/home-assistant:$TAG +docker rm --force homeassistant +docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:$TAG +EOF +sudo chmod +x /root/update +cat >$UPDATE_CONTAINERS_PATH <<'EOF' +#!/bin/bash +set -o errexit +CONTAINER_LIST="${1:-$(docker ps -q)}" +for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike "${container}")" + docker rm --force "${container}" + eval ${DOCKER_COMMAND} + fi +done +EOF +sudo chmod +x /root/update-containers.sh +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 5272aa5b7e2a2a6a0249f519e1731125f6b1b810 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:55:33 -0500 Subject: [PATCH 1292/6505] Create mariadb-install.sh --- setup/mariadb-install.sh | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 setup/mariadb-install.sh diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh new file mode 100644 index 00000000..c9a18f8a --- /dev/null +++ b/setup/mariadb-install.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing MariaDB... " +curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null +apt-get update >/dev/null +apt-get install -y mariadb-server &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Adminer... " +sudo apt install adminer -y &>/dev/null +sudo a2enconf adminer &>/dev/null +sudo systemctl reload apache2 &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From b1f458d7f2f6bec23d49069509de9496537c248c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:56:11 -0500 Subject: [PATCH 1293/6505] Create mqtt-install.sh --- setup/mqtt-install.sh | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 setup/mqtt-install.sh diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh new file mode 100644 index 00000000..7f5e9e3e --- /dev/null +++ b/setup/mqtt-install.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Mosquitto MQTT Broker... " +wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null +apt-key add mosquitto-repo.gpg.key &>/dev/null +cd /etc/apt/sources.list.d/ +wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list &>/dev/null +apt-get update >/dev/null +apt-get -y install mosquitto &>/dev/null +apt-get -y install mosquitto-clients &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From ce02de0e74c2b77b5e3359a395337f3151b42902 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:56:52 -0500 Subject: [PATCH 1294/6505] Create node-red-install.sh --- setup/node-red-install.sh | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 setup/node-red-install.sh diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh new file mode 100644 index 00000000..bce542ef --- /dev/null +++ b/setup/node-red-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node-Red... " +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul +sudo systemctl enable nodered.service &>/dev/null +sudo systemctl start nodered.service &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 5a52055142cbfc61aea5f5fafb82c58797e5816a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:57:41 -0500 Subject: [PATCH 1295/6505] Create ubuntu-install.sh --- setup/ubuntu-install.sh | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 setup/ubuntu-install.sh diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh new file mode 100644 index 00000000..58674399 --- /dev/null +++ b/setup/ubuntu-install.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 53b9d77ca7a5732114b3f17a97e9035334e49f5d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 06:58:19 -0500 Subject: [PATCH 1296/6505] Create zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 91 ++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 setup/zigbee2mqtt-install.sh diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh new file mode 100644 index 00000000..4e3ba373 --- /dev/null +++ b/setup/zigbee2mqtt-install.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +set -e +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Zigbee2MQTT Repository... " +sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Zigbee2MQTT... " +cd /opt/zigbee2mqtt &>/dev/null +npm ci &>/dev/null +echo -e "${CM}${CL} \r" + +service_path="/etc/systemd/system/zigbee2mqtt.service" +echo "[Unit] +Description=zigbee2mqtt +After=network.target +[Service] +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zigbee2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From b23bb6965b4e1fb6180392c7ed4b96566a9b9fa6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:03:18 -0500 Subject: [PATCH 1297/6505] Update adguard.sh --- ct/adguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index fdf6a9b3..93ea0211 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -151,7 +151,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/adguard-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From e0bc337772909bac43b7959fc8012c603abd3713 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:06:04 -0500 Subject: [PATCH 1298/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index c35dcae7..5084c5e5 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -161,7 +161,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/zigbee2mqtt-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 63f3dd68e2d808e39242f034706d59c69789f74e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:13:00 -0500 Subject: [PATCH 1299/6505] Update README.md --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 52026a4c..9328eea2 100644 --- a/README.md +++ b/README.md @@ -837,12 +837,7 @@ ________________________________________________________________________________ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard_container.sh)" -``` -To create a new Proxmox **Unprivileged** AdGuard Home LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-adguard.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

From 20bafb8279a1575ed0cf89287036a3f4d5081fbc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:28:48 -0500 Subject: [PATCH 1300/6505] Update README.md --- README.md | 42 ++++++------------------------------------ 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 9328eea2..4e3f97b0 100644 --- a/README.md +++ b/README.md @@ -165,12 +165,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ha_container.sh)" -``` -To create a new Proxmox **Unprivileged** Home Assistant Container, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-homeassistant.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/homeassistant.sh)" ```

⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

@@ -329,12 +324,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc To create a new Proxmox MQTT LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt_container.sh)" -``` -To create a new Proxmox **Unprivileged** MQTT LXC Container, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-mqtt.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -385,12 +375,7 @@ ________________________________________________________________________________ To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red_container.sh)" -``` -To create a new Proxmox **Unprivileged** Node-RED LXC Container, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-node-red.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -432,12 +417,7 @@ ________________________________________________________________________________ To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb_container.sh)" -``` -To create a new Proxmox **Unprivileged** Mariadb LXC Container, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-mariadb.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

@@ -649,12 +629,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian11_container.sh)" -``` -To create a new Proxmox **Unprivileged** Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-debian.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

@@ -683,12 +658,7 @@ ________________________________________________________________________________ To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu_container.sh)" -``` -To create a new Proxmox **Unprivileged** Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/unprivileged-ubuntu.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu.sh)" ```

⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

From 3a2fd02d1250b727abdfd205f26f2b45b477a787 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:34:19 -0500 Subject: [PATCH 1301/6505] Delete adguard-install.sh --- unpriv/adguard-install.sh | 64 --------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 unpriv/adguard-install.sh diff --git a/unpriv/adguard-install.sh b/unpriv/adguard-install.sh deleted file mode 100644 index c894db5d..00000000 --- a/unpriv/adguard-install.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing AdGuard Home... " -curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From a800052678edbb8b9120b1bb90de8b39f6041f90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:34:29 -0500 Subject: [PATCH 1302/6505] Delete create_lxc.sh --- unpriv/create_lxc.sh | 121 ------------------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 unpriv/create_lxc.sh diff --git a/unpriv/create_lxc.sh b/unpriv/create_lxc.sh deleted file mode 100644 index 509a73d4..00000000 --- a/unpriv/create_lxc.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=( "$TAG" "$ITEM" "OFF" ) - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - if [ $((${#MENU[@]}/3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." -[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." - -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using ${BL}$TEMPLATE_STORAGE${CL} for Template Storage." - -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using ${BL}$CONTAINER_STORAGE${CL} for Container Storage." - -echo -en "${GN} Updating LXC Template List... " -pveam update >/dev/null -echo -e "${CM}${CL} \r" - -TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - echo -en "${GN} Downloading LXC Template... " - echo -e "${CM}${CL} \r" - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture)) - -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) - -echo -en "${GN} Creating LXC Container... " -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." -echo -e "${CM}${CL} \r" -info "LXC Container ${BL}$CTID${CL} was successfully created." From e2ce5f72c1693113ecc67d2c85ac7c148eea5557 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:34:36 -0500 Subject: [PATCH 1303/6505] Delete debian-install.sh --- unpriv/debian-install.sh | 60 ---------------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 unpriv/debian-install.sh diff --git a/unpriv/debian-install.sh b/unpriv/debian-install.sh deleted file mode 100644 index fe9ef62a..00000000 --- a/unpriv/debian-install.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 69ba20e8c53340c492331fb112a9775b9ca08628 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:34:44 -0500 Subject: [PATCH 1304/6505] Delete homeassistant-install.sh --- unpriv/homeassistant-install.sh | 281 -------------------------------- 1 file changed, 281 deletions(-) delete mode 100644 unpriv/homeassistant-install.sh diff --git a/unpriv/homeassistant-install.sh b/unpriv/homeassistant-install.sh deleted file mode 100644 index 76713df6..00000000 --- a/unpriv/homeassistant-install.sh +++ /dev/null @@ -1,281 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing pip3... " -apt-get install -y python3-pip &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Docker... " -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF -sh <(curl -sSL https://get.docker.com) &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Pulling Portainer Image... " -docker pull portainer/portainer-ce:latest &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Portainer Image... " -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Pulling Home Assistant Image... " -docker pull homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Home Assistant Image... " -docker volume create hass_config >/dev/null -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Creating Update Menu Script... " -pip3 install runlike &>/dev/null -UPDATE_PATH='/root/update' -UPDATE_CONTAINERS_PATH='/root/update-containers.sh' -cat >$UPDATE_PATH <<'EOF' -#!/bin/sh -set -o errexit -show_menu(){ - normal=`echo "\033[m"` - safe=`echo "\033[32m"` - menu=`echo "\033[36m"` - number=`echo "\033[33m"` - bgred=`echo "\033[41m"` - fgred=`echo "\033[31m"` - hostname -I - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" - printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" - printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" - printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" - printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" - printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" - printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" - printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" - printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" - printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" - read opt -} -option_picked(){ - msgcolor=`echo "\033[01;31m"` - normal=`echo "\033[00;00m"` - message=${@:-"${normal}Error: No message passed"} - printf "${msgcolor}${message}${normal}\n" -} -clear -show_menu -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - option_picked "Switching to Stable Branch"; - TAG=stable - break; - ;; - 2) clear; - option_picked "Switching to Beta Branch"; - TAG=beta - break; - ;; - 3) while true; do - read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Switching to Dev Branch"; - TAG=dev - break; - ;; - 4) clear; - option_picked "Backing up Home Assistant Data to root (hass_config)"; - rm -r hass_config; - cp -pR /var/lib/docker/volumes/hass_config/ /root/; - exit; - ;; - 5) while true; do - read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Restoring Home Assistant Data from root (hass_config)"; - rm -r /var/lib/docker/volumes/hass_config/_data; - cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - exit; - ;; - 6) while true; do - read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Editing Home Assistant Configuration"; - nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - exit; - ;; - 7) clear; - option_picked "Restarting Home Assistant"; - docker restart homeassistant; - exit; - ;; - 8) clear; - option_picked "Just Updating Containers"; - ./update-containers.sh; - exit; - ;; - 9) clear; - option_picked "Removing Unused Images"; - docker image prune -af; - exit; - ;; - 10) clear; - option_picked "Updating Host OS"; - apt update && apt upgrade -y; - exit; - ;; - 11) clear; - option_picked "Reboot Host OS"; - reboot; - exit; - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose an option from the menu"; - show_menu; - ;; - esac - fi - done -docker pull homeassistant/home-assistant:$TAG -docker rm --force homeassistant -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:$TAG -EOF -sudo chmod +x /root/update -cat >$UPDATE_CONTAINERS_PATH <<'EOF' -#!/bin/bash -set -o errexit -CONTAINER_LIST="${1:-$(docker ps -q)}" -for container in ${CONTAINER_LIST}; do - CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" - RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" - docker pull "${CONTAINER_IMAGE}" - LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" - if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then - echo "Updating ${container} image ${CONTAINER_IMAGE}" - DOCKER_COMMAND="$(runlike "${container}")" - docker rm --force "${container}" - eval ${DOCKER_COMMAND} - fi -done -EOF -sudo chmod +x /root/update-containers.sh -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 878b56f1ff2788cdd4dc90374f3de1c86fa0c14c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:34:53 -0500 Subject: [PATCH 1305/6505] Delete mariadb-install.sh --- unpriv/mariadb-install.sh | 72 --------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 unpriv/mariadb-install.sh diff --git a/unpriv/mariadb-install.sh b/unpriv/mariadb-install.sh deleted file mode 100644 index c9a18f8a..00000000 --- a/unpriv/mariadb-install.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing MariaDB... " -curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null -apt-get update >/dev/null -apt-get install -y mariadb-server &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Adminer... " -sudo apt install adminer -y &>/dev/null -sudo a2enconf adminer &>/dev/null -sudo systemctl reload apache2 &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 6d4c3e7022b262d90ba91c449a510858c5a53708 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:00 -0500 Subject: [PATCH 1306/6505] Delete mqtt-install.sh --- unpriv/mqtt-install.sh | 71 ------------------------------------------ 1 file changed, 71 deletions(-) delete mode 100644 unpriv/mqtt-install.sh diff --git a/unpriv/mqtt-install.sh b/unpriv/mqtt-install.sh deleted file mode 100644 index 7f5e9e3e..00000000 --- a/unpriv/mqtt-install.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Mosquitto MQTT Broker... " -wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null -apt-key add mosquitto-repo.gpg.key &>/dev/null -cd /etc/apt/sources.list.d/ -wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list &>/dev/null -apt-get update >/dev/null -apt-get -y install mosquitto &>/dev/null -apt-get -y install mosquitto-clients &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 5560e352900faa919e7b24e349b13993bfc4803b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:08 -0500 Subject: [PATCH 1307/6505] Delete node-red-install.sh --- unpriv/node-red-install.sh | 64 -------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 unpriv/node-red-install.sh diff --git a/unpriv/node-red-install.sh b/unpriv/node-red-install.sh deleted file mode 100644 index bce542ef..00000000 --- a/unpriv/node-red-install.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Node-Red... " -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul -sudo systemctl enable nodered.service &>/dev/null -sudo systemctl start nodered.service &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 52b361f64dd39985c16acf9755a1712ab277c8dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:16 -0500 Subject: [PATCH 1308/6505] Delete ubuntu-install.sh --- unpriv/ubuntu-install.sh | 59 ---------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 unpriv/ubuntu-install.sh diff --git a/unpriv/ubuntu-install.sh b/unpriv/ubuntu-install.sh deleted file mode 100644 index 58674399..00000000 --- a/unpriv/ubuntu-install.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash - -set -e -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 6bc48190fd5673d17c1c96d52e707d2f277d4dad Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:25 -0500 Subject: [PATCH 1309/6505] Delete unprivileged-adguard.sh --- unpriv/unprivileged-adguard.sh | 119 --------------------------------- 1 file changed, 119 deletions(-) delete mode 100644 unpriv/unprivileged-adguard.sh diff --git a/unpriv/unprivileged-adguard.sh b/unpriv/unprivileged-adguard.sh deleted file mode 100644 index b5b528db..00000000 --- a/unpriv/unprivileged-adguard.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Adguard Home LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${GN} - - - _ _ - /\ | | | | - / \ __| | __ _ _ _ __ _ _ __ __| | - / /\ \ / _ |/ _ | | | |/ _ | __/ _ | - / ____ \ (_| | (_| | |_| | (_| | | | (_| | - /_/ \_\__,_|\__, |\__,_|\__,_|_| \__,_| - __/ | - |___/ - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features nesting=1 - -hostname adguard - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/adguard-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Adguard Home LXC to${CL} ${BL}$CTID${CL}. -${GN}Adguard${CL} Setup is reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" - From 89239cc4d8303208106ad2580b880971f1cf2d9e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:32 -0500 Subject: [PATCH 1310/6505] Delete unprivileged-debian.sh --- unpriv/unprivileged-debian.sh | 116 ---------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 unpriv/unprivileged-debian.sh diff --git a/unpriv/unprivileged-debian.sh b/unpriv/unprivileged-debian.sh deleted file mode 100644 index 73562de0..00000000 --- a/unpriv/unprivileged-debian.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Debian Bulleyes LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - - - - _____ _ _ - | __ \ | | (_) - | | | | ___| |__ _ __ _ _ __ - | | | |/ _ \ _ \| |/ _ | _ \ - | |__| | __/ |_) | | (_| | | | | - |_____/ \___|_.__/|_|\__,_|_| |_| - - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 - -hostname debian - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/debian-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Debian Bulleyes LXC to${CL} ${BL}$CTID${CL}. \n" From 302ac8aeb0f0a131adec44ced91375e3a1060811 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:41 -0500 Subject: [PATCH 1311/6505] Delete unprivileged-homeassistant.sh --- unpriv/unprivileged-homeassistant.sh | 127 --------------------------- 1 file changed, 127 deletions(-) delete mode 100644 unpriv/unprivileged-homeassistant.sh diff --git a/unpriv/unprivileged-homeassistant.sh b/unpriv/unprivileged-homeassistant.sh deleted file mode 100644 index 6998b93b..00000000 --- a/unpriv/unprivileged-homeassistant.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - - _ _ _ _ _ - | | | | /\ (_) | | | | - | |__| | ___ _ __ ___ ___ / \ ___ ___ _ ___| |_ __ _ _ __ | |_ - | __ |/ _ \| _ _ \ / _ \ / /\ \ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ / ____ \\__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___| /_/ \_\___/___/_|___/\__\__,_|_| |_|\__| - - - - -${CL}" -} - -header_info - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 - -hostname homeassistant - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -info "${BL}Using fuse-overlayfs.${CL}" -fi -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/homeassistant-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Home Assistant Container LXC to${CL} ${BL}$CTID${CL}. -${BL}Home Assistant${CL} is reachable by going to the following URL. - - ${BL}http://${IP}:8123${CL} \n" From ddec96264d857d86308463becd3c60dfc698be4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:48 -0500 Subject: [PATCH 1312/6505] Delete unprivileged-mariadb.sh --- unpriv/unprivileged-mariadb.sh | 116 --------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 unpriv/unprivileged-mariadb.sh diff --git a/unpriv/unprivileged-mariadb.sh b/unpriv/unprivileged-mariadb.sh deleted file mode 100644 index 7db3ff84..00000000 --- a/unpriv/unprivileged-mariadb.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Mariadb LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - - __ __ _ _ _ - | \/ | (_) | | | - | \ / | __ _ _ __ _ __ _ __| | |__ - | |\/| |/ _ | __| |/ _ |/ _ | _ \ - | | | | (_| | | | | (_| | (_| | |_) | - |_| |_|\__,_|_| |_|\__,_|\__,_|_.__/ - - - - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features nesting=1 - -hostname mariadb - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/mariadb-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. \n" From 5ef5cb97989689ad37e8ca98a5c4ef68990ffa10 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:35:56 -0500 Subject: [PATCH 1313/6505] Delete unprivileged-mqtt.sh --- unpriv/unprivileged-mqtt.sh | 114 ------------------------------------ 1 file changed, 114 deletions(-) delete mode 100644 unpriv/unprivileged-mqtt.sh diff --git a/unpriv/unprivileged-mqtt.sh b/unpriv/unprivileged-mqtt.sh deleted file mode 100644 index 166cb0d6..00000000 --- a/unpriv/unprivileged-mqtt.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged MQTT LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - - - __ __ ____ _______ _______ - | \/ |/ __ \__ __|__ __| - | \ / | | | | | | | | - | |\/| | | | | | | | | - | | | | |__| | | | | | - |_| |_|\___\_\ |_| |_| - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features nesting=1 - -hostname mqtt - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/mqtt-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created MQTT LXC to${CL} ${BL}$CTID${CL}. \n" From 3dbd9f58314eda70b4c3821953e5583a1d28d2af Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:36:03 -0500 Subject: [PATCH 1314/6505] Delete unprivileged-node-red.sh --- unpriv/unprivileged-node-red.sh | 116 -------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 unpriv/unprivileged-node-red.sh diff --git a/unpriv/unprivileged-node-red.sh b/unpriv/unprivileged-node-red.sh deleted file mode 100644 index 5664a5a8..00000000 --- a/unpriv/unprivileged-node-red.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash - -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Node-Red LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - - _ _ _ _____ _ - | \ | | | | | __ \ | | - | \| | ___ __| | ___ ______| |__) |___ __| | - | |/ _ \ / _ |/ _ \______| _ // _ \/ _ | - | |\ | (_) | (_| | __/ | | \ \ __/ (_| | - |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features nesting=1 - -hostname node-red - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/node-red-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}. -${RD}Node-Red${CL} is reachable by going to the following URL. - - ${BL}http://${IP}:1880${CL} \n" From affc7b7f5a50db67f6ec2c57a4d3a385777bd6c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:36:11 -0500 Subject: [PATCH 1315/6505] Delete unprivileged-ubuntu.sh --- unpriv/unprivileged-ubuntu.sh | 116 ---------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 unpriv/unprivileged-ubuntu.sh diff --git a/unpriv/unprivileged-ubuntu.sh b/unpriv/unprivileged-ubuntu.sh deleted file mode 100644 index c35e96b4..00000000 --- a/unpriv/unprivileged-ubuntu.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Unprivileged Ubuntu 21.10 LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - - - - - _ _ _ _ - | | | | | | | - | | | | |__ _ _ _ __ | |_ _ _ - | | | | _ \| | | | _ \| __| | | | - | |__| | |_) | |_| | | | | |_| |_| | - \____/|_.__/ \__,_|_| |_|\__|\__,_| - - -${CL}" -} - -header_info - - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=21.10 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 - -hostname ubuntu - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged 1 -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/unpriv/ubuntu-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Ubuntu 21.10 LXC to${CL} ${BL}$CTID${CL}. \n" From b3ae85c856b09df15dab8148845342e61cf8a545 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:54:18 -0500 Subject: [PATCH 1316/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4a88e41b..97c8ca53 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,24 +7,24 @@ All notable changes to this project will be documented in this file. ### Changed - **Adguard Home LXC** - - Add NEW Unprivileged Install Script + - Add NEW Privileged/Unprivileged Install Script ## 2022-02-22 ### Changed - **Home Assistant Container LXC** - - Add NEW Unprivileged Install Script + - Add NEW Privileged/Unprivileged Install Script - **Node-Red LXC** - - Add NEW Unprivileged Install Script + - Add NEW Privileged/Unprivileged Install Script - **Mariadb LXC** - - Add NEW Unprivileged Install Script + - Add NEW Privileged/Unprivileged Install Script - **MQTT LXC** - - Add NEW Unprivileged Install Script + - Add NEW Privileged/Unprivileged Install Script - **Debian 11 LXC** - - Add NEW Unprivileged Install Script + - Add NEW Privileged/Unprivileged Install Script - **Ubuntu 21.10 LXC** - - Add NEW Unprivileged Install Script + - Add NEW Privileged/Unprivileged Install Script ## 2022-02-20 From 125e66df2f37b0ba0156a5a2cdce0d8ac9bcf505 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 07:56:21 -0500 Subject: [PATCH 1317/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 97c8ca53..9b3713aa 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,24 +7,24 @@ All notable changes to this project will be documented in this file. ### Changed - **Adguard Home LXC** - - Add NEW Privileged/Unprivileged Install Script + - Using NEW Privileged/Unprivileged Install Script ## 2022-02-22 ### Changed - **Home Assistant Container LXC** - - Add NEW Privileged/Unprivileged Install Script + - Using NEW Privileged/Unprivileged Install Script - **Node-Red LXC** - - Add NEW Privileged/Unprivileged Install Script + - Using NEW Privileged/Unprivileged Install Script - **Mariadb LXC** - - Add NEW Privileged/Unprivileged Install Script + - Using NEW Privileged/Unprivileged Install Script - **MQTT LXC** - - Add NEW Privileged/Unprivileged Install Script + - Using NEW Privileged/Unprivileged Install Script - **Debian 11 LXC** - - Add NEW Privileged/Unprivileged Install Script + - Using NEW Privileged/Unprivileged Install Script - **Ubuntu 21.10 LXC** - - Add NEW Privileged/Unprivileged Install Script + - Using NEW Privileged/Unprivileged Install Script ## 2022-02-20 From df3dab2dee6f837b47bb77d0917ec540b2a4e4b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:00:28 -0500 Subject: [PATCH 1318/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 5084c5e5..51b6375c 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -32,8 +32,8 @@ ${CL}" header_info show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + printf " ${YW} 1)${GN} Privileged ${CL}\n" +# printf " ${YW} 2)${RD} Unprivileged ${CL}\n" printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." read opt From 0d10f98edc066864e97699d8aabd1d3e0b48b111 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:38:01 -0500 Subject: [PATCH 1319/6505] Update debian.sh --- ct/debian.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index 5a6aa2f2..25334366 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -122,6 +122,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -130,7 +136,7 @@ export PCT_OSTYPE=debian export PCT_OSVERSION=11 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 + -features $FEATURES -hostname debian -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From 3e975df75229afa5abc39002ba70afb20c9293e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:39:02 -0500 Subject: [PATCH 1320/6505] Update adguard.sh --- ct/adguard.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index 93ea0211..376aa43b 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -122,6 +122,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -130,7 +136,7 @@ export PCT_OSTYPE=debian export PCT_OSVERSION=11 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" - -features nesting=1 + -features $FEATURES -hostname adguard -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From f53385c575cf8731271ee34a5f6075b1684eaa71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:40:05 -0500 Subject: [PATCH 1321/6505] Update homeassistant.sh --- ct/homeassistant.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index f6fbf8a6..12b85286 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -121,6 +121,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -129,7 +135,7 @@ export PCT_OSTYPE=debian export PCT_OSVERSION=11 export PCT_DISK_SIZE=8 export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 + -features $FEATURES -hostname homeassistant -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From 74974510396c5f03cee64d81c183ee3ae0f10bc9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:41:10 -0500 Subject: [PATCH 1322/6505] Update mariadb.sh --- ct/mariadb.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 6e258e68..d07c35ff 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -122,6 +122,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -130,7 +136,7 @@ export PCT_OSTYPE=debian export PCT_OSVERSION=11 export PCT_DISK_SIZE=4 export PCT_OPTIONS=" - -features nesting=1 + -features $FEATURES -hostname mariadb -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From 498cafd598f91faa1f6774ad69e4d1ae6b3dd821 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:42:22 -0500 Subject: [PATCH 1323/6505] Update mqtt.sh --- ct/mqtt.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 2664dffb..21d2fe3e 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -120,6 +120,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -128,7 +134,7 @@ export PCT_OSTYPE=debian export PCT_OSVERSION=11 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" - -features nesting=1 + -features $FEATURES -hostname mqtt -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From a6b58b0d3909c1a26a4e60ef6fe459f6dbd59dd2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:43:09 -0500 Subject: [PATCH 1324/6505] Update node-red.sh --- ct/node-red.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index 4ed8b967..1635fcf9 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -119,6 +119,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -127,7 +133,7 @@ export PCT_OSTYPE=debian export PCT_OSVERSION=11 export PCT_DISK_SIZE=4 export PCT_OPTIONS=" - -features nesting=1 + -features $FEATURES -hostname node-red -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From 0f4df566705c8f4a156bb757d27e3a4abcbbc253 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:44:05 -0500 Subject: [PATCH 1325/6505] Update ubuntu.sh --- ct/ubuntu.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index bed96ac1..ae48204c 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -122,6 +122,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -130,7 +136,7 @@ export PCT_OSTYPE=ubuntu export PCT_OSVERSION=21.10 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 + -features $FEATURES -hostname ubuntu -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From 0de17528eb8a337cc1e025723969174d67d0b516 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:44:59 -0500 Subject: [PATCH 1326/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 51b6375c..61af5e51 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -121,6 +121,12 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null @@ -129,7 +135,7 @@ export PCT_OSTYPE=debian export PCT_OSVERSION=11 export PCT_DISK_SIZE=4 export PCT_OPTIONS=" - -features nesting=1,keyctl=1,mknod=1 + -features $FEATURES -hostname zigbee2mqtt -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 From 2ea662a5ea2b922007b4047bfb4c4b6bd9e205c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:50:27 -0500 Subject: [PATCH 1327/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e3f97b0..bc4b2890 100644 --- a/README.md +++ b/README.md @@ -529,7 +529,7 @@ ________________________________________________________________________________ To create a new Proxmox Zigbee2MQTT LXC Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt.sh)" ```

⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

From bc6441778ff72205be12555e4aed0f508798fa6c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:52:05 -0500 Subject: [PATCH 1328/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9b3713aa..f082cf67 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Adguard Home LXC** - Using NEW Privileged/Unprivileged Install Script +- **Zigbee2MQTT LXC** + - Using NEW Privileged Install Script ## 2022-02-22 From 705a0fb14b75ddc906f01fc7c63d9241dac5e899 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 08:53:00 -0500 Subject: [PATCH 1329/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bc4b2890..3d6449d0 100644 --- a/README.md +++ b/README.md @@ -519,7 +519,7 @@ ________________________________________________________________________________
- Zigbee2MQTT LXC + 🔸Zigbee2MQTT LXC

logo.png

From 280638808f43b5f91dd052dd5bfb584fef406c95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 10:49:02 -0500 Subject: [PATCH 1330/6505] Update node-red-themes.sh --- misc/node-red-themes.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh index 82f030f9..8217f0bd 100644 --- a/misc/node-red-themes.sh +++ b/misc/node-red-themes.sh @@ -95,11 +95,6 @@ while [ $opt != '' ] esac fi done -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - echo -en "${GN} Installing ${THEME} Theme... " cd /root/.node-red if [ "${THEME}" = "" ]; then From e0e6f4b5baaf975cc31731214cf9eeb973f79fe4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:28:24 -0500 Subject: [PATCH 1331/6505] Update adguard-install.sh --- setup/adguard-install.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index c894db5d..0b411892 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash -set -e +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 383fb7f7e01d2b343f20360adc6dd12a8f0453a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:33:45 -0500 Subject: [PATCH 1332/6505] Update debian-install.sh --- setup/debian-install.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index fe9ef62a..795d7800 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash -set -e +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From b1c2dc599e710dabcef3a39c6a9549a145aaa7ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:34:30 -0500 Subject: [PATCH 1333/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 76713df6..fe171575 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash -set -e +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 6303e3e45fa9e7f453b44264c4bbb967ae51c769 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:34:58 -0500 Subject: [PATCH 1334/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index c9a18f8a..ba82d3b1 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash -set -e +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 4902ab8c464aa70637ed2edb2228d4bb58954664 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:35:21 -0500 Subject: [PATCH 1335/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 7f5e9e3e..8ed686a2 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash -set -e +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 50262cbf8b19ed080f2dad429dc9b658a37dc3cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:35:54 -0500 Subject: [PATCH 1336/6505] Update node-red-install.sh --- setup/node-red-install.sh | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index bce542ef..ab40fab4 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -1,5 +1,27 @@ #!/usr/bin/env bash -set -e + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From ce27bed12b7d6994d37fe420d33adf4340aaa0bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:36:23 -0500 Subject: [PATCH 1337/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 58674399..c2c89763 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash -set -e +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From ccd963b16b5d0e473596f19688ff4fa9f037e42f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 13:36:48 -0500 Subject: [PATCH 1338/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 4e3ba373..f36d52ef 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash -set -e +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From e52f5d9e6fe50562e8b50c88d7920cb57c00f6c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 14:05:56 -0500 Subject: [PATCH 1339/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index fe171575..a5618b05 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -279,7 +279,7 @@ done EOF sudo chmod +x /root/update-containers.sh echo -e "${CM}${CL} \r" - +mkdir /root/hass_config echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname From b1b3987882172855c935a1941fde661f788ab3ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 14:11:53 -0500 Subject: [PATCH 1340/6505] Update latest-update-menu.sh --- misc/latest-update-menu.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/misc/latest-update-menu.sh b/misc/latest-update-menu.sh index d6656c2b..8912ea3f 100644 --- a/misc/latest-update-menu.sh +++ b/misc/latest-update-menu.sh @@ -22,6 +22,11 @@ echo -e "\e[1;92m Installing runlike... \e[0m" pip3 install runlike &>/dev/null fi echo -e "\e[1;92m Creating Update Script... \e[0m" +if [ -f /root/hass_config ]; then +echo -e "\e[1;92m There's Already (hass_config) Folder! \e[0m" +else +mkdir /root/hass_config +fi UPDATE_PATH='/root/update' UPDATE_CONTAINERS_PATH='/root/update-containers.sh' cat >$UPDATE_PATH <<'EOF' From f78e5820bd325d957782379891044a909de854b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 14:14:26 -0500 Subject: [PATCH 1341/6505] Update latest-update-menu.sh --- misc/latest-update-menu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/latest-update-menu.sh b/misc/latest-update-menu.sh index 8912ea3f..75319e9d 100644 --- a/misc/latest-update-menu.sh +++ b/misc/latest-update-menu.sh @@ -22,7 +22,7 @@ echo -e "\e[1;92m Installing runlike... \e[0m" pip3 install runlike &>/dev/null fi echo -e "\e[1;92m Creating Update Script... \e[0m" -if [ -f /root/hass_config ]; then +if [ -d /root/hass_config/ ]; then echo -e "\e[1;92m There's Already (hass_config) Folder! \e[0m" else mkdir /root/hass_config From 0c4d50c124cf538424ad50259f93e0a9a040d6ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 14:18:20 -0500 Subject: [PATCH 1342/6505] Update latest-update-menu.sh --- misc/latest-update-menu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/latest-update-menu.sh b/misc/latest-update-menu.sh index 75319e9d..0c9ca4e8 100644 --- a/misc/latest-update-menu.sh +++ b/misc/latest-update-menu.sh @@ -22,7 +22,7 @@ echo -e "\e[1;92m Installing runlike... \e[0m" pip3 install runlike &>/dev/null fi echo -e "\e[1;92m Creating Update Script... \e[0m" -if [ -d /root/hass_config/ ]; then +if [ -d /root/hass_config ]; then echo -e "\e[1;92m There's Already (hass_config) Folder! \e[0m" else mkdir /root/hass_config From 8c3aa3a14e46cc4c2d2e42d1f98e4f5436b7a425 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 14:19:26 -0500 Subject: [PATCH 1343/6505] Update latest-update-menu.sh --- misc/latest-update-menu.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/latest-update-menu.sh b/misc/latest-update-menu.sh index 0c9ca4e8..8e67baea 100644 --- a/misc/latest-update-menu.sh +++ b/misc/latest-update-menu.sh @@ -196,4 +196,3 @@ done EOF sudo chmod +x /root/update-containers.sh echo -e "\e[1;92m Finished. Type ./update in the LXC console\e[0m" -exit From afeda12902f7b883f3ac25c46412529b9c2a8dd6 Mon Sep 17 00:00:00 2001 From: Garret Polderman <73959394+dailyenergy@users.noreply.github.com> Date: Wed, 23 Feb 2022 20:26:37 +0100 Subject: [PATCH 1344/6505] Small addition to the usb stick mounts I already had a zigbee controller stick at dev/ttyACM0. And was searching for an eternity to figure out, that I had Zwave stick in dev/ttyACM1 to add as an mountpoint in lxc config file --- ct/zwavejs2mqtt_container.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/zwavejs2mqtt_container.sh b/ct/zwavejs2mqtt_container.sh index 2e908b54..c944d824 100644 --- a/ct/zwavejs2mqtt_container.sh +++ b/ct/zwavejs2mqtt_container.sh @@ -154,6 +154,7 @@ lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF MOUNT=$(pct mount $CTID | cut -d"'" -f 2) From 110ba2779ba82f67dfcb825bae9de86645d41f3b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 15:04:24 -0500 Subject: [PATCH 1345/6505] Update latest-update-menu.sh --- misc/latest-update-menu.sh | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/misc/latest-update-menu.sh b/misc/latest-update-menu.sh index 8e67baea..2d23b5f7 100644 --- a/misc/latest-update-menu.sh +++ b/misc/latest-update-menu.sh @@ -97,7 +97,9 @@ while [ $opt != '' ] option_picked "Backing up Home Assistant Data to root (hass_config)"; rm -r hass_config; cp -pR /var/lib/docker/volumes/hass_config/ /root/; - exit; + sleep 2; + clear; + show_menu; ;; 5) while true; do read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn @@ -111,7 +113,9 @@ while [ $opt != '' ] option_picked "Restoring Home Assistant Data from root (hass_config)"; rm -r /var/lib/docker/volumes/hass_config/_data; cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - exit; + sleep 2; + clear; + show_menu; ;; 6) while true; do read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn @@ -124,7 +128,8 @@ while [ $opt != '' ] clear; option_picked "Editing Home Assistant Configuration"; nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - exit; + clear; + show_menu; ;; 7) clear; option_picked "Restarting Home Assistant"; @@ -134,17 +139,23 @@ while [ $opt != '' ] 8) clear; option_picked "Just Updating Containers"; ./update-containers.sh; - exit; + sleep 2; + clear; + show_menu; ;; 9) clear; option_picked "Removing Unused Images"; docker image prune -af; - exit; + sleep 2; + clear; + show_menu; ;; 10) clear; option_picked "Updating Host OS"; apt update && apt upgrade -y; - exit; + sleep 2; + clear; + show_menu; ;; 11) clear; option_picked "Reboot Host OS"; From 6f908a73031680e77ff9d886690c40f2e650444d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 15:13:33 -0500 Subject: [PATCH 1346/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f082cf67..30b336e6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file. - Using NEW Privileged/Unprivileged Install Script - **Zigbee2MQTT LXC** - Using NEW Privileged Install Script +- **Home Assistant Container LXC** + - Update Menu usability improvements ## 2022-02-22 From 0914b891fd331c4e72a3e182a8c4ab66ffbda93b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 15:48:56 -0500 Subject: [PATCH 1347/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index a5618b05..d7aa94b2 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -180,7 +180,9 @@ while [ $opt != '' ] option_picked "Backing up Home Assistant Data to root (hass_config)"; rm -r hass_config; cp -pR /var/lib/docker/volumes/hass_config/ /root/; - exit; + sleep 2; + clear; + show_menu; ;; 5) while true; do read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn @@ -194,7 +196,9 @@ while [ $opt != '' ] option_picked "Restoring Home Assistant Data from root (hass_config)"; rm -r /var/lib/docker/volumes/hass_config/_data; cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - exit; + sleep 2; + clear; + show_menu; ;; 6) while true; do read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn @@ -207,7 +211,8 @@ while [ $opt != '' ] clear; option_picked "Editing Home Assistant Configuration"; nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - exit; + clear; + show_menu; ;; 7) clear; option_picked "Restarting Home Assistant"; @@ -217,17 +222,23 @@ while [ $opt != '' ] 8) clear; option_picked "Just Updating Containers"; ./update-containers.sh; - exit; + sleep 2; + clear; + show_menu; ;; 9) clear; option_picked "Removing Unused Images"; docker image prune -af; - exit; + sleep 2; + clear; + show_menu; ;; 10) clear; option_picked "Updating Host OS"; apt update && apt upgrade -y; - exit; + sleep 2; + clear; + show_menu; ;; 11) clear; option_picked "Reboot Host OS"; From bd0c40d2cea412209058ab52ff8589b5670f7ed1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 15:50:03 -0500 Subject: [PATCH 1348/6505] Update ha_setup.sh --- setup/ha_setup.sh | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh index 343dfb08..a97b62e8 100644 --- a/setup/ha_setup.sh +++ b/setup/ha_setup.sh @@ -127,14 +127,12 @@ show_menu(){ printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" read opt } - option_picked(){ msgcolor=`echo "\033[01;31m"` normal=`echo "\033[00;00m"` message=${@:-"${normal}Error: No message passed"} printf "${msgcolor}${message}${normal}\n" } - clear show_menu while [ $opt != '' ] @@ -170,7 +168,9 @@ while [ $opt != '' ] option_picked "Backing up Home Assistant Data to root (hass_config)"; rm -r hass_config; cp -pR /var/lib/docker/volumes/hass_config/ /root/; - exit; + sleep 2; + clear; + show_menu; ;; 5) while true; do read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn @@ -184,7 +184,9 @@ while [ $opt != '' ] option_picked "Restoring Home Assistant Data from root (hass_config)"; rm -r /var/lib/docker/volumes/hass_config/_data; cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - exit; + sleep 2; + clear; + show_menu; ;; 6) while true; do read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn @@ -197,7 +199,8 @@ while [ $opt != '' ] clear; option_picked "Editing Home Assistant Configuration"; nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - exit; + clear; + show_menu; ;; 7) clear; option_picked "Restarting Home Assistant"; @@ -207,24 +210,29 @@ while [ $opt != '' ] 8) clear; option_picked "Just Updating Containers"; ./update-containers.sh; - exit; + sleep 2; + clear; + show_menu; ;; 9) clear; option_picked "Removing Unused Images"; docker image prune -af; - exit; + sleep 2; + clear; + show_menu; ;; 10) clear; option_picked "Updating Host OS"; apt update && apt upgrade -y; - exit; + sleep 2; + clear; + show_menu; ;; 11) clear; option_picked "Reboot Host OS"; reboot; exit; ;; - x)exit; ;; \n)exit; From bb4ba3eb9fbe43018bb5bd412d005d8bae8fcc71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 22:37:30 -0500 Subject: [PATCH 1349/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 61af5e51..44b90444 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -18,14 +18,15 @@ function header_info { echo -e "${YW} - _________ __ __ - |___ /__ \| \/ | - / / ) | \ / | - / / / /| |\/| | - / /__ / /_| | | | - /_____|____|_| |_| - - + _______ _ ___ __ __ ____ _______ _______ + |___ (_) | | |__ \| \/ |/ __ \__ __|__ __| + / / _ __ _| |__ ___ ___ ) | \ / | | | | | | | | + / / | |/ _ | _ \ / _ \/ _ \ / /| |\/| | | | | | | | | + / /__| | (_| | |_) | __/ __// /_| | | | |__| | | | | | + /_____|_|\__, |____/ \___|\___|____|_| |_|\___\_\ |_| |_| + __/ | + |___/ + ${CL}" } From 046b9d7512a4871a69eedc0d54bad7bf9a6bcc18 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 23:37:51 -0500 Subject: [PATCH 1350/6505] Create nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 169 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 ct/nginx-proxy-manager.sh diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh new file mode 100644 index 00000000..5d755682 --- /dev/null +++ b/ct/nginx-proxy-manager.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Nginx Proxy Manager LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + + + + _ _ _ _____ __ __ + | \ | | (_) | __ \ | \/ | + | \| | __ _ _ _ __ __ _| |__) | __ _____ ___ _| \ / | __ _ _ __ __ _ __ _ ___ _ __ + | |/ _ | | _ \\ \/ / ___/ __/ _ \ \/ / | | | |\/| |/ _ | _ \ / _ |/ _ |/ _ \ __| + | |\ | (_| | | | | |> <| | | | | (_) > <| |_| | | | | (_| | | | | (_| | (_| | __/ | + |_| \_|\__, |_|_| |_/_/\_\_| |_| \___/_/\_\\__, |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| + __/ | __/ | __/ | + |___/ |___/ |___/ + + + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=3 +export PCT_OPTIONS=" + -features $FEATURES + -hostname npm + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 1024 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/nginx-proxy-manager-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Nginx Proxy Manager LXC to${CL} ${BL}$CTID${CL}. +Nginx Proxy Manager should be reachable by going to the following URL. + ${BL}http://${IP}:81${CL} \n" From 98061508724af4600754ee5d94518ee0815a90c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 23:39:17 -0500 Subject: [PATCH 1351/6505] Create nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 241 +++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 setup/nginx-proxy-manager-install.sh diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh new file mode 100644 index 00000000..83cd2863 --- /dev/null +++ b/setup/nginx-proxy-manager-install.sh @@ -0,0 +1,241 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + sudo \ + curl \ + wget \ + gnupg \ + openssl \ + ca-certificates \ + apache2-utils \ + logrotate \ + build-essential \ + python3-dev \ + git \ + lsb-release &>/dev/null +echo -e "${CM}${CL} \r" + + echo -en "${GN} Installing Python... " + apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null + pip3 install --upgrade setuptools &>/dev/null + pip3 install --upgrade pip &>/dev/null + python3 -m venv /opt/certbot/ &>/dev/null + if [ "$(getconf LONG_BIT)" = "32" ]; then + python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null + fi + python3 -m pip install --no-cache-dir cffi certbot &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Openresty... " +wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null +codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null +echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null +apt-get -y update &>/dev/null +apt-get -y install --no-install-recommends openresty &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Yarn... " +npm install --global yarn &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Downloading NPM v2.9.16... " +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.16 -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-2.9.16 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Enviroment... " +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /usr/bin/certbot /opt/certbot/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx + +sed -i "s+0.0.0+#v2.9.16+g" backend/package.json +sed -i "s+0.0.0+#v2.9.16+g" frontend/package.json + +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done + +mkdir -p /var/www/html /etc/nginx/logs +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf + +mkdir -p /tmp/nginx/body \ +/run/nginx \ +/data/nginx \ +/data/custom_ssl \ +/data/logs \ +/data/access \ +/data/nginx/default_host \ +/data/nginx/default_www \ +/data/nginx/proxy_host \ +/data/nginx/redirection_host \ +/data/nginx/stream \ +/data/nginx/dead_host \ +/data/nginx/temp \ +/var/lib/nginx/cache/public \ +/var/lib/nginx/cache/private \ +/var/cache/nginx/proxy_temp + +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx + +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf +echo -e "${CM}${CL} \r" +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -en "${GN} Generating dummy SSL Certificate... " + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi + +mkdir -p /app/global /app/frontend/images +cp -r backend/* /app +cp -r global/* /app/global +echo -e "${CM}${CL} \r" + +echo -en "${GN} Building Frontend... " +cd ./frontend +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +yarn build &>/dev/null +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images +echo -e "${CM}${CL} \r" + +echo -en "${GN} Initializing Backend... " +rm -rf /app/config/default.json &>/dev/null +if [ ! -f /app/config/production.json ]; then +cat << 'EOF' > /app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF +fi +cd /app +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating NPM Service... " +cat << 'EOF' > /lib/systemd/system/npm.service +[Unit] +Description=Nginx Proxy Manager +After=network.target +Wants=openresty.service + +[Service] +Type=simple +Environment=NODE_ENV=production +ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge +ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 +WorkingDirectory=/app +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Services... " +systemctl enable npm &>/dev/null +systemctl start openresty +systemctl start npm +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From eb1cfd8ebdc7443be7c5ce29ed75bdbae36a08a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 23:40:02 -0500 Subject: [PATCH 1352/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index 5d755682..8c00049e 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -160,7 +160,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/nginx-proxy-manager-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nginx-proxy-manager-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 80abb34358516e2a736def5803a3f331be57a24d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 23:41:48 -0500 Subject: [PATCH 1353/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d6449d0..05e84f8e 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,7 @@ ________________________________________________________________________________ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. ```yaml - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/npm_container.sh)" + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/nginx-proxy-manager.sh)" ```

⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

From 14beed969ad1d59ae299eaa7f517aa17371089c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Feb 2022 23:43:06 -0500 Subject: [PATCH 1354/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 30b336e6..9db99381 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-24 + +### Changed + +- **Nginx Proxy Manager LXC** + - Using NEW Privileged/Unprivileged Install Script + ## 2022-02-23 ### Changed From ef1c7a0369aea1516b08c61267ec3d4524debf46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:26:11 -0500 Subject: [PATCH 1355/6505] Update adguard.sh --- ct/adguard.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index 376aa43b..baf27373 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -17,8 +17,6 @@ done clear function header_info { echo -e "${GN} - - _ _ /\ | | | | / \ __| | __ _ _ _ __ _ _ __ __| | @@ -27,7 +25,6 @@ echo -e "${GN} /_/ \_\__,_|\__, |\__,_|\__,_|_| \__,_| __/ | |___/ - ${CL}" } From 8e5286ae9ac5ddbd6aee607c9e64bd74af52b164 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:27:03 -0500 Subject: [PATCH 1356/6505] Update debian.sh --- ct/debian.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index 25334366..a60bd857 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -16,17 +16,12 @@ done clear function header_info { echo -e "${RD} - - - _____ _ _ | __ \ | | (_) | | | | ___| |__ _ __ _ _ __ | | | |/ _ \ _ \| |/ _ | _ \ | |__| | __/ |_) | | (_| | | | | |_____/ \___|_.__/|_|\__,_|_| |_| - - ${CL}" } From fbfc56989de6efdbca6553de81767d3808ff0b53 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:27:49 -0500 Subject: [PATCH 1357/6505] Update homeassistant.sh --- ct/homeassistant.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 12b85286..f84d8163 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -16,16 +16,12 @@ done clear function header_info { echo -e "${BL} - _ _ _ _ _ | | | | /\ (_) | | | | | |__| | ___ _ __ ___ ___ / \ ___ ___ _ ___| |_ __ _ _ __ | |_ | __ |/ _ \| _ _ \ / _ \ / /\ \ / __/ __| / __| __/ _ | _ \| __| | | | | (_) | | | | | | __/ / ____ \\__ \__ \ \__ \ || (_| | | | | |_ |_| |_|\___/|_| |_| |_|\___| /_/ \_\___/___/_|___/\__\__,_|_| |_|\__| - - - ${CL}" } From f2bf138bf1d86de9db4d662073837c86a2cb2942 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:28:36 -0500 Subject: [PATCH 1358/6505] Update mariadb.sh --- ct/mariadb.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index d07c35ff..72c13d74 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -16,17 +16,12 @@ done clear function header_info { echo -e "${BL} - __ __ _ _ _ | \/ | (_) | | | | \ / | __ _ _ __ _ __ _ __| | |__ | |\/| |/ _ | __| |/ _ |/ _ | _ \ | | | | (_| | | | | (_| | (_| | |_) | |_| |_|\__,_|_| |_|\__,_|\__,_|_.__/ - - - - ${CL}" } From a1aeabd5f1526a9816fe5ad5fc4adbc3494ab916 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:29:23 -0500 Subject: [PATCH 1359/6505] Update mqtt.sh --- ct/mqtt.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 21d2fe3e..18661d83 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -16,15 +16,12 @@ done clear function header_info { echo -e "${BL} - - __ __ ____ _______ _______ | \/ |/ __ \__ __|__ __| | \ / | | | | | | | | | |\/| | | | | | | | | | | | | |__| | | | | | |_| |_|\___\_\ |_| |_| - ${CL}" } From b79f8a37b1191e9b47c74973242f0dab002aabf3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:30:39 -0500 Subject: [PATCH 1360/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index 8c00049e..db9402de 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -16,10 +16,6 @@ done clear function header_info { echo -e "${RD} - - - - _ _ _ _____ __ __ | \ | | (_) | __ \ | \/ | | \| | __ _ _ _ __ __ _| |__) | __ _____ ___ _| \ / | __ _ _ __ __ _ __ _ ___ _ __ @@ -29,8 +25,6 @@ echo -e "${RD} __/ | __/ | __/ | |___/ |___/ |___/ - - ${CL}" } From f48c800b6770d809256b0202a3ec91c5dab3e85a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:31:32 -0500 Subject: [PATCH 1361/6505] Update node-red.sh --- ct/node-red.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index 1635fcf9..aeb0574a 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -16,7 +16,6 @@ done clear function header_info { echo -e "${RD} - _ _ _ _____ _ | \ | | | | | __ \ | | | \| | ___ __| | ___ ______| |__) |___ __| | @@ -24,7 +23,6 @@ echo -e "${RD} | |\ | (_) | (_| | __/ | | \ \ __/ (_| | |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| - ${CL}" } From ff7559def03a5daeb8c6270112d4c6d023ff9bac Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:32:24 -0500 Subject: [PATCH 1362/6505] Update ubuntu.sh --- ct/ubuntu.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index ae48204c..010b9738 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -16,17 +16,12 @@ done clear function header_info { echo -e "${YW} - - - - _ _ _ _ | | | | | | | | | | | |__ _ _ _ __ | |_ _ _ | | | | _ \| | | | _ \| __| | | | | |__| | |_) | |_| | | | | |_| |_| | \____/|_.__/ \__,_|_| |_|\__|\__,_| - ${CL}" } From a29eb08216aa6035e96c55cbbadd1c873a0d0bdb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:33:05 -0500 Subject: [PATCH 1363/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 44b90444..65013d29 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -16,8 +16,6 @@ done clear function header_info { echo -e "${YW} - - _______ _ ___ __ __ ____ _______ _______ |___ (_) | | |__ \| \/ |/ __ \__ __|__ __| / / _ __ _| |__ ___ ___ ) | \ / | | | | | | | | @@ -26,7 +24,6 @@ echo -e "${YW} /_____|_|\__, |____/ \___|\___|____|_| |_|\___\_\ |_| |_| __/ | |___/ - ${CL}" } From 31897b7af60c840f61e65c6d69a402d1ee8f478e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:42:36 -0500 Subject: [PATCH 1364/6505] Update esphome_container.sh --- ct/esphome_container.sh | 46 ++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/ct/esphome_container.sh b/ct/esphome_container.sh index 4188ab73..902c9969 100644 --- a/ct/esphome_container.sh +++ b/ct/esphome_container.sh @@ -1,5 +1,12 @@ #!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` + while true; do read -p "This will create a New ESPHome LXC Container. Proceed(y/n)?" yn case $yn in @@ -8,6 +15,20 @@ while true; do * ) echo "Please answer yes or no.";; esac done +clear +function header_info { +echo -e "${CL} + ______ _____ _____ _ _ ____ __ __ ______ + | ____|/ ____| __ \| | | |/ __ \| \/ | ____| + | |__ | (___ | |__) | |__| | | | | \ / | |__ + | __| \___ \| ___/| __ | | | | |\/| | __| + | |____ ____) | | | | | | |__| | | | | |____ + |______|_____/|_| |_| |_|\____/|_| |_|______| + +${CL}" +} + +header_info set -o errexit set -o errtrace @@ -101,15 +122,16 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -info "Using '$STORAGE' for storage location." +info "Using ${BL}$STORAGE${CL} for storage location." CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." +info "Container ID is ${BL}$CTID.${CL}" -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +echo -en "${GN} Updating LXC Template List... " pveam update >/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +echo -en "${GN} Downloading LXC Template... " OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -130,8 +152,9 @@ case $STORAGE_TYPE in esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +echo -en "${GN} Creating LXC Container... " DISK_SIZE=4G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then @@ -149,14 +172,17 @@ pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +echo -en "${GN} Starting LXC Container... " pct start $CTID pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 +echo -e "${CM}${CL} \r" pct exec $CTID /esphome_setup.sh + IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created ESPHome LXC Container to $CTID" -echo -e "\e[1;92m ESPHome should be reachable by going to the following URL. - http://${IP}:6052 -\e[0m" +info "Successfully created ESPHome LXC Container to ${BL}$CTID${CL}" +echo -e "${CL} ESPHome should be reachable by going to the following URL. + ${BL}http://${IP}:6052${CL} +\n" From f547d808f6d43020f2573b443f7c84abf8b46088 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 12:44:01 -0500 Subject: [PATCH 1365/6505] Update esphome_setup.sh --- setup/esphome_setup.sh | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh index d62a6e2e..001730f0 100644 --- a/setup/esphome_setup.sh +++ b/setup/esphome_setup.sh @@ -7,7 +7,12 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` RETRY_NUM=5 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -27,38 +32,42 @@ function msg() { echo -e "$TEXT" } -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +echo -en "${GN} Setting up Container OS... " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" +echo -en "${GN} Updating Container OS... " apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +echo -en "${GN} Installing Dependencies... " apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing pip3... \e[0m" +echo -en "${GN} Installing pip3... " apt-get install python3-pip -y &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing ESPHome... \e[0m" +echo -en "${GN} Installing ESPHome... " pip3 install esphome &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing ESPHome Dashboard... \e[0m" +echo -en "${GN} Installing ESPHome Dashboard... " pip3 install tornado esptool &>/dev/null service_path="/etc/systemd/system/esphomeDashboard.service" @@ -72,8 +81,9 @@ User=root [Install] WantedBy=multi-user.target" > $service_path systemctl enable esphomeDashboard.service &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" +echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -87,5 +97,8 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') systemctl start esphomeDashboard -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \r" From a8926503e293ff518a55b4d37cfd02e5c98541fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 13:04:15 -0500 Subject: [PATCH 1366/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 563f88f8..577146b3 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -71,7 +71,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null +podman pull ghcr.io/home-assistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From c3cf4911223cd3cc04409b7dc2a9d3398faf5c28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 13:04:53 -0500 Subject: [PATCH 1367/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index 161caabf..03acdb78 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -8,7 +8,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done - +clear set -o errexit set -o errtrace set -o nounset From 7ef00c687dec8a82d14bea836c6a88d74223652d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 13:39:02 -0500 Subject: [PATCH 1368/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 577146b3..2adb4581 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -63,6 +63,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Yacht... \e[0m" podman volume create yacht >/dev/null podman run -d \ --name yacht \ + --restart always \ -v /var/run/podman/podman.sock:/var/run/docker.sock \ -v yacht:/config \ -v /etc/localtime:/etc/localtime:ro \ From 6dd717923c877564dfd0134ebe62d465717de812 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 13:55:34 -0500 Subject: [PATCH 1369/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 2adb4581..d3fef405 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -72,7 +72,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull ghcr.io/home-assistant/home-assistant:stable &>/dev/null +podman pull docker.io/home-assistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From 4594b790739950877039cbed8cba5f809c3e5a91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 14:15:13 -0500 Subject: [PATCH 1370/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index d3fef405..18382acb 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -57,7 +57,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" apt-get -y install podman &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Yacht Image...\e[0m" -podman pull ghcr.io/selfhostedpro/yacht:latest &>/dev/null +podman pull selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Yacht... \e[0m" podman volume create yacht >/dev/null @@ -72,7 +72,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.io/home-assistant/home-assistant:stable &>/dev/null +podman pull home-assistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From 1f3abcbf0de850879dc4fc00efa932bb927c7482 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 14:23:39 -0500 Subject: [PATCH 1371/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 18382acb..18d5dba5 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -57,7 +57,7 @@ echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" apt-get -y install podman &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Yacht Image...\e[0m" -podman pull selfhostedpro/yacht:latest &>/dev/null +podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Yacht... \e[0m" podman volume create yacht >/dev/null @@ -72,7 +72,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull home-assistant/home-assistant:stable &>/dev/null +podman pull docker.lo/home-assistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From 782be3ee5d39143b439fc079e3d7c4b7bf57a7ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 14:39:17 -0500 Subject: [PATCH 1372/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 18d5dba5..029061e8 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -72,7 +72,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.lo/home-assistant/home-assistant:stable &>/dev/null +podman pull docker.lo/home-assistant/home-assistant:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From db30eb9b3f0bd1cf5b57ae7408107297d70621de Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 15:29:18 -0500 Subject: [PATCH 1373/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 029061e8..641062a4 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -72,7 +72,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.lo/home-assistant/home-assistant:latest &>/dev/null +podman pull docker.io/home-assistant/home-assistant:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From 25b8de467bb1a57d73411857a206c1fe220c12f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 15:54:30 -0500 Subject: [PATCH 1374/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 641062a4..2d780292 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -72,7 +72,7 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -podman pull docker.io/home-assistant/home-assistant:latest &>/dev/null +podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" podman volume create hass_config >/dev/null From 0738894e8a068c751e0fdf3777c53bfea6053ee0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 16:06:34 -0500 Subject: [PATCH 1375/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 2d780292..419252f5 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -123,10 +123,16 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + podman generate systemd \ --new --name homeassistant \ > /etc/systemd/system/homeassistant.service systemctl enable homeassistant &>/dev/null +podman generate systemd \ + --new --name yacht \ + > /etc/systemd/system/yacht.service +systemctl enable yacht &>/dev/null + echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From e5dc3226482f97827a7730a1f03cac3e7bddb92d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 17:04:49 -0500 Subject: [PATCH 1376/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 65 +++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index 03acdb78..56447d87 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -1,5 +1,10 @@ #!/usr/bin/env bash - +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` while true; do read -p "This will create a New Podman Home Assistant Container LXC. Proceed(y/n)?" yn case $yn in @@ -9,16 +14,31 @@ while true; do esac done clear +function header_info { +echo -e "${BL} + _____ _ + | __ \ | | + | |__) |__ __| |_ __ ___ __ _ _ __ + | ___/ _ \ / _ | _ _ \ / _ | _ \ + | | | (_) | (_| | | | | | | (_| | | | | + |_| \___/ \__,_|_| |_| |_|\__,_|_| |_| _ _ _ + | | (_) | | | | + | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ + | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| + +${CL}" +} +header_info set -o errexit set -o errtrace set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' trap die ERR trap cleanup EXIT - function error_exit() { trap - ERR local DEFAULT='Unknown failure occured.' @@ -105,9 +125,11 @@ info "Using '$STORAGE' for storage location." CTID=$(pvesh get /cluster/nextid) info "Container ID is $CTID." -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" +echo -en "${GN} Updating LXC Template List... " pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" +echo -e "${CM}${CL} \r" + +echo -en "${GN} Downloading LXC Template... " OSTYPE=debian OSVERSION=${OSTYPE}-11 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) @@ -128,24 +150,20 @@ case $STORAGE_TYPE in esac DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating LXC Container... " DISK_SIZE=8G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." else mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null fi ARCH=$(dpkg --print-architecture) -HOSTNAME=homeassistant +HOSTNAME=p-homeassistant TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -if [ "$STORAGE_TYPE" == "zfspool" ]; then - CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" -else - CT_FEATURES="nesting=1" -fi -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ +pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null LXC_CONFIG=/etc/pve/lxc/${CTID}.conf @@ -153,24 +171,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF - MOUNT=$(pct mount $CTID | cut -d"'" -f 2) ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" +echo -e "${CM}${CL} \r" +echo -en "${GN} Starting LXC Container... " pct start $CTID -if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -info "Using fuse-overlayfs." -fi pct push $CTID podman_ha_setup.sh /podman_ha_setup.sh -perms 755 +echo -e "${CM}${CL} \r" pct exec $CTID /podman_ha_setup.sh IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Podman Home Assistant Container LXC to $CTID." -echo -e "\e[1;92m Home Assistant Container should be reachable by going to the following URL. - http://${IP}:8123 +info "Successfully Created Podman Home Assistant Container LXC to ${BL}$CTID${CL}." +echo -e "${CL} Home Assistant Container should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} Yacht should be reachable by going to the following URL. - http://${IP}:8000 -\e[0m" + ${BL}http://${IP}:8000${CL} \n" From 339c79a0f675b5679cdd698db324feb10a740b8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 17:06:14 -0500 Subject: [PATCH 1377/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 65 +++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 419252f5..ebafa0df 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -1,16 +1,11 @@ #!/usr/bin/env bash -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM trap die ERR trap 'die "Script interrupted."' INT @@ -27,39 +22,55 @@ function msg() { echo -e "$TEXT" } -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" +echo -en "${GN} Installing Dependencies... " apt-get update &>/dev/null apt-get -qqy install \ curl \ sudo \ runc &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing Podman... \e[0m" +echo -en "${GN} Installing Podman... " apt-get -y install podman &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Pulling Yacht Image...\e[0m" +echo -en "${GN} Pulling Yacht Image... " podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing Yacht... \e[0m" +echo -en "${GN} Installing Yacht... " podman volume create yacht >/dev/null podman run -d \ --name yacht \ @@ -70,11 +81,13 @@ podman run -d \ -v /etc/timezone:/etc/timezone:ro \ -p 8000:8000 \ selfhostedpro/yacht:latest &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" +echo -en "${GN} Pulling Home Assistant Image... " podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" +echo -en "${GN} Installing Home Assistant... " podman volume create hass_config >/dev/null podman run -d \ --name homeassistant \ @@ -85,8 +98,9 @@ podman run -d \ -v /etc/timezone:/etc/timezone:ro \ --net=host \ homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Creating Update Script... \e[0m" +echo -en "${GN} Creating Update Script... " file_path="/root/update.sh" echo "#!/bin/bash echo -e '\e[1;33m Pulling New Stable Version... \e[0m' @@ -109,8 +123,9 @@ echo -e '\e[1;33m Removing Old Image... \e[0m' podman image prune -f echo -e '\e[1;33m Finished Update! \e[0m'" > $file_path sudo chmod +x /root/update.sh +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" +echo -en "${GN} Customizing LXC... " rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -133,6 +148,8 @@ podman generate systemd \ --new --name yacht \ > /etc/systemd/system/yacht.service systemctl enable yacht &>/dev/null +echo -e "${CM}${CL} \r" -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" +echo -en "${GN} Cleanup... " rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 828e83b07ecc86c7effb06dc96230f368e732112 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 17:09:29 -0500 Subject: [PATCH 1378/6505] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 05e84f8e..ef6908a4 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,6 @@ ________________________________________________________________________________ @home-assistant

Podman Home Assistant Container LXC

-

With ZFS Filesystem Support

To create a new Proxmox Podman Home Assistant Container, run the following in the Proxmox Shell. ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) From 19db8e803600162a973c89b1c5990683fa29f3a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Feb 2022 17:24:46 -0500 Subject: [PATCH 1379/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index 56447d87..65d500d3 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -121,10 +121,10 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -info "Using '$STORAGE' for storage location." +info "Using ${BL}$STORAGE${CL} for storage location." CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." +info "Container ID is ${BL}$CTID${CL}" echo -en "${GN} Updating LXC Template List... " pveam update >/dev/null echo -e "${CM}${CL} \r" From a61581a015577f7dce4bb05c578dcd8e35151694 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Feb 2022 07:36:25 -0500 Subject: [PATCH 1380/6505] Update homeassistant.sh --- ct/homeassistant.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index f84d8163..eb184bc7 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -16,12 +16,12 @@ done clear function header_info { echo -e "${BL} - _ _ _ _ _ - | | | | /\ (_) | | | | - | |__| | ___ _ __ ___ ___ / \ ___ ___ _ ___| |_ __ _ _ __ | |_ - | __ |/ _ \| _ _ \ / _ \ / /\ \ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ / ____ \\__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___| /_/ \_\___/___/_|___/\__\__,_|_| |_|\__| + _ _ _ _ + | | (_) | | | | + | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ + | '_ \ / _ \| '_ ` _ \ / _ \/ _` / __/ __| / __| __/ _` | '_ \| __| + | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| ${CL}" } From d34e88c46e6255d54ccc14b0d74490ca177b849b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Feb 2022 07:37:13 -0500 Subject: [PATCH 1381/6505] Update homeassistant.sh --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index eb184bc7..27796f79 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -19,7 +19,7 @@ echo -e "${BL} _ _ _ _ | | (_) | | | | | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ - | '_ \ / _ \| '_ ` _ \ / _ \/ _` / __/ __| / __| __/ _` | '_ \| __| + | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| From 1d2515e9cb747e20f1d87ac45bacc83d976baad1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Feb 2022 07:43:53 -0500 Subject: [PATCH 1382/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index db9402de..d6decb7f 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -16,14 +16,14 @@ done clear function header_info { echo -e "${RD} - _ _ _ _____ __ __ - | \ | | (_) | __ \ | \/ | - | \| | __ _ _ _ __ __ _| |__) | __ _____ ___ _| \ / | __ _ _ __ __ _ __ _ ___ _ __ - | |/ _ | | _ \\ \/ / ___/ __/ _ \ \/ / | | | |\/| |/ _ | _ \ / _ |/ _ |/ _ \ __| - | |\ | (_| | | | | |> <| | | | | (_) > <| |_| | | | | (_| | | | | (_| | (_| | __/ | - |_| \_|\__, |_|_| |_/_/\_\_| |_| \___/_/\_\\__, |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| - __/ | __/ | __/ | - |___/ |___/ |___/ + _ + (_) + _ __ __ _ _ _ __ __ ___ __ _ __ _____ ___ _ _ __ ___ __ _ _ __ __ _ __ _ ___ _ __ + | _ \ / _ | | _ \\ \/ / _ \| __/ _ \ \/ / | | | _ _ \ / _ | _ \ / _ |/ _ |/ _ \ __| + | | | | (_| | | | | |> <| |_) | | | (_) > <| |_| | | | | | | (_| | | | | (_| | (_| | __/ | + |_| |_|\__, |_|_| |_/_/\_\ .__/|_| \___/_/\_\\__, |_| |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| + __/ | | | __/ | __/ | + |___/ |_| |___/ |___/ ${CL}" } From f9ddc4c1f2adc7cee127a88c05187b1571114c74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Feb 2022 07:49:16 -0500 Subject: [PATCH 1383/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index d6decb7f..d62b23c4 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -16,14 +16,14 @@ done clear function header_info { echo -e "${RD} - _ - (_) - _ __ __ _ _ _ __ __ ___ __ _ __ _____ ___ _ _ __ ___ __ _ _ __ __ _ __ _ ___ _ __ - | _ \ / _ | | _ \\ \/ / _ \| __/ _ \ \/ / | | | _ _ \ / _ | _ \ / _ |/ _ |/ _ \ __| - | | | | (_| | | | | |> <| |_) | | | (_) > <| |_| | | | | | | (_| | | | | (_| | (_| | __/ | - |_| |_|\__, |_|_| |_/_/\_\ .__/|_| \___/_/\_\\__, |_| |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| - __/ | | | __/ | __/ | - |___/ |_| |___/ |___/ + _ _ _ _____ __ __ + | \ | | (_) | __ \ | \/ | + | \| | __ _ _ _ __ __ __ | |__) | __ _____ ___ _ | \ / | __ _ _ __ __ _ __ _ ___ _ __ + | |/ _ | | _ \\ \/ / | ___/ __/ _ \ \/ / | | | | |\/| |/ _ | _ \ / _ |/ _ |/ _ \ __| + | |\ | (_| | | | | |> < | | | | | (_) > <| |_| | | | | | (_| | | | | (_| | (_| | __/ | + |_| \_|\__, |_|_| |_/_/\_\ |_| |_| \___/_/\_\\__, | |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| + __/ | __/ | __/ | + |___/ |___/ |___/ ${CL}" } From 72900b3f715ccebe19f76b57c9a9b9bfce9576dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Feb 2022 01:38:12 -0500 Subject: [PATCH 1384/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ef6908a4..330a76df 100644 --- a/README.md +++ b/README.md @@ -905,7 +905,7 @@ ________________________________________________________________________________
- 🔸Vaultwarden LXC + Vaultwarden LXC

From 57fb9b1d4affc8ff3fe73d3d5545a342bf69b8eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Feb 2022 10:42:15 -0500 Subject: [PATCH 1385/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 330a76df..903ad923 100644 --- a/README.md +++ b/README.md @@ -827,7 +827,7 @@ ________________________________________________________________________________
MotionEye NVR LXC -

+

MotionEye NVR LXC

From dbc8c49fef946b2f4ae20c0b7a76db6d3b2edce9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Feb 2022 10:58:07 -0500 Subject: [PATCH 1386/6505] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 903ad923..3b29ad72 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@
Proxmox VE 7 Post Install -

Proxmox Server Solutions

+

Proxmox VE 7 Post Install

@@ -235,7 +235,7 @@ ________________________________________________________________________________
ESPHome LXC -

Logo

+

ESPHome LXC Container

@@ -600,7 +600,7 @@ ________________________________________________________________________________
Zwavejs2MQTT LXC -

+

Zwavejs2MQTT LXC Container

@@ -705,7 +705,7 @@ ________________________________________________________________________________
Plex Media Server LXC -

+

Plex Media Server LXC

With Hardware Acceleration Support

@@ -739,7 +739,7 @@ ________________________________________________________________________________
Jellyfin Media Server LXC -

+

Jellyfin Media Server LXC

To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. @@ -766,7 +766,7 @@ ________________________________________________________________________________
Pi-hole LXC -

Pi-hole

+

Pi-hole LXC

@@ -799,7 +799,7 @@ ________________________________________________________________________________
🔸AdGuard Home LXC -

+

AdGuard Home LXC

From 0f110d2d2a0923626711bef5af0120a9bb3e7dff Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Feb 2022 11:04:01 -0500 Subject: [PATCH 1387/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b29ad72..a3abfffc 100644 --- a/README.md +++ b/README.md @@ -366,7 +366,7 @@ ________________________________________________________________________________
🔸Node-Red LXC -

@node-red

+

Node-Red LXC Container

From b526b9a3f804d3c97b76f80803ec4bb6b97848ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Feb 2022 19:31:43 -0500 Subject: [PATCH 1388/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a3abfffc..c9f15a24 100644 --- a/README.md +++ b/README.md @@ -849,7 +849,7 @@ After the script completes, If you're dissatisfied with the default settings, cl `admin` **password** - `Leave Blank` + ⚙️ **To Update MotionEye** From 7b364dade1605e90a07384887854f74fdb1d8403 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Feb 2022 09:33:42 -0500 Subject: [PATCH 1389/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9f15a24..3a2034c0 100644 --- a/README.md +++ b/README.md @@ -916,7 +916,7 @@ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vault_container.sh)" ``` -Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. +⚠️Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. From 8de61f65e0e612a51653027d2535f0819a3ad3e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Feb 2022 16:40:31 -0500 Subject: [PATCH 1390/6505] Update vault_container.sh --- ct/vault_container.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/ct/vault_container.sh b/ct/vault_container.sh index 6ab85226..56b5ac3b 100644 --- a/ct/vault_container.sh +++ b/ct/vault_container.sh @@ -1,5 +1,10 @@ #!/usr/bin/env bash - +CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` while true; do read -p "This will create a New Vaultwarden LXC Container. Proceed(y/n)?" yn case $yn in @@ -9,18 +14,25 @@ while true; do esac done clear +function header_info { +echo -e "${BL} + __ __ _ _ _ + \ \ / / | | | | | + \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ + \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ + \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | + \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| + +${CL}" +} + +header_info set -o errexit set -o errtrace set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` trap die ERR trap cleanup EXIT From 416dd27e47c6481b3caa8a2f9c19fddcab37eaa7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 05:56:20 -0500 Subject: [PATCH 1391/6505] Create vaultwarden-update.sh --- misc/vaultwarden-update.sh | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 misc/vaultwarden-update.sh diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh new file mode 100644 index 00000000..02697a4e --- /dev/null +++ b/misc/vaultwarden-update.sh @@ -0,0 +1,52 @@ +#!/bin/sh +VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ + +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +function update_info { +echo -e "${BL} + __ __ _ _ _ + \ \ / / | | | | | + \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ + \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ + \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | + \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| + UPDATE +${CL}" +} + +update_info +while true; do + read -p "This will Update Vaultwarden to $VWRELEASE. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +update_info + +echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" +wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null +tar -xzf bw_web_$VWRELEASE.tar.gz &>/dev/null +cp -R web-vault /var/lib/vaultwarden/ &>/dev/null + +echo -e "${GN} Cleanup... ${CL}" +rm -r bw_web_$VWRELEASE.tar.gz web-vault +sleep 2 +echo -e "${GN} Finished Update, Please Reboot Vaultwarden ${CL}" +while true; do + read -p "Reboot Now? (y/n)" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +reboot From 94a81b2b731dbf132742d825f461e6710068c3e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 06:02:11 -0500 Subject: [PATCH 1392/6505] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 3a2034c0..8860d43d 100644 --- a/README.md +++ b/README.md @@ -927,6 +927,13 @@ Expect 30+ minute install time. **Vaultwarden Interface - IP:8000** +⚙️ **To Update Vaultwarden** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/vaultwarden-update.sh)" +``` + ____________________________________________________________________________________________
From 8945d6f5897e7c2170e3b345eb316cd946d7b4ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 06:09:02 -0500 Subject: [PATCH 1393/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9db99381..439571ed 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-02-28 + +### Changed + +- **Vaultwarden LXC** + - Add Update Script + ## 2022-02-24 ### Changed From be5b8d597c25fd788d8fa4c5ffcdb17363cc664a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 06:09:32 -0500 Subject: [PATCH 1394/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8860d43d..65e59b2d 100644 --- a/README.md +++ b/README.md @@ -905,7 +905,7 @@ ________________________________________________________________________________
- Vaultwarden LXC + 🔸Vaultwarden LXC

From d017b5ccdb19366eebd5d35e2612d7ac1928726e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 10:06:48 -0500 Subject: [PATCH 1395/6505] Update vaultwarden-update.sh --- misc/vaultwarden-update.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 02697a4e..1315d6ea 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -31,6 +31,8 @@ while true; do done clear update_info +echo -e "${GN} Stopping Vaultwarden... ${CL}" +systemctl stop vaultwarden.service echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null @@ -40,13 +42,8 @@ cp -R web-vault /var/lib/vaultwarden/ &>/dev/null echo -e "${GN} Cleanup... ${CL}" rm -r bw_web_$VWRELEASE.tar.gz web-vault sleep 2 -echo -e "${GN} Finished Update, Please Reboot Vaultwarden ${CL}" -while true; do - read -p "Reboot Now? (y/n)" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -reboot + +echo -e "${GN} Starting Vaultwarden... ${CL}" +systemctl start vaultwarden.service +sleep 1 +echo -e "${GN} Finished Update ${CL}" From a823c84006c41d0e3950af25fc2ef98e4a60f43e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 10:07:57 -0500 Subject: [PATCH 1396/6505] Update vaultwarden-update.sh --- misc/vaultwarden-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 1315d6ea..c6d61282 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -33,6 +33,7 @@ clear update_info echo -e "${GN} Stopping Vaultwarden... ${CL}" systemctl stop vaultwarden.service +sleep 1 echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null From 7cf689b19aad3fecc34c8e294353119e8aaa7867 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 16:49:04 -0500 Subject: [PATCH 1397/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 83cd2863..b194c53f 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -102,9 +102,13 @@ echo -en "${GN} Installing Yarn... " npm install --global yarn &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Downloading NPM v2.9.16... " -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.16 -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-2.9.16 +RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') \ + +echo -en "${GN} Downloading NPM v${RELEASE}... " +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-${RELEASE} echo -e "${CM}${CL} \r" echo -en "${GN} Setting up Enviroment... " @@ -113,8 +117,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+#v2.9.16+g" backend/package.json -sed -i "s+0.0.0+#v2.9.16+g" frontend/package.json +sed -i "s+0.0.0+${RELEASE}+g" backend/package.json +sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") From ffe90345366b3001c03f5b6b9ddfeaaebab43727 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 19:36:26 -0500 Subject: [PATCH 1398/6505] Update npm_update.sh --- misc/npm_update.sh | 54 ++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/misc/npm_update.sh b/misc/npm_update.sh index 8570f566..4289e892 100644 --- a/misc/npm_update.sh +++ b/misc/npm_update.sh @@ -1,6 +1,30 @@ #!/usr/bin/env bash +RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') \ + +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` + +function update_info { +echo -e "${RD} + _ _ _____ __ __ + | \ | | | __ \ | \/ | + | \| | | |__) | | \ / | + | | | ___/ | |\/| | + | |\ | | | | | | | + |_| \_| |_| |_| |_| + UPDATE v${RELEASE} +${CL}" +} + +update_info + while true; do - read -p "This will update Nginx Proxy Manager LXC Container. Proceed(y/n)?" yn + read -p "This will update Nginx Proxy Manager to v${RELEASE}. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -8,17 +32,13 @@ while true; do esac done clear +update_info set -o errexit set -o errtrace set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` trap die ERR trap 'die "Script interrupted."' INT @@ -34,11 +54,7 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } -T="$(date +%s)" -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +T="$(date +%M)" if [ -f /lib/systemd/system/npm.service ]; then echo -en "${GN} Prep For Update... " @@ -62,9 +78,9 @@ echo -en "${GN} Cleaning Old Files... " exit fi -echo -en "${GN} Downloading NPM v2.9.16... " -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.16 -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-2.9.16 +echo -en "${GN} Downloading NPM v${RELEASE}... " +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null +cd ./nginx-proxy-manager-${RELEASE} echo -e "${CM}${CL} \r" echo -en "${GN} Setting up Enviroment... " @@ -72,8 +88,8 @@ ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+#v2.9.16+g" backend/package.json -sed -i "s+0.0.0+#v2.9.16+g" frontend/package.json +sed -i "s+0.0.0+${RELEASE}+g" backend/package.json +sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do @@ -152,10 +168,10 @@ systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm echo -e "${CM}${CL} \r" -T="$(($(date +%s)-T))" +TS="$(($(date +%M)-T))" IP=$(hostname -I | cut -f1 -d ' ') -echo -e "${GN}Successfully Updated Nginx Proxy Manager, and it took ${RD}${T} seconds.${CL} - ${BL}NPM should be reachable at https://${IP}:81 ${CL} +echo -e "${GN}Successfully Updated Nginx Proxy Manager to ${RD}${RELEASE}${CL} and it took ${RD}${TS} minutes.${CL} + NPM should be reachable at ${BL}http://${IP}:81 ${CL} " From 9f5b461bdb2eafcbc771926d2c06466d0737731c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Feb 2022 19:40:24 -0500 Subject: [PATCH 1399/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 65e59b2d..f5fc56c4 100644 --- a/README.md +++ b/README.md @@ -313,7 +313,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc
- 🔸MQTT LXC + MQTT LXC

@@ -364,7 +364,7 @@ ________________________________________________________________________________
- 🔸Node-Red LXC + Node-Red LXC

@@ -407,7 +407,7 @@ ________________________________________________________________________________
- 🔸Mariadb LXC + Mariadb LXC

MariaDB

@@ -619,7 +619,7 @@ ________________________________________________________________________________
- 🔸Debian 11 LXC + Debian 11 LXC

Debian

@@ -648,7 +648,7 @@ ________________________________________________________________________________
- 🔸Ubuntu 21.10 LXC + Ubuntu 21.10 LXC

Ubuntu

From 985139df53b6894225f6db73480b0fc31010eb89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 16:20:11 -0500 Subject: [PATCH 1400/6505] Create daemonsync-install.sh --- setup/daemonsync-install.sh | 87 +++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 setup/daemonsync-install.sh diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh new file mode 100644 index 00000000..10ff105b --- /dev/null +++ b/setup/daemonsync-install.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y g++-multilib &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Daemon Sync Server... " +wget -qL https://github.com/tteck/Proxmox/raw/dev/misc/daemonsync_2.2.0.0059_amd64.deb &>/dev/null +sudo dpkg -i daemonsync_2.2.0.0059_amd64.deb &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From f3b6e831df294957be52c3aa81d947ba388110e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 16:22:08 -0500 Subject: [PATCH 1401/6505] Create daemonsync.sh --- ct/daemonsync.sh | 162 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 ct/daemonsync.sh diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh new file mode 100644 index 00000000..5d1172a9 --- /dev/null +++ b/ct/daemonsync.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Daemon Sync Server LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _____ + | __ \ / ____| + | | | | __ _ ___ _ __ ___ ___ _ __ | (___ _ _ _ __ ___ + | | | |/ _ |/ _ \ _ _ \ / _ \| _ \ \___ \| | | | _ \ / __| + | |__| | (_| | __/ | | | | | (_) | | | | ____) | |_| | | | | (__ + |_____/ \__,_|\___|_| |_| |_|\___/|_| |_| |_____/ \__, |_| |_|\___| + __/ | + |___/ +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname daemonsync + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/daemonsync-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Daemon Sync Server LXC to${CL} ${BL}$CTID${CL}. + Daemon Sync should be reachable by going to the following URL. + ${BL}http://${IP}:8084${CL} \n" From 3b96f878e4dc5f0d8899b2dc0417fbf1387fa3b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 16:42:03 -0500 Subject: [PATCH 1402/6505] Add files via upload --- misc/images/daemon-sync.png | Bin 0 -> 55960 bytes misc/images/play_prism.png | Bin 0 -> 3691 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/daemon-sync.png create mode 100644 misc/images/play_prism.png diff --git a/misc/images/daemon-sync.png b/misc/images/daemon-sync.png new file mode 100644 index 0000000000000000000000000000000000000000..c8ed9c5a32120f4e84dc8321b7941dedb48add60 GIT binary patch literal 55960 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 JPDHLkV1n56wjBTf literal 0 HcmV?d00001 From 37d89837cd2b566a09a4bbacde74bc63b5a22230 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 16:51:27 -0500 Subject: [PATCH 1403/6505] Update daemonsync.sh --- ct/daemonsync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index 5d1172a9..79989b29 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -153,7 +153,7 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/daemonsync-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/daemonsync-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 6e24f0b987f09c7d1d9e32ffc19cc9a36468345a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 16:51:58 -0500 Subject: [PATCH 1404/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 10ff105b..c05e06e8 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -61,7 +61,7 @@ apt-get install -y g++-multilib &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Daemon Sync Server... " -wget -qL https://github.com/tteck/Proxmox/raw/dev/misc/daemonsync_2.2.0.0059_amd64.deb &>/dev/null +wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_amd64.deb &>/dev/null sudo dpkg -i daemonsync_2.2.0.0059_amd64.deb &>/dev/null echo -e "${CM}${CL} \r" From dc06c532748f6aeeed8c55056a18dc1d2d485482 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 16:52:27 -0500 Subject: [PATCH 1405/6505] Add files via upload --- misc/daemonsync_2.2.0.0059_amd64.deb | Bin 0 -> 3008644 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/daemonsync_2.2.0.0059_amd64.deb diff --git a/misc/daemonsync_2.2.0.0059_amd64.deb b/misc/daemonsync_2.2.0.0059_amd64.deb new file mode 100644 index 0000000000000000000000000000000000000000..0444976c762251686dcda5a03086eaa5983991f8 GIT binary patch literal 3008644 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%0AFRP8hI}25xIV+*WX{BE82w*q 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

  • P$(!?1D=ZX)zDQs$acr^k2|P75jPOF>otGP2+-@>cx)U<3Sz zQ&MLqD%4NxUpI|=Vl|ynRZ6?oa&(|eIbnw0fIxh#fVnj6YG#p;qj~-b{SI+Y;?Fe7 zgPBFoD4&1F%B01IjN>fCq}DVl;{LZhfia*`C}LzGL@Jst^aY6WGx#Y!#;$1Lzhwq+ z=}cdfQT!S0Y`?Molaoz=dbUR7{{`9+wS$$!NxGQ0&{vSXeqw>T51MZ@n29Zp&osxv ziGFWIE=@n*17X%jXW64%S76;YJcEW?`I0K1FPckrUSvodPsgDdNK_Ex(M{P}NJ1eb ztYtY62mt3=^^R60!uMii^=_y`Xpk81UkIC4mn3ddI#V{ezjqCi@Ijb^3O}DrnRcIw zxaADU#V9}P%ItddDZ|i+pAe9b%Q?gaZ{pjFWGIlj91wV%eapx{ICe^#G3tB zv2W86OS)V*j{<+rTWBHfNKT6AKx4PVWd#-$J|DnAB8rOU$eAGFauwM)zG*!~lNW7= zwqu`l*ZDf14(^3&&|MTaZ(rkg8uOLIT^eS^xYbGr8UQ1aiEwkbv#Mw)dXoTd%0W-t zQ8wuFpwcA?Xl$lk94C^rirnKWDuT*?e)V$#Z5j(7ucLgLEov0<1p%@{<_8y4O&jvu zL->5&^~JCWqOjJ3bk%O~}I2WzwFo&broU0_KBP}X00MCx`o@k;9 z#-7zgAH*$S-uopV7Zp_4r|`$KCpNPB5%NAZCwJcXN8aRtE5YkaTo!DRaUH`14Tf14 z7V+2cvW|4oq7xkhuKb?iVS>C`d4}?04S!|DO-E|PnV#2736hEN9&vN1;-`2iX<+cZ z<(+B03)1i#4DXG$-Ep!IPl||We48o3`WcZA zusd#Bj!Qm{o2u>>9ahiFzeb7R3$Fk2bJF59g0k_G;xhtC-d8KDu+S$J`;K#1Kc$R(df% zHplZqUSlN6;OYmusYNRJ^x@0bCwzDQaXWOKva#*R{`<#`30sR=7I*JKj8zfRvrTvW z>%2bkpC!#IO|WnS*SPr(A!@TQ4R~Ki5vl*?Kh^Jm!iQgy(~r8Xv|fkuS|^03E~vuF z@unj^bI>w4M4q@L8Ry#Tt9(nKxWWwuhTJ-saX&3r=?W+xVt75!#yFV+?5}>`LwP=v zmy@jvV4_Xa`4CcKG4TIGaH^T0c3h$Lx?r{GUP&kHCAt+HrV)OocLBB8wu}#_1)vUMUb?ISYRn(z!@lOUj-2&aAqOoSZ0QoG> zjpwuX<(C@*@NfH5l&mEeVQ>sLq}%ZBDtr|wq1mnlhjDt^#uIKLDo)62S8*wf8CX5A zv909XxbBseVHNr)3YQnlCuHW5cw6BC>`$v49hD(%YRz7xMTdDW-ALmf5H=O;3zZ!* zy))hcLT!o4dX4J+I`!}EPyF6Q)>%+^+YtU3^D$Y zu{zA=Od|#pVRP};!{bdWaL@N+NN%x3&SpU|6$CF<*LT@R<6#f4&DeO`78Uw(w^!2jFD+F|oOb|MB4A2u>(85M=*cxzET58k&nR{?mu( zL)vWiQQ5|1?}sFyiw2x3{aj0Qm1e=l)$Upt2#P!#Dbje^Ld4CqUSckUiEv0;=6&p> zxg-TREU4=vbs)#qTllkRU-v?gAJ3+CK%v7X@70o}?)JiS3fM@aBD>V(R&ElHjcysy_Umrt?H-6;1bEGokTdAc-~9yhQk<8P6` zYO{0`d!9rT$;dSL+a@Ip7NuvO`6IJ;Kft9Gl!I@TBE*UWnrESzVd9W*22Kw_b$Gy; z#AeL8kW^dK<4udI@lIi2IR@d0^D%UL6OQV-FdcHLhC6<|R!-_Dz55zG-^5E_W>eB% z)d71-NNuCBdrbvU42~Z_pT%UKN#G!G<_p0;S~$w%@*lyVkps8CHv4YrG5|Wfx=q-j zO*D!}qg)>VimB}klTktUTV8PjNl2Beh()VOK2-vzbqAq>X)2=-2@|yET@QP9b_>F7 zi=>p>*=k&Ecp(%PA`fX0dZ)mtw;r&Au!y0E+m5IMZ0hd;7V|0Li9kKLN#+XD<)+Bh zCw`x!AY~j^J2PV=ne@ylmlJIxlULXz&}((2k29Gh2alc}QkfJ8ojfa{eYW1T6_kM_ z+&hMfox-#N4D`Z$r>9Wa(!WM4?5I34`#@0-Hq`kRUPEI+PI+=FI()gnc+v@}^?&Te zmnMykGCn86IoVPuE%0jt-a&RJF{rn_|FB4B@1%hrUZ>tyD}Rg^wRHSrVtJBB#6+iG zBhNSiH&5ahbtlL{)>bzgLpf$OE64r8rHONN?dukoeYD+jvUSDLZm4^YM{%<<%?&@N z7HdwtQ*ks;vSdCRbA>Jz8Ar)_H1^5JOJ9DwDZQiL&B2F5EJ7bI7qe=%C!9qrrI=4{ z*Jj7sZBssFLHA;w<1ojeI}V&^AV?m9jUUGBEC>%Yq!2(R4&lme1pj!OM)szZ%aNay zEBv_wv_*Td8;Hf5V@#8SO!JkgHUB3Ea1mZoMH)3YDb2RcWGXnN6n!SS*bg4_?Ck1x z>#Bd?(uYhnRwp?hnN-F!d%yd=6hLo?GtgP3P8&0zZRhKlDt$%l3O~yW(HkD9gSXPtXE8 zWuQsst>tdSg#D&dY3z9$!(_Zn$~==kfkm$C>fWzw$$D49UC!gLLv2SB-ke(7YktLc z+sWitr?1FeV`Y*X&5p*q)gsUYi|pRJsC7Gf8k<~!jJyt+%6QkCQC(Z*?CpmB>Kq7# zWQ|tRqgf;?QkvTck2XQ!E{I>&te>3|d^Qd_$Eh|&D@i(EuBsHwPN+FXX$dRxFescx zElzZ1mvTp?^1rSWLdoyFl!2k4hqSkmzlp)_FhtObvwR=-457$HM^vv0v>0m!9EQN2cr`@lsQVmU!zi2I1hv4 z=y9;EEsB-1mpSN|v;&u#`rVibR$m^y&yH)SDStfX>DgVgYN24G>f5|Y8s}QwZG;6( z`YF<_wrl+3bA6NBPozRYh@AXXgzJTSdN#&{H2BN-lR7u5_@iAEp=#v^7>@)IVnpxU z($~PX9pwm~PfgDm7-A)JfKZX*EUu!f5Y?ZV+C_xFjl=#MQF9^2+!#oC-pIE}So9I3 z6cvj7F2}35C0AT^20MA*f&66DN!4pPXE;w;KYuUrbclEynOV_8$`|~XG98{qMDtm7 z&e=?-6C5e4eTSAerZ(Ar zC7=+Zir}3F_@ZJJgrl%?S#pM@n__>9_H zW0XQ}t$oI8m3qcgjTWkEBZL1p7o4`FP?5igYSB)KHG9b1xrBiHm8BIAQ}It;{Xxz$V(T6fe*?Vy%CZ1EF+=_zGD6s*6n*qL6C)n;rmq6$9}3z5(^NV z*(P7K4`1B~{7T(vg|`FF*h9zF)Z5h_koHN?MzrJ3lXD~0m9o_-+KgcU#Pt~}VJcUf zWYPi2_k|Hh5-<1lX!FZ@x)J|!a40>D<$>X1`h1va4eT2^6Ev1-MPb0~XpB`D3o|7cI!wu+Y}X5^%OTrf z7B>S9(O{T3(FfJKXNYbsXFR05R##Ex(}`sXVXRoMKemX?Qqg=(PmDJQWZaVGUfqo` zKwIX}A>YPo@inU^&n#!oTC3n^pC2H;XI^Eo5|=;q?gRWo3)RZBWmeOclNITjGl+TU zp8pT^UE5H6+#R?afa+nOf2JTgQ0D4a#w@P8e_plj{R`AM#Mxg`W~b~p#U~I;q{%|b zD2%~x>SfmV2iblXRp|sCe5=sXXCp84pJ$XvsX42cUN9H6`qfdV8ex&7e#!K>Nfv-U z0z)i--vh|y&m;$IK{mt;WgrS<9XzE!F~7fImp#uOaVZez9boy21pp&`ZRrTodv%+R z$Ozb+(nr!8uhNSv1S{#2=tpAwa|8=MpEOPK2I6< zQoH!uvU#EVl{LFl^JdZfFb}5Z3cHK{MZAj09su;M0AwwCj7C%TgZpK)hv5lLK+o=w z27yuu9e0W!_S5PK`M1X5DN=d)$_3gqHgj}X4ovG-_I-*!#%5!-4J z1yN1k{Q4EAWb*DGA_+5sqzzK&(7$>~Tss^dn+X~(Wtr}}Kaa&~;?Ah~0kyWppl#&(-n&bL=OR@cApBbA zZC%o0Sm{U|)%Dbh4hISBjZ)XV#1Pzh3Nd01hsfq=?Hgzxy75P;c9gO$frODl^Bx?S zS^NZ4#$lnkJXk-)D$VQ~7iepPP&WvbC z1`n}aN2$HcMH)xN8D8=}OD{zvgkoKnk4j=XGscB*xJlcb0j(7c6bNMBG0-B*+XGI6 zfAg5wWGT`9p(kuO$ur?vD{KO{0dqZpCN&!4OqHM3B7!Q}hxF4vS4?P)ZNh|*8$DM& z{{UqHeUCu@rSX`mRzYV{!wWYoPS&k|6o(Y7CT#9&`ruU1SGsy!IUAPfzu#^(9J?LufXC^DfiODLR?kfEZw&c-pB$;Jit1!Mcj3-PGUPx6zTh0nz#13= z@Vd55Y#xy!50mH|FFY%>r#XHD(C+ygT~W?ti2Z{vAFBc!YIn|NH_LDipl{qNATplo zZ_qJ_+{blCE(bT)+4pQ+SR;|Ux!Ouo#VFz`vq~j($X3<_a0mwxTfUCLT+cEc68GPc z&*FB>(M?lZ&VuAQ8zXcR+Q-ce3+dl1&nbFG@eQ&-{5Kqmk;dH*6xK-RIAxgyL0hNs zGI=JiK=^P5jmk{7Oj(s(5y9+0CdZmbttQG;vyUg|8RTZo9!wtB(&Rvi>0XLJEa0!_ zM8J0jsOd=b)gr)ahSmpn?Hw`wXkIm>a)ruPTmKyO`m5$G+HWR9QEyiXwAqA3+@KSxlJYt$2vbwCC ztn)FdXp9iJCZFTX`~?ywE&vrPZ@a!vOPymZ1XIe*!BGsjkHz0gR`INac4C|IEaI`J zDGcFA(>u5uMEB~y_DlAY+32qsty84zge(KU4GReV$8l4O)=(u3S;hesI#gHDho~x6 z>5sXfrgmVbk3?SU7WcaNMC3~ro>PZVEJG>e`imVQRWqEs_)O=fsFmJdn-)u}g>ZkU zR?5XNxg1@frZY)rB8S=*=6}DHPyZMd3wIrh#u!2S@*kH|775!BG`UP+^RD)f!lAvt z*mh}@kp;JJrYHD;c}x%N#Z_Q|<|2G!hU zdnwn&D9551J_>!TY{Z|U6LV^Bn`4Zn>%j;e5$_&6YO>yH!$$%;@TCKKFw^0ysBg|| zq9U1ZE5eVLKhzC*3?BFxM%LubgeYxBH_P1CrvaTI7y(_G$^jB|KW`SdZApu5F6aPe z%mRQ39aWzg{J8+RjN?gr42~R_|%nVPcQLy-+L}{8NfoVw5fn-Fa%Rl82ebj1(i{5*B zr=3-iE#u9UGr)Qg_4I+1Mjd$OlswS1g#m{^HY~?31lso-`1>}hPDmM?8?$5-dg$r5 zxe`WC|3M2l`-Ue+y)YyOKyL=Z@sxb$fpK!&@BtjcRJ9Jj`Bsf@H^P%`Lpf*=-;Rar z)I9{Vh2WMG>LvCl7&;jWGYma3c!G7eT6|Ii%lOZKG;f+?%DGZ;JB%L@q!J`WGNM6v@x||QqEqW0OKiFGmT1aTr!_5FpwZIE2HPhl zY8KqT=z5pq+fmcOY3Uq}oNY!xY7qIlaP{yiQ=`o22qa+ZRmth~AeAbvV|Ir!{-PD^n*IPtn&t^|D?jmhL(*y33Y*&UWg9R@Rk_>KkbsW>C#Z)ChaIF3(l$6R<%2-F>gJJ#y1ihf z2Gi4outqjb(5_;u>dz6T*stfh25igcauFkxBn7Ns{47+lj+8I6N|IUQ49b;RJZ+Fp;o{e8CVyfqt8yx#peV!3>VH=N|Y)*a39>f*RLSe z3>kxIB*}%Nu~f2G)t!X$H&C9#um2ieC4zPBWkVL94#vKvNTuYJNLQ6+(Y%N?ypw?H zwOjr2T`BH{+p&03@;z&>PtqyJ@|SXTh_zRc-jC5Q-sv!W(q3JX@!>gooFqLX?dXNUd@lV8qatl#N9ayoGqJL4`i3=WH6JMpNH`{t z6FC}#QeBrwIG1SOBj#Vmn>PxRMlI58i<$rI=jmdYV_KfE+p3hLLua?jGfZql#P>kb zaylY_pYsCb7(j)pQByOgzgoyoSLHw*gn_msSflP#o#ip*x$s|xT^F?E=)ddCAEv%V z*~Jh=%lUs!=Pmj#`ykg}smar)$kUp>+e|NSxC5FgfH~{TVe7)~2@169C9+Dthocv1 z&MoU)of>a^0-?Y)hrc&KAx<{t@Xd`cpQgiPr;qfCt@4|ph8Ip^dkzNc3+~@nk6Yf{{}P^6_^f3T~!{{!;33~50Ju_0#VjV2vM z^=7T(uZYVa(@%k*9$UZEC&+aqwC>h(GDvHJ6{->tO#oNWia+eP(|;p$H#O(F-9BBt zv}K_TvUorme$7dSLz~V>ti&x{y5hMt_gTQM<&wr=;}w%{v;D}?D6jh(-rDe_l`!A{u51&rcsT4Mm^%tWBD z^#J3g=l8ELW*)X>0@wFpO4bd=JgF=MQwN8g&)uYDT zQFML>PPG{Ra0uJiNv72fBH&cNPtHOlLo-JSDG<<4B1lFiP(Y>wDtz#ifhdn4ih0_B z(RK_71p9-A4&ENGAzY?ja;)L;7T?s~o@F-SrvY51d-gc%Ol10=Afi}miH1k0l(`xs zm`&aM5*V+vJ<4_&5o04N^#SwLbf6U+iF8ut(HqH%!60D*<~Wj{30BBJ*!0WQoE190 zC2MG7$Q`5s4UGCNxGk zWIshAgp|;Uva3W`WnBy!VPx;1vA7s?F9@h}-)oZ}pf<$|V_xp>-zz|YZ0~Rh9WeZ@ z^_MzScg|oGJ2Jt>JrnCrVZox-RzH|UVn>XO23K0`2y4rqu>$ z_vA8<6k<%f@gbMhd5x$+Hmun({}SiIk|*I_e)wJM#0(8EB9lN5`4g+=*SJvi;b7*N z-5g1zDb#wlta2n zLsm&~-up&(DloTuI;6Tnvu7#j^b#jbH(mN&?Q4fk1KL$g(zBv?hzbsz{BS%O5%IG) zm?$)u?hS-{y^~GILQG>;w4M7cJ~c}rnwHE0rkPKfSGXg{WU&x|Rw)u?pxGKTw)Iv` zuX+M|2c^7~qbAg!tAQ_$SGUD5P$q5fO#+b!6i?7njl7@#;iGxKVym$x(JS(^N3-q2 z8K|^I=^i>l$KY_guT<;RJ6Uo*7s)QV3O;57*FhkPRn<&+Mqehy#&YhF&W{HcIbX~uvJN%Ozy*x)b9S9&Dx4bhi~rWK;V8?0qn5u={Mp6@RO`#6}dSPvFL%F)JT1avnTZmEd|& zYK6K19;sAD1!^y>EB&gkE@kJBkl)7a46HV;xR_E8g5oPDmq&bH)6VJ#c@d=uGhV*a zvp)iGKMPp2!c@1>pajvFj>~PRw$uI!y(MOB(Ya`gDZj~?zF$g>K8pgtO$Opw7}&9NUcsP*g%P9q zV5KuOJY}?!F{l!+)$b>^P~~-Q!eei_jVI z+d4wEmjyRa*hje0mv5Guy&^uSRD<1JSm5&rgTKhG$xZ~ZJFR20Sf3zAZ>hj$Jksj^ zhF+t2)a>YwmwzxS;TyP2Ma(*Be4aUtk}~I?k89eA<&LlIeXVlUBgn=iT#I`Z@_7U> zfrFOytTj$FQnFS5i;i09>*x6%3XCUE=C4r%3?!6U^D}tYGu;n|%KH5U2-ma~d$cUz z6Z45z?bHx<{V77E@p@DZ+%0%_r-7~>+oTcIyxS!R{XuPHSBw<;kdv%%tG94R1W-*Ipg$yXCTnxs?@Vq#P{wCDU&V>WmZbJyk%{aWnLXZBKxQe&-dZ~EaDUq3?6{9ES)7~u zRY3NeAaf@C(I*7aw^2R!X8HB+iR0X&>av08*>=w@CVrFkU7<@q(k@xxNF;n3B#rYhb42WtDAvo-Uu z5BDC!q7;nht;c7qcX%TI?*%?*JvgfNi=9r^rLJ;*Z*QOh=(=DFg(xL|V`c`n?&Mqq z4wdmDLNNHnmz3VNMo(T5Dp?PsXz8Bc_}V4z@XX^W1+W@RYBNSqN(BgUUBjeLj18=Y zQEE|6pc_v%H@#Dgi$(5!2-H`xJ~z1It0p%|$qjN~yM-!Sc}j*7vG~n#W3_?waLLHy z!}BZ?BK6X!-*q1%FHC4x(+?&lk{IMfx?5h~!RYWxev5{`JiEkZ;BB z-oAfO%7~i5-B|So4&EOtEVgceRI#OFhyPK3p8`Ec*xy>Y?`O}BHv1&``MELGZ*MD$ z^8F8DV(|5=OFMXoNRnt_;cp|X~cT#!ilNG5M3Ao!gcaOFV^{K<_ zO&AsR+EicHhVm#YlcL(oqg;}cF<>5C&Sc^amSytu~H+7#|4aVqm7@yd;zZLtW)k5@uv{YB@+H&TXoQ$ ziIEB@0OfFpU2cIaB=sZC1!1X|osQ1myiapj`S~Pv6koS$IDia{E@67?#1nZ38Ekz$&?SD9}pzN{R`yO-u zuPh9Jdq>ebocpR9CNxe3NpoH5cXO!o@DTmByf@@Iq~4|{mwMBv3k6y&%C7dPd(w5h znJnEyjT8E{4!IE}KOckf+`1vh9)5z1g9xmk9BJgX<-x$K_flgZ3kuDcPH$G#UA**d zP91lS@nOU`HxD}q{=%3*KT~h_k{j%#rIVx6fPr#8aChnXt#z>5+dgXYY0NdE*^ha3 z)U<1o=jCu{XeKkuo(A&3Xv(l_0wjF7vT&I?yr@17<^&;2mhy)kNF?m@HgEnq(Q&1Gv+ z=i2jV4wJkWC|7Q<#@gw~^w$U39yEDWV=iD~ZGa*LB1wcRx1jp0a8=9+K9SZ>I8^URjdpsNN`huS@;Hp_Db_UNIBMUKbn>qaLN+*1&i^efTbBSgb=Wt(U zDdKZyGkEr==n}kQH(m&17|EQVt-FB@>hZe-E>h9}6VuuF&)3+SHC;9E|I!X?0s0`i zwvgRfeKQ89#w3(jF3Y;Z(7m2%i5jl! zWw3hm0=}b&DlRUN{54iNg+;}L<8A$>3TNPVBjZlZPSOevtbl$J0${uX*i=tGCEP~+ zR`fP$Eg%qV{VTQSvHFk;*dJ;jp3^bGBc?FTd);v;&3|~WMhM%6}?k_7p;E4B7Jj-(_hnIhMRv(h+^efbxVLi6Sk6k!oLLLBK2qq zK<%KSUP>|Opmp^>^CRi2a zLoES@@@waLWfwa4+t-X3ZSy42TnP6SWQpCOHupmMn6q5gzygA_Ton&b*c);)>&@)H zf|3j+%)Pe3@fsiAWB^@#G`K2C5El9DKVtIpVs;oKdev_&O2x?PioQ(IbtqJmX&T!+ zH(kn!@T^~!^~yU1%gaP3#oDB;sPri&QdD{3v5ga3>LXz^v#O(mQC+as^Y-cN=GV-v z^gGrUhi`NoVbyH9q^@wLaUHo=CQ(vurL(&jV0G zrq#kWw!hp!bS|M&H77{q6Q#fA$IPGkP0$mfLDdsC!<$Y|NGH(8!wVBZNktv3w43(T z-~|1YSQ$b_a`>*@qSH0nVeOGwub7@`SRNexkDk@pz^52)ITWes^;GDg=1mY-PaqKU|DTiSxxl&GlB=1svEJ695@;AVG+U(nE$ELA8T${ zNL8#pHI0-FI5HB&VK(PFCh%TnZb-wdA236GIdw=sq|puzA2HzSGp;TOVVrkQdHR-- z^f7OeC+siUbtd&rwJvxJ`GEGm;wW*zCY^w|fkh|GFcwNW&ES^ZOMNkYq~~k>lnAhR zas=Qu#Axx36aSv)O=Q$7sw?{$!dPLfsnM$_LY1*}&w{cyeL5HVghj{msnS1<2Ls z+t?&rZ2Y3qBbc_m<0gTPs=fEO_Q>2bjmHmc_!y}Jcl{E)RygH(>wvX>zo_}1qq9+t zUOQ@(f&9HddJ0LTKA4-fzc*=y^;j--aK9TcGCMtdVMG&P?9qn^;%kK@4(WrdPd8h2 z!dms0=<~yubTBv4W|ltuFx&Ae3X@Byty5|x%F!M99pWHTf%Kar=Vd1UuwYz|3cc3O zn{)|&q8i{m;uz5n0(#?;Yn-fi-i!n3BX{ka>Q8rfF&~F2F@BAZBr`AQq=S$_&Mm{o_LFy7Nai^*8f<2e zmpzGqI(7oZWvj7XW5#Gr`c`GVA8r6MoO58M)rE#SfOH`JN z9a{woBf;)6PONL(SQPq>@@N>hAa5ny2tH?*2jBoU^wBo$0JZHc6e2NZn%bExKTPg4 z2E43K`;YszlSTn6Na*G9Wr#b3b|JX`m~DiOLhv`OK0-vkT#h^j)knpH`>v+HeVC~k zH$ZM9C8Z5PWSWdL(Z@JM|Cd_yO ze@pNyJIfW#$Y@j+t|@8J0z*J_McQpPWxne7{Ect&U*&pedk$EcNs29&m>+UcCEgI zmW8TAjW3ZBl-?@^KfO3aJo4Lw`q>J+Ki4{EhM=slEm~Az+IF{ktDa_3PbOfF{H6cQ z-YfPQw1lDh6&zqB;SEFtK6FlU&V;NS%CVBn39+DTlZ=<=2M)Xp$<%mTmh}2 z3Y0S6vxID7w0K9;2Y}-(d?6e7o$?B@&RfBWubT%dkw#*MM~r*&!8?1>E902Uqn_JONu(XYqJs|f^rS8^%AO(tK#)`LFv zDp)2gPp#pTV(ypVY*3F@-9i8*sOcii9*DPWP-NOUz<)bVTD*$Uj&Cl5roiPtw5*cG zz3Z=zD|wciIDH=gf^@XaBsh1Tv)3o3r5~t3$UhYndud6^tA)a4A_~_QENW9PJLB+V ztJSx8nPyonYJ4-Dc(+>F;uU4?omr%E@KU&fNS8*~hD>YH;b*v3^TE72r@1bqvZ7BkgQX}fLQq*HYt_0p0=f^e{Y7rd=A^9o^8uq{d%xWIHZr>)> zR~N~@j`k#Cb1V+T_D9AO1CJv;b0@rPfuwQ41N=2m?4gM6Sz(V0qjTLIG$@4oNhn-q zFPC-8VGkZQp83WdGTD%H6U}_y5;NP!O+Fvo4;QWibmc;u=t_kPfChq3U{+Q?g03jL zCj|w$ngjfhT9|})imBq_e{Rkr-47K&>f-u-%ce^qLt63KxFyF35BGgG(qvEU0E8OU zR*|~;w6!@@qfBkyh2;=$?R%wjJ~O+?j6A?jdn;oNk z3vQfyo3qMbSOgkrY-|Pk`@7yG?z<82bDLw5=C=H^y-D)w=%pcRZmZgpToO*fiIvG3 zdy$49aH^i2a%owdOC9k9Yp=pQIg^|F}p* zaxN4hN#y#dzl<>8*cC}^@~Q)>uh{EFx_`QXZk$=Q@S?WZ8GW|fy&t z6*c6DW~M_cC%yV0M2WSqNk(nF+@4sBDEXvVRBP>m*MD?TNGA7Ig{z07QOg?`o1?2c zX&Ai0(tm=P2jDv&<=Zc!Z#qZYab7jv*U1EOqfR)|1o61&px!KYEjnG*F%(nrT{T=l0%gvXY?;HTW|%s(faJ_up~LsGNEO zeHZsOl6%8#V`m;3F+OkbfBEV_L6|zk^begFf7GhL{pq5Z_-X)x$s$s{^y8B^{TsX5 zE$KZ|e`+Buz_>oc#mb=U_dxms*!kN;loAN$5aP7saIx`&hVkI1P{>d?-U)$j)q z`7O7ii;TkS67j))7u=`EEd8SRCnn8r#Q`93MCGsg5i`!}rVy>(IG!fLU*@~VD4kc8 z08K0{DEn$)a#n5JgZ8R#6x_Sm$IufpbMIGv2%w2;yM%z$AsMXwP>%`%vllAIvh z-Nh4_0NDZf$TIWA3lT;FGFl}0UOvKG$^BCI>0dEw?U?h30)&C?hGY`^s(x%jOD}g@ zxlGMpj=t)`Y?@dD?=-Gg_W(K{$xiYp3|#l`*)5Qe0Zblrl9vFt!N*-@QZYujMu(8C zlLd>(fB|PCr?H{F^3UZfy{#UX>tcJ>rztNksg2pf@!TpW>KrNMUIj>)wwTX5` zrck_)YalstvdWYfyNcBg&HKQ3XNZ^p10o&|el#Yux3~oPxC@=?5io!p+8rxT)%Rn4 z+ViPB7;FkXNafHND;v%O%~HRB0W&)(9m%YwPAI%iDv`>{32A5i(JRR@#C+B$A`V;@ zIBhDA(;4jUI3M1Kh_dvT(K>)qss_5iLxqD&SB_r5MEYiGK*g0G(>f~HXMs|guBXS8 z`sSA|>SY@`SfOp2hFJ$s>u$ydNCWXLB1nv<8stU+r!d@<^NQ0w0-{GoA#gMJ?(8@a zz9Sd|nKs2}qpEhQ=(9dCUc?|_U$YPyXnjO7D+$@}H*}y=8x4R_n;_ySG2@i2Xgj-K zL+&9dZg9@?g0k(0`zL-sE#1(=;>d6X^$YC9-yP35GerJ?;lmD}P9bKZL{U3zggKdUY0PMMDEH$7Z5}>@)RM|B z^7izIvGIdQ+-`s?0oSp8naP$Il+r3ML?6iCcfOpLjiq> zByXT=w3R8NN@=Se3W;;dcDD~7w#hqRvy$@MO-_1BuMM1^tqg8MTaX-OHV^6%kIX{X zeXW09uC#>X0#_XPcB)G>Zh5{@H2^XR*MFtI+z$`ReeBz=Qb|V*{J^fWNTyFd?=e~6 zfF*pO;Ow~wjtxVMaH4fKdAdCt+A)Jfx%6eWU%UlB7a%9us)8^AH?RvZm^cmdR17b` z>~Rn#Zl->(;zwVr!!XURbi&6lS}fSkfh&WPT6n%7!V0J}l^m><4Z&6@HZNl0ZFg&h#UE2W(>8CGDxrKH)7*#&8H%&*P@*;8xAQJJK2D||BUMZ%CDi0D=U~97wMz#mfACQaMm#Wy_BPnU&wI!eF1^A1a zt#aVcZB=1Bgb35ptQbVqvQmB3>bz1x*=i+vsWEZW7L>(Tzf2M#L}|KVlM72e^G&+z z{TX`!3ktpXp$g;0K@Ml%rUCpfWr7{+DA9#sN-yjtF#{8dX_iLW zjdf`Ug`RvcR*Td6oCbZwuct_NMD3I@*)gV`cG$3_IrFeDKaO`e0dAQ}77IEooIY!n zoAq+%*U|ViQK2LRiW8N7uoQ8_aJWKm8_&}W2&jUygv}I$>n`s&( zka83E=dw_2v?(#f>xAXA7O9@EyA?fBT)g8>`W2LK*;1t9d)=%ld0=YbMBuWp&;pfT z204BiSy7|#8+4x1!?pX+q`~SuNE;&LiUe5rYE>@>V~I-MzoiegtA-{{fzrUl{hHL& z*x(a*uP;Q7)9cU3fYAh+wyP-#7Z#%2uJ(~DRA?#vmg2;)-aJfF5H*k7hmHbutD{EP z)FOihJaprLlCMWK@>&=bh_R*EYnKv|=Oqi0h`Z8G)cTPZLq| zW^4fy$2ahPd_=K}ME+456FYtwCxtm4N+i-0&B9Z70p$TpG1o2|CUY)i8G%$$zgA#0 z&2i>Yl#D=5UVuvT?p-B8LzXW$bAOoIp6^ivd2tzmsZfq4Jxuf;tH)+5vQc3a#koFQ zqmAI(2;*=vW(a*J443o`b1yCJGiY2izP>D{)Ql2*T`9xh5F!{(`2sV%;sh1Xt)Z7Q zZvtK@X>2oHizF~y?X#@9&|Ml$t+WIJV1=~w@(JJM7g||OUGsK=aKhvMpSUN%fsif) zuARPt?6=U`2^Tk0izhFA16GSMe4BJb%{G%x#Ou1sgi;4co?L;oS79nvm165fO9}oa zmKv?YKx2Q*=p>ANwwqZEUATBl0m=W8% zh5(VI%4z*vR5vkqpaYh{*+z-#@-k;2qdQ9?$I%~Y_w5F;6$MNzBMDatc2e&}f z&wd3gQwyLKlKRKrZ8O3GG^%_(bJna_NnLuJhtv{U&dq^G0iTYJHzu9;f$ErvN;gM? zOUpF9{&dH*bC9YH#b#r%psoOOaLYa!07*OMVJg3(7~1P^cVM&bGG&hK`Ki#IDApT= zz(7Kkkga!k7y>X-L3qz7!wEYk6=T@$F}oI7+7c*M&V*uJYO76YR%D-M7PW8AtcDfk zt+lde2hZr!$>jgaKxP%{`~fq6$-nU$b@}@F21lrbk~p` z8mXq#71s#u;D^ zp2yH&34S-0qVK=Uq_>5hYQs1ozN=IWb?nBfC;4_~Fu|Zo0fVl|{4I(*q)uFy=So{?L_CO_yuodj`=*S`xT!=aR-Hcz z%^~PGzTM0Si4BDAU!DRAAYC6#uVN*e-;c-J^9mN;DkNspt+vH>)(}w`gAc|`O9^Du zk{51h$C5@khS7wi)BlzY89w5lT|oB2cZRX&zjUwhUt3%)DMp{3 zN+nFzB}ySFqF|gFcd$%IRhx*qLLr4NqHrfD^z6yjO>1Mn=7#V+H7EYZ zVu(JtQz1!Y!yGFtx?-O{7sD}hVoJSGrTNUyc;kQumpOKG%9JYO_Z}y{Fg14XI zGr2F-?jXW!+pBKI9xTK80LJ&v~I(#cpknUEE9Sq_kC~ z$IQHKf~mzrpia&f6`y(JYxCGwa#d!qBtt2$Mh5#b;AYj!Y)FbaxB(#>UXbNHut5zy z%ebOI1cCq|SVT}sX#Di6!V7iI&F3>JA-}Hb%lQadDz9rJXb}iGGHm>bZ=S(OVNG7P z3RQN^*02pDsLs8uSZa_qJ@>-LmG-ScZ!cYE^S$~4glx^{YG_j2nxwN>xj=RL!X z@n?2gy%_Yk`Fpz==@vAa+RJ1ZK_D!~eXm{BSkGqW##dM=`A9mm%DY6OgoEQ&u8A|8 zLD1o>2n?R=be|${^hMqKi*dO^!5a3X^Tzdk{6>2a?+D6}Zg_34HUPUrN^12dt*?`6 zz9@)lT2H4xiJa<+)klRV1xT$`vrrg!YQpE!m9NjE;`JR!6g?sMSP%UFLbVU)@2!lC zv|p;J-l5}*ULDe#9~O{Z*N8WN5;2Eku1;ICGZR};)ou1})}+4p^3g7Yl0RplXWz%p zL!PqJ`ZKdS^JX3P6h4?wbQ|G-C>bAU8HLz63xizR!j%*zSi{3eZ*>?9R3{F39peKj#K#+O zLl3pvjV>SUyjsYsC);muFY2emiHm-Z`BcN2srTT#(k(mfkWsRAHmDHO6n3W5SVAJ3 z6{NVMMt>~n2Zo$JlYrpFIHXUQ$Zt^|tK5vz@;BZ^FkmaiQi9#IjTwkcVa);BWEJcE zG*E&dSFh#C)errQmtC`1-qcNBS`zSnyo!arisF`HobRxu$!M&yhZ>-n3(OGAWAF+O zkoT8NuvhvRnMWvc4lzds`VQ|s_h!Hlz9zatvoVG$r|&18ej-r@>9_Zzmai$FVYX~P zH&4-Gz0q+=!$?Kt{B+-LI{y>MH^IZQzwIa2Es+B21#@`+#7puo-%zo66d0UUsKGi4 z8t0R%Ha(02C0Es&rcWk}LWKR1IK52}<*{pIc(D-2gfjdz04uUh=B~=_-Qi#V(njl@ zF814s8Ecm3d_#e%r%Tk_Yii~$(IsWWy7F8BJQ3fQP?dKhGadxH=2*xXyJ3jV;V-HN zWp_^r*tOhM=nsWFCRyv@J8%uH9leD7mv0%@__$elsHJs{13*@(yxjBSkqs}DS5tt7 ztf3)iC}#@nHZ~iY{z3#p%8Uy4L*yxx0(A*ZkA61IAev2eu6iqi>J8eRrWAYIoym+& z@e#y4-x7jcz7PXPcOw%>3%7C+YXVfP|LNTfL zWTuFLCCTo^Rku`M6RLzA?@U5YHak|V$0jnJOYOSR>o$pJ-gMq29=v5;*oFpZdtHAqz^q#s6UisiEg zlJu5~=ZWOlB|ltl?(zoFrrNtTr;QiYSP?DI-p@4#dwPljmh@F}gK%w4KCC= zx!O}UQA7$r2lVYIf<58=J9O=M%v~QqlswTV{qjm|W|nZi+ssW17IZ6-;|C0f;bq-H zwC3-y$s0QEGo7H4%QjV@WS=d6BkRYnF9@#5s>vz)Mt?txg3RzKeB$C2dXcAiWOf4! zNX|n^c6QDTjMD)G0gU&-1r&QuvsuP;AS+g8=GqM*mCc0c$}bew@Nc@Wpkcblo@yj4 zmm2S%=b9w(DsNd|kvwj05=BA45iJqqQ6RAg70A3SsW$baTTZZ{$oYEVC`!{0y~(ap zM=>MiNxGZ#MH3>uX7XgZ?wT31~o z+y%>BTz?Az4?J~tmzC+3rp^(q%E(#E1-m$wzX8LU;plEd)sS+QmA?8-#P3JIPOkyT z>nie)M^AT6@>2AgV~aWcXc|k!-=vp+y#~YMB03v=_hN z{aQs}{YL7>Vl}V{3#}CuvpCwPoaZvPS)Ze$LI8yMn4U+f05mQpUMei7Ba;Xd4kb1& z3HOp~$y-~gTQ#*L&N2~*NC*-B05*X>e}P>Jn?YnK;*fWZ2foR_ELuyh-!ONhhf8)H z;%`#us$$>G8A^D0ou84gkz|Wt1mkT^lki7s)8>v{7VtgPwM~L za|SLA=$>4Fy$5Y!gw^BeKW%ge=s;p9C22cF&&mY0|T9)a|P zQynO8@Kl%K7Q0MpyoH8OYln_1wv{R5A1QpS?VcFSNVrU2>Ze$|IxSSUdXXod1=#Mt|wlO53wc> z=j{on30b^l#B*BGJH?37m!0x{q$}I^bP&QF^96JGa8ONrQZA7Wepl=5KMD%M;;PiZ ze4${EWC(nWPjl@H25VJ1<8Pc>9aE}?s_MiRWz@VwrUIRF+f!k}?v3;C(fIFwgO28ct4N9J$3IiAqw$#=M1#^I>xRE8 zEbAH6JiI_XZ}z9DsTr@>?-1mD=Q@b36+LPPAn07K9{1R+kCmj(|6gT-IZ$`*Auttj z(5RHJ&4GWcK)7;+)2o-kYv0i}^k7{5`ysI%UwCleb@b4zE82wuV08Ty<^02N+mV-2$D)^M@6S)kv(tx0}K;QY=YiaGrf8^=S#(FR;+-W z6UOolYZ#;PdpDb=b~B}g;}r2bw-FVI9Bp^T2oXp(9Br<2w?{mWhqUTAQkEj&}fEuSx>AQbSZej`M$x=MYsHwI8q z5c~!zqI0X^yPI$&(TAb6@0<7OH3PCcD*YHwlxe!nE)iLR%HBHpiA!$al{W`=_h?5w zxx$)8YO`>!tXcEZ=gS|IQbc&=mk}_<0F|l}hY{KzBt=Qaq&^UfIhpC-t3!YrzHscf(k2a$maseznS#$@p%J z^&Ua`x`O4cNBRW505?F$zg1VJ;vcF+YLoFIg^}gY@d5)i8=+frO^6h`+Y~F+fEG%g z#M}MbR?|xXGqvT(dHjXrNqy2DuyTS0GfCW9n4k0L+FRWx|NH)sPx++oN6DSubACzq zh5a(cAclJb24qBgtU}KLSJndAa`E)~k*{y}%Ba@l>%&}$VTMR{LeR|;`S`g3Kws@v z;?B3DVfKA5;PCeW#=h`tU?VG5$IdJ)0lwaSX!>X4bI;l4k(9aYt80%?_>LM;wW?9am4{y+4RRN2S_i zgFVVOSpx$oUb%Sg7-00|u23QKq?$3LIP7AH#zvGU_YAx80jGo0i<+M{ZTvWU{uu8V z&naAJ;oWv{L4Q%~nJ3b%{q4(~QgP~k(A&`|uvkr@iUjvMo3k0J7L@98#l3;CAND!+ z3l6G=m}Jc6R)`zlxDlN{kUAMhDaZf`V;Hq9UyE>$1E8Yqx%S)Khm$sV(La_%8+{&cmO>ReOdzdxnDVYG8L+6os*q*#xV2*^`sD zKY&aNa>uABvJmfj=i}l&hc|uYS;f*YmNqm|e1WOxkE(~v*4SXVvKXs6AC$+PIx65c zZ}{Qlet!|#EhU`+)?z@%@sLrna?hF$)+uW?SPRU~Eqgp~@08ueRne~O#v-arcFTn- zHFwq?Z3K%H54zRU z({nddIpxm5b}?Gt2RhNTK<9(50a4Nb^%H#TtGMiA3cqyXp=?0G8qxa|qUfj$U6(xa z0v(U}t;jjn9H0wg9xGM|9%^3(g-tzX#a`qL!HUN3rUqGZ zE;=@lM0MSpn0`$y8_(D1kkT~G2SVA$!`&qQ@Yf@dS+&-hcZsG z?V*$`UPRlrCDu}}7Kg80gaZ3Em|1tZ7y0LJ2(451_%OA;DLBj zG@BqQ!u3ugsDMB+;AKJ+++h_ksfppLky$D4I~NMQ;GM-~-PtJw6Z&2q9#FYBViW1i zYZo@y*{_}jA6ylOJQ+N<(h#g%##P(ve_BxvI{FaiEwri>r1snVqls5s%e1-&2GQ6^JJ$BtLr zLzv$^#9-R&@+F)`M;j(-6Tn2tOombnO3j0at$oz7DPE*Ui8>uev^5tw5=Xk4lnns` zU-G+OSY;#S)se7{u(vi!Y=Qv8Sz<{FG&p$mKX^^ZWc@C7iui%Z)e$ko!y}p_fj&v| zHJkNlM2Y)fEDKj}c&{pGtV3oGhA82}OM+WKilDTC{;olVTpm)+ZKgE)ey4Pbrxy0Q z;|=9tuHKg^PJL1iANAjjt9IulM*}w^fTw~f< z$D88$74vn$um&Q8;Fb~AWBW-(jz4_?A(8CqYlMti)Pu}#V2VCc5pJV!z247m*79g) zq((D z4R*BZcoF1DbM!bm^D(ZrRV)+Z;U(A=Ox)Ihhb48AY^%}t@d zJI*!ro4#~O@u?N96ay6J8L zUUQq5Ye3!~?}WNmRA!fe&?)LfaG6nI1vYj&jm+xeU(;I1S-l$*RDTSr)BREqS=Fo` zt-l9yxWtgPTKiy&u8DeC+ytMi+4w}NEG@=59@S#I!lAYS6TG$wtlfs?Swfj3ZpGk& zhztN>J)!TL^fgewGxaDw>AVL(`(SeO0B)ssnIG^LxR8%{glO(}=>x+$Gu-ds?HGuM zFB)GOBILY?*6{MK3})#Xa#$A>dETV&nw>Ws53<4cHJKO{D&uoSP126bm-6WyhUrLs z|B;>KgE}}X$f>dAV@z@uJd!#@j}aZ)d{N_F6wWfd9eW$EW>4Wo;|F{AkBC)N(%Y(*)h|u{ok8bNsEBBK4Uf$b&C(QOkEDSmVS7XaWLmZ7+ zX^PQvsM`t0)tNp(9N5~0;@XjQHZk^@&w2(ACdg@vgJhOt9&ho;t6k zAv>bBU!Io~${08cXQ70jXZ<&PIOK%RyH}ObM0Us$WE$4HW6s7tPp#KLv+PmWY3#5? zkJeyc>^g;?m<0aa$_u5>e2l{N68G+#Q;&XPj5a%f-_#FMCk+`}5XBLGxl{lpw4yf~ zm6c{)!n}|YQK7%wn~qrq<~jp*p#(>PvWgF2$ODt8}S;L+~?(Ot2($bQqkl3U(JA069^JRm)5$~+-Du^Q~Vie z2}!!Mn2_i!fCaJG^cJ%b-o5?%+%PZy+>qfW*W9b)^Hs!*{HvU{1o-741c(7ZMfc~4 z4u$V%L$Fi_c{G+icdM+qM7Oahr(CrnN+Q}q^~gc@ zX3t$Jk)Qppj3$o$K>J`y=k93l4scU|x$>kT?}hu&(ddcxA?+3S1MVBY|KtrS_Io$R3maFH=nphnH7} z8Ubk|za>|{2B-2^Mb*oE@YhoSn_@p)My5()n{KCjDH0wfk6SuS6(Bmk*tQYog3S;a zqmj<%+Kw2EDOPXjE6TAgsTt$lC=4D5f|wWHI?xXqG(g5@b4z+SjqAv9^{<6Gc7kl+ z8##rdh9Uc#ezi3sF1HY4&|eewpg+Q0=PG9#HiR$#nNu(d!m{0WTpDHlKEu2$jNAIX z+mebX|6-O>H&nWcXcIe9hmDd$Il#f5S{bnQ`Y+Zho==~W4QRqif^q|6M#RU03*Z%F zx?|pP4#iNQ|EkW^6{?oZL?s3qoin#taE#EI4GTV~p6KQO$z8KD2#q(gh`JzevzBRD zZEVh|)Qwc`Vl$+yxt43RD-d)6`tNCWYD9Q>G&;JohyB`Z!$5)E9Q0U-`xy%DE?OYrC4{UE4Cy+avtbVYqQN>Lh} z?JRD`#nh7VC6u(y17sDAh|R&4L@|E>e+v-?|@4&Fr=v>EmB|cZzDD%8?t9 z_JztR)QaEMn5W!{EhutJ1GP@)tAHGjZCoiB00UaxV`i%hqz^&-cfCtb2md5o&MXH? zY_u1{i;+<>`Pq}{@xX%-tt?gO!gcTKFAmDHVhd~%GYataAlf^g?6>uR`+G^xp&olq zdv-=FfCKP59iT~vtF@sJ(XRxE8wG0J>pd$vA1EaDteWUyu#TEgr;>XORWM+}XD~oF zLAzvQA!RV5$G8G;YcW?e#c1QieYJx|x(h3I>Alyk9{+a7*li~S&w$sXL|4zWPF4}v zUxg<+NL*fvO$zADaO_{M(xrq2hi6yHZ);mrxHmGXGi_GT7uHX=>cLtAmfrE-`-?E% zj%mw>p_e3&%MB+5QyQJuRLwhJcd@2gD6hR}Dht9=CsrvT`sq*a7KO(XnkH3}k%546 z%Vwgfcm&XBBN~FK5k;EdV`?g7Ek8P>B{Tyh&G{R+F6!^`ahEEXeyIrFOnZdK9NY-p zN8;k~j}+{O!Ttw43bbftUS|PwNyy^ooVyWeUS1{k?eLQoSu!fC#&{+%`5CmI7|^7f z1#!bNkU1DH1n_k4>ZtP4rj@^(Gj@V-^GvIqzQ=9e?=rd)jrglRP?A22Z1_P5`` zdRiFx)PIVh0I-n*JT?-rS5AYwgqM%Ia~iC zd#!_&Ods4WZ*~m#JZ<96e>#bZL_%-`96wU2Epf%SPq-aj=gSm5aY#r{!TcqFfE!K? zCwsYN&6RhB6;Kzz&J+b<_Hu#(P(hA?$-`xnD0(M@5panYaoGw`)4)4=A(K3$7lH;2 zn)FBYeWbq4S|ro|ZmWZAq6T>g2Tp+32m**4Hb0LWcS++&+0@hIal7!l|B|w3??!G> z@oyNW=TSIdj2RzttxK?AQ+HKvGf4pkiCLV7vhMWP+aYyj_LRQl z&h>b-x(d5M@h^kU--`)!+Bm-l*)h;}@;M11vKMx(!4*Mr+v!3s7E!HxHxgXMXEmEQ zJb*>c%XqdjrY`&|HKibaQ>~Aum-sV-6hb`)z=zbpGAe^lggbU)7*u+Zsr*msmo$Nx zdxcFn&|T+}Z(;fzpyn&lrAF6Al!+kWe`<6)8V0hwilYU0&qy3smJTZhEM6sn`N9x@ zHkif9Re03LO|Tr%Bz9FuGehEa;@(K4C$TI_%R{k(0_}W`s(L7K!J^isvk1x+27aRcRk(cp4PMh~;MrhpqN905a%?3#@1D&~bQccYd*% zr`1NJ)Crc_bilq6GO6xq*zGR6+Du}F-J2Ghevo^bgm|)TjsG@o2VoHtsAQ7bl&@(! zUUuP#h(}a{z*DKiz7?!?uDPVNr!C(7@$G9lAR$JxYEJ8$00y)0#A|c7VW1k`kjrB; z<~2fGFXn%}1mC~FiXh-sAwpa)b1SmVT3(FvWsY=mkCoy_%tEH>S*AJkJDZ$!De$5p zUkgNrCvYH7@Jzn?p4m1dimyNh>hg~|XwT#o`fpmX?ia7jhx8s-jXkVm?zJ9>cB_Vv zI<>rw*c|aZyWYYEx(%yzVI5>L%j-d};ib!&nDIWgRUlev7~FlVzTyqnO!bI_9z0B7 zCZYyGboOlY_0<7m!TfNG`!eoJ>X>yT!;)>q$K$4>Fh%rg>7%w+lm2W9%mw5i7U*jMMF&HK_J zpUoXO`)b2=DHK_ego~=_Ld01Sy-p^MxQ-lT1HS|SzNaBtC=0a6Lo!$@QI6y3{)>0Q zP-?YXb2jrB29NI8O@u2ei8w)y1HE`bJcy!gffwwMMDb)QGZj^Ih2SCDvUHx^1C z+aOA2No(LyU4&?g-ixa;K=co5cryfG+!u>0Z%xvE-%c&`7 zYGM?z2$ zO8~_95MKrqFtA!|+|%v;&_ncfH0%F}%);^MaRNqMP>P|mNCQvfVYp30+uyP#r<%ZJ z0&8K%zOILp1|;qjgor=e28VZ0TLfGe$4dtRt{=0P+at~&K$e-(&ihcNBFss!Ozd3b zDJOESg0Q;vZDSJlSfU3+#+YW9SQMYDUrva{j0qQ|ZAui6Dt!9M94hx^QA(mFc4W#~ znuo%S(qxCa02ZhknoL7NLimHhZ;nk2n`)}C^h1Zr-x7*)v}cb4oaFFDr7-rA`nNnmn1^r)~LBicFYaaE)C|f+}y=KYdEhT z#mQ<~hTgfrFZG6%+Hhj?FS9?fsp=Fm2@3mbA$oX-ButlMLS0Z?@7onhi^W&E)fUwy z1z`iClio6YI9nssZxPd>&)=<=i)X6&aASfwx$Wt|YieZBb^jgch!$F< zIvpEDJe~ac13_0kbvZ1t5<1-c1XstSFYufN`QRjI3(N63R zv|E!Dx;7pvSSK8zc?~>H&4@xXcjI!l zu0FC_9&R_@8E7OETFF;A)CI5?tb5i-QM7xV*vC*!fbLnj;W!`txm4ey5 z&RN_8Q}eSR{rvSDaNPE?>Z>pAN78G5ZknetI|C$Jn;i;===E0#>=>91+=KsIw@^7< z%`ILzQK5?8T(r&eo6>dz6K|~BEmR-nOSxyy-xL0+%;5soMa;LoyyGq5ige~}_{BM@ zaq?6t0n>Rz6$htuyFTHZa)Y%)(4G6ue#6gX>nV?8 zNX@H`0hI|8i0sOKCzt`_lN@Y=hE~4Wul|Djz!_n17|i)FF0%K=@8v~mR^Y8XagXg^QZ_QvWeYu z+{3?*wR~hM+QL0#C@vK<=20F`E3^B*78|yg$BTW2 z=CA@9eWr|g2X_};<2b`$`LdG?YYa*Hhb40nk1zr29Ir zIqrwE91#LqSykIx|NCz$cLh$lQauno|BYsSS`fyR966$)SU2(PFE3i!{MjGhdC5Rc zbR#!I zh)>gPn3c_A7ZmNF5=>J`CWPErTe)q9UomfTty_WZ=jXCa=hgB-&s_kWV8z|syygFJ zC%Q{oI(7`0n}?J`kGG`$+BWx?Ovb!8up5~dsNZq@-N-h$coTo5hkheG&Bn((){{=V15q@XUGGX+&C`R8{&Ev&Mb0(K&Mxg<#QppX!hS1 z-acBkNlG4xg%uu>+SQc>ONoaQZ9IBng$MnkKDsBgohyuQOkGD4SEv`HEhwT@KK23> zAj=>{l=arUr|(I5ufz{tD$_6Q(3~+#HbrRuQ|q`Y-sUkS0*rlB8dq!^#Z((*m!>}` zmpn?fF7Lz6PMyo#;fvZDA`ip5I(WRZM_dh)_1}6EApw^j|vRJN8*Kvfk^Gy>Ycv9uOkNs!BQ*`W3BgJj{<53v3U*05s< z_;IJ1=);_>6Au}ulsnvx>fXU;PNr))R++7x8sZaO4N?if=&BMz>5S#&wC*KqHd6?T zv7sZb5Ydb_A9Jth+o_F%cZ?}m6pDDgLN<1!ugsDm9X#&n*`^*vpW;nO8QdK!P5?$o z^nLoY8mYSD0Q8+yvoia}+YCx1qK9Qxy|Co;@#yb%SotBMFtYw2Zly7@m|gt_(I{Y( z5Em&R5!=HQ~IR{8Qd_87J#<>?M*}0~OI{(9AK*OnbRY z4@{wev#H?Kb>)!yIdTH%dBl;id(6s@ASJLu@YL^?IM?BF6DO;rh;d4TZwXmgW=fXM zd7aUXvYCSM7$d)kN8}RlmiZ&eYd*c)kcCvb zg9hD3av>lch|R&~b$r4J!&CSgXpvq+weAWp4O~lfYI{z#sb%qQTsOW{>=XE_gAanu(#xwleyXmC5pYf`l^DFoQJj3u zSTE>Aq4sUH>Vv>EMCd9*UIK{=1DniPoj_Q6<@KS_V1!igVuv3i6GWJrdfZF9=`!?p zmZTCm(E>Ph1>7CpP=f$-Yr6E>HLQ2-_3IP>VGgHkEO$D1E`}_JzOrmR>tj~{2+t$l)TU8eI#EcQ zej{+wW$z@UF-w`N!tUvxCh+7}*NKUZj-`5fCS#Rx&EkqVAGbBP0!+6ni-Bo-DjBKN zD0&J+Akk=R<#W_xFDVuf-l_;)NrHDt}k(V$VH;&xbt1wlRwsZk7wC^dEdP~ci;5AmK@k) zbIdF_cj|+#)}}6-y2^lT#04L%@Tls!xm)`8>R$omiNg4 z9DcaEV?@elE}(Bcp=cqsXeswll0xvb?AwuSn5zGJ9!#7#qrHWSE^CC}bI$cMQ?kN6 z?u-^i@i&L??pS@8kkCKC`7A-oi^QR;Q5C8dk$C~v6OMm{fy>XKya*nB^PIFY_;%zO zlpecOzgh@ zw%<(R={r=T3|bPo`IY5^9X zi!vnsXP-1KBW!;#JmoTVDt0PFfwPcF&BH5@$$lRAqUG9Oy7VfIo~dU+D6O5{d%sK5 zlBufwLxr26P5?@u1A+N6Qcu_`1ql!jEp&LnG=@I!IfV%c-eY=B-n8jti4T({_j*_Q znfi2V%&el-d(aRHqS>D& zgudrzo3z0uncZkh=?-fjn1@*356}JXsl-FGf2}=bXFN=ow@mz%|6izvOpz;*uFKvb zi%uy^kB)MxK}i!`L$zde{5idzY!;?lnXj+Tb!1`2yPf;}V1z{#D1*U>KQEV3{Ul&h zpGqxe8%QgZ$f&9G45t_{MbN&c3cHdm(M<+S_ES?aj916Q{!9xx^KCoHpIn7p%tAVy zbqG;;F4&ep@Vb+eEvh4rGV(`}A5;u5sFtr(mm@V(hIOLCQSD#x)qz}$6m7_Id%^N9 z+XgQ8L}hGhyrS%LlY-&$tlhl`wsEpHC}X9C=l*lmnolooX)aeg^IXQA?&d5VM2Lst zWmIJX_O}nGGkW!p4+t6&J@Ujm-^K+~IFM^bL1KE4-7~3p$6Zcd_M1(%U);nU`QJEA zCvNStT=-|7nruP{^@Vrq{FvX?8=)J%6GNT(vI2U);C1=Pd9M3rq$UgL8O(0`$+g{m z&BC)yyd)6E9|SEOL@$i)SoNTIfU$5SQpbH4ZXN|73>uI+tA-1iX~A`;#$31075Zo* zjOGpwhyg@lfTG|*|J}CZjO+Jy?~V?)g<*hSh=V`z3wdaxqkQgnzxy3eFVXd>IdB)6 zke*^cIFyDVfXst{;5l!u#9^|m)ri{J+Lz95auDEuxifGj9$%WHN^9>zWE5}L7QBWg zV;KNJTw6}6{J@X!DD^9Q1g^OVZs?)pLH$FOoG_T3{_tZH51SUQRID8Ac%qL~Ii=9`{^W70;ni3M_ofjfy_wJIZ;{cJ0 zjjTAmXCfK+8%=!^e8il&NN?U9lM9%Y#sT%5lXT~Rtl+DO?w3Ng+*5dBa^pVRlkrlO1}ZQWHfcQ(!*Ch`lonb=kzKdU4ON>Wze zF0Jo(yV1dZ)wVzi%D^q;@I0g$pDU)oY-(dlOPUPF;N&z7)39Ka(OzD<1sBX4VYh<)BDv30WC! zl#E%HdsZBe&_9ishxftE4l1COb6;pA55Lw!mOytQpD>pYmJFIo5hl5iC4s*3O{htD zu;kFXLG^!KduZDmOp0FmXJy6t9nPFihOL@l_BpJrrG27xWg+hnK#^tKf6AGLPw+6! z_Q&3=Zvxb%cL%Y`ND9mI()ZCQo2F@R(f1cSbuo_6|> zsYFAIDWGUb?3Ja@7yeimv0^3Bq*DO;-7}x~^@LB*IEii0233R6^T+Gif{dWRL=7a2 z;>~%YI2`ZuGgu9o0CiPPv$m|C&q2#*IXGM>$rw3#bmOvimY%X-XGZbvF@!QHldnSb zR=U=^Rq02s-9&j%NN3#oh7CzhjF<^q468Z`YHJt|RxbS;jp2eEi3VNX_L$Ku?wR=l za5BQ1o&0PHlmXeVj0I>ipYaT3LdqXH%=DaaU|^T<;jU-xrKKh_+dHU4mZw63Y@W7~*HR~CKjesWqK9+eu(>-{!89-rXBV}X z^rf6c3Tht)R9^ZnfL<{TbbJsK|Ab_o@xLshs2Ont^K zt%4rdt%w_{5h0xLmWrvtv%Y0eWO+PAv>I3#09am-bOgY1>I@>J0Lvj_l>l&@MpsoL z=n*Xw##%A9Ek`9fFG1qq$<^mf6lD@+6>0x;tGc_G&HhfXOxozS<4q(_U@GVVe`jc- zs+-K4_DAMy)vJo_>Q$Q*F~m}C)_Q?_xFm5AvUB^G@cx(S%e|6l!Y-IAIaA-F=N zB_v$6@Ao?Z6>WVluVX6TKARFeK)%oqv1Sw)gx>erg|3R(%>A((P$Z4vKSVShrwRxM zpEX_Hq9tuRfJ!w`asVf9vAG`6FcPiCpEzde3m#5C=3@e%VB-*i`F${T4}w?3V(AiW z;Zv^d$J_yNZCL*UqNW|y`w!z4yFr2t19dWjWEmQ~!=E=Gr2Bhiw>QMzqx%ri9HmA$L33j4oLuW46n5I`VgaRCQXjMZPc=`f930c>){spkga$vrRT*V8 zE7)mSU4^~`00aU-JM*L%#In_{=&csi%4ODV{#}r`P9utm^w0M0nhmA9?@F-wUq*nH zF>9c1))UJIR2)@=d!Z37`B1-}`YKdXKxS!=wf3u7tU?Io`f{>eNB%dEWzjUyWu4Gz z)Ac?5#U13xJ$A<*aQ9K$MMa;=g5LJxt7^>jlasRI*;(rWbZkn(ESD~+OqIS28D@GN z`U`HJ-IYi$lz{cx5v|2|>MA`b=f832mn2%%)Sk0=#V@)>g(AYY!qYjXC}rH^G5cOP zme&jri6Frt%DSWuA<#X5;AEj@)Z8r54UdD49GVVvB|qhDNxoV2Jt-tR4t%=pa=0Hs z2sm0Cm)$rqcoh~9xHRS6V5f0+i%sa--iT9U05UF)y$K4_db;)(ECU2uN8#b-4DujD zw1O0X0?JZ@vzFmaTy1N9!*sehkK-fUSw%Gl@ik{s3oiv$RJ&on6Osh1z|sJcLNxhG{BF34CEVzy<0n^#(Rk;KA?BAA%EOw`wi1S5T?|)@KA~{07oabD z&S@g*!J`RE(xE*O7?D--6fAj=A!j6K6YIvEdG^RnQ_7IBezUo*JgQ}&O?-q# z@0;ffQd2bRei#ycP(Sqr)TPOE+4_4c1mKx8<)8EBL(Aa{E8;Aw?p5s4JRYlPrgJ#t zc2^n|+?j1#ZQxuS!poVtHLb-GR_|CN=kzITK3$b;$#1S#ciGq zKq8TrxAW#UEt7ae2(0s5S0 zsA%5?=8(yDNV&6`+83*)P4W)Nf3TkQxMn`+up!g;$d~Gj(q6ialuQDl79lm~b3?X} z7 z8Jhj<>#*`X!Ne-8LMamjJBSHzos6YNFp5b5oDg2R`kxjPA(KFAq^ijx0uygx592O) zdom{&zwhxyS@WsxZMLU-!1Ir8Ip{k!UX@KGAR%Th1D2q++gIrgKtPb-R<)*;vURdw$B z#-p?DO);MnB5iKta(<(jyhb*}La3Op-`Nl1s&$tW{(}WH`r7 zmlrzGbhOykmYwoPmR>H$8-cum-VFmLLYpnl2R@i0&n|{CE6vKvG)tnGhWrdnlZOE*Bag| zv6Ad>)5_M)Qgx`zS@wP&IuZ_>oyS^>^DhU@9bK@j+u#B#vRMD)hhHED&b3Ol(}_SX zdz(9zqRx-XR&5Tw6BC^YOl7ouVEATW^>AK$sO(Bsjq^I@*}FWiggqV<$k26I%r*Kf zIA#@g>6BLtt93K|h%exHQ#mdt=Xb1Y$k>rFV-FwN9i`t*%sP2Eu#68j^N(|!KFOkC z8LI*i|Lp(rJ?4_$dCAIuI)TERu(x^OX9;7&1xX#bwEFs|pqGXpQWywQv? zKv~+?0=&w{f|zIqf8wB|VrRyLO;VDn-T-d%Z2|cBzF?s5C(V+Iqv&G!64Fi$%)eJOs6@C?8pt5F*~PS=o~OeOrD` z!Qk;^(s6wa>OKpku2cb1+nmWkpG1qN&m1$So8OWJ$Zl&n)1f6*5JHd=19@W#;+PKI zh*!wI(%lh<+l2rl4`r!V#m-~6Om2ZX%o|mS0?j198U~eKenB=|PR;$s^+=;qOj0Nu zNA&oTXA!RcGq`?^;HO8gm>z7%6Pql_;bd8CZ83tOCS~Lrt@_vGy(Xq9+$_11mYuh@}3r2Chf7bsXl??k6ZNgm;%{CbAsv#{DS904?ZKs3EPB~O(5W7 zt_OhV8N3OeIGn`~5WEmCd=hMA=*V@;t@9E&KN$Gowl{5FM)ZJwl38YqAkavrvTuaO zS_W=FtGcMYAL%$GX z_H%HQTIBJ~;{H91`htBpPrXMRVE8q|ts;ZnxXowoWz%c{BEMKKb4B_;aWSiK_rq=1 z$jZ4`8C~UA&N@AH=NZ6Y4;&}y0lQJ_mi#u2IAW+Loa*T6%kV=rw-#@T20BW91ZPw7 z_t;+wpC*G!b$DT+^qW&>RYF4hYBlti@HD|4S<_seC=!RuKp_N{o?<8U(uP*vw3y#L z_u94@fJWo|(Rcq>_~A7pbRW(1Kb-67^w{~meJl68mI-Ba8zEuefxz=)mbNBuEFC!h zbPSOibRm{xE@R;;h*j8Q-d=*s=300)L>(h-z-dy-1Z2H{GQ}|s49%2h?*1=u+Mb}U zAuQ366qC7Wf5nycs`*Lm_!2E6x>R*Nh0h)@-A7dBM+X8~@;Z zY?-2W@MhbhIi_;+En;(YJ`3|x@-F)RhA~|AdEMyy57>0nak$Uon-6m2NOez-i(d%} z2}~D{S@hsm0lCG}?^f_@Bb_6F1(#G(_#Fz_F$_#RYiLQ?RiEOxuBNzWBcLc1>Szms z9V68vXvP3bYlX zH;-2`M;t|dEA}<-x5E#gooMyT#R1e*tIy5l@T< z)b3&a47~+j$nw6>waPAwIBrX>p~)w4RKw}5j^`rJw~asyEQ3^;j^l%gp5-;x*VUR$ z2MNl!rJY6A*QE>Nyw1%owSrp{oUxnMfFauX9jdO&el1jnAZ&t=N#sIR$OL;KVAa*T z8TaHnm~>NM!73taSh)}tQ&zec&(;}&Ex>=wvr_O?rkedB4SWi&poT9 z;W|=_4vJJ0sUMeTbI$c3n5P+V*LB+O^R1jmQezO;qDD$37l`jiQu-5zn>1Y=ZNr~z zH&J%pU@|9!YOenYI9RTVaiBJH zlvH!rBA>&k_?al_jbS5&%37h@OO4Ab0| z;s9Nv7=!lS^B1SaqRW2l+hV|cjSu7(y6w$478HS^@!Il|K$ug8&NMMJF_aHJuUiIu0 z(PCH|8X&L2L^TXQw&_~x9?|90Cd0VNhXnxM(j6NUwet7X-E88l-O&7RzFr5-dcoYkQz=-nrf!?grUo|>xp-_p8NY_QKh{CGkR^bhUt_UevOVTm z#NQ4eDsA;pj^Blzk-M@|t-t^cH&{!zgn>o*QbMC@Dh&V(1KH8vQ@Imouf+tX=lH585Q-{Gu*cWfVcH)=SQGRJ41hp0S0bz4BgKiFfe4gJYgP zp;xVv^T~-Apr$yp&ea^2+2~3vHn?!h6qMdoHUoptWd`l|ZlU>UQ&E+|H(*Jfbw*8; zE`;T(5Cbc%PbqAE{}pX0p|i&Nl2KdlQSs<#`MT}{1WczLh8yi=ta^Tb1Y0zLMDyGP zFWID*T(P{diZv@A@>D1^2LywPrP%a|Q{A@M(I;nGmHcB+K>0`SgY0DMGx61L8W4W|;=*x8kJ;3X@B$g~Ejboz>3CXyiYtESMVjn}k28Rx7VCDN4Us@-4s6dY$`eW2K^^${z9m{Aq+T!S>7=?q`&%EhmekBHgb{b!{DQ zgnfaWm~WACi3X*|E7Q^7zt(VO2xUIvk4YME&_P=doUdMZOysZhnAN0%ohzvy3>Emh zN-?4I!W)^nwsM;bS9MPo0lnAuKE6vjP$r|#Mm>5s5EQSZI@;YO{Qy6HoE){)rh3VsCs7v z`v!ubUuY_K)2Gvo6ydLr$X_j|`98PWwx^wOawV*V4jTG`?$&{b6qg>y!U~!6N88GO z_+Ljw63n;8WA0^Bw^fk>o82Z_LhL{HAMRromyYby{7FEdbXYA~XsN!*N*Hq7l*Muu z1g=sX!YMQWa>YF1v#Q8KAsO|S=0l->5GTbb*ow@KY>|U==OO)OrRi&S$*4R#l~Yw- z4oUJcyo{`n)5u5mmO106E))Cib}z~;|3M3DQ(PwE-XdFawWKfZqZHTG&) z1|>54%#N?B(#P4SOl>5?GOC__hAcw!ptUYAllW7ecHAUe#KbrD9@|qd^0fH`FT>6# zhsLz|nZDLb8%X2$#L9MCkdMlF9^!whfwVs?O{ASIxTf#on-y}z_4XXESII_feOZBw zPNtbDmPyqsR{KhFURq!gnkc4PZHpLN=FZ5hLxLO2N*G=aR7BSTie58)p zBL&}cPQ;}9_QVLAQVrvJL)I4M=Sixe{}28Px*PNME7IZf@%RJe|AbFVEH&t=2`aHy zvFOsC=u`PQ?%8mC&@DLD3K0IV*Qg%lDVEE~xFV&|j|*_)AD9piE1FzqX(Lj^diVfz z9ElZ&-V{ZHh6Xq}MN4&jG6D?BR0Mjmeoj7x`Qhf83(n)=bC)Y4&dq(!hVDl+P4*Ef zOg5ADINm!b?jbXV8Y0C5z+|)y)y= zNNe$koYyG+4GTT7*2cvkMY#bi6SB*H%fnPiL|-CO2-p1=JD%=S=` z8+x6jFSf)&)ewB28Zy(f5bl0^zQeV$*p&_Zq0@@-ys#dszLOT7%9K5+PvETejxK#v z!1OZ~+o?7^U1w*&+0b^i;l~%}%Bwh8kowGNpuOPpGv&{rpW_DF_&(P2Mkk0+6xv5+ z-)yz!aXJxC_m9q^NN4oRLc5~Ll{up0iK+crS1vnICC!1J!*t(vfBylLx zAOt@A8E*j6yI`XbkHv1J{a}ar4%EFtrmCpi#A|zxMj;!7fxl@Krnb$rQRe7E<6Jmo z539JjP$b*QV*xhU4!5In&-+W(PvZkWGv0AxMFt9rL6SFz^`X2xRGBD4mk39*l|wF6 z^k}}=_-J1Yki!NaOY{JS5~nZt^Ogt^ct-XGqi7{W$#P03Iv%bOqC-pDzL=ZhHSvOp zAF+Fm0=x4s>l1Nxa+oE9|0dAPjl}%Qq^>nBB0u==e!^(=O61|~?^8V$9T+4FSFnBTZ>~3ScE$_a83FQs z%4uvqoc&uK_5+sepLpif&eNyt-=GH(um=$aBEl(TryddhIdr@xHah47&5P^Pi{0|v zB}G355m3^C7=;S3*xgKK7e0-(i6 z%S=Gjk7pYh`mkX{o?&#DEVF}dGw?lQ^=a+*&`cS#AZ6WbOCLbWy{R04YU;$znyDMZ zP3i9FeTgUr?GN#v?5?J41G$T;mKG}qlc3U>wpZYA>zRBWgf!*WxW;RcvAU;xuIGsX zkL@qi^%DnuJGm*~TFO=rYI|+-6w*oGFdAy^lj`*@v|u2G**WNu@r_(j&j6XFq+}C> zLKKF}==;Uy8V7{ZbH?JiENsGpXJ?A5^#7Xq6={(6*3J`ZLmam6rOe1ZU$JI z)Z^V_G!NI&4gUhyQd)Q79%;Q)$*>7ec4n>CT7pzXO0%2k4lV2g4V6#2r*+Q^hz%#IiaGTa(Cgx?Da~Fv6#7;ybE^$9?Uj{!WZIWvrWeqX4Yk8g@hQ`!O^d-Q& zKy$ZMB!4FH&U}%*)|r}U{gtMDc|+EYpRbIj2`~@4(b3$vM31d$0%$~8w0wUVUx5An ztheK-QXaEOfkivQw0}Q1bjDQiPUcXxq(L?hKJ26;B|xXCSW3S)L@vn!DF@wkNGrv~ zTE064Pj!^^#Sr!8Zso;dul9sIWcNKmtZOWT-;9(HS`8~>i|AIMwy$SRWiA?NJWD=T zt$|QQ4uZ?(N2Dg}O}OkBmKfrmWAj?XEAJj;Kxp0AYzX9T`&yxr&NLuF)r8Ubsgue+ zz4qccryzkoPOvaRHXZhd2>$zkIx%d;Ug@}F7Rarjj*$(By?<2wU(`SOha`|f>UVt& zItZ_zP2Fw@(QTF!c4YefXR^E?{P%3e6g93XRzYhKlR-v$I(xj+<;R*cTW6jSy7MBC zOvC#>r34c0Xr

    #=NOoxO5Gmd?q@rV?o&w8n+PjHgY|bVM~aMS5dQMu|kDW8r}{C z2en@m!tCMewzEr2-n5`qVYnPtb{LSw(q(EQ(?|(SJ2d(j=)_t8ayZ-kJ%-i!sit@m z`_0&0q8oF|uIKh_yRTr^u#Xqe!fz0eTgn2?u*vLVZ7;-;6l0*dfSb`Z-#D;sLC5+5dr?F!K|aw;eeL_Gzs;`AINVW z)Qt(YUwLM^pFXcgVDW)4T|R_l8ssG}lt=Xf&fsupHO7kR{#nX?29LqFsk&)0AWB9D z-&%~x^JOfoe(IP;ZB>Rv0tyZ!0`UBF@$BIU_5Si>VoPG^%x^fMAfiaC$YCF`geoco z7AJ^1gglY}-UY4L#f9}XW_E3j!OePJkp#~WRk8pQZai=fF{2xR?+I)UePiys=pD&+ z&=}$Z?~nTZQ9-K~4_4BjUD|JUffpZ>SB;mxVB!z-)no;Ni1oI@SLvbieqXkVX)PlV1*A{ zw;K|-q1HH%ODwKOfO^0i8_B)%dVt#)s49%;Zse%+tf8#&TJbxu0 z@m%GLe|uEFO$R1UOC&3_CV7i|zHp9-w{>N{(E!QEasNT&lm4R8uCd@q*(Br%&4?2U zcE{=sLLx=X`UB|=iRFD50gcrCSW@m1f;o)y6<)6E`;lplyqK=K$1qquN-qHPQVQxw zleZ+`(^32ds{$jfcsd{SM}5ZSsq=NNJsc>EM;=&1jmg}MH!lSP2lKvA+0W7+3zxf5 zqD-9=?+(?W{&l{*x7~+ ziYOmW-cBe`ov`83y=x`Af8wLD*+?lO(`&%}^EoLTO?OAO<6sy1#}%rPrTp=vqP4ln ziVP&rixSOvbWwF5r1ZJb{@DhupGv2%uzG8WCDNXWIZY5iIXWk)i~(s#mk-6KQk-f? z1%ttu@}Y9J%E?TCP5WcS@9`7=5TJ}dDkHS<)#K4R>uyqqII@b>RSXefh{r=iJ}8Ai z|5N+ADh32K&T)?_GDiHKj-)|`$WBEg=k#H)n~WpCgKYu`y_X)a)!J;Tb2@O^ehh1f zEgs=$p`*Rla^xv{zfcSCSoGIewNa;tUDlWQ@GoCJlOV$u2sm&&NbEiW@ORL45u68) z(|1Mrmy30BNcw>7{I!tgZh zZS3vjYLxW4T~U*v6)Vz@e)LEZlMELg52@yMR&sTYM^yXun4`s-qFKt=&YSE9%KADm zsfYuFw6b6F(}|=()xJtSLZIMO>{eS9m5_h{SI=4&rW#QfM9CFmv&WH(9p zYl0=#*41v1#VPn&5sgf=oCwh6R|HGz-Pf9$3EC|F z)erOBM?fXiyK{l701{$wou@k{Uski+e!Nu}bKj})U)OWzFQ zCo!SOw<8WhyE;GRK06yM*4c*n6p16S{0KT0ng?%URxSG>$py4cZY9r?Z8|5UjEkvC zzLvvStAnlOGj5}tKcKyCFms+#it2h}!*XQFW11QZmc*3RX36&OO>- zjfisLwZbNO30fKEJxPZo8Kz&ZJzvA24pq>voPUbL8BN==?3+VEH1 z7n!awvKZ{n2vqg?Sn_rAVn^okT}=#ur@vbe&|W?vrr!_@gH_Vz7~g|PH}&=bNZ#D3 zh-Z4|w~5Xx9_nEL3~fW%xNe5yq;~@&^c8sA#nOZKL9ajlG9Vd?P2Bwuv4cBKfq*yd29$?=$ z+-bUbJvs%M;LI59XaF97XLIH=5O*5M=BL0KlxqeNp+m80%-n)xQeW=XjQJ}>0m&&Y zX3Hwz?d-(6W`WqS~yJBrkK?R8aejoM7%RE$m5#Ws76Wq zsv6qVzv#K4pQ5cGkp`FtzpsRyF`%=nqDMW;4ZUA5RAM$9E88S^>_v!L4v|daTp^s) zND_(Arpr5xtSE**z_ulZ@Dzq=q*tuUhhAi(+;f=^s|CEQeH4}PCmO6@Qp3RJKY*fQ z4Q|vz$u`b?{e@>ZMRa>85U=wx*0CKUPrV)v$w$|-Tt36hiU|ABzs#`36H>h})N#mr zKh%McV2HbLKCK$5ELqvu+--AcEa{QIw>tQ4Pth(COPv<(7N|kT-0gF1`70xP10@i zUS3CD=wPPN4$j4Vu-R1GaDA?IR5x_Ni=ocW@L^UqJ6bd>cv5tk16-ESo-H5^O(%tK zA$KA7--Zq^lVioj?5$?kmA9b=hLkgzoi=TKG?^7ZaIdotbq>kmM0(v^M7YisQo_;) zJD*5A5~Zbnf)cO)X@INwMD3)buA(Q;oiMpYl57jo2Qw)1*DsAh<^-80s}iEwmz4ji zN%F+e*vIe8jpk*9zjXm1w)DTaXim#qx|OHM6j6x2ZAZEG*Arv#)d1)@?bz8a zz_frjXo=i>DjhtWH&+URzh6L5n<9h`9TE5a`T+E&*dyUUxH51(4Bj-nzxl&KDI5nE{{CJplA zj#4_>y)qogm`kE;RSYwTk?e>ofY=*G<-Xh8!Xz+O8(_x*_}Cl=*wgK#;v5=cGk_R-1d#CUR70NKi{ZSx;#_8n;xF!{89!>c%kjG?@p zD&AVt&VP82;HuyXbYbw(_0XARh=3m^;~d}XrC0iJ(Glg>LJ(VW^nj|)k_n%aR|F0( zk6%=3Qr=!+J1UVNd98F;;_+KL0X4Tc%<|;tNQ1^*GJDeq@4}Ic+Oday=sDHM2s!9+ zgs)sxzrsic23>A?Cq7uX8L(=EMaL|Z<(&K)oBiK*fQb@vpq%F0=sD9pxtXDMpW1&7 z;4TD>f@N3kS&yg98`R+LS%^K7e_r$e6&8s=@RaACX5Tg9W5-rgLDWAN0BT)9&$ zFg_^nO;2A}+?7HywV=21SghB7IaDon`~MHuEe>ps^Na#UDT{Nr)y2@z;mAt`v~UN( zT5mJhyxu9`{}|TCrYv%nNz`4u410vabC@-(2LF?KPv0C;?rf_#j`Pt>XBn#?(b1OeDymp?zsgke=irTQ;PMd`Z z%WuZ!DzLJ1<%mFnvxuCt``OV^y)}q@Ua{J*^=a?M)It;eERakaULU=<&2VY)>Rb`} zMb3BY(80hQ)dgfoa@i(xa@dK%W|wa}_L`muJ`dHuFyNw%tSZ>B|D<=u;~xV2mY@8% z+p%`rmOzMue77dZCC*YdYS@jf>!y%ehBecO6q9|!j=Awp42ZJr-M-PNmhCP zEEWbq-^we=9ubiQEw;*u>_n7j=pDh?Jb)8DQk95t!@HOTYfkkXo#!A}zafnd#pA>I znv4O+4sjjiGza7>u|Jel5`dku6Td;fR0#`}{F&>yyFpl(Z8aA@K!R#_|jVUF6B+U9-x@a{1&7+;Ljej(FbRkL+UZ@7Y-wc{BhlcTP5 zW6!DrHJxI{GOtA_hM?QnTV**uNvT)I6J={EN)-VyZ+>{z6ypVAMGaSK&{dP#+f&l`ZgpRw|dA?fB`1QJ%Ig*`W65F_!k{1Kx z+dD>}7*auqO?ZeiPicQDSm^reqCZ}Vin)I-dN(!P6;k?-I{zU0x_u<&7R;-#Taw7D zGLFKlo1u?ct}Q*)IFnE*Zdb!qky!?LC^*3*RQl1*+{U|^T9yFSwDOL47tpPr9qq_J z4K#c&_pt}rjbzbDk(dMec;ljRS0yx|jUEVxVWjbU zOTIX`ElLu$E`|O>6OHTs9Ujd9L5h6@>7Y#JTvPbJSg=7xu4E9@zj3KgVC!_glX?%% zpW~URT8HGuK5W|d0*5zXB6RAY_XxtYUjT5J79(_76NmZ5b3N^Tc@d4Nr(=FBc6o5W zQnwY3%GF`~nF6La^m4&?o!M$!hPt2nF@-QwWB!NIRa!;Va-2g%* zwSZ_Ly|47IMlhFOzGgytmoe&cuaVA#&?1ZD&I36fS2Y;^x3fS3(A`wxL%%$@AwJ{8 zdcq40H`;*nC-u8giMy4qIc4K$%&ALA}v)t#T^|xcMkz)LK017|CDE9>mr(g0Yr@mD#^6y(sQZ?V`A9$ zvk+J2;~FHN$XoaHlLON6YyS4}eAtHsFJ1+IZHxjJ$7@gr!r*hU=8nE#|+EgG8(KecNzrfj-9Gw?4S!#)>(|m^b&>c@wY!M|~alW^$ zsIM+@fenUE*R^-2q_m&3d%&iI1*n~tmO_L4q?8Wy?Nw-}gx3zIQCN~%p2wn>RfmAe z=0wNeaN+c_;ijH*UFa0e^>LV9B9mf&?T4{ED7Y7!HFjiJh-IiSEpXP#b@v)r)ZQSW z`%$N|v?I(z^{xNkZ{;!chvoXEg&Xn!Sl!*sU?cZ$4R(WUQIuVz ztm^a;>!R|gt?=odk|ZDJ>kPlZLynb?dQ&1A?_ATT?!-ELaYvsyZgcBV{MUm%`qf1s z&R9Xf*#e&SPNG(5+ia&yAWd8ZAV;6BhBL?`2tOBmlJ#vG)3NWi`ZrBQCI=ac&I}Ch zqfi9`55nF6WznmyWn6p^CWkZC>{T&Z8JNVJ9lFH}OY!3SM&w zG74Y~pc5b9k70|sTfqa03<_4&P1e$RtkT{+4a&DmZ}o}VqCrua9axzIeuLgGZ|pxB zUvJ?l1XQSBzXhvnTti0W${Q4Jd=id<;_>O0p-RdaiNg7fuj?+2v=}O)n!eiDN}OOq zIpIbx5c3mR@ar-&BFhlR-$2*dkLpT)B7Bf_^O&{t@r&yr{ zBA+Z47Do-(phr-C$1;z&Qseo!Eq!#eGJWH&*yT`3W2*HD31JwL&>q!FURCE%suKiW z=K7~;Y6bzEYxSlq%3&lIeQ;_{eh2wtTvms?&&fp?or!(Iz@C*GW*rP>@cPe*Xn@q*M8^0U=sn ztPLPr+(5%!dKW>*dg0UwEZPKdqGB8SLc_Yk_8hpC0tNu{3BBarH6X3yC0x=2U) zW||3O!>w+puMbSF=m0VI;OEKijbf3CPdf+(vqD%S?&OMsR9GwuUz(W8-ZBF5GfK~7 zX|I41CbNl}hm2U5e1Q!9NwKn-zb{s-{pSa^nhZ`$o?^>TNayx`rKI+lT}umXLlAwc zh?21R}QZifMcY_AG}@;Yy)Wsy_lOFX$>ZfZ;@`=fRZ%f1UM}zTW5}z(^)2lWBmi z$s-F>zdcuyn@_n|jlM{?!IJYXyZ&`KjR_{=b(5=@Q%|ed6(eFcUbcV%HoiV%RSa2o_&fAGzed--_mjZ$cu z;f3t=>xk5rYs58@nmBff{iCLuIS?J~oD@Vr`-l#2nK~8?;|Su2mrgbVSl7XA0$dyF zzYbhQLGGMif7czlZZz7U#e&$%s7BCxw&kw5x_mq%ye`a^Vd-t@@OU>Fpp45!WPz#M-n*R+s%(HT^T~v+Xvl%o7kPYD)XX%V<0d6zS|=II{hu z+zgzz0RG#EUDP}KG+sX=o)Jc4>>PV5IeyXh2MJjsk~D|QjOOr@*^UVs12iIu{ZKWd zl=pc>b%ynaW2N30W@tG+r}Wugf-W>DQR`PLBJOp^ZubW$d$HQSE{B=y&{cAVXvkvU z?pHPZX5zCo3U7zd8!OJZXxvNO=6nKo?)dH7V|0LSQ4>gVkys8#q~d4?cpyq6H;0fY zA#LDkPs{u%^0@dHDA|2)gTPvpzgUqlIMd9+^k{Vf@65T19a>AEH6Ls;R*n;Z8G&m% zT!wS-MtPRF*($a( zy$ia*L%y{runtyT@X+3=m70y(5)ytFiuSv$@FA^iObvE8Mv9P!8iAPj>ufbm<^t0rIHG;? zw_6oMLit=EI>Ln-YOa@b&UrWEE|5%~r&9T`nSNYSe`O`AV6IkZy;G~-?QyY|#+cJm~#{?FVCZ3*|DXI6BMQBZ39N zcDK}_R&Q23uxS~Ks|C9!wbknU|y8ms40 z-zOE4j1E{xJGDf{L?&PWhd29inbQ`*5-MU%wQN=H6vihuiGc)r?VNJLpqH&Ot!F$9 zQJaV3kZPe{l}C8C-YsOuDqr(jqMQlRBo}=4m2eVH1a?x)YL8a7+--Bl6+J+-44PX? z=waO>dBbQlX{}3Ag``yura4BM(?N_hiKxn(P8|e*iEgq82)fsNTheuuUj16NGlOJE zq-4u7MbkrKwaD#t62(EeIKaFgM+Z#)p^G0}^Sa_Wol&SkZIV=1fU^41=LSElu#>;i z)?|~1ddH!Udsi5Tg2#jgH{i{i;Svn(*@{;!owR6_U<*{bst~7nW`Jfs0Pl~>_Y5Tt zq5DNSVx)?43ozuh>{apM2{yBH;2L>t6f%wIe2*FO3vSSCM@a)Reqb3qla;@QUe_|# z;~Z^$V9U$8iSe$+ZD)(U$m?{id2|J0wdq%Vz-e19@~8X;nN3k)0O|b+0Lv;_nT_6u zndo$X?q8s>!UaaD(sZ%?%ZfTLNTB9KEdLq1l#hdE43Jp%06$B~lZM;r8Vge6xt7A> zkGn7b5Eu)QzMDN!`<3+t3n+AO=QX z;w`}xGGw&0zeFAWNaAy0;4IKI;4;i(H@C%a@CIBtsr@j4nI*StSpy$u9fw>v=S2;{ zQnRU5Qo9V63_}3evTY724w3hgjC|5z(w=RuDpC63vd=%MV80=utI^r{ewtkzC}&E; z>dD;LGP@xG^04I8j!iX_owJM9?hJ{B_RE3rg$NruwI#txLL8ygxZWOJN|6=E z2`_+=#AU;>I-Q;{TzY)q=1NfOq<^FQ){NG>%;s!JZwGp`7;wvZ`RSPbql2Eh?>vo^;G z#&|zw-EM^A@AZp2HqIqQ2cSoWf!@>HWOw`q*6Z$S3=12T2?@?G*!=HmOJE;AI8CUB zCx)H@q}kX{nGh-@4wD4U7YqG3#1!pK9}x~-EAYL~pB+WMZe>uF5_s73sWW$sJPhs8 zQaA()+5&Lt+tso?yyjStvJl7bM~-g5%#qfMOZ8`=SkBDH>O22{g)Gz78hlHxTyPP2 z)-_>IQ3<+MQ#P;|syv*txaD9;u3udEMSKx+t`_m|?~pz{MqfqWmD_uGD0~kueSBfS zWG+R!p7RnQjug7PA?zAM;tLlB2qgp6ByZgdRd#k<8`2(Oo)VlqzR9& zVPAn9{du2g%B@6tm^|H7Rrv-JGRzW$=9_(+;rsyo;hhn6{vxw|J@Uw(=v>;m4;9YT z$o3GaAGGR7zu~MrHOe4{==Rzhn_CD_pt9b;l~g{{a&0Vn-1~w{p+aFr8Jf$GdXMYr zkvGj1l@&BY;z4$ESZsw!(Br=hx4%sI_#nh>^?~dqDp_-%K9@mqh+*4{cTt zkjg648omY21H+*x=N|*~hr4)I5N5k>faRtcu~1gutjvg3{O33InLIu~lc>Ku_%;yB zg}giKE=4|~716QRUowah#4g;IhJsN-hXMMWht;?_U{8|&csPoa&GDUx#7dtpj7-2= zWimkr_63#EQ%lPj(wLK7=28B5;it& z2a@Qb`6XJh%wdZ^)i}D=8k0);XhpK&$NQdlrMo&J+78>Qry%na%NRkN2`5|t?m;i9 zZI%8jCc$F!yTbi#n9A2#oy@`~wY;v^d`Bm%29pW{S=?ZK0F-32LsP5pKE32J+2s(S zR+qW-v@*cQ>_g<<7FZ28d>}s&N-5b#kP+Ds`l`d1P?$E0I(ub9~zpxIZCW}uv zNyA+~ZlB=%LrLuW{UPVZzx~PaLCr^&G6U0+mmFlpenvbbgLjU5PJ|n7_n)%TX)<*< z11YNo`BJo3}=VUtDZ(s|z7ZE}nF5oo-xJd^v>0 z=aAH(d86%mgLr-QX5?s<*2g=UT8FuAWO)XhK9QDwcJ&ie$iuWlJ$EwZY-bC#5euI><3$)l2-W_H! z<-gBf&erCtn)U~SfzEd&lhZCN{*O%sF-gkDM@nX}EN`VD{pBG<={Gw3K#g^MDJ(Nt z6}?L8a*UpvWFHKf)F1}}NH=NYDr})=qzxP!rEhbrLOU0JKbCue)m(;DedRSesHo28 zvxpUa#IORz_3q9d`<*v&dx(FnPAH@>C?#`479%fVNdwIsXBE(e|6Xx! zfljdV=1Owafr(drpt-`+fD7tx&2BS*`00`ZPoF)o>o7BB%op&v z4YIP*i>*+D77y~v0O9}96xBCr{p-R4Q$I$bX6;LD)>JWBNvG|!JiCy95-el%IWa%AR`zjauo_s0ImB2 zX6yD{xFzD-POEk@Q(3aOfpUUQo3?e%ZJ~uTkHa{k%J0sfY)I1}qrR8#=aOztse)Te zCwZeeAD8-9$sh38E^Vnw+qUU%$WI2U_^J&=;Dcu}D+Wek&)uNRvr=KMdGu?6fdqyl zZOfuBm#c=-wr1fqg4S3|=dL~4c_~3p7`DeafBmqH>tYy}`PD4x69((FqUlv_W9qCZh-4xcb@r z_#v(1y_JGzMuGFzZ#x^BR;t8ipDSky5M{(+TQ~D~Y?s8#J>32rAFJ=#yfHLHp-+_= zk2UGS3S?%^JfcIky`JQUNNvYnZC_Uw6J6H+@MtQshfqGm=I-;@)|`Ss>%Pw?mGjE| z&&(G%)Bt}8$fGKQ7&Y9NR^lMiY+p_mkOhSA1VGNF&axAR$RQu7q;-_DM^GPNdL&Wb zh1v=`MCi@XD)pa-ZA%Bm+S)s6*d#)NsGpufjY+ za`VV)`foyIDJBiOcx6BSFKMosJqBwZNsoO2vTcr^p!uN|0@fnGb1Fjb&hZQbUmvA7 zgL^XU@HlY{_d7gSp(sc6uyqti!N=`LfvUS7@hxDOp!?dyu^wb(F zC-wZS0)e8y;)lG1a(sZCatO<;r1(f!9{P-MlPrHzp!sJexWypFyo$5&<>!-4sOHNCm-FwTB8t`<*dN`Bb+bp zfX>C^hY1Ht)IRLD*do1VJ3ob&{=ZatsqWv88auEVzyv!iL7_{QFyZf+{Q8GeIPWXM z>D8>xv?B`l4FSD>X#a5i3E(A%)P+}DzW$3!cUzwnn;T^g(S(INHH7nTJ*bMGykW&k z(C0oB+=^~!Bpt7yuRP4u&;kP)k_)+9B)q91he>PqhxKln4GUq+o3WslP;9rSV*cUT z;%qLJ9kIITpTsMKdJD4%3#lI<5!-`rOP8YkB1o~e?g+D1^a3C_+o011e|rPTk+Oz% zfyjy8xdS@5`3S7MMcM&XQC_VKf}?YFA+DDZI0Tlv3M*k!*4e=aa|p!G4_*SRurX3x zq#Gy3g(U>+EU&fM0Yt6P88mjfcns_DE*Bq{*xXgUrFs^wVJYL0aDRk25T#vKjYc69VWea*zw2g}3 z$t6g&p90+YlcKMp6V+JopaF!p=V_JZ7J|Gp|KzF{$)N0q64X)L`9F5^HH4|MqXU_W zwqzsSKiquU3`r!y=o{}CV-{_G!D?&}^a6X4Rso)b(GZbNrtQKv~AU0b_VcIT{#Y*E$P|M@UFtu6b)D zPx%`)&gM2>1jYjR`Vxy&UXUDoV49&3SP(OZ<1YNz^Q9ZsQkc)oTszoUDa|g=)9nJs z)BX>BtWV5f_dhfGvPbwyt7O3U&wis(Z&TzYO_fau(Xd5X`Wu_3ptn4rX_)=6C| zU$j~7k_2F`?pDZI{5Zo^Y)UCo#afy?N&PLv#pfczC7`f|_(c+mN}=fTH|d<6DaW>> z`a4=;l2g@JUGRV(O%5gmhT7O~`L?ReYRw1s7}=t%Vm!?LOS1-l(E%SVCd=5YDb1?% zm)Am**=ynWGHiWffECt+rYeeSx^nR8+9{vMcH&rst{W9z# z8B@O`Zl4PCAhCGrXe5W=1!PJ3F+-C^48^{Z5c4*SiHu>v`$h34Z$y(!35`Ci#3d8h z*%v;YmyG8`gK7UMG#U+2VYTA7%^=84ba+J}@1l>P*bIi&0QJuC`Ch=Bh2SgF{K_<@ z(sjq-L3PC-x4=MGmT^&LVd(bynq4m%+oUTGX8YV=kfZvi5|f-$f?Y!$aF`#!U1)M@ zbAq8}G8@MkQ+NUkI?W;q26-TU0fQ>qRwfLm*#65HxXGl1SRmr}aJde0zNifwa>-+b z1ePTx;=ZRJJ@%2Mefs>pzZr<049Gx;{(?1&&X@xL2uzF}YY33*V0#X_TasjcULrGMf=nM3g5neJzal7s4|bk};12IQ5d`*ybZ~ggTLntb@{v zNZTRiU?&mV-l>PzuR+dAt-(AcCV{-+oAqhpr?-F3yo3j_eO$yHK9yVCV?H8V(?(Dh zMi#ux{*r#Qk6Uu|T61u-$jc(m_Ay7+eMXphlpmf*X2R8lW>`3Hcmvl-Y$~6p2(+Uz z6Z6f6UOSa$sItSdvJqB?Z80jEf05#phl{8o_X{5%H$7O4DMPnSSOoh1U;e}eMMkN1M1+CC2*Zr(=lJp`NM{Zeopg< zxXQ^Nql{|UM!fP0>IV}tT%hElbLJ}YQhH)D@#;IcT+ed|vxt_&v>Ne(t_I#r*?H?X z#BJl5sd=iu*F~J=PN2OMD;Pug-CVK2a%HH+Wn7wBsI2es#h$2pBn94&FA~Fxemw%M z_oAxaer7F;`(1pR39o5xLGs{GmHAc&6{aMAzAkr#km*{}uC@oN$h8M@%~t{Am}=-h zK9!PR7|PnX#}aNZ-So6u1V;Y)gV6S?wPP3OkvKp_h)sz?Kjz7|Ol+!b{*DCB0ei6f z&oOzK&D_%@kNXzS&m{4S5s1Mcrx^SK6M*T@{>FA~gf}`oYRl|brkvlV8MbLgtLX}C zhQq(%2&@=p91_!69=3-BY`W(HH(LaE2EBk0){Mk5)h(ud!7Wko4d+@eUqqYj`*>#z z2;^{zQ$Mo79D|!SkxB3M&#b+96vry?CmoO)k@odU{8tR?!gD+))-u<7SSly(}Xm|2m0B|W7G>ikE=vdbz<`5a^Xm6BkoG!FnEhi)-_ zu4y4sT7i9rQ)1%W*`=n6$X;H9IvE=2P=u4fNtS^q){v5YS~_2ZefZh3)j6G$_4qDL zBWO-CEN)~)&*9!-m=NsfnOUloL-UXDXl%u|X|`-VsB>}~WrfFTusZ{K_mBS)NoQIr zWdTRFIU&B4(g1ymSj9%TWo|!}H(D{4pbKD5Ahhw#Pb14_0 z`^q|8-;KMM^*juKa3FxpCEtZg8jJbEAT5%X@T~0wZ*2jWX`7x5UM}bg!==#~2sdPy zSg%f8{y-Y#4L+maFH)`s+P{YGgf~{Xj{QV20ne@Hnlh)V}kuP84k{O81dm23!J<+y`DsL}N9#JjmOF+-byOOSP<;T+8V%2k0F zKYJu!K=Tt`_?`WJEFR_6gK|i|9!aqV@Y#kYb&A6C+@TVR*xK9gXms&^!Re~aI{?4% zvY03QGV;HE-haNGN_qfU3d_Nz>h}aXa0ZH&)ykmCj3yyUTI+^9Y>qq#FUM<$H@=23 zn{rU}pWXm{iWF)ssPLyAo}8)AzrvPV6^4*xbr4XipuLR9X786fiviMfV228H`J2Te?;kX?^V)UDG}~dB;caEP_|lv3^e!*= zR@go??f8=GEEqPaEw$x@UUnHBI)vCps&Bjnf;I@=utgF7yQfWi^4r#M?I-VSOBO|G zQZ`)FqD(8r5NgS#0=2)yeOw)#SD=IwpKJ$&;{h|W`||eNFm(ViK+eCK+WaZ^-=agf zMbBfvv@xt_S_e5aD39BXMNdy9%V^UcNhzz2@lpDpOCeuTJ_E}Kh$^#PNXx>=goY{( z1b(<-Wf_PATGn_CD{kwGsbKodHo?E?GZn0}b?Z$qk^RNQyPX_}hQZRF!5ZGlTK`k%&)NqBC>;yI*GEA6c% z5&HFm2+dj4`ExZ!XjtFUGvEuhk8Z4Vl;Z4}?W%a45pcF8P-hf#KcE|0Thd}(51K2MP;`Ml- z7}=fJW#9~+NJKMRMmf;!Og;JTIiufh z|79OvVDXJIuUykvqI3NyUJrP&8=mDD)!tSb@YW*C?K70A45KKyh#>(%;Dt~^kbAtlSM{Ti@@ z!d>MN2o+jq1cYv3UFfTOI@f1bIrmi46WTU|(75=zkcL4WIfR};`0+6{%*!lEj4Csy zeGkrl4&}8Ns6})}WMpbu#K#AYP?~m_=l1Cz0E!BjD5EPEw`9)Qm3X@Nnb?A6?xe7y8E#82VMgH>6!ZV#P_94?RYM?USRAs|!zHOPD)Q*?;_Y z_;%40_XmgyF~!0W(4lA80mQDS3J+$9?IbEMmMgkLv%L*LI_*8uX@^fUbv~;DJr25D zq3AZ~k3S)qb{)$#5C0r(jK&e&Nvo-61Gg=-m{SYQMDLVf&5qh&?bv&kNGOIuN-UgL zSf9pjK$olbt^n)Lu?DIjr4wG<7^0tWRG`6#wDDjlvvpTFA^RBE4GQ!!t=*oqpTkn@Y7ghD*6d1881!C4-SEMCZ|>Q zUJ4okIqbTz0UgOs*#|GyM?4qd^M0%h5q0SHBIbdD=nS0=V#i#YH?t>%9P8eCq5}Eswt}#y;2waY+>;Y-4b9Fk zI~h{>F=hKCvbnXTpa%E=0PKu<2G-W;&r#Ax~~>8gCDzXB-W z2jf`RWk#HE3<3bMyGZdL&MA9&c`oVZmjrw^#yp0fEnB}UxPQCB=H(Jg3KUw~*WM0B z(3~H)HcOMtAX5qTKt;e&2|o}+;k#Z}GodF6Ih$!RMgL6gg@;O$G<`c z01ZmA)K}U@*;XeNAS5%(IxETd^EauUw-QG3LUH{>DKM;PrhxjVz+Rt9(I{JBB^QV+ zoNrjUuCqHBe9leR`^8P;<%kxGdcgf}ry>0)3wGyrt2r!DSMPrYej)Y#Yr2+D?1Cg!#O)xIi0#KYyJzV30rSXQa zxVZg1DIzq`)$!gT@|glQneJ>L=o&&ScIjV&EVYp$KS#Tx3U>h{1%XKBCmL<{9@DiORWeCWpI;H5j`hn7>Oms2c9K<-fr zI_Y2Q{24jt{l)R6h|v70z{gNR`6I5S&T*n+$hxc}eT#=toZ@mG34{-jz=XNR=i0f{ z8*VJzjBz+5xPJ~a8Fkv}5QPvp0t_>#N(L-mWP*o1@`NT>VinojM8c2|IE9$B0S^** z?`5+?|H+}4%+Z(`aV)Z2~;1rGpaJ3w*PWg1wI|4dNJ%Ct{S5pS;`38v;>n|zXI zcwtpd5Tf3&^;pu_bcCZrT`|fnqttreP;)sZo|Ro?;^_$AaQ9>o|zSCYOQW&}= zno{O%tQXGdki@QQ8E3lg@d`NBd_UN=e}Q>TbHsjeg7oT#K1F=uWQp<&91~!J>^y^- z^5p*HrO@)jUmm@J=rU{RyK)KZThH@*{;wr`g#*iKyX3yV3&?M`Rm5&7>BY@e5s#$@ zOtt%S^Ap(eCQYgSviGixy~{jJl8W&?#vjh3w8Tn~9Fb{l;y@+Z=HNEX1o+Tf_!=t9 z)OP?CaAF)18bYsbBO?02df`Mh)y}=7Ft-eJknynQiHj;j5+;1NYndapyx|tKL{W_C zpy7{pJ6@EyjC9>a0B)2;#yddXUaetd$cvn>I)cJ{KjbhiGmm6)Z&xBG&{7}Vf1&P$ zAfrr8YacSiLpElA-D-AroAV{~@VcAIyh`Q)Th0I~J zx)umMf>WrZX3ym@#Di8NMPnvd3e@X+0s%3h=ar(_EH@4vTF1Kzhon(A_1_I`6lgcd zaz@v4DMhzuJC?s2a9YGCTqt6@ye!bO%d@s%@g*W7HoN&pK2Uya=8oc!K%^I>b44%P zr?-7rZL05aba2`um=j*6s6zIKx2O7e+|E6@^(lKi03W#nAz^Q7r@49j8`0nMdmaC! zF9_9UNS6q;tXMV3Q5;&Rgwi7#316wfS6#G}{NBcAk;2Nh%*WNuIaPo5A{#RPeNR7J zcctPwJ8dGg1x-BDhK}PHgSooP>$+zC>KsxPcPP@Z%h7^WQnbPeK!uV>7XN{Gbew6A zf|JDCeoB7!gw>q#`&jjhFzt52Q_1%CKp(da(^e|BV%DOImZa-7Rp3C6EG)%Q%aedA z2>68T1uTbd;som)+o*}6Am8(p$N1j4>TTQy=mQ0c|K1W{LF5Wxd9KQ%;HzOi#e>88t{_Mq@mA$Zi+fv`ql{oR!pIHQ4WwK^eFe$ASY{Q& z1IzcHSh!wt!pU*bYf5t^oM3|25(`@3;31L9KCty;T>qQwK*V_(LQE`2A(h33hM8*| ztpJdB@S4w0kD4@u!e|lMn?<-BMM@3b2r5NTAs0tLd46}rc{XwnLxhYLdPWrUje4oU zA@mN+Zf9LJ4?^hQPZJ9HVrE$Z&*`=LM534DBrWhO6Z%sA-Qm-sGdMGp?Nsd;n;aL%ub@a=ecX&z?%b9)Y8Kr-WFNsh zDC<$4XfyvR+I47_y*(pm zA{6%bue``iH3|OBtDjblu^>~`YsQj*$n+DT4VelUB9zQUjZNxxq7W~My0-2@jr8WP zHsXnc%lus}@fp69B_+=nXv1+Btl--60*2w()hIb~q1KS{&djT09Gc;3q?w&HAte?W z?0UFLO4yc!7~nHwzhfN&(fZ9)YI0_4{laI`y?@IC3J?ti_IbQLA+Zc;6iiy%vTkWq zSTwlqYfD)Y83xfHikcm$8X`8-y&2n{!o(T;NV}W=PK|2##oQ0z^&TXjZk)U&Zya|R z-)iV5Yny_la;(k6On=5ESCI9I_?oy~>Uf3a53>DuNFX*FGELq#$wJm>3y7D@fmQ)f zbUehy+Uw;*rpr1e9uS?NR6WK1&=EhI{T2BJ`b0~GEG1o>0yTnd0For7HXK>iNA$?@6byP{W%QRCJuW5h zi@34*y>#WXn#b}#G5obG@HGdcH9U(cgxO)t6O(AG2Q=kIcXm$F#BgXE>7S@}aab2h zaIBVnaD!@WUUsK(92oZsuDNysS8M)H+ES)V)qcZ|oBR2sIGpFK5aipx+w0%pB$>&` zs88<)+>t(;j(TB~`dMF!f{m41L4{0!?`!A3PNU^|THD@NP?pW&Bs7`J-+L(6f(3Tm z?()r{q~F!kW?=Ra*v+`G=o!a(lYm{86(X+j-`k;f8Q*Nh@8jxTo-t{5b^XvW5pC9q z=;|nnH2ij7Q}VWe2r!+aT_J+V*6FxHl!GdJ^gl7ocl8q2SO4`Xh)l4sP;2_+B^Fe| ztirMYg-}<1oaq`5tgn)|veK(Avwgx9CPGU^Ub^0C795|?Yf1C*N@8{DI!HN5C`v|F zKJ&sXEd$;K!e-G;^?d$}Wpa}aPXo%-oN`3te`)*SGyhRnd|>wJ7zC>zivew`Y;-E^ z>u!S6tEjfJ-SwUaF895$lp~0SROH&!Uwb|J1ukC;X)YCe+IOb`EDZo9vEs9$ zMpl&tc!HJSNphl$*AOf0`_#AB>Fs=;Rd4I%5<(}g1m2n^+j@7)uC%-4C#>X3&RiZB zbv8dCXjD6Ic7r|ny-Eo!A6EgCUkxLGB2YBp9gHq1UYAEC33BB2o7Uj$sXR`MK?`qp zs??S{dh+OqhDCKTVJo}f6OrBf&G#yZ&g!5Rw8L9N)T#4y(es8iu+HH%#Es=Z@lfQv z>1?rN97}V$P$n5eZVUW^M3MC@%86pzwKzV-$if%oLnOjJCU^LDDb8&6>!cO!HC|uE z=fmKx<^{;i57lE0MLyOeT*s=|_I}%%Uh_xR<~;8qT0W<=9?9n8B?F6eLr*dvHp!IK ztB_U+wh9+eCF?TCT4nZ<43Bno?;J}Wd2>)QXm8s8p!5}VHk##m!QuNv*{P3MDb2!^ zmOoQ&>DCbc3S{YCoR0O9=y*hxJ(=k84Z` z=I>S8pSxAlyT)p&MEGJX?&9uuxkV*VzW1cbE=?GtrO!=ZLPd(B>j$_+`2nld|DPEH zxdILXp7VJ za-r)do&@`JH2Mo3#Kn zDUUbm6!AH|XV}Y7NZP-EnKq@JGJn@V*cP6Ew%d+`Nj2tVP$5mqyD5ivyFwSTi?1$+ z3DH%V0z4Xh`W5-73BQ3|y(Nur0iw~6T9B#pT5WED29B)3I*Kk$iBP%J+mP;h@JX)! ze$$D`qeMOJiT;nXAZuBW@<1#6EG(Zw()wx`!b#nW{_H+~4p?jsEDV)0coNL7+6^BP zcsq@A{?5@tRpb|@&5E|^{L2xZ?5YeKq~s4`WU~|Wm51Qld{U#Qhjq0k=6UnCZN2=} zYQhEJ+_KFi_|zD#eE(lQLYE zmYi)7EO@Ly0(2+`c>JCWlEiP864zBd0GUx~a9|rtP`^1BjImf!^b%Sfw(G1AwcRh7 zMia{$pQJjoCGfCM&?Gargng9A_d_W+NUa>yPv={}$919;xTRqmqQ;8kzRlh0+G~uK zzq+!Wfy%Q)A5Ek+7L&SBQV%7r%u8FR`nYw%|IVX&=wP-gMw*sg-nN)9 zFS${ZU{CkKTP&6nqj=D#G$NvcF|)f$wkFO2v)2@IZ0xJGUT7DN zo;8J`J=HM|-$Fq=Ug?;fk6GhKHyb_dg5O8RcS1$A=*j2P&P(SIr6@ zD!A+qJ`%$t-uVl*)n8%D zZEkZwhZ$K{R)avzZSN$vow7*l5^4`+=iDg0{Lnm2nrd?R4r0-VN}bhVnvAYi~H>cR~b?w)Qr< z3>q8?Yh%>HHLO{y?`T8jo zBQp0~ah#Aq`iLE$)rPaj3IOw2+Ph7qb zgo<|6#PxOJbBtYs zuYNPukAo3Krnb5_mw8Y1@++I|DFF*iE>+UbU=#h-^O#nL4oX0!v&5guWK$=!)G$nPZ_xmj?{7VZc7;5L1eZNl~({nVIHp zeGXQTkeJIMIC+j%RTjEB$SH-Z1BV<{$D>NTYZq#8CXh?k1ft{3_1l0`zy!_uBT3LJ zTt2q0Ko=y%MDd6fr^ErD9FZftb*AUJ|KsL4s6hhMg?0x9B^22n1im>ZXhT#y{Wlgd zbH2atJD?pCn(OF{7h*R^1>wJihv)$$I$=tk#e}-o_bLzTtiA*mlRJx%Nzt;C9qj8fXY{)l~3w6dOo8bE4FOD(kxb0EEcte#^=Qz%liWY0h9I&_S~(f5!o zNuw7ZRaD@^AoLj)F_(#BEeEqbOG}ct<_$ev?_I#cvO%oQG7Nl`HZDsVYpEB11^Y@{ zO5*(VfY~7kMg5pT=#DQ$FKdA{()%Kd0;t??yW?b;fl-}AWBme|Yg97$07f2pfo{JH zjL>89jI_0)83Kjy7WuW3Vyg2}T}MdRCy1|F)IN|ta}JOKeC_f5;f_&oy-oI?I}t@i zJ67tAVNz_3f6XjelDqYRKQ^p3qg`??R3x!;M|zN882_3NY5c@x{|F%nc&2Wz0!k?y zP>u8kkw+zzC@@7aJT6QysxR%IK}GMZlAc_Q|L?87+?hvaSDgZOfKl zT^I1OjLsfiwqkqeDAccGKg&g#*^$mGTrQcSgI226<+`pBslvRB?(^+~gtDdve$eDm zvrU62I(%O{q2&2fZM00Z9?I$>t+*!`7L$~TukYfEMOlV}a81J7`aAha&-}cV!Axbk z1q3;*S99QcyGDkcrrv=iQJv*f(TkJ0(MaB9LJOOqUMZLGI|_Bt&)8sXSBZRaw1rAL zy&fXvQlDf;l-Cs61i*iI^@X|Tgl^y6>s(M)oAa2tY7?3||udMJ~uV0;`oB4NC zz{1I=ZuMJ74o!C10Cg%j%;zP9-vu(GU2hvQ5wZLT75KT7 zibF`IOu)5rt1b%!7QI0wlvW_S6&8qfE%!!_q5QbmJiSZC?bdq2vMpshZwf+iSis@w z5n@G~&8Em;9Y;sTwt*hmsn`xe{s=?TI!*qOwfOZZgWJey+1g%U;0>{No#fU}3ieeJ zC|p$)`iDB~!F{6EYhueVxD^*oeam)~mCn=Oj#xtQH*9XEQnv^>+O@pS^E64MAe5S> z`9;U{G{~4PBi+!_*k&&n&V~BEHo@pX!peu{k#Z?v1$P(ip% ze|2yM3q#S`^I{P*!F>RAUaM%AzTQ_geBAGc%GXE9FvjMncRIE+8c){)g^NqEj=TZ5 zfMV7>ZjFmZ`rpbe9o$+FxQnE`)q&~L{UNN&x7lfAW@9@P!Rk`=;1R&lmd>05d4U)&>DfoOm6QG2G@h1OfLi@RG-WRFqIbl;|8=rUX#K-4@je`P*`*2{%nt4 ztIURDH7ns8Wx=n7G(0mf2*rWbn$ zzsu$guN%ZBaY1r9GTs>-hW5S8OA0!?I+)|DTX`3Avkd$Ckrv&L+(B{fa3=2aG=Lr{ zqC68Yre_*Xu}o2A#zebD3hU{}^YfM35iO1O$}xcSK_8lM8syYlK{q!>I+YjP*PQwk zf+9b*I|cjc>aTiy8w^)%kwaW@C5B`RwHmi;_#qtN$ik5HV3~^xrLkhDXai5If`06UZBPdBZQj|Ww$(A1!4(Hd@ch4Xp5ZV2USA=H`I*vtzV<(jPb8Lh$KnKB$mKy zgd?3=>>yQ@)jOnt6&-1zV>;T8G!49veHZ>OV)6xg^vZAd*w)d2`GNDWz&G<}AtdAx zq(M-`+ZGwA6eM!N_;qu3l)_14T-H4X0nG!mW?_8ob&bs(`AtBamqV$Ptb0V)!7AZ~O9nzO^cE>5*fS&;m=x9h!C~6XLb-3ESFiVYT7z_0$ZX+s*<8pDtPO zuDSrfgKTPS@wXF|9bftmLUatf7=B(qJ8;%jpHCxb{-ABI8Kio!A*~{|63Szix!s}x z5PvcKEvOVuT=F2yCw5D$R&&@l88k$N%-8SFw8Ge^>A+~Dm+0tXZc8DcoFa0a+@Tds zKT8#Xf2sEbB0GxD92uA0v6N%)s)Bwac(E&~Q4mN6V>ZZhw;0FSvDXf8x0{AXggE6~ z_pOO(zPpXxP>$ddCP@41?NFbx2$!ig4+X$!T^ zoB!;FhWu+5MLs;S$bQ5qAMf5R-rua+WA>sStpV|wML@(<@dC+)4|ECe1?%A4(&aZD zO#9Tk^T|&!tf)?5Y~Z7o-g{?W>PEOtj*ps`Hi5eV`X=n6ZG+Lr>6i&9d2z{P<^4d> z)ASs#;C{)HQ+OWR`e0tOCD35a;AmSrFX9q4BxyUFYp|y_#Bs_)ThRhIGw>hLi}Fd4 z$gEwA1o!L8Ir6y>Eb!cBY4xhX%cmRgbyjWdxnOFTFDDYjo~T3+Z(?7GXnN{d?1+YJ z9KdDg2Ua%Q6oFqPchoRh+9W#8(;065?EnK;%=W=;DQR`wdyMEzur>_T-<|&u-lxBf zb~d&csGp##2s50zTje638;lb=1@*dne818I;)}Sdm;YxjDMiShL6X4|76m3>qskq8 zx3Cdw=TaE^Gn`1PF0LE&VW=gZ1U;UvoZzzUh&W8SAcs=T+6Q1!RQkIOu_!qY+tAQh zJUxKuqP_PcGubH93hm;w5K(tCE%M2P;bXieBO+?gSb%zw<<0^I+`<6edUjb!m*YsH zMQzF4Pk$(O`CLqWVf&R`-e3-+M@U}e=*(u6?j3NS)r(3XeO3lJZvYfr!Y-iNX^_*zCd-8OJmy+ zT+#Tdmn`Mw2uWCTpUV+M3NU@fEI4P9G@#SEkr>={nh68BMighYi)nz;Ra1YFm{=tE zlRz;~us!zp%M>BKTE^OT+z>SMr=(i-)fxAT&VkH>flQz>z~sp`mTrib861?#dwM&< zpxj^&*p+-+Um?}kH*nb;}JnNP~3-4>%{EH1;Ts3wHX`BexGV-xwr?dbfVqv&% zw@r}t8B%eYhhz}V$Jj7JH6fkPPb=G~#4nEMCrk#5AkWK=9y6P`7BUIcK-MKF9bWts z*P7ixvnKnYtKvImt>H0}8(T#6#hB5c+759tphZxH=S&uR=rw2^!4&on0k@8 zra0j{cV}8i>>ox7cA3Fy=IKIC+;ze-_(L|@L}&5 zM*Arq)_N0*+#sgk$5BJo{rL}KA%B8Vz4K1u{+nLU$pqHjGmtPdF=ppZ{Sh!1L~5Yg z)W^DW4W--o8Y)7IKf*tdb8IbEK4;~(3hjg0RP@4mwD8k#rV=K8<<9>o#R_22%xO}? z1MZuTEyIu6WFHgqhIxm5|8p739#koT617UEIL%8laysP_Ki==KUyWd`B|W4@yh|5T zI)GxKmTNuOIcy8;nEL;zJk7g`$o1@0?anx701IWC8-f1lRI<4vTH#HoGVDM1w7x%X zmM8HMvViF-s`&FX82^6{p#5TYNRyBd>Lp_Jk!>RugK`{rnH+z?OmKvk9q-1Er>h1M`oJKjKXlsvG`f zK1=#QbxZteSB~=}oXZ&x!btM*PfcTMszJ3@)kd9?EGVNEG!@Wk{R!@z5$@3 z#Dpo+UVe8`2!(@1n8uLX6i(1%h&j){h zdjT=Y-o|EtxkqB0&?8EutoZe7yI?Y`xe`-6J6q{0rzxu^u`nRsQI^Ae2-1|}VdkKK zTa1WbO^CLT=)S#%10~)tJAih%v1UJVXHJnHL~upwZuls$WH^E23Kl^5BkA2h89z@S zwOsjh@ve2xMzn>veV&8Tgkg>i$U;=KB2|u9=`5XipptZv*}jJ-Fj~HZ$Eu;i#18m> z2!r6SQ5EC>b^~0qH9S~W{;N_X!g-Dn?3%(-knm^F*!p4p%3965&Y?fF#Cuh!`5DxY zwvmOb_A|U><#xx{5~D8QqIU=Ge}g6+JFc@z1HsTz*gFdcr)rJaEqR;GEk8e<#yShJ zXtxVd^68reyz>5 zT=HRi>cBr0J!B2u>Lv#c3`d`;wfzP!0uGI=zFos3B zfd0D+>A+&N9~fHRCf=vxZvtLljNgxdsB+8+sYoI%%dSJw7y^dVk&S`0)Q>b$h=0N&oK`{;k@T#Jm4#g&`QK4+p`Bgb+^u&Y2*teJfw(+~_kgVCn z3B>D)hm-F#jIz4Db%FJGeGacwy*m2b%vpD}=WZvrbPKX`4Xx1F4yncfCOvHB>41zX z=Fk)stR0uft1BpHftf{U2g?2Px6t!_%5_^GJ+Z}ZWwD|ml0^L$&DdF{K)vF^Z==3Hi>I=roA7iCJdwfYEI(M@w1OVoJ108plv0x07ij_!@~hba!6) zM4HqZavy}vt>lXtW~kbcpM4xml;t3fOY+HLtI5)j2Q+r7uWvVU^fLs)J->bg_i=hf zS!UtcGsp1PTYfI6&>_9wjZ5l)^%8K_uz=c;g^$SL5>2EA_{qkaYRsFm^!J5?5ijb5 zvru6+yXwOa;e}Zr@Zgoc3aIMXz*CHPj2yL14{z(^Tjktq1BfSsG17%Ds8)Wo($PRkm&Edw6*tXv_s`7i~-N} z6qi+q=d8JGOPT0ZW3srdH`D^g6BZl)fR`~_L)Vr-a$nHX6sL86OJhh95dyGf9!$H( zxcHJdv7fy>n7SR+LMxy!C*n8<0nmN6a9nS*E$XQ@ZN!$JET4L=@k1o@&_SJ*;nH|P zms3AmMA32Pkb=}m*;SG_k+*A;5km~%?};dbm*g`O?Yvz6ZGt^PmYNl;Bj;`)C?!b@ z;Jo>5l#`+dat4(QOCz8bWKK~fwITSdwIF<@r`%yJ zqx773EQa%8ElpwaaT0B=K$tmRL@);t1FW%d5N=E+q?Aq1RhhJ{=hUB9ib?K8)}JFg zx*gw9RsCBEYfAeG6(1^lA}I~t&vQJu;fkU&H&c9;E3bxTDKa3v)j(_^&)|uX*!Zvf zXvl-b3pRp}QM1m+vcbe3mM-%WqO{8OR2}4KAJ8+LJ`x7y@y)^_U}8*$qn4lRj)a1ziOXfR!I+dI=dA33lz2? zWcaTpB>s8xgA)Ud4>te|m-T0rW&BgQZSJS8c@5zzlV9$QNZsFF2tc@`VpNY;R2dXt zoOhoUfq|63acV)!18TZ9h0JH@E?caz7=05^j1`Dfh8vOuVz9Qloro*{;V5&_^U#dN z5p4lL&R#|IjIy14DGuVmOJda#RA!BTYId>m&i_C}vAlxZUj7r)XGQA!rB%YLsmtT4 zjy4D_{Lf6zU!g_kjSfRe2jl#jVmg@Ye_{3%hRgBHBi@_}j$)U(d3UatF*oYBZW#U68hcEg3Ngbv>`6T*qzUNni%g@$H);s=2UY9w3MD2xQ<%zo$q^f%eeV@TrjzgTv z(dZ3oeh2)`uH1n~Vh!%y0hXH^{T>H6cK)((h(&>ByA2WqN)m}%WIJrS2IF(nnqT;O z_bA)}^NDmL7#A9cWHqwP9*z4}{dO0^&Tnex(i2F61eEHFB_jORmfm&8WnIGw#CF#v zye&=#y`}^d?9s^7{2psyF{FHZtunj zvx?(TTfSF3dEL(P&4 z<<*Nb;f;Pno{M8j?ot3~gg{7Y4{Re&-Dn0ER_l>b5(ktt%@9ci)SWd;I>YXZi#o8k zr-qnlsXS?%i|9)=>T}jOhXeep00|`kz(De8J9Mh2Nbmy4YyhXsGUPmdGqS*OE)M2g z+LH#is)>*Y(+M?YcRVd~)}7*piwviSdRIkIv1}rI`7Hh%PeRmv+Q3}yqLwyr`kM5F zuL+g!ycP`@?&K{LErI2MLNO{CSZVUlmjIKJ8YUlGGHKqjZG;)x4eq1Or?68y-(4nD znIjzQj5B1Z3o!}b3?>^&F81c-A}w3_>sCyv+H==91l3z-7ltx8feF4sS#o#&9^Ss) z2Ui2u6Q1t8G1=mFEOwm7%_}0FQNR(~vXNwX`?l3q+joO!D&auWZR0q~NnRf>PK?vN zkim)N$IfXYN_NDZPTtK{OJ49NB0nMpmrvHXAs>F=etAtv=S(h(Y3yM3k-Dvvkj?4s zwp9}XvsVK+!%N4VL@2oW>F%@^+^FTE61b@VBXb|SUI^B%kh#*+z;<=B%$Q+t%5YA~ znBnUJ$xnG3aOA$bIM`&}w#I}@+Qkq(+`O-s-AClniu;>EK3idpy#5J)7;io3Rim)? z(8CEA%me;FkpdvfLUK;x_cQsNE0f4(6*f5C{Ump&D47L)tOO|Ipnim{=5yqW_F6(+ zo!m|i2PesHzx9#$AYht)c@J^8h|4a|H#kY@Ra2X(^k&&1Kfh9iyq3obH->HJMLp(C zVb1G5>=LPOtsYYyNN0Jqz_%e6%x{-=lkSht3ht80oMnST%wBfmR(>Sc%HHVuIW1Z% zJ1suNSVI(M5u$hpR?x{|+cb0D*$6TrMO@AgY zAZ?6LA=HOTuL=VgT>hFGRUvSv40cN04emVCqO}NB^3RCJX`p{gG>df2%CS^NxlJVm zvr!01;YE%6dtQ;$nyG}rl*1YZ8Eqj42lBRvahSMAU8dRjnfxtpLkN@~4ZjF%DIFPANaCg21#= z>?tw%d^|kkR#8lyRfs|sxZ+nE0IYdg&vTo<0*f&<`5b>Itw?_BKcx_~9 z>RB5EEakOF$43BL@z`dGWfpfkHaUbqRZ6{b{@NW^6|-$DXlY)^IPzsSU@C5q{b>~mU=8YhKWXj!c!=preKYhClKj^xmA z^ga4ztPE$vq1hwe`()iB9b5dU>fu8nW00{_BGh76vDmZWW=N8p0k=>W zLUhy(1a=O}(UbnnD-oT6x1PrY=c9(21rB*mP|@F4<EKG^wyEhvW()F z+(O3J*#AE1Lo}_iHXa^--M3SX>e>P<;U#ab_53R&zS|FsC51k#=UQbac7M(hnrd6| z^};_Q?nU&dYkdH3YScfd99FifG@Qy{bx2OsWr3>w+C@i0m=DBfNbk6`3Cip-EhZR! z&WuHD?|N(cCf_nCD}R@#9aEKN12$T`d!PbounWJBi44Q)sB&E1Q=hEm@+6(fbukEV z`4GBz>lxOt4cC1r^3y`|J7*x?k^&)p7&Sh+D3Re{;M>p;lM*WhX6xN$Rn=sc7vFky z)0a=I|FmDa*V^`kwQ8YbjNMq9XDkwwZPqObq%)d)Zd?f6-eQAFh=a*P{@ZI_#$^G61m+9DP}?3CLHcjLZZwGH-l|2kq*mq z-Y#5IIkdp3?cwW1-umz=n42;f)oM|A2goj^W5M6H{X(i*W}Vsu@x+jd=Yo)G<9@hy zdvZE_uUEycus(NzE0>e^*F16R@LA=+h;EN%^%)xq5Q-bT*6PaX&N=dLJzTCgurTh7 z;Ri;{;ITnl6Hl)9w_+05CMI|XUG)}ku?9+>`2*f#k53T0PL2@Y)EMjx6oe}4l2?1R zkZoFUXQ)jV!vt^YE$ZN)Oh#=xQ6E@Zz4x#5UreWg!2|t)%Q7JJ98?X6pt*7$N6{ zBBi*GjxQ1+PekRWaDrMY77_AM?^p8m7yqRGIgiyh5j=Tf(oh zs^eNr-V)f9*qiC%Upq#s+?O*4lNuL}WtH-2;H$?+BvQM|0mEGgkPgT+VI5WoJP%(W_|oeM0|Pkw_^FE3xVCnuD?RB3*O4^GY{5o$)7fVVik+!Os}zD z;pRP-V@CFe^+P9AZI!^)6;JDWqCxKBHI@<4jnu~C@cikmHL(&e^$L}cdL#jwncv1<%AsE1#$#61gFs=0I_b zog;|4QoY{6>Xo{AKdHDyq3fHw1Uu3kJkW5No2Vt}-`}N4;zzsB>mHwcc$$}zg%~Y= z+nUl}auQFiKOc$ThO^xp_rXle?6b~uIluGtG6=>zQL_&(0l0cC6u2S2&In)`(v{HF zuAqDgM(@t#dPbndTkx=8uF$TTE9=qPI5ExndJ$^=!{pK8cKy0&S%)(WK03A|;Sx2G zk|n#O7S|oZ4!oVxNuEZh{5ITCNxyZg_W2&eW`evuU)Ropu^^{yUm5P8X~Z%`&;GnY zZb`>%N24!dhpxJHdT)qgmRAjoG0W_oa?+tnxGzqx9q{24xOx6?SqKI8yPSsVGvJRN z0rHO)(8j~J7FzrA1~b}iQn|=9?*bIOyME?Cl zJnHX(2z!8o4}Uvn^=)0C9Ce-7H;Bh%K#Z1&%JhL41)Mq}yOA|YZHys@-5Ba+X#iLT zaPu+MqJ4K=swa5#e<+Es+3x&mIMN7f7XNp05d?$zi5>9 z%8GKO-?xQ5vS=*v$@r>!3%$r2YB6ogBLV5&mk54oyXF88{t_GWNIwvDqod~;{&rzf z{|imKO&m~y$%l)s!ExNj?8@1dT8jyb2VZu|Oh8hCr~Ie)I*{?mxpwE&*gxEK@!67c z-$y_n6PLdYpU85-Y4C7IMI^)CgN#=N*7*4N>xtqAaD^@gmmEzaXW|W9p@fI9k^ZQH z?QKJqX(A3%&l*6f8H-Q`&EvJxS$JDd0hr1&{7;agFn_ytZRr1rjI(xz zM_C*JGGLUsS&J{g;A?XU<&!&+BGoLB6)tRB+1{%b>2jRnAp!BBlQ9_=O!b20H{H>* z@WV-L#+n312(>~eybJ3mAs^4*W5|>lRqH-j-(`|h&VPwMe|MSDHF_N@NLUzv$QCI_)7nsr{wZp0_4zgWx8b-IWKh9fh2%pl~k%^CdA{6TK0A)!VJ zfdX(oozdP567rA}IF2HPo=JeM)9*eXzU+-_xT#X{C}|l(_NHm0#rOu;7CzBP(v8Y; zvXR>Ork8~Z7Gr9gGasR;fzZw18dR>~g(hTvT&8#WRuCEp2YT|SgkWmWKZ0U0^-kDV zeObG2m-w@n+YC~1i2=cAPQC$Gtw=vviK-3Rb}s(ynY8=<``?7=UG**!aaj;%aCE}3 z0K4}PmELjl9l{oK@CFDzCm$s+`qyXwuk) ze~mQ8^D>yZP$ff=tMz7P7Gbfn9o|P6rXc34xbXmMLSjaDYu;kLXn>V{QN3XhxVmJU z&rACDHe8CG(J-#i0Z9L!O55Xf-=#vkbs_`kw@d_I@yQJ8J8VA{8`D2Ad*k%Qok73q zbuJqP;KWl%zC$lwvfvohBH;LIcNs{DT!2{lIeyr0^&h<%0w^Sgn@GSXi7_F@)RpX9 zcT|1CRuuhamE)}E-_1^mo}hK+f2|J96o|OxPnA<*jGfVcOGz*%HR*ca$a6nmPPXE< z?aOwQF050usbZ|PKB?0xcrH?56(I`72(Ig1J{b0eL#GA$)<=s90{lx^^ayNM#9^{g>5|WBaplny%rg)(WtA#nCx$`tm4>u>|Vk(~| zrp(SR4Q6K`)?sIRvkG&b8AoCpXv8HXP!lqqHl zr#u6tO!>Mw_~R)ANdh`sqNx0{H3Q%Y=oiy5%ZxTu0wJMuGG2K#c*dkj=zVqobrow% zHrF0^&L{fa(%JWgw;i_3>tR{9Fm^emb07S*eLJMm8q8xnY_;IU)(VwRv03&WC&C&L zg;^pbAp$ zT?BJae~m-l@n7t3WdkgmrUVHVdMD%av1yW!{Rt{` z{3#xB@r@3UgXZnt^dp(-(|<@sNOys^R~0Ne45d)fi<8L!0m|#VX~-s+YV26IlBy-Z zyp#l%7oO%+9a3ssZ+9pkP14Ybeg-OBPxKevyu%A9e7FEOCY0(tGG8jE)PUZcKq*o2-HPWOOv-nz_0g04pmt^%c1#G!5bd`CE^IsO^l?6cF?KA zge<_VhxJ6VtLwGGNSQP5?;+z|p!wfX&?d47poVjp|eM>9SKrM+7p}7cy$s zHZ4}I>O4>{O4K9`$OfChqL3_1v6=N?wK`lA@Ed|zvH&^?TgCK9m@U-+Uh?boMlj`kzC#XwT6a0Fh^ue*G1pv-{bsd)I%^mj7pQiv)%jdIc zi-9ejn$e!2*cyijfq%{#sPy}xjksu_d;AsZZ5B*g_CXXozaT-~J%g=%nyn+$P1{`o z?g-OdN;Dl$H8ZsUfF68$^EIoI>M4iND4_iTRfe=|4eOaVcP?> zb6VWT><%e_6M+jrND+*KN&5hcolg+7&&bCK1~9Vf>bd_=EKV*XIDe<44^ThFo+91m z^lu2CddXe5;8fJJDjD@+9wycW#BK5MxpZVz>v{rx5y*Cn+Q(LZ*6DdxzDQ%rHvOJc z$_Nu_Qp4*4^x5CRZV>Lr(c{_HGK2_P<(*IUG=cmGW4-XCr2tNIzkvnNs%LbaJmw0^ZQtpd-Gf*CHo z7nYGgO>^fyP+kWPdq@UcyaqQy9HY@C)O|DX z^?L|Rmf9IZW$sn4m3T)psBT<_D)#fl`l4%K7(ue`XEP*)s1C1@)nG@sLTN^Ld||Wa z0v8%DYQBzDwDn1zs$(gsrJwN&ysnyD$n(n2KnI3DPW+q~$$#sIBiu-wdJ&N4&tT21RNNM|4cQv4yc$)oy4 z$Ga>Xa#@ZZJrS=KOwDBp&W3ryp&VDWAXKej*4O3w0x@?UsCqE^{AzzH;~BP6|BwLl zwllJo%C)1Itmv|{A8V5JJWuel%-Yog`d=|MeCqVR100vS23+eTXFQK+RlTT01>eQ^ zgkKm5tdiO`nWi}09!P$>zvHq??Cv&mO!^E^y>E4B-=uNzNxP3Ubm0*$s8T;;0U zHS)BZUWN%9nOyl~kIs1@y9OT|^32`y^A+&XAPJ6%%d_Hl?mcY0Psu_sx+~$$@8T_$ z7iU7&nB+w?2Rzj^#4KunjiVk*FR;kUuO4A2!HMeN8&rC))!f)am zR=SQ(&j~fPLynA{_X`NPq_>4Ah!@h4^2hC9cUd)~XpOxOsNjXJ9ZPKB_B5|o)=~FY zh|saLOIlCFskh$i=U?yEHaj4JDvZ!{m^_Anp{Zf>lvwmiZb_4;k$2FLq}#k|16#S| zvFDL9PS{=Du)7Q2m^GpGR6qiNtt$Qs3`c!0m2c=G*CAm*yy>6}6`%GktP&2Vr#NwW z-l1H*375*fW$`!LUlZQ%MMg59ss3c_rzf&=lSr~BY{X~Mf&6JvSd1EwY#H*W8`HcK ziz2w_`aX!JUlf>ps%5RBLR1AS7_tz(*GX9fdhU>WCC`_;|*yqPb>*%;0AwB;BDxS25tV_{iQH>VN`Ve6vYpjw}15$1u-wq{R81J|z{}nHiYCK7ZSe$-NYEH@ml9 z7VIP%tR)VjvLLDG3!|0#H>DNe`>4{4FJU}bDO6CD7)ycy*3 zM$`by(R(EzU*j*&_EFlL8#Q08R``N3OMe2}IH2iAGCr67}|SA zyQ*y6TlrPgjA6Xyyo%nF^pSrxo77dw+TE&8~I?zG6$@8LWI0#OTLth<;@z zKdSHRSs_(Q7`a?Uodl`jGMwe|kfo(2_yL*q@D)*6?Zgs&dDJ8B);=I;NyvdkC4z4y zxvF~UuXr{NxtnsoHHdY}J(_pyyPa7=92uM+fmD*gr)=ac9!KQ}y;;xhv!VVB80Bt_!Slq{coaNA zq6Dp5wWj{rMYUVN6f88{Vyn-h`_15?6Fd$Q5efo*eOFfT5{TRb^=`N(l0d0W=3)8Gw(>rgA~Nf+moitq7V6m|K@<2=l;^^*cC^g;)O4<4_YE(S z=X#12<2O;KGT#pgPcy*5NLk>6Q{Vb@w%YIE6eum?X6q))tEygdIinCf2rQHQ1+P#$ zi%}vHivotJvOGQ+ONv{)`7_z^N6m7a72uc&nn*C!qa9T+ZAI3TJoj+75Z~#SCGquG z^IO78Nj8Uxxo_;EK zCYAia0`jd25xA!v)Z1>d5$NiNd;^0^=XBr;t89m8xm3xp!)^M9fO0?5xE-Qj5QJK` zZ~B<>;pO}l(sJg29l@BCUo!3^a0k6jHX#{Nz|DJY?9aawWTyT*EI$EiCsyeJUAE(( z?<*QMmt~-oACR8WSvv_D;q23fFY-tzOODKq{fWxk(z4{cE3fBpxY&xahB41ac)AqD z);$Vr_ev^pOouDGPFHOIEA1MbD5P3e&# z&O@jj`G1UK9W?(&>k76mB_Mh(#!q+*OPGypq=~y7RK5@9(0HN${@pCM#d<4;bL_iC(bXl$Y!IfsM;6A)-)CF%q6*B2F&zor~IZXoq$e$V_WzF<7n&%Tiz7LJ+l0wvRG?TF3(4yGolCFQz6z9zyn?y zT2jT}1B}ctqdJ>90R799b4+*C(>86MwXcENSd{>y1p~177HI082(Ei+?gLk9%`Em9y3SSFb>+ z>hNenU}ONVG?@3g-O_KwiSE(<=cH&(9I;JhL$Hac2r}T3Kl7ues@Ac60VTIlKGB_Y zq;fr<7n=5ffx(S3EhUTxC8pV@t8na($Z!vxg!V8$FGJFx%-BI*a^00O?L^q6JDygx zOxkMV^zah3PyBK>`V5#F)tMla_NaEHeKXYRJI5zsi0u8@pQbgnU|nm)CyNq@sh7x{ z26@hn&+Sb42{6^YI7WjrMw`W(BDQY#1VgEu`QJ&A+<1mExult$>da;DgTHEQ@pna~ z-mi`1bHoO|srzvS%pvmeib3046Dmk6Ov(@IGA}`O(a@uXyWhh1=1y3lJKn(@2>}bN z3$9@Coe16A$?w%TE#(`AoeiNtU^R*!hA==$7qD-POWwYL@Uf$NY1HezMtJPxo8Rg5 zQ#HfZAHJ{lzma*1<$-~(1#wcv_D0Qf9PM%;Y<9G5+@TBwtgply-qqZf%1RcEzsT>{ z;Kw3R*aYm6i=x3-(tSpm%rXN;?Aw1Gce?8-Q4j<+Cy{b)d^Z`ISZzKoNL&x+WR7*!!MU{Xe_0Vo zzh}EG%FOnsi~InK{0e%fSk_yUR02ff*{;_7cQKPmd_uZDXH={V;!%-!xPP>e6X%Me zc??EBPJ3v>%P`HYZtH|1DUPt>moLoe8R!~BO}~svat^oVd(yefC=0?9G$4#lQfi+K zIN3WdCJbcU@C(pkFV0b@&3P&{qF+9CY+V1hRZB6Cdpmuf$LNNg%_HlPw8Av(I&DS3 zA#28M&2hn%=*AZI1?)r=(Rt+1ztVL#%+@=h{zN~YFp}LB_|QD+?;#&n-y>)*p&k36 z_?-l?5>GqyAEHaH&w zk}U1$uzJ!AQ9$9e5A>t>&4h$KJD2SbBsw(?DK4xSPa%Ui5&fF^*r20KF_7$TOD;Pm5e$i;2&1KTyvUefnPkXuQUWNmxy{-}Z59 z)1DCv@B{Gu`C#0+cGY5u|4yWHV9!ydx-K=z#D-GaX9ovNmC5PHV^%_viQ!j*=6L(n zmf4Uh+R15}zuifOz8glL`O$T@)0&))F>ne9YZ}rm;C_ zII_|NEhQB|IisxLbi7(?MKrcvf-t_4=jqN+u!)a49-hQ%Eq z>?#O4V%ZCbpkzT;6)|88gE-|v4|Z)+84~3nlvSKG*Hw7zr%w*Wsa3CkpfQM5%cGbx zV)xC?E%Om4L?LrY^@j_<6!Jg;6bxaln$?jLi`j)m+24EZ2YEQ73mQtA$lDpS>K^Nj$k7c!ueSC#qe_g9161}6HCV-8&#o06? zJc%4^3XVe@(#mD(Z@xDZeS7N)DbIH%OhzQt49SGigX|H1{7OJFtyToClToJyF^8w@ zr4v~r(Kz!%RFtRGc4ms8TNsDOr4#(j)Q+0oAOZP?clOtK4Ds@=;Ho`U)pmmv1ICb? z1gL;S?$kMkMLuq}@*qt-1ez#l=cwE0N~+UGYH2#r7-ZLGjY-Vkz^l3odc3xLJ(i4T z*Ify|!T&;Q=FmGod|>6YV{|u-O`E_u%KJm#XyB9#t1w<2q7qD|7nT4Fk-vf5Q>UrB z)3mL@5qcWx#rWZTu7#M_qV3z7f1addGpDB`MM;sAd5X{~%E_Nz(qB5BVj@nidP5j_ zoC6v{qC&5@mFZwrYkWA4;8cFp24Aa>T^+K7^N6V)%3)*TgQV+aayO`20?yswF65+_ zZqJtHvSv$S6HzX8PY4DDf$T4F=}Wb#TA^7o1GGYZ3}}9Gpx-IBRjh=)L4m^0S9+Xt zCO-rPpo*>5?V)xBFA`6TxQ3?<#Hzuq(t)HmN)~&Si6u4@3$9Mcn=7`6^e{1|x6AgW za@oxW?L|S%c140cE`n+Fgod5mn;J@wny{vQu3P=Wu@3wJ)xsov&E0|pypQFowUcL* zUC^*WJ5QoLim~o_AZNOW?S#iKm{wVOKjhWsXqbC*4lkv;d1D^D$ zn&$HZggrS_iG8i_he;8JU|fy*BEgQ0=gl!16xU?wmja~NW}Y|$wm#r`HEd8M&J8ko z`SP7z#-WQ#4)+{r@%jyjpSJsqIGx%WEeL|DqDG)6YVg3Icmdye zQ(n-386n^~r{?y?8?sfgWWB6U)gV+0@(iG>n8Q8pSOs90gg2`X{`!UZ3)Eu%)Ob}ig^i zEwnAVPH@-5QK`}Kwsrt09OZw`h8x8>yUF#>y%$V6DaVhP@%^bohd4ZM#I9{fe6;mV zOPy@H2SC2!h}BKMqB=xzE}Ti(I#i?X)A0!w{cm(a+T!nq?2(DA{v}iee6iFN_1@&?Ja9#M)O<2_ zDcHfBRF>Qm`EB6bw?^$L1QYkTEB}CGbID@U*FG`o(Zcuw){RjkS8q5-F^~zlC_Qq3 zN4Ok0;UYY|G+p+8Idmd#=Q9H^x9z%|zrV)1aNGz;SQvsqu_MJJa;UbdQepX+M?{6* zxTFmnZLc5WmZQLka{4dIk>i1;)s)bHh?~*H8*eE}HC4n{f7S;Om(?Pu8%r49ig1%8 zQ4w-+IAq%ab~wlGlo_b2$Ppz!4|{}#jWZ>m{8H4ZKEAlGI%_R?b~QJ5v$wRFLeJ9* z0NPx4jmUvRJ9cd;qtEHh%lYMa{e3}L)<&`D#Q%^=2W@d0hc8Z3sm6a8=P2J?3}Z@$ zwxZWUKVt0M0fiS9*WNr5v7Ia|4C_j(N&@k$C+Pv2k;g7HQ!D`l4zT^x#c56Cq_8Vu zUN}HGhB1Zk7(nFo(^HAs{7$1<68ishS7hmN&x7N8_ z9|SpZgPMCKssHzQMtbW4F zcGPF8VRXz6sBGH{+d5`3fI*V$tWbEwi0HI@Vc&RcWUmqt8m9>KbTE*D|58ykgkqRh z5%>-AuNHGYpr=DHnS)*8uZc>Uj8!son2y-xkf7r=@}S&J%+r5MQwD@DV!D@18G8Du zsmJc%CEextzzLH3y#~`=>O35X?c@Qg-k#c-g*SfX770mJljb^@3j0KdQ@?Sji$3S5|1Y}tTDRuqFV=kIdmC)GH>gHJ<>hB z-FDUrIjbr@tA(69eAL{H2nNw;v`xVTll{>9rA!07SiYt+WM}{E^|^L#0rexj<|-4- zfD4Idp%yh0D%2y^tFoq|J7EnKEr#lb!-GzjUj5NG_|asBxCuq%jERDkCu{`z?W;EoT--=3A>pT73zTERR-P zHq8t`T`xo6c5nI5=*h)UvQm_}s&~x7I^5u-E!@NSQ3J;Ex~S9isVE?>N_g#>P>cG| z7@f)kSeTM${ZOxj>|(yJWjh+v)<@w;Pycay8SeN4#1o?P#z!dMM+#YxX3x;{yYCrWYY_F#zZd~^Xm4q|tGNjj^HC-fbwHI`naB&5PSX2{ie=T)yaz%c6m`d02eBYcmGTj${YRb=3ET0LSF6VY~yVTqSm9 zsNZ!i#AE$(iI`=LQ2c;|R~Ao2=Em6nX{ST|-Yy(ni>3YwQ1p0%D)@Kq$b{Ie174x2f=`MYM>XmPgsM~ef;kfIsK(IV1 zZX4nvX*+CttX7GGCUv#LuDCADsO8#`_9RC}TESk5q!Z(l(HFEi*8Bwe=zesXRgUA* zjI9a7RbJUo;#aBujzIvI)aNR2`~9scL%AOKwU0)$P4Oo#pR$=`A4`36Nn=4+K@M3& z#oVLAWx~b!#v5N}3823T4sSz%G}<5NRjwCMSTHjA^3CV?!_su6;(SE1j4!~rUUuCw zK%@m;~0u}Y=(ZcYf(z3V=tokiiQZX5MLx#cREMCxY8 zvyhYAgSAxQR}YberO96i+4F7BeTj9%Ecbtsxq)qn_j;aH?lA zqt+{j_w(o!&wnL5N7`n?l64hCZ4liI3K zf&@Cx4^Z-xsKTLPH_ePz1Cmw>TEYtVr#LEFxXdNF=Vpwed}FUEn`|LY#P}h8co-of zy6Y4fsOzH2wrtmn0R`G~Z;hy9LX!mdCELqmNZ0CJX-KOid3*XA-a@Zt{Djs!mG117 zy}V&F>r=@S_)K22@@s%a1E6ah!HnYp`h?+|n+G zv~;k8CT8H3`fy^)E=HYT*3(uEvw@R5H|!01JQ*=&0-{sFQ6ckPyqW#B9ZM9sRXPiiBcFwNG^hrdcV_O!vcc-Eswmq8F{V~l(zT7 zKIV{JZkFG7+XgoVoogYQm!=c7``fK3CPjyOrvWigMb;}kO!T;!C3P-&V}OHsX)Y>v z_&r~yAl@(Nkhz!6EhVyy46~$O;hXl$(^249km&ucdf)6wcpti3^Q~|^L(Df1DNf2$ zzL&;2^Txkr`>^U1p*AoEk9G%jdW5f+7NaZvK5~RyUJ5a%-bmr9V&Ly41dH8ShQYGZ z-_~MMBWPIBDkOJWPHZO4p9)U@dFklhbMXEdoD%?Ry2ZVssu;BsjkBzWtN)!7Fkfjh z74k8YAxVY2F&4#MXWK>hbS+Qk`>b?Xa=7-mbXCm6Gm`TbDfWh};=R&yMoOfp(wY|L z>?BQaBlNFI#g&Msr6-c*d6)a=MUzZ~H;T9kj3VCRY>QlCj9G9|<3QH8+F3wgX&Htv z>y}q~i=|m0HJW)Da? zm07wE5^faZzxKVlDun92*m3c5nwRydK{v!K`X(em(; z3EoBAO>jBotHq9+dlK-&tep((0lolm6;RY_<+FVf!cMjOc}@QcFFuaBt+TotysOAK zrPWLxy|2Y@ao2=L<)PYQ)Y)+IObLjc10FX}DHY>%T}$mKDS8lI9XsFWd^?D+Wq2VU ztg|GINX2ms5F!Z0lS^)n*lF<)OuSr<>0Yf38wL9LR`^hpq2m(eRh_=5jiU`ZhdVvE zZDkRYFsW-(`BSQX5qn6gTn=bRAlIIN&e`@OC@_AK8dFt5vW&F;^^Kk)1^D>lPO-*q zi?w5`jnwvyEwH0-A^~uggRO-l*j9NW|6$(}{cK(lUifkTSDjp0(m;YMcg!SpWp8lU zF>$2YxpOxEO%~b_%%xvPY`{;J#BAp(qt|+r|LYT%{_&|wGxXqh*PO0>b23XcRa+g0 zS{mjtusC7mBvv_(4Ya5P``Zt4zqaZE(GxS1O1|%%^!|5?FDHgcY_8QUO(Di_)w1f5 zt#bASDaV}3$qVJ_tV0wNn%76A!qS<9uvrlM70G#g!mO;2P^wC<~u0( zRUjsPY^Tg2vxA(V8y0BK*zA`ebo1mHLmoPnQ}s+B;`2At^J zpAQ;IoxgQyOt!rlF`X42b@l$ck;(2HfRHq`cyGP=5MxPNtLp~=JulTyTAucZxAPKL z4bUe332V4B>h+dDWjN)Nh*u872!}#PUaA)+$aTVA3+4qyW=QcT1c{j+TZh?;3f(`U zE;gPw@S+ssuCx=tonqi&?D3J9srjVQ(3lf*oq%`7(5DW_P}eN;)Zt$Ul35`f85H|O zW=w<+4u-on?@D{ZmvDGE;+_U6P9qFaO|;e}jshz|-qDx{qA4>SD9`=Cf`5x3yTi$Msmc$9tYy z)0ix()|4~pbs^i&H1L>w;sm|Pn*cQU>5Oh`T<^^V05gAW7gw!lg6%^(K%&bH>2-57 z9-jP0Z=XPyi*^CCC0;F{jEAsIFMP#_Lx)FFgin2-3Hf($5ET@kK+HdDs5y(WWv>{a z)o~QUJQz-WV}j;OT@14Zz^IoX)rP0h<`*O=HD)>(62tpr(Q7KOVN@+R=CDP;FAT#+ zun{UKJe>;lgwW6wV;F6)4L87m18k_h5Zc-9582P*hAK5jZ%#0y17S@VHBdhP*(u^N z9Y@v0BhZcKaJcLBgv(sKT~Oiw7>cfc%q9_0JD<$ku@Ov}v)85punJ}xHP7$6lp31o z9U<3%>(7D5g}!gByViBPL$lWF2lgN;BY#yWqzN{=_ zrK|w($7CaV?SX-RvANdiwL9(m%h>puPis}7LfCb$7F9RbH38Cew6Bo#jYm?R`uOu@ zrH;s;tUayC4>?gB1+ZWL#ndY@FSTkD)s)KbFb-Ged$@Fy@3yZ4@4snjCzR&xTheNZ zl#^RrpBwL5BWaxuLx*0@)#5>u3lrdYl((qf3*OlETOq_3(d*?{c&W<0vTD2tQ_=V; zpYyxKOmRm^6)9g$V`)JzPyYM%53S1PNn`Snz^dH)b`vzEBgY|r2Qh<~xmb+;y)tDa zp-0g_uJ^9>NWqYGRx{G1suG*;{4w0l)42stfUbz0=y#r3RpbId+SgfVJ^x>zr8DQb3H^ zAA``zr~w37M<{Pi0lfnnIt!%3_tp`Wse#ob;S=;13@u~l#ME#_?GeQU;FEd-z9{oI z=4h+0#p9N&_JABqZy**j?$mbI$W@a7dpx|yl5M}K=Pt68<0mHf&MA8qw0 zfb$^p;aCmmK~`?V@oR4Cdyw8N$?#1klbJmno?+_ne9RJ4imX@$3d>;H12x6%-P z$*XHJV8vuwTm=w%DlC4tBAOJGrTE}lJN~6&Om6VtA z|I(&iQUF4zr)aKp0h{I+AZPs!g?LXBKPg5)RoJ?^JXOQ1xo{TJ`rI6s z5pnKx6b!XJ{_A?3f&Qj?tzie9c9=J=&u}CZ4}QsvsKh{x2fchKdvBS$E+ER+nyrZd z4|Uwpj>EV@)f;>|xuP3UuhUff#vpcgS_+znk0UzY@RWE6(xbL!S+8@m?9JeEvt%SJ ze2*A5DNncMz;0dl>YIX4kFOQa-*I&O$R9*njNq}I26#^JD4y9jHJkn)WHQ|$sxEwF zPZP%nylpk`qen6y0*59=l?FEAqn~k`C`54$j`vh`;!q*#1gVuD z4c(t4{6j(`BHwI+M{Y(bq$W5fq30GLXtG}VD7quH`s*jHV@1&3hsn;3E=uW5zp_6m z*w-p943D#zBez_;uQq1fk>4oZV=ugP97(O?L;ljs-VkD*>-8`VSOQ&RA`VReA^vO` zdm)lHHKP~FEcEmFr`#6u)-WCN-jVe*vV(yQu~5({8~NRhrR;U5VYH{k-oX?}8j2aj zP^sZH^#=xX{o>_Wt&Dwyh82C7sm&;yO+a3kN~cj7KFg$lWM2a%OruYA3s|(}7gssU zU^$UX?6DuzFzuU(P%+U92{4@WY7V1tD~7&j>Y5w?B0-*ha%wJp_f|%$MK#XnRwH4K zx#p=QnEEr(+mYb*X_2p9;?=8YvtU|!PC7ybrLTKB2H2A75;z;)<9T4mnV}m4%l>rW zS}?G^j?wYM8bwsrVV(7d^g6%)b<_SjQvC?TT5d3%4Ybyo~zrIAO zN`^69EoMq^^guLwrB+%qGGEMX2%lhEFpme%IB0}65dX(V?b;A@uObBT%ZdWoOV|xJ;}hS36%`h0uq)OQL+X5cU&Yxbr`t!UonCD}V|&?uev78DEs&mzW?boQy=$w z*J!)L_u=B_qRCf$1AEKQ*@c7m0CsK9!P?fkype6cJSuw%Zth0yWf9p{vw$4axcs8D z=Ns})#R)z3ntUl(fw{`gzoM&bJ)Nyykm_LfoLr6h>Z%1tS>|ynY-5Xef9lS81+Ebx^sIs0e~T@370w%zfTtiLGA-JsE1YEw@qK;FSe%6M`V z;sFV=g%lT zW^om>KK4X$aFYSYXj_tTh?zU=b0qWd-QsX--6Q~N*d;j4;LIRk#w3Bv?yOtdaZuO( z!654M#Da6dk0mt(mEngDtOEv$i@2Fu@MEP@kzEVI0kl~H!JwirTabRpD4gz22}sr~ zr|3Q8bPwe3rpYs_Fb_2aPRxM-U<*k$-jmY+n`NQ*L97Z@er(OvNCeF9C+A{g<{snb ztkGeqTT$)Z4>Xk;$r9KYYN6M4<>m*^5H;82k{`LF zfH^20wsz`k%LJXF6td7VuVR8KeTbWzVqa0JH4XB$SWx;j1TtNA1mTW zh!=t?Km{GstC=u%Rff5mwbn=$l)U281a}PM+-prN20~})*DqkUFJsDLYO%n4!F-N2 z3x#CaeJTAJxp>lJhF~M322fMa;guCSa239*g@#|ri;bgF zoqVy~OB*Vtb~kUHtJ}u3pX7bhMa-X$qjn?ROBQ*Duwd?gYPoM{_}YG9tCF|y z*16cbIa*n9b5f6~MH86!3LA|9_MT@G@uCo)Ab>EKD64WwdBXZn9<_i5c=1lhyvH)H z;$V?*XL_vqTb#%0fP3Fv)_;n|borB0U*d486~wQwJ4*LNUl+sW)S1XnR@@Whe`4`( zKhfSqb3IwxZ#Q0YGPB|tcsU>NhadDX zb^VnHYn9RRYBJTIl|GXH3g>h&K4n_0l z4ZC2EwR~0`cqEQATk`PPc4#-@bwOgOj?FEk8EDlcn;c>X{6FR65!3%ZQ;9kDhC%&} zOjKc-;;|nFOOKf`>v_jHX?f5;k?)jovdil{w#Yu(qCUgk(cu)+d!4iWM~3q8YNV6j zf5*>|lN|)YkA^n`9si<%R-Ecxyl3hjQw{lnV=PIZ3|Sjzr|Kc-&mm9fmSQdl(~qD0 zNeqlzyi9)1zAJPACp?9cjIk}vN1w?CqvU9kR?h8`WMTr#U6@V`@OR&9Ul;80G;Eo#+ovu(C#w@SYCZYrvf^CG zM-uv4AW})lx8Cko9vbR7ObHGOu%({YGc%`5#a|C&X0*!YKVP<#0`Zs5Q-tJ1Doxfc zcT_zwmyGoaHE+?|;ET`8w~C-+`vk%!1R%IU=r`do{1tTR<-~9}_K9rEvnvJi=+&=A zx`pAZ@ zH3NY!x?00MM>5G-!Va1TnK&`k(~ZnzoSyZJRxi-S(~4K_pfYL zcO6Hu3Ej3v=lYhQZl)6Jv~woH3h?^5x@ADanI|AIJ;{r`>kp&R8~2^O=+mjqZw$?U z=a@8GaO)lz04$OkJmL%#eXz3HB0sgfg@3DsVb3gDp<$GOM# z9gPl#XCgwsHm`tW=0m(v-%}VAYhlihrhW@jWklJLp#EkCD?>AQpyj7+#p^VTsq%S* z_1G+;==AsSOeHp!YJXEihSbl5TDOl#=xIRTM{U|Xpz+a18iF)`G$l>!#Q#l-3KMJv zVXFnU3F3Y2PC-{7Im5lQZ)chh6JHR$?lZcX`&QcXV@T1LVHJ{f_EBif(pn!nJx#Q7 z03|@$zccl^^Rbm~B^7Gj>f`dcSCCL3cLQX;m6ZZn+!>)v3` zuTSm16NMU^pZ?k*BXlb_aB2=8=`yg>{;pDEcIt-zOTa`goV`7n+e2cp7V{IXJpm^$ z#xRlPaf8FgcaI3@?BJQbH1olVZL9p>M4Q%*+@i`00s3A-&ZM1x#){0o^0__R<;^F&`-Y`I>qo?^zCaM7TykL-28j~l3x?`%zW`6P2>`Q!3mWx*AXrx zr!2ideiY6!#5mM&Of~3pqIKY<*th}ilawTO=dmT~lG=UaV=^rLF80U-bB zfBrui|Dj(~b#SonOx8H{{;+AYOw5CvW3S!033C`>d)JyXnsNlIkZI#riV7)D`I#*1 z>Px65Qah*}p>bQl;Tn9D_HFoYL!zfzd{j4eQJ19=@(mY_m1&)cZ{IlatV0h{mTz7s zh&>Nv*^!Er;Kf#b{pV6fd!j)w_(}eK9)!zr&aP)3Xv? zMR|Z_GX%-2>45fJVC~c!3)7#X9V2SP#81^|I4XH7=mJGJECSANT~zW$r!3_Fw4Y_R zhhcM^Q>XbBpP0#v?RIr$<8FM-J)q?ogd-Uoo2fD*RF;UvsKhm;vn%$~L)uPFHR2~% zOs}Sl3g~1l?zq&(4DjL@3z-vXvP_H;58&WDHvAz`#84zQKRf?e?<>^_p8}PyIkB&) zRMJAXl*;%{db`@0I=G(s(D;}&gUyNLeV+!fZ!6$0&}&3Mer?2Rmc+@s2_zCA0w&&^ z!Ag31e-~SF{`pT)K0C^5tV2$^IL=pXosxMM6%zYiOsqPRywWIvg!!ZWHk4jQYxlpn zn1E}!9dXhjX8JR1B$*hi?WMrXPB5y6^g!2|{P%lcvyF_MY${BdyF8PS0<5^AbdBn~u3=FlqRd zNhFRnkePwx{~r>XT-YXM%?*_r_&>|ajfU3!RV5~RoaOH2fN040C+EGw`0M>hrf_g? z3+L*{&nVast#Syv+?EsyPyTnUuJfU?k<87t5*3D^=I1*xLovpDzS|Jivg3}M;5kn+ zcw>)s{5eTfMFb|pY)LHU@q_rvTG@({XF$c;pCs54h~%}S`_29e_y!TPQ{jH^=QWne z4D1wOc7c869b(OI$aao{Iz!Y=ZJ`Cb_8<<2rSKhOqSpK-BZ*xA3asW%w&Z!WFn0W& z(uP{>#yVwbFx2bsod-~K6bQ?|0y2pQ717mlIBlozhiUUIg5R<=S(5BaZQUB;zd>aH z;rawB)&-Nn+OYe~P??Cs=t^MK36Y@)(xA5MZz9jB$28q_m~k%6e{i+Nk^ZjIP|I?h z3os674_Ckdq4qs3V7cr|oUT|!D(IVV68Am8>_c!pr`nP}RV7!N+ZVeJ6?s7G$+xBkAPCWz6i{8Wh^-7n!Bz!o}6YCUhCm3(u;4u%!xQl+_Dcu(0IW@Z| zwYIJPF5CE4!S~N428z zO;yBgXdJx9egBqXN&B^HE3a;=3Udx|t#>ezK30S^wCpKo#9I znqd97)b4Rg-&E^9x`kEZpJF@1@v_>fzE=I258*C~FnyAb*Y8FOvs*pSTD{!WbplCS zfEro9l1-zz&?}n*GZgFFFLA-jnb0ulaa(@^nn^ricVxW{GH&!-K!wD*Ng$lBT zNr$j1olwC_um2)ciZZcHs8j%8N?r9;>7->-N9MwD4)Ve9WPC_@XPhx1{f3>H(OinS zF~-{i@v7_Xptq1M+j(2j3{|u2GBtiX(GsPl;h?8P99!H zVC{w{GFXAJTqFAjQQ4Lep*0z3n18To^o_&*_N=!p`nGBRQ0akF5n(48vG#GI_V19_g)DH9rkhvWLeMeU2Aru@yX?+#`Sfh3_r9u>f^DL2I=vAh;`IFWMVFGeOi)!2wCnsiV;GGsD;+pw9O(|VYs$nd$!L)W^4SNMI-vs zDc1POw;-rn_&HS^6qJh4Wc3=SD4cNvLkt*=qi=H5gojxYOXmZk=-q&&9WD`dFf`Az zG&wlyl03>#jJ)K%8j2*$#FagCdr>>rWdC4c7pgQa_Fl1{gH zzDefq+710|Hdd9Id(4`ANCcrs|8t1ecZd%pvfPNZKSnDBp!p$oTf^;TGLuI(R2(*A z0S)Iz?plXT>>yyviCv|cc+-=n1*Q8aop3CY7z6b0P;Jo2tZS9zWbQ`D1>T2={MIdH zsMQU#|HRELX@gG(#a(*6x?pd`y-bdZ)n8i4n!A04Z4TNx}*Uq=%P}Ef6|lFar-`ib;t?HCVbY2tDl%a>CG+D zY4@;{!CAJ(VFWG%X)4HA!pL=uMlYkj2((E}@BkqelN>ws#SyI!Oc?)dt`ByVD;ooD zjoeTTOzN2I)d+a|HSk+(O-HF7CK|%XV_}Ygg;w-ivhX{}cp}h@XI=({&-w1wcyvRi zn*Qwu-`m}Gw07QLMVr6==ZSl(m&B0$CK)ypbZ0XLswvr`#!uxU44YyPnp<34jK0q} zX8xPqbwq#@_KliO!MBZnv86D#-Z0&Ox2r9KiwkA0t+gLEszs0Z8B}+>c4z)8wuuwF z$EeLdgR~9&M9SycEt(3!@l&v2=AY*;_B2rCMl1&H@PAhL#7*g#84@6=3vE>i-lKTe z5!+!tX)lW$@A=ljy5*murXWz~da~R9+z~$WU2Kaafv1L{4pd-}n;hhb!Ri9~AW7Cx zFOfP-QlW@Bd<|3o8lD>+4ofAU$}K|cqHI^BVZI#~HJAYpr36gw;Dgvg2eERH6Z-(H zJBin@t0L+l#L86-j>3pEwGHr!C%PB|p+R8B0vl^?<%APWxbi0*A#=n?@rBx+j$~e(q2&bYGdVA>cb< zzTjDIUJhQznl4868Z{^R+S=E;-d|GuCuA!cN(=6(3d;@0>j`ibVz`KoYaoSFHntWT zj*#Y*{4FTT#6*UO zJp}9oG_e;^6FfDt5!$Q5(M4{6`yckU*p5106cbPXU*%@%NW{XnVWFc=>y;ZgWPeGe zYIqps71I-o-;PDFE~qfK$1E_viSTBvXiT?AV=?bFBHyuff?Si1Hm z4PdqM`DcF?D2|B+d<$e)qo%Y|G0O0$=?Q;14&>)z6DH~PtS2TiQgbwBD5weXg2=Gl zw)xgE8fNptJjK>?4vZ7Dl7A#!6xK{1iQ`s^WP?dfoqY+qN$ctb-_Xgx4+GSw-)6*o*3xvboh7LSZqX3wpq6*_W~!IW zDJDg8e#tl+m)~YD6b;lljR(6#vO_*j!}do7i)Gp1txf9Oo|;}1$X>i3AS;Sx2=f%b zTiqfwPP;z+*GRTn<#l@QL*$0Y*+!z0*8qLkM&9KeYl>DY*(@!6o(DDgPS|!>Q=F!2 zc?zH8+5ulx+?$Gw@}CTRwtq;VN;EQk1xldvPV=f>m}rvuY4cR#81)K{97cq9MYVy$ z68GfQ>PCe>Lt_T$QqT07k{d<$*n zy;zqe=HfKnDB_oU=dmc&xcoaedAp+eXOZuxZz%bWAS!-H|t7~q`t#f4Jsq2#G<)c2`lTx)}9stbbN+x9~haI z>tFMkGAXAkZu|j$G++B(O;~Q+lxOP1^kyU!pw2EjiyM=_jXVJ9HR+%%IGm!}p8Js! zzq=_#)^Ul)Jf#4!k>-}Tgj27sziZld#oO0bEbe2{Jqp;*I)rtAw?EWB(%%Nz}4zkw9BdrLc~&ex0VqF5wvjEEma& z;*6^YRaK_gJ7VaCg-fNVyHX2tV-$zC#Tkq2#8jf3nyE`+^*P}xfdu7LChFwzJq9DW zzVIm+Z}n)Y#W4AdrZ2QS2umpqdCoeEK;|y;y5)`Box~tz`c`#0KfTV)>1Ec2JzMHc zk_Atd?s{qsDBgrC$^o9TIGbarw(nc2$W>?7r{;Jp&caf^%!OZyuxS2smU1Y5f)fjH z{X*@9hCV>@sjuH;t$k`u9J!@0-sX6ylDZ}vZAJltJ6|Sh(X-QMYgQ)ddGIf_+<>5! zG)vKoUFDy(VQ9Ac{{`E-8%@_+8zpR3xLRH* zlJkGK&=XEU$C)PW4KVS$aqTA@ei`j9?lfFyZOFlsnnDCu3dsf<@k3?Sq2~kmj|*?@ z0JfUR!K!+mG}vZ=MKHYaoHdd)O9V(d`qK3oV~5$k9+I576~|$;(q`oag!iwES2*ga&J^ zVv^YhHc3g+#vzvgr$()}i#UNA0`7sCi*b|cuxRD2DVKk13Vb^Qt96I@4QIwqjRwa6&*hxp2IjPGpwnD%49m6D!6M** zEmxJV4<7{RrHUm;H?HT6m@+p3%dRv$NkVRKp37zYPEXTPU2v=8zj9`e=c;xDAQW~C{~DXexuXTeD}@y7_0 z=W%3K9~#kAKWz!Nso2pU%W0(Ki|d?y-!tnq@NNc}`v@T(D4oS11wQU~Lcuo>Q|IY~ zWGu=O)6c|Nl2s#_x@($|mL?ETJ7fQ&9DL@o*~O3{=k_6((m)>uV@=uPlL_xpSi}Ap z6!~Z`xD(eHUh<(9;4MP4X|o{%CKtrnLxEbcxx-8iBgZMw6J@Oy|35&mx<-)iQbvpP z3Mtfu9EJijlvLNoOo-qUPLj@KW)iC+_Ol$*%hY71tu4x4vyKn%Vn$?JHgt&`dbaQn z7pS(sNvy4ipnDF}zCffJ4$M&S3Em;F^aI#VSmkg}A00)Lx^-?G&m5}|-epgb0}h6r z_|n}(!AuVV3BVmz_IWT$!?UV(J+p@Zshn6~;#99CX^dPlWF~L;t>m%BmK)H?qCv2H z>yL=JF~Xu&Fb5|+eS)>Cvl_{JScOYQ#2@=BoN-*=Ca@Cak#EGaLz@lt z@jT+Zzw+%fDoh~3!n^5m4Wub9Ob4&mHXnsxiCQ)dR?E<6i?-=B0U;|fr!v|Yu1Cn0 zqPVXW5uI1Myy%rdT2#iK<|r+m*SO!m1h)q>DO${Gg$fut6g8W%Ya&CBF}S>Dl3y0+ zeK~C$Vr>g{_}=bQ1z{3-Sic6Y81e+&gy>_6-SGh(5IYO^ zSF#uYJ5rTCb}~yGK{yEJRUrO4d^kV4+m|VM0BOOF7vrP5b9}eFG|VWG6-(SeVSRs6 zMz#=Pwa9`?>$3}Ey1uS}p+%VpkKn}&_y+R5yxmg0vJ62MmF+)n(Hf+H$U8jQ)mE5fJaP-NGZv3DdNyLnIK$UxO}8 z?Zz`iFqe>J-;Yc1;)6n$Ph#$bd!J~kcC-0rr&DDsq?nQ^#s(;{stq0MGGP*620#rw z(6eKE*u0+(3ru=*an%)~PNKs3+$F2C(MAt!8TIqDW$bi!F)OUR6z6DV_ldver|p^4mDW%L(ZUEy?x z7=wp|CjvYq2zjecH~7wl%0uf3DX7Y@ad5|{Z{f>J6NmQL+8psJ3)Y4UwV-eE$rC4a zBnc8(+G8)`5HeVpnaJxvCZM+7%F1_eCN@vg+~cGR_mdBdnQZj~3z& z=Ie)wNs_#htLRBzQbmslvn2ud*EX_f);1Ynm%>{UDM8@1 zqIKqu9Dw;5Cu#S^y>^@kW5~TYdih8M(#_^CLm!(6z{>AkmC`dX|QnP!71|8CKj0uj#v}fq2SZV2PiZOo3&r& z3^pTpfGQ+NvT5g_EE2Qq_Y1&;9bTfFk=v7>OOsq7l;RG4%64X~gn4{1u^dmpK(w+Y z0LFvbBe{JxB5{Qr;D%38df@3j?SC#v7OT9~VNn@txf-mz;-Vr2K{++~K3j%Cx&8XE zUXZ9<5-kWu`qL8-Gk;5Nwu1(=n`t0|fBs_^ijjpVs<%bzS8H?z<4LC^j>vC5aJ2bg ztb=3GG{vd)5;5Oqz81)W+cK0ZHa5PC+)l$r%+yQzR%mx$$7FU%DzuQP`X}h!1kB=q zFGde#!cvFTaICUZYGG=E}woA@g`x>YujMWf?;9w2<#dLd<-ZL-N|~vs(IZ3 zuG>G8jLZ*OmfHD7%AwBKQN)>(eC8)zC1mdH$$UGKta7cX@|L-&POdNi+lAzWcnqbs z*}(Cy61R`nCqFK)f@>7L8tsRy)mcyyw#~j+nc8*|mKM24-5Mi7Y=$sG{v4F=G((Sz zlKxc6JX8ht`|9fT%nWyP)QNwMn+!Z?Cruy&Z9V(8-<@XX=j$@;Sg*N*+2ln`99%3asbZe z@h^Y%j|tMWQ<$=P(|jP%@5|I2?m8O;1rDv`?*=@Aj**akxX^W~f7MMBm485`So_-s`r3vZl>U}PPAWaJ;eQL2S73t*bqUdp zpPc=IJ^y_BQsj0=zMjWI;j!kb)nQwjNv*`E=aU}Q9pYBN%tUwhOmROD{rcJI|C^kN zCgbibkmdL$F3@K-dfzxu=RSdi-OnJzi5L2hZ;Gb@2*b!3^kVLQj0Fbn1bjD)Q7M1R zgcP?71nKW^`7jb_Qj@c5Ao9G|{}k|t?3Zuj0Q9f=Z4kPmw*zczt?iu`8?Ms!VWA;`nP6!~th(vmRkt4%%1(ee<> z1995L>vXISjjugu%gx*cyJXZRC-yVW7DmRdL7Ad!L9ELMDh#)xP>|G+T{P0)Q=YO$ zxQ^T|vPE}SpC=0N1LEzftl0tJ=PBqyYFi={X~}B!`jT5fH0I=FY3s4X%@{`&%ux1 zg{FL?pb6~aOr~zz@nzmNcbN1Agk{A{BNkz!Uh0*<#(#J?L7SQe^QDUc`*Yl80G<7z zlwQ{wFz9sew=T7&?T4<)r}GeeOl;~B!EJuCc^us2_}UYkX%l~9UIEQX?lC0)_+D|v zeR9G7^ymtxdJf3@RW#1RFcK+i4y~pxNby@8RrD!4IrS)3PDPPy11f_tN|746?(zV@ z5f$XHU(@e9D=4ie9yq*5TUr(`%B$q?&?1f+A0JHKG;t-s|3f3q6Sq3*a)uGEaLLH- zYC)6qp2@!U$$-lAwcCpKt!MP~W}YQwHHU-Fkyf4Mwd;rr#^&=m?f}WBvMI>S2H8kv zaPXf_VDr)&VQ=-m88R0#p*@S1>H2BQ2xC2?tWC2Z8y!A_p?*QNIxtWt3L0jj{60}c zHa2z}#K8o2N0KX0d1u_vrZ)gzn-M0@KU}J3y6aB}S~1crjHll2jxS}TSmeBRE+E;2 z-|_>Y2+=+HN!Y{ASh3 zDOIji66DpF2(-|cCXm6sHxjW|um)mS@@6sACeF0$3j>E@{Q?q~?M(4&y5yc}$bK;q z6-aUvR}RNp#H}QZ9&|zQ24sfai~{^xt(xoTT5D!1zf2jWc(V^zTC-D=kU-gt=xaMs zqp*HiIR<1~HxfQFd}C+qm24UzR!YZ51`pMq?F0tonZ)?mrqk|Jr!@((o}@i-;erzE zLp6b&nm~jA|Dj=C;kS9M#e_9*x^ySy-P;oS|3*)3n(MiQ;+)k{&Imw z8lk}{Br|5ZpH^HEqj}?k8fxo9WI65C9K`iIV8xWp@aC zPL|R%#)}>TYJC*E*W8Uf+^2mD@UkI$q*b1~Zlfuwbs{JT$`M2eda$EBe`8phk;X}x z3m%!-ypBz0_vuQlthLdRzFutS|D?A1ggydfz9rpqh#(XW|HWj_Y*yos`rII7H02#XG0K$ZoO(*m1D?fHvW(dh z&#Iq=m!H@V@8tn9&BoQJpCG{bnz@F>6kq{YU@##~K3NQ{c`}cj-1z#^0B~L8BV{4L zfDf30KWIK5pgg z9UWzDLPSlW_hmJGUxX93KtoQCIQAWwq{il)g!DbNijuUCANbmRrVKAvSSe<$==}&C zPlNhzk#kDhpN|faN;4>QU&NndZM>V_v3D?1bt=(ryGmC7@RHrOPw9GF2&|#Tp7s2evjowWFqn=n<>6>vV}-hkVL3VBIy}7h zRVFVDUN5+^o_Q&XC`$VFib)mR6{h)%Kq?mQd_^f=n?lNGwj8M-*d@IX?l^zC%DX%E z-$@}U-Rk+MNudW`BgylD29>!(5fgT!Xq%|fx#mGsM=QSANwhn8`V*;YM%)RCK)BxI zsWb5MgRQH`glDLXq$G4Mp?1^Nl}$j-?x;=`bu44%?{__b*o+cG*XW00Wg-Vg-^X8= zID~*p725GccX6-C!3|9(1ZW$h8Y+#GbnkbSySI8zHWH-&vkQWP7bhj(?+PB8?RYg= zEb#3kU7ass+hgRR+>N+&`7@|MoI2gg3MrHjjhM`DYsup2FoWk_RBHBz8_m$Ir{yRQ zsJU7W9L0fhhwz~Mv^Icad`VLw1Gl6{N@3({Z9`Qq1`m;uu^*>&fRoMh5VhlA49!u0 zCMg(Ui@jJ3kFb~^-nO;Ud)Nw|_kL(dHRH)cc_zU5hmZ(dNgZ53APEW>?|Z*a_8~5T~JvHYvxABk?x)cMzd4 z0q`S7C&*4mq;;k!XTzW4+?wIRisa`&=3c9qv$0d8-07M~a<=w)%W^yo*1rw%kGr1c zIt$n;>>7Kz91^dl3|vWgt+Va)^bu2p>7?VYb$@$Xa5gR*?M?>FWVo={22=KIf9-sp z*&53ur^I4wrj^V_*lboD7jYQdBX{(R+OI%ita&c#RY}XozTmm_LMx_Ox(?9ax1(&# za=)BgeA9pDwgtlTRhYYiK)0@B8Dn@0;KD^Y*D(8+7!mnsIiRwC8>ojjP_pqoDS=KAQ-F zbBiZ7leT2=cu3K=Cw@v=!!_iR4)0Xp>m<{sqb(4d{;0&hb}?iG9*L(+ah+gmf;P6s z#o-(bcr`gGi1U<*)8ZwmGE;#{{Vun& zfr1Nh<%m6Q?r0`;(QR6$CfFI2h;$8SM6_q+d$)Ts8kuNUiwYRx-ln9wY2Q|lp$Mp0 zJUKmvJKzo4LtZat;XFA?F+oO zgN6HC*Q_Co+1yf7mhJO(V+7+a*GxrN^Qvv@^z{Is2!BzYNt4|M6eMlTkKhi+DriR`bVrqFzSS%zt43Q#=-kn0Ggyt~zZ{wg+ z39h3lT+BZUGv||fpzl}#mh>H!S^`181YSL9u;k*SvCiGot>^{_#JN@Y3-2Bbqkdxl zeOQxV-`;t|4(42Kz%T${JYfW;YjM}yj#s*A47Cv!{+X3{%g>9aXJxBH)O61)j<$s*d4sy3f1zg>AWFtqb`b>yD)}0UCxlmC zQdwWIpE7eeTI0_(b6UI;F;MfY!nAJT!2hh30ogr+NjKo0+PAJQEJd5ceDHc(H)o`G=M+-o<4q)^qAV$)%0brN(T`BkZXD(;QJx?7F!qnXPlb zhn6$HImnFY37=5E?Ok`*(yv@?b26axpn)_R6G)_$92~!>ws!el;GEXFNbdkX$;vKP0xX#vCSJ?#^=qi${HPtx zBe&?{W*Y{T5yvV8*!uaQHfU5ezi+#2_qKR2EyfNb^Sd7g?d7Pl3PHt2HuQ~H`Q_3B z@s|xqnChp7-c4u>#&n*>1m6%={yScY?3Z{ndJa#=yFGw5e=~_r1&CHCMaXzwpSF<< zoLWaO62Gw9UYzHV>*oONPFpxV_C%Don_j<4pa}Wqi$H#QrC4KOxle|o02AO$)4xLQ zEMAPRm86E&94T&RwyQVgx#aF4BliK0*&>@zalnsP0M54@*M~L!4ES zNnFVQfB;lZbR~$>5X#@F3;@6f3fRF|{r0g28zFM)btsTdqw5nqGa~AgK9rmg20^d3MXcj(YbyZ7 z-c~>kPKab#A*ou6Tv&`fsl?@`%!a-)e!={@exu3#0Rr&ZDeuon(nGaIxP(=Q-sr4A_0`Iy1r zv~K)1yW;gGHF6rny;eK5WK1`%v{!N}pL<(-^RpmN0RY;eGCwU6E2aHfzyNhFZiv57Of^b1JiS#0U?cD41>Y*~UUP@TKF1shzD1XH zbdaQu-W90BI0?5`r- zzOFVp;K_`%db(a-%RA-BtJkj^s&*52QdcON2f|MgD5&GuL0O#JV`FakJXVSs+U*)d z`pm|SbZo|msjAIci2|-u#dD?<7Yv%DoBKnjK5;lqoghlvn&MjU#;IuI6dWmSnhJ(Q zg4?Zq1G-~8S_#UtWy%|}STZe@E5hwU!cRN+D&*gs%YZ^5XJo()@ld@!Mp&qu9HyWI zdAZD?sX5`~v;McmafQ3`!BL zSQ`*GfHhl^{o-)Q-Gb$M`{3rTj-s)&$aETQF5QQyI%NA9%QFAmaVHDEAe0Xb4BEB&f`|yx37Kf8SGP-1A%6)Z=Zx;V_!Z zsgWTNwkl|-%RN0D2r0MfT&9@Q=+*;2+}Gfk6R%3mc-b-m%^x2*B)$9$;s?HFAoc!@ zR*C4}tld~=E28a)WBNvgOvpfO7C!vtTMkXllBk++fG5i*$+Rx^MTHz6|NE3sVYniEvn?K!qGxy!&CE@NmL30>_9bd{<6Sg)%G1Q~4m z;egbcO*hJb0=By#x0B zG#t$&Za{BQM7{zFgCn2yNuGX$HFh(z+-$4Qh_6out~4&8iK{3k8~<m-`1kS}@EOzgEJeSO3L_m6 zBx6~#Jo%~B1GppqA`12Tf041w!8HCOkp-cY2nD`4GZ`S* ze#2MqjrW6XfZaWjF=bWBgcW$_>|TIl>ycGuG1(deqKY^X{3=yzzTdcKe*UkPvN`Oq zX4<Ux(pNtlE=Nx)d^O8rosLU%u!FPZ*~Oi#R4k zkZkxmof8({;q;3^>a5XYZ)5yq2EAYYd1#nD%oDL~J`Z4aX!V=nVAJ}e@f{VAkbk7A zO(ouuuHpiMNKOg<7?c;ywL42A`{j;60R&6Xi(6Q7o|OiSQl^UE-?*>eRpvj3K`){f z$YjT}XC{tRggPgm`4RE}kvY`S#)DYaB3r$oNmwO`Biq-}?K*b!6rmpmm#5=g+!VPp z>}Rpj(6W_k>cT^MA6t5yHbKRfS0>cp2!sdAn!13SwW4Z%8U|~y_K4PUFQ)E*!vq8K z6z?O|pS@Nbwbke`+-UV$FgwcG^-@ghQC6y2YJ<6cuTf z_^v9;d+U&8z`K~{yCIJv6ude|wE807ZCm?j7 z@(Y2jGK_JVXTrgY^LJgH{2Pw?WrXDyVi_K5u8dNvyJ~9VzL14UP7hqOj0X>W;Q*pl zo@0!H`*c@zE7;p=VMCd?sblhmJ(u7&-bVwO+FDS7s)?Ab?ACKm#kPt@gIvv6NtMJK zzUHl$1LOF@=aUywf|CG1e1v65WR`2+t_L{D79+pz-`qX~)4x47|c8>b!0o~W<8N;XiC+ya)&s7!7Tq6<<05$-N6{Xnc~YLtpz?8Z%h_h7*+#7J+U%wS6c@8*1FgEQ_?^R7Pw z>uabEr8T8^#&%G%l3DG;e)bjxWXR&riX6Mq7ra>!ul;RktXy!NG4)B51u*fQ9|RK85M`M|+zdHKOU@2B@9i!f{s~aj-{&XcIvWn*gx-}#tV@rEnx4jdreNXwaJF5pfGp1@ zZT-Mf7D_2{#|BKJ^5rZLa;=Xb5 zI?X=*^%&g-E3(aicz+aESjtP6B^mPdThuKv(=3~tli6S@AiqV48te9E^AYjZFt|e_ z9Ts8x2L{T4Pce%KUr7RC)aJi?;)9N7EY|$btzwza+ZF#&7`O{NW#!iw<4ZZ`mKHD5 zjLmpuV=JH5HxFC{0-4dOh}`i}P)`9}C|{Mf=NGhH;ike->=*hDa98nRc}PvUPRA+} zMdX3uM%<6Uj!w(ZcLH$^1Yb?WE%)E4sIk}S+oKQ zna@j5qGC70q3~AyQu1B`4qxUJ7hVPU0&1}1BuHFUslCNtBTUb;2q+>8(yr_{Qcl$Q ziJtO7z`nxq@$-Sa^tKr{KKqhZ_Isa>`GR~Zz;e%wmg`0M!Dkjk)oM^>s7&VdpS*-4 z##dPPP9SCoND3t*rev`+Ozq@qf*n6HH^N1ex%8h)PsLZ4J)jVN;PXR#b*DWf5flQy zUcHTB{lu~jHY$6taf!^GK;4%G`q|uWA)uIc$~{GvOYuD$Fc4k7?5-FcBs=65rIQ44 zfB{*=L~J&{iI&JvkR+(ek%Fuko*jzEC+B&7&ABg+^H$l!4^E~85YH6R?CxwrICf$eKVg2g9ce}NN>%pFi?661d^p9clmqKwWMhpw@F5C#DoKDqG z3;h3}u_tQ7hX(&&c`BQMKQTmp79k9Vvv%3kapKTi#RhLOg;|83YO{XAE-1CvziNNEZ!7*p%D5%@7gmC>&!r6kwpW=rXl9!V)g^(u(1N_Y;(RFR4O5WTjk z2UiVk9eaoPeKzmixA1^a<#kQzhaj|?*GK=PEOl)vR(jf9SFp~Yi2O_30{1e67adL1 zTgFJp=$l>0QEwlP#i&}@$}=&GGvFk6O@d-B%58I;`(?e`qbOPjP53#%7Fnm0Q;Q4l zAP;EfBr$f4>#hw)cUi+g$oigeOeIF=hbf5FJYeh{8&r=MF48?@6Uf^bC*)T{@j&rs z0dSn?#$zfq76kuG^GQXC{PJH}UaNL*sCj#r$hJIY&$x_;3PMwV`=Hv4QQmB&imsG)rrN~BQT*8H~S*yuv zI{ejtZKsE7uwtQfhTTPOYU9-JSiK+Z{W@@ULbr=HG*y!g)GBWF4#cdrPcDml7I?xH zF*@x3G%WUxTDrTG-8?Fs@jTR|Zyn%ZVFU5O!0GmeOF6@c^)|)J1xr3}?ccEZ;iC&i zX?QbeZL!(x%8=Yd*fe^w!4}7$_@ZjWB0uhUO-x5tSt@1p(Ml27eDHMBXuGooUkMv* zuc>zEX^3-)kRnOh6y$B*u&~g{3iOYevJbnr4m#P&e!`6;BeU8N)>B&{@ z$NR>b;K1@6%RO0Q^mm2LMQq*35m?o>@q$YEW5?VJ>ZSx)WmX2Jts7*7i|H1>b%VY1 z?-$RD0w|>416WF%_N+(@Jbng=dP@gNatc>}+RI-h>@vt51zAFACgXowm2o>nmH>6j zn+bC)swRYpMcAuyT5K+h>fP`+QnHT#+r8$SSfBm*3$ZvnI+ZeM8k>zDV1%#~&!4z#UhxtZy%|c|ieob6I+U$OM}lR>r6|L(6>YmYKtbvW-Ma>ngwo+2W)$UK5l841yd2P9mpR!1w z2hu!Y_cS!`T@ny`w${_2(OHuk!MeAa^uYZMvF3Fqyz2RXp~&PW$$+aOZjR1J@&<>a|vOmO0() z8D*=&UGQI?33%`#)`3VgqzHa$*zD(KCXm&$BsTvvvsr|JkyYi!qArqg+;(PyS$-n! z@Ps$;7=kzR-X&HcmPlEH3{Ol_cMoO|*W&BSCKAQj<9;#f9NtP@+kD!UbH`t;-98jdqerr#y(f%t$};{Xh5P_aK(oKg zkRrFiQ^?ygM#-Sh-s0Hx#SE+>gq<69swCp~q3&l|f69AzvA6&rw5%c#)@4rVlL_JD%+*FRJk=+_w!-Ow&JV754-uTh*Y^a=-`KN`^kn3P=#KO@BxYDz&raI(uDtSZ%&&k4 zQU7B@kf>TerOe?xUzX{x$;@DivN6jU&^OrGf)-{K>bmm%Zi4ybl1r0zt0Q=F+d#jU zLZ9G$nyXeM`0dEQ%(lU29ZQ?e_Kb!Ls22q%{*+9w)k7MXvPMbCth}Ov;C|UtgkQ%r zHkK!yN8Ff2Wj6!!UlOL0)rk2lxm72)PgB?XBK7HtbcgDLDyOkuHnNxaW&)RrGS57m zQ$pQya24A+JBU15niF2%xczrob(IIE^a}UCw~2E^)P{gU`w|+^b6Js$^^|IjOE`u6 z%;j${M#Pg^IG-GtI~eg_d$U{k?%JrmMbsIRy>iefREKT@TPLT4n@3sy0?5ULsTG)E z-9+bMq9}W&U?#Vw=A6K=O;LXdRuPtoYSEr>yh{ocL#e9LgrfKh=V1P?CE${zrc6WH zrRPo(`qsX1`#>Ua_r;K3MP)aL;BaP7*F!D*9#a(1;@K{Q8Tz5CT%RIm1*)v+g!Aa} z&!N*8+atle@_Gbg%K^Qt1A5o`DdC<#UzaKHcCp*+U~L~9i{wmKf|w;oM(zJFbL3?U zpH^?4imj8K9aRLQgWMWG^FU%xaLUYRQ{Kn$lX?U`iuuC{p8FsXj-!bdRAWc3!Cg*kK)jiHw_H3iN>WR)*;K7HaShm? zdRXy+K_bQdO>H-&eR8dyQQ_$&WSh!iOzs6kCDxlQ;-G{-k3hBFA0ls#83=2-HSDYf z-$74MOlPl~1NniuOf@MQ^ds}R%5_pdyz+1~R|;=(j*Zk>Mj2O0#!5dJW)Xn}H-R4} z-fC5JPn7+aH(e@)=3JslGjb^tuMx3)6roN+5Omt+xbXZHC2v0X3-|ot|6`5|c4r@_ zz6d0e*ic_6uS%Ad<&Pq%4zL3cap|EXKwBW`7Mp{HRdWGIyPMt{3f<`t)Qifz3*IRPVSrMJ zAY}2G04OL=H9=0mgql^ykJHf8NpceRd^6BoG9Jlc9#`NkpL8P)R^dCuHl*%j9Y_u~ zbIrm}=9^A`6GL10H*QE{e|mk)k?3E|dO>DRe8)UknKV{-#pOcqlJgoZ|JipYJ3^wx z;GtW6Wpu9C;{xt79bTnEc$o>4IDqO*`3i;unmp@29{GzG*B^C-mM(lHrR;6-hw+*h z6n*}$23Zms0_oN9x#!3NswPr?94;kh9Ua#ANDmjek&E-lb;}~uewLpn%$f$livC4E zCl%j_`Ynv&{^#M>kt(fX|9JOt%dZBb1Su%`8W)QU)X`d4XpSB#OC#1RHD0j}Y55U5 zg?|CVAEN5oXn0?+jYP3|>{t`H6j?F|>9}k}#7D)6 z8Zyb{IM}v--hz#&`Y+}xbq7gl&V^4$9058{_BoTiy>w504#+9jNn4b}>Z$@49VaE$ zRP|Pg(*~Hx_aglqbz=p9nBR-wdPMN$)KMu3U+mfY>5zsfVsDE5VYB{QoTQQp^h{Wx z6ldlN!v7vl&pVB~m=rtXkY~^#*k>NE`69)>`DkjfeRpK*pXoyYa6r9S0tR$XB~|&36~9M(0K-N2YP6whC&nMw+K-f3CjBg(p7HOi{3~;Q z#)AGAFGofNke(AL7wGW-OO{#|7y}1yo4DSir;>?#LX4`yy|-l9j29n+?Vgoop_>;E zg$%o3WBrib)}U$%dMCge*J@n(&Lp>tkP9G10Tj#3F2c-e&94{raJdkjE!1>XZ#bE- zyDpe)0I;7}2<|o8swV3$IuTx-?6IFddsQ^-^I9x?Nm$L&YxQW%O95s>PeWXu_pZpD ztvU+76N1bAl!?~x2rwJYPmOKXHI)ypJ-7~kzBSGu;1$07BqD_Wd2gh#hCdROeasmrpWcRHGIP_56T?>*X2p-F&Ypb2!Q(Q`Fj0>nq(da)(6UeL8$I>tO0&yAODWM{E6BhZiIa8YK)He-NB92p97GcZI``4#=)7 zTO1W9f{=d1jD?87-Jn<9O@p~{36P=$P+%7q{e7P;U%L6ZG8R5P3-a;@_tuPK6s~4- zG0di>5*W%O-h*;Z_>_x(INf`yQoIq!m4K%Ak$JhCy!T#Yr+cmjV@=@39YKxn-KDyz z0Xod7d}R_bf)%z0o20$!lD0p|3gQumu=5nZv^%W+j86Cz-&Kma6T~#D6REf?5j4%9 z%jt}KtczN{!=77xcmos0m6c8QaIAvicoI1kXKMqL5#)eq48Yq%Bw9dbP8h} zx|5sxb)%f!e7dx#Viqq5*hwv5<4ny?Wlr!_T`0mIZ#H)^o3uEKUi%7`2HQ9_Kx zc+jO6IrQ1}ZmPQ|Geeu&l=&m|e|Y(_(9X(5ytQ;7MTPZx7^%J$r>^BsJ<)$u6fFUV z@eb#YJ57(qqD9A{#p)M{53-#&fJY#>M9rK5`_Do)-xWcw0J&rqcrwSF!aR*8G2RVmVQR|61isScw~Xf6eDFse?Nf9k~{;=a<}67E}Kaef)$ zl8QGSrb;AZ%eQOlNM2_srsuKLvPZ4IV)c=GPTyky|F>}Erv!`4HB#SCU}7`_Gf9Ic zT^m6OX1^LdU;^_71m`wEQ~i%~yqD{WmG5$9;y7aR?%A2aP9mljdln`+MUu&!I!h>%9P%?W-f0 z>OolO18@d$elF1?p1W;0Ys5#LC`{1!s*4AE*~m!60VM6g>xV|nRJVptpp|%o@~nL- zH{RsqZ(PIDf1@b~!!ztmCbh{o?1&=d4{xgT-=9&T9h$#Qur1n54mD^Iwz2`;vjB0X z!kIbL%l#n|?z&q%SZ<^}J@oetgEy|Drl(3yt@@gYL8P$P_<|;3D*fu_05Sl+Nhqp# zFIV z({0Y_EA(4|fl0(n(wmk!#xsC?3+4()j81#H%ia^aoovA~xRu$~Y5F+Zt0Uz3yIUM^ z@v&=zk)fQ|qN?LX)6czv*PU#aG${=D$&6b_j3ex&e!TOXQf?=sWCNm?elz#}S(WD; zOSF$G͈Aw;7juPMWzTE)P}+l5gZ8$oD z>a>guPAMnh+rxs#=-Ymo>8kznzeBo_O>7-|E8)RkHy7bcDMCNlj?8I7m&5C0MABa9 z$}}BI^_DlSe@Hc!u;bG5tg?&858u+GMGu~t_VLb3O0J4J`>EV zK!kVbszsaEIjQE@hYWeG$`CB{+$>yiL#r(kh4b1lAG03Ln$?gY`SBk#QeH`%UKvDD zd;c1jf>b?k#8v*IYP>PhRQP^*p)&rU`zD@2=jA4LbV&HDQ5q(CTw4@2-^)}qha;e{ zNrQH!b#u)JFiVadu&8C%zRec^X6Q6wZIqFc1m)BtCJ;So4$J1jDYke$w&NB*qM5O% z(u8OlEU-VO2Y>e=4=kk42Mkg^6wA9muXJF|z@J~${xqvR4z}`7 z3_asr)1aYuLZZ%`_AHr&xQ%x>ciNU){YDOlRAw=C@lw7)r6K1$;d(&SaX{53Gi4EAlrsKDUNjJ-u*J$_oPi!FoGEJ>JOgLGo(JmVKnV^`H|6 z$z7G{-2=Vm>IWI)R8XW(sA$5)Yj{LKDBpJTENhn+##UblC;qcoX??C%r%kP#hEK!!s`xfknr+WgO8ti z0Iijz^}2dFa&n?1zQL6-R6tXUX@Pb}!LwBC-;p)4<0vLjr_2qY7nd z%grA$VcP)DB_`Peh9MA?+MPh0swc10AQ01Qy@>l)!a1WvjmXg5FTHLLS`?!`wkl$W z)yY_w@x@f*3wf(1`zZY2-VN82FKFu$B#*urUR_$i+Xba~CuKa0z{L;rcvv%1dwY@{MkanMhQAadF?Vpm9u zv4iFY?VBz7PfT5(2ImU!>SNc;m5q%Svhi5S>2*I#dG@1h7e44j@LPYW3Y@ZZVQ4qM zOs>7>#R_n(szB$%^uI&!B8sK^|6T`uJl2}j z!r<^yOc`5z7CwOu@9w^!bHJhE%9tF?3VX=S-0@%?T+7;^#cWQE{(<_XgXf(}avq0y zC@5Ofi?d7Pw#)V7^BYtExw_JZgEr%Popbf$I3$wIII`>8rH;yrOY$)`f3(M}bne8keAH z5r9x&ynK<|@)E{4QBftEpH^w_tBbf8-?=CdXl3o1k*<*qiZk9n34xK>6OO zbQL1jL&DCGyRS`GG0J#NvI@;#-{XiFbYf=66H$=f-*psAB(}J+-QFSeC~}nuYoGsq zY{F&dtXTVB>TQSkFYJ0y_|(Ui%RKtv5^qbwEb^n<^UR|POG$^n?Nygku`dHNhqv*I z*8>%Q9a5mSB3hj@!)@BtaV9AGPctsu0+41l|9?;$QTKtkAPuVC@@fbm7%!tUXAUQ& z%Ak^fcpY~gfchQo;^NprEo`Nl^AyVJK$zVOYVa#u!ag--X7%w3AHhFJTqcJcmLQ>? zl%OiEgpflwwn?)xe%425O@6#9KFOo<8<%)KuW_Tf7Uh){h(}9%d%q z=QE-z*&blbSAH!{9F}dT$cYCpGqelZPQeWdkKz9hYw*53TdO6r#j>HmwiIQN(de2w z$pVfxaW)*&)-Hu^>LuV0{AmLz3AF7R2do0HG643Br8%57ZW*UIs-imFrXA<3J2c=Au{Bi5<}xVvT36nyNS_80QNDgBqALMhQ)-<6`BMVZzVBdg6C>`L@dwj!>pS0 zX%*Q*v!Op(fQ7&)<0|CGL9&DfC_9#+g!)q=JM=Nv5TJOt^+PQ)*NxsH9Y~OM} z)ag!G$BKnGGP<4TG(iAKVQ0N8Eo3b|tRDb#=z#m;cmy~;5>5nHbL2i(JI3&=rhoJy ztZ(cA3RQIS!8Jc3=tIZb4nDlOyJ+|y%a-C?s+}^!Z-sCTzD6~5&r@mmZc@Mz- z%;2T0?fUKHJ5@B3c)_mYPTl&R%BO7oZ3tlKFf9DCuCqsS0abnkC7-AuWqaUm)gCvZ1`RK z_zFzAPuOjH4J-JPr>KB(!V$;#wKPGVPao3@qS|Zr#Mj1|2bO5xB;T|jEBb2^BWM_N_sGTdN*6YJ@jhBs)_N8i zJsd)3Zc=N#I^^K88lllsloUo*s%m9X@s1BkmQYR140OS(YcaCrTjv4V0(>$0buRFzlkfFgv=jTxD8Ea{iK$H2vfrh z;_{D)uijR*JJ(*0(RuTY%#B7aki@mCQ+uUSf$AQyNFj4+F?m=4<+D%+824>91yOD-%Ihvbe~?R5Nl+4z&66B6i__$!R!Gflrt=L0^=5>F z{?%ulKfzvB5Fxn*gfyu!B~ck41+%lVwfK8JUFwXwn8so$iKbQrk?-^=plU83;@QIP zW>v=8`GXc^3JZ0CN)WRswN9Nv(VX#oO6UT#%l@^IYO(1OUv5ZDlK2XQ!e|(1A0v&$ z-wDZ(B`y8!?F-21mx+_1=qZh!;J_9#srB2~-wFK)` zXBEF{tn~MRHxKM-ftZ;ZY=+Z38wEa}=cL-xq5@*SJ8!o~-tCQ;!zzvE#>4&3tj>Jh zPz#z^)v2>L-CC8;$8-ZPTxFu5LEs)mT54Yse$5_+o=&fb*dAF-UPmX$aFO2TjauC5 zf@^hkU!sJ}x@xg{qF#JR#cs|wFdT}Qv4ja0r)_w;@<^?QYokt*kOlfN!o-c8S___? zY64!b{%u*H_vXh?Ut#G3Izve^3=n&m(jtUuKV5Tn5h>=S7^5RYpu$0#PrP*12o-m* zDe70$d+ZOFVgM{beD92iPSiPk|Dg_nf*x^yi{a$$MEj#A>iC&e-F8H8*AJlkt=Y$} z&2pL^UQ0 zxFP~RS<7eX0TDEex43_^)`DyfwDGairyVgnI>xQbYbTVvKwg=}{`MXNVO1U!D>YUl z-FwX_W{)1wpR*1gUPeM?vOWC_U4vC|mt{wZ+tOEtL%P3H47k!V;$Mdi&nmcn7?d#6 znYIUhmVnK@-|)krFIWVQYLj|}3uxzY69f87Wu@4NMMqL1R!lYOat3%h)B$hbd?B(e zLsORg{4InYcU$vaT?{~{Zk_ll$9Gjz$bVj@7H2aZj%E3jh|;wvP(2HDSetC&v0`qx z=B4%Prag;-lzuA9bM}ARe{P?#T4g=SXRl~oA6@sQxC>Ydp!?CR>YG~HQe)ne<(T|$ z#LSI`;SHrk@}=5s&mb@9AkOZh1RGq-5)RpkvV91|D6IC3veSX! z^0E)&pNx@URRI)p#(5k#)qhrIqg@)FoTW7V@8oyc zUKr0J``SNxv}o%g?lHbDn*CVNbaROjXfptL0T0bQ%(cGbr#CxJnw1-G}*&?w@rK!MEgLg=iP-XC6rv{5sRWd*Il( z#!GJixx-z_$?wvYu?gC?h-6z?m~sNqpL0J4p0DJq2tzBG#y1&W3EA1urM~Iqj#gdS$?g-rlv7$NxT(xvcJ|hu+WkB4Tv4vLCRX3i+RUY((I0IzwLm;SI^xkFDm^<+ zG@C^xVTBoPEd%0+=~Q%b99NA>Il#gH#7vkgHXv`?68AU)bNqQ*62joVzqF~aqw-zH zQ96$fM=J(&G1&qw)X^V1#E6V8RFFFAcE#t57OT-EJ|BAIl@<>4B2|viXY36;l?;b^ z{IDt+>3fwGi|O9yJ4?W5Jz2$*JP~g%$PON&G_1FV93?Tf4PrkUB^X5PJ?)<@ z>nN_=k~h%|h0F{1MSV>&Aec%;&t1`F@$s46+7;|@Le^NQQo;qM5aJ7`fF_5|L{n3%IC@CBpl#Ax55 zAo;MmC(zZs*TDTiwZ!9q z9TH$yh@27YD_Iyb^wv3s-Dbp<-paEsdL`O%4yUAvFeIg@ch{Q}_)Bm3A)&3vd**b< z68Vw;!?RJLY3&F$1H={Ug-(Y`B~DU^?ME~j@{*?0$_pgeH~e^R#akKkY;8oL*#*RU z6@#(9EOFHl^8bJ#rGw$e)k?|de!T8qYk#~XOUP0%3NK6Ww88HmUW(oG6DXX|N(7_7 zvc)8IOYkpcwDh{Zt!05EUUjlFi;EYB5BTQgS7`m`T_wg&BlT4w6YRl5W#A8?xa5IB z^ikp*Fc(J)(a}OnmVgpWmfrTnvl*|SQS`FKbBjxY7I)~|nj4s6I)QMhWa?$S9!^ZtUEf6R;VuPmsbbFq zF9sOT*ylM2SGJzua-nc*8k)qia59k@i)>eenR9_uO@flO>OS{hLr#DlZYUyyyZ_uf zumQIDKMhi6m44!$aOSCBNu&JPn3#R;#=L{R|rhE3^-lo}66?J=|IQS;6>TQHWmxw#g1m6$Y<7%pO(S$=x zdwv7Sd3k>a#&myntw5o8gtqkodDtH8e10dnCO@6Ee&#I(?g=5dCq~CLlqVdHoR4yu zC97=X&Z~yt_LN|Fsy2Sorhb&$laNyhLtOR1B*TniD8dh`_lqXz>-Gc-x_l~^3~L2E zH*whT4jRpX^6bbQE8C}+a0xOli4{?YBd66tg&b8Df6PyX3IBxH#TyFYt43qN47q3Q z5VUrdi!H?UKRYU0A;4`0rTaA5nNEn7W?8oSjYX$W1{R4YG9?vHK*4b$So;z zny&@O<%Qj1SlB4kQzeOvtLv-=V=f#IA4eI502$Vs_q_wzOt`! z)>|EEc#hJsNDZ5A@NO0+Ft{K0*YLWM(8!sfY?qAwL`y?l)Pyu(=tpbFt^=Q7?YvA6 zy@DKLbv3deIMy@1JFmEb0?a58d?k0MY5J$Vtx_%fxC}=NoKfWdS9C$_N4pjhho>y@ z*7PP2w?Ys%^)}r1NHnTn9l=YsVaP#3%B-F=sMnR_{8bnLb15 zK|;>=v-#I6rvZ#->(wln9IZzsvwU#BbStLWczju{u0Otvs9n=FkI0i;3k~S_O^6X< z3nuc^I_4Q0Y=PmiEx$-HeZ{`MKV3L_`;l~W(Tn%*R71z?z%YSRbK@l-cMW9lop=(| z()}pXs;n5+>b)(N1%9b>cN8X9d!Aq!5S3Md-18AlVtj6{EJC4YIcdqGZ-W&tR<5B@>k5YbAGAc;baMMMtp+VWNZ zSfkHGplsF1J*AndfSj+k5#po~B%pO$=h{+|YwKZ;QNR4SSvxI^=tNLdmh}tnfmYV< zfkJ3XCH2P2&N87tqUotgvQy;>yae^PO|4)2x<(6Xt%GRsrCrPQl``n8izr;b0u z>Xe_^AN2q#eRIwf%%#QDe-U&QJ_(zS{Ed}3ojptUFdU~JrzZRy%$#%+U=Glj1MHtg zp38QtY*_A`!IZ|>(#yg5KM(3=I_yF_r}G`PD{Z_WlN`2?yRYv1RFZ>GaUkt{f8yc* z%AmLvG5#RfAq!~{JxqA^_2o)P6c(h+ZS6Oo9oEVTzC>hzoJjwJ#MBViF>Yec&4zQ% zn#(mUD(zG{*$nnLayVUzPdq5Z`7R1V*1xFzLz{Z98GhP2rBVsUVHV75b0{U3D4pv4 zr^Y#s>bg=Podl$-eMj{B8@s?r1*wh!8%iRVVb!u}lCd0`ki?W*h1?(*Qw#1#*&$5u zJ`b#=#FO3r_cd$CXRXA-Z9l83>(7365kY0b%Y3D#Epmz^J6goQVvaJRiCjE` zE{_MwbE45-fc!Ok2D$G>CBcQFSgi27I$hZ1HUE!{IPF5jbL7f!Nji-2zLYMp1e1;s zc|m%@WF%7_L3_~7d*$2-ug8;o+k!i;U!xaa5AUgK(6_zIriwI*y+JYE{2X{Z2P2sL zRz7IjE(7@iA!IZcKMu$Ogn6fu(2UM**nn*nvAcFt5);F!45o4|s#e!bP{LGBm-xdc zMZ0phOL?(!ogZ{d<|Hpw2Zi1##Xr|v`&k}fcIRL!J34rO_k-3nlBfFDb?gPW&^8J) z&VyTT^xA1i)=AmTT)X!TAe<28Z#+BgbFdIgf!h|b_|~nlKLZiV;hYuVLz3+gSS$J< znWL`p&hJXl$~%`fI(~-T?vV8j3S%vl0H*(dVV{_#mG-SjS5jD~H!Pj%>?RFr4mI$q zs`Z2%#$!Mmo!Huydfc!qS)_T1Af-xux+8hZL@U$qaIXD>)1u5d$9vI6975i~kXp(q zRD!99-|VH-Tj8i2d~~ZX-cjYlYue7$)Vu!1j;bD)*ntIgHRO(y)!-AM(H~Ckh7M(~gbE z(Dpz)Ie1l`i23@(Vrzi&HKkzznt!!%m7*odb2!>)SjFZ_3z3v%%i8OI92I1sWq>;B zTGA5(a8GX-=f371w2T$N$Y5aGc)ll0Z4VwULN+T2bSf4oYmt7qAalT6u@Z`;0-*lC zz{#;@UrP^SPiX6G29jUQHvklzN)R8XPfc4^K<>4LrOr`OPj7#sMM%)dcY2Ot(CU)V)*{l2@14UL5R^!! z5~D47h{vsb5G>;!dS9q9--v-a3%!4T;Mbd%&Mxd_mx{(OZ!D=}V zM7uN0$2xdB#*KcFCs&PKuEg#xOw|-EBLa+g9W{X}(9w)iEJcbz5GM?H=kYrb#l-;V z)F-A~u+;`hV|+ocbi)qhZ#yOb*UbCg3}J+e!5c(DZiNUVztJBno3}#|o?LDWUqdjV zM1&uC7Bq1>D)J(yp|cp@Ohj1TAmu@!OIbE^57KpLDo+&r>d#Elmyt9_L<=J@5}3zA z*ggjgy*KCW(?oMwE6_E?vi}#^%X<8 z9(qo+V#sHcoTOQ*%$0<&BfQH|Ge?s0+>*_3(_9R{<(ax~7QtsUCnzqYcqpyn#Q3(l zlzTpDqHXhLp)Oab@b*1$sNS7hwaK&_gYT6TXDGDwD?8n|+#K*U2s9p#n=Xhh*O?aQ7uqa+C4^bwRdGI@7lPIY4L+!5W* z1tSbt%1nE2RRYxC`?93#9fxR0-Jr__-J>8?)tcA?Q2mWKw{xkR}K35+UPS2d?XS-PR@ ztmUcApZfFpQ;Ose!R!oe-~k%jxG8Yxl(ftj23%8PRN3J^Jmif^#IPRwX(9QyRg8iJ z@96}3V%y1z3$yyx3S&nZN4}3Hfu5f|3zTbaz*H)rZs%T-L5)8jAv3ZEV-p)?*0s)W zEpVaIFp|fT`nlwRBVE~d>MKEeGvb+i$#r_>Y{s$@S5fSHn#%v(Jmj42Fah7~8eNfk zopa|uktgnh<)R(Apg#gw=EPv)?A)D4Z=r6ik=ETZxMV`I74#_m4v9iZ*NCc=tfw?p zwFLCIM0t`-aQFB9mvesR$tF1trT0qN^ukq4kG&mvqX?>6!apJ+^Z%GpO#wy9qx8!V zV9ItyD}R>gr5v0X-65Di@mUe6bPNJuKVJjuNC@K5;e<0B-CDXjI=L}QJFGHYk{sOv zh*Z2ESo@D!2G)_oBMfmy>RivdBFpB1zUYbMcfoc_GbGOkO5AJ={%HGK$~S2t!7_BNEQ6<*6M3aHK z*vFG~VCU*VP^(S9nIV5ft(bcW`|>j$GmI<0(!T1v5)ds+1P2^RFTcfV5$}ZKdFy%# zI^5*?O1h=DgQz#>8*H_ZZP?#za}KQQ?^Dgh{b1IbDT=QF=A~^QmgO)@YTzvy4raBV zmt@C13uuuD<)@FkXM8x0JTgX(b@7rCIM0^>kKEIaRt^qNsw9{5zFWwRP)s?$|O&h zA_f|>&6u^1NoRp^NN_s*SDkbW!6A>bRsJa@{4X&SI0?l!dq9xgUk7PrpB_w2FWVi`w3*oV+2Q0=~qbxt5w&r zN7ql8GqIBq?_LwE;!uo8K>n8KsWZXi;rOJ^&rs2GUu=7Q?+N zB%dQK@f;RP)S`mJ$kMhr6H6+?&b>_cn{;vPqg0oUi`EpC!0oQwFoozG)DKxI@!f^% zbWIdJw&qvpBvA%|WNL5)Jl&ZVMan7pGP1u{0oTQicQ=bp=ZUA@qvW=z==Z8G{-lio zwip(pArjE_7fdZoAZ~8r?-&tmO1+}*Mz~BWw0hp&%BF=fQT%;kmR sonRRE1jP} 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

    s{+h@?_^wI?I2?07cB0l;2QIoor9 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

    S{d2(jHh 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

    _-E0#J^3NryMytm{ZZELdfM$u<A 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�{ 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

    >*fqc^4GFhQH< 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

  • 6Eyy%@Von8l;nd`}<}CP04lEKf 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 z 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
  • O;3pzaC+ZzICkq-v z>v6TR7)`RBntV4?FEkAu`N)ELz$CWWdQJGie_p|r^_q02z*ui3pws!Q%0f%V8&dW= zxC6fd>`^_ohMX>}2F6L_^m_wS8iyD&xfhbY2b4~w_<3YwSX1~v~AZn^@6l5Bm z9tyuSy~vwh0mnfBVF`EV^&iyBQ1XV5NDpKl$EH+#Nv|h8g3^%;QP!&KD!(i>H+uH& zOELkn|DdR#@bE4B)2T=h?*DKD%&u=|%G)4Q!|7`QeV8FKn}8P@6AqO0^ziKha$V77 znfUX;V90lkMs9iQQ5x^56vt-KKlc^~wB#<;3=VaGHg_Dr^p*JgFZvO=A|d7*I6cJ3 z%-m>M`0>JmGP`nvcx+e-b$0omUzdduZW#s-5X5!om2gs4lm^9l#zQ!~|7!_?4n~k# z3Ql-QBeq=-xY+s@Z6GAhuHMDh@zg#a3Uy!%wvK>XZvkn%F2gmVE5zkc-qFuT^e42z z??&OGc&eATU5|&Q1myKVqYxTBd5!-0dD%3)`lCqBdqx!FZ4GI{W)2;T)*m^&MMU9X z#I~5UeQg5~HRK|Hla$~fwo;w*c=o6eY`#1hZ@eJ24%XKbI-0$RA-rVmQO$0tA?lBG zcd*jtdo*0_h_3V*Yt-npkRJb5%FbL45zJ8fD3(%h?)i%xOF()4*WP;Gr&de#d!K<> zNTRhJ2X6a9L&e%V`8_Sy6=A=Eb~xnXqg{oFOQ$;9KMq}nLw#C3jpqGhI$weD7M_J! zx@G0JoV15VGEL7!uJ0owWeX4z;#@JU0~vNSDMK@5#>pp~i)a2SlX@*^QFemCvarL5 z5STFZc&8pIhcPfSdVp<~0!=}L6bqC0dhXqS{&{Hye(ZtPfrnqU2V?ccc|8c}Zf z=-5n2U6a&wXl6>I?@P~r1GWwDZTQVm9%`1oS3uTQ_`g=8RMS|K7yy;_U!PQc&k&O*Tanq=TbfndnCrk|J!BC5$JEAx{c=0ZrGS5M}%S=KN9)_1RafjQKwE`_1 zKIoY3{s^%8wSW}8ZV&W7G1dxHJR_df+kJ2jpJhqk}s`2Q{a*exj7Fyd21Z%9=@Fhyf zu;vjt7=g|mZsJ>GVT`QmKl`*GU4MuA4}C#uZZ?{f!pc2@fTH-eKBhyn4$?17rcGsw)6A@$4F?NwA=MX6Jmw|Az~OCya}{jW*%StZ5Mv$a#Ma z($EiFK^m(d*Tjj97VM8frw!-rvR0^%UTHp=6hlk;kBmHjH_zv7PcfzBu(nk-Iaal^ zvKJ2X=Cs4|q65p(3YnY*f2i=Y4NXkTEE&1eDbY)Ry>z&wa%i)BdW{6XTPk;mZ7bUz&oruDse#G<5RfbR&ry zPrQ5j)sQ~*_fUhi`Iou+_Q1oshM&Q*5yIUCmVt&&-kwx_w8#G>9elFNMXTz&gYVeT zGVk&u%uE0%tp79bRCx6q9e(why$%L$U^F|*g)Zu1G*@fqxC2pPqIkUd1;K$wjMf`B zG)2tm*|NIo6FHW>S;rF-rD3XB|HY4q43jB(;geAfAuTLT zWagh4u%__6hqwO?izB$;xR+&c0Kbd6q%<0L;n?4toRj#DxPQ7YcP~8ABr1%BQfEKm z%m);khy1-L^0yQlOR5Mffo;cc#WKKqN>#0FKV#9Di=$_gCEqUV-QY-R@Tf9jg=I%#f zFUXD@E0&z)pLHk2sn0umy%dt9Y!-5Bjg0Mz5ZpVa<9Obv!5z&PyY zD$7g`l?%dS1RWa1j(l{mA%pz%z~*vCoF{NkOX%;&McT4ij&FVznG42ig={{9J1@Yr zqE&QRjag|`k6!>8q4mVOcuaosfEZ2wzW&XXzA(l_`*?bUl}a`YR)bA(YfSetM53YD z)ENswskTcDKu<5?w6XSST1rdzCF1cIvY42QFFGPV`tLbg()BL{Zn z2&QWK4R!4z%h02dZC9C(YD>+lnqw)rtIM!S2=6DfDQ0tq;M%InH}Zm zn`aA0>dRo!-sb~rw$;Da=J(8wo-_>c)b*;1tt!20_aoW`N+=uj?uGffo$zKg+Qb#a zx;(3-7+z&7-XR%QAhU=%8S)}F3kx&)35CuPM$4@>mtAK@VmQ-Cz(wL7ze?*tu*g6E z1h`ju4_9pMtsHHD$Or$3bgcBos^lQ$Va#D~_<-+fN#1_nL^9Y(#es&nv)hBIPqwi{ zXn-{I>n9Uc0&40ghZRPCd9g-0WZ-tptV@Tsp_Mw;tvne0U}XE%OL^SOv5{lNI_4V+ zfQc>od38=IuNQmG@!9uAO_5P&a~u(txD_vB>*nMqkp)nwe;Z%}V&DCMU)*g(v+Hfs zyzlebXIs1ScBTJZp-%+kQMvRFHC6E&%zN3xxGEA?%_NH}$ zzZ|i^tXq*p-|Q0bNQF<8gXGmPWdNT3!)6kYG9XKq2oW}MHSwZD9oHV8o(cKaJ^se3 zyuqQ{*nqp)>*?$0fJVT{Vg=#Y#_&jvR#^ z{BZGG5#3Zgvy~9Pt@m)F?UcUtXr(X_7}k0Cc_E&4XTMPw;5j6L_5bUObqGz*wo_>3 zTD_6Jdepn?crkLq5ijPb%B{a*M2uqv=T!GVtwDR!gD5TZPL6)WPU#u{qmVdjKz9<- zO7<5sE-y$e7Cmx()~D<3SZ8+AM$a`UWzKh{U}A@+9vA2coXQ#4xt!pc%6=R1DWFVh zJQ#SyITiS;Dk@hX*8?BzeuiBqAr(zyd{ni7%1YZ>z5s}s^VLMIiy2z_W4~&QHL|ab zbMtPje1g;VLFU3ANngX!zOOhAd7kO1YLhPJGeu8xu~wh@lvvH!UO=Sqb+GEM$z5w> z6`C~;9Z6VO0&5->;HE9Z&q(mI1_KZO5sfDk1ual@{sWsv0A8H$YYu}UYzs?#*)IcW zu9Sqtloqp4suyMMlY?f&PXPT>8&+{qnfut6ca*IYE;9pAtehiKg8a@mzK3}EJvK?S z`bx(pbF1eZzWtCWHY!Bq8}wG31adPO1%uwS*Vv%y1i~*z(JDeW%nkwwukA;(S8<=)4&3hR}P7(3yeE`*D2M=NtfOW)4Cg> zJJ6G?r9Wb6<3dLQIEYTPFKW~C;&~VD!txFEhVqB*FfSU~+&Fn7i)Xo`_!JAk^-%zUI_?~4dGm$`o7ulO=N@3;{fO&;rL8dfH<5O=%5#bU{kw8UmhiVc zh9xu?#d|bK4XDY3L(&ATBhf#&AbrG)(^^G;*phQ~TXEU-tcRE+;?d-gvs7Eq@(SQP z>&`fc4z-;@*uOKfXYA?b_NdOQzBTGie-Ro=M?zVY7$<*aNf8odHYvIjYqC??{!}jI znDPOj^xR{?_|b)Pe%9BAE`DeR`mOP+_pe@-I~`#a2a}!VHg9%$dYYWt;{0WKwCGW$ z;IEX?;Z-zaAv63zWXXje5&IM}f^!fGZ@c}xe6ifSJ37Md#oA18@V4%hb<%4)wJAGU8^dmmh_=~9C zROD-2(@}$)$bv;we%mH8`d|JK+t^^^Xf-c~F@q=T$5k;N$W4XzoXqex6zJ+Iydtnr zzw<{Ft#lxl#5mNQ#KThuV(=F}k{FsVFw?(Ivx7L#FCN?cZ7 zT$HL^!s!;oKYHU1IKw4#c3>$KGWidrh)k2XXZm(cQ2*cJw^U(kg(dg~d5lI6v??3# znhOP3D%vE{!=;*{j0hqJq(0EQ>fZ$l69^gHcpzx_WaGiP`nu8B+2SeV-qUY+XQ!8= zbLW`bPRfFxf@ctf?*F~GSwu}HVK+eA# zJrz;0`Nb$T!a$5@;2#Z@EYniHxT#}spJ_!Jc2vRn7Jbbk_H6bek`J0k2kv6Hhs^x< zP7#I#8>2qy?$sN{5y0G`(88lvvQJL|W^#$vthHnsC~p;dZWnjJj~H}7v3xz~@=?(G zNAuHY(o~AX7+tf%}g`bri5#zQ;O@n7NNdVA}X_ z(+|a_WY|2x%pAKIs`KHKt4)bCLz2aMbQGU)fOyI8`(b zWTsj=xDk>la4hI>rT*s9sO&4N#zA~LD8i8d1qA>Yz3_!_r7!ol zAzXCk1V~wmC1^3fe9;mnf6(8|U(q&+^~N;&!2+YDMU zd$FoZS_tsQ+{=T^0Wen*kSYJ5P7RNoikHio9R5wAX*P{Ab`e{sFx$jSQ@xHsGv%#5Q6FP`x}5UjW$*JdCuQO}rXGLmYJhn|`xC~Nhioh_96 z|9=A?dYTIMqiIzP|E}^wwqiRFo%X#;sM9dj;TRIq%vm&gh#7^tR z(+=z-`%5)#Z!2h&S_}W}5Ew5xu^M7WK7l&3gS+l<7rSn>Y(~9e7<+uf3%Rg9s?@K$ zHlZhzt* zzOBt6yRL~JoBkYus!(hdMRIVbZ;X;QN)c76KklgN3%a1+fAj)l(A_!*ThK`EZu2S? zjnT7KnM)CA+N_cL$_0boXDRka1O^FSh|G4x^sbk zI;@`f#p431vM`vL6h~T{Pq=u-ks1qdS(vbFl=4rq*oX72y#WJc*zQS=}Xb&|1~*-iyOQ%F|R^!0i_kqkRj4iiBLv`?tvW4k&R zpL2E$wMd7BVUIs5x3@oC(4C+&Jh4h*5kri5XejBj3|r(`+R4?M&b$n3mjUJV<98B5 z1eq{5+UgN&bUBJbX>MJIH7a@`6O_ygf@6Z`;$}uTLLJtp~?&nLTr%j9$p+p2+4K<_R8HYGPF% zd2$r}PH^?cPg7y@No5cBDIIT60higif8)en;`((-?QLy|CXhr8RQEjGQW_wfa%cqoJU#z5kc!T!?K|fS7Z-WW3jspOUvEp@ zXiA)yx?v{824VoYVV}!TjJb35{`*yG{M`y_aWp8~XgKZkQ^k2=M`6Y}8790FWU>|u zKuAAN_SE85bk6Cb5Xg*|y)Sa0o*alKC=@fPy4Tmk!r(Gg|Ge;T_u&#inV# zBE>R+GomrhdI(0lfx&H0irTjJ{r|AZ42eN7aPu z!y{JdRWn7sq^D@;E3lH?e($g~z^?*`lw~z;N|_do^|>nki7hV z?K*GOI+`JUcvOgZvT%!27f3iv|0Gv#HJVFv+G$oArDQ5*SHLSYvxHVTnzs2GN?4le zeBr{!T3K&^PG(GOOpp(dWKUR<}SY6C>$2NC~y`3c6)G z@aw6v{}nEhiIs<{pbIY~H@5>@CR~l%KI75#&RwVI1QDI(xnC>py`wPxI#?wI>@DA9 zQ9NfHW5#mo( z$M;XX8N4C(v)YvQlGDXl2EpC2IiK znFb!Dl8IJBi8A9u(_P=5iF_AAp@^U0n}XJ^4h(j2-B39zX^rdFm~fcfw3Omn`LaHuh8xQ~P9qlv2w<^)(RwGOHs8yp zxyo-0fBqqdr6GDY0i2wUM2mOr5%fj5F!t?n3IJWUEbTgBxu$M|iaN+W{NMaSM zXyscHfWlrzVxb(|?dqCQ)udp@?K|E(o0j7c)j2xdt%u`1Js9Ao4!Vn7Sh^?UUju6z zng}V8ll=ENFyhv;PYtuN214`gv9NtF+D(&AeKJWlJ-@#ne;gIuMz4uiFJ#CA*Bj1j z(D8IMpmRbg8UWM3GHqlM>|6sy6zISSnqGH6?sJthX-8j2_=ujj` zf@}YNb)MAouGL|vqKecG49{#UcHKP5^o<@WK=E^n7@BFqsX;Vp#mYJWYqTD39{$X$ zLQG^daOg7`;t|@}j^_GMW@?)>x>BOh(v_xGZ#7CKPZ2e4OsTPFugW;eT(>W-Vd!Z6 z)pc=NZMl?x78sZf1EBJtMe;8re94B@qYafe&YdjNNS420^WnD0*y-r&8H*FP?Ln8g z5UEAgfFBC#KhSs(mkI1_b5tF!=!Sn>vf(C=;iIBxuX+a3IZ%+x+Euz~rxvc<1#K^u zm2|ZxLI+H5n-Y&nZsV?q3`cy9E1dsBQ?AUO!~Cw3))ygfBX$bK8j0HQNsZ^}-C$K` zU*B5_DF?c_OU)q&m#v7W!K7-_i1%;+ zLJBG_$Zy!ZU?=eY4A^n+Vq*UAq@TQ+G7Rd4V8=7Bive6zr9?`3fCT=aOFkZ0A7V@* zTmkv-5nQiqi6(BUI|ZkY!A*lThu(>vXnx=zjV@VogVk*ZD#2ILDD*M@U=4fZNH&)( zdk$}e{iEO=;wRRm@Y<>>*zQOpFCZ==ehWf_A}5t;k?M8igx$gdW>arRDktN<5of|X zNRw1{D5t){vbt5sAc0+*ZhOJNGn82(!bZ`M z@@Dk@(<{viE-R^gfD9TN^6=ppibfOilW{6$FooVfr=kLN?328gN6uFS)`I_Ry1!j< zab`?lXsL|k^SaMh7?KV6s;|7OaJ2u-%RO7xRu=g^{}IvrU127Fa(?{m`wcFRCkXd$ zZ)~yhxxrF4ycg=Ohp1t6bbjeyHQ`Tz_ftL?0n7QG$Uh~_{mKxCC$I_?mFsT<`f=5T zkFL*Egkjtpf)K-R2bTOG`_{eh@1T3+ec-R^fw$+WE0KE@bCk-E><0vOPdo-vE(v-vKCI=F1nIRWIxaz+S z!OK72g3ktSbO?69vaOT;fyWVVu`?`{Y)(A|q{}Hje3HBNa*XC+u z(`2xa%|d&lNvF%6409SUw53SpP+Ry9#Xr@a0w8+Bj!&X0J=^H5JaJ87opNNecjX6! zG6US>ROPWcE%u zC)n41;ci6Cnla!?ZO_$S9`b4&kU*4rYgxnttJ(7U$uN z9}F(tDyJ;3&F>$FA#Li&8Ox;0B8tdbf=5i%oc)&C0AfBO7}!FHUA?j-^F*?7IR5Y? zY=f9Ysh(NE=3&n8wiYvYzYRqz3JEyLjVLY^w<`lP%XJTxA~S!`mx%d?Y=)vWI`g7d zhC;g>6#-vEB&1^yM5lM;v_^E0Qh0+AYI6S=!F@fMaj|V4bDnMP=afSCp>!2UcVOCH z%iCejg$yed1XWP+dSnKn@CONlw@$g*l?i7K7R2h2Sw1SCqMb(%d*aA>OBvqRR`eqn zgFUk$+N{uwEroom-KS;wsn7nl2F;&N*b77_9Qj-1X)SLXC^2y$6`1H zUHTxXC%5?0d2vZO-6MiD@2Cj!IXrER!QZt#cpVM4va$%MJAfX|@7UV=2sByIFSy^i z1ZR_^ZA((`Gc%vNc}Gk$kXG(V^#Um& zc97^%JogB9#NJSA|D%eQ`G%pR-$ZnpB~dmTKT3|0ElHiwC##eHG&mzr`{g1?fO{c3 z&=|*}3h&rtQV!YFeuDbW>MzGJj%;{e8O^>Fk=yKy6tVdeBwG@6bDL(RbRgLE(&SFo zeL1a4YgzEwKWB<9mZEyTX-(DooT4rZ|Wuen@6X?+FakEKI zWy-Kc7S3s0uIqOTp545?9vQl)p;JO-Ai-x+b6A2~szSSl25*~s06XUT_CpPKeMG|f z=qS1i|E?AoW*Dsk+G#$Yk+p%#>^^vbEj!?S|JH`e?w%w5pHZis@rI4t;e~|c`EV#! zY9$7j?sMu`>t}s#;i!0yw4|PBJ)~|Eym)7s{&&V%e$nyWR&DyOmy!+Yve@XCuM+UN zuYgdMScAY`J1zhCfUv1Z2ssh+9b{%e2}-^PL1Ez`_f76KA$n>olub|_WrDg|YEFG# zkUtL_-XEGjO-a$mN{)upT$z0kh|kQ*}QV%j{5Gzczqy9hc>U}v3JlZ1f)L0hG z)FSl0%26Yu-!&mWCChD$qQ{2;X(S=c#kb*6P;xW5S zM|J{T0<2qVNoBf0jOkm(UF|UkT``u~ti|;QtnBp-3+!JKv1Q?3 zA|ZjsxyOB~wZ{d>tY)VxvT$W}Qr!&soQS(Qj2CbtN_gmpGhSGCy6jfWD{{c6IKpH5k&RtkLJ{$1FKjG5KcbYU&&N3-U zIP5!Ma$s1j#$mhCp~_ddxx_@dpp(!be_I`)JD;!yesbYQy;8#J{*1FU+#?042!I_h z_xN7-wAC%r+jafhzZHBDF&!Onl2sK|l^*1X3N>Z+a zZ}9`OhAr(%#(9U4FQ0h;^#Dna3_^L9Vhx9)SWkfBu|inBsa;S!Ld?~jH4LHiReJM|AgmdB9ZviHP&j@IOx{UwH#6x5HSuW zU^_*7l9yaFT6SQa4cfVfNFx3G1g-;fLX7~!&M8PhC%LLDVss9HsEgJtw>p}2a>baO zx}M;~cxeqt=1(s@mF(IDOWUT6D?oNCyz+_h#vb@F`s?wv>A*X$z_ZZ?i|&*0NEMy| zYkDwtsH>T~zH|z^&RR*P>x_dL-W|w9tutqESJZSl&-?n5wYJRpwJH@=!h*z;6%%;6 znWw0_B3v!4R$O+!ga(l~==0aZ3~!E`M&)yGS)DUkrD{^hU{kvSc%fiDZlehZUe@Vv zvTXBTCwdlJJ0b)TGOYw>ZKaHe$fxr;UQu{i6b#13UX~ks{mTraAoOGC)nPVq5QA>_ z^440M@aAgyA<{(t>+`@`huHSCvRgFAo$cxG*-zC%n9y^09K{@X!(Ovn2u?IGMtnVeHkSu(3*3X3$67P_iCcl*QjUN~G#b-5W0<|yT|CUX-D2YzW-u`&0xNJT zD7}O1k}VX5&X6?i5abv%4O$Gp<%E7NhS}z~Fmf;*O_vUX3uj@!cD>EY$MXHnBMAhOgvpOw5UmTTj5QCI7k=Lo zz&xa_2B5-FLe$qFjBA+jyOZ;XAOlJ>8UJg> z`=ww~wAd95ABMDMz!_0FL9j5m^K(g#jT0Gm%t~z7;BAxeGi&?+4#1t(c&0b3wp3^( zkN^4^%C|)Wc7g_$;-qDMr{!+k!%-6|oEpwhpyw15;4*kb!D6o3+dCbt44BZk7MhWg zd%(0DvF}Al4w!`Y%?M;b!T+~@wK~t#B6JtkhdRUv8=2)~6{__|3>AMW;Tm1tkUe4)d;0Pg@fp3x9Z~xeZHNb2Z z^*Zld7uqVy=P5W=SlCnL8UEPd==oMDq?dnvCFw2gI3au{{#6T1Dw&d^e?+l!AhZ#Bqg@#=oyk`&H~;h2la0K!WpNjc`q3Q=plTISlo;Z z!9=)tb?0WYRVGT^RoeM`x1T+qDSsEI=PvE?tK{PRmmR3#FIZ|{r+>s*PXz)x{3p(D zhfFb9Tqt1Khd1BdD+)u#%LfF7UDaIxv<0+BJXL|=srwvYuNc!hVeK1}OvAIwpHcC0 zmtvVE{@(`|JP7H;YY7b)C*eHx;cm#^}S*nx6Q)%`a&d z?j`yz$NsEK>g!h}n4k%2Un^4knti*anuLoFaHlj9+%N0066wN!X5kTc7eUPjS=-{GJ^{^%0ggDOls0|$N# z72TN5%MU>q8o+$)F<VEam-m&&v@XOHva1Dh2R5lV$?xj3fE1#1F~mACZd8FjB}@wDY3j z9;~n>et@4XR42*b0R8#`-!BBNVkZ+j$m_hemSEzzQm~?srap*kPPv?yL1Bg~olb)x z%KljSQoTt=h$SBWlAOdjL41GB{%ib%gB{}Vz$~5<|29IfRy(_(iOo>#aV zb+{Z(HnH}RS||3)m!}vW6NxL#c4~`yPL*pr#$1b0Z}mhg{}`C-e)+}y=6!i|Ul_@^ zzV|Ulx%@iMfXedaAkkaYzh|8FJg3_r4zzno@ib9K6g`AbHy+`vEj9R)2XPIpO61f_ zf9J4sDL60Wm_T;tnM7iG8s;RQmul$$37~UhjwVGPKQJ;MuM8#wtzT&eNX?PCk`oMO zYl9o_s})ulrFU>FKgvZ)jnK3$N|WaIb5&|+I{90f5ydjZM*yLK1zLHn z;jQ8r4sfqkrpC*_NeG5c#dN&sY$gAW_ryd`(Ah8^PEha-*l{zy6TdUaZPVqqPz1Uw zxyVJptOn7}pd-aihU{j?N$A~hJ16GaokKV@@hTY1R7MAZhqQ`_4M15OUaTp2kf+xjO~#lKqIl{Gg{5MQ%D2HxGNsN0=KBS3d%J+)Xa zOuc(<15K5EuK~?E+$iC0S_%EMns_df`?^JzzE#)7zwKaU&)x8a&=Vbg)SBCC&2{QM zK+7Rw-IEUCj1~>4!j{NTklJ1s!$cbDmLCQ&7~bRe+t zoax4=3c8xBc9Y&O#uOuR`N4#SCBukwe1zXdgqY(opW}aILJ&QE669J#nYnGPTTIl= zurK!R^1n+npB*iF3f&M#J{2sdt>iMmsj;luV=NIA99a|q zjgJvdP~zaQve6#^tD>Klk$6zAa$kFl%rU@bjlezG^0X0y(A%8`Yhjy(e{k%gJF-2o zDxwAxxF%rV=;*AfxL`^K-!ZFN%@_(+H=k zwPn`D#rf_SBq-?ng$O}d`AnxuLO31~dOCQ$mkTl-J5%fSj|?0=6_ zgmOR`7d0=-h#a=%UjtvjToy!td`rCc)_Z0iI64}jDY*)0d*2wzAK&BFkyup-gT_|6N3Jvm{6Skc+UMffIClSzQ#cI-=%~ z$)9hWxW^v%H+;&eo^23k$VYZc-!2695rPCvV2WbAr#S;Y(1M zS%Uz@KU_=AF2RNFHLI8mRdy3t8TjtGf)xwPai1Nw#einI#r@dFa>s$x{<_9R@;bl8 z^0BtmD;(`sWvPkryD7rA9^0!>M1u+W8tNXJcG5l<9BHGTd_v}5@Y7?WBExP_+8eeV z0nXh9PgE{MMcf@>)a|ihSzMJ(LY901odPrJn5aUEIS^i)~Fm^ai02p!Y2+khFbW%I3u-rZJ6?fIO}CcILMY z&nn4o&l>)ei~N?y3nR1AGLZkt>od1Zys%j(2l)f~ny@*jfT@Dji5$8`Knt-;o-V7u zXkk1%Vl%1U#Jq;<13CR9v>bC~wCZ`D=2*ja?PgYx@0vys!#gQYmvO>K)O#MxoPAw7upbXC3|GX`kDLq z<;z({>>g!7hTKV@icZ7S=-)u>6NjnVX5QN*{Q8`i(rXbp5ELa&%zT)-Yt4~3Kw1zN z?~n~J+s_vfE9l-rI2v)?uX^xqnuZ-zTJZsDgy@Vl=Iy8l2SA?&j1nPrghpkOK!JLN z+eCXRTwMtwi6!Dnlo9Fn%K=rRgOVFH%4n=>)Dp9FgsL|znH@AP z6PMrVenO+@;?jvsNjAUQSE)gk3mV7yu8By$verruDvn`R*sIX{aBha?dD zzTpTkXn|}7mTNSSXut$r!(+H-e|Yv^tF2Qo=d2qHMzM%3i1| zIR{V|^`ktd=&5KTUWwz;TaK&PezV2=)?2xTqjMd&QdZg4*68tWY=lt)mX;&wUEX)g zZ6)xBfMd`+zKgU9k7|bWzU`4p1@g?dnzc=Jq=1n=e@#3a(XOLx-sl5NK#WME#{4S* zA@~;fx_3niA~LC|u$V0vXg{e-5z9qb>M(EMAnUc}d)k!&|HU+ebrSPHxsX3#Qe+7MWJv6->t)?-@}f}$s;OC8;E za3iYee%qO zV2epERB{ZuD6;NZgXN@*_}kc5uyN$bGEMJ<#<6P#@utdCEDRG>3M-*SPpgX)De2Et zMrZBPSd6m=i-{1^)G7ZrrIC|53T5MLvSJC@KzQnRMjjzs+mQ;l0rf#mOf`Y_gJ$T1 z1tSDy6qKs1xA4Vu6Z)G3{A zfv(5_xfuTwTDUSiv>tM#*j-RhmwJ8#l&8l9|D*1?J1re zvzK{%H)6g%A$2#v3<<>>LWiygERGLzyHRU@jg)k_(b`KVGEQl0UDiTtR1ho19s2P` zSGcV#)i!am=R<{z?f+^hVaV}vk29?_m2nv>WQD~M5_M_B?{NWlS3!9c3Zs<{yg~A( ziaL-#@i6M@^sJ&IvDJH3@_<24@Sp#p14T4is>Zw=&k3c!(ZwjA^4`jhj~1b^KV8O? zq`Dc%s2Zm@ z^0J|aRG}%c4Hj!8z|~5Pe%*Qt5@PG!w?3n=coOvqM%Fn+rLam17<6PX9dSQ&IVy+B z7Xz^aF_b{u+(bLh#*|UoKrFc0%a4f%JeCWPD0<4)ULLYM*gz5=L@v$CVHei-{CgR! z&@8pqjKUo6iGyo1ArOktmQF!$RGKhG@m&{M_?WqI8$Xo=oB|@0)E}r3mA3Nk*FKcc zIS{rg(KDcPfW+HHJA)%U`&n|oZ=#;vE{Q}_%R9M-0ndpSnu;YziqrNW*immM(dKX4 z&VlK!!1NIr+!7s)$7eh+^=jy$>Y8XnA`!=d!q$A)3*)LzqMhU4I?%I!xWdnrn=*Nm z5La>Akk!(EeNMG56!@&^F)i5whu?lac~VSQ zGOHwTO6{DK8imy+j$FC$*5CJ$^`2cGaXdbu>j@8I)I^e0`b~69Qi;0{n+lebF~6_$ z-GQZM%gEJ|AU}yhR8<^~7C@d=W)gF*sUtTU8u5XfZ-Katva9x!)VQ4A3J++9MDFod zO~1*Dp2=xzP^GL80g5GLc%xF~+*=76zPZ0B5b2p=ULDXayt)rsV#Mnz#XjAn(>M?p zJrRQbu{TDWZc*cb5t#@6gH-g@(-_$k(b~*%nDXmLBQn(}cYJNIQP&AH+Y)vdBTw)R z&+Ch+jap%$VWlT+G0-h8(9b{+1-oIc9gd!JhY153&CupjB2?5+3Nk~q!wbX9k23>W+V4EvkO|kM-(<8pkCBdsN5w)`5xysKOSHe(p1>yPfip)&;pg{| z|0#H1-vX;`F7?Cl(?(MLyK8SS3PJOFi&npvv$0}6mXxQYgO!^q+aMtE;$~-Ry_d{O z&m-9Z(_feGX;)$4vZ=Y9Zdmj2-^C*m3{I_88cM36s0RIeQZfXQE#ZQ_g4j-n0TxOg zI&~cZv`zz{R$X;d*wH!^P!|@|M}fQklHSpU3*{8>Y1?oj^xdYc+4q^$)w{1-;B#YK(QNo|2?#;e8z9IX*0$}mM+0QVo zh4i6Db6IZ+?YNTLM8R*!flo?qIC0G1{YZ&6(qz+&HViAg^G5wk?_s%kY-7CSaA@hu zQQBi_Q`7oVsfrT&4q z&*gwDwF95}st`k<;b_M0AZm)e-Lsrq-zOe^Yj1=EvhG)f@YMVecGjj$PvCW|Gv}2C zKSkI5Ki7Q{^)-Mb+UR`i(=O0HIZs7{{#nEeF4FKl0J6F9x$d>ycq)7 zQUT;@$0~a>4q=D7DV!v$%l?%__|UQbQ1<>mhlIe}gy4=>jz4duOskU?flL(|1<~Vp zmEnRV&@VANY^qJ4;ZI(4-(Quh`Ndx0Tpd9L-ED)RMSm^u`o+S(2co8sAG8Mu0T0gk zcNYY?e*r`o79VfeC9?%ShO(4ls!()9MmSP~=-5l3?5VqF##CXt%2Gn_>6HjB{D2E4 zz!dGQknM!X1Ok=-Q*>9Ck6Zl5i-o&61OA)hR0 zH+Mu-`+WLr*^_t`5jxfc^YRN*#8oPfhwW5q_t-bYwEraR)91j&lyQFAKi3IeMEEBuCu^L>TOIdvy^9Fk{v_b@j(#r#@0?WA@{JLB zqGrzNZOnGE?5IImeU$F*p?E6Y3D@MTenO#a=vN47wXjNfC}z9hcr%CCSEXEGS6J;w z;8W2z0#(w!hL}I{P|l$y>}xfAF3W5FTW{^&FPzSlusa!~0$Pe}xl6@AqgDh1*LB;- z{O){0jg5FY75qUoKpGc2s=@DV9Wbo#-cqV7JCJ+L6cD-(p22-mvBM-$Kel0x(v)>a zP;)iZN4tGfn^V6i#zcg?a?76?fbr$Cz505O?t1EI(8gVh<~8=^Y&ZuzcQ3t1fy^Y9 zL1;Y}3aKfe>x18ff>Z}@=wo+O*5e1x1j?1o3E=jn2*Oa%3-3LJb1y~awg4lvZ{;Gz zQG~9^iV03;g^j$1WQ;*?X8YoHocRrMwfoDO>Eb+aoG9F_9(U}E#KOu5wshdEq({D( zRz-ewK2eCvfUz{RA(5i8YxPsHtS=Od*bF7PG_w)BYXgws>W5U4*LOnCh0h?O3(m~3 z{1x5vZ65ZX2_vS4eX1S+Gq#yk z4&?8rTe)Cy*lOf7?%v48l~CqN0KGW9?V=;WUg1%+yHhX~S(F%71FlYaf|YO^kWTt6 zc^%0@U;1^d_s&u?|A$%9fW3EE3-gHqkG8iP$$)jOcB~gF5Ywx}WaE1p>4=zL+yI&b z8<|RDAxT67A+Zr{Y;9{>bwdxV%LcAgG82`$TPilaULP~n@`}6L*QQsM9^VnuvpVBe z<-4-Ry{H0L{KSO><#Pdfol$wm9L{7g~Yfa1d^9IJI#z=?|fy9FOmOAaLm z;!ZMrm(TTq-_A8qZ)VpS6G?p9^ig?(kx)#k*WQ8J z|MmKKnhSpM0G-f?l&sgG(-?7N-x{{iE&Kc5l{zFKS;u7djeLWP@VYQ{v{yvz(9VIK zsMyRQ>81ORIo0UxoDaEE7aiBRLxUjwsr4WFxAlTzrhQfDN(^Yiq401ojE?2>uDeB) zB|FJSd=7_H5@|vSE6)mpW}&g>HX7T7bMY$1kV@2Me5@yI>wksXKasx z^EU<|{@vEDI%*#yd>tS{+-4;hcUAw6#t7+2%%bp$0--;4!6w;v;!xSfgve=kVS%FzUVxh7<4293 z^1FJ!hc~bD)bGY%H$~jcK`$uhL$%Qd%6-HSBf|rgp$|I-IAV%4qsnJpe4ybzM%Dng z_b}3A4-q^4Mq+9Rt4Qe6#@jsvK>{??C><0<;Ae#8t2vj%*IISI!zVW{_+HssZC!N; zXfFE#xC_#6Pm<$xoji!0^p~HK&|uob{y$K9=0hbEGI@Ikb-b+UEd?&A26$II*25u0O^#uZiUcj2{ciyRahp`8I$+ZWBx+ZK)|GYRN}c zu_lK}aunB%^zt?Lc>DW~Iy-xT9?L>ySp(&s!Q?FWes>Z%i-J;H>#Qm7W4}RIS|{*m z#^Ud7e4K8|7zmc1{~xX^`&5H6;Y2vFd33C_~?mlBa+gHnbM366(%IU2LuReu|t8V9`Tkh zuD*-OPetMG-ib+In{H3PW;EoBm3^Ngr7p(9X%0C4lsAqr1eUh`GhUYIyGMJGQ9wsm zkmU6em+AwDAcy5ord^Dn`F{eN&J(B#+@cwOyRM-;yunVyK$B{6V~uOiqtHhag2-a2 zZVe+^^^UCYXD1$lYuzh0F9aI^Ujpg8p9P0q@06ok*EdMMJn3$Z#Bctg$FAfm`GW@l zg1%|+0004pD$*c0UvWShKlJ6&)yC$1;GXhq4g6bkWc1#* z$ZRadO`Zkcqp9$IK9>~Z5wR0>UI$pCW^4MnUaYNFlcYVJ`_q^l15W43#zUgGnTc3Q zKgx7YT-QS{on7=Xxa8)M3LJ5ey--R(Ug}bbhzKj#?P3DJk~rgbmO8n&x{~0Lvvw`Y z+42da!Ma+C=I4g%N6?>X>z0QQ79d5es6i!{5icmgAB7FQ*34&XXsDrJnQ}L>&GM* z8i>GhK#9Un9BT9}yP$F)CnrNB`MTF?;F+IF{=f5lo+PSXN~SF7vG!IjMxgi>S`$pT z2n@sTMyWw$Pfz~~uJNL=q*j<4n9rOQO@z`b*`J%18|el?&m36n3C0Rr zNh+oLy1$?cYoV9dDJ-q;4A@uG>Z`fuU2LcI7u)#Z;!j$}QaPO9cG55DtdgT?I zhlgKe>Gq^or*+wIc8DH@ zPdN0Kw)mmg`X|1t;|E96*>!v5XnbA5NaRjwUQ!6_) z6FjJj9DHEd@7M+RUNdl9;4cHLFq_ONVMbQ}XBJTFXVa zRbvVxi^g5Q_`z1q<&zYdN_arFe$ZPY8dxa@FJqJJFtnRe)FN;*@@_S_&F@p`2vMqC z9Ug=;0IDNHgonua5SmmU$E~Dm&T{;LKaw0s3Q|%Ag)#yXHwq;?I|UgXF!}ZrwJO@J zj6O)|4Kk+Sy-QRDI!R@&eQI&vJbl9jAGO90Os7#}e-v#1Kp4jz9_MG(d6ED^D~Ge1drf}b4SgIe0!grpF8OHQg2LL4@G zC;Z%>{xaxM42{LWLb21bdP!srW8bIg-GySNVSdEa=<23$W_qy!o>#)3|&BhKeHv46Fkgs8I_hp<|&tfzsa1# z06##$zh`1ih~b1uH~+z{y4WuN@23BH^&o!pi%@Ha_6g6$`DbLjayXD8)*&1ferrMh z$;b;=iXDrdMJ)5zoA)$oz$!BlOWF!^WbH<*RyIdV`!`zJKu`8~Qf)6Xr{K)nlGCGl zssNL(eaR9}L7C_x?F>mSQ!pvKinyz!Jrve_Mkh%QYA%yCb}KIMtRMFo?hT#6>z8=XCPhBw?xw*-+y^Z3LC8NsT+N01SPM#o(M87bykE*Q0%)Y5FD0 z>r-$?&$LYeYDO4_t?|$#phBz2DNLnq%yyy)S;%5}mhQNA!x~`Iedv`K$%bl|U z3ol(FrSy5zc(cpqVmJoFOBspN#Q~giexR@O)BN*750iKB$hg2m!Bdb3=FSdRf53nE z)vI!{_TL4gQIw2Pz<*EA`EVz#r+}?$$)lq362RCv(R&|^;Y^Nqix1%z%>zbo*_qK? zm&&`p|OmZy!=K->i#-EFjQ#i&j^X}#l)MCIx7s#ZtKJGP4dQ24GnMhi!@tD^LT zos2ZSITqmQpNmzqDhdU<+fl`(0E4?l zVTsuT)G??c&W#&^YXtZPGov&`jQ59C^58K2AC`ccL!scygVf~6I^4MkS)k~PUM$He zXzMNtL12(Vu)vJ)Ad%Mw>ZTgO~ zff#fR^^k-nvBoij3AF;9cHYn2(uS{eoj-5rD8ecGuOGS#MRQmp8*q4E}v&7Io(UZS=GteJRyR`YkF!FsV+w*Z zgF*y=0OKhG+SrN?yTNN4i;vUz#5COS4XilUVmvF(6Tq@?@FJxJXn%_+Qjw3?F`P-L>_7uQ0KzzXgH#L)7jAH*o!O*h>&gc-uj4nuL~>KmhbH8GgUL zB`vf(E0UF2mNH;31#OLQ0-3f{r0%K01bC#6vPZ0$Zq6op zsOqYx={i~99v-UsS$J3k9q=sFz^k#+l}KBx`27{>%MaPZ zOjhRmo{u^~v-BywmmaVv44<{voy*^rI6JpzX9Xt^K(C@Hi%j!zrHZ<><4ijdKh_sO z-`LAKO(0S-`Jzn55p|%8v&ihOUb<8XM)c(gA`~zYKE*LJt2_CW4NN&ryv?G>E|{*OAlQ^`*l73J46G{vGKaLJ2SfaE1aqx zDV5?*USBW(&mAeVpm6a`8qPDW#*m! zI=eEjClb^gO7l3BYA82P#EA(47dA8ca$Mir#OlSI?_)M(L+vqi?#TYV+iXC~6O!LT z5n6AhM6)hZcLNe4H<>3*HLnJWXYFkrtnves71oFa3wv^|$!OyFaHN0%lpH^ZY55kj z7l>LaU^lYklGc1g4vuLFrII%Wz3Bue^^G^H^5!?7MjvQo@GZ7o$iawjBbA}WG@psETZ*cuGO@~6gpK>zKX zbwut+iEhNisEF!^c&K?y7Wq>XTG{5{RpG&Vp~i7391@w&sJYoU_`xz4mhavv1gabJIzFCUEs<-2&;JH&q6Xfc z@zpbdnlI&X9@#8)u9mD-lXRj1<(R&UofH6P6DQe4YTtN5C<^Cqy;EnG*a5ulngs1I zg}1Lki{_a-ShSw9Jgt}qR0GHhEQ_|y<|5ZLC+Xx+Q2}9Eg@W_nhUvdXN@M{gK!s*W z_|oRUD^dubdD*$3dRQ}&lQj21Uhl_u&9MX|SY?cYw!VYaim=(93S0I@* z*82&F(jc)BxSmO@yFcKwOpBU>< zm6-`tB~sAYuu}lLRKxIj+&WARqU+aHIF`ZL4en8sQRt!Z@v`y;-dnmB7j^3yN`UR` zTl;$7)z9*CE6phqiohcFEmrsRvIcl`K<{+dnkJE*bp!YcS9*P)vUqtGpMBxb0p1Ad z^`_A9S>*A+KW(r^^y>(qWdcX&vc-O0q7}<;mdTqbdaGOM)SY)#!^;@XHzS}l9%!K| zlfPIhoY_3TaM_7!w79Otp{VPZhk#gZR(KXuugywcZeCzBR1^1Kz_fCDqnSl78FJoFh{?#|4fiW`nQ<7g zCZ?TveUz2FvH!|KcId0Rt8IheLttZoi@q*c7n=Y1q5-%C;U+oUQeL*Num?u;a*GlI z0{_E%NEddi$bTG~9FJ%$ z0S#6{=$#r>z`!V!fnN02qL*Arf5F{i>21`HXF zlQk-XqRi+ACvvwb3NG9T?fZ$;IN1O^Wj~9zw)%1E&zI?AA9*W4krW!!+F}v@XbyPB zB`2aScGt~d&R7(RdcBBK+`BF-8q4b7U3~&=@=D!iVC^OOa)U@rZnvHJh;*S z5J>q^^uRs>#j=nDo2j$0s*71D?6D9|xm> zzEA^Y z7o%kx**%D-QN5^=>>5|QL@WA6;59~tx)WL2WkIA!!$*kwp%Y@{YWDE%CDutGG{?x| z!J#2&R}DPnn3&aa(Gs1HuY%iaG&sSycCD-f=R1juSYve2n2En>Z5ng}aH?n&U* zEM_2JofffxMw6_LN_1WeozNG8FYuEiaS?+9)KT=8GQXx%ZWDMDNu9;lcuB-C^(`xk z41*ry$Z}KMW9Rk8!+&6{p_iKvLV&;cingu!2o4%Kh~t7Opv^sI3C_L9w~Z;C{zPn{ zI6C6{GR!MX=_qvdj-72&igroAiSjVn%HGbh2b8-;Ch0l-b0okFZfex{#rwzf`uJaJ zRx4_fa$9u`z-A(&t|V`AkH7MmZ7?^aR=Rg{160mJxGrJTuxmxQOv@6GD`Ant@5bE$ zBhcFAk4kV#%)w{WRh-gW-|uLZaEP_+zBvXB43hMsDnqGkmtji)SzS%9Q{R@Em#`5l zkEy~XcXcgVF7tEWZf7tht}uZ*?0LAvo8WBb;Z?2ZycU9z8h&2X)xd&^R+_E7r}c*T zC`fMVo)i1-;zZ$Y^Wo6N5K_Stsav@qI#OPZ%4G@`kq|d~z1=KK=7~??2Ult<<3 zCi5T6b&7^`8n>N!COLH6E83d>@7RCkqc6N#5(AKVD0l=jvUCJ+t>RR8<%SOcMPK2r zPOj5@mBr9Xqb>(+~2qeSuED zJDt^}#ujL9ZNQMssJ@$^6QFz??fzG9b0N5@bKiA%LrTaFz2C$Z9{O;f=Y9`algKPZ z0gtn*pN%U*(<(?}y^(-|zdOthGu#BvzIY2T6%j<8YX&mA1H5?FqVdv|^_W!oF*ljR zscR%ZmoU20*R8}9=_mB4>1j9c_yBTNTuS+~aD*m%ZR7U=2}zXfC zt#{)<&MMs{&LPerZe`3S%}=GOC|+|3?%G<|45|qi-|qmlSSkyA_hYCxrOkFGh*Nag zbQ9)qKjG}4;n&6hk{uIh3|h@bM8wg7*8A882|!+0AdMgKKZ2#R3RJTvHY#obklm7J z?#z@NG{ZUg!{$`G?$=gbUr=<3Fkk< zhq|qc$*zLN;dML5^$^0DMNGO`oR?&U;xE^h7y9$|-{UvIz)f#WK~MCk?gj`2HV)FD z!PvZLqO>mbj05Sdt}74&WJ!q?E=IH({QO_?6ArLY4A0Cca#QXfN8-BEfhqQ_>q8QOisG)$iBJ``ISkhJ;xgdZlrheJ)U@A#4)zRU18CZqCL*g=LK;SfE z^llj=(Ic@T^wyCPz~(5W_LNmdCEhg8W~U3>2%0{67Od(qAKQ*UsOtV6M%5U&jDXv@ z0Mt%Hp61d5Yo6{5$DR+bT*0kg2z-EN3VH=)41BQGqP{w^x{91>RF)|VRGLJc!H$DA zr1_Ed686G74hL{kgT!>I&{fr;D;L~^deQs+s<=TmMVrAm+cd)Mab?$h&igDzWQc3e zcNh1Sa2b@TJ`?3B3Ukw7LmWC<A z??Jgpqn7PlE}ircbpFMv_pHZlvZHOPXJC@d%3xps5#BFIHcl6n+^FJ`q-8rdVh4IFd(=w6pVOr7r^MlJc4>D z!GLJw?cfz`65GS-k>>-Ye{+LeadJf1vJVia01_bxFmeP3HCY%tdtH%^yH)6Z0F-4T z-#j)RMxm0HpGaR*p&VskM(Nhj%L|{Qs>D!rWxv>1wSh|g$wLoxTXe}LYN#M2NMV(0 zn2W}e(QXbdy?R1B{t9^pbAPCai^0$a+gg98NBbF^ZE8|E+&H-_MGR6vWDQhLsi0kH>SysM%e%jmR;vM(q)KceppSO`bodwkYW%v5bHFv3+ z+AV1v$m~;6jJsZ|{`fbU*JV2o3vAY4zIa^vD&P$r_xZPk;4nA;#20EItL-1iJ=;)6dWnR@{` z_dxO1N_CD|%N-PjhOjN%*jGlY4i;L+<8pNd?R%&!2blIPL)<8W`88V)Cj-|skP-Ihqocm>6ifbTqS&tXkM0t6@@f>q%`Qe&nxgK?)p{ z6FoHC`@Kzc&WQr^h9ys_|C-^-XS&;Tq!y0dvc=k4ki1z$v@yS-j!VGakGt-e>**rl z(r*IE@F2eUCwneuXjtG^N_?gFv-Hpi%4^@%3_*7QAC@uvsig!vqY;<4szv~vtYWaa zv?m?`ypmJ%;^YIqO52XySIYz6ZNaQ#sjIOsCWhS0rIN&$NEk5;mjpYfMBw7uRH)jySa;^ zX`v6)2@cwTwrQb4VFL&+BQq<2ZxQQdnB+eRm&)+v14$-=TRQHmgO3!>dO~-?pQm=# z+@^GsJqOj7p-&7g_wz1!B7m1oaWf>cCd_jV+bo+40W>Mw)DPcv2Q$d6&p2=wsSb3h zbd(JTK{7DMQv!^htQxUW=GmAp{$j>Ki%7iV1_|$>dy@S_{(l8U_jNe!&m(s*q^aJk zt&7g?dWkRK2c_iK$Z)iTV@82yCQ)G`!@lAu2AOiINFaq-Qhy1HP(+lFonPx6OPpTA4Y&FH*)mMe6Ij9s2D9?RH|4jCP2afV z&<%aq5r>?ma$q#B$+ zPYV(@%J(oG=4h-@m|%tJO)uN9Ykb{nHbmtd7I&g>Y|cEnl6Zk8abtF%NY5d+ME0Kj z@qIziP|@RyK!$ewB``XaL;WUi5tMrHohN2HjsGi^IRJ91WmpydgZ(^0tY3y8~9Qd1ao_!!pG02 zb=p#X6|KPM4<;@>o7S2B5uFk**;yZMucF|vA7kgeBcQ5v#Wjb59Zc&ZZmvp~vl63Z zC*Blr1eI6CW@nE%N&)80;XKSi5wNt%f&w?cch|Z$B;hFeB-67p>kp4K5+D_o32RUa zJs-ccRJ~HsJf`?5UaB~0sAzI-UIl)ZjtYueYA0mRV1^Q5Lt?8h`Ft&a1ld$p^SijhJkg=g=3e71TUtQ|!=-mQvr(K_J|{6j zPExiLbTNJ20MK#Lj#-kD`OE}94cwd+&Cxf&IUDf>rs1_*>t@2E6|8EYq>nv56IUFX z{Tj=uXHX1}a!5p))N2>MZ9s?ajAv!S)CUhr4Hr@~b8{{wyWF{Z>PDVFTK_3vX=jgp z2lEhma+Dh+6YnK?z%--hl|TW~9FygAPxo$Twpx3ub9}(20V+OZT{|WG3$TuTsQ;bx2MoJNrQ%vruJ50XGTdp+d96#dX-4%?Y{R zNDJ>NNiWMz75LS$oAF?IkC43Uh~UiR<|3^fZqbC${K~~^EI?O>?mcahv@@v})vBPM zEt*v!hKSQb?px+sgW5p}dt1BOoQ9nhKN^c7g)c%6Iabw^+;QsH9RP8nd=$1Soq;0@uknaFZZ$PsvSJP?$cIS$qc_CATd|P;=WtHKHkN&Td{Q zW0Sa(ckU7zv`tVqgB%l8exp_hS-d3=T{4kLAL5KLpTVRi8Ge2gD0hZ40lQ^$3WSMy z5(x6^Sdd!lvTq*g#7#1*4luG+VHkoxRchoit+2cGwL&CW5HHHymmmBmB2_;D+)*?f z`y69?Jc|iIW;C)j<-baV)W4O{fTDE^F12C48bFX@IKwjmLI+}JHfFB?^jb|0z>@gl zP4AI7-Pp^t-dm*pV{~VoPrZRn!^+m|I0G5-NK#~}nq*JVSQF7Cq7VZl9j;$$pP(MNX#PLdG`Ay@W&bkSIfa5rbUO7rmw+;`vd$$^JeE_yv ze19}J_0m`K=fAq*Rqrpajha%U3X=1k`lo5CZg4d)S^kVB5yoX5pe;DtDR)d^?@==D z9zBcpew|qLeE=Jo&~_lTRpB{cWKw1KnR6!2Z1cHj#5!2G(iPL+i7%mft7 z0&e;sylSb(2&>=J5@T*OkCS<#eB(SeJ`y92cuLGm0<2U^Gd_y`Fv6Q^M{vF!me=>t zjIhxMJyX&Cy>oN2#=xb*ji^XH(2PRkgcM6O#tx|gQY@R&1!njuf7ZZDN^goep8fP- zgZ{)zqDyBmk1XeLRmil^v;_pkm|*#Qg-UPx-m|c)gDFQPh*J0rNRbcFZTUT14pk97 zru8tX1%2^p4ii#souo}@-D-QNe`;k)vM=s)h^)vZ_l#)EHh<>K9N(mXQGazAWVSmD zu6fnFr`FE73_#UJpL3JFyO}rN>*;8`cq{%_K-}DI26fsw@ndTiLtDUL|jV-E<;^IVxo;? zXQdWL`i}GD42;OehUJ1+29m$VBJ@J7bw}>MXsfgu1e*a-<F-=sAjxCwAPZn5Q z9#~RusShmM9NC_^5$=YNxXX5HkDyuFYqa!wyAvhL+VEZ}89Cdq5bvPI;x*vIiZ8@1 ziou7o@V1i3-3un0Y9sYUNxUwVjbph^gPI3qU_2{9P1=vk&e>W))KHAnNHnp!#kdxE=#+vlPG5*_S zc8aGiP8#DMX!<*npqjr?%Bz1n@wc%J5^udg$qO}nw5Wwfpy_z6Q6N8ze`@btp88lX z$1HJ2Ob_@xigb!cX(C6oB=>s@7%J5hqZQ~J$oHlc`WmK-+Avu@v23M!8(&WaR+G8f zIWsCn_Fx7St(d{4jr@F$HoH+9i4H+Su3)2#a{?Ss9o_tT(N{Om(RHUj;bWc@qdsKq zY00%(y&s}Js#5U^M$1N&c#$%5O$*Xz)iAap!yV-lN)AY6X!sJbrg*ckMAzfm&EKeO zLEqq7U@I}IVhgth6a!-1ongylnB(P2NFJK0ta2|w^2Y&`rgSF>RJ`%M;$Ny-&R)@@ zO9T6>n(%WqMF%KZ-YD&-W~e;Md1akbkzCljUEL^z7re9@+3^s9V3*OqWM|H9izctk zUPzmPpLlCnQ={PRBBD_0vyOVjsS{-&ul2Pwg12_Hs^5fD$9tzV(0gpJJXedA|K(NL zOV^O0ve@t{LUn0|OSz-gOt^Q_XCqYhb&O+t-w)iawQXnzt?d11>LL>!A;a@8!^p zX$5%?R=M;Nuu*SO3NS-*6fFLmilwuC8U+QaWNd3&;54?j29Aw``hk7l0I`>$+3`Exb;TZ`7`3+#Jc-(mf7mR-QYW8zgsN%FYii2o zu9Nh07i)#ZZ|}#eb-EN`mj=5A^Z7*0e+FE?s-P-|_Yiz>9?I#jwQH_P>7Sl}h}jNa zUfh)@n;TvKXkSGbJR0y%JH;%%NedofV5oMC+Kgw0u2=BAjz&+*edRN^Its>zp^HAV z>5rPNS*nu~ZM8Id4-R2KHauN<`2eCwIYb7X)%UiORag$~a9%%>#+YR5aFr3&FVK2i zKa-#TcpPNYKq1skZOrZ54*yh?$!^K)|08r~_6XZ;*PY_@@MH9^z`;|8Zt_3#x8CT9z-Zrg(mRLw9WlU0kWwT^#?cW+$T`_E6Y9~+qK zt9Kz?r-Yc?-w_^<2j6^`b91OWvVLqs1PHb*$A!!har9&m%>u0VN2K#}J+IMDtQI11 z?0IR|bruu1gc1dLt~29_h)5te!2@q7gmCx%Tn_TTX@Bqg;66T_*qxOtT_-+)5#bvK z+!s?7?DITQ+O_c;R-;W@3do-kcpd-S@HLo{-tOai=2Cv3HxRbj9vTqO2M#j;FAW?V z=c7tLe544fkkO`TPNU!qClf8DXX&Bf#P!F&BB1{M2z&SrLKa%)`RV%V>mrV(E1`&~ z^A@jFwXoM@zKg-@*w%iJ6v)1$5v!H`?{z3-Dxk&V8UGbw~|z>(>-Z@jGZRKE@HyV3Y>vR!CHWn?Qz*o zG7jiRwfGVan3v#q`<+?nlim!J1EY&YMK&=eOxK!bFdsd*pEp1pRi5ErfAz(D3$*)U z9=4oEC}qEvv1(U*-Csh*{CvuH0cW5*@8fMNi85Q`uis-$%$^PR9okx2Rz|OXPdnGu zUKh?&oTLx)9j(&PqwlVL9hFGqOKo|P&H~6PEv`vcLjp+1#nCSVpY>bp)*d{3$2kh+;`8-nH zT_w*e0nYGK*hQE+G4c{siFvc#wsMiQX*XAZu!!|*71na}CqA~c zz1)7Kfr))T3}*2)v%q?RusLAdFvkHa&Ru~Qa|5CuA~nN3Z}~z5Y0{K$9L?nuecd(j zdkZK64brj8=h72QAs16T!MOZ*chc!O}I*pAW2U+L!(Q>&n2O%xqFT8JiV`!vT;EPlSd z3Xzlk8)Lw?F`clvtaUSZOE8=+^tA5QmjNa;dl+T9zR(%+3?nlas#B4bsEC@O2hXBE zQ;BvuO8*lkl~hY^J+T~j)oUrmu%YUCslY0*9X=1Yx(}C=2fN-ISoDs~Vy7?iRa2rq zXyXGDZZl@xkM=`-SYB$vzQOGvVp3o#;ubi+54dU1vnj^3co6K~&7s%B^2+rwE=MrF z6YgAAAws_MSQY8n@!AZga*V9)-zovbBl?>B+>% z%I&UWuPU$U9NSPOi08&u{uV-l!6mA*&mc22bM(MGP~^6FFs2{N7vwBXjHJ25Iarjv zOH@}~RwBQy|JzYx2qh@Wp4;EkCkJH~7izV7I)OQUe@@#AkOFvUXI9Eg{EN(`VkLs9 z>~X(ePWKm+s5XP=q_-5O)W(?5n^oj`iLn@J(o$PKFE&drxP@oyg)+MbOY-$tZ&_-r zPb1R%1|_3ghD$GL10EnLL{3oD#+5J-E`YU*Lzr-l6yE6%2U08`HtNNJyC2Fj!9OCU z)3ul=X8=RzwpgW}YFe{cCknKdSk zc748&FdG4TX8sa{I4WQy*N)vy6x@EbnplGTJ%>>3HaRh#1zzc{xauD6F;m??XT1p< zk6Di%FS7{xNepZ*j_9j4^Y9u3A7St}FFg}Uh-&9F=PX?NDXsDhFRRi(-q?po82ltv zfNy%T5~@SOBv)&KYNXvz$zil*Z3!u_sI+&`VBYGUmtKo47-0eNq{e`-UHqf*6GC=nzOfuqeEz>jJiH zOt~Jh50|;Pvn)Fr5}p=<7M_-qkmmRC-23EE1$+rZv47&Dxk5mbuk%aZU6H`GRU7al>n=@E<*9#HFMQCTzxOt|)>J^FtA}^Z7 z`2PlwmSdT-@{}wTz#N}F#@ai6XD+Rw$yvO94*NN_TccIFlMWgBX|!<)x7Ui$fEKQ; zZWu|S>%f$OSv*NkF4WuMmp;Ua)a2B_z{N^^OnmCYR)dWwHsTXBs)v%$AX6V=LT+LR zvoq*pJo*s&xI^%Uz{})!Ssci`LC+gKSPQ1KB&E)EuVb-ipYyZcZT}lfQXQEm(^)>}H zf&@CH=aI8=jhJ6{*n;}}X74jv7|?P88%M1d14uP9F#^6g$~oqeX`4ps;8SaD5cQQ> zEfHMgfEv{1N@is0xSI8End{m^K5%B2vwYQlDjXJWHN8)!3^6ma&d^g)o|EIZS4Ft| z=ZN4A=@Pgs;u*wk7e5iCqsxbyBB4gGl}n^ADq(o>=!=A+>wsd*6u3;-9~4t*tHVja zudYU+0-`6KV1G2%QbnV)$5M2psIYU)YCoyud@QkTuU{cGz!UQHOVK-_-sFTunT+Z- zDgB$ckdP+kN8JfTk)Z;Forx9#Pw9TEz&5pHZ&}N$1h&5HU?|-mOQJztLk$m;r z@@l3gq;GDnqAA#2Z>L(cp-dGA5q%dyHv#J?YmKgmewp|;fheySQhSYZPJtw_TnZ49 zEs?UiJCgrT9LWObUO)$?tPX7U&v#zGXK8>g^uTG-6gAY!lpsOH1ACzO? zyjKrMTUGC&xgc&i5rOksWAfs0f&20-v6{Eiu6zhg@=tN~h)tqGMn&1YhoT5MS=mb@ z{9dnzaV81xUe{vYJ)|I>36Y+kI7@Hy%WJ%&&who64-qmh4nXTjXfS#Nz^?E($4R8f z2vg}pL2$czk)bH6j-^AYbm@vKodc|FWKs+x*Lp%`;WZfryB36m{C5~jL9SjT;n8;h zWNR$g+w|%SL5H8zMc0|bs^aVE#3-m=@y}j4s&Ed}n%xkNp4=aWedsh1Nl|Z|gC7^5 z6-8K*$PfR@gfB(F>{dC&SQiB2m^KL`l9+*YIq>g*j?em?XwQB50 z>=-)AGTn0hq?q^USEv^wYcKQzb*3Jo^%bQY0IFk` zMf#0^&k>+-!zV_EFk~Icd>HlGs-py?F!blAX~d9}nfFDK9+=QJwM25j@zO5+pkSYP z@`de+RDi$Q%7-)n(ZyN5gTb7N<9pF+!tw3^bZ=|XNkjKH8->nzU&%t^adew9oMv~p zU;+^*E=3fYjK-V_{4w~`y!d(Hu)+Op@3Nw-ug68>MdT~wr?#06+Jy+< z7;VhpsrpLrWQa%*NG83NBA1Kg#s9kF*B@s}RRc#6W&8OwDMWs8yG_iT??{9_Ns|WZ zoPsCD6gs{lul02t{z<$bJsWxMn0>sAlpXadlqox7?P>PZo>{LatS~pmnD4CNeTWR$ zVjHXk60oMW(m#5j@7$;vy|8-F-wMK_>Vi)3Em>wgd7N3nE9Sd+K<@+^<*eS*hh z--!72|DzsFklx__l1K9(Xx;S)1c=-=1C%UyBG4yf!97?7gYU(?KNLr&piE@f#6a3h z*q2^u6ZFsm6Gb`KI&Tt<{Y`LCp;FJ5_q!$raHTCJa!yn@BrSFm=j-mFZ6FHo+kRm~ z&*P4J3$A{e7kik>vG@_t%!=0jMV`mc7oG`b^%@5QOl|0-qajRQQ@#wm$5J9~;6-_F z)}C7PBxszpu{(ut6rKTHA%Q!U&z#A)fVU_Rqc^#?OMBNQdrQHaBPM99!~g&W)^82IK3$m)Mx& z(?Oq;hSylx@d5JzgXezeOo21i{FAyq=lxMjS#9g@5PZ9HC(7?8H=%yOJAKq^uDc>! zePb{VoO_7<{>-ECfMxK!|sLt z?kli}YxCH_yg0TFp}W$(#cXw()Kajf4cHr?qHPl_Z(ZcE@c;}rL$xtRhc!~=O66Oywbjnmk^A!)+5exGYvJ0Ck`0QPc=0? z#FP-KNlBvXX0)JqpQX%0D*`;aUPWh*Y)?&c*n^(En`7`bzbKPPznq2>~XH-+3LN2l=*{r6CclGG3__ii=a@G*U zdV6(On(9)-C78%>{k`Z_#`fgE1uC{e6`nuMkBw}e&)lpYUqz<~gOY{M-cYwfDc4plsS^8envs&g5vUk50e(5Q8N9nQa>vbZ&orzP0 zrs1DfTgk>c3!!cuRWcSk`1-Y_e{-ff>bwIM1L;WghXa%hFf2oQ{swZ9sXKhZEEZJ* zoP3n3GEOk&AGM@A@gr@Zd{Z$XsShHy+vO<mROn(fO0z^{$bNdytrkGKd?(Kzq~5T*V~)mOjB$H9E* zgei3>bIikU`Gz6=vbW=Dr`Eq=nrf@x3~$5W1!M0NTA6m!89yt6yZClFb) zqlYBK%DS5oR*v_8gWPp$Pi5PIp+b}FQ^wc-Ia57^PVA9slM)hS zmH7sDE*5+dgrGd)p!R;kJ)=koGmp`Cfms%~)!#N8xN}6)YwDA_U%@ZZ-3VibTbnun znbZtqDh9aRrj_y)D(O)8lWuthpdIY=*Vu-m==F>j8Ty!;%OVS5wCI?7Z#ctPqrm~ zNfofdIE6H@eTd^zd7$P1k;FI+@4^;Q%T2gpGa2rL1MO|V07>@{4QqNZ@PTu_-Ne2J z(Bp+ps!qJK?kq?h9+0$0ndUC=&^jLK5qHJpHQX%pe0TjzS%^Hj}#|^3)V%J z;PRr7TcB`fH5{jOHU#QH^_P&Qe11-4sUMrqRL~k~6r$kDMVb>*2mPhz!~E~VQ%IW? zJngkvNl47^rK3}=yv*HIwHEN{_%S42J*)A_?1$8bq%V@ZPuk0ok-Cy6&_b-)=T8<# zMW%q7=g}&-l8ubDh96wYETV1GZgXH`t>kVhG&jdD!RChtr4@gRI-&fI_0q<(h5 zP2h*>7zGd4#J=Q|T$ZjDCQiFk{VdRaKjl3^Q{CGjq|@NMNZ71{+KMhjcHH z`o0aksh)9-+4%i|XaiQn+8e+Huzl`eQ}o#fq+Fy^G8NZ>M}>T;ha9upJ#ueT-ZWlu z{d0g4iSxiP`BliMw2O)(ttTJU)~g$e_QIW=WiRk0rk~Qp44P6E9AW8xwdm*DLEcJA z^~}o?6H4iK?7aQwxDrp&$w3v~_{r<6OA40dao?FH5cy4 z(}uTbrs1eda~DxS=SvoCgo-lubgH$P{5({=EN|i>XjAHPfpVhH&jpF^vQO||&2jD4 z1036i;6SRrFX}Xz5u#~GQ1nMmex;5td0gZG|t~*R3 zX*Kei>`$@hO>zHP?a<-om@arm5a7t0+uZ<2K#VnH)cckT8=|E3m5EjNPf=C$ZT}$% zy5iNj1j$*m5JCxtH}XP7VUIg~z3baFJYb&c<+Xy3Q|17-pIQ@q5p2Kjhd=!2!yZxQ zw2Q*w8orn8QGFuR+rRgU%8SEXY-=nPfnYB3PX)G4upKJ5V$I1!pAamX1o`FSxQBgO zxPWFISQa7Q)ehsPx_o#<0Ww`jcNu_Usp(RuZ zrMyuDAQ#;eFHz%ni?%Y<*12DGM2N`)aGm^x4^M_1l9alyea{Fpq6Uhge3Jh^IJkZdcQTzNEoDSNCpiaKw=RfK1 zZiH6Ymm?Ij`?M9*H8|482F$Lg<%nR&FnU6e?2`IUINJhF+!gQf9qCj7XoTUWXK5wG_9NWtg5 zqZV(CfL=z%=)5m~;e#5tAoYBNAKo=CoQ0q(e@yazcpq|9Z_8cKpqkNyO0P-Dk@eh{ zubL$17E9Z-=5jihKH?|kolC)ZIJK_IrK6O4qyR6Fm{MV3Sf*iS*h_zw<*du2~N=y zMV4vWl_i0}gU0R~SVq$xeH7LNC$o~%CPg)P3+>P{@C;E}0C|do;eBL-w*$KS)_!XR zxGtAN4})Xk-B$~7l66#>(}oSTdmBGmErmh?Sw8`ycU*??(IsAY0CpgQHv0AWR*+n} zseUG>JUoYo$G3kMNfm|<&Rn|f)h3`8j^gAI#tscgU*dzrw9EJhmUfutN@ zwOKry*ZO4j@CU$>4p3pX(J)IzJtaeL6jVLXxz37wWCW5RR#$~P5IT4HLg4H?nDN;p zx?ZLCBK>O+>E_VV{?7~ z24sgkbZF**aMXKEYZ;v3{BsCOYXAI9hzXSzekEF_=+k)M8^f8svAGA^fHg z@O2MGgZQjFvEQX09vp3@L9eJ-Y{u> z7}IuI?Hm?){2gJS$7@TP@WYAUm#G&WrGJ8~Bl~SxLJ}ATeH;WH|2*1J_=0kch@}PVbAJ5 z76o-BS|pw}Khz79_z^q{G7!|8B?FohJ2zehJ=az@cz<6KH#4P*Rrq^T75`49e6pmb z?*nvl*B$%evTK@mpIOmgzbhy_#hQW*UJd_fjB+iZckN{_^S~f6{2Pwgc+?^Yk#CN& z?sdb~GNUt^|6+-;3i&SMGR>~^k|UC1Z5x#-I`>2YkkftZiy{kX>wxy8AjCM+Ms-LB zX2oy2Puj3KugjOgkGarU?Y9TI;iOZi4z4#FqeTW{dj)F{ywiH~59RtVxubp4ie6fp{qZs}yF>$<==MUd6NcB{Un#TFU$Rx5^c?WoHL5kuPJ zA89JwlKS#z3=RQtptEiNAP3a>kIbL0Qz*d3QV8ks&>0|E5 ztEZ}kug0v879b26OY%RqIXvf-bc>FP(zB6C3p(S(+wGku3wM}9g=4v}=gZh5Ahsz8 z-}-^(`DE5HhS+G^qZLKKvrN9;Fs5f%*vI^>mXV$AfQ#gZCrIbH5Rv`{DNcwltA}Y2 z+mDrF4#F6$vW(vY5?%Ahun!6RRUiOrILCqZREg?_=wv+)XclODnwlJu?1DwS0bB*z9z@jvwLXNtz)M%7~Nvj(0OGjUKk1u-0^BNXya=_dF}<>^G{< zW$-t50$H{son(?#Uq-!;y&B!^n!NQ-$pdhv&~uE2E#WsZd;h%?3a$(Fy_!z{=ibqW z(n=>RResZ~6d3TPZ-314m@k}t<;Rtz|{qV24P>jN~I=zzNYpn z90ssJJ&&hev_qS+k(ASKvKxq;{JTzle51C{_(mgF4W6WnNpfLIOwQ=v#VXF~gOTom zR%YX0^pYX0hkI@rR<+C-pwLB%^3;urX7YP3DNIn~a*y}Kr%ZHtVd!TPa6y@xMpd*! zd)&_O-ox4+fyef4sPYwp#WZ4kYr{d3TylUb7i-J~;h)OfGeSs*i{F-1vv0e$jfJYw zm#lf~vB?Mp8p(iUbk$u&$)YjgLc?)LA8Mow+CXGKv_-u}_0~bRmYfq?NTF=(V@~5m ze!pY6#XHL5sI#b~QEm*BItV*440nVlm)p*!fK1bNy~|tp|3-=O2o`#HixrKDEFHpe zB=&e$ubWa=%Q&a*xA}0G%GO-z_rGq)ah(9XR1+qWN^1Wx6bx-eR;8%RkmG8C=tsf$^3niNUoT0Url(33y(46Sp|GQogA*Sbzd7s!;d-$ z9Sl2it^BDoLXjig%JDkHWysyuUzpWLGi>G{+(Vx=DS6q86Yp`o?pk&WfRM@i=6&A|B!)Pon%V_q92CN$7V=aimO zgagaks)8He|Ma8V`d4+Ry#Yki4EpvCH}VCII)#gT zj|!4PjK1^J;h|CXjg@XU>iVH+a#&#~o4sYyJ0?%W*_7Eea(ordgw7O41)Hh33^!4L z+2^08ehP*QSi_9#Bs?!QCl`6mx*kGexggL$y|pj%jF5Aj!?nGz-Da zDSJlBwrwd3iCn6UVLmp-7XhV5$mW_z4_&AjO$CLB*YWE1eLz0A6_XqX=GJ61iL+q8o5&9Re%Bv)4AGqK9GAc{GaSw$j9ST0Mw)n|a|={e&fP z8W3c5T#podlNmIyPv-;q3l@Qmv$ko^grK;M0)pnuA#`10V@Cjl{Oq^2B-1(FMugk* zSf?&+@wbQm(BD4{v#YE2wBSwUXXVJNM#qS#l|x9ESU(7UV;uGv0n%Y#seunsm`f*? zQ)(UpiWD{K_f`Xuf${Lhw=~a}(x2{3WDlc|SF99W5 zV{@_SR~H~oyXd~0l|`=(&x=0EX-u?zp+!f9drl{KT4>t1Vg6Nr-E#VT@Kfy!>8xyF zHLxb%UK*^4;&P{?+c5fS8e)I zKH2&Hc(Kv*4yVkh#dq)-XgI!ukHBV;Fi#L^1`8y4_Eb+GL2A zLw|f#@xoo{%0dHS6h6m)e_z&+R#Z+uv*xgEAy{yH$o4A3^L+I#J=iB3B(#&(7Yct3 z#>{sn`O*rOU_b@r!f5;;(1LG+TD@3nB%2+)(CDoBdB3nCrefeZZzh>f&gAE{ggSpV z=1mPDAbZ*XE{Vl)Bd3P*7Tq<--Q4t~Gco~U-qC76=;aI_VdbrsgWRd0|AWBrXYMCU7q;IhX3EiJ}lVZXVC}cLPZf5>3IFIYqT$u{)*iT5LQ^mj2e& zN^@)%M{1HBeWoc{Vg|V@JshT<37GF}x*R&1HHcA3S3Muj&XK-u*HE;Y2nC&w`m%=8 z7-C9R`jqiX1DAj((Y0=@XWCi1j`D@{$ahG)kp#rp_A&&4N?$mwsEKgGIO78Z*tZ>US@5xayuOmAcr3Vdnzb}CV zXTK6;;XORrgiXi_=-wN?-IAoXns#??4BO>t(&O-?DCwveAP!7jTcjty_>``zv95-; zAX*#E=w-Dl1{=L(xo*Df9M87JX79))H0E+VcbLeWzgtxA-;coSqZ z1`HZ5`i!w+{p$4rPCweeBpXytj01}SloI>B%G#*ZQ=0J2Z?huFS}<`Ig`Y*1x28rm z0c8YMsCZs$0TQL8)rqITXPswFsf*YksS`->Coh|&fkeXb+`&oof7o7ypC;f!G@v6C zr$o!rJlPZYpJ&do()J!WAIRy!ESa0Rw*dC$o%rg=M~qjY*DdR=gsp)TD|mZHqJTLc zRaW%>DRyNhAFo4=H)f>Je7jGoqsyI7OmMKsj=OwW(C!&5ning$~iw*rg^V#A_zQ9Uf!C0KuegKI~6 zwA>K z-0?5CUJIE|A_=3DDpKbwhh=>%SH(J(Uu#5c=I19BMw66hXu92$s{Am5mw1~1(X!W_ zr1}%#sQA-AY<(r;j?qt8kCUep+!`H^_iSzwW^Vq3O1JOoSwQq`;0>K9Xc|=@znP6I zkjVHJZb?jhGUQImtt%)+baFiJUZ4kulyO%cM733%2Wb~-H3$cT1zOD!ZP!uDAFhuj zD6>I0;6dXrXAxewrn`L|QjDbC>0?AU1YB30M+EIt8dv?s|9Jji6Rd+l$^|=J_;`K` zp?D8p|FJ0hq&EV4<<9yO2EbFULx&2yg1F7AFU@#c-@g_hW9C}J=c!+9O;pa~Z`z%r;&cY)B_u&Dk*^7TGtoBTYE5v~8 zfSTO){6M~yKMSkw)&FIO8owwGrNN)r0f=_e#z~6YiAFqJ7zz@ODMfeNiw^J3D+zV} z`AF>^ceeFw-truAl-)ll_exhdImXe8jYQBw7@M^REtkhP`62>oiG=@tqii8+8Fg+h6_73=;hMS}}OpAAn zz`(}(Y(tvn`nQ!bk48+Q&V|T%gKe+jEK$@>ejQis$7apAy9PiSl+wA6ECgMA)Mdqi zX5<(+ah*(MT+SW16j(B@;kDp77Y0ruXTIHgBg!1M_yWy~HE>u(!7SYl`1S4w4ssQ1 z`SBd#U$`155b)m0U(}~2U=WOQ**XDe9)B^QcAlX4NHn}*@~hz%$E-uv-goGkoBoPZ zdZYjF{bu({Xn*z6gS61()7iHymC!tS*azKe^+CKne1xqHvh&D0?rvpVkTRP%ZeH9w zZ;h#q*@;9?`(n<=%g3jj@*Q18WmX6njFp3(1TRJl+^C9ROn1-uN>X(!kT=PhmZjn_ zos5}QsUmBkE88}xOaSu+Fn0=Qw0|e$y&+@bp&ud6VfsmA+GFN7RIeaN^F$pJ^`48} z6P}r+0Yh{j*cu8$#-yKfs_ahzMV1~sY#Qqtj;oa%jsa*T>&!G+Kor23Nkk0g{w3an zylMo$e)+=SaZP^7O>#xFzRr6@#$IS9nQy+&(I>~#;)Jsm_cCFai5zOz?Ba@2?&Q7P z{aytY`Mc(TtHg;|#>iB7Ld*R3awtDWD)!&QeD;B z$Ph37SEtfg_voSb1;e{6UnM>!n20AS4`ST?{Wb91xl&kdp>OA5tM%eXa>FTVUNHY% zKeA9y{ExT|Src;A5o-#nDB`$Vu-`@BCMlTos*cVPR^U|_k_1%edt6)Dn z<#G??l z-(oYx9z*Sjzem3z`Redq$o;ZCD;aCoe)1SD(G{TViJ&0BvXcZ}4|T^3Y>>+4 zu6~0P#h+XIOkdBDtAHUL;!UHX^(S1@^L3pAE#gxkU@#I?{h`J%q^@rahfi4pp~1M5 zFdXF0mEipRsxJ?nDH~+AmP3YL&<*w}ZxQTw<;*RC?A3PVzLaX1+9PQB0>qxSKa>95 z_hH7FeS8UZML!z!>&PQ7$r(-bKb$Ebk}c>UYQvGdsLD;ef~^%DSySm}rI&K$6H0A$ z*fmY;N~Bxma>RF#C#v`JOR$y;9RP&!vgHY$Qm-lMRJVn723>bP<}cYKILcZ=3i>Y* zRC(UkPop^u8^xXC_P-}p)^6LWe}D&aOa|G6u`T#{a4y!o!(6JMtST7o)||Vb98M0a zDxx-8>g4rhO}M)3aQ^P%YUTuCwPQdDH>fhU4Ijy-u)nLFj_c9j!0Ty@vj$>=T%GWK zxKlW@zxpc_*q#g`YuXL3&xXJtSf{s!0w{mj?q~>n0Vip9DSBxY04S`RlzG5<8GSF~ zf4Oj&5{WL$Uz*{IRTfSFU!Q#2atk9XZ#7r>FdUJWWHh>baX`YJt6TUgWCsBAH5n(B zLG;;DEH~J34NTms{frqMb~_Yb_2Nv zszmra{9bm!xdu6=J{3}Ck<`7DcJ$7<12}Ki8_@bbY_cz>ga=wG#Dco|b@vJj@JBfhd+N9Z(n%U;&o|IlhWb=U%+r1CYI=(N_iNM zUes$EB#e!8Z@A^l^+cmBoKC@&BV&oJAt^}k^FD?Oc#UuH`&ESUJ&p7(#UW(?9sOG@ z?s88kF1-nNIVCo`zm2GHEOdS#oS8O6X(~@^Xt)P%-;E;UDF=-q`uybS{%ctDqpna8 zgod~6H=M!jd>P}V9o;H_9kt`}Og8b&9wn=%2i`DA&*LA+(sw2w5+Gj!;Q>cxx@$5Z$JZ@dey~H!+xVJ7mjCczUbubaweieLP zeIC@Hj*4@w_#}b2PAlqpX#^6SZB?9JeMd#ev$&tHrL|1k$B7R4*Zf>Y)pVfUAb*St zGh*8IZ^t6fe`!bviflz258_wmFfcEA^=RvrBVf>4eVpAI0%>PvI+y2ccD#8k93 zP84o9b}>-$&y{Dua#>|VJE03HhJtMFE+BOQdS&uc()3OIDXNdmkSDp7PfqXlsE?i) z#>EBROP#CU77A67gZCKB5go_Vo1PpJ?g9Hj7#C3zVarm#U~Z6X(0DSHSQE}jC##I1 zqR(Xv^HAh)3dP%<_Tqx6guJ*GEdpr66{Zw&5K+3eIDlAc;&Z)$mF3pwn;=sJH!L;q z^!2%1N`!gBsE8NmBUfoEwQ>nSa3R4c#}Va8YOC$|JIh|$?8Ng&Y@4&y--!syybHRG zc5iTVTkWhu98xvmg+ zYx1E%aWBkhuFrVgAa+^QDRk0^-~w0r1b#e+8uqU?bhC#&tRakYECn%03rU6R7P=s2 z&}p_=Hs*>7=U7$;#@dE=)g?ke*f^)0hIgZV|(XCnVfAVS|=${=9~W@^mwgpIF0axclvkq1{tuk zC1e`;+E_8UTdPZnC=JW1nAK^Jm=tHPtQND<$ET0|2Yqt=N6zk=e0u>%;;b~ig@M#u zMGg%nE8LaAht3IXNy=R4?6AZ=S)~R$juBY-NXs;$%5YNXKJ zr*2xm-6{@O2o)-0vmVIUD;%=PnhT&zs-Qn0K5@m)H3eJA%$a51Wg^}7%$h)bH89gd zJZ@Yp$nSfK3YK1K6B?&8nhA6mxeA)R&6Q(;7u=;jF)>H&ti57E`Tm8lCc0yp>VYuL z;}Y)^Wg63%eY_fX8r- z^2BUEmPm!EE^a&L&to8EG>=+lW%Z{hdjeH9ODPv0Oyt8r4W=xTD$TW)h#)n!4!nMf5`+^vMI(1jw z1GwhgzjVEsAy}-kVNGvePTD6W>~~Q@CG(ZT{{CzTeYyNPssz`|EnY?AYl%4<9&dbp zI42xkjA5jt8sYkr`FZck`zaC;xf!tidbOGu!y9LvywV(9cq&p`hnDhaR@@Zb-p^0M zuW*|m=HmC#Y|$LQ3VM|a9Wa9!^GH6J0ZV86!4~hOWrsQxFfwm_MMxYaA_TlMzwutm zQaB6C>_M9xs`y~#|9Qf}y2Kzztqj>=Tv4Y4*y#iRGkF`n%j{)|&g+Z5W;kDZtZM{S zqKvVSCt}eBr^5udjAoD~wn_!RE7^!!gvZN#&OzT>HTQziOrJe!BN@M13_~amDE3-} zh}ggEcjr*qubjYLTVQzQA}a}}(^v|B4E}_`Q-hR}@oz7HtdruxWKk45?We~6yWvg# z4;C4C{oVhSwhJ;OfR6UGCbjdkFpC1V$zbqGJ;ixsCF7v1P|`&#$k9(sg%!A^qH`CO zC_#SYS)kuY6;bC3pON-7L($=Xk^N#;9Z%c#b&82uY3hf}0b}cp68?{NEO_kBpy4@} zl(@y+XmpO%RANs5_JlPPNxvp88G%=+qa#Pk#R}v|*f|z75?9A4?|g(pgpXeq8#SM` z7t}=0M-E|DLe}5NA9e&v2Wo|v0}u@e6SA*UsFt~CJk{IOmtm`mP#R+VfeTV#2VsrS z;PkX-!xJ*7(83Yt#s??T>I0dhE9%XZzeL?SMD0^OSQJJio5(K`!y>bn?S#2l(L5=r2F<85t;CG?D;xY#61qZ0L?$f`$L;3=XbcgcHtB zvatyhIxK2lt{AiGZSIGl!KvW1!FcH<3LV1oXdPv1=@ZZ;ap|BYpCy2X%+j|8yW&2HT2b~ik>>)L4LB-*xiJr++r0} zX1PO4B|0EJg4=d;%a9iMS!)j0RoihIYLA_}RUKS)N#a5%gd(7U1)6GO!ZO4g@sxT? zw2n~yl811N%ubk11W5xp@_cwZT zvpTB4e@|RohjX_-7J9`JyMInKJ|OvK0^mS3@)9E_U-J%gf|%~RXgE=!C?D#%+aI69 z5q7j`l}H+bLyy^_aoJ?WlUWH-2;&G71@>_}Q8dEgH!sxFd#Kf&?CeYX|SK-M4UcHQ|<74d{_=EnE;Zmx~uHSItx+phSzaDCTBj8&hs6A0Dk!BGC;Fd zTY7i|+T%5MJ}Y%}rn5_7>7`r5SqtBb2#4=d-%{Z}|iyjHNFN;*7O(Ig~DYZJW>Bx>yi_YkN$IOoLs zA8&J8PQ7j<;;q{*h@p(p5-u$`NUb!!P%P|1@ccgzcM$lzvU4B4IykWA!%9O#)F)-; z$s(Tva$EyE=BrvVoA?BOh+wW(rJHUc@i8KeV737`I*y;htE|HrGl+Q@UEm?OtC}4u*%O9 z8=8F8atvN1TqJcqT1VjzsIgj@hFrEii`UQC@qR{w9o;M~j8bh|MppPc_$@;1_$sbB zMx1TFlagYSF-(O638PG=X=?HGFdj(lpZR-2=-v|xo{`xBWa5X_l1{OMy7ZNepK&Ii zd-1SQZ8w=X;{qtt_9`5%8v!Mcz}qAxMG+1T%6wNW5zD*aG`XhDO8ba=Mz z)*P#&Mz2WdgTVE~fQA6PP!DYleh;{85V6k@7o;>`ZBg&IG~T<%oKb+laqLE<37L{% z`6jUt8)r2upK>sTbULd2WL)zo}irT-=_rVdIoD33*6zsm`ab z+9Ttw{Zp8`UubK`yHD4A(=4jr{?J+|nEA@+QSH(h6G>_k^j{TdVIX#W6zvCZG#c0n zs5Rigvz?+PtfyaUr*({|Su7wk^o1tY8AOl;p(Tcp4MbEWX%no5S=}ZuM;&6+9eY?U z9gN?a>_#!3NHw!ci8Oe#Te22-X>+($w-jk|bTp)qIT|%JSs6~ldq1?UeiQjr5{?TE zu2#yc^lVg%iM%!F#Z)UcWNP zTn_+4(c?on)U+3TOpG})27Gtntx>(SNk1I&SQ5Ys@@!KQy=GjaY0!!bq)dh~Ybk7a zd%YHynM4<&E|pRQ=5x(%R&XB7am_7jeP$xsnz zex&pfefXc%z*$TW%aJXS;I>#8(DXwq7}b2-rYW&>cU5!ya1WwJ@gEu3!a`6z7JJBv zm=w2BuQHn68zV^x7N-Ejt_w7i%qHs^-z|iEl~0iHW{G|t)+1~96|*ncpZEM48$f3ugq$@!^7`fgg}y9ZuAYvG;8v-KxT0w2M@Bg( zAL^5ossJhzQ=2!)GoxrGIP zcYKzhv#hn#W!2(54@eQ>4cz{PITMpyw`_ARwi;R6&X8~sM(K&�IBa((gc5m8fo$ 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%0A~U?&XDlGI4 zeLA9xv{Q)-<7*RMQ1k>66rTv3!tAP3r`7|(W$Qq0e%-9JEWae~5e8t^sF;5b4+6s7 zyUWrM##a^b34!A~!F(ZlaC3spuBK(rvTQOMg76X~rrS*=1jxR0-M&APVOQ8dZrMNZ zdV@Vc5_^){mZ$+diWgUJn>Yl0L~&4CP&j5Sb6d~UGE>w&p)`iCPE`Bt zr%*hX>*8y<;aIc3-fi+;QTA{6HDH*l017xw|6p5zrn(PaJAt&(j_w*cikffa$nku# z3@tjyj=mDoA(`Xq4nus1-`rqC>$W~}<4OzjZ4*cq7@~n8c4a~{U($MS4K_rbAmCP5 z5InUs(`HIe2j;qz;|!P>W6*u~W76|h zbyt-U1eKmeay`BMXM=t9SG5`1YCArIHuPetFF-Z!J zHHDy23j9w+rfC8FmCu@=75b#-YG5TGh_@HnCQ>yII8fHjQNY#_hqod6lr)|SB$5y z`f9G=l8TwxuvVL~%zx^3h7>aF@6lkuZa50I0_E^E0)ySTDj7;_}{4p981Tgdua{UKM{9P$y5s(Ji+bx{;3=~Rl9vmBjKy)}_K#JWS!@=tp zlC}BV(oiN^7xep*8Xv^L#hPV0`&s9()wz)(Xz9S8Q{KfC1>vRLDFC_{CBS!+I@?jZ zm}d~po!4dSKp(V{eC}VUc`d+-|;mT!ttOn0I zDD}B3U@taxQ~~I_{|Aq*j;P18u8JoD8WzlBPYyOr=^2~D4NIE=`TQp3mJC(vd)+%P zx~e)kfNgT##=yLZVuxs*B(T24I$cz;M>z*m!oq@^cI921L-4lVFpzGT^y=^JlGCN> zz5R~lfA<|VOhzM&2T0{3Z130M^OoQ`^}pU*mB9=;=}uXK{0=9&L#H}iDe5f5;T&)a zE+4UUoG{Jl*~2_ZxQk$lwU0S*cuAoBc6@N}t+bRCKa*39&*dc49h*V`vC+a7Qv0z= z=tN~G`D01=ITcVf5rS@2Pa;8A&d+XcYiuDOH3nQ@92}Wky8B7l�pJeHuu>#z*s! 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 z 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 z�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

    &R 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

  • +
    + 🔸Daemon Sync Server LXC + +

    + +

    Daemon Sync Server LXC

    + +Sync files from app to server, share photos & videos, back up your data and stay secure inside local network. + +To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/daemonsync.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    + +**Daemon Sync Server Interface - IP:8084** + +[Android App](https://play.google.com/store/apps/details?id=com.discsoft.daemonsync) + +[iPhone App](https://itunes.apple.com/us/app/daemon-sync/id992411172) +__________________________________________________________________________________________ + +
    +
    MotionEye NVR LXC From a1dc8f90c607986b216f5c04e70bf9759ce9ec1c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 17:00:07 -0500 Subject: [PATCH 1407/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 439571ed..16fcd0bf 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-01 + +### Changed + +- **Daemon Sync Server LXC** + - New Script + ## 2022-02-28 ### Changed @@ -102,7 +109,7 @@ All notable changes to this project will be documented in this file. ### Changed - **GamUntu LXC** - - New script + - New Script - **Jellyfin Media Server LXC** - new script to fix [start issue](https://github.com/tteck/Proxmox/issues/29#issue-1127457380) - **MotionEye NVR LXC** From 26336731a637a7e61b3f15c60f7a3de6641967af Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 17:04:05 -0500 Subject: [PATCH 1408/6505] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 120d1c4a..40eadc4c 100644 --- a/README.md +++ b/README.md @@ -842,10 +842,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/d

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    **Daemon Sync Server Interface - IP:8084** - -[Android App](https://play.google.com/store/apps/details?id=com.discsoft.daemonsync) - -[iPhone App](https://itunes.apple.com/us/app/daemon-sync/id992411172) + __________________________________________________________________________________________
    From def32ef99cabf04699435eb507106efbbb0902da Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 17:15:26 -0500 Subject: [PATCH 1409/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 40eadc4c..d4302b8a 100644 --- a/README.md +++ b/README.md @@ -842,6 +842,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/d

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    **Daemon Sync Server Interface - IP:8084** + +Search: `DAEMON Sync` in your favorite app store __________________________________________________________________________________________ From 4628ecd991f291538a82bd6d091902f424ddf551 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Mar 2022 17:36:59 -0500 Subject: [PATCH 1410/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d4302b8a..f4783ec9 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant Container LXC + Home Assistant Container LXC

    Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    @@ -518,7 +518,7 @@ ________________________________________________________________________________
    - 🔸Zigbee2MQTT LXC + Zigbee2MQTT LXC

    logo.png

    @@ -797,7 +797,7 @@ ________________________________________________________________________________
    - 🔸AdGuard Home LXC + AdGuard Home LXC

    From ec03c998ccc5d9f2cf16446b4c44f6089aa7d132 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 04:56:08 -0500 Subject: [PATCH 1411/6505] Update daemonsync.sh --- ct/daemonsync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index 79989b29..ea718383 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -15,7 +15,7 @@ while true; do done clear function header_info { -echo -e "${RD} +echo -e "${BL} _____ _____ | __ \ / ____| | | | | __ _ ___ _ __ ___ ___ _ __ | (___ _ _ _ __ ___ From 35f132e6a46e5e5df68749fe392d7c088cfbb17b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 05:46:31 -0500 Subject: [PATCH 1412/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f4783ec9..809d7715 100644 --- a/README.md +++ b/README.md @@ -520,7 +520,7 @@ ________________________________________________________________________________
    Zigbee2MQTT LXC -

    logo.png

    +

    Zigbee2MQTT LXC Container

    From 8ea1e80b3e78fc8fc6d38d0f06c92f55176d4802 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 08:33:52 -0500 Subject: [PATCH 1413/6505] Create update-lxcs.sh --- misc/update-lxcs.sh | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 misc/update-lxcs.sh diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh new file mode 100644 index 00000000..c83d6645 --- /dev/null +++ b/misc/update-lxcs.sh @@ -0,0 +1,54 @@ +#!/bin/bash +set -e +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This Will Update All LXC Containers. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _ _ _____ _____ _______ ______ + | | | | __ \| __ \ /\|__ __| ____| + | | | | |__) | | | | / \ | | | |__ + | | | | ___/| | | |/ /\ \ | | | __| + | |__| | | | |__| / ____ \| | | |____ + \____/|_| |_____/_/ \_\_| |______| + +${CL}" +} +header_info + +containers=$(pct list | tail -n +2 | cut -f1 -d' ') + +function update_container() { + container=$1 + echo -e "${BL}[Info]${GN} Updating${BL} $container... ${CL}" + # to chain commands within one exec we will need to wrap them in bash + pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" +} + +for container in $containers +do + status=`pct status $container` + if [ "$status" == "status: stopped" ]; then + echo -e "${BL}[Info]${GN} Starting${BL} $container... ${CL}" + pct start $container + echo -e "${BL}[Info]${GN} Waiting For${BL} $container To Start... ${CL}" + sleep 5 + update_container $container + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL}" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + update_container $container + fi +done; wait From 28d809649be4013ec873c1b337a7900217f0320a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 08:41:37 -0500 Subject: [PATCH 1414/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index c83d6645..277cc04a 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -32,7 +32,7 @@ containers=$(pct list | tail -n +2 | cut -f1 -d' ') function update_container() { container=$1 - echo -e "${BL}[Info]${GN} Updating${BL} $container... ${CL}" + echo -e "${BL}[Info]${GN} Updating${BL} $container... ${CL} \n" # to chain commands within one exec we will need to wrap them in bash pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" } @@ -41,14 +41,15 @@ for container in $containers do status=`pct status $container` if [ "$status" == "status: stopped" ]; then - echo -e "${BL}[Info]${GN} Starting${BL} $container... ${CL}" + echo -e "${BL}[Info]${GN} Starting${BL} $container... ${CL} \n" pct start $container - echo -e "${BL}[Info]${GN} Waiting For${BL} $container To Start... ${CL}" + echo -e "${BL}[Info]${GN} Waiting For${BL} $container To Start... ${CL} \n" sleep 5 update_container $container - echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL}" + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" pct shutdown $container & elif [ "$status" == "status: running" ]; then update_container $container fi done; wait +echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From aca75652c853ed0eac96867d0ecd2fa56bd5a9ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 08:57:46 -0500 Subject: [PATCH 1415/6505] Update README.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 809d7715..a638f96c 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,23 @@ ________________________________________________________________________________
    +
    + 🔸Proxmox LXC Updater + +

    + +

    Proxmox LXC Updater

    + +Updates All LXC's Fast & Easy + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/update-lxcs.sh)" +``` +____________________________________________________________________________________________ + +
    Proxmox Dark Theme From b7f39d3f23c32be76bc6b0c2f9b7c93aef82611f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 08:59:01 -0500 Subject: [PATCH 1416/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 277cc04a..6bbba261 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -32,7 +32,7 @@ containers=$(pct list | tail -n +2 | cut -f1 -d' ') function update_container() { container=$1 - echo -e "${BL}[Info]${GN} Updating${BL} $container... ${CL} \n" + echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" # to chain commands within one exec we will need to wrap them in bash pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" } @@ -41,9 +41,9 @@ for container in $containers do status=`pct status $container` if [ "$status" == "status: stopped" ]; then - echo -e "${BL}[Info]${GN} Starting${BL} $container... ${CL} \n" + echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container - echo -e "${BL}[Info]${GN} Waiting For${BL} $container To Start... ${CL} \n" + echo -e "${BL}[Info]${GN} Waiting For${BL} $container To Start ${CL} \n" sleep 5 update_container $container echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" From aed987a17edbea835d2cd3a79390d1889b068670 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 09:00:22 -0500 Subject: [PATCH 1417/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 16fcd0bf..9d6a50ae 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-02 + +### Changed + +- **Proxmox LXC Updater** + - New Script + ## 2022-03-01 ### Changed From 416ee5ae845d763f724a4600903366ca4269b8f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 09:45:50 -0500 Subject: [PATCH 1418/6505] Update debian.sh --- ct/debian.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index a60bd857..64524773 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -6,7 +6,7 @@ CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` while true; do - read -p "This will create a New Debian Bulleyes LXC. Proceed(y/n)?" yn + read -p "This will create a New Debian Bulleye LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -156,4 +156,4 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created Debian Bulleyes LXC to${CL} ${BL}$CTID${CL}. \n" +echo -e "${GN}Successfully created Debian Bulleye LXC to${CL} ${BL}$CTID${CL}. \n" From 97d74efae762f38233125a453d57cdd376eaacfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 11:06:03 -0500 Subject: [PATCH 1419/6505] Create dashy-install.sh --- setup/dashy-install.sh | 118 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 setup/dashy-install.sh diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh new file mode 100644 index 00000000..10e103b1 --- /dev/null +++ b/setup/dashy-install.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Yarn... " +npm install --global yarn &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dashy... " +git clone https://github.com/Lissy93/dashy.git &>/dev/null +cd /root/dashy/ +yarn +export NODE_OPTIONS=--max-old-space-size=1000 &>/dev/null +yarn build &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Dashy Service... " +cat < /etc/systemd/system/dashy.service +[Unit] +Description=dashy + +[Service] +Type=simple +WorkingDirectory=/root/dashy +ExecStart=/usr/bin/yarn start +[Install] +WantedBy=multi-user.target +EOF +sudo systemctl start dashy &>/dev/null +sudo systemctl enable dashy &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 2ab6dcb70fdcc73e42feaddcbc36d528b6b558a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 11:13:48 -0500 Subject: [PATCH 1420/6505] Create dashy.sh --- ct/dashy.sh | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 ct/dashy.sh diff --git a/ct/dashy.sh b/ct/dashy.sh new file mode 100644 index 00000000..aec3fb8b --- /dev/null +++ b/ct/dashy.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Dashy LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _ + | __ \ | | + | | | | __ _ ___| |__ _ _ + | | | |/ _ / __| _ \| | | | + | |__| | (_| \__ \ | | | |_| | + |_____/ \__,_|___/_| |_|\__, | + __/ | + |___/ +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=3 +export PCT_OPTIONS=" + -features $FEATURES + -hostname dashy + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 1024 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/dashy-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Dashy LXC to${CL} ${BL}$CTID${CL}. +${BL}Dashy${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:4000${CL} \n" From defc179596c8217a15cd436ff7456b468c9dc37f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 11:21:45 -0500 Subject: [PATCH 1421/6505] Update dashy-install.sh --- setup/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 10e103b1..b17957d4 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -74,7 +74,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Dashy... " git clone https://github.com/Lissy93/dashy.git &>/dev/null -cd /root/dashy/ +cd dashy/ yarn export NODE_OPTIONS=--max-old-space-size=1000 &>/dev/null yarn build &>/dev/null From ea99be316db48c66168dcf4c82c972ce669ca06f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 11:44:29 -0500 Subject: [PATCH 1422/6505] Update dashy-install.sh --- setup/dashy-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index b17957d4..56e6bd48 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -74,7 +74,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Dashy... " git clone https://github.com/Lissy93/dashy.git &>/dev/null -cd dashy/ +cd /dashy yarn export NODE_OPTIONS=--max-old-space-size=1000 &>/dev/null yarn build &>/dev/null @@ -87,7 +87,7 @@ Description=dashy [Service] Type=simple -WorkingDirectory=/root/dashy +WorkingDirectory=/dashy ExecStart=/usr/bin/yarn start [Install] WantedBy=multi-user.target From c43b1e1ebd451d4d10cb566b69f08b76f6cfa27b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 11:45:55 -0500 Subject: [PATCH 1423/6505] Update dashy.sh --- ct/dashy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/dashy.sh b/ct/dashy.sh index aec3fb8b..ba366911 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +clear YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From ee5b4a683fc5fbefba76cdb82a525a39c0fe625f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 12:22:55 -0500 Subject: [PATCH 1424/6505] Update dashy-install.sh --- setup/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 56e6bd48..99bdeaed 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -75,7 +75,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Dashy... " git clone https://github.com/Lissy93/dashy.git &>/dev/null cd /dashy -yarn +yarn &>/dev/null export NODE_OPTIONS=--max-old-space-size=1000 &>/dev/null yarn build &>/dev/null echo -e "${CM}${CL} \r" From ce813e8cef6039a6f3cc734b82d207a19772a676 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 13:11:45 -0500 Subject: [PATCH 1425/6505] Update dashy.sh --- ct/dashy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index ba366911..25cab4a1 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -138,7 +138,7 @@ export PCT_OPTIONS=" -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 - -memory 1024 + -memory 2048 -unprivileged ${IM} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 945382910b5aff07b41649b58511bfb4b3adf59e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 13:32:37 -0500 Subject: [PATCH 1426/6505] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index a638f96c..4acb1166 100644 --- a/README.md +++ b/README.md @@ -841,6 +841,29 @@ ________________________________________________________________________________
    + +
    + 🔸Dashy LXC + +

    + +

    Dashy LXC

    + +Dashy helps you organize your self-hosted services by making them accessible from a single place + +To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/dashy.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    + +**Dashy Interface - IP:4000** + +__________________________________________________________________________________________ + +
    +
    🔸Daemon Sync Server LXC From 2a4189b6f446d41fb830989561c254f844279c86 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 13:33:37 -0500 Subject: [PATCH 1427/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9d6a50ae..c3268a1e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Proxmox LXC Updater** - New Script +- **Dashy LXC** + - New Script ## 2022-03-01 From c948482711607951ea8a8181403adbf298ad57fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 13:34:17 -0500 Subject: [PATCH 1428/6505] Update dashy-install.sh --- setup/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 99bdeaed..15065741 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -72,7 +72,7 @@ echo -en "${GN} Installing Yarn... " npm install --global yarn &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Dashy... " +echo -en "${GN} Installing Dashy (Patience)... " git clone https://github.com/Lissy93/dashy.git &>/dev/null cd /dashy yarn &>/dev/null From 57517ed480a80d775838c4c64f509fa7953df6f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 14:57:55 -0500 Subject: [PATCH 1429/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4acb1166..25fbe879 100644 --- a/README.md +++ b/README.md @@ -280,7 +280,7 @@ ________________________________________________________________________________
    - 🔸Nginx Proxy Manager LXC + Nginx Proxy Manager LXC

    hero

    From c739d3f564e691d75a90ca22f9bf66fa4783fbdf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 15:34:15 -0500 Subject: [PATCH 1430/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 6bbba261..ad2ec632 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -33,7 +33,6 @@ containers=$(pct list | tail -n +2 | cut -f1 -d' ') function update_container() { container=$1 echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" - # to chain commands within one exec we will need to wrap them in bash pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" } From e368fe8eec74f77d433f1b209dc0afeba5681aa0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 15:35:56 -0500 Subject: [PATCH 1431/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c3268a1e..f31a36b9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -65,7 +65,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Home Assistant Container LXC** - - Add Script to migrate to the latest Update Menu + - New Script to migrate to the latest Update Menu ## 2022-02-19 From db26f1f64f2e4c85e88b8abaf86e9fa03eaeb577 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 21:11:59 -0500 Subject: [PATCH 1432/6505] Create influxdb-install.sh --- setup/influxdb-install.sh | 95 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 setup/influxdb-install.sh diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh new file mode 100644 index 00000000..52cf1aff --- /dev/null +++ b/setup/influxdb-install.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y lsb-base &>/dev/null +apt-get install -y lsb-release &>/dev/null +apt-get install -y gnupg2 &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up InfluxDB Repository... " +wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add - &>/dev/null +echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing InfluxDB... " +apt-get update &>/dev/null +apt-get install -y influxdb &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +systemctl enable --now influxdb +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From ad52e5cb81378a5648de945462e6f84b078016e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 21:12:43 -0500 Subject: [PATCH 1433/6505] Create grafana-install.sh --- setup/grafana-install.sh | 94 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 setup/grafana-install.sh diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh new file mode 100644 index 00000000..b8033dca --- /dev/null +++ b/setup/grafana-install.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +apt-get install -y apt-transport-https &>/dev/null +apt-get install -y software-properties-common &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Grafana Repository... " +wget -qO- https://packages.grafana.com/gpg.key | sudo apt-key add - &>/dev/null +echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Grafana... " +apt-get update &>/dev/null +apt-get install -y grafana &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 0efa862161b3558153f332f3252cafa53ae99e12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 21:14:14 -0500 Subject: [PATCH 1434/6505] Create grafana.sh --- ct/grafana.sh | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 ct/grafana.sh diff --git a/ct/grafana.sh b/ct/grafana.sh new file mode 100644 index 00000000..ffca9ac8 --- /dev/null +++ b/ct/grafana.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Grafana LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _____ __ + / ____| / _| + | | __ _ __ __ _| |_ __ _ _ __ __ _ + | | |_ | __/ _ | _/ _ | _ \ / _ | + | |__| | | | (_| | || (_| | | | | (_| | + \_____|_| \__,_|_| \__,_|_| |_|\__,_| + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname grafana + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/grafana-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Grafana LXC to${CL} ${BL}$CTID${CL}. +${BL}Grafana${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 33c2df4c1eeaef6097a94ff0ae72df2b79192c76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 21:15:46 -0500 Subject: [PATCH 1435/6505] Create influxdb.sh --- ct/influxdb.sh | 159 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 ct/influxdb.sh diff --git a/ct/influxdb.sh b/ct/influxdb.sh new file mode 100644 index 00000000..b6d3bcbc --- /dev/null +++ b/ct/influxdb.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New InfluxDB LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _____ __ _ _____ ____ + |_ _| / _| | | __ \| _ \ + | | _ __ | |_| |_ ___ _| | | | |_) | + | | | _ \| _| | | | \ \/ / | | | _ < + _| |_| | | | | | | |_| |> <| |__| | |_) | + |_____|_| |_|_| |_|\__,_/_/\_\_____/|____/ + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname influxdb + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/influxdb-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created InfluxDB LXC to${CL} ${BL}$CTID${CL}. \n" From a046345b8ab1da83753f726ff3075accbe57c1d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 21:42:10 -0500 Subject: [PATCH 1436/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f31a36b9..094afc29 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,6 +10,10 @@ All notable changes to this project will be documented in this file. - New Script - **Dashy LXC** - New Script +- **Grafana LXC** + - [New Test Script](https://github.com/tteck/Proxmox/issues/45#issuecomment-1057602944) +- **InfluxDB LXC** + - [New Test Script](https://github.com/tteck/Proxmox/issues/45#issuecomment-1057602944) ## 2022-03-01 From 2aea5bba27280bef2b98442e90588ff4b1ff26e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Mar 2022 23:19:00 -0500 Subject: [PATCH 1437/6505] Update grafana-install.sh --- setup/grafana-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index b8033dca..be34f222 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -84,6 +84,8 @@ ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF systemctl daemon-reload +systemctl start grafana-server +systemctl enable grafana-server.service &>/dev/null systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" From 03b8f7c817d400aee8b7163564bddc76ff6a5e57 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 06:54:41 -0500 Subject: [PATCH 1438/6505] Update README.md --- README.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 25fbe879..dec78824 100644 --- a/README.md +++ b/README.md @@ -631,6 +631,73 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z **Zwavejs2MQTT Interface - IP:8091** +____________________________________________________________________________________________ + +
    + +
    + 🔸InfluxDB LXC + +

    + +

    InfluxDB LXC Container

    + +To create a new Proxmox InfluxDB LXC Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/influxdb.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +⚙️ **To Update InfluxDB** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    + +
    + 🔸Grafana LXC + +

    + +

    Grafana LXC Container

    + +To create a new Proxmox Grafana LXC Container, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/grafana.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` + +⚙️ **To Update Grafana** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + ____________________________________________________________________________________________
    @@ -911,9 +978,13 @@ After the script completes, If you're dissatisfied with the default settings, cl ⚙️ **Initial Login** **username** - `admin` - + ```yaml + admin + ``` **password** + ```yaml + + ``` ⚙️ **To Update MotionEye** @@ -951,10 +1022,13 @@ Benefits include automatic daily security updates, backup and restore, file mana ⚙️ **Initial Login** **username** - `root` - + ```yaml + root + ``` **password** - `root` + ```yaml + root + ``` ⚙️ **To Update Webmin** From 1131b2d48da8ea692b602963860ea8cc6a7c7b12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 06:56:51 -0500 Subject: [PATCH 1439/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 094afc29..bcf661f3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,9 +11,9 @@ All notable changes to this project will be documented in this file. - **Dashy LXC** - New Script - **Grafana LXC** - - [New Test Script](https://github.com/tteck/Proxmox/issues/45#issuecomment-1057602944) + - New Script - **InfluxDB LXC** - - [New Test Script](https://github.com/tteck/Proxmox/issues/45#issuecomment-1057602944) + - New Script ## 2022-03-01 From 94c8aea673e5d94c8501341933a0587ee661bf35 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 07:01:47 -0500 Subject: [PATCH 1440/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dec78824..97abec23 100644 --- a/README.md +++ b/README.md @@ -677,9 +677,11 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/g ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - + After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. +**Grafana Interface - IP:3000** + ⚙️ **Initial Login** **username** From 763fd945e0e428877375648d81f444866a00a9b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 07:37:57 -0500 Subject: [PATCH 1441/6505] Update influxdb.sh --- ct/influxdb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index b6d3bcbc..0c60af4b 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -22,7 +22,7 @@ echo -e "${YW} | | | _ \| _| | | | \ \/ / | | | _ < _| |_| | | | | | | |_| |> <| |__| | |_) | |_____|_| |_|_| |_|\__,_/_/\_\_____/|____/ - + with Telegraf ${CL}" } From 20e852588777459ef5edca33b63dbe66c05cea09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 07:39:05 -0500 Subject: [PATCH 1442/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 52cf1aff..dfb55c81 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -71,7 +71,11 @@ echo -en "${GN} Installing InfluxDB... " apt-get update &>/dev/null apt-get install -y influxdb &>/dev/null echo -e "${CM}${CL} \r" - + +echo -en "${GN} Installing Telegraf... " +apt-get install -y telegraf &>/dev/null +echo -e "${CM}${CL} \r" + echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname From b4b3711e36134f63442c56b7e822901a9ac4af2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 07:47:05 -0500 Subject: [PATCH 1443/6505] Update README.md --- README.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 97abec23..1d86ebe2 100644 --- a/README.md +++ b/README.md @@ -636,11 +636,11 @@ ________________________________________________________________________________
    - 🔸InfluxDB LXC + 🔸InfluxDB/Telegraf LXC

    -

    InfluxDB LXC Container

    +

    InfluxDB/Telegraf LXC Container

    To create a new Proxmox InfluxDB LXC Container, run the following in the Proxmox Shell. @@ -652,7 +652,21 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/i After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. -⚙️ **To Update InfluxDB** +⚙️ **InfluxDB Configuration** + +Run in the LXC console +```yaml +nano /etc/influxdb/influxdb.conf +``` + +⚙️ **Telegraf Configuration** + +Run in the LXC console +```yaml +nano /etc/telegraf/telegraf.conf +``` + +⚙️ **To Update InfluxDB/Telegraf** Run in the LXC console ```yaml From 799d84edf208ff80a20d0bea116e100dceeb7777 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 07:52:12 -0500 Subject: [PATCH 1444/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bcf661f3..d3cec2f9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file. - New Script - **Grafana LXC** - New Script -- **InfluxDB LXC** +- **InfluxDB/Telegraf LXC** - New Script ## 2022-03-01 From af0882a7fb5cc88f713589ca5373a22511c5b4de Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 13:03:41 -0500 Subject: [PATCH 1445/6505] Update homeassistant.sh --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 27796f79..1204f5ef 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash YW=`echo "\033[33m"` -BL=`echo "\033[36m"` +BL=`echo "\033[94m"` RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` From 9a517371e45103cc51a1b7bdbe5c63a4f8056bf3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 16:59:15 -0500 Subject: [PATCH 1446/6505] Create wireguard.sh --- ct/wireguard.sh | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 ct/wireguard.sh diff --git a/ct/wireguard.sh b/ct/wireguard.sh new file mode 100644 index 00000000..de7e47a7 --- /dev/null +++ b/ct/wireguard.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New WireGuard LXC (using pivpn.io). Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + __ ___ _____ _ + \ \ / (_) / ____| | | + \ \ /\ / / _ _ __ ___| | __ _ _ __ _ _ __ __| | + \ \/ \/ / | | __/ _ \ | |_ | | | |/ _ | __/ _ | + \ /\ / | | | | __/ |__| | |_| | (_| | | | (_| | + \/ \/ |_|_| \___|\_____|\__,_|\__,_|_| \__,_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname wireguard + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/wireguard-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created WireGuard LXC to${CL} ${BL}$CTID${CL}. + \n" From d5c64b79ea3cafeb02efd69bc69435ddf95f4bc1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 17:00:26 -0500 Subject: [PATCH 1447/6505] Create wireguard-install.sh --- setup/wireguard-install.sh | 103 +++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 setup/wireguard-install.sh diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh new file mode 100644 index 00000000..83ad1efd --- /dev/null +++ b/setup/wireguard-install.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" +OPTIONS_PATH='/options.conf' +cat >$OPTIONS_PATH <<'EOF' +IPv4dev=eth0 +install_user=root +VPN=wireguard +pivpnNET=10.6.0.0 +subnetClass=24 +ALLOWED_IPS="0.0.0.0/0, ::0/0" +pivpnMTU=1420 +pivpnPORT=51820 +pivpnDNS1=1.1.1.1 +pivpnDNS2=8.8.8.8 +pivpnHOST=pivpn.example.com +pivpnPERSISTENTKEEPALIVE=25 +UNATTUPG=1 +EOF + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing WireGuard (using pivpn.io)... " +curl -s -L https://install.pivpn.io > install.sh +chmod +x install.sh +./install.sh --unattended options.conf &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 83fbe96cf4b1f8431be8c604a84af87cd5be451f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 17:42:58 -0500 Subject: [PATCH 1448/6505] Update README.md --- README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/README.md b/README.md index 1d86ebe2..0e93baaa 100644 --- a/README.md +++ b/README.md @@ -1059,6 +1059,45 @@ ________________________________________________________________________________
    +
    + 🔸WireGuard LXC + +

    + +

    WireGuard LXC

    + +To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/wireguard.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +⚙️ **Host Configuration** + +Run in the LXC console + ```yaml + nano /etc/pivpn/wireguard/setupVars.conf + ``` + ⚙️**Add Clients** + + Run in the LXC console + ```yaml + pivpn add + ``` +⚙️ **To Update WireGuard** + +Run in the LXC console + ```yaml +apt update && apt upgrade -y +``` +____________________________________________________________________________________________ + +
    +
    🔸Vaultwarden LXC From 91f2958957715437f5036119ebee0a3c1a8b9436 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Mar 2022 17:46:27 -0500 Subject: [PATCH 1449/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d3cec2f9..6caec923 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-03 + +### Changed + +- **WireGuard LXC** + - New Script + ## 2022-03-02 ### Changed From 8a36b55982355c7bb73de1c342e3d3883b2f15c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 07:50:51 -0500 Subject: [PATCH 1450/6505] Update webmin.sh --- misc/webmin.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 3beaeaf8..6c77b12e 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -22,16 +22,16 @@ apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip sh echo -e "${CM}${CL} \r" echo -en "${GN} Downloading Webmin... " -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.990_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Webmin... " -dpkg --install webmin_1.984_all.deb &>/dev/null +dpkg --install webmin_1.990_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Setting Default Webmin usermame & password to root... " /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /root/webmin_1.984_all.deb +rm -rf /root/webmin_1.990_all.deb echo -e "${CM}${CL} \r" IP=$(hostname -I | cut -f1 -d ' ') echo -e "${BL} Successfully Installed Webmin, Now Go To https://${IP}:10000 ${CL}" From 6cbf5555d295bbb0e2c5e111106ab7704de10b5e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 08:49:29 -0500 Subject: [PATCH 1451/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 83ad1efd..9aee5a05 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -60,7 +60,7 @@ pivpnMTU=1420 pivpnPORT=51820 pivpnDNS1=1.1.1.1 pivpnDNS2=8.8.8.8 -pivpnHOST=pivpn.example.com +pivpnHOST= pivpnPERSISTENTKEEPALIVE=25 UNATTUPG=1 EOF From 4793b2e23833bc30764c1bd1932996e14299b931 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 10:41:56 -0500 Subject: [PATCH 1452/6505] Create kernelclean.sh --- misc/kernelclean.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 misc/kernelclean.sh diff --git a/misc/kernelclean.sh b/misc/kernelclean.sh new file mode 100644 index 00000000..f544a61e --- /dev/null +++ b/misc/kernelclean.sh @@ -0,0 +1,86 @@ +#!/bin/bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +# Current kernel +current_kernel=$(uname -r) +function check_root { + if [[ $EUID -ne 0 ]]; then + printf "[!] Error: this script must be ran as the root user.\n" + exit 1 + fi +} +clear +function header_info { +echo -e "${RD} + _ __ _ _____ _ + | |/ / | | / ____| | + | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ + | < / _ \ __| _ \ / _ \ | | | | |/ _ \/ _ | _ \ + | \ __/ | | | | | __/ | | |____| | __/ (_| | | | | + |_|\_\___|_| |_| |_|\___|_| \_____|_|\___|\__,_|_| |_| + +${CL}" +} +function kernel_info { + latest_kernel=$(dpkg --list| grep 'pve-kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) + printf "OS: $(cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $0}')\n" + printf "Current Kernel: pve-kernel-$current_kernel\n" + if [[ "$current_kernel" == *"pve"* ]]; then + if [[ "$latest_kernel" != *"$current_kernel"* ]]; then + printf "Latest Kernel: $latest_kernel\n" + fi + else + printf "___________________________________________\n\n" + printf "[!] Warning, you're not running a PVE Kernel\n" + exit 1 + fi +} +function kernel_clean { + kernels=$(dpkg --list| grep 'pve-kernel-.*-pve' | awk '{print $2}' | sort -V) + kernels_to_remove="" + for kernel in $kernels + do + if [ "$(echo $kernel | grep $current_kernel)" ]; then + break + else + printf "\"$kernel\" has been added to the Kernel remove list\n" + kernels_to_remove+=" $kernel" + fi + done + printf "Kernel Search Complete!\n" + if [[ "$kernels_to_remove" != *"pve"* ]]; then + printf "It appears there are no old Kernels on your system \n" + else + read -p "[!] Would you like to remove the $(echo $kernels_to_remove | awk '{print NF}') selected Kernels listed above? [y/N]: " -n 1 -r + printf "\n" + fi + if [[ $REPLY =~ ^[Yy]$ ]]; then + printf "Removing $(echo $kernels_to_remove | awk '{print NF}') old Kernels..." + /usr/bin/apt purge -y $kernels_to_remove > /dev/null 2>&1 + printf "Finished!\n" + printf "Updating GRUB..." + /usr/sbin/update-grub > /dev/null 2>&1 + printf "Finished!\n" + else + printf "\nExiting...\n" + fi +} +function main { + check_root + header_info + kernel_info +} +while true; do + case "$1" in + * ) + main + kernel_clean + exit 1 + ;; + esac + shift +done From b27b040dab84568cd226c9179fb18df6307b4de6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 12:36:54 -0500 Subject: [PATCH 1453/6505] Update and rename kernelclean.sh to kernel-clean.sh --- misc/{kernelclean.sh => kernel-clean.sh} | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) rename misc/{kernelclean.sh => kernel-clean.sh} (93%) diff --git a/misc/kernelclean.sh b/misc/kernel-clean.sh similarity index 93% rename from misc/kernelclean.sh rename to misc/kernel-clean.sh index f544a61e..77fb4dec 100644 --- a/misc/kernelclean.sh +++ b/misc/kernel-clean.sh @@ -5,7 +5,15 @@ RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -# Current kernel +while true; do + read -p "This will Clean unused Kernel images. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear current_kernel=$(uname -r) function check_root { if [[ $EUID -ne 0 ]]; then @@ -13,7 +21,6 @@ function check_root { exit 1 fi } -clear function header_info { echo -e "${RD} _ __ _ _____ _ From 206714b4def281398e4e3610e89408b645e56d53 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 12:51:45 -0500 Subject: [PATCH 1454/6505] Update README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 0e93baaa..a6f66204 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,24 @@ ________________________________________________________________________________
    +
    + 🔸Proxmox Kernel Clean + +

    + +

    Proxmox Kernel Clean

    + +Cleaning unused kernel images is not only good because of a reduced grub menu, but also gains some disk space. + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/kernel-clean.sh)" +``` +____________________________________________________________________________________________ + +
    +
    🔸Proxmox LXC Updater From 99b0b27d6e17f12ca43824150d8daa76c8ebba8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 12:55:10 -0500 Subject: [PATCH 1455/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6caec923..a76d2811 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-04 + +### Changed + +- **Proxmox Kernel Clean** + - New Script + ## 2022-03-03 ### Changed From edbdf2161e778ed8cec4cd7e47b5c9542ac2fc9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 16:04:45 -0500 Subject: [PATCH 1456/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a6f66204..b1e36e8a 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ ________________________________________________________________________________

    Proxmox LXC Updater

    -Updates All LXC's Fast & Easy +Update All LXC's Fast & Easy Run the following in the Proxmox Shell. From 0fed77a0c55fa7d2d013b4bb04b2ea2d12dd2db9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Mar 2022 23:59:31 -0500 Subject: [PATCH 1457/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1e36e8a..1f25ee3e 100644 --- a/README.md +++ b/README.md @@ -1117,7 +1117,7 @@ ________________________________________________________________________________
    - 🔸Vaultwarden LXC + Vaultwarden LXC

    From 4984b5d6f53261072c1eaacb56f4e0cd59ad5fca Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 10:28:24 -0500 Subject: [PATCH 1458/6505] Update kernel-clean.sh --- misc/kernel-clean.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 77fb4dec..ebeaceaa 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -69,7 +69,7 @@ function kernel_clean { printf "Removing $(echo $kernels_to_remove | awk '{print NF}') old Kernels..." /usr/bin/apt purge -y $kernels_to_remove > /dev/null 2>&1 printf "Finished!\n" - printf "Updating GRUB..." + printf "Updating GRUB... \n" /usr/sbin/update-grub > /dev/null 2>&1 printf "Finished!\n" else From 6fa11ff520ed5836f0807758293418eb2e7437b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 10:30:09 -0500 Subject: [PATCH 1459/6505] Update kernel-clean.sh --- misc/kernel-clean.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index ebeaceaa..0561c105 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -62,7 +62,7 @@ function kernel_clean { if [[ "$kernels_to_remove" != *"pve"* ]]; then printf "It appears there are no old Kernels on your system \n" else - read -p "[!] Would you like to remove the $(echo $kernels_to_remove | awk '{print NF}') selected Kernels listed above? [y/N]: " -n 1 -r + read -p "[!] Would you like to remove the $(echo $kernels_to_remove | awk '{print NF}') selected Kernels listed above? [y/n]: " -n 1 -r printf "\n" fi if [[ $REPLY =~ ^[Yy]$ ]]; then From 1290286473dfc69ee4364c1d82777cb79ced355b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 13:27:20 -0500 Subject: [PATCH 1460/6505] Create homebridge.sh --- ct/homebridge.sh | 162 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 ct/homebridge.sh diff --git a/ct/homebridge.sh b/ct/homebridge.sh new file mode 100644 index 00000000..7248b124 --- /dev/null +++ b/ct/homebridge.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Homebridge LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _ _ _ _ + | | | | | | (_) | | + | |__| | ___ _ __ ___ ___| |__ _ __ _ __| | __ _ ___ + | __ |/ _ \| _ _ \ / _ \ _ \| __| |/ _ |/ _ |/ _ \ + | | | | (_) | | | | | | __/ |_) | | | | (_| | (_| | __/ + |_| |_|\___/|_| |_| |_|\___|_.__/|_| |_|\__,_|\__, |\___| + __/ | + |___/ +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname homebridge + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homebridge-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Homebridge LXC to${CL} ${BL}$CTID${CL}. +${BL}Homebridge${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8581${CL} \n" From 4aaf8753db3d57eeb1652db6e2c083f97ba09831 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 13:29:16 -0500 Subject: [PATCH 1461/6505] Create homebridge-install --- setup/homebridge-install | 97 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 setup/homebridge-install diff --git a/setup/homebridge-install b/setup/homebridge-install new file mode 100644 index 00000000..599632bd --- /dev/null +++ b/setup/homebridge-install @@ -0,0 +1,97 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs gcc g++ make python net-tools &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Homebridge... " +sudo npm install -g --unsafe-perm homebridge homebridge-config-ui-x &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Homebridge Service... " +sudo hb-service install --user root &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From eaf4c39e106c8b53660417c49343f5b1418514b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 13:33:47 -0500 Subject: [PATCH 1462/6505] Update homebridge.sh --- ct/homebridge.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 7248b124..6f00b4c2 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -16,14 +16,12 @@ done clear function header_info { echo -e "${YW} - _ _ _ _ _ - | | | | | | (_) | | - | |__| | ___ _ __ ___ ___| |__ _ __ _ __| | __ _ ___ - | __ |/ _ \| _ _ \ / _ \ _ \| __| |/ _ |/ _ |/ _ \ - | | | | (_) | | | | | | __/ |_) | | | | (_| | (_| | __/ - |_| |_|\___/|_| |_| |_|\___|_.__/|_| |_|\__,_|\__, |\___| - __/ | - |___/ + _ _ ____ __ __ ______ ____ _____ _____ _____ _____ ______ + | | | |/ __ \| \/ | ____| _ \| __ \|_ _| __ \ / ____| ____| + | |__| | | | | \ / | |__ | |_) | |__) | | | | | | | | __| |__ + | __ | | | | |\/| | __| | _ <| _ / | | | | | | | |_ | __| + | | | | |__| | | | | |____| |_) | | \ \ _| |_| |__| | |__| | |____ + |_| |_|\____/|_| |_|______|____/|_| \_\_____|_____/ \_____|______| ${CL}" } From d498c1fa55d0b02ed4d64633d0f4c27239a00f88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 13:35:25 -0500 Subject: [PATCH 1463/6505] Rename homebridge-install to homebridge-install.sh --- setup/{homebridge-install => homebridge-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename setup/{homebridge-install => homebridge-install.sh} (100%) diff --git a/setup/homebridge-install b/setup/homebridge-install.sh similarity index 100% rename from setup/homebridge-install rename to setup/homebridge-install.sh From f3b1cf7543d5895c5db2c5353858f003beda0af3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 13:56:05 -0500 Subject: [PATCH 1464/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 599632bd..7568ec1d 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -72,7 +72,7 @@ sudo npm install -g --unsafe-perm homebridge homebridge-config-ui-x &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Creating Homebridge Service... " -sudo hb-service install --user root &>/dev/null +sudo hb-service install --user homebridge &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Customizing Container... " From b1571930adf1d7aba050e612a2d7383c9eeceaf8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 14:26:00 -0500 Subject: [PATCH 1465/6505] Update README.md --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f25ee3e..558e16f8 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,59 @@ ________________________________________________________________________________
    +
    + 🔸Homebridge LXC + +

    + +

    Homebridge LXC

    + +To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/homebridge.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +**Homebridge Interface - IP:8581** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` +Config File Path `/var/lib/homebridge/config.json` + +Storage Path `/var/lib/homebridge` + +Restart Command `sudo hb-service restart` + +Stop Command `sudo hb-service stop` + +Start Command `sudo hb-service start` + +View Logs Command `sudo hb-service logs` + +Systemd Service File `/etc/systemd/system/homebridge.service` + +Systemd Env File `/etc/default/homebridge` + +⚙️ **To Update Homebridge** + +```yaml +Update from the Homebridge UI +``` + + ___________________________________________________________________________________________ + +
    +
    @@ -272,7 +325,7 @@ ________________________________________________________________________________

    -

    ESPHome LXC Container

    +

    ESPHome LXC

    To create a new Proxmox ESPHome LXC Container, run the following in the Proxmox Shell. From c731cd56d925faf409b3ed5dea6c4ac7e8da4712 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 14:26:52 -0500 Subject: [PATCH 1466/6505] Update homebridge.sh --- ct/homebridge.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 6f00b4c2..e54dd7b6 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -128,14 +128,14 @@ pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 +export PCT_DISK_SIZE=4 export PCT_OPTIONS=" -features $FEATURES -hostname homebridge -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 - -cores 2 - -memory 2048 + -cores 1 + -memory 1024 -unprivileged ${IM} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From be046ab993d564fa0ff4e1d4695b12ac9fc14cf6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 14:28:03 -0500 Subject: [PATCH 1467/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a76d2811..3cb88cad 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-05 + +### Changed + +- **Homebridge LXC** + - New Script + ## 2022-03-04 ### Changed From 3b10b291e4d4eb3c0be8f91ed1b1e3da39d9c277 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 14:49:01 -0500 Subject: [PATCH 1468/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 558e16f8..22acce7c 100644 --- a/README.md +++ b/README.md @@ -862,6 +862,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/g After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. +**Webmin Interface - https:// IP:10000 (https)** + ⚙️ **To Update GamUntu** Run in the LXC console From 6729f7c36a6a0124aced72453f88394a988d7ea8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 16:10:09 -0500 Subject: [PATCH 1469/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 22acce7c..c36897a1 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,7 @@ ________________________________________________________________________________

    Homebridge LXC

    +Homebridge allows you to integrate with smart home devices that do not natively support HomeKit To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. From 0b7949936cc859ab83637668a657415083fa2a11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Mar 2022 17:21:39 -0500 Subject: [PATCH 1470/6505] Update README.md --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index c36897a1..42228769 100644 --- a/README.md +++ b/README.md @@ -328,7 +328,7 @@ Update from the Homebridge UI

    ESPHome LXC

    -To create a new Proxmox ESPHome LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome_container.sh)" @@ -357,7 +357,7 @@ ________________________________________________________________________________

    hero

    -

    Nginx Proxy Manager LXC Container

    +

    Nginx Proxy Manager LXC

    To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. @@ -407,9 +407,9 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc

    -

    MQTT LXC Container

    +

    MQTT LXC

    -To create a new Proxmox MQTT LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt.sh)" @@ -457,10 +457,10 @@ ________________________________________________________________________________

    -

    Node-Red LXC Container

    +

    Node-Red LXC

    -To create a new Proxmox Node-RED LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red.sh)" @@ -500,9 +500,9 @@ ________________________________________________________________________________

    MariaDB

    -

    Mariadb LXC Container

    +

    Mariadb LXC

    -To create a new Proxmox Mariadb LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb.sh)" @@ -612,9 +612,9 @@ ________________________________________________________________________________

    -

    Zigbee2MQTT LXC Container

    +

    Zigbee2MQTT LXC

    -To create a new Proxmox Zigbee2MQTT LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt.sh)" @@ -691,9 +691,9 @@ ________________________________________________________________________________

    -

    Zwavejs2MQTT LXC Container

    +

    Zwavejs2MQTT LXC

    -To create a new Proxmox Zwavejs2MQTT LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zwavejs2mqtt_container.sh)" @@ -712,9 +712,9 @@ ________________________________________________________________________________

    -

    InfluxDB/Telegraf LXC Container

    +

    InfluxDB/Telegraf LXC

    -To create a new Proxmox InfluxDB LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/influxdb.sh)" @@ -754,9 +754,9 @@ ________________________________________________________________________________

    -

    Grafana LXC Container

    +

    Grafana LXC

    -To create a new Proxmox Grafana LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/grafana.sh)" @@ -795,9 +795,9 @@ ________________________________________________________________________________

    Debian

    -

    Debian 11 LXC Container

    +

    Debian 11 LXC

    -To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian.sh)" @@ -824,9 +824,9 @@ ________________________________________________________________________________

    Ubuntu

    -

    Ubuntu 21.10 LXC Container

    +

    Ubuntu 21.10 LXC

    -To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu.sh)" @@ -850,11 +850,11 @@ ________________________________________________________________________________
    GamUntu LXC

    GamUntu

    -

    GamUntu LXC Container

    +

    GamUntu LXC

    GamUntu is Ubuntu 21.10, Docker, Docker Compose, ZFS Support, USB Passthrough, Webmin System Administration and Hardware Acceleration all baked in! -To create a new Proxmox GamUntuLXC Container, run the following in the Proxmox Shell. +To create a new Proxmox GamUntu LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/gamuntu_container.sh)" From 21e266c50d01107f79db5de9fd81733bd26fcbf3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 12:22:25 -0500 Subject: [PATCH 1471/6505] Update zwavejs2mqtt_container.sh --- ct/zwavejs2mqtt_container.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ct/zwavejs2mqtt_container.sh b/ct/zwavejs2mqtt_container.sh index c944d824..3b49ad4c 100644 --- a/ct/zwavejs2mqtt_container.sh +++ b/ct/zwavejs2mqtt_container.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` while true; do read -p "This will create a New Zwavejs2MQTT LXC Container. Proceed(y/n)?" yn @@ -8,6 +14,20 @@ while true; do * ) echo "Please answer yes or no.";; esac done +function header_info { +echo -e "${RD} + ______ _ ___ __ __ ____ _______ _______ + |___ / (_) |__ \| \/ |/ __ \__ __|__ __| + / /_ ____ ___ _____ _ ___ ) | \ / | | | | | | | | + / /\ \ /\ / / _ \ \ / / _ \ / __| / /| |\/| | | | | | | | | + / /__\ V V / (_| |\ V / __/ \__ \/ /_| | | | |__| | | | | | + /_____|\_/\_/ \__,_| \_/ \___| |___/____|_| |_|\___\_\ |_| |_| + _/ | + |__/ +${CL}" +} + +header_info set -o errexit set -o errtrace From 26abf2b965b6088fcc0265c4d13b4f0f7a480ac4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 12:24:10 -0500 Subject: [PATCH 1472/6505] Update zwavejs2mqtt_container.sh --- ct/zwavejs2mqtt_container.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/zwavejs2mqtt_container.sh b/ct/zwavejs2mqtt_container.sh index 3b49ad4c..fb21a900 100644 --- a/ct/zwavejs2mqtt_container.sh +++ b/ct/zwavejs2mqtt_container.sh @@ -14,6 +14,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done +clear function header_info { echo -e "${RD} ______ _ ___ __ __ ____ _______ _______ From 08e037b9fc854c76a4b74a1c520379d2de6d4c7a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 12:57:53 -0500 Subject: [PATCH 1473/6505] Create zwave-copy-data.sh --- misc/zwave-copy-data.sh | 118 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 misc/zwave-copy-data.sh diff --git a/misc/zwave-copy-data.sh b/misc/zwave-copy-data.sh new file mode 100644 index 00000000..94861225 --- /dev/null +++ b/misc/zwave-copy-data.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +# Use to copy all data from one Zwavejs2MQTT LXC to another +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwave-copy-data.sh)" +while true; do + read -p "Use to copy all data from one Zwavejs2MQTT LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Zigbee2MQTT LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Zwavejs2MQTT LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich Zwavejs2MQTT LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.01.23" 13 50 || exit +info "Zwavejs2MQTT Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi +msg "Mounting Container Disks..." +DATA_PATH=/opt/zwavejs2mqtt/store/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ + die "Zwavejs2MQTT directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ + die "Zwavejs2MQTT directories in '$CTID_TO' not found." + +#rm -rf ${CTID_TO_PATH}${DATA_PATH} +#mkdir ${CTID_TO_PATH}${DATA_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Zwavejs2MQTT Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + From b59ba4ec2ab4d486547365e3a303981b4d6125c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 13:57:07 -0500 Subject: [PATCH 1474/6505] Update zwave-copy-data.sh --- misc/zwave-copy-data.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/zwave-copy-data.sh b/misc/zwave-copy-data.sh index 94861225..f2c639ab 100644 --- a/misc/zwave-copy-data.sh +++ b/misc/zwave-copy-data.sh @@ -10,6 +10,7 @@ while true; do * ) echo "Please answer yes or no.";; esac done +clear set -o errexit set -o errtrace set -o nounset From 7185a1436770934c6d45989fe13135d7a275aba2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 13:59:01 -0500 Subject: [PATCH 1475/6505] Update zwave-copy-data.sh --- misc/zwave-copy-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/zwave-copy-data.sh b/misc/zwave-copy-data.sh index f2c639ab..728fbaf7 100644 --- a/misc/zwave-copy-data.sh +++ b/misc/zwave-copy-data.sh @@ -82,7 +82,7 @@ done whiptail --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: 2022.01.23" 13 50 || exit +Version: 2022.03.06" 13 50 || exit info "Zwavejs2MQTT Data from '$CTID_FROM' to '$CTID_TO'" if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then msg "Stopping '$CTID_TO'..." From 18fc82bc59dae52f5cf2d190142f14937fbb17c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 14:29:42 -0500 Subject: [PATCH 1476/6505] Update README.md --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 42228769..f401f267 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **Import Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** +⚙️ **Copy Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** Run in the Proxmox Shell ```yaml @@ -222,7 +222,7 @@ nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **Import Data From a Existing Home Assistant LXC to another Home Assistant LXC** +⚙️ **Copy Data From a Existing Home Assistant LXC to another Home Assistant LXC** Run in the Proxmox Shell ```yaml @@ -675,7 +675,7 @@ Run in the LXC console ```yaml bash /opt/zigbee2mqtt/update.sh ``` -⚙️ **Import Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** +⚙️ **Copy Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** Run in the Proxmox Shell ```yaml @@ -702,6 +702,12 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z **Zwavejs2MQTT Interface - IP:8091** +⚙️ **Copy Data From a Existing Zwavejs2MQTT LXC to another Zwavejs2MQTT LXC** + +Run in the Proxmox Shell +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwave-copy-data.sh)" + ``` ____________________________________________________________________________________________ @@ -900,7 +906,7 @@ Run in the LXC console ```yaml apt update && apt upgrade -y ``` -⚙️ **Import Data From a Existing Plex Media Server LXC to another Plex Media Server LXC** +⚙️ **Copy Data From a Existing Plex Media Server LXC to another Plex Media Server LXC** Run in the Proxmox Shell ```yaml From 20170611c0450e243ab3c35df8d9a17099c1a694 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 14:39:44 -0500 Subject: [PATCH 1477/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3cb88cad..47e4374a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-06 + +### Changed + +- **Zwavejs2MQTT LXC** + - new GUI script to copy data from one Zwavejs2MQTT LXC to another Zwavejs2MQTT LXC + ## 2022-03-05 ### Changed From 37d6fb6e7aabfcf831dffc29289b3598d3f7bb41 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Mar 2022 14:49:17 -0500 Subject: [PATCH 1478/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 47e4374a..f6752f00 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Zwavejs2MQTT LXC** - - new GUI script to copy data from one Zwavejs2MQTT LXC to another Zwavejs2MQTT LXC + - New GUI script to copy data from one Zwavejs2MQTT LXC to another Zwavejs2MQTT LXC ## 2022-03-05 From 651e7579a3b1d445e978388159578a5f405f1a25 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 7 Mar 2022 03:43:20 -0500 Subject: [PATCH 1479/6505] Update debian.sh --- ct/debian.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index 64524773..50ddb664 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -5,8 +5,10 @@ RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +APP="Debian" +HN=$(echo ${APP,,} | tr -d ' ') while true; do - read -p "This will create a New Debian Bulleye LXC. Proceed(y/n)?" yn + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -132,7 +134,7 @@ export PCT_OSVERSION=11 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" -features $FEATURES - -hostname debian + -hostname $HN -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 @@ -152,8 +154,8 @@ echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created Debian Bulleye LXC to${CL} ${BL}$CTID${CL}. \n" +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" From 30b4378eb3daa6662685825957eb5c281d10286d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 7 Mar 2022 10:14:32 -0500 Subject: [PATCH 1480/6505] Update debian.sh --- ct/debian.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ct/debian.sh b/ct/debian.sh index 50ddb664..84bb6977 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -147,6 +147,11 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF echo -en "${GN} Starting LXC Container... " pct start $CTID From 91c40b3818971ec7ff6c0008cdfebfe08f9fa92b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 7 Mar 2022 10:23:29 -0500 Subject: [PATCH 1481/6505] Update ubuntu.sh --- ct/ubuntu.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 010b9738..538c93a4 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -145,6 +145,11 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF echo -en "${GN} Starting LXC Container... " pct start $CTID From f6679ae12fb1d3034d4416ed1af8999708d0d901 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:30:26 -0500 Subject: [PATCH 1482/6505] Update debian-install.sh --- setup/debian-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 795d7800..079842d3 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -59,6 +59,8 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -73,7 +75,8 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" - + fi + echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null apt-get autoclean >/dev/null From c70f89ae21449f04600f8f07ac49cfc417688600 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:32:36 -0500 Subject: [PATCH 1483/6505] Update debian.sh --- ct/debian.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index 84bb6977..ab032e13 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -38,8 +38,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -72,6 +72,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -140,6 +184,7 @@ export PCT_OPTIONS=" -cores 1 -memory 512 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 33416008e03e2a94670dac825d19735a4eec58d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:48:31 -0500 Subject: [PATCH 1484/6505] Update adguard-install.sh --- setup/adguard-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 0b411892..b1fad316 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -63,6 +63,8 @@ echo -en "${GN} Installing AdGuard Home... " curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -77,6 +79,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 0b5d1a669e31a7e19476bb9323fa29a6082f230f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:49:39 -0500 Subject: [PATCH 1485/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index c05e06e8..5eacd342 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -65,6 +65,8 @@ wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_am sudo dpkg -i daemonsync_2.2.0.0059_amd64.deb &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -79,6 +81,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From a01c715f9572bae644c891f3e9062e4cb787cd69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:50:19 -0500 Subject: [PATCH 1486/6505] Update dashy-install.sh --- setup/dashy-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 15065741..a06a3f3b 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -96,6 +96,8 @@ sudo systemctl start dashy &>/dev/null sudo systemctl enable dashy &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -110,6 +112,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 4d56a72b1f81d629f7d8baf4e4976607ba7706ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:51:10 -0500 Subject: [PATCH 1487/6505] Update grafana-install.sh --- setup/grafana-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index be34f222..f14f16ea 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -72,6 +72,8 @@ apt-get update &>/dev/null apt-get install -y grafana &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -84,10 +86,9 @@ ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF systemctl daemon-reload -systemctl start grafana-server -systemctl enable grafana-server.service &>/dev/null systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 1e71aa0b715d6e676866a068c2c67bc89442e363 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:52:33 -0500 Subject: [PATCH 1488/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index d7aa94b2..820c5185 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -291,6 +291,8 @@ EOF sudo chmod +x /root/update-containers.sh echo -e "${CM}${CL} \r" mkdir /root/hass_config +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -305,6 +307,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From ef67a5ec93b5ec53b6c97ad6ae1c0dfcda8b5f96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:53:07 -0500 Subject: [PATCH 1489/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 7568ec1d..fb0b5eab 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -75,6 +75,8 @@ echo -en "${GN} Creating Homebridge Service... " sudo hb-service install --user homebridge &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -89,6 +91,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 7809a86e86f5882337412f0ecc3424453654ec67 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:53:45 -0500 Subject: [PATCH 1490/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index dfb55c81..bdff8c5a 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -76,6 +76,8 @@ echo -en "${GN} Installing Telegraf... " apt-get install -y telegraf &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -89,8 +91,8 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -systemctl enable --now influxdb echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From cfdf3cf8c4df77aab77d1479cb59d723ca40ca84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:54:30 -0500 Subject: [PATCH 1491/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index ba82d3b1..27b84f15 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -71,6 +71,8 @@ sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -83,8 +85,9 @@ ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From e7740243d437cbe644269992db8350ad7a876350 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:55:22 -0500 Subject: [PATCH 1492/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 8ed686a2..b30943fe 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -70,6 +70,8 @@ apt-get -y install mosquitto &>/dev/null apt-get -y install mosquitto-clients &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -84,6 +86,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 642f92f266987b45569599521b06f5db49476b39 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:56:30 -0500 Subject: [PATCH 1493/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index b194c53f..f34628ae 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -217,6 +217,8 @@ WantedBy=multi-user.target EOF echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -231,6 +233,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Starting Services... " systemctl enable npm &>/dev/null From 16c32dd1f3c666c3ed67f02d56ce8ac42bc62062 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:57:10 -0500 Subject: [PATCH 1494/6505] Update node-red-install.sh --- setup/node-red-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index ab40fab4..a88bf399 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -64,6 +64,8 @@ sudo systemctl enable nodered.service &>/dev/null sudo systemctl start nodered.service &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -78,6 +80,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 50a7d4f7e0dcd9ef68f8ec335aa8488c61fa1568 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 09:58:56 -0500 Subject: [PATCH 1495/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index c2c89763..15c62c0c 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -59,6 +59,8 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " chmod -x /etc/update-motd.d/* touch ~/.hushlogin @@ -72,6 +74,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 20df47fdbe01d77f9773e5a34b11844975dfc5b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:00:53 -0500 Subject: [PATCH 1496/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 9aee5a05..3574a71e 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -81,6 +81,8 @@ chmod +x install.sh ./install.sh --unattended options.conf &>/dev/null echo -e "${CM}${CL} \r" +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -95,6 +97,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 9ee7a455185b8ffbf1cfdde1e856011238da93ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:01:36 -0500 Subject: [PATCH 1497/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index f36d52ef..d2d0742c 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -90,6 +90,8 @@ User=root [Install] WantedBy=multi-user.target" > $service_path +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " rm /etc/motd rm /etc/update-motd.d/10-uname @@ -104,6 +106,7 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" + fi echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null From 28cce8d24cc9880c329fb26467fa49ca7f2fd85a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:04:30 -0500 Subject: [PATCH 1498/6505] Update ubuntu.sh --- ct/ubuntu.sh | 57 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 538c93a4..9c8ef3be 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -27,18 +27,6 @@ ${CL}" } header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" -} show_menu while [ $opt != '' ] do @@ -70,6 +58,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -138,6 +170,7 @@ export PCT_OPTIONS=" -cores 1 -memory 512 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From fd5e8a5540ffd65e4f22f5f846eded0dd2fd5847 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:08:20 -0500 Subject: [PATCH 1499/6505] Update ubuntu.sh --- ct/ubuntu.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 9c8ef3be..61dc62c7 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -27,6 +27,18 @@ ${CL}" } header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} show_menu while [ $opt != '' ] do From 1ad7e816df0a2fded7c80a05d2f7a2c0befa4328 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:32:51 -0500 Subject: [PATCH 1500/6505] Update adguard.sh --- ct/adguard.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index baf27373..28d5823f 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -39,8 +39,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -73,6 +73,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace set -o nounset @@ -140,6 +184,7 @@ export PCT_OPTIONS=" -cores 1 -memory 512 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 6b104bdceb5b1430c07277592e55dbc8889e85f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:34:14 -0500 Subject: [PATCH 1501/6505] Update daemonsync.sh --- ct/daemonsync.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index ea718383..d35540c7 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -37,8 +37,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -71,6 +71,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -139,6 +183,7 @@ export PCT_OPTIONS=" -cores 1 -memory 512 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 4ad44e709583d12a788def9ec63b2242bd049c45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:35:43 -0500 Subject: [PATCH 1502/6505] Update dashy.sh --- ct/dashy.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index 25cab4a1..0e5dd77a 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -38,8 +38,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -72,6 +72,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -140,6 +184,7 @@ export PCT_OPTIONS=" -cores 2 -memory 2048 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 8fc98568ed5c5258d303e2f2ec3efadd68721475 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:36:45 -0500 Subject: [PATCH 1503/6505] Update grafana.sh --- ct/grafana.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/grafana.sh b/ct/grafana.sh index ffca9ac8..45d795d9 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -36,8 +36,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -70,6 +70,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -138,6 +182,7 @@ export PCT_OPTIONS=" -cores 1 -memory 512 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From ae6794de2d3dd08517fe516742448469503c403e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:38:06 -0500 Subject: [PATCH 1504/6505] Update homeassistant.sh --- ct/homeassistant.sh | 49 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 1204f5ef..07c6b1fd 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -36,8 +36,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -70,6 +70,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -138,6 +182,7 @@ export PCT_OPTIONS=" -cores 2 -memory 2048 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 8b1e3ac646972a9e0d881cbbb346d495e0fe31eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:39:14 -0500 Subject: [PATCH 1505/6505] Update homebridge.sh --- ct/homebridge.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index e54dd7b6..ba22de14 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -35,8 +35,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -69,6 +69,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -137,6 +181,7 @@ export PCT_OPTIONS=" -cores 1 -memory 1024 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 61ef881908b7a391433d29cf36e556e486294e50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:40:23 -0500 Subject: [PATCH 1506/6505] Update influxdb.sh --- ct/influxdb.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 0c60af4b..0212b927 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -36,8 +36,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -70,6 +70,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -138,6 +182,7 @@ export PCT_OPTIONS=" -cores 2 -memory 2048 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 9ad1e29239e1d5f79c17260df95bf4fc590903ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:41:41 -0500 Subject: [PATCH 1507/6505] Update mariadb.sh --- ct/mariadb.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 72c13d74..e0e3e666 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -36,8 +36,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -70,6 +70,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -138,6 +182,7 @@ export PCT_OPTIONS=" -cores 1 -memory 1024 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 451876559e997fd2cd9ab5e2a785aaeae17a8f46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:42:54 -0500 Subject: [PATCH 1508/6505] Update mqtt.sh --- ct/mqtt.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 18661d83..34e0f249 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -36,8 +36,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -70,6 +70,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -138,6 +182,7 @@ export PCT_OPTIONS=" -cores 1 -memory 512 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 27f7fe5e1dc3962e2da704bd60fcdf06c7cf3e45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:43:57 -0500 Subject: [PATCH 1509/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 49 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index d62b23c4..34c8bc4d 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -38,8 +38,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -72,6 +72,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -140,6 +184,7 @@ export PCT_OPTIONS=" -cores 1 -memory 1024 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 119f422e596a51814236ba4b69fda62ff263aff2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:45:16 -0500 Subject: [PATCH 1510/6505] Update node-red.sh --- ct/node-red.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index aeb0574a..6a72554d 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -36,8 +36,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -70,6 +70,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -138,6 +182,7 @@ export PCT_OPTIONS=" -cores 1 -memory 1024 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From ea29ae8d63e65a9d16a884c3c124bd996dfb8771 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:46:51 -0500 Subject: [PATCH 1511/6505] Update wireguard.sh --- ct/wireguard.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index de7e47a7..0f88d4e8 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -35,8 +35,8 @@ show_menu(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -69,6 +69,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -137,6 +181,7 @@ export PCT_OPTIONS=" -cores 1 -memory 512 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From 7a135349d5ccb684d20aca38c8295b034730a95c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 10:47:45 -0500 Subject: [PATCH 1512/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 53 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 65013d29..56e8bccb 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -30,16 +30,16 @@ ${CL}" header_info show_menu(){ - printf " ${YW} 1)${GN} Privileged ${CL}\n" -# printf " ${YW} 2)${RD} Unprivileged ${CL}\n" + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." read opt } option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message}${CL}\n" + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" } show_menu while [ $opt != '' ] @@ -72,6 +72,50 @@ while [ $opt != '' ] esac fi done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -140,6 +184,7 @@ export PCT_OPTIONS=" -cores 2 -memory 1024 -unprivileged ${IM} + ${PW} " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit From d2e800a7d83d4212e225ce91d7da04ae3de83db6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 11:02:20 -0500 Subject: [PATCH 1513/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f6752f00..aaa2a48e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-08 + +### Changed + +- **Some Scripts** (eventually all) + - Choose between Automatic or Password Login + ## 2022-03-06 ### Changed From dc8e765e448c7fabd65236e13351f670cf06d0c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 11:28:58 -0500 Subject: [PATCH 1514/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f401f267..341e493b 100644 --- a/README.md +++ b/README.md @@ -1028,7 +1028,7 @@ ________________________________________________________________________________
    - 🔸Daemon Sync Server LXC + Daemon Sync Server LXC

    From 81ff8e37441e1f6bc8c1b251e23647c06a008ce6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 13:09:41 -0500 Subject: [PATCH 1515/6505] Create esphome.sh --- ct/esphome.sh | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 ct/esphome.sh diff --git a/ct/esphome.sh b/ct/esphome.sh new file mode 100644 index 00000000..c1aed58f --- /dev/null +++ b/ct/esphome.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="ESPHome" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + ______ _____ _____ _ _ ____ __ __ ______ + | ____|/ ____| __ \| | | |/ __ \| \/ | ____| + | |__ | (___ | |__) | |__| | | | | \ / | |__ + | __| \___ \| ___/| __ | | | | |\/| | __| + | |____ ____) | | | | | | |__| | | | | |____ + |______|_____/|_| |_| |_|\____/|_| |_|______| + +{CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 1024 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:6052${CL} \n" From 36784297561dc36125a1f358f27495d0a9c12b5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 13:13:17 -0500 Subject: [PATCH 1516/6505] Create esphome-install.sh --- setup/esphome-install.sh | 111 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 setup/esphome-install.sh diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh new file mode 100644 index 00000000..9f5b1ca4 --- /dev/null +++ b/setup/esphome-install.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing pip3... " +apt-get install python3-pip -y &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing ESPHome... " +pip3 install esphome &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing ESPHome Dashboard... " +pip3 install tornado esptool &>/dev/null + +service_path="/etc/systemd/system/esphomeDashboard.service" +echo "[Unit] +Description=ESPHome Dashboard +After=network.target +[Service] +ExecStart=/usr/local/bin/esphome /root/config/ dashboard +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable esphomeDashboard.service &>/dev/null +systemctl start esphomeDashboard +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 986d96239f948069b48fa581b3edf8b3990acfc6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 13:15:50 -0500 Subject: [PATCH 1517/6505] Update esphome.sh --- ct/esphome.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index c1aed58f..f3e8f556 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -25,7 +25,7 @@ echo -e "${RD} | |____ ____) | | | | | | |__| | | | | |____ |______|_____/|_| |_| |_|\____/|_| |_|______| -{CL}" +${CL}" } header_info From 800bac5bb1705d0ce915ff8d4ce1264a89a23b0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 13:25:19 -0500 Subject: [PATCH 1518/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 341e493b..86516547 100644 --- a/README.md +++ b/README.md @@ -322,7 +322,7 @@ Update from the Homebridge UI
    -ESPHome LXC + 🔸ESPHome LXC

    @@ -331,7 +331,7 @@ Update from the Homebridge UI To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    From 85678e4909ea11f30b2e4f372c8b1e5a42341c90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 13:27:58 -0500 Subject: [PATCH 1519/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index aaa2a48e..88efe861 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Some Scripts** (eventually all) - Choose between Automatic or Password Login +- **ESPHome LXC** + - New V2 Install Script ## 2022-03-06 From d1c0b65f514be6e6c4c536d5d35c01690c87564c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 13:45:06 -0500 Subject: [PATCH 1520/6505] Create vaultwarden.sh --- ct/vaultwarden.sh | 213 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 ct/vaultwarden.sh diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh new file mode 100644 index 00000000..aeb4e83f --- /dev/null +++ b/ct/vaultwarden.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Vaultwarden" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + __ __ _ _ _ + \ \ / / | | | | | + \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ + \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ + \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | + \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| + +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 4 + -memory 4096 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From 932e8b3ff924aa4087833a3ebf7d93f753c60384 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 13:46:15 -0500 Subject: [PATCH 1521/6505] Create vaultwarden-install.sh --- setup/vaultwarden-install.sh | 172 +++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 setup/vaultwarden-install.sh diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh new file mode 100644 index 00000000..f5ffa455 --- /dev/null +++ b/setup/vaultwarden-install.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + git \ + nano \ + wget \ + htop \ + pkg-config \ + openssl \ + libssl1.1 \ + libssl-dev \ + curl \ + sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Build Essentials... " +apt-get install -y build-essential &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Rust... " +curl https://sh.rustup.rs -sSf | sh -s -- -y &>/dev/null +echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null +export PATH=~/.cargo/bin:$PATH &>/dev/null +which rustc &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +apt-get install -y nodejs &>/dev/null +npm -g install npm@7 &>/dev/null +which npm &>/dev/null +npm i npm@latest -g &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Building Vaultwarden (Patience)... " +git clone https://github.com/dani-garcia/vaultwarden &>/dev/null +pushd vaultwarden &>/dev/null +cargo clean &>/dev/null +cargo build --features sqlite --release &>/dev/null +file target/release/vaultwarden &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Building Web-Vault... " +pushd target/release/ &>/dev/null +git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null +cd web-vault.git &>/dev/null +git checkout v2.25.1 &>/dev/null +git submodule update --init --recursive &>/dev/null +wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null +git apply v2.25.0.patch &>/dev/null +npm ci --silent --legacy-peer-deps &>/dev/null +npm audit fix --silent --legacy-peer-deps || true &>/dev/null +npm run --silent dist:oss:selfhost &>/dev/null +cp -a build ../web-vault &>/dev/null +cd .. +mkdir data +echo -e "${CM}${CL} \r" + +echo -en "${GN} Create Systemd Service... " +cp ../../.env.template /etc/vaultwarden.env &>/dev/null +cp vaultwarden /usr/bin/vaultwarden &>/dev/null +chmod +x /usr/bin/vaultwarden &>/dev/null +useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null +sudo cp -R data /var/lib/vaultwarden/ &>/dev/null +cp -R web-vault /var/lib/vaultwarden/ &>/dev/null +chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null + +service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null + +echo "[Unit] +Description=Bitwarden Server (Powered by Vaultwarden) +Documentation=https://github.com/dani-garcia/vaultwarden +After=network.target +[Service] +User=vaultwarden +Group=vaultwarden +EnvironmentFile=/etc/vaultwarden.env +ExecStart=/usr/bin/vaultwarden +LimitNOFILE=1048576 +LimitNPROC=64 +PrivateTmp=true +PrivateDevices=true +ProtectHome=true +ProtectSystem=strict +WorkingDirectory=/var/lib/vaultwarden +ReadWriteDirectories=/var/lib/vaultwarden +AmbientCapabilities=CAP_NET_BIND_SERVICE +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable vaultwarden.service &>/dev/null +systemctl start vaultwarden.service &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 3b603268612d054cff4238161c9765a948b9dd72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 14:37:16 -0500 Subject: [PATCH 1522/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index f5ffa455..c01def0f 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ set -o errexit set -o errtrace @@ -97,19 +100,9 @@ file target/release/vaultwarden &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Building Web-Vault... " -pushd target/release/ &>/dev/null -git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null -cd web-vault.git &>/dev/null -git checkout v2.25.1 &>/dev/null -git submodule update --init --recursive &>/dev/null -wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null -git apply v2.25.0.patch &>/dev/null -npm ci --silent --legacy-peer-deps &>/dev/null -npm audit fix --silent --legacy-peer-deps || true &>/dev/null -npm run --silent dist:oss:selfhost &>/dev/null -cp -a build ../web-vault &>/dev/null -cd .. -mkdir data +wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null +tar -xzf bw_web_$VWRELEASE.tar.gz &>/dev/null +cp -R web-vault /var/lib/vaultwarden/ &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Create Systemd Service... " @@ -143,6 +136,7 @@ ReadWriteDirectories=/var/lib/vaultwarden AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target" > $service_path +systemctl daemon-reload systemctl enable vaultwarden.service &>/dev/null systemctl start vaultwarden.service &>/dev/null echo -e "${CM}${CL} \r" From 0b2d9b36c949ccf507516027f10e7d2dba1440a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 14:50:54 -0500 Subject: [PATCH 1523/6505] Update README.md --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 86516547..a81c86d1 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ ________________________________________________________________________________

    Home Assistant Container LXC

    With ZFS Filesystem Support

    -To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell. +To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/homeassistant.sh)" @@ -273,7 +273,7 @@ ________________________________________________________________________________

    Homebridge LXC

    Homebridge allows you to integrate with smart home devices that do not natively support HomeKit -To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. +To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/homebridge.sh)" @@ -328,7 +328,7 @@ Update from the Homebridge UI

    ESPHome LXC

    -To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. +To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome.sh)" @@ -359,7 +359,7 @@ ________________________________________________________________________________

    Nginx Proxy Manager LXC

    -To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/nginx-proxy-manager.sh)" @@ -409,7 +409,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc

    MQTT LXC

    -To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. +To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt.sh)" @@ -460,7 +460,7 @@ ________________________________________________________________________________

    Node-Red LXC

    -To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. +To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red.sh)" @@ -502,7 +502,7 @@ ________________________________________________________________________________

    Mariadb LXC

    -To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. +To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb.sh)" @@ -614,7 +614,7 @@ ________________________________________________________________________________

    Zigbee2MQTT LXC

    -To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. +To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt.sh)" @@ -720,7 +720,7 @@ ________________________________________________________________________________

    InfluxDB/Telegraf LXC

    -To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. +To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/influxdb.sh)" @@ -762,7 +762,7 @@ ________________________________________________________________________________

    Grafana LXC

    -To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. +To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/grafana.sh)" @@ -803,7 +803,7 @@ ________________________________________________________________________________

    Debian 11 LXC

    -To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell. +To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian.sh)" @@ -832,7 +832,7 @@ ________________________________________________________________________________

    Ubuntu 21.10 LXC

    -To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell. +To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu.sh)" @@ -983,7 +983,7 @@ ________________________________________________________________________________

    AdGuard Home LXC

    -To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. +To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard.sh)" @@ -1014,7 +1014,7 @@ ________________________________________________________________________________ Dashy helps you organize your self-hosted services by making them accessible from a single place -To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell. +To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/dashy.sh)" @@ -1036,7 +1036,7 @@ ________________________________________________________________________________ Sync files from app to server, share photos & videos, back up your data and stay secure inside local network. -To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell. +To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/daemonsync.sh)" @@ -1146,7 +1146,7 @@ ________________________________________________________________________________

    WireGuard LXC

    -To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell. +To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell (V2). ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/wireguard.sh)" From 08d05a4812dac0bb9fc037c5f9a6292e4782350d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 14:59:55 -0500 Subject: [PATCH 1524/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 88efe861..7c608a0d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **Some Scripts** (eventually all) +- **Some Scripts** (eventually all V2) - Choose between Automatic or Password Login - **ESPHome LXC** - New V2 Install Script From 81e4f52150c556660acbc4befd6601c0c5054456 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:01:00 -0500 Subject: [PATCH 1525/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 56e8bccb..bd9cba13 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -30,8 +30,8 @@ ${CL}" header_info show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + printf " ${YW} 1)${GN} Privileged ${CL}\n" + printf " ${YW} 2)${RD} Unprivileged (no device passthrough) ${CL}\n" printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." read opt From 696cc64c883f3e18f377b5d8630adadf5543cfd1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:09:45 -0500 Subject: [PATCH 1526/6505] Create zwavejs2mqtt.sh --- ct/zwavejs2mqtt.sh | 220 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 ct/zwavejs2mqtt.sh diff --git a/ct/zwavejs2mqtt.sh b/ct/zwavejs2mqtt.sh new file mode 100644 index 00000000..2c94a824 --- /dev/null +++ b/ct/zwavejs2mqtt.sh @@ -0,0 +1,220 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Zwavejs2MQTT" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + ______ _ ___ __ __ ____ _______ _______ + |___ / (_) |__ \| \/ |/ __ \__ __|__ __| + / /_ ____ ___ _____ _ ___ ) | \ / | | | | | | | | + / /\ \ /\ / / _ \ \ / / _ \ / __| / /| |\/| | | | | | | | | + / /__\ V V / (_| |\ V / __/ \__ \/ /_| | | | |__| | | | | | + /_____|\_/\_/ \__,_| \_/ \___| |___/____|_| |_|\___\_\ |_| |_| + _/ | + |__/ +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${GN} Privileged ${CL}\n" + printf " ${YW} 2)${RD} Unprivileged (no device passthrough) ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 1024 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8091${CL} \n" From ad34bddc45685c6167fcd9f9b86cc096284d8000 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:10:59 -0500 Subject: [PATCH 1527/6505] Create zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 119 ++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 setup/zwavejs2mqtt-install.sh diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh new file mode 100644 index 00000000..5e5050b6 --- /dev/null +++ b/setup/zwavejs2mqtt-install.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo \ + unzip &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null + echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing yarn... " +npm install --global yarn &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Build/Install Zwavejs2MQTT (5-6 min)... " +sudo git clone https://github.com/zwave-js/zwavejs2mqtt /opt/zwavejs2mqtt &>/dev/null +cd /opt/zwavejs2mqtt &>/dev/null +yarn install &>/dev/null +yarn run build &>/dev/null +echo -e "${CM}${CL} \r" +echo -en "${GN} Creating Service file zwavejs2mqtt.service... " +service_path="/etc/systemd/system/zwavejs2mqtt.service" + +echo "[Unit] +Description=zwavejs2mqtt +After=network.target +[Service] +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zwavejs2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path +systemctl start zwavejs2mqtt +systemctl enable zwavejs2mqtt &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 3e33a762d6f2f44ac46270430e851d6243a6e8d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:27:11 -0500 Subject: [PATCH 1528/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a81c86d1..5715bd52 100644 --- a/README.md +++ b/README.md @@ -687,16 +687,16 @@ ________________________________________________________________________________
    - Zwavejs2MQTT LXC + 🔸Zwavejs2MQTT LXC

    Zwavejs2MQTT LXC

    -To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell. +To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zwavejs2mqtt_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zwavejs2mqtt.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    From 912f9b0ef0764a5a57c731046e338110790a9fde Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:28:23 -0500 Subject: [PATCH 1529/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7c608a0d..16d391a7 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file. - Choose between Automatic or Password Login - **ESPHome LXC** - New V2 Install Script +- **Zwavejs2MQTT LXC** + - New V2 Install Script ## 2022-03-06 From 44fa275ac79185d62e409edb94f70eeaa0b00973 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:38:42 -0500 Subject: [PATCH 1530/6505] Create motioneye.sh --- ct/motioneye.sh | 214 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 ct/motioneye.sh diff --git a/ct/motioneye.sh b/ct/motioneye.sh new file mode 100644 index 00000000..273c7bd6 --- /dev/null +++ b/ct/motioneye.sh @@ -0,0 +1,214 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Motioneye" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + __ __ _ _ ______ + | \/ | | | (_) | ____| + | \ / | ___ | |_ _ ___ _ __ | |__ _ _ ___ + | |\/| |/ _ \| __| |/ _ \| _ \| __|| | | |/ _ \ + | | | | (_) | |_| | (_) | | | | |___| |_| | __/ + |_| |_|\___/ \__|_|\___/|_| |_|______\__, |\___| + __/ | + |___/ +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8765${CL} \n" From 93008f3bb0e5ad4992128ae1c750decc9447ebbf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:39:37 -0500 Subject: [PATCH 1531/6505] Create motioneye-install.sh --- setup/motioneye-install.sh | 114 +++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 setup/motioneye-install.sh diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh new file mode 100644 index 00000000..24aa68bf --- /dev/null +++ b/setup/motioneye-install.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Motion... " + apt-get install motion -y &>/dev/null + systemctl stop motion &>/dev/null + systemctl disable motion &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing FFmpeg... " + apt-get install ffmpeg v4l-utils -y &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Python... " + apt-get update &>/dev/null + apt-get install python2 -y &>/dev/null + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null + python2 get-pip.py &>/dev/null + apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null + apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null + echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing MotionEye... " + apt-get update &>/dev/null + sudo pip install motioneye &>/dev/null + mkdir -p /etc/motioneye + cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf + mkdir -p /var/lib/motioneye +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Service file motioneye.service... " + cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service &>/dev/null + systemctl enable motioneye &>/dev/null + systemctl start motioneye +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 22471edc58b42c30a8a2fddfad69bbb5ed4cd4f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:42:11 -0500 Subject: [PATCH 1532/6505] Update motioneye.sh --- ct/motioneye.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 273c7bd6..1089429c 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -18,14 +18,12 @@ done clear function header_info { echo -e "${RD} - __ __ _ _ ______ - | \/ | | | (_) | ____| - | \ / | ___ | |_ _ ___ _ __ | |__ _ _ ___ - | |\/| |/ _ \| __| |/ _ \| _ \| __|| | | |/ _ \ - | | | | (_) | |_| | (_) | | | | |___| |_| | __/ - |_| |_|\___/ \__|_|\___/|_| |_|______\__, |\___| - __/ | - |___/ + __ __ ____ _______ _____ ____ _ _ ________ ________ + | \/ |/ __ \__ __|_ _/ __ \| \ | | ____\ \ / / ____| + | \ / | | | | | | | || | | | \| | |__ \ \_/ /| |__ + | |\/| | | | | | | | || | | | | __| \ / | __| + | | | | |__| | | | _| || |__| | |\ | |____ | | | |____ + |_| |_|\____/ |_| |_____\____/|_| \_|______| |_| |______| ${CL}" } From 2687ae3738ee7369fa8444b3d1b4647840af2586 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:46:36 -0500 Subject: [PATCH 1533/6505] Update motioneye.sh --- ct/motioneye.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 1089429c..88bf00ba 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -17,7 +17,7 @@ while true; do done clear function header_info { -echo -e "${RD} +echo -e "${BL} __ __ ____ _______ _____ ____ _ _ ________ ________ | \/ |/ __ \__ __|_ _/ __ \| \ | | ____\ \ / / ____| | \ / | | | | | | | || | | | \| | |__ \ \_/ /| |__ From 42f2f803c9113b45cd145c3dd738b86765d108be Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:47:06 -0500 Subject: [PATCH 1534/6505] Update zwavejs2mqtt.sh --- ct/zwavejs2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt.sh b/ct/zwavejs2mqtt.sh index 2c94a824..79ae3129 100644 --- a/ct/zwavejs2mqtt.sh +++ b/ct/zwavejs2mqtt.sh @@ -17,7 +17,7 @@ while true; do done clear function header_info { -echo -e "${RD} +echo -e "${BL} ______ _ ___ __ __ ____ _______ _______ |___ / (_) |__ \| \/ |/ __ \__ __|__ __| / /_ ____ ___ _____ _ ___ ) | \ / | | | | | | | | From ceabb25aa9282e790df56def73b07e38d0865b2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:58:06 -0500 Subject: [PATCH 1535/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5715bd52..b176294d 100644 --- a/README.md +++ b/README.md @@ -1053,16 +1053,16 @@ ________________________________________________________________________________
    - MotionEye NVR LXC + 🔸MotionEye NVR LXC

    MotionEye NVR LXC

    -To create a new Proxmox MotionEye NVR LXC, run the following in the Proxmox Shell. +To create a new Proxmox MotionEye NVR LXC, run the following in the Proxmox Shell (V2). ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/motioneye_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/motioneye.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    From 210e57a8713db62dd0cf73089092d7f6a85ffa85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 16:59:29 -0500 Subject: [PATCH 1536/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 16d391a7..c9a01e1c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. - New V2 Install Script - **Zwavejs2MQTT LXC** - New V2 Install Script +- **Motioneye LXC** + - New V2 Install Script ## 2022-03-06 From 39e5c0f2ba46a6b6f2d4d1b24144771b25161140 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 19:08:09 -0500 Subject: [PATCH 1537/6505] Create pihole.sh --- ct/pihole.sh | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 ct/pihole.sh diff --git a/ct/pihole.sh b/ct/pihole.sh new file mode 100644 index 00000000..33f64f2f --- /dev/null +++ b/ct/pihole.sh @@ -0,0 +1,212 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Pihole" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _ _ _ + | __ (_) | | | | + | |__) | ______| |__ ___ | | ___ + | ___/ |______| _ \ / _ \| |/ _ \ + | | | | | | | | (_) | | __/ + |_| |_| |_| |_|\___/|_|\___| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From 80905de0b1cb1c79e9b46bbc922a0020ba22a8c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 19:09:46 -0500 Subject: [PATCH 1538/6505] Create pihole-install.sh --- setup/pihole-install.sh | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 setup/pihole-install.sh diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh new file mode 100644 index 00000000..b0dfc6e6 --- /dev/null +++ b/setup/pihole-install.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Pi-hole... " +curl -sSL https://install.pi-hole.net | bash +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 409c9aabd3bf4468f3be869801be702c33a49f92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 19:12:49 -0500 Subject: [PATCH 1539/6505] Update pihole.sh --- ct/pihole.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/pihole.sh b/ct/pihole.sh index 33f64f2f..29946fbf 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -18,12 +18,12 @@ done clear function header_info { echo -e "${RD} - _____ _ _ _ - | __ (_) | | | | - | |__) | ______| |__ ___ | | ___ - | ___/ |______| _ \ / _ \| |/ _ \ - | | | | | | | | (_) | | __/ - |_| |_| |_| |_|\___/|_|\___| + _____ _____ _ _ ____ _ ______ + | __ \_ _| | | |/ __ \| | | ____| + | |__) || | | |__| | | | | | | |__ + | ___/ | | | __ | | | | | | __| + | | _| |_| | | | |__| | |____| |____ + |_| |_____|_| |_|\____/|______|______| ${CL}" } From 1543851281700a1aeeb8cd3add35a4f11314f8d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 19:27:48 -0500 Subject: [PATCH 1540/6505] Update pihole-install.sh --- setup/pihole-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index b0dfc6e6..a79208c5 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -57,7 +57,7 @@ apt-get -qqy install \ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Pi-hole... " -curl -sSL https://install.pi-hole.net | bash +curl -sSL https://install.pi-hole.net | bash --unattended echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 00714d953bc06fe0e68e2bd805267ea7913da510 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 19:34:23 -0500 Subject: [PATCH 1541/6505] Update pihole-install.sh --- setup/pihole-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index a79208c5..b30274ee 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -57,7 +57,8 @@ apt-get -qqy install \ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Pi-hole... " -curl -sSL https://install.pi-hole.net | bash --unattended +#curl -sSL https://install.pi-hole.net | bash +curl -L https://install.pi-hole.net | bash /dev/stdin --unattended echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 6125eda7ab1fabbcf29b14b2a6781035e074679c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 19:38:11 -0500 Subject: [PATCH 1542/6505] Update pihole-install.sh --- setup/pihole-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index b30274ee..b0dfc6e6 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -57,8 +57,7 @@ apt-get -qqy install \ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Pi-hole... " -#curl -sSL https://install.pi-hole.net | bash -curl -L https://install.pi-hole.net | bash /dev/stdin --unattended +curl -sSL https://install.pi-hole.net | bash echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 2ff97055757fc2c2d0acf05b0c82b1429489142c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:11:15 -0500 Subject: [PATCH 1543/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b176294d..fa42463f 100644 --- a/README.md +++ b/README.md @@ -944,16 +944,16 @@ ________________________________________________________________________________
    -Pi-hole LXC + 🔸Pi-hole LXC

    Pi-hole LXC

    -To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. +To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/pihole_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/pihole.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    From 924a556c1b29d2728e77328b2f38ebf101268fa2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:12:15 -0500 Subject: [PATCH 1544/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c9a01e1c..ec8a04a1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file. - New V2 Install Script - **Motioneye LXC** - New V2 Install Script +- **Pihole LXC** + - New V2 Install Script ## 2022-03-06 From 3d974556ee8619982b86d5c6262a79848ad1c6bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:19:43 -0500 Subject: [PATCH 1545/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ec8a04a1..87073276 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -29,7 +29,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Homebridge LXC** - - New Script + - New Script V2 ## 2022-03-04 @@ -43,7 +43,7 @@ All notable changes to this project will be documented in this file. ### Changed - **WireGuard LXC** - - New Script + - New Script V2 ## 2022-03-02 @@ -52,18 +52,18 @@ All notable changes to this project will be documented in this file. - **Proxmox LXC Updater** - New Script - **Dashy LXC** - - New Script + - New Script V2 - **Grafana LXC** - - New Script + - New Script V2 - **InfluxDB/Telegraf LXC** - - New Script + - New Script V2 ## 2022-03-01 ### Changed - **Daemon Sync Server LXC** - - New Script + - New Script V2 ## 2022-02-28 @@ -77,16 +77,16 @@ All notable changes to this project will be documented in this file. ### Changed - **Nginx Proxy Manager LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script ## 2022-02-23 ### Changed - **Adguard Home LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script - **Zigbee2MQTT LXC** - - Using NEW Privileged Install Script + - New V2 Install Script - **Home Assistant Container LXC** - Update Menu usability improvements @@ -95,17 +95,17 @@ All notable changes to this project will be documented in this file. ### Changed - **Home Assistant Container LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script - **Node-Red LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script - **Mariadb LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script - **MQTT LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script - **Debian 11 LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script - **Ubuntu 21.10 LXC** - - Using NEW Privileged/Unprivileged Install Script + - New V2 Install Script ## 2022-02-20 From dc9118e8575e7342db8ad1b7dc2619ba91c8a458 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:35:01 -0500 Subject: [PATCH 1546/6505] Update pihole-install.sh --- setup/pihole-install.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index b0dfc6e6..05686f50 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -49,6 +49,11 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " echo -e "${CM}${CL} \r" +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + echo -en "${GN} Installing Dependencies... " apt-get update &>/dev/null apt-get -qqy install \ From 51594a5f76b427e519f8c59bb8c50565da35a26d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:40:31 -0500 Subject: [PATCH 1547/6505] Create gamuntu.sh --- ct/gamuntu.sh | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 ct/gamuntu.sh diff --git a/ct/gamuntu.sh b/ct/gamuntu.sh new file mode 100644 index 00000000..267cba57 --- /dev/null +++ b/ct/gamuntu.sh @@ -0,0 +1,224 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="GamUntu" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${GN} + _____ _ _ _ + / ____| | | | | | | + | | __ __ _ _ __ ___ | | | |_ __ | |_ _ _ + | | |_ |/ _ | _ _ \| | | | _ \| __| | | | + | |__| | (_| | | | | | | |__| | | | | |_| |_| | + \_____|\__,_|_| |_| |_|\____/|_| |_|\__|\__,_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${GN} Privileged ${CL}\n" + printf " ${YW} 2)${RD} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/uinput dev/uinput none bind,optional,create=dir +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}Webmin${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:10000${CL} \n" From 7953a32acb8236b83e4683f8459621d2c8ca3766 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:41:27 -0500 Subject: [PATCH 1548/6505] Create gamuntu-install.sh --- setup/gamuntu-install.sh | 132 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 setup/gamuntu-install.sh diff --git a/setup/gamuntu-install.sh b/setup/gamuntu-install.sh new file mode 100644 index 00000000..4c548d29 --- /dev/null +++ b/setup/gamuntu-install.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=5 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo \ + libnet-ssleay-perl \ + libauthen-pam-perl \ + libio-pty-perl \ + unzip \ + shared-mime-info &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Downloading Webmin... " +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Webmin... " +dpkg --install webmin_1.984_all.deb &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting Default Webmin usermame & password to root... " +/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null +rm -rf /root/webmin_1.984_all.deb +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting Up Hardware Acceleration... " +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Docker... " +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF +sh <(curl -sSL https://get.docker.com) &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Docker Compose... " +sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose &>/dev/null +sudo chmod +x /usr/local/bin/docker-compose +docker network create proxy &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From e4e8514ec7c684db527fc6fe315e84749d46bdce Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:46:50 -0500 Subject: [PATCH 1549/6505] Update gamuntu.sh --- ct/gamuntu.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/gamuntu.sh b/ct/gamuntu.sh index 267cba57..ba02fc55 100644 --- a/ct/gamuntu.sh +++ b/ct/gamuntu.sh @@ -172,8 +172,8 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=21.10 export PCT_DISK_SIZE=8 export PCT_OPTIONS=" -features $FEATURES From c90531ecda4e80b58b612056c2c5ec35d288303e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:47:51 -0500 Subject: [PATCH 1550/6505] Update gamuntu-install.sh --- setup/gamuntu-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/gamuntu-install.sh b/setup/gamuntu-install.sh index 4c548d29..128b2315 100644 --- a/setup/gamuntu-install.sh +++ b/setup/gamuntu-install.sh @@ -110,8 +110,7 @@ echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname +chmod -x /etc/update-motd.d/* touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) From 1b5cbeeeab2c4ccb73bac2b03a1ee71c079b6202 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:53:39 -0500 Subject: [PATCH 1551/6505] Update gamuntu.sh --- ct/gamuntu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/gamuntu.sh b/ct/gamuntu.sh index ba02fc55..b8853e31 100644 --- a/ct/gamuntu.sh +++ b/ct/gamuntu.sh @@ -30,7 +30,7 @@ ${CL}" header_info show_menu(){ printf " ${YW} 1)${GN} Privileged ${CL}\n" - printf " ${YW} 2)${RD} Unprivileged ${CL}\n" + printf " ${YW} 2)${RD} Unprivileged (no device passthrough)${CL}\n" printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." read opt From 95123264faada46e2aa4c38e48d80cb4c7550460 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:57:17 -0500 Subject: [PATCH 1552/6505] Update gamuntu.sh --- ct/gamuntu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/gamuntu.sh b/ct/gamuntu.sh index b8853e31..f01468de 100644 --- a/ct/gamuntu.sh +++ b/ct/gamuntu.sh @@ -221,4 +221,4 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. ${BL}Webmin${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:10000${CL} \n" + ${BL}https://${IP}:10000${CL} \n" From e41d78a5e34001ef7ffb1d079676bb11b5743851 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 20:59:58 -0500 Subject: [PATCH 1553/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fa42463f..2d64f74f 100644 --- a/README.md +++ b/README.md @@ -854,16 +854,16 @@ ________________________________________________________________________________
    - GamUntu LXC + 🔸GamUntu LXC

    GamUntu

    GamUntu LXC

    GamUntu is Ubuntu 21.10, Docker, Docker Compose, ZFS Support, USB Passthrough, Webmin System Administration and Hardware Acceleration all baked in! -To create a new Proxmox GamUntu LXC, run the following in the Proxmox Shell. +To create a new Proxmox GamUntu LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/gamuntu_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/gamuntu.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    From 7fdeddfb7aefd6e6d42869a0c3dca2ed2509c286 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 21:01:06 -0500 Subject: [PATCH 1554/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 87073276..a430f5ac 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -16,6 +16,8 @@ All notable changes to this project will be documented in this file. - New V2 Install Script - **Pihole LXC** - New V2 Install Script +- **GamUntu LXC** + - New V2 Install Script ## 2022-03-06 From 755b1898d112332953d8587772106e3b104e1823 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Mar 2022 22:12:08 -0500 Subject: [PATCH 1555/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a430f5ac..4219af80 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **Some Scripts** (eventually all V2) +- **Scripts** (V2) - Choose between Automatic or Password Login - **ESPHome LXC** - New V2 Install Script From b245d943003db92b95f3293c97039219cccdf89e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Mar 2022 15:00:33 -0500 Subject: [PATCH 1556/6505] Update grafana-install.sh --- setup/grafana-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index f14f16ea..ee6dae77 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -89,7 +89,8 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') echo -e "${CM}${CL} \r" fi - +systemctl start grafana-server +systemctl enable grafana-server.service &>/dev/null echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null apt-get autoclean >/dev/null From eea0ea23921536765e0a6ec8e43a854aa088f9a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Mar 2022 18:34:08 -0500 Subject: [PATCH 1557/6505] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2d64f74f..534b053c 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ ________________________________________________________________________________
    - 🔸Proxmox LXC Updater + Proxmox LXC Updater

    @@ -714,7 +714,7 @@ ________________________________________________________________________________
    - 🔸InfluxDB/Telegraf LXC + InfluxDB/Telegraf LXC

    @@ -756,7 +756,7 @@ ________________________________________________________________________________
    - 🔸Grafana LXC + Grafana LXC

    @@ -1006,7 +1006,7 @@ ________________________________________________________________________________
    - 🔸Dashy LXC + Dashy LXC

    From 27739ae03c3aa56a326ee26ad9b8f863155c258b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 08:58:47 -0500 Subject: [PATCH 1558/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 534b053c..736e87b9 100644 --- a/README.md +++ b/README.md @@ -1140,7 +1140,7 @@ ________________________________________________________________________________
    - 🔸WireGuard LXC + WireGuard LXC

    From 598b2055f0ce1cfac07f5a7fa4a76a399c7833da Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 12:58:43 -0500 Subject: [PATCH 1559/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index c01def0f..48d94bb6 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -100,9 +100,19 @@ file target/release/vaultwarden &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Building Web-Vault... " -wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null -tar -xzf bw_web_$VWRELEASE.tar.gz &>/dev/null -cp -R web-vault /var/lib/vaultwarden/ &>/dev/null +pushd target/release/ &>/dev/null +git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null +cd web-vault.git &>/dev/null +git checkout v2.25.1 &>/dev/null +git submodule update --init --recursive &>/dev/null +wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null +git apply v2.25.0.patch &>/dev/null +npm ci --silent --legacy-peer-deps &>/dev/null +npm audit fix --silent --legacy-peer-deps || true &>/dev/null +npm run --silent dist:oss:selfhost &>/dev/null +cp -a build ../web-vault &>/dev/null +cd .. +mkdir data echo -e "${CM}${CL} \r" echo -en "${GN} Create Systemd Service... " From 921e1fb3d14055988ac64cf3ae20eb03dd5abc10 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 14:57:49 -0500 Subject: [PATCH 1560/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index b30943fe..fe1a5ce2 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -28,8 +28,8 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 +RETRY_NUM=15 +RETRY_EVERY=5 NUM=$RETRY_NUM echo -en "${GN} Setting up Container OS... " From 8f58dacaaba00b603efbeae40f82293f53f96349 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 16:15:17 -0500 Subject: [PATCH 1561/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index fe1a5ce2..b30943fe 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -28,8 +28,8 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=15 -RETRY_EVERY=5 +RETRY_NUM=5 +RETRY_EVERY=3 NUM=$RETRY_NUM echo -en "${GN} Setting up Container OS... " From 8ff61f0cde0c311fe46252e2b6532d05a1e2f760 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 19:32:38 -0500 Subject: [PATCH 1562/6505] Update homeassistant.sh --- ct/homeassistant.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 07c6b1fd..b5781d86 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -188,7 +188,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 +# wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf @@ -199,10 +199,10 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID -if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -info "${BL}Using fuse-overlayfs.${CL}" -fi +#if [ "$STORAGE_TYPE" == "zfspool" ]; then +#pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +#info "${BL}Using fuse-overlayfs.${CL}" +#fi echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" From 18e6170b040a9b1a8445d7ab438622318116e3b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 21:19:50 -0500 Subject: [PATCH 1563/6505] Update homeassistant.sh --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index b5781d86..488f64a8 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -173,7 +173,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 +export PCT_DISK_SIZE=16 export PCT_OPTIONS=" -features $FEATURES -hostname homeassistant From 4643ccd538f15b232bc00cb1bab606b06f6d2d2b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:02:20 -0500 Subject: [PATCH 1564/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 736e87b9..bd6a54e1 100644 --- a/README.md +++ b/README.md @@ -195,14 +195,14 @@ ________________________________________________________________________________ @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    Home Assistant Container LXC

    -

    With ZFS Filesystem Support

    + To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/homeassistant.sh)" ``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    +

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. From 9cd5f937fe8719406e7dd12c4a15d19e2e52e635 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:06:29 -0500 Subject: [PATCH 1565/6505] Update homeassistant.sh --- ct/homeassistant.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 488f64a8..b5c80952 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -188,7 +188,6 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then -# wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf @@ -199,10 +198,6 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID -#if [ "$STORAGE_TYPE" == "zfspool" ]; then -#pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -#info "${BL}Using fuse-overlayfs.${CL}" -#fi echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" From d3e61381d562657a509655919922d577994a9166 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:17:53 -0500 Subject: [PATCH 1566/6505] Update adguard-install.sh --- setup/adguard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index b1fad316..a920546f 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 456d36f99fcad250d26693af4a4f43c7c670ce36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:18:27 -0500 Subject: [PATCH 1567/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 5eacd342..077c9f91 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 14f48601369bd08f8030011ec00cf8d3ac6af95f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:18:52 -0500 Subject: [PATCH 1568/6505] Update dashy-install.sh --- setup/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index a06a3f3b..003b87c1 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 77b4cacd36f13c67fc6fb17470edbd1bd837303a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:19:18 -0500 Subject: [PATCH 1569/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 079842d3..3e7149c7 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From b58fe086d9d1b56ecdbedbcb9f28ed69cc364b48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:19:43 -0500 Subject: [PATCH 1570/6505] Update esphome-install.sh --- setup/esphome-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 9f5b1ca4..6311925e 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From d51e79128df57ab68e6ab186f816e0e66c208146 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:20:15 -0500 Subject: [PATCH 1571/6505] Update gamuntu-install.sh --- setup/gamuntu-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/gamuntu-install.sh b/setup/gamuntu-install.sh index 128b2315..46efea00 100644 --- a/setup/gamuntu-install.sh +++ b/setup/gamuntu-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 7dc73abbb9f247cb07f94749dd4630e09f0e30a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:20:49 -0500 Subject: [PATCH 1572/6505] Update grafana-install.sh --- setup/grafana-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index ee6dae77..e683a417 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From c8faaeb178f5ce9d4e2394e4910a7fc18f4fe176 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:21:18 -0500 Subject: [PATCH 1573/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 820c5185..1b40a48a 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 054d41d173803595c7df87b66d357f518533cc31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:21:45 -0500 Subject: [PATCH 1574/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index fb0b5eab..61c8178e 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 2f929890b852e79dbbbe71bb286fae6fa3fc7fb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:22:12 -0500 Subject: [PATCH 1575/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index bdff8c5a..6f592dda 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From d4e40ebf4d1b8f7434d38c01fad9b009c1748047 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:22:58 -0500 Subject: [PATCH 1576/6505] Update jellyfin_setup.sh --- setup/jellyfin_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh index 2588e6e4..0f7a2549 100644 --- a/setup/jellyfin_setup.sh +++ b/setup/jellyfin_setup.sh @@ -9,7 +9,7 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM trap 'die "Script interrupted."' INT From f5e7830c5e9ebe1d4a7d0ab7a0ed138ef8da8b73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:23:27 -0500 Subject: [PATCH 1577/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 27b84f15..4d738ba0 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 7a749809d93e2c14a5d04f22759d7a504aea7215 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:23:55 -0500 Subject: [PATCH 1578/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 24aa68bf..8a8393e9 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From a8654194abb704624cece168e3a8153cfaf69e17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:24:24 -0500 Subject: [PATCH 1579/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index b30943fe..59202b35 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From d2bdba11b00e448943d8d8bb3cd0f706b5653f99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:24:52 -0500 Subject: [PATCH 1580/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index f34628ae..00df49be 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 3c653ba9fad90b5d34b5ec17e8c0c8eef4ca9036 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:25:22 -0500 Subject: [PATCH 1581/6505] Update node-red-install.sh --- setup/node-red-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index a88bf399..f68c5e32 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM echo -en "${GN} Setting up Container OS... " From 157d5380fe372c75c2d12fc9513c73b225afbc2b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:25:55 -0500 Subject: [PATCH 1582/6505] Update pihole-install.sh --- setup/pihole-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 05686f50..74eae09a 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From f84984930360dd003bde0ca079127ffcadfb61cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:26:26 -0500 Subject: [PATCH 1583/6505] Update plex_setup.sh --- setup/plex_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh index 120fbbdf..8d10d71a 100644 --- a/setup/plex_setup.sh +++ b/setup/plex_setup.sh @@ -8,7 +8,7 @@ shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM trap die ERR From 0a77e288e4fa04b9c21d5e2b48f6daf733d51fda Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:27:07 -0500 Subject: [PATCH 1584/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index ebafa0df..83dbb60e 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 8c639813af7a20efc979b469dbf6aef1ef198b0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:27:32 -0500 Subject: [PATCH 1585/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 15c62c0c..c3bbca0f 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From d9b65f595d70a4e49d46c891bdaf38c15f55a88e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:28:03 -0500 Subject: [PATCH 1586/6505] Update vault_setup.sh --- setup/vault_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh index 4826d660..57f2117c 100644 --- a/setup/vault_setup.sh +++ b/setup/vault_setup.sh @@ -13,7 +13,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM trap die ERR From c7bff3055bf045cb57f1ba6cdbe9665072dc0ef7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:28:35 -0500 Subject: [PATCH 1587/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index d2d0742c..ee50d424 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 9f538f637cc008383ba548e9bc39c1868dfb4b33 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:29:04 -0500 Subject: [PATCH 1588/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 3574a71e..d47b4a42 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From ce593b57e5c5a1b010fb856e7d3415003e7147dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Mar 2022 22:29:35 -0500 Subject: [PATCH 1589/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 5e5050b6..2c921eb9 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -28,7 +28,7 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 25d6ed3c4d00e5ed648958573bb6739544533d87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 07:44:36 -0500 Subject: [PATCH 1590/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 48d94bb6..816e4db5 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -1,7 +1,4 @@ #!/usr/bin/env bash -VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ set -o errexit set -o errtrace @@ -99,20 +96,14 @@ cargo build --features sqlite --release &>/dev/null file target/release/vaultwarden &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Building Web-Vault... " -pushd target/release/ &>/dev/null -git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null -cd web-vault.git &>/dev/null -git checkout v2.25.1 &>/dev/null -git submodule update --init --recursive &>/dev/null -wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null -git apply v2.25.0.patch &>/dev/null -npm ci --silent --legacy-peer-deps &>/dev/null -npm audit fix --silent --legacy-peer-deps || true &>/dev/null -npm run --silent dist:oss:selfhost &>/dev/null -cp -a build ../web-vault &>/dev/null -cd .. -mkdir data +VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ + +echo -en "${GN} Downloading Web-Vault ${VWRELEASE}... " +wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null +tar -xzf bw_web_$VWRELEASE.tar.gz &>/dev/null +cp -R web-vault /var/lib/vaultwarden/ &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Create Systemd Service... " @@ -170,6 +161,7 @@ echo -e "${CM}${CL} \r" fi echo -en "${GN} Cleanup... " +rm -r bw_web_$VWRELEASE.tar.gz web-vault apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* From 9b5ec7c601a26e0e6f165b370ee353e7d0f3032d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 08:22:24 -0500 Subject: [PATCH 1591/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 816e4db5..f4697c2b 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -107,6 +107,8 @@ cp -R web-vault /var/lib/vaultwarden/ &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Create Systemd Service... " +cd .. +mkdir data cp ../../.env.template /etc/vaultwarden.env &>/dev/null cp vaultwarden /usr/bin/vaultwarden &>/dev/null chmod +x /usr/bin/vaultwarden &>/dev/null From 2c9208a707a9216840bc0383fcb69e499a3a56a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 09:00:29 -0500 Subject: [PATCH 1592/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index f4697c2b..00be623b 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -94,6 +94,15 @@ pushd vaultwarden &>/dev/null cargo clean &>/dev/null cargo build --features sqlite --release &>/dev/null file target/release/vaultwarden &>/dev/null +cd .. +mkdir data +#cp ../../.env.template /etc/vaultwarden.env &>/dev/null +cp vaultwarden /usr/bin/vaultwarden &>/dev/null +chmod +x /usr/bin/vaultwarden &>/dev/null +useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null +sudo cp -R data /var/lib/vaultwarden/ &>/dev/null +#cp -R web-vault /var/lib/vaultwarden/ &>/dev/null +chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null echo -e "${CM}${CL} \r" VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ @@ -107,15 +116,6 @@ cp -R web-vault /var/lib/vaultwarden/ &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Create Systemd Service... " -cd .. -mkdir data -cp ../../.env.template /etc/vaultwarden.env &>/dev/null -cp vaultwarden /usr/bin/vaultwarden &>/dev/null -chmod +x /usr/bin/vaultwarden &>/dev/null -useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null -sudo cp -R data /var/lib/vaultwarden/ &>/dev/null -cp -R web-vault /var/lib/vaultwarden/ &>/dev/null -chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null From 6ffa555d2acbba72841c8dd6b926af39021e8aaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 09:47:07 -0500 Subject: [PATCH 1593/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 00be623b..54a9f28b 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -94,28 +94,32 @@ pushd vaultwarden &>/dev/null cargo clean &>/dev/null cargo build --features sqlite --release &>/dev/null file target/release/vaultwarden &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Building Web-Vault... " +pushd target/release/ &>/dev/null +git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null +cd web-vault.git &>/dev/null +git checkout v2.25.1 &>/dev/null +git submodule update --init --recursive &>/dev/null +wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null +git apply v2.25.0.patch &>/dev/null +npm ci --silent --legacy-peer-deps &>/dev/null +npm audit fix --silent --legacy-peer-deps || true &>/dev/null +npm run --silent dist:oss:selfhost &>/dev/null +cp -a build ../web-vault &>/dev/null cd .. mkdir data -#cp ../../.env.template /etc/vaultwarden.env &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Create Systemd Service... " +cp ../../.env.template /etc/vaultwarden.env &>/dev/null cp vaultwarden /usr/bin/vaultwarden &>/dev/null chmod +x /usr/bin/vaultwarden &>/dev/null useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null sudo cp -R data /var/lib/vaultwarden/ &>/dev/null -#cp -R web-vault /var/lib/vaultwarden/ &>/dev/null -chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null -echo -e "${CM}${CL} \r" - -VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ - -echo -en "${GN} Downloading Web-Vault ${VWRELEASE}... " -wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null -tar -xzf bw_web_$VWRELEASE.tar.gz &>/dev/null cp -R web-vault /var/lib/vaultwarden/ &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Create Systemd Service... " +chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null From 6636d4a4635acdedd8c99eb0b00ccf626b2c6781 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 10:12:27 -0500 Subject: [PATCH 1594/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 54a9f28b..1c038ad2 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -167,7 +167,6 @@ echo -e "${CM}${CL} \r" fi echo -en "${GN} Cleanup... " -rm -r bw_web_$VWRELEASE.tar.gz web-vault apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* From 035da37a82f2d21842f999a4ea1591d86cb0cc8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 10:16:51 -0500 Subject: [PATCH 1595/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bd6a54e1..2bfd9df8 100644 --- a/README.md +++ b/README.md @@ -1188,7 +1188,7 @@ ________________________________________________________________________________ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vault_container.sh)" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vaultwarden.sh)" ``` ⚠️Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. From 6d16d55fec2e6583f79978a386bcda2e957934a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 11:07:42 -0500 Subject: [PATCH 1596/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2bfd9df8..471d2786 100644 --- a/README.md +++ b/README.md @@ -1179,7 +1179,7 @@ ________________________________________________________________________________
    - Vaultwarden LXC + 🔸Vaultwarden LXC

    From 513177a5b23974604d66b33c4de74202b3263631 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 11:09:13 -0500 Subject: [PATCH 1597/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4219af80..1fe7d45e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-11 + +### Changed + +- **Vaultwarden LXC** + - New V2 Install Script + ## 2022-03-08 ### Changed From e5aa4e7f00a9129e741a0db4e83221b67ee8c010 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 13:25:07 -0500 Subject: [PATCH 1598/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1fe7d45e..b18ae1c8 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Scripts** (V2) - - Choose between Automatic or Password Login + - Choose between Privileged or Unprivileged CT and Automatic or Password Login - **ESPHome LXC** - New V2 Install Script - **Zwavejs2MQTT LXC** From 7223a66c23e4b1d6392dd260c19fd17e603bbb23 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 14:40:23 -0500 Subject: [PATCH 1599/6505] Create photoprism.sh --- ct/photoprism.sh | 210 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 ct/photoprism.sh diff --git a/ct/photoprism.sh b/ct/photoprism.sh new file mode 100644 index 00000000..d4d6da78 --- /dev/null +++ b/ct/photoprism.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="PhotoPrism" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _ _ _____ _ + | __ \| | | | | __ \ (_) + | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ + | ___/| _ \ / _ \| __/ _ \| ___/ __| / __| _ _ \ + | | | | | | (_) | || (_) | | | | | \__ \ | | | | | + |_| |_| |_|\___/ \__\___/|_| |_| |_|___/_| |_| |_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" From 8e7494e59ee59c15798b5459dcaacdf5099e4d08 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 14:42:58 -0500 Subject: [PATCH 1600/6505] Create photoprism-install.sh --- setup/photoprism-install.sh | 152 ++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 setup/photoprism-install.sh diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh new file mode 100644 index 00000000..4796c98f --- /dev/null +++ b/setup/photoprism-install.sh @@ -0,0 +1,152 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gcc &>/dev/null +apt-get install -y g++ &>/dev/null +apt-get install -y git &>/dev/null +apt-get install -y gnupg &>/dev/null +apt-get install -y make &>/dev/null +apt-get install -y zip &>/dev/null +apt-get install -y unzip &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Golang... " +wget https://golang.org/dl/go1.17.8.linux-amd64.tar.gz &>/dev/null +sudo tar -C /usr/local -xzf go1.17.8.linux-amd64.tar.gz &>/dev/null +sudo ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Tensorflow... " +wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null +sudo tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null +sudo ldconfig &>/dev/null +echo -e "${CM}${CL} \r" + +sudo useradd --system photoprism &>/dev/null +sudo mkdir -p /opt/photoprism/bin +sudo mkdir /var/lib/photoprism +sudo chown photoprism:photoprism /var/lib/photoprism &>/dev/null + +echo -en "${GN} Downloading ${APP}... " +git clone https://github.com/photoprism/photoprism.git &>/dev/null +cd photoprism +git checkout release &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing ${APP}... " +sudo make all &>/dev/null +sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null +sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null +sudo chown -R photoprism:photoprism /opt/photoprism &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Service file photoprism.service... " +service_path="/etc/systemd/system/photoprism.service" + +echo "[Unit] +Description=PhotoPrism service +After=network.target + +[Service] +Type=forking +User=photoprism +Group=photoprism +WorkingDirectory=/opt/photoprism +EnvironmentFile=/var/lib/photoprism/.env +ExecStart=/opt/photoprism/bin/photoprism up -d +ExecStop=/opt/photoprism/bin/photoprism down + +[Install] +WantedBy=multi-user.target" > $service_path +$ sudo systemctl daemon-reload +$ sudo systemctl start photoprism +$ sudo systemctl enable photoprism &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From c5ea1d8e8f9fe03861cdacb07bc5bd0b4d82f877 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 14:46:26 -0500 Subject: [PATCH 1601/6505] Update photoprism.sh --- ct/photoprism.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index d4d6da78..84ef28c2 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -207,4 +207,6 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:2342${CL} \n" From 71165f81a2e5194ad08c93758e6d83952eb91b13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 14:55:48 -0500 Subject: [PATCH 1602/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 4796c98f..0ceb0ea2 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -91,13 +91,13 @@ sudo mkdir -p /opt/photoprism/bin sudo mkdir /var/lib/photoprism sudo chown photoprism:photoprism /var/lib/photoprism &>/dev/null -echo -en "${GN} Downloading ${APP}... " +echo -en "${GN} Downloading PhotoPrism... " git clone https://github.com/photoprism/photoprism.git &>/dev/null cd photoprism git checkout release &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing ${APP}... " +echo -en "${GN} Installing PhotoPrism... " sudo make all &>/dev/null sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null From b54d31ecc942c465e96c733c6d999fdd9d35704e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 15:22:47 -0500 Subject: [PATCH 1603/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 0ceb0ea2..d0326094 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -98,10 +98,12 @@ git checkout release &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing PhotoPrism... " -sudo make all &>/dev/null -sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null -sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null -sudo chown -R photoprism:photoprism /opt/photoprism &>/dev/null +sudo make all +sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism +sudo cp -a assets/ /opt/photoprism/assets/ +sudo chown -R photoprism:photoprism /opt/photoprism +cd /var/lib/photoprism +sudo chmod 640 .env echo -e "${CM}${CL} \r" echo -en "${GN} Creating Service file photoprism.service... " From 1df69e59dc6885cad388603c50a9d8c07b9887e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 15:40:21 -0500 Subject: [PATCH 1604/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index d0326094..7c20ac6b 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -97,7 +97,7 @@ cd photoprism git checkout release &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing PhotoPrism... " +echo -en "${GN} Building PhotoPrism... " sudo make all sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism sudo cp -a assets/ /opt/photoprism/assets/ From d9b1ac279fe664a0b60e4fb73f52acc109bb0bb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 15:41:25 -0500 Subject: [PATCH 1605/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 7c20ac6b..bc910621 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -102,8 +102,6 @@ sudo make all sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism sudo cp -a assets/ /opt/photoprism/assets/ sudo chown -R photoprism:photoprism /opt/photoprism -cd /var/lib/photoprism -sudo chmod 640 .env echo -e "${CM}${CL} \r" echo -en "${GN} Creating Service file photoprism.service... " From 2c5e139444060362b25f9adddc2ff435a52a5fe3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 16:00:06 -0500 Subject: [PATCH 1606/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index bc910621..84965c1f 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -122,9 +122,9 @@ ExecStop=/opt/photoprism/bin/photoprism down [Install] WantedBy=multi-user.target" > $service_path -$ sudo systemctl daemon-reload -$ sudo systemctl start photoprism -$ sudo systemctl enable photoprism &>/dev/null +sudo systemctl daemon-reload +sudo systemctl start photoprism +sudo systemctl enable photoprism &>/dev/null echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 6263fc6f7b19f8384ddac9c0425d7e882de449d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 16:05:02 -0500 Subject: [PATCH 1607/6505] Update photoprism.sh --- ct/photoprism.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 84ef28c2..748267a7 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -5,6 +5,7 @@ RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +PP=`echo "\e[1;35m"` APP="PhotoPrism" HN=$(echo ${APP,,} | tr -d ' ') while true; do @@ -17,7 +18,7 @@ while true; do done clear function header_info { -echo -e "${RD} +echo -e "${PP} _____ _ _ _____ _ | __ \| | | | | __ \ (_) | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ From da171df9b6ff08d6e89f26c5ff988481567c9236 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 16:31:36 -0500 Subject: [PATCH 1608/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 84965c1f..84b123df 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -104,28 +104,28 @@ sudo cp -a assets/ /opt/photoprism/assets/ sudo chown -R photoprism:photoprism /opt/photoprism echo -e "${CM}${CL} \r" -echo -en "${GN} Creating Service file photoprism.service... " -service_path="/etc/systemd/system/photoprism.service" +#echo -en "${GN} Creating Service file photoprism.service... " +#service_path="/etc/systemd/system/photoprism.service" -echo "[Unit] -Description=PhotoPrism service -After=network.target +#echo "[Unit] +#Description=PhotoPrism service +#After=network.target -[Service] -Type=forking -User=photoprism -Group=photoprism -WorkingDirectory=/opt/photoprism -EnvironmentFile=/var/lib/photoprism/.env -ExecStart=/opt/photoprism/bin/photoprism up -d -ExecStop=/opt/photoprism/bin/photoprism down +#[Service] +#Type=forking +#User=photoprism +#Group=photoprism +#WorkingDirectory=/opt/photoprism +#EnvironmentFile=/var/lib/photoprism/.env +#ExecStart=/opt/photoprism/bin/photoprism up -d +#ExecStop=/opt/photoprism/bin/photoprism down -[Install] -WantedBy=multi-user.target" > $service_path -sudo systemctl daemon-reload -sudo systemctl start photoprism -sudo systemctl enable photoprism &>/dev/null -echo -e "${CM}${CL} \r" +#[Install] +#WantedBy=multi-user.target" > $service_path +#sudo systemctl daemon-reload +#sudo systemctl start photoprism +#sudo systemctl enable photoprism &>/dev/null +#echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From 0acacfa515b68cefa354164bb478d728ae4017c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 17:18:33 -0500 Subject: [PATCH 1609/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 54 ++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 84b123df..e764e82d 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -104,28 +104,44 @@ sudo cp -a assets/ /opt/photoprism/assets/ sudo chown -R photoprism:photoprism /opt/photoprism echo -e "${CM}${CL} \r" -#echo -en "${GN} Creating Service file photoprism.service... " -#service_path="/etc/systemd/system/photoprism.service" +env_path="/var/lib/photoprism/.env" +echo " # Initial password for the admin user +PHOTOPRISM_ADMIN_PASSWORD='photoprism' -#echo "[Unit] -#Description=PhotoPrism service -#After=network.target +# PhotoPrism storage directories +PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism' +PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals" +PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -#[Service] -#Type=forking -#User=photoprism -#Group=photoprism -#WorkingDirectory=/opt/photoprism -#EnvironmentFile=/var/lib/photoprism/.env -#ExecStart=/opt/photoprism/bin/photoprism up -d -#ExecStop=/opt/photoprism/bin/photoprism down +# Uncomment below if using MariaDB/MySQL instead of SQLite (the default) +# PHOTOPRISM_DATABASE_DRIVER='mysql' +# PHOTOPRISM_DATABASE_SERVER='MYSQL_IP_HERE' +# PHOTOPRISM_DATABASE_NAME='DB_NAME' +# PHOTOPRISM_DATABASE_USER='USER_NAME' +# PHOTOPRISM_DATABASE_PASSWORD='PASSWORD' " > $env_path -#[Install] -#WantedBy=multi-user.target" > $service_path -#sudo systemctl daemon-reload -#sudo systemctl start photoprism -#sudo systemctl enable photoprism &>/dev/null -#echo -e "${CM}${CL} \r" +echo -en "${GN} Creating Service file photoprism.service... " +service_path="/etc/systemd/system/photoprism.service" + +echo "[Unit] +Description=PhotoPrism service +After=network.target + +[Service] +Type=forking +User=photoprism +Group=photoprism +WorkingDirectory=/opt/photoprism +EnvironmentFile=/var/lib/photoprism/.env +ExecStart=/opt/photoprism/bin/photoprism up -d +ExecStop=/opt/photoprism/bin/photoprism down + +[Install] +WantedBy=multi-user.target" > $service_path +sudo systemctl daemon-reload +sudo systemctl start photoprism +sudo systemctl enable photoprism &>/dev/null +echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From 3be17db49c885951a4c39a7178c96ddae243dbe8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 18:16:05 -0500 Subject: [PATCH 1610/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index e764e82d..9e72cf8d 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -105,20 +105,18 @@ sudo chown -R photoprism:photoprism /opt/photoprism echo -e "${CM}${CL} \r" env_path="/var/lib/photoprism/.env" -echo " # Initial password for the admin user +echo " PHOTOPRISM_ADMIN_PASSWORD='photoprism' - -# PhotoPrism storage directories PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism' -PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals" +PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' - # Uncomment below if using MariaDB/MySQL instead of SQLite (the default) # PHOTOPRISM_DATABASE_DRIVER='mysql' # PHOTOPRISM_DATABASE_SERVER='MYSQL_IP_HERE' # PHOTOPRISM_DATABASE_NAME='DB_NAME' # PHOTOPRISM_DATABASE_USER='USER_NAME' -# PHOTOPRISM_DATABASE_PASSWORD='PASSWORD' " > $env_path +# PHOTOPRISM_DATABASE_PASSWORD='PASSWORD' +" > $env_path echo -en "${GN} Creating Service file photoprism.service... " service_path="/etc/systemd/system/photoprism.service" From 07bcf486380480a80b164df708fc9f151e70191c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 18:41:12 -0500 Subject: [PATCH 1611/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 9e72cf8d..df7587b1 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -99,7 +99,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Building PhotoPrism... " sudo make all -sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism +sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism /dev/null sudo cp -a assets/ /opt/photoprism/assets/ sudo chown -R photoprism:photoprism /opt/photoprism echo -e "${CM}${CL} \r" From 07e31ebbe2dd1349b505bdf0cbd5cf0094843ada Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Mar 2022 19:07:45 -0500 Subject: [PATCH 1612/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index df7587b1..9e72cf8d 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -99,7 +99,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Building PhotoPrism... " sudo make all -sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism /dev/null +sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism sudo cp -a assets/ /opt/photoprism/assets/ sudo chown -R photoprism:photoprism /opt/photoprism echo -e "${CM}${CL} \r" From 79869c526e4e9b35d89664c6ec61083c7ad1b252 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 00:26:11 -0500 Subject: [PATCH 1613/6505] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 471d2786..9ce7173e 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ ________________________________________________________________________________
    - 🔸Proxmox Kernel Clean + Proxmox Kernel Clean

    @@ -64,7 +64,7 @@ ________________________________________________________________________________
    -Proxmox Dark Theme + Proxmox Dark Theme

    @@ -86,7 +86,7 @@ ________________________________________________________________________________
    -Home Assistant OS VM + Home Assistant OS VM

    @home-assistant

    @@ -266,7 +266,7 @@ ________________________________________________________________________________
    - 🔸Homebridge LXC + Homebridge LXC

    From 055336fb58e3b826749dd695097fe2f920e5f472 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 00:31:27 -0500 Subject: [PATCH 1614/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 9e72cf8d..5d6fd17a 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -99,8 +99,8 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Building PhotoPrism... " sudo make all -sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism -sudo cp -a assets/ /opt/photoprism/assets/ +sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null +sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null sudo chown -R photoprism:photoprism /opt/photoprism echo -e "${CM}${CL} \r" From bca287a65ada04bd494b6adea2c890ef7e58e2bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 00:42:59 -0500 Subject: [PATCH 1615/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 5d6fd17a..771171ed 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -98,7 +98,7 @@ git checkout release &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Building PhotoPrism... " -sudo make all +sudo make all &>/dev/null sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null sudo chown -R photoprism:photoprism /opt/photoprism From 4d26e88018e4f8ac62dae4ce36ead2a33a4f5f75 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 00:57:53 -0500 Subject: [PATCH 1616/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 771171ed..e58e6e54 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -91,7 +91,7 @@ sudo mkdir -p /opt/photoprism/bin sudo mkdir /var/lib/photoprism sudo chown photoprism:photoprism /var/lib/photoprism &>/dev/null -echo -en "${GN} Downloading PhotoPrism... " +echo -en "${GN} Cloning PhotoPrism... " git clone https://github.com/photoprism/photoprism.git &>/dev/null cd photoprism git checkout release &>/dev/null From f1f9234c7f597e93e8b6462c3f0df454fe66c054 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 01:30:52 -0500 Subject: [PATCH 1617/6505] Update README.md --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 9ce7173e..a3258668 100644 --- a/README.md +++ b/README.md @@ -1027,6 +1027,43 @@ ________________________________________________________________________________
    + +
    + 🔸PhotoPrism LXC + +

    + +

    PhotoPrism LXC

    + +PhotoPrism® is an AI-powered app for browsing, organizing & sharing your photo collection. + +To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell (V2). + +``` +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/photoprism.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +**MotionEye Interface - IP:2342** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + photoprism + ``` +[PhotoSync](https://www.photosync-app.com/home.html) +____________________________________________________________________________________________ + +
    +
    Daemon Sync Server LXC From d68e8dc5e1540d89338950101b6226cda525b767 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 01:33:02 -0500 Subject: [PATCH 1618/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b18ae1c8..48c9a7b2 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-12 + +### Changed + +- **PhotoPrism LXC** + - New Script V2 + ## 2022-03-11 ### Changed From d4df4a89f3fc4b8e38fa3cd182498833c1e6a51b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 01:42:14 -0500 Subject: [PATCH 1619/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a3258668..5c6d9f95 100644 --- a/README.md +++ b/README.md @@ -1060,6 +1060,7 @@ After the script completes, If you're dissatisfied with the default settings, cl photoprism ``` [PhotoSync](https://www.photosync-app.com/home.html) + ____________________________________________________________________________________________
    From 178ab4e37debe6f45a5aa5694b07215eb0a829e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 01:44:53 -0500 Subject: [PATCH 1620/6505] Add files via upload --- misc/images/photoprism.png | Bin 0 -> 63270 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/photoprism.png diff --git a/misc/images/photoprism.png b/misc/images/photoprism.png new file mode 100644 index 0000000000000000000000000000000000000000..736014d40fc7888c74fbac709be7b580d007980d GIT binary patch literal 63270 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 LNkvXXu0mjf&bHES literal 0 HcmV?d00001 From 9c8761053d23645d5f00a34da4e01fbfea1f81aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 01:46:16 -0500 Subject: [PATCH 1621/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c6d9f95..bac81c7b 100644 --- a/README.md +++ b/README.md @@ -1031,7 +1031,7 @@ ________________________________________________________________________________

    🔸PhotoPrism LXC -

    +

    PhotoPrism LXC

    From 553b6c56f38ebbb8344a7239ed2840c4638b0070 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 01:50:14 -0500 Subject: [PATCH 1622/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bac81c7b..aeb1aecd 100644 --- a/README.md +++ b/README.md @@ -1047,7 +1047,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/p After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. -**MotionEye Interface - IP:2342** +**PhotoPrism Interface - IP:2342** ⚙️ **Initial Login** From 19042e062c094b7026a90aee6323863e39cd56a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 14:57:02 -0500 Subject: [PATCH 1623/6505] Create homeassistantcore.sh --- ct/homeassistantcore.sh | 213 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 ct/homeassistantcore.sh diff --git a/ct/homeassistantcore.sh b/ct/homeassistantcore.sh new file mode 100644 index 00000000..f7fd1dd7 --- /dev/null +++ b/ct/homeassistantcore.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Home Assistant Core" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _ _ _ _ + | | (_) | | | | + | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ + | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| + ${CL}${YW}CORE +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}$APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} \n" From 06cb27dd6f16efe65c263e996f74cdb7a8ec82dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 14:57:57 -0500 Subject: [PATCH 1624/6505] Create homeassistantcore-install.sh --- setup/homeassistantcore-install.sh | 120 +++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 setup/homeassistantcore-install.sh diff --git a/setup/homeassistantcore-install.sh b/setup/homeassistantcore-install.sh new file mode 100644 index 00000000..15be0f95 --- /dev/null +++ b/setup/homeassistantcore-install.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Build Essential... " +sudo apt-get install -y build-essential +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Python3... " +sudo apt-get install -y python3 +sudo apt-get install -y python3-dev +sudo apt-get install -y python3-venv +sudo apt-get install -y python3-pip +sudo apt-get install -y libffi-dev +sudo apt-get install -y libssl-dev +sudo apt-get install -y libjpeg-dev +sudo apt-get install -y zlib1g-dev +sudo apt-get install -y autoconf +#sudo apt-get install -y build-essential +sudo apt-get install -y libopenjp2-7 +sudo apt-get install -y libtiff5 +sudo apt-get install -y libturbojpeg0-dev +sudo apt-get install -y tzdata +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting Virtual Environment... " +sudo useradd -rm homeassistant +sudo mkdir /srv/homeassistant +sudo chown homeassistant:homeassistant /srv/homeassistant +sudo -u homeassistant -H -s +cd /srv/homeassistant +python3.9 -m venv . +source bin/activate + +echo -en "${GN} Installing Home Assistant Core... " +python3 -m pip install wheel +pip3 install homeassistant +hass +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 65cf82151d740d429554a3c5c97f4906daf36fbc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 15:25:07 -0500 Subject: [PATCH 1625/6505] Update homeassistantcore-install.sh --- setup/homeassistantcore-install.sh | 35 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/setup/homeassistantcore-install.sh b/setup/homeassistantcore-install.sh index 15be0f95..a44be86d 100644 --- a/setup/homeassistantcore-install.sh +++ b/setup/homeassistantcore-install.sh @@ -60,24 +60,23 @@ apt-get install -y sudo &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Build Essential... " -sudo apt-get install -y build-essential +sudo apt-get install -y build-essential &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Python3... " -sudo apt-get install -y python3 -sudo apt-get install -y python3-dev -sudo apt-get install -y python3-venv -sudo apt-get install -y python3-pip -sudo apt-get install -y libffi-dev -sudo apt-get install -y libssl-dev -sudo apt-get install -y libjpeg-dev -sudo apt-get install -y zlib1g-dev -sudo apt-get install -y autoconf -#sudo apt-get install -y build-essential -sudo apt-get install -y libopenjp2-7 -sudo apt-get install -y libtiff5 -sudo apt-get install -y libturbojpeg0-dev -sudo apt-get install -y tzdata +sudo apt-get install -y python3 &>/dev/null +sudo apt-get install -y python3-dev &>/dev/null +sudo apt-get install -y python3-venv &>/dev/null +sudo apt-get install -y python3-pip &>/dev/null +sudo apt-get install -y libffi-dev &>/dev/null +sudo apt-get install -y libssl-dev &>/dev/null +sudo apt-get install -y libjpeg-dev &>/dev/null +sudo apt-get install -y zlib1g-dev &>/dev/null +sudo apt-get install -y autoconf &>/dev/null +sudo apt-get install -y libopenjp2-7 &>/dev/null +sudo apt-get install -y libtiff5 &>/dev/null +sudo apt-get install -y libturbojpeg0-dev &>/dev/null +sudo apt-get install -y tzdata &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Setting Virtual Environment... " @@ -87,14 +86,16 @@ sudo chown homeassistant:homeassistant /srv/homeassistant sudo -u homeassistant -H -s cd /srv/homeassistant python3.9 -m venv . +while: source bin/activate - +do echo -en "${GN} Installing Home Assistant Core... " python3 -m pip install wheel pip3 install homeassistant hass echo -e "${CM}${CL} \r" - +break +done PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " From d4084f0e1d1ce7414fa22bcb8556c9e93d56cc71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 18:01:23 -0500 Subject: [PATCH 1626/6505] Delete homeassistantcore-install.sh --- setup/homeassistantcore-install.sh | 121 ----------------------------- 1 file changed, 121 deletions(-) delete mode 100644 setup/homeassistantcore-install.sh diff --git a/setup/homeassistantcore-install.sh b/setup/homeassistantcore-install.sh deleted file mode 100644 index a44be86d..00000000 --- a/setup/homeassistantcore-install.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Build Essential... " -sudo apt-get install -y build-essential &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Python3... " -sudo apt-get install -y python3 &>/dev/null -sudo apt-get install -y python3-dev &>/dev/null -sudo apt-get install -y python3-venv &>/dev/null -sudo apt-get install -y python3-pip &>/dev/null -sudo apt-get install -y libffi-dev &>/dev/null -sudo apt-get install -y libssl-dev &>/dev/null -sudo apt-get install -y libjpeg-dev &>/dev/null -sudo apt-get install -y zlib1g-dev &>/dev/null -sudo apt-get install -y autoconf &>/dev/null -sudo apt-get install -y libopenjp2-7 &>/dev/null -sudo apt-get install -y libtiff5 &>/dev/null -sudo apt-get install -y libturbojpeg0-dev &>/dev/null -sudo apt-get install -y tzdata &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Setting Virtual Environment... " -sudo useradd -rm homeassistant -sudo mkdir /srv/homeassistant -sudo chown homeassistant:homeassistant /srv/homeassistant -sudo -u homeassistant -H -s -cd /srv/homeassistant -python3.9 -m venv . -while: -source bin/activate -do -echo -en "${GN} Installing Home Assistant Core... " -python3 -m pip install wheel -pip3 install homeassistant -hass -echo -e "${CM}${CL} \r" -break -done -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - fi - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From f4d8bd40046d3cd473b96e73589691b9db472b7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Mar 2022 18:01:46 -0500 Subject: [PATCH 1627/6505] Delete homeassistantcore.sh --- ct/homeassistantcore.sh | 213 ---------------------------------------- 1 file changed, 213 deletions(-) delete mode 100644 ct/homeassistantcore.sh diff --git a/ct/homeassistantcore.sh b/ct/homeassistantcore.sh deleted file mode 100644 index f7fd1dd7..00000000 --- a/ct/homeassistantcore.sh +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="Home Assistant Core" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _ _ _ _ - | | (_) | | | | - | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ - | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| - ${CL}${YW}CORE -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - fi - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" -} -show_menu2 -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - fi - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}$APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} \n" From 96dbb2b523ed0c03f3440783a1e4dfd8a5de2cc3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Mar 2022 09:57:29 -0400 Subject: [PATCH 1628/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 1c038ad2..09e1c824 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -133,7 +133,6 @@ Group=vaultwarden EnvironmentFile=/etc/vaultwarden.env ExecStart=/usr/bin/vaultwarden LimitNOFILE=1048576 -LimitNPROC=64 PrivateTmp=true PrivateDevices=true ProtectHome=true From c56beab80d8965a94e25adfeb595480a10926806 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Mar 2022 10:32:42 -0400 Subject: [PATCH 1629/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aeb1aecd..06b6f925 100644 --- a/README.md +++ b/README.md @@ -1091,13 +1091,13 @@ ________________________________________________________________________________
    - 🔸MotionEye NVR LXC + 🔸MotionEye VMS LXC

    -

    MotionEye NVR LXC

    +

    MotionEye VMS LXC

    -To create a new Proxmox MotionEye NVR LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell (V2). ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/motioneye.sh)" From 942d82856166b16bf6796326b9bb9259a15e2eda Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Mar 2022 15:47:35 -0400 Subject: [PATCH 1630/6505] Update podman_ha_container.sh --- ct/podman_ha_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman_ha_container.sh b/ct/podman_ha_container.sh index 65d500d3..7bf3164a 100644 --- a/ct/podman_ha_container.sh +++ b/ct/podman_ha_container.sh @@ -153,7 +153,7 @@ ROOTFS=${STORAGE}:${DISK_REF-}${DISK} echo -e "${CM}${CL} \r" echo -en "${GN} Creating LXC Container... " -DISK_SIZE=8G +DISK_SIZE=16G pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." From 422854ff4e006436a2399bc2ced3e94c65ae5874 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Mar 2022 16:03:37 -0400 Subject: [PATCH 1631/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06b6f925..45e22cab 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ To create a new Proxmox Podman Home Assistant Container, run the following in th ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/podman_ha_container.sh)" ``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    +

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. From f0d6cc57f449c1b3b846355380678bca1363b458 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Mar 2022 18:45:42 -0400 Subject: [PATCH 1632/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index ad2ec632..b630d8bf 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -35,14 +35,15 @@ function update_container() { echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" } - +clear +header_info for container in $containers do status=`pct status $container` if [ "$status" == "status: stopped" ]; then echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container - echo -e "${BL}[Info]${GN} Waiting For${BL} $container To Start ${CL} \n" + echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" sleep 5 update_container $container echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" From eceb1a6b551b8008395366992cac68c17c8b331e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Mar 2022 18:49:00 -0400 Subject: [PATCH 1633/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index b630d8bf..b20a0ea3 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -32,11 +32,11 @@ containers=$(pct list | tail -n +2 | cut -f1 -d' ') function update_container() { container=$1 + clear + header_info echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" } -clear -header_info for container in $containers do status=`pct status $container` From 538b9c5deda37d74873ffccca5be47b6ccbf897a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Mar 2022 23:32:42 -0400 Subject: [PATCH 1634/6505] Rename zwavejs2mqtt-install.sh to zwavejs2mqtt-install.nodejs --- setup/{zwavejs2mqtt-install.sh => zwavejs2mqtt-install.nodejs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename setup/{zwavejs2mqtt-install.sh => zwavejs2mqtt-install.nodejs} (100%) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.nodejs similarity index 100% rename from setup/zwavejs2mqtt-install.sh rename to setup/zwavejs2mqtt-install.nodejs From d00b5694e5fb6a4c5dff2360fe6f55d3cbe64fb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Mar 2022 23:34:01 -0400 Subject: [PATCH 1635/6505] Create zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 112 ++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 setup/zwavejs2mqtt-install.sh diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh new file mode 100644 index 00000000..9461db8b --- /dev/null +++ b/setup/zwavejs2mqtt-install.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get update &>/dev/null +apt-get -qqy install \ + curl \ + sudo \ + unzip &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Zwavejs2MQTT... " +mkdir /opt/zwavejs2mqtt +cd /opt/zwavejs2mqtt +mkdir store +curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null +unzip zwavejs2mqtt-v*.zip zwavejs2mqtt &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Service... " +service_path="/etc/systemd/system/zwavejs2mqtt.service" +echo "[Unit] +Description=ZWavejs2MQTT +Wants=network-online.target +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/zwavejs2mqtt +ExecStart=/opt/zwavejs2mqtt/zwavejs2mqtt +[Install] +WantedBy=multi-user.target > $service_path +systemctl start zwavejs2mqtt +systemctl enable zwavejs2mqtt &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +rm zwavejs2mqtt-v*.zip +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From ca510f617de9925d4b757cc264a348edd5beca0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Mar 2022 23:35:39 -0400 Subject: [PATCH 1636/6505] Create zwavejs2mqtt-update.sh --- misc/zwavejs2mqtt-update.sh | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 misc/zwavejs2mqtt-update.sh diff --git a/misc/zwavejs2mqtt-update.sh b/misc/zwavejs2mqtt-update.sh new file mode 100644 index 00000000..f5654ba1 --- /dev/null +++ b/misc/zwavejs2mqtt-update.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -e +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` + +echo -en "${GN} Updating Zwavejs2MQTT... " +systemctl stop zwavejs2mqtt.service +cd /opt/zwavejs2mqtt +curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null +unzip -u zwavejs2mqtt-v*.zip zwavejs2mqtt &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Checking Service... " +SERVICE=/etc/systemd/system/zwavejs2mqtt.service +cat < $SERVICE +[Unit] +Description=ZWavejs2MQTT +Wants=network-online.target +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/zwavejs2mqtt +ExecStart=/opt/zwavejs2mqtt/zwavejs2mqtt +[Install] +WantedBy=multi-user.target +EOF +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +rm zwavejs2mqtt-v*.zip +systemctl --system daemon-reload +systemctl start zwavejs2mqtt.service +systemctl enable zwavejs2mqtt.service &>/dev/null +echo -e "${CM}${CL} \n" + +echo -e "${GN} Finished ${CL}" + From df076b4544a126097057b647c7a7349e197ea552 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Mar 2022 23:41:34 -0400 Subject: [PATCH 1637/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 9461db8b..7c5aaa19 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -81,7 +81,7 @@ User=root WorkingDirectory=/opt/zwavejs2mqtt ExecStart=/opt/zwavejs2mqtt/zwavejs2mqtt [Install] -WantedBy=multi-user.target > $service_path +WantedBy=multi-user.target" > $service_path systemctl start zwavejs2mqtt systemctl enable zwavejs2mqtt &>/dev/null echo -e "${CM}${CL} \r" From c20bf2e53c38f571a0b7f5843115fca3f896974f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Mar 2022 23:57:34 -0400 Subject: [PATCH 1638/6505] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 45e22cab..afdd88a6 100644 --- a/README.md +++ b/README.md @@ -708,6 +708,12 @@ Run in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwave-copy-data.sh)" ``` +⚙️ **To Update Zwavejs2MQTT** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwavejs2mqtt-update.sh)" +``` ____________________________________________________________________________________________ From 6fddf47f856043a4fd70aec09c1b08ede8b0ef9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:00:04 -0400 Subject: [PATCH 1639/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 48c9a7b2..62e2cbbb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-03-14 + +### Changed + +- **Zwavejs2MQTT LXC** + - New Update Script + ## 2022-03-12 ### Changed From d1d279a30af0fc42088cab214c87883e0042c276 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:49:57 -0400 Subject: [PATCH 1640/6505] Update dashy.sh --- ct/dashy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index 0e5dd77a..67d42563 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 8a6d04ecf3a10396215fba06b7c7c79d5b24dce3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:54:18 -0400 Subject: [PATCH 1641/6505] Update adguard.sh --- ct/adguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index 28d5823f..69e27ea8 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 28e058240fc417c5915ae800d20221af001b943e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:54:52 -0400 Subject: [PATCH 1642/6505] Update daemonsync.sh --- ct/daemonsync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index d35540c7..0a12272b 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -163,7 +163,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 5d848542c3e79ad91686301e80dd770583ec935c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:55:21 -0400 Subject: [PATCH 1643/6505] Update debian.sh --- ct/debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index ab032e13..b5898aaa 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From b3a40bcf59c036c24e51b1f32289d299eb058d7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:56:59 -0400 Subject: [PATCH 1644/6505] Update esphome.sh --- ct/esphome.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index f3e8f556..52eacea5 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 0fb0ecd165d70525c97578895f46df1de2dae4b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:57:25 -0400 Subject: [PATCH 1645/6505] Update gamuntu.sh --- ct/gamuntu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/gamuntu.sh b/ct/gamuntu.sh index f01468de..f390625a 100644 --- a/ct/gamuntu.sh +++ b/ct/gamuntu.sh @@ -163,7 +163,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 1c90a864eefcbe88f7311326bb18b62c2c369048 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:57:59 -0400 Subject: [PATCH 1646/6505] Update grafana.sh --- ct/grafana.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/grafana.sh b/ct/grafana.sh index 45d795d9..de689df1 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -162,7 +162,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From d59c67f48746fb96a036a16d64b6ad52d5bf7a8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:58:41 -0400 Subject: [PATCH 1647/6505] Update homeassistant.sh --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index b5c80952..54afbe11 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -162,7 +162,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From ca5fd3f2263f27726b653e43f920dfede19d7a57 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:59:13 -0400 Subject: [PATCH 1648/6505] Update homebridge.sh --- ct/homebridge.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index ba22de14..e4bd0871 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -161,7 +161,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From bfb50c44295d02abc962879fb8eda40976b474ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 00:59:50 -0400 Subject: [PATCH 1649/6505] Update influxdb.sh --- ct/influxdb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 0212b927..4bf9b405 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -162,7 +162,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From f331e1f3c67a91d1fae48e9d926b0aacaccca585 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:00:30 -0400 Subject: [PATCH 1650/6505] Update mariadb.sh --- ct/mariadb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index e0e3e666..920e0fa0 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -162,7 +162,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From d9bc28f1c4a3e94a729070da1113569df5081414 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:01:00 -0400 Subject: [PATCH 1651/6505] Update motioneye.sh --- ct/motioneye.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 88bf00ba..23332a38 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -163,7 +163,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 09b67f9d91e0b4cd9ca518a2d76c38cc0b6ee34e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:01:28 -0400 Subject: [PATCH 1652/6505] Update mqtt.sh --- ct/mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 34e0f249..315a9e9e 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -162,7 +162,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 8e7442955aafb4c49fa607e1faab1464f7c7ade0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:02:00 -0400 Subject: [PATCH 1653/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index 34c8bc4d..cc406fc0 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 749d5e379c89a345ca59f7f0aa6b116b01c02a37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:02:42 -0400 Subject: [PATCH 1654/6505] Update node-red.sh --- ct/node-red.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index 6a72554d..b75eb47d 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -162,7 +162,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From f2e83fbcd0101daa91ff5b8c4ea5d5e91faa52f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:03:14 -0400 Subject: [PATCH 1655/6505] Update photoprism.sh --- ct/photoprism.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 748267a7..ec2325ad 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 29568e79f27680452b6a92e49928d283434bbecd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:03:47 -0400 Subject: [PATCH 1656/6505] Update pihole.sh --- ct/pihole.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pihole.sh b/ct/pihole.sh index 29946fbf..870c883c 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -163,7 +163,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 09e380e5582a76e92e63a12bd2269c0b94961c1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:05:29 -0400 Subject: [PATCH 1657/6505] Update ubuntu.sh --- ct/ubuntu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 61dc62c7..d187fb95 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -162,7 +162,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 02a9846caaf3d3ba8e44bec9470b15ed692b8952 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:05:55 -0400 Subject: [PATCH 1658/6505] Update vaultwarden.sh --- ct/vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index aeb4e83f..c81d099c 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 24bb42e8ed6509dff8614e4279934a46f7971e83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:06:20 -0400 Subject: [PATCH 1659/6505] Update wireguard.sh --- ct/wireguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 0f88d4e8..92856500 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -161,7 +161,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From f249a9194202e197210a9a9668f7718540ea2a37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:06:53 -0400 Subject: [PATCH 1660/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index bd9cba13..0b0e222b 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -164,7 +164,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From a8e7d14178dce36cb10e1d75175910aca73e8cba Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:07:22 -0400 Subject: [PATCH 1661/6505] Update zwavejs2mqtt.sh --- ct/zwavejs2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt.sh b/ct/zwavejs2mqtt.sh index 79ae3129..9e66ab47 100644 --- a/ct/zwavejs2mqtt.sh +++ b/ct/zwavejs2mqtt.sh @@ -165,7 +165,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi From 379c1710afacb128fae21b0082c17a8ceef89b8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 01:41:11 -0400 Subject: [PATCH 1662/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 62e2cbbb..50e81870 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,7 @@ # Change Log All notable changes to this project will be documented in this file. +### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) ## 2022-03-14 ### Changed From ccb971c5fc09c5140d4c1b6267e0dcdf9b68a020 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 08:24:18 -0400 Subject: [PATCH 1663/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index afdd88a6..2d517e5a 100644 --- a/README.md +++ b/README.md @@ -1028,6 +1028,8 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/d

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    **Dashy Interface - IP:4000** + +After getting everything setup the way you want in interactive mode and saved to disk, you have to go into update configuration and rebuild application. __________________________________________________________________________________________ From 9f40d570571fc3a5378d057c9f9cc35b3a5dcf33 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 08:25:40 -0400 Subject: [PATCH 1664/6505] Create dashy-update.sh --- misc/dashy-update.sh | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 misc/dashy-update.sh diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh new file mode 100644 index 00000000..531ec581 --- /dev/null +++ b/misc/dashy-update.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -e +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +clear +echo -en "${GN} Stopping Dashy... " +systemctl stop dashy +echo -e "${CM}${CL} \r" + +echo -en "${GN} Backup Data... " +cp -R /dashy/public public-backup +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Dashy... " +git merge +git pull origin master +yarn +yarn build +echo -e "${CM}${CL} \r" + +echo -en "${GN} Restoring Data... " +cp -R public-backup/* /dashy/public +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleaning... " +rm -rf public-backup +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Dashy... " +systemctl start dashy +echo -e "${CM}${CL} \r" + +echo -e "${GN} Finished ${CL}\n" From f79471d3419895788f632ffd08d5205adc077588 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 08:29:46 -0400 Subject: [PATCH 1665/6505] Update dashy-update.sh --- misc/dashy-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index 531ec581..3a065303 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -15,6 +15,7 @@ cp -R /dashy/public public-backup echo -e "${CM}${CL} \r" echo -en "${GN} Updating Dashy... " +cd /dashy git merge git pull origin master yarn From ad8ef171a02700e12b47eddee17524d53b12d4de Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 08:48:20 -0400 Subject: [PATCH 1666/6505] Update dashy-update.sh --- misc/dashy-update.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index 3a065303..104730a0 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -8,30 +8,36 @@ CL=`echo "\033[m"` clear echo -en "${GN} Stopping Dashy... " systemctl stop dashy +sleep 1 echo -e "${CM}${CL} \r" echo -en "${GN} Backup Data... " cp -R /dashy/public public-backup +sleep 1 echo -e "${CM}${CL} \r" echo -en "${GN} Updating Dashy... " cd /dashy -git merge -git pull origin master -yarn -yarn build +git merge &>/dev/null +git pull origin master &>/dev/null +yarn &>/dev/null +yarn build &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Restoring Data... " -cp -R public-backup/* /dashy/public +cd ~ +cp -R public-backup /dashy/public +sleep 1 echo -e "${CM}${CL} \r" echo -en "${GN} Cleaning... " rm -rf public-backup +sleep 1 echo -e "${CM}${CL} \r" echo -en "${GN} Starting Dashy... " systemctl start dashy +sleep 1 echo -e "${CM}${CL} \r" echo -e "${GN} Finished ${CL}\n" From fbebc4e8f5ff8febbc6890f58c060d0bc3d671c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 09:12:17 -0400 Subject: [PATCH 1667/6505] Update dashy-update.sh --- misc/dashy-update.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index 104730a0..f0a309f8 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -11,8 +11,8 @@ systemctl stop dashy sleep 1 echo -e "${CM}${CL} \r" -echo -en "${GN} Backup Data... " -cp -R /dashy/public public-backup +echo -en "${GN} Backup conf.yml... " +cp -R /dashy/public/conf.yml conf.yml sleep 1 echo -e "${CM}${CL} \r" @@ -24,14 +24,14 @@ yarn &>/dev/null yarn build &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Restoring Data... " +echo -en "${GN} Restoring conf.yml... " cd ~ -cp -R public-backup /dashy/public +cp -R conf.yml /dashy/public sleep 1 echo -e "${CM}${CL} \r" echo -en "${GN} Cleaning... " -rm -rf public-backup +rm -rf conf.yml sleep 1 echo -e "${CM}${CL} \r" From ae60447540fbb14f13a5728a5d4e95043ad43db7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 09:21:08 -0400 Subject: [PATCH 1668/6505] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 2d517e5a..e6e8fc0b 100644 --- a/README.md +++ b/README.md @@ -1031,6 +1031,13 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/d After getting everything setup the way you want in interactive mode and saved to disk, you have to go into update configuration and rebuild application. +⚙️ **To Update Dashy** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/dashy-update.sh)" +``` + __________________________________________________________________________________________
    From 9fb9e64cb31bc5c74eed9f0f04fbebba822d29c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 09:25:23 -0400 Subject: [PATCH 1669/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 50e81870..eba97e20 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) + +## 2022-03-15 + +### Changed + +- **Dashy LXC** + - New Update Script + ## 2022-03-14 ### Changed From e4c56e9bb93e61319bb2240d29522bf4d952b550 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 09:29:00 -0400 Subject: [PATCH 1670/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e6e8fc0b..d32fa784 100644 --- a/README.md +++ b/README.md @@ -322,7 +322,7 @@ Update from the Homebridge UI
    - 🔸ESPHome LXC + ESPHome LXC

    @@ -860,7 +860,7 @@ ________________________________________________________________________________
    - 🔸GamUntu LXC + GamUntu LXC

    GamUntu

    GamUntu LXC

    @@ -950,7 +950,7 @@ ________________________________________________________________________________
    - 🔸Pi-hole LXC + Pi-hole LXC

    @@ -1012,7 +1012,7 @@ ________________________________________________________________________________
    - Dashy LXC + 🔸Dashy LXC

    @@ -1106,7 +1106,7 @@ ________________________________________________________________________________
    - 🔸MotionEye VMS LXC + MotionEye VMS LXC

    From 90181c2fbccae07d4f0e48500fade500e2cac313 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 12:35:36 -0400 Subject: [PATCH 1671/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d32fa784..54884180 100644 --- a/README.md +++ b/README.md @@ -1243,7 +1243,9 @@ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ``` bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vaultwarden.sh)" ``` -⚠️Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. +⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. + +⚠️ If the Vaultwarden Interface is unreachable, `nano /etc/vaultwarden.env` and uncomment `ROCKET_ADDRESS=0.0.0.0` and reboot It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. From 8b81d2870bf412c79ab444b8c32b323d3cb402a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 12:49:13 -0400 Subject: [PATCH 1672/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 54884180..2564c9d1 100644 --- a/README.md +++ b/README.md @@ -1245,7 +1245,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/v ``` ⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. -⚠️ If the Vaultwarden Interface is unreachable, `nano /etc/vaultwarden.env` and uncomment `ROCKET_ADDRESS=0.0.0.0` and reboot +⚠️ If you find the Vaultwarden Interface unreachable, `nano /etc/vaultwarden.env` and uncomment `ROCKET_ADDRESS=0.0.0.0` and reboot It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. From d642fa656117a5de9a33d6d388cff502f80fb5ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Mar 2022 20:57:48 -0400 Subject: [PATCH 1673/6505] Update dashy-update.sh --- misc/dashy-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index f0a309f8..f38228f7 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -18,7 +18,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Updating Dashy... " cd /dashy -git merge &>/dev/null +git stash &>/dev/null git pull origin master &>/dev/null yarn &>/dev/null yarn build &>/dev/null From c6b7a1e4a401c33abae94b164187886fdecbdf03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Mar 2022 10:03:14 -0400 Subject: [PATCH 1674/6505] Create photoprism-update.sh --- misc/photoprism-update.sh | 108 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 misc/photoprism-update.sh diff --git a/misc/photoprism-update.sh b/misc/photoprism-update.sh new file mode 100644 index 00000000..0c7cda8f --- /dev/null +++ b/misc/photoprism-update.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash +set -e +RELEASE=$(curl -s https://api.github.com/repos/photoprism/photoprism/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-4) }') \ + +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +PP=`echo "\e[1;35m"` + +while true; do + read -p "Update PhotoPrism LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _____ _ _ _____ _ + | __ \| | | | | __ \ (_) + | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ + | ___/| _ \ / _ \| __/ _ \| ___/ __| / __| _ _ \ + | | | | | | (_) | || (_) | | | | | \__ \ | | | | | + |_| |_| |_|\___/ \__\___/|_| |_| |_|___/_| |_| |_| + ${RD} UPDATE +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${GN} Release Branch ${CL}\n" + printf " ${YW} 2)${YW} Develop Branch ${CL}\n" + + printf "Please choose a Install Branch and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Release Branch"; + BR="release" + break; + ;; + 2) clear; + header_info; + option_picked "Using Develop Branch"; + BR="develop" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Branch from the menu"; + show_menu; + ;; + esac + fi + done + +echo -en "${GN} Stopping PhotoPrism... " +sudo systemctl stop photoprism +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cloning PhotoPrism ${BR} branch... " +git clone https://github.com/photoprism/photoprism.git &>/dev/null +cd photoprism +git checkout ${BR} &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Building PhotoPrism ${BR} branch... " +sudo make all &>/dev/null +sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null +sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleaning... " +cd ~ +rm -rf photoprism +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting PhotoPrism... " +sudo systemctl start photoprism +echo -e "${CM}${CL} \n" + +echo -e "${GN} Finished ${CL} \n " + + From 951bd588699706aef7809dc04796f8e7388196ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Mar 2022 10:20:33 -0400 Subject: [PATCH 1675/6505] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 2564c9d1..20dd2c31 100644 --- a/README.md +++ b/README.md @@ -1076,6 +1076,14 @@ After the script completes, If you're dissatisfied with the default settings, cl ``` [PhotoSync](https://www.photosync-app.com/home.html) +⚙️ **To Update PhotoPrism** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/photoprism-update.sh)" +``` + + ____________________________________________________________________________________________
    From 1a41890e05683b8b76ddc5b1fa518838fd2bd132 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Mar 2022 10:22:34 -0400 Subject: [PATCH 1676/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index eba97e20..76592b47 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-16 + +### Changed + +- **PhotoPrism LXC** + - New Update/Branch Script + ## 2022-03-15 ### Changed From 1f4a5ecd5fd4b1f39c443bc87203107f4e4be58e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Mar 2022 17:42:54 -0400 Subject: [PATCH 1677/6505] Update dashy-update.sh --- misc/dashy-update.sh | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index f38228f7..141ac886 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -1,11 +1,34 @@ #!/usr/bin/env bash -set -e -RD=`echo "\033[01;31m"` +clear +YW=`echo "\033[33m"` BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +while true; do + read -p "This will Update Dashy LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done clear +function header_info { +echo -e "${RD} + _____ _ + | __ \ | | + | | | | __ _ ___| |__ _ _ + | | | |/ _ / __| _ \| | | | + | |__| | (_| \__ \ | | | |_| | + |_____/ \__,_|___/_| |_|\__, | + UPDATE __/ | + |___/ +${CL}" +} + +header_info echo -en "${GN} Stopping Dashy... " systemctl stop dashy sleep 1 From 056a2a8b74f0db56c4b3bd247d52fe6e5711cf0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Mar 2022 18:08:45 -0400 Subject: [PATCH 1678/6505] Update dashy-update.sh --- misc/dashy-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index 141ac886..a2ca3e42 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -41,7 +41,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Updating Dashy... " cd /dashy -git stash &>/dev/null +git merge &>/dev/null git pull origin master &>/dev/null yarn &>/dev/null yarn build &>/dev/null From 41bd62199ee8ab9abd6ab08294c67e3009ecf540 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Mar 2022 18:17:07 -0400 Subject: [PATCH 1679/6505] Update dashy-update.sh --- misc/dashy-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index a2ca3e42..2fd16c2a 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -e clear YW=`echo "\033[33m"` BL=`echo "\033[36m"` From 9f6e72c5df11365697d400004b54c84a9ab5081c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 06:59:04 -0400 Subject: [PATCH 1680/6505] Create docker-install.sh --- setup/docker-install.sh | 95 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 setup/docker-install.sh diff --git a/setup/docker-install.sh b/setup/docker-install.sh new file mode 100644 index 00000000..941aa6fc --- /dev/null +++ b/setup/docker-install.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Docker... " +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF +sh <(curl -sSL https://get.docker.com) &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 3e8712e96aa13af1584ddb2877d2fc89700e84b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:00:06 -0400 Subject: [PATCH 1681/6505] Create docker.sh --- ct/docker.sh | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 ct/docker.sh diff --git a/ct/docker.sh b/ct/docker.sh new file mode 100644 index 00000000..789d913e --- /dev/null +++ b/ct/docker.sh @@ -0,0 +1,258 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[94m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Docker LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _____ _ + | __ \ | | + | | | | ___ ___| | _____ _ __ + | | | |/ _ \ / __| |/ / _ \ __| + | |__| | (_) | (__| < __/ | + |_____/ \___/ \___|_|\_\___|_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done +show_menu3(){ + printf " ${YW} 1)${GN} If ZFS, Use fuse-overlayfs Storage Driver${CL}\n" + printf " ${YW} 2)${GN} Use Standard overlay2fs Storage Driver${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using fuse-overlayfs Storage Driver"; + SD=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using overlay2fs Storage Driver"; + SD="#" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Storage Driver Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1,mknod=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=4 +export PCT_OPTIONS=" + -features $FEATURES + -hostname docker + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + ${SD}wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +${SD}if [ "$STORAGE_TYPE" == "zfspool" ]; then +${SD}pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +${SD}info "${BL}Using fuse-overlayfs.${CL}" +${SD}fi +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/docker-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Docker LXC to${CL} ${BL}$CTID${CL}. \n" From 570ec0a5f16e8a1541c4b1fe74b102249dba80b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:03:28 -0400 Subject: [PATCH 1682/6505] Update docker.sh --- ct/docker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index 789d913e..0fd1bcac 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -127,7 +127,7 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" printf " ${YW}${message3}${CL}\n" } -show_menu2 +show_menu3 while [ $opt != '' ] do if [ $opt = '' ]; then @@ -153,7 +153,7 @@ while [ $opt != '' ] ;; *)clear; option_picked "Please choose a Storage Driver Type from the menu"; - show_menu2; + show_menu3; ;; esac fi From d8b769c1675f063435159ce22131057d53a6d517 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:07:24 -0400 Subject: [PATCH 1683/6505] Update docker.sh --- ct/docker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index 0fd1bcac..5d1c915a 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -117,7 +117,7 @@ show_menu3(){ printf " ${YW} 1)${GN} If ZFS, Use fuse-overlayfs Storage Driver${CL}\n" printf " ${YW} 2)${GN} Use Standard overlay2fs Storage Driver${CL}\n" - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + printf "Please choose a Storage Driver and hit enter or ${RD}x${CL} to exit." read opt } @@ -152,7 +152,7 @@ while [ $opt != '' ] \n)exit; ;; *)clear; - option_picked "Please choose a Storage Driver Type from the menu"; + option_picked "Please choose a Storage Driver from the menu"; show_menu3; ;; esac From 8beeb0e0e7086fc3957fc2dc26896032b2fc2b21 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:11:56 -0400 Subject: [PATCH 1684/6505] Update docker.sh --- ct/docker.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index 5d1c915a..77a526c0 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -243,7 +243,8 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID -${SD}if [ "$STORAGE_TYPE" == "zfspool" ]; then +${SD}if [ "$STORAGE_TYPE" == "zfspool" ]; +${SD}then ${SD}pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 ${SD}info "${BL}Using fuse-overlayfs.${CL}" ${SD}fi From 44c55543185bfb6b1b2ffb8a293ac3e29a6f37fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:17:18 -0400 Subject: [PATCH 1685/6505] Update docker.sh --- ct/docker.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index 77a526c0..91a83199 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -143,7 +143,7 @@ while [ $opt != '' ] 2) clear; header_info; option_picked "Using overlay2fs Storage Driver"; - SD="#" + SD="###" break; ;; @@ -243,11 +243,11 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID -${SD}if [ "$STORAGE_TYPE" == "zfspool" ]; -${SD}then -${SD}pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -${SD}info "${BL}Using fuse-overlayfs.${CL}" -${SD}fi +${SD} if [ "$STORAGE_TYPE" == "zfspool" ]; +${SD} then +${SD} pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +${SD} info "${BL}Using fuse-overlayfs.${CL}" +${SD} fi echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" From eccdf3ab1c90f139c60cd1c93004b47cc1df739f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:27:34 -0400 Subject: [PATCH 1686/6505] Update docker.sh --- ct/docker.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index 91a83199..e04bb30e 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -143,7 +143,7 @@ while [ $opt != '' ] 2) clear; header_info; option_picked "Using overlay2fs Storage Driver"; - SD="###" + SD="# " break; ;; @@ -243,11 +243,10 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID -${SD} if [ "$STORAGE_TYPE" == "zfspool" ]; -${SD} then -${SD} pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -${SD} info "${BL}Using fuse-overlayfs.${CL}" -${SD} fi + if [ "$STORAGE_TYPE" == "zfspool" ]; then +${SD}pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 +${SD}info "${BL}Using fuse-overlayfs.${CL}" + fi echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" From ea623d17088eb51588c37c9a0913655b3a824d48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:48:38 -0400 Subject: [PATCH 1687/6505] Update docker.sh --- ct/docker.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index e04bb30e..0493cb8e 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -137,13 +137,13 @@ while [ $opt != '' ] 1) clear; header_info; option_picked "Using fuse-overlayfs Storage Driver"; - SD=" " + STORAGE_DRIVER="fuse" break; ;; 2) clear; header_info; option_picked "Using overlay2fs Storage Driver"; - SD="# " + STORAGE_DRIVER=" " break; ;; @@ -206,7 +206,7 @@ function cleanup() { rm -rf $TEMP_DIR } if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1,mknod=1" + FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi @@ -231,8 +231,8 @@ export PCT_OPTIONS=" bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - ${SD}wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 +if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf @@ -243,9 +243,9 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID - if [ "$STORAGE_TYPE" == "zfspool" ]; then -${SD}pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -${SD}info "${BL}Using fuse-overlayfs.${CL}" + if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 + info "${BL}Using fuse-overlayfs.${CL}" fi echo -e "${CM}${CL} \r" From 5540fbd8d311264277d001657dbe59097eacac22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 07:59:42 -0400 Subject: [PATCH 1688/6505] Update docker.sh --- ct/docker.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index 0493cb8e..7a46c1ea 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -114,7 +114,8 @@ while [ $opt != '' ] fi done show_menu3(){ - printf " ${YW} 1)${GN} If ZFS, Use fuse-overlayfs Storage Driver${CL}\n" + printf " ${YW} If ZFS, You Have Storage Driver Options${CL}\n" + printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" printf " ${YW} 2)${GN} Use Standard overlay2fs Storage Driver${CL}\n" printf "Please choose a Storage Driver and hit enter or ${RD}x${CL} to exit." @@ -246,6 +247,7 @@ pct start $CTID if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 info "${BL}Using fuse-overlayfs.${CL}" + info "${BL}Select FUSE in Options >> Features.${CL}" fi echo -e "${CM}${CL} \r" From 31dd738e9ac2f09d07a8a87b547cab840a8cf2a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 08:08:02 -0400 Subject: [PATCH 1689/6505] Update docker.sh --- ct/docker.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index 7a46c1ea..918d9a03 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -206,8 +206,14 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } - if [ "$IM" == "1" ]; then + if [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == " " ]; then FEATURES="nesting=1,keyctl=1" + elif + [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + FEATURES="nesting=1,keyctl=1,fuse=1" + elif + [ "$IM" == "0" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + FEATURES="nesting=1,keyctl=1,fuse=1" else FEATURES="nesting=1" fi @@ -247,7 +253,6 @@ pct start $CTID if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 info "${BL}Using fuse-overlayfs.${CL}" - info "${BL}Select FUSE in Options >> Features.${CL}" fi echo -e "${CM}${CL} \r" From afde4dcd559ab5e16c04f384eda29da8b29bf8e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 08:15:40 -0400 Subject: [PATCH 1690/6505] Update docker.sh --- ct/docker.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/docker.sh b/ct/docker.sh index 918d9a03..03cba689 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -115,6 +115,7 @@ while [ $opt != '' ] done show_menu3(){ printf " ${YW} If ZFS, You Have Storage Driver Options${CL}\n" + printf " ${YW} Non ZFS, Select Standard overlay2fs Storage Driver${CL}\n" printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" printf " ${YW} 2)${GN} Use Standard overlay2fs Storage Driver${CL}\n" From b7ed7db0db9f1b8fe5ad24e4e72c4eba505c2da9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 08:17:25 -0400 Subject: [PATCH 1691/6505] Update docker.sh --- ct/docker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index 03cba689..63a3cf1c 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -114,8 +114,8 @@ while [ $opt != '' ] fi done show_menu3(){ - printf " ${YW} If ZFS, You Have Storage Driver Options${CL}\n" - printf " ${YW} Non ZFS, Select Standard overlay2fs Storage Driver${CL}\n" + printf " ${RD} If ZFS, You Have Storage Driver Options${CL}\n" + printf " ${RD} Non ZFS, Select Standard overlay2fs Storage Driver${CL}\n" printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" printf " ${YW} 2)${GN} Use Standard overlay2fs Storage Driver${CL}\n" From 5587010d4bce9ee7595e122acba0ef76fb089053 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 09:44:33 -0400 Subject: [PATCH 1692/6505] Update docker.sh --- ct/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index 63a3cf1c..235e44c3 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -114,7 +114,7 @@ while [ $opt != '' ] fi done show_menu3(){ - printf " ${RD} If ZFS, You Have Storage Driver Options${CL}\n" + printf " ${RD} If Using ZFS, You Have Storage Driver Options${CL}\n" printf " ${RD} Non ZFS, Select Standard overlay2fs Storage Driver${CL}\n" printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" printf " ${YW} 2)${GN} Use Standard overlay2fs Storage Driver${CL}\n" From 14d3476878842e0f1f7412a1ca2d9260a57c24af Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 09:59:39 -0400 Subject: [PATCH 1693/6505] Update docker.sh --- ct/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index 235e44c3..b68ba244 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -214,7 +214,7 @@ function cleanup() { FEATURES="nesting=1,keyctl=1,fuse=1" elif [ "$IM" == "0" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then - FEATURES="nesting=1,keyctl=1,fuse=1" + FEATURES="nesting=1,fuse=1" else FEATURES="nesting=1" fi From 9ac1b88309827fbb7374f49e1f38b83d5bb81569 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 12:56:28 -0400 Subject: [PATCH 1694/6505] Update docker.sh --- ct/docker.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index b68ba244..b7f13aa0 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -115,9 +115,9 @@ while [ $opt != '' ] done show_menu3(){ printf " ${RD} If Using ZFS, You Have Storage Driver Options${CL}\n" - printf " ${RD} Non ZFS, Select Standard overlay2fs Storage Driver${CL}\n" + printf " ${RD} Non ZFS, Select Standard overlay2 Storage Driver${CL}\n" printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" - printf " ${YW} 2)${GN} Use Standard overlay2fs Storage Driver${CL}\n" + printf " ${YW} 2)${GN} Use Standard overlay2 Storage Driver${CL}\n" printf "Please choose a Storage Driver and hit enter or ${RD}x${CL} to exit." read opt @@ -144,7 +144,7 @@ while [ $opt != '' ] ;; 2) clear; header_info; - option_picked "Using overlay2fs Storage Driver"; + option_picked "Using overlay2 Storage Driver"; STORAGE_DRIVER=" " break; ;; @@ -253,7 +253,9 @@ echo -en "${GN} Starting LXC Container... " pct start $CTID if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 - info "${BL}Using fuse-overlayfs.${CL}" + info "${BL}Using fuse-overlayfs Storage Driver.${CL}" + else + info "${BL}Using overlay2 Storage Driver.${CL}" fi echo -e "${CM}${CL} \r" From 0e2fb7769ec8b4e22b1663fc53c9d89fee09635f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 13:02:19 -0400 Subject: [PATCH 1695/6505] Update docker.sh --- ct/docker.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index b7f13aa0..6631b064 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -251,13 +251,14 @@ EOF echo -en "${GN} Starting LXC Container... " pct start $CTID +echo -e "${CM}${CL} \r" + if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 info "${BL}Using fuse-overlayfs Storage Driver.${CL}" else info "${BL}Using overlay2 Storage Driver.${CL}" fi -echo -e "${CM}${CL} \r" alias lxc-cmd="lxc-attach -n $CTID --" From 2a8505fbfe3ccc703320832ae60be750b035e9bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 13:13:18 -0400 Subject: [PATCH 1696/6505] Update docker.sh --- ct/docker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index 6631b064..c8fe010a 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -255,9 +255,9 @@ echo -e "${CM}${CL} \r" if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 - info "${BL}Using fuse-overlayfs Storage Driver.${CL}" + info "Using ${BL}fuse-overlayfs${CL} Storage Driver." else - info "${BL}Using overlay2 Storage Driver.${CL}" + info "Using ${BL}overlay2${CL} Storage Driver." fi alias lxc-cmd="lxc-attach -n $CTID --" From 4bce10c0b60e1965e4223704f283c6d10f19ddbb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 13:19:31 -0400 Subject: [PATCH 1697/6505] Update docker.sh --- ct/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index c8fe010a..110a0b7c 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash YW=`echo "\033[33m"` -BL=`echo "\033[94m"` +BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` From a58f1a8ebd671f61fee0684a5afe98ac41c6073a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 14:52:04 -0400 Subject: [PATCH 1698/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 20dd2c31..71dbdda7 100644 --- a/README.md +++ b/README.md @@ -928,6 +928,8 @@ ________________________________________________________________________________

    Jellyfin Media Server LXC

    +[TurnKey has a LXC CT for Jellyfin](https://www.turnkeylinux.org/mediaserver) + To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. ```yaml From b4cdf90cb23a475c565ad576f3063038fdca7828 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 16:33:55 -0400 Subject: [PATCH 1699/6505] Add files via upload --- misc/images/docker.png | Bin 0 -> 49776 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/docker.png diff --git a/misc/images/docker.png b/misc/images/docker.png new file mode 100644 index 0000000000000000000000000000000000000000..210598c29e4e83090b4df0a8cd2ca424c37d61a9 GIT binary patch literal 49776 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 literal 0 HcmV?d00001 From a1dec0f324db71120e562ab724f9c24f411a79b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 16:48:33 -0400 Subject: [PATCH 1700/6505] Update README.md --- README.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 71dbdda7..9ce34aeb 100644 --- a/README.md +++ b/README.md @@ -802,6 +802,35 @@ ________________________________________________________________________________
    +
    + 🔸Docker LXC + +

    + +

    Docker LXC

    +

    With Selectable Storage Drivers

    + +To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/docker.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +⚙️ **To Update** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    +
    Debian 11 LXC @@ -1242,7 +1271,7 @@ ________________________________________________________________________________
    - 🔸Vaultwarden LXC + Vaultwarden LXC

    From 2ea655b3c71c32007ec3405f0488247dc5b886ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 16:48:41 -0400 Subject: [PATCH 1701/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 76592b47..e691746a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-17 + +### Changed + +- **Docker LXC** + - New Script V2 + ## 2022-03-16 ### Changed From fe45be47249683adb475a6488b1f5878af93bd64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 17:31:17 -0400 Subject: [PATCH 1702/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 4d738ba0..2655b8b8 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -68,6 +68,8 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Adminer... " sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null +mkdir /var/log/apache2 +chmod 750 /var/log/apache2 sudo systemctl reload apache2 &>/dev/null echo -e "${CM}${CL} \r" From 03b675b58e256c530aa5dbb222c0239d3c6a94f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 17:40:00 -0400 Subject: [PATCH 1703/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 2655b8b8..d8cec842 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -68,8 +68,6 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Adminer... " sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null -mkdir /var/log/apache2 -chmod 750 /var/log/apache2 sudo systemctl reload apache2 &>/dev/null echo -e "${CM}${CL} \r" @@ -95,4 +93,6 @@ echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +mkdir /var/log/apache2 +chmod 750 /var/log/apache2 echo -e "${CM}${CL} \n" From cb344cd045d42541b117aba6f359f5a3d994fea0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Mar 2022 17:55:07 -0400 Subject: [PATCH 1704/6505] Update mariadb.sh --- ct/mariadb.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 920e0fa0..7776ba36 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -201,4 +201,6 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. \n" +echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. +${BL}Adminer${CL} should be reachable by going to the following URL. + ${BL}http://${IP}/adminer/${CL} \n" From bbfa8ee1f2372b437f8f6edc426df7e2a60ac0f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 07:05:33 -0400 Subject: [PATCH 1705/6505] Create technitiumdns.sh --- ct/technitiumdns.sh | 213 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 ct/technitiumdns.sh diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh new file mode 100644 index 00000000..7a66d1b8 --- /dev/null +++ b/ct/technitiumdns.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Technitium DNS" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + _______ _ _ _ _ + |__ __| | | (_) | (_) + | | ___ ___| |__ _ __ _| |_ _ _ _ _ __ ___ + | |/ _ \/ __| _ \| _ \| | __| | | | | _ _ \ + | | __/ (__| | | | | | | | |_| | |_| | | | | | | + |_|\___|\___|_| |_|_| |_|_|\__|_|\__,_|_| |_| |_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:5380${CL} \n" From bda90eaf9cf2ce3c774a93a6e48f9709e4d0f54d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 07:06:31 -0400 Subject: [PATCH 1706/6505] Create technitiumdns-install.sh --- setup/technitiumdns-install.sh | 88 ++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 setup/technitiumdns-install.sh diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh new file mode 100644 index 00000000..3f258dce --- /dev/null +++ b/setup/technitiumdns-install.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Technitium DNS... " +curl -sSL https://download.technitium.com/dns/install.sh | sudo bash &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 0137e70d1b2e5fc84aeab31481de7241525ecf68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 07:30:18 -0400 Subject: [PATCH 1707/6505] Create technitiumdns-update.sh --- misc/technitiumdns-update.sh | 76 ++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 misc/technitiumdns-update.sh diff --git a/misc/technitiumdns-update.sh b/misc/technitiumdns-update.sh new file mode 100644 index 00000000..3f2b7c75 --- /dev/null +++ b/misc/technitiumdns-update.sh @@ -0,0 +1,76 @@ +#!/bin/sh +set -e +dotnetDir="/opt/dotnet" +dnsDir="/etc/dns" +dnsTar="/etc/dns/DnsServerPortable.tar.gz" +dnsUrl="https://download.technitium.com/dns/DnsServerPortable.tar.gz" + +mkdir -p $dnsDir +installLog="$dnsDir/install.log" +echo "" > $installLog + +echo "" +echo "===============================" +echo "Technitium DNS Server Update" +echo "===============================" + +if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 5.0."; +then + dotnetFound="yes" +else + dotnetFound="no" +fi + + if [ -d $dotnetDir ] + then + dotnetUpdate="yes" + echo "Updating .NET 5 Runtime..." + fi + + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 5.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >> $installLog 2>&1 + + if [ ! -f "/usr/bin/dotnet" ] + then + ln -s $dotnetDir/dotnet /usr/bin >> $installLog 2>&1 + fi + + if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 5.0."; + then + if [ "$dotnetUpdate" = "yes" ] + then + echo ".NET 5 Runtime was updated successfully!" + fi + else + echo "Failed to update .NET 5 Runtime. Please try again." + exit 1 + fi + +if curl -o $dnsTar --fail $dnsUrl >> $installLog 2>&1 +then + if [ -d $dnsDir ] + then + echo "Updating Technitium DNS Server..." + fi + + tar -zxf $dnsTar -C $dnsDir >> $installLog 2>&1 + + if [ "$(ps --no-headers -o comm 1 | tr -d '\n')" = "systemd" ] + then + if [ -f "/etc/systemd/system/dns.service" ] + then + echo "Restarting systemd service..." + systemctl restart dns.service >> $installLog 2>&1 + fi + + echo "" + echo "Technitium DNS Server was updated successfully!" + else + echo "" + echo "Failed to update Technitium DNS Server: systemd was not detected." + exit 1 + fi +else + echo "" + echo "Failed to download Technitium DNS Server from: $dnsUrl" + exit 1 +fi From 7ba4d7c1ca91a9f3219fb24cc5de61551221568c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 07:34:59 -0400 Subject: [PATCH 1708/6505] Update README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 9ce34aeb..f7f52db0 100644 --- a/README.md +++ b/README.md @@ -1011,6 +1011,32 @@ ________________________________________________________________________________
    +
    + 🔸Technitium DNS LXC + +

    + +

    Technitium DNS LXC

    +An open source authoritative as well as recursive DNS server + +To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell (V2). + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/technitiumdns.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Technitium DNS Interface - IP:5380** + +⚙️ **To Update** + +```yaml +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/technitiumdns-update.sh)" +``` +__________________________________________________________________________________________ + +
    From f398292bf24e99559625296c5735dedc4ea7d25a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 07:36:53 -0400 Subject: [PATCH 1709/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e691746a..8b6e7aef 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-18 + +### Changed + +- **Technitium DNS LXC** + - New Script V2 + ## 2022-03-17 ### Changed From c1f5da22f3d9d1e2d3d8963aff1c3a501b1ed8c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 09:09:22 -0400 Subject: [PATCH 1710/6505] Update README.md --- README.md | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/README.md b/README.md index f7f52db0..e94d412d 100644 --- a/README.md +++ b/README.md @@ -888,35 +888,6 @@ ________________________________________________________________________________
    -
    - GamUntu LXC -

    GamUntu

    -

    GamUntu LXC

    - -GamUntu is Ubuntu 21.10, Docker, Docker Compose, ZFS Support, USB Passthrough, Webmin System Administration and Hardware Acceleration all baked in! - -To create a new Proxmox GamUntu LXC, run the following in the Proxmox Shell (V2). - -```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/gamuntu.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - -**Webmin Interface - https:// IP:10000 (https)** - -⚙️ **To Update GamUntu** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    -
    Plex Media Server LXC From bbbe5ccaf482ee69cf55a22350c33969fe378670 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 10:28:35 -0400 Subject: [PATCH 1711/6505] Update wireguard.sh --- ct/wireguard.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 92856500..70930cc8 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -22,6 +22,7 @@ echo -e "${RD} \ \/ \/ / | | __/ _ \ | |_ | | | |/ _ | __/ _ | \ /\ / | | | | __/ |__| | |_| | (_| | | | (_| | \/ \/ |_|_| \___|\_____|\__,_|\__,_|_| \__,_| + ${YW}With WGDashboard ${CL}" } @@ -201,4 +202,5 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') echo -e "${GN}Successfully created WireGuard LXC to${CL} ${BL}$CTID${CL}. - \n" +${BL}WGDashboard${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:10086${CL} \n" From ef395109e8a3a392cd1f74a552b30727e2fcdf19 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 10:29:21 -0400 Subject: [PATCH 1712/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index d47b4a42..2309f036 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -73,6 +73,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Dependencies... " apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y gunicorn &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing WireGuard (using pivpn.io)... " @@ -80,7 +81,42 @@ curl -s -L https://install.pivpn.io > install.sh chmod +x install.sh ./install.sh --unattended options.conf &>/dev/null echo -e "${CM}${CL} \r" - + +echo -en "${GN} Installing pip3... " +apt-get install python3-pip -y &>/dev/null +pip install flask &>/dev/null +pip install ifcfg &>/dev/null +pip install flask_qrcode &>/dev/null +pip install icmplib &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing WGDashboard... " +git clone -b v3.0.5 https://github.com/donaldzou/WGDashboard.git /ect/wgdashboard &>/dev/null +cd /ect/wgdashboard/src +sudo chmod u+x wgd.sh +sudo ./wgd.sh install &>/dev/null +sudo chmod -R 755 /etc/wireguard +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating wg-dashboard.service... " +service_path="/etc/systemd/system/wg-dashboard.service" +echo "[Unit] +After=netword.service + +[Service] +WorkingDirectory=/ect/wgdashboard/src +ExecStart=/usr/bin/python3 /ect/wgdashboard/src/dashboard.py +Restart=always + + +[Install] +WantedBy=default.target" > $service_path +sudo chmod 664 /etc/systemd/system/wg-dashboard.service +sudo systemctl daemon-reload +sudo systemctl enable wg-dashboard.service &>/dev/null +sudo systemctl start wg-dashboard.service +echo -e "${CM}${CL} \r" + PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " From 57b780bc561a053e1f2d0e004a8df5c37dab9a37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 10:37:04 -0400 Subject: [PATCH 1713/6505] Update README.md --- README.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e94d412d..2939e6a5 100644 --- a/README.md +++ b/README.md @@ -1184,7 +1184,7 @@ ________________________________________________________________________________
    -Webmin System Administration + Webmin System Administration

    @@ -1229,12 +1229,13 @@ ________________________________________________________________________________
    - WireGuard LXC + 🔸WireGuard LXC

    WireGuard LXC

    - +

    With WGDashboard

    + To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell (V2). ``` @@ -1245,6 +1246,19 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/w After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. +**WGDashboard Interface - http:// IP:10086** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` + ⚙️ **Host Configuration** Run in the LXC console From eef89a1c745c78391e021566e221fbb8442fb251 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 10:38:12 -0400 Subject: [PATCH 1714/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 8b6e7aef..f92ca315 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file. - **Technitium DNS LXC** - New Script V2 +- **WireGuard LXC** + - Add WGDashboard ## 2022-03-17 From 4f370fcf70efa3305db6a1d98f385c6fed73726e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 10:42:22 -0400 Subject: [PATCH 1715/6505] Update wireguard.sh --- ct/wireguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 70930cc8..d254a211 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -6,7 +6,7 @@ CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` while true; do - read -p "This will create a New WireGuard LXC (using pivpn.io). Proceed(y/n)?" yn + read -p "This will create a New WireGuard LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From 06349833df62119052ed5ab2800263235dd2333e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 10:50:53 -0400 Subject: [PATCH 1716/6505] Update wireguard.sh --- ct/wireguard.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index d254a211..18ffad5c 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -202,5 +202,6 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') echo -e "${GN}Successfully created WireGuard LXC to${CL} ${BL}$CTID${CL}. + ${BL}WGDashboard${CL} should be reachable by going to the following URL. ${BL}http://${IP}:10086${CL} \n" From 51b2d151e067e83f1dbadd91d7a179c8b12cd18f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 12:58:32 -0400 Subject: [PATCH 1717/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 2309f036..3524fef9 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -91,7 +91,11 @@ pip install icmplib &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing WGDashboard... " -git clone -b v3.0.5 https://github.com/donaldzou/WGDashboard.git /ect/wgdashboard &>/dev/null +WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ + +git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /ect/wgdashboard &>/dev/null cd /ect/wgdashboard/src sudo chmod u+x wgd.sh sudo ./wgd.sh install &>/dev/null From 513f6de676953bbf00be1ea5f64581cb22d7ffe7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 14:13:02 -0400 Subject: [PATCH 1718/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 3524fef9..037a5eb6 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -48,6 +48,10 @@ done echo -e "${CM}${CL} \r" echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " echo -e "${CM}${CL} \r" +MAC=$(cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address) +echo -en "${GN} MAC Address: ${BL}${MAC}${CL} " +echo -e "${CM}${CL} \r" + OPTIONS_PATH='/options.conf' cat >$OPTIONS_PATH <<'EOF' IPv4dev=eth0 From 4ade2bd47e0b54b33c00b9ba0ba597fe5daaf8fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 15:21:20 -0400 Subject: [PATCH 1719/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index cc406fc0..3f51512d 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -16,15 +16,12 @@ done clear function header_info { echo -e "${RD} - _ _ _ _____ __ __ - | \ | | (_) | __ \ | \/ | - | \| | __ _ _ _ __ __ __ | |__) | __ _____ ___ _ | \ / | __ _ _ __ __ _ __ _ ___ _ __ - | |/ _ | | _ \\ \/ / | ___/ __/ _ \ \/ / | | | | |\/| |/ _ | _ \ / _ |/ _ |/ _ \ __| - | |\ | (_| | | | | |> < | | | | | (_) > <| |_| | | | | | (_| | | | | (_| | (_| | __/ | - |_| \_|\__, |_|_| |_/_/\_\ |_| |_| \___/_/\_\\__, | |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| - __/ | __/ | __/ | - |___/ |___/ |___/ - + _ _ _____ __ __ + | \ | | __ \| \/ | + | \| | |__) | \ / | + | | ___/| |\/| | + | |\ | | | | | | + |_| \_|_| |_| |_| ${CL}" } From c16703f78a1df513ee3e5976b31fff181de05555 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 18 Mar 2022 18:56:11 -0400 Subject: [PATCH 1720/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index ee50d424..d0a50072 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -89,7 +89,7 @@ Restart=always User=root [Install] WantedBy=multi-user.target" > $service_path - +systemctl enable zigbee2mqtt.service &>/dev/null PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " From ed23baadcee0b47c8567427a57f068a1ffb2a11e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 10:39:51 -0400 Subject: [PATCH 1721/6505] Update wireguard.sh --- ct/wireguard.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 18ffad5c..bb31d6e2 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,6 +114,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -190,6 +235,14 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +pct config $CTID | grep -i hwaddr +dhcp_reservation(){ + printf "Please set DHCP Reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From fcb8aafa5977aa8feee933cdd9f9f457fcd2ab21 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 11:45:53 -0400 Subject: [PATCH 1722/6505] Update wireguard.sh --- ct/wireguard.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index bb31d6e2..e6774094 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -236,9 +236,14 @@ if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi if [ "$DHCP" == "1" ]; then -pct config $CTID | grep -i hwaddr +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + dhcp_reservation(){ - printf "Please set DHCP Reservation and press Enter." + printf "Please set DHCP reservation and press Enter." read } dhcp_reservation From 3280f46dae1bbc43f9060c165f7d28763fcf9298 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:26:05 -0400 Subject: [PATCH 1723/6505] Update adguard.sh --- ct/adguard.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index 69e27ea8..ac8278f8 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -82,9 +82,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -117,6 +117,52 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done + set -o errexit set -o errtrace set -o nounset @@ -192,6 +238,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 7936bda04baf9e0c16050f95f8db0d854592984f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:27:31 -0400 Subject: [PATCH 1724/6505] Update daemonsync.sh --- ct/daemonsync.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index 0a12272b..c6403ba5 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -80,9 +80,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -115,6 +115,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -191,6 +236,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 305d8b1dc248041903ab2d48fd631981aa05a798 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:31:54 -0400 Subject: [PATCH 1725/6505] Update dashy.sh --- ct/dashy.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index 67d42563..fc62084b 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -81,9 +81,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -116,6 +116,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -192,6 +237,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 556773c7b24579bbe10c3a593bab45ef22d0eb37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:33:58 -0400 Subject: [PATCH 1726/6505] Update debian.sh --- ct/debian.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index b5898aaa..d36b6e82 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -81,9 +81,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -116,6 +116,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -197,6 +242,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From c43fc18705c75bea54d994b38511501a237f4000 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:37:11 -0400 Subject: [PATCH 1727/6505] Update docker.sh --- ct/docker.sh | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/ct/docker.sh b/ct/docker.sh index 110a0b7c..a5e5096e 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -160,6 +160,52 @@ while [ $opt != '' ] esac fi done +show_menu4(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message4=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" + printf " ${YW}${message4}${CL}\n" +} +show_menu4 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu4; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -248,6 +294,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 9b42d48f5ebc21650f96720faafc36956a5edfd1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:41:00 -0400 Subject: [PATCH 1728/6505] Update esphome.sh --- ct/esphome.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index 52eacea5..06f9d513 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -81,9 +81,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -116,6 +116,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -197,6 +242,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From ec5d19e41031a5a0db21641d86f1d5c4364a0458 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:42:15 -0400 Subject: [PATCH 1729/6505] Update grafana.sh --- ct/grafana.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/grafana.sh b/ct/grafana.sh index de689df1..0e7244df 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,6 +114,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -190,6 +235,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 1ea03657315231579e880832ad47f4bad80b385f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:49:13 -0400 Subject: [PATCH 1730/6505] Update homeassistant.sh --- ct/homeassistant.sh | 127 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 4 deletions(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 54afbe11..61e0eaf9 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,7 +114,100 @@ while [ $opt != '' ] esac fi done - +show_menu3(){ + printf " ${RD} If Using ZFS, You Have Storage Driver Options${CL}\n" + printf " ${RD} Non ZFS, Select Standard overlay2 Storage Driver${CL}\n" + printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" + printf " ${YW} 2)${GN} Use Standard overlay2 Storage Driver${CL}\n" + + printf "Please choose a Storage Driver and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using fuse-overlayfs Storage Driver"; + STORAGE_DRIVER="fuse" + break; + ;; + 2) clear; + header_info; + option_picked "Using overlay2 Storage Driver"; + STORAGE_DRIVER=" " + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Storage Driver from the menu"; + show_menu3; + ;; + esac + fi + done +show_menu4(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message4=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" + printf " ${YW}${message4}${CL}\n" +} +show_menu4 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu4; + ;; + esac + fi + done + set -o errexit set -o errtrace set -o nounset @@ -161,8 +254,14 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } - if [ "$IM" == "1" ]; then + if [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == " " ]; then FEATURES="nesting=1,keyctl=1" + elif + [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + FEATURES="nesting=1,keyctl=1,fuse=1" + elif + [ "$IM" == "0" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + FEATURES="nesting=1,fuse=1" else FEATURES="nesting=1" fi @@ -195,11 +294,31 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID echo -e "${CM}${CL} \r" + if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 + info "Using ${BL}fuse-overlayfs${CL} Storage Driver." + else + info "Using ${BL}overlay2${CL} Storage Driver." + fi + alias lxc-cmd="lxc-attach -n $CTID --" lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit From e13011ca6a4f9e97d5cd978ae6eba77b14ce092f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:52:55 -0400 Subject: [PATCH 1731/6505] Update homebridge.sh --- ct/homebridge.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index e4bd0871..8f6eb118 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -78,9 +78,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -113,6 +113,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -189,6 +234,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 0aa58706531fd852b0ed46b37db8ce8d837ade2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:53:51 -0400 Subject: [PATCH 1732/6505] Update influxdb.sh --- ct/influxdb.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 4bf9b405..119d2a4e 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,6 +114,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -190,6 +235,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 0e0c6272b75244d55b18dd435bdc08610dd06d7a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:55:58 -0400 Subject: [PATCH 1733/6505] Update mariadb.sh --- ct/mariadb.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 7776ba36..73e2134a 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,6 +114,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -190,6 +235,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From ec93d0968b0d9dbefaec77c8f46c0d5187f1b99a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:57:16 -0400 Subject: [PATCH 1734/6505] Update motioneye.sh --- ct/motioneye.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 23332a38..92894a21 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -80,9 +80,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -115,6 +115,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -196,6 +241,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 7ffc9508d5083489a66b9b5bc2270f3625ca9275 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:58:27 -0400 Subject: [PATCH 1735/6505] Update mqtt.sh --- ct/mqtt.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 315a9e9e..254f4619 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,6 +114,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -190,6 +235,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From b35ede13b91a99ec164ef9b4b93a1b1dbac47b7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 12:59:51 -0400 Subject: [PATCH 1736/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 62 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index 3f51512d..670cbdcd 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -78,9 +78,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -113,6 +113,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -189,6 +234,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From fbcb26cfaef021e848809236082464ee3f892233 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:00:53 -0400 Subject: [PATCH 1737/6505] Update node-red.sh --- ct/node-red.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index b75eb47d..504ddc71 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,6 +114,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -190,6 +235,19 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From ccaf83a02a2390e84d91aa23b3f4c7525ccc9c5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:02:06 -0400 Subject: [PATCH 1738/6505] Update photoprism.sh --- ct/photoprism.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index ec2325ad..076aefef 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -81,9 +81,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -116,6 +116,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -197,6 +242,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 12bedcae6ad5fbef5087bbe0e5935f92fc2d8cfb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:03:29 -0400 Subject: [PATCH 1739/6505] Update pihole.sh --- ct/pihole.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/pihole.sh b/ct/pihole.sh index 870c883c..2667f184 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -80,9 +80,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -115,6 +115,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -196,6 +241,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From fb435da0e41df2c15c8659cb1cf154272b0d848f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:04:49 -0400 Subject: [PATCH 1740/6505] Update technitiumdns.sh --- ct/technitiumdns.sh | 62 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index 7a66d1b8..15ffdf42 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -81,9 +81,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -116,6 +116,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -197,6 +242,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 0908630416698b3afba37eb088cf8b6efcff9f4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:05:53 -0400 Subject: [PATCH 1741/6505] Update ubuntu.sh --- ct/ubuntu.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index d187fb95..d24150a7 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -79,9 +79,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -114,6 +114,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -195,6 +240,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 3bac36c4b4a6ccd6bc48915cb07d215b282efee0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:07:10 -0400 Subject: [PATCH 1742/6505] Update vaultwarden.sh --- ct/vaultwarden.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index c81d099c..6e8c43b7 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -81,9 +81,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -116,6 +116,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -197,6 +242,19 @@ cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 34d0cd7121146badde2998c6149b7029e358bd9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:08:21 -0400 Subject: [PATCH 1743/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 0b0e222b..9d0edba5 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -81,9 +81,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -116,6 +116,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -203,6 +248,19 @@ lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create= lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 64acabc3f8610708451b235ba08dee632e3eb588 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:09:18 -0400 Subject: [PATCH 1744/6505] Update zwavejs2mqtt.sh --- ct/zwavejs2mqtt.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/ct/zwavejs2mqtt.sh b/ct/zwavejs2mqtt.sh index 9e66ab47..65034e6c 100644 --- a/ct/zwavejs2mqtt.sh +++ b/ct/zwavejs2mqtt.sh @@ -82,9 +82,9 @@ show_menu2(){ } option_picked(){ - message=${@:-"${CL}Error: No message passed"} + message2=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" + printf " ${YW}${message2}${CL}\n" } show_menu2 while [ $opt != '' ] @@ -117,6 +117,51 @@ while [ $opt != '' ] esac fi done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done set -o errexit set -o errtrace @@ -204,6 +249,19 @@ lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 12c0838fad7975eef005cb6e7309e9245c8bac9b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:20:07 -0400 Subject: [PATCH 1745/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f92ca315..87cc157b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-20 + +### Changed + +- **Scripts** (V2) + - ADD choose between Automatic or Manual DHCP reservation + ## 2022-03-18 ### Changed From 9bdbfd8426aabcb1c0ee9e5c1ad4647e47b4c6e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:25:34 -0400 Subject: [PATCH 1746/6505] Update homeassistant.sh --- ct/homeassistant.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 61e0eaf9..c34df4b6 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -286,7 +286,8 @@ export PCT_OPTIONS=" bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then +if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then + wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf From 456919dfa59411ab8c899d5d24f769ab0dd5c44a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:40:49 -0400 Subject: [PATCH 1747/6505] Update homeassistant.sh --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index c34df4b6..030d3157 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -286,7 +286,7 @@ export PCT_OPTIONS=" bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then +if [ "$STORAGE_TYPE" == "zfspool" ]; then wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi From 3b4156b530e68e5e863f3279cf8ce87e723a8871 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 13:41:48 -0400 Subject: [PATCH 1748/6505] Update docker.sh --- ct/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index a5e5096e..d885d263 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -285,7 +285,7 @@ export PCT_OPTIONS=" bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then +if [ "$STORAGE_TYPE" == "zfspool" ]; then wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi From 8e5bfde43be7ddf780f94f3efb3eddc9f1872164 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 15:20:37 -0400 Subject: [PATCH 1749/6505] Update docker.sh --- ct/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index d885d263..b1ad914a 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -287,7 +287,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 - warn "Some addons may not work due to ZFS not supporting 'fallocate'." + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG From dca41e5f0b530c43fe79639df4018b0a33d9d071 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 15:21:19 -0400 Subject: [PATCH 1750/6505] Update homeassistant.sh --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 030d3157..e25ce4d5 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -288,7 +288,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 - warn "Some addons may not work due to ZFS not supporting 'fallocate'." + warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG From 1240cb76885c73f291df85e3ecc34c3f5ed49f17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 17:09:42 -0400 Subject: [PATCH 1751/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 1b40a48a..45b25e4b 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -21,6 +21,13 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` @@ -63,7 +70,7 @@ echo -en "${GN} Installing pip3... " apt-get install -y python3-pip &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Docker... " +echo -en "${GN} Installing Docker $DOCKER_LATEST_VERSION... " DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) cat >$DOCKER_CONFIG_PATH <<'EOF' @@ -74,11 +81,11 @@ EOF sh <(curl -sSL https://get.docker.com) &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Pulling Portainer Image... " +echo -en "${GN} Pulling Portainer Image $PORTAINER_LATEST_VERSION... " docker pull portainer/portainer-ce:latest &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Portainer Image... " +echo -en "${GN} Installing Portainer $PORTAINER_LATEST_VERSION... " docker volume create portainer_data >/dev/null docker run -d \ -p 8000:8000 \ @@ -90,11 +97,11 @@ docker run -d \ portainer/portainer-ce:latest &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Pulling Home Assistant Image... " +echo -en "${GN} Pulling Home Assistant Image $CORE_LATEST_VERSION... " docker pull homeassistant/home-assistant:stable &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Home Assistant Image... " +echo -en "${GN} Installing Home Assistant $CORE_LATEST_VERSION... " docker volume create hass_config >/dev/null docker run -d \ --name homeassistant \ From e12173571884560d3e5e3adc88bdcccf34e2fe1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 17:14:28 -0400 Subject: [PATCH 1752/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 45b25e4b..167fd6a0 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -21,13 +21,6 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } -get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} - -DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") -CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") -PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` @@ -70,6 +63,14 @@ echo -en "${GN} Installing pip3... " apt-get install -y python3-pip &>/dev/null echo -e "${CM}${CL} \r" +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") + echo -en "${GN} Installing Docker $DOCKER_LATEST_VERSION... " DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) From 426c304275fd299a7a579130046f19b878f7b8e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 17:28:12 -0400 Subject: [PATCH 1753/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 167fd6a0..a9814b81 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -82,7 +82,7 @@ EOF sh <(curl -sSL https://get.docker.com) &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Pulling Portainer Image $PORTAINER_LATEST_VERSION... " +echo -en "${GN} Pulling Portainer $PORTAINER_LATEST_VERSION Image... " docker pull portainer/portainer-ce:latest &>/dev/null echo -e "${CM}${CL} \r" @@ -98,7 +98,7 @@ docker run -d \ portainer/portainer-ce:latest &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Pulling Home Assistant Image $CORE_LATEST_VERSION... " +echo -en "${GN} Pulling Home Assistant $CORE_LATEST_VERSION Image... " docker pull homeassistant/home-assistant:stable &>/dev/null echo -e "${CM}${CL} \r" From c0babe1ad87a4c91b8d7f025672ff6b0e190ae0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 17:32:32 -0400 Subject: [PATCH 1754/6505] Update docker-install.sh --- setup/docker-install.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 941aa6fc..632884dd 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -59,7 +59,13 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Docker... " +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") + +echo -en "${GN} Installing Docker $DOCKER_LATEST_VERSION... " DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) cat >$DOCKER_CONFIG_PATH <<'EOF' From 33731e887f71930dc8fdee40104d0d9e4f3192f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 17:54:46 -0400 Subject: [PATCH 1755/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 87cc157b..acce5043 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Scripts** (V2) - - ADD choose between Automatic or Manual DHCP reservation + - ADD choose between Automatic or Manual DHCP ## 2022-03-18 From 4d4ae641b9cc694695c260d9aafe3a10eb703468 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 20 Mar 2022 18:50:41 -0400 Subject: [PATCH 1756/6505] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2939e6a5..3a01aad3 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,8 @@ ________________________________________________________________________________ @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    Home Assistant Container LXC

    - +

    With Selectable Storage Drivers

    + To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell (V2). ```yaml From 2cc5f3e2b5eff4dd3160cbfa94df564ff5a24e2a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Mar 2022 02:10:46 -0400 Subject: [PATCH 1757/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a01aad3..c5da436d 100644 --- a/README.md +++ b/README.md @@ -688,7 +688,7 @@ ________________________________________________________________________________
    - 🔸Zwavejs2MQTT LXC + Zwavejs2MQTT LXC

    From f1d7a9e1f4704299ab48816979c77e86f53fda40 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Mar 2022 14:09:07 -0400 Subject: [PATCH 1758/6505] Create haos-vm.sh --- vm/haos-vm.sh | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 vm/haos-vm.sh diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh new file mode 100644 index 00000000..655e866a --- /dev/null +++ b/vm/haos-vm.sh @@ -0,0 +1,195 @@ +#!/usr/bin/env bash + +while true; do + read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +CL=`echo "\033[m"` +BL=`echo "\033[36m"` +function header_info { +echo -e "${BL} + _ _ ____ _____ + | | | | /\ / __ \ / ____| + | |__| | / \ | | | | (___ + | __ | / /\ \| | | |\___ \ + | | | |/ ____ \ |__| |____) | + |_| |_/_/ \_\____/|_____/ + +${CL}" +} +header_info +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + warn "'Disk image' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the container?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +info "Using ${BL}$STORAGE${CL} for Storage Location." +VMID=$(pvesh get /cluster/nextid) +info "Container ID is ${BL}$VMID${CL}." +echo -en "${GN} Getting URL for Latest Home Assistant Disk Image... " +RELEASE_TYPE=qcow2 +URL=$(cat<1 {print $2}') +case $STORAGE_TYPE in + btrfs|nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + IMPORT_OPT="-format qcow2" +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +echo -e "${CM} ${CL} \r" +echo -en "${GN} Creating HAOS VM... " +VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) +qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},size=128K \ + -scsi0 ${DISK1_REF},size=32G >/dev/null +qm set $VMID \ + -boot order=scsi0 >/dev/null +set +o errtrace +( +echo -e "${CM} ${CL} \r" + echo -en "${GN} Adding Serial Port and Configuring Console... " + trap ' + warn "Unable to configure serial port. VM is still functional." + if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VMID --delete serial0 >/dev/null + fi + exit + ' ERR + echo -e "${CM} ${CL} \r" + if [ "$(command -v kpartx)" = "" ]; then + echo -en "${GN} Installing kpartx... " + apt-get update >/dev/null + apt-get -qqy install kpartx &>/dev/null + echo -e "${CM} ${CL} \r" + fi + DISK1_PATH="$(pvesm path $DISK1_REF)" + DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" + DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" + TEMP_MOUNT="${TEMP_DIR}/mnt" + trap ' + findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT + command -v kpartx >/dev/null && kpartx -d $DISK1_PATH + ' EXIT + kpartx -a $DISK1_PATH + mkdir $TEMP_MOUNT + mount $DISK1_PART1_PATH $TEMP_MOUNT + sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt + qm set $VMID -serial0 socket >/dev/null +) +echo -en "${GN} Starting Home Assistant OS VM... " +qm start $VMID +echo -e "${CM} ${CL} \n" + +echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" From d609369a89ecf59adf6482545cea2ec05704294b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Mar 2022 14:29:47 -0400 Subject: [PATCH 1759/6505] Update haos-vm.sh --- vm/haos-vm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 655e866a..f5b821e6 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -188,8 +188,8 @@ echo -e "${CM} ${CL} \r" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) -echo -en "${GN} Starting Home Assistant OS VM... " -qm start $VMID -echo -e "${CM} ${CL} \n" +#echo -en "${GN} Starting Home Assistant OS VM... " +#qm start $VMID +#echo -e "${CM} ${CL} \n" echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" From 4c304615a0f190dc60d60c92cb7007863313d0e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Mar 2022 05:16:43 -0400 Subject: [PATCH 1760/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5da436d..17ab7085 100644 --- a/README.md +++ b/README.md @@ -1041,7 +1041,7 @@ ________________________________________________________________________________
    - 🔸Dashy LXC + Dashy LXC

    From 0491c4dbdbccef6eda3a5509fa9ac8a0e80494e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Mar 2022 06:27:04 -0400 Subject: [PATCH 1761/6505] Update haos-vm.sh --- vm/haos-vm.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index f5b821e6..5d18e431 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -188,8 +188,11 @@ echo -e "${CM} ${CL} \r" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) -#echo -en "${GN} Starting Home Assistant OS VM... " -#qm start $VMID -#echo -e "${CM} ${CL} \n" +echo -en "${GN} Starting Home Assistant OS VM... " +qm start $VMID +sleep 15 +echo -e "${CM} ${CL} \n" +CURRENT_IP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/') +echo -e "${CURRENT_IP}" -echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" +echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} IP is ${BL}${CURRENT_IP}${CL}\n" From 2f6bb3d0cad409c2cf666af7d7a09f06c658730d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Mar 2022 06:37:54 -0400 Subject: [PATCH 1762/6505] Update haos-vm.sh --- vm/haos-vm.sh | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 5d18e431..f5b821e6 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -188,11 +188,8 @@ echo -e "${CM} ${CL} \r" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) -echo -en "${GN} Starting Home Assistant OS VM... " -qm start $VMID -sleep 15 -echo -e "${CM} ${CL} \n" -CURRENT_IP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/') -echo -e "${CURRENT_IP}" +#echo -en "${GN} Starting Home Assistant OS VM... " +#qm start $VMID +#echo -e "${CM} ${CL} \n" -echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} IP is ${BL}${CURRENT_IP}${CL}\n" +echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" From 27e31b4d09afa1d3521e9279a9fb4efe3c6d0b42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Mar 2022 09:20:56 -0400 Subject: [PATCH 1763/6505] Update README.md --- README.md | 96 +++++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 17ab7085..80ae3b91 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ and attempt the *No-Nag* fix. Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/post_install.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post_install.sh)" ``` It's recommended to update Proxmox after running this script, before adding any VM/CT. @@ -39,7 +39,7 @@ Cleaning unused kernel images is not only good because of a reduced grub menu, b Run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/kernel-clean.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean.sh)" ``` ____________________________________________________________________________________________ @@ -57,7 +57,7 @@ Update All LXC's Fast & Easy Run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/update-lxcs.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs.sh)" ``` ____________________________________________________________________________________________ @@ -95,7 +95,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/vm/haos_vm.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos_vm.sh)" ```

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

    @@ -121,7 +121,7 @@ To create a new Proxmox Podman Home Assistant Container, run the following in th ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/podman_ha_container.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman_ha_container.sh)" ```

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    @@ -147,14 +147,14 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” Run in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data-podman.sh)" ``` ⚙️ **To allow USB device passthrough:** Run in the Proxmox Shell. (**replace `106` with your LXC ID**) ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -163,7 +163,7 @@ Reboot the LXC to apply the changes Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman_hacs.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/podman_hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -200,7 +200,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/homeassistant.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant.sh)" ```

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    @@ -227,14 +227,14 @@ Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” Run in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data.sh)" ``` ⚙️ **To Allow USB Device Passthrough:** Run in the Proxmox Shell. (**replace `106` with your LXC ID**) ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/usb-passthrough.sh)" -s 106 +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 ``` Reboot the LXC to apply the changes @@ -244,7 +244,7 @@ Reboot the LXC to apply the changes Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. @@ -259,7 +259,7 @@ Run in the LXC console Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/latest-update-menu.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/latest-update-menu.sh)" ``` ____________________________________________________________________________________________ @@ -277,7 +277,7 @@ Homebridge allows you to integrate with smart home devices that do not natively To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/homebridge.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -332,7 +332,7 @@ Update from the Homebridge UI To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/esphome.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -363,7 +363,7 @@ ________________________________________________________________________________ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell (V2). ```yaml - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/nginx-proxy-manager.sh)" + bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager.sh)" ```

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

    @@ -395,7 +395,7 @@ Add the following to your `configuration.yaml` in Home Assistant. Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/npm_update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update.sh)" ``` ____________________________________________________________________________________________ @@ -413,7 +413,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mqtt.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -464,7 +464,7 @@ ________________________________________________________________________________ To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/node-red.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -489,7 +489,7 @@ npm install -g --unsafe-perm node-red Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-themes.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/node-red-themes.sh)" ``` ____________________________________________________________________________________________ @@ -506,7 +506,7 @@ ________________________________________________________________________________ To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/mariadb.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -618,7 +618,7 @@ ________________________________________________________________________________ To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zigbee2mqtt.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -680,7 +680,7 @@ bash /opt/zigbee2mqtt/update.sh Run in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/z2m-copy-data.sh)" ``` ____________________________________________________________________________________________ @@ -697,7 +697,7 @@ ________________________________________________________________________________ To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/zwavejs2mqtt.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwavejs2mqtt.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -707,13 +707,13 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/z Run in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwave-copy-data.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-copy-data.sh)" ``` ⚙️ **To Update Zwavejs2MQTT** Run in the LXC Console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwavejs2mqtt-update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwavejs2mqtt-update.sh)" ``` ____________________________________________________________________________________________ @@ -730,7 +730,7 @@ ________________________________________________________________________________ To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/influxdb.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -772,7 +772,7 @@ ________________________________________________________________________________ To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/grafana.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -814,7 +814,7 @@ ________________________________________________________________________________ To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/docker.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker.sh)" ```

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -842,7 +842,7 @@ ________________________________________________________________________________ To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/debian.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -871,7 +871,7 @@ ________________________________________________________________________________ To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/ubuntu.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -899,7 +899,7 @@ ________________________________________________________________________________ To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/plex_container.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex_container.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -917,7 +917,7 @@ apt update && apt upgrade -y Run in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/pms-copy-data.sh)" ``` ____________________________________________________________________________________________ @@ -934,7 +934,7 @@ ________________________________________________________________________________ To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/jellyfin_container.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin_container.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -962,7 +962,7 @@ ________________________________________________________________________________ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/pihole.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -994,7 +994,7 @@ An open source authoritative as well as recursive DNS server To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/technitiumdns.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1004,7 +1004,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/t ⚙️ **To Update** ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/technitiumdns-update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/technitiumdns-update.sh)" ``` __________________________________________________________________________________________ @@ -1021,7 +1021,7 @@ ________________________________________________________________________________ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/adguard.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1052,7 +1052,7 @@ Dashy helps you organize your self-hosted services by making them accessible fro To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/dashy.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy.sh)" ```

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    @@ -1064,7 +1064,7 @@ After getting everything setup the way you want in interactive mode and saved to Run in the LXC Console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/dashy-update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/dashy-update.sh)" ``` __________________________________________________________________________________________ @@ -1084,7 +1084,7 @@ PhotoPrism® is an AI-powered app for browsing, organizing & sharing your photo To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell (V2). ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/photoprism.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1109,7 +1109,7 @@ After the script completes, If you're dissatisfied with the default settings, cl Run in the LXC Console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/photoprism-update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/photoprism-update.sh)" ``` @@ -1129,7 +1129,7 @@ Sync files from app to server, share photos & videos, back up your data and stay To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell (V2). ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/daemonsync.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    @@ -1152,7 +1152,7 @@ ________________________________________________________________________________ To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell (V2). ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/motioneye.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1194,7 +1194,7 @@ ________________________________________________________________________________ To Install Webmin System Administration [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png), ⚠️ run the following in the LXC console. ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/webmin.sh)" ``` If you prefer to manage all aspects of your Proxmox LXC from a graphical interface instead of the command line interface, Webmin might be right for you. @@ -1240,7 +1240,7 @@ ________________________________________________________________________________ To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell (V2). ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/wireguard.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1292,7 +1292,7 @@ ________________________________________________________________________________ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/vaultwarden.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden.sh)" ``` ⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. @@ -1311,7 +1311,7 @@ Expect 30+ minute install time. Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/vaultwarden-update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/vaultwarden-update.sh)" ``` ____________________________________________________________________________________________ From ac7cd693e78e6bdc3e64b76be77f783f29a2c482 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Mar 2022 16:31:57 -0400 Subject: [PATCH 1764/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 80ae3b91..0a728540 100644 --- a/README.md +++ b/README.md @@ -1291,7 +1291,7 @@ ________________________________________________________________________________ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. -``` +```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden.sh)" ``` ⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. From 979681173130188b255c27eba27eb9d799776057 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 03:21:56 -0400 Subject: [PATCH 1765/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a728540..0f1cdd7d 100644 --- a/README.md +++ b/README.md @@ -1073,7 +1073,7 @@ ________________________________________________________________________________
    - 🔸PhotoPrism LXC + PhotoPrism LXC

    From 6d9537098655c77a16969f838a220e56ee328bb5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 05:38:37 -0400 Subject: [PATCH 1766/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index f312617a..655e866a 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -134,7 +134,7 @@ case $FILE in esac STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in - nfs|dir) + btrfs|nfs|dir) DISK_EXT=".qcow2" DISK_REF="$VMID/" IMPORT_OPT="-format qcow2" From 2913adaaafb250cf197b31aba6e79dbe5a725f53 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 14:59:01 -0400 Subject: [PATCH 1767/6505] Create heimdalldashboard.sh --- ct/heimdalldashboard.sh | 271 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 ct/heimdalldashboard.sh diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh new file mode 100644 index 00000000..fac092ed --- /dev/null +++ b/ct/heimdalldashboard.sh @@ -0,0 +1,271 @@ +#!/usr/bin/env bash +PP=`echo "\e[1;35m"` +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Heimdall Dashboard" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _ _ _ _ _ _ _____ _ _ _ + | | | | (_) | | | | | | __ \ | | | | | | + | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | + | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | + | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | + |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and press [ENTER] or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and press [ENTER] or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and press [ENTER] or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press [ENTER]." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:7990${CL} \n" From 241e44270344c3626714400564935181343cd837 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 15:00:18 -0400 Subject: [PATCH 1768/6505] Create heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 116 +++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 setup/heimdalldashboard-install.sh diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh new file mode 100644 index 00000000..b6006497 --- /dev/null +++ b/setup/heimdalldashboard-install.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing PHP... " +apt-get install -y php &>/dev/null +apt-get install -y php-sqlite3 &>/dev/null +apt-get install -y php-zip &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Heimdall Dashboard... " +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]'); echo $RELEASE &&\ +curl --silent -o /opt/${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" +cd /opt +tar xvzf ${RELEASE}.tar.gz + +echo -en "${GN} Creating Service... " +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target + +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall-2.4.6 +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 + +[Install] +WantedBy=multi-user.target" > $service_path +sudo systemctl enable --now heimdall.service &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From b540687d8238e7e3755b2bb4d4154907d75ac3e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 15:10:38 -0400 Subject: [PATCH 1769/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index b6006497..30c91325 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -65,11 +65,12 @@ apt-get install -y php-sqlite3 &>/dev/null apt-get install -y php-zip &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Heimdall Dashboard... " -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]'); echo $RELEASE &&\ -curl --silent -o /opt/${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +echo -en "${GN} Installing Heimdall Dashboard ${RELEASE}... " +curl --silent -o /opt/${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null cd /opt -tar xvzf ${RELEASE}.tar.gz +tar xvzf ${RELEASE}.tar.gz &>/dev/null +echo -e "${CM}${CL} \r" echo -en "${GN} Creating Service... " service_path="/etc/systemd/system/heimdall.service" From df3407268ce51a0f449dc2a3ce277549f860348b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 15:27:07 -0400 Subject: [PATCH 1770/6505] Add files via upload --- misc/images/heimdall.png | Bin 0 -> 61187 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/heimdall.png diff --git a/misc/images/heimdall.png b/misc/images/heimdall.png new file mode 100644 index 0000000000000000000000000000000000000000..46c6bfb1986dd29d5e39e1c3a007fc88406f3df2 GIT binary patch literal 61187 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 Date: Wed, 23 Mar 2022 15:31:25 -0400 Subject: [PATCH 1771/6505] Update README.md --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 0f1cdd7d..ffc87651 100644 --- a/README.md +++ b/README.md @@ -1039,6 +1039,28 @@ ________________________________________________________________________________
    +
    + 🔸Heimdall Dashboard LXC + +

    + +

    Heimdall Dashboard LXC

    + +Heimdall Application Dashboard is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like. + +To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell (V2). + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard.sh)" +``` +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Heimdall Dashboard Interface - IP:7990** + +__________________________________________________________________________________________ + +
    +
    Dashy LXC From cf4785c1de6b6d01cc472fc0edb6e8de05df5230 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 15:32:53 -0400 Subject: [PATCH 1772/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index acce5043..c150da6f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-23 + +### Changed + +- **Heimdall Dashboard LXC** + - New Script V2 + ## 2022-03-20 ### Changed From 139d770a688502623a3899670b99680da2de292e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Mar 2022 16:53:01 -0400 Subject: [PATCH 1773/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ffc87651..9ec0c6f9 100644 --- a/README.md +++ b/README.md @@ -1046,7 +1046,7 @@ ________________________________________________________________________________

    Heimdall Dashboard LXC

    -Heimdall Application Dashboard is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like. +[Heimdall Application Dashboard](https://camo.githubusercontent.com/bcfd4f74c93b25bea7b14eacbafd649206bf754a3d4b596329968f0ee569cf3c/68747470733a2f2f692e696d6775722e636f6d2f4d72433451704e2e676966) is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like. To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell (V2). From 9bb3a685494a55367756b52edd7bac3990f75472 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 07:06:38 -0400 Subject: [PATCH 1774/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ec0c6f9..c59687e7 100644 --- a/README.md +++ b/README.md @@ -804,7 +804,7 @@ ________________________________________________________________________________
    - 🔸Docker LXC + Docker LXC

    From d2a01e4c388a0e57d4878279573eabcaec9627c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 11:02:32 -0400 Subject: [PATCH 1775/6505] Update plex_container.sh --- ct/plex_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex_container.sh b/ct/plex_container.sh index 13c418fd..68949613 100644 --- a/ct/plex_container.sh +++ b/ct/plex_container.sh @@ -109,7 +109,7 @@ echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 +OSVERSION=${OSTYPE}-20.04 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From a173111565af344673888f56afb435f25bf56d33 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 12:06:11 -0400 Subject: [PATCH 1776/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c150da6f..bae3b774 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-24 + +### Changed + +- **Plex Media Server LXC** + - Switched to Ubuntu 20.04 for HDR tone mapping + ## 2022-03-23 ### Changed From 8a99bf2f5570512fae590394c2a1bb7363c3589b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 12:06:47 -0400 Subject: [PATCH 1777/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c59687e7..d5950e8c 100644 --- a/README.md +++ b/README.md @@ -890,7 +890,7 @@ ________________________________________________________________________________
    - Plex Media Server LXC + 🔸Plex Media Server LXC

    From 33daeeb00c6219ec7c7cf3109611be4ce9c355a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:08:00 -0400 Subject: [PATCH 1778/6505] Update docker-install.sh --- setup/docker-install.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 632884dd..31754c8a 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -76,6 +76,28 @@ EOF sh <(curl -sSL https://get.docker.com) &>/dev/null echo -e "${CM}${CL} \r" +read -r -p "Add Portainer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +PORTAINER="Y" +else +PORTAINER="N" +fi + +if [[ $PORTAINER == "Y" ]]; then +echo -en "${GN} Installing Portainer $PORTAINER_LATEST_VERSION... " +docker volume create portainer_data >/dev/null +docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest &>/dev/null +echo -e "${CM}${CL} \r" +fi + PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " From d0a98242ad35b2ae11777de03fadd9272306f020 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:14:38 -0400 Subject: [PATCH 1779/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d5950e8c..05e6c674 100644 --- a/README.md +++ b/README.md @@ -809,7 +809,7 @@ ________________________________________________________________________________

    Docker LXC

    -

    With Selectable Storage Drivers

    +

    With Selectable Storage Drivers & Portainer Install Option

    To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). @@ -821,6 +821,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker.sh)" After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. +**Portainer Interface - IP:9000** + ⚙️ **To Update** Run in the LXC console From bcf45d0cc22e7299aa9f83f9cd08654936c08dd3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:16:31 -0400 Subject: [PATCH 1780/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bae3b774..3dfd2432 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,7 +9,9 @@ All notable changes to this project will be documented in this file. ### Changed - **Plex Media Server LXC** - - Switched to Ubuntu 20.04 for HDR tone mapping + - Switch to Ubuntu 20.04 for HDR tone mapping +- **Docker LXC** + - ADD Option to Install Portainer ## 2022-03-23 From f4f04c51cb0b6436a07a39aa2bbe5f9ad5c81efa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:17:10 -0400 Subject: [PATCH 1781/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05e6c674..2510ba4b 100644 --- a/README.md +++ b/README.md @@ -804,7 +804,7 @@ ________________________________________________________________________________
    - Docker LXC + 🔸Docker LXC

    From 649ca870bdaa0507b2e389ecb46772980e27d067 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:27:19 -0400 Subject: [PATCH 1782/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2510ba4b..8e76cd00 100644 --- a/README.md +++ b/README.md @@ -809,7 +809,7 @@ ________________________________________________________________________________

    Docker LXC

    -

    With Selectable Storage Drivers & Portainer Install Option

    +

    With Selectable Storage Drivers & Add Portainer Option

    To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). From d0b8f37dfa626ae148c58bfa86bf67888d4cffb7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:28:46 -0400 Subject: [PATCH 1783/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3dfd2432..8cb28346 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. - **Plex Media Server LXC** - Switch to Ubuntu 20.04 for HDR tone mapping - **Docker LXC** - - ADD Option to Install Portainer + - Add Portainer Option ## 2022-03-23 From 445853f79616077e58aecd2eee79dd32e78a5640 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:32:10 -0400 Subject: [PATCH 1784/6505] Update docker-install.sh --- setup/docker-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 31754c8a..deea1d9c 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -64,6 +64,7 @@ get_latest_release() { } DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") echo -en "${GN} Installing Docker $DOCKER_LATEST_VERSION... " DOCKER_CONFIG_PATH='/etc/docker/daemon.json' From 120e208a5a237e0a5a9ca5d805b3e7b56ecf09a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 20:54:15 -0400 Subject: [PATCH 1785/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index d8cec842..e4985159 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -65,11 +65,21 @@ apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null echo -e "${CM}${CL} \r" +read -r -p "Add Adminer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +ADMINER="Y" +else +ADMINER="N" +fi + +if [[ $ADMINER == "Y" ]]; then echo -en "${GN} Installing Adminer... " sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null echo -e "${CM}${CL} \r" +fi PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From 9e01adf4a23c46648d637b9660f4c6d7269dea76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 21:06:40 -0400 Subject: [PATCH 1786/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index e4985159..d8cec842 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -65,21 +65,11 @@ apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null echo -e "${CM}${CL} \r" -read -r -p "Add Adminer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -ADMINER="Y" -else -ADMINER="N" -fi - -if [[ $ADMINER == "Y" ]]; then echo -en "${GN} Installing Adminer... " sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null echo -e "${CM}${CL} \r" -fi PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From b1803446bd98a2b824398fc81434008f48e3c27a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 23:35:22 -0400 Subject: [PATCH 1787/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 8cb28346..fce6d47d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Plex Media Server LXC** - - Switch to Ubuntu 20.04 for HDR tone mapping + - Switch to Ubuntu 20.04 to support HDR tone mapping - **Docker LXC** - Add Portainer Option From 857d166d11b492e85e5a97016e32d99e64bd5ab6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Mar 2022 23:37:59 -0400 Subject: [PATCH 1788/6505] Update docker-install.sh --- setup/docker-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index deea1d9c..a34d5d59 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -77,7 +77,7 @@ EOF sh <(curl -sSL https://get.docker.com) &>/dev/null echo -e "${CM}${CL} \r" -read -r -p "Add Portainer? " prompt +read -r -p "Would you like to add Portainer? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then PORTAINER="Y" From 9d531333823847fb33466d10cecd0235d6e34911 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 06:07:31 -0400 Subject: [PATCH 1789/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e76cd00..4af4cd92 100644 --- a/README.md +++ b/README.md @@ -986,7 +986,7 @@ ________________________________________________________________________________
    - 🔸Technitium DNS LXC + Technitium DNS LXC

    @@ -1254,7 +1254,7 @@ ________________________________________________________________________________
    - 🔸WireGuard LXC + WireGuard LXC

    From 0118f1fb0e7469327ccbce52c3f4e4db473a55da Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 09:19:34 -0400 Subject: [PATCH 1790/6505] Create scaling-governor.sh --- misc/scaling-governor.sh | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 misc/scaling-governor.sh diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh new file mode 100644 index 00000000..cedd41a0 --- /dev/null +++ b/misc/scaling-governor.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +set -e +show_menu(){ + CL=`echo "\033[m"` + GN=`echo "\033[32m"` + BL=`echo "\033[36m"` + YW=`echo "\033[33m"` + fgred=`echo "\033[31m"` + IP=$(hostname -I) + ACSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors) + CCSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) + echo -e "${YW}Proxmox IP ${BL}${IP}${CL}" + + echo -e "\n${YW}Available CPU Scaling Governors + ${BL}${ACSG}${CL}" + + echo -e "\n${YW}Current CPU Scaling Governor + ${BL}${CCSG}${CL}" + printf "\n${BL}********** ${YW}CPU Scaling Governor Selector${CL} ${BL}********${CL}\n" + printf "${BL}**${YW} 1)${GN} Switch to ${BL}conservative${CL}${GN} CPU Scaling Governor ${CL}\n" + printf "${BL}**${YW} 2)${GN} Switch to ${BL}ondemand${CL}${GN} CPU Scaling Governor ${CL}\n" + printf "${BL}**${YW} 3)${GN} Switch to ${BL}userspace${CL}${GN} CPU Scaling Governor ${CL}\n" + printf "${BL}**${YW} 4)${GN} Switch to ${BL}powersave${CL}${GN} CPU Scaling Governor ${CL}\n" + printf "${BL}**${YW} 5)${GN} Switch to ${BL}performance${CL}${GN} CPU Scaling Governor ${CL}\n" + printf "${BL}**${YW} 6)${GN} Switch to ${BL}schedutil${CL}${GN} CPU Scaling Governor ${CL}\n" + printf "\n ${fgred}NOTE: Settings return to default after reboot${CL}\n" + printf "\n Please choose an option from the menu and press [ENTER] or ${fgred}x to exit. ${CL}" + read opt +} +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) echo "conservative" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + clear + show_menu + ;; + 2) echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + clear + show_menu + ;; + 3) echo "userspace" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + clear + show_menu + ;; + 4) echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + clear + show_menu + ;; + 5) echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + clear + show_menu + ;; + 6) echo "schedutil" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + clear + show_menu + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + show_menu; + ;; + esac + fi + done From ed7c357edb68168cac4e18ea795a07e9046f022e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 09:28:41 -0400 Subject: [PATCH 1791/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index cedd41a0..cddc2dbb 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -1,5 +1,14 @@ #!/usr/bin/env bash set -e +while true; do + read -p "Change CPU Scaling Governors. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear show_menu(){ CL=`echo "\033[m"` GN=`echo "\033[32m"` @@ -24,7 +33,7 @@ show_menu(){ printf "${BL}**${YW} 5)${GN} Switch to ${BL}performance${CL}${GN} CPU Scaling Governor ${CL}\n" printf "${BL}**${YW} 6)${GN} Switch to ${BL}schedutil${CL}${GN} CPU Scaling Governor ${CL}\n" printf "\n ${fgred}NOTE: Settings return to default after reboot${CL}\n" - printf "\n Please choose an option from the menu and press [ENTER] or ${fgred}x to exit. ${CL}" + printf "\n Please choose an option from the menu and press [ENTER] or ${fgred}x${CL} to exit." read opt } clear From 81ff6dbfd6b84f595a84e3d6ca7f0e8d0254193d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 09:43:55 -0400 Subject: [PATCH 1792/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index cddc2dbb..6770b758 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -e +clear while true; do read -p "Change CPU Scaling Governors. Proceed(y/n)?" yn case $yn in From 397af2d63dbfe33bcbdff8ee81913577bdef85bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 09:56:24 -0400 Subject: [PATCH 1793/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 6770b758..5dedb717 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -e clear +set -e while true; do read -p "Change CPU Scaling Governors. Proceed(y/n)?" yn case $yn in @@ -26,7 +26,7 @@ show_menu(){ echo -e "\n${YW}Current CPU Scaling Governor ${BL}${CCSG}${CL}" - printf "\n${BL}********** ${YW}CPU Scaling Governor Selector${CL} ${BL}********${CL}\n" + printf "\n$ {fgred}Only Select Available CPU Scaling Governors From Above${CL}\n \n" printf "${BL}**${YW} 1)${GN} Switch to ${BL}conservative${CL}${GN} CPU Scaling Governor ${CL}\n" printf "${BL}**${YW} 2)${GN} Switch to ${BL}ondemand${CL}${GN} CPU Scaling Governor ${CL}\n" printf "${BL}**${YW} 3)${GN} Switch to ${BL}userspace${CL}${GN} CPU Scaling Governor ${CL}\n" From 6c2db49284452e01c843c81c04e9b04ce2d690ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 09:58:46 -0400 Subject: [PATCH 1794/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 5dedb717..95798059 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -26,7 +26,7 @@ show_menu(){ echo -e "\n${YW}Current CPU Scaling Governor ${BL}${CCSG}${CL}" - printf "\n$ {fgred}Only Select Available CPU Scaling Governors From Above${CL}\n \n" + printf "\n ${fgred}Only Select Available CPU Scaling Governors From Above${CL}\n \n" printf "${BL}**${YW} 1)${GN} Switch to ${BL}conservative${CL}${GN} CPU Scaling Governor ${CL}\n" printf "${BL}**${YW} 2)${GN} Switch to ${BL}ondemand${CL}${GN} CPU Scaling Governor ${CL}\n" printf "${BL}**${YW} 3)${GN} Switch to ${BL}userspace${CL}${GN} CPU Scaling Governor ${CL}\n" From 50d4e92cf65f2fcc88a807499e9780e00b832469 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 10:28:45 -0400 Subject: [PATCH 1795/6505] Add files via upload --- misc/images/cpu.png | Bin 0 -> 15254 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/cpu.png diff --git a/misc/images/cpu.png b/misc/images/cpu.png new file mode 100644 index 0000000000000000000000000000000000000000..cbd8207c1e13f7b19d74b59d0984c5d0a18ff943 GIT binary patch literal 15254 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 pL)&Sa#yGn*qLe7c4%vk@3J4ux!-2I#h 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 c1E Date: Fri, 25 Mar 2022 11:08:06 -0400 Subject: [PATCH 1796/6505] Update README.md --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 4af4cd92..f5e95dd4 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,26 @@ ________________________________________________________________________________
    +
    + 🔸Proxmox CPU Scaling Governor + +

    + +

    Proxmox CPU Scaling Governor

    + +CPU Scaling Governor enables the operating system to scale the CPU frequency up or down in order to save power or improve performance. + +[Generic Scaling Governors](https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html?#generic-scaling-governors) + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/scaling-governor.sh)" +``` +____________________________________________________________________________________________ + +
    +
    Proxmox LXC Updater From 16e8edc2098f33fe3b6710eba70e337f5d3ece93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 11:10:33 -0400 Subject: [PATCH 1797/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index fce6d47d..7f624c70 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-25 + +### Changed + +- **Proxmox CPU Scaling Governor** + - New Script + + ## 2022-03-24 ### Changed From 36eea12323a3feceeba267ac65c8aa680d8e99ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 11:28:17 -0400 Subject: [PATCH 1798/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 95798059..a857b40c 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -2,7 +2,7 @@ clear set -e while true; do - read -p "Change CPU Scaling Governors. Proceed(y/n)?" yn + read -p "View CPU Scaling Governors. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From db907c70ec0479b82020a0c82ce95b51493d88d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Mar 2022 14:35:40 -0400 Subject: [PATCH 1799/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index a857b40c..630e87b7 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -10,17 +10,35 @@ while true; do esac done clear +function header_info { +echo -e " + _____ _____ _ _ + / ____| __ \| | | | + | | | |__) | | | | + | | | ___/| | | | + | |____| | | |__| | + \_____|_| \____/ + Scaling Governors +" +} show_menu(){ CL=`echo "\033[m"` GN=`echo "\033[32m"` BL=`echo "\033[36m"` YW=`echo "\033[33m"` fgred=`echo "\033[31m"` +header_info + CK=$(uname -r) IP=$(hostname -I) + MAC=$(cat /sys/class/net/eno1/address) ACSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors) CCSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) echo -e "${YW}Proxmox IP ${BL}${IP}${CL}" + echo -e "${YW}MAC Address ${BL}${MAC}${CL}" + + echo -e "${YW}Current Kernel ${BL}${CK}${CL}" + echo -e "\n${YW}Available CPU Scaling Governors ${BL}${ACSG}${CL}" From 49c0d304839d8056ffc2f4ef46e17c1dead6b33f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 00:12:34 -0400 Subject: [PATCH 1800/6505] Create unifi.sh --- ct/unifi.sh | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 ct/unifi.sh diff --git a/ct/unifi.sh b/ct/unifi.sh new file mode 100644 index 00000000..99d76846 --- /dev/null +++ b/ct/unifi.sh @@ -0,0 +1,270 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="UniFi" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _ _ _ ______ _ + | | | | (_) ____(_) + | | | |_ __ _| |__ _ + | | | | _ \| | __| | | + | |__| | | | | | | | | + \____/|_| |_|_|_| |_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8443${CL} \n" From 0587e821bc3566b46186141645be187761ed8ce7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 00:13:49 -0400 Subject: [PATCH 1801/6505] Create unifi-install.sh --- setup/unifi-install.sh | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 setup/unifi-install.sh diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh new file mode 100644 index 00000000..f222154b --- /dev/null +++ b/setup/unifi-install.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing UniFi Network Application... " +wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 93200c0e33f0051a0dde54774f1d1197b3c32cc1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 05:00:28 -0400 Subject: [PATCH 1802/6505] Update unifi-install.sh --- setup/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index f222154b..0f4bc5b1 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -60,7 +60,7 @@ apt-get install -y sudo &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing UniFi Network Application... " -wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip +wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip &>/dev/null echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 7d2ab0ef4f7b3c92f1507ffd085f885782f8cbcd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 05:40:42 -0400 Subject: [PATCH 1803/6505] Update unifi.sh --- ct/unifi.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/unifi.sh b/ct/unifi.sh index 99d76846..6b485dd6 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -17,7 +17,7 @@ while true; do done clear function header_info { -echo -e "${RD} +echo -e "${BL} _ _ _ ______ _ | | | | (_) ____(_) | | | |_ __ _| |__ _ @@ -267,4 +267,4 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. ${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:8443${CL} \n" + ${BL}https://${IP}:8443${CL} \n" From 68c0f73080c58d870ad3c3fc557d828c661b8a06 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 05:45:04 -0400 Subject: [PATCH 1804/6505] Create unifi-update.sh --- misc/unifi-update.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 misc/unifi-update.sh diff --git a/misc/unifi-update.sh b/misc/unifi-update.sh new file mode 100644 index 00000000..a7a19aae --- /dev/null +++ b/misc/unifi-update.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="UniFi Update" +while true; do + read -p "This will run ${APP}. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _ _ _ ______ _ + | | | | (_) ____(_) + | | | |_ __ _| |__ _ + | | | | _ \| | __| | | + | |__| | | | | | | | | + \____/|_| |_|_|_| |_| + UPDATE +${CL}" +} + +header_info +sleep 3 +wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh && bash unifi-update.sh + From 96903e74a5cb3b8859fed3c6a76be40b8c2434ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 07:00:44 -0400 Subject: [PATCH 1805/6505] Create omada.sh --- ct/omada.sh | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 ct/omada.sh diff --git a/ct/omada.sh b/ct/omada.sh new file mode 100644 index 00000000..af8e3b65 --- /dev/null +++ b/ct/omada.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +clear +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will create a New Omada Controller LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + ____ _ _____ _ _ _ + / __ \ | | / ____| | | | | | + | | | |_ __ ___ __ _ __| | __ _ | | ___ _ __ | |_ _ __ ___ | | | ___ _ __ + | | | | _ _ \ / _ |/ _ |/ _ | | | / _ \| _ \| __| __/ _ \| | |/ _ \ __| + | |__| | | | | | | (_| | (_| | (_| | | |___| (_) | | | | |_| | | (_) | | | __/ | + \____/|_| |_| |_|\__,_|\__,_|\__,_| \_____\___/|_| |_|\__|_| \___/|_|_|\___|_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose an Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + fi + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + fi + done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + fi + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=20.04 +export PCT_DISK_SIZE=8 +export PCT_OPTIONS=" + -features $FEATURES + -hostname omada + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 2 + -memory 2048 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/omada-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created Omada Controller LXC to${CL} ${BL}$CTID${CL}. +${BL}Omada${CL} should be reachable by going to the following URL. + ${BL}https://${IP}:8043${CL} \n" From 63dba4c5a5287fc8b6c0068a480e1b7f17837326 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 07:02:34 -0400 Subject: [PATCH 1806/6505] Create omada-install.sh --- setup/omada-install.sh | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 setup/omada-install.sh diff --git a/setup/omada-install.sh b/setup/omada-install.sh new file mode 100644 index 00000000..f4587b2c --- /dev/null +++ b/setup/omada-install.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get -y install curl &>/dev/null +apt-get -y install sudo &>/dev/null +apt-get -y install gnupg &>/dev/null +apt-get -y install openjdk-8-jre-headless &>/dev/null +apt-get -y install jsvc &>/dev/null + +wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add &>/dev/null +echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list &>/dev/null +apt-get update &>/dev/null +apt-get -y install mongodb-org &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Omada Controller... " +wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleaning Up... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /tmp/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 4aa80de869503061ea009549e19587c4fe89c2c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 07:08:44 -0400 Subject: [PATCH 1807/6505] Update README.md --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/README.md b/README.md index f5e95dd4..adad6d98 100644 --- a/README.md +++ b/README.md @@ -911,6 +911,64 @@ ________________________________________________________________________________
    +
    + 🔸UniFi Network Application LXC + +

    + +

    UniFi Network Application LXC

    + +An application designed to optimize UniFi home and business networks with ease. + +To create a new Proxmox UniFi Network Application LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**UniFi Interface - https:// IP:8443** + +⚙️ **To Update UniFi** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/unifi-update.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + 🔸Omada Controller LXC + +

    + +

    Omada Controller LXC

    + +Omada Controller is software which is used to manage the EAP + +To create a new Proxmox Omada Controller LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**Omada Interface - https:// IP:8043** + +⚙️ **To Update Omada** + +Run in the LXC console +```yaml +Working On +``` +____________________________________________________________________________________________ + +
    +
    🔸Plex Media Server LXC From 7e1870d449e9f945494ee610a7e15a1cd68a788f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 07:08:53 -0400 Subject: [PATCH 1808/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7f624c70..6c4d70c9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-26 + +### Changed + +- **UniFi Network Application LXC** + - New Script V2 +- **Omada Controller LXC** + - New Script V2 + ## 2022-03-25 ### Changed From 0f0f52cb86d26546e7f09ead4213a4a314e3be1e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 07:46:29 -0400 Subject: [PATCH 1809/6505] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index adad6d98..07679ce0 100644 --- a/README.md +++ b/README.md @@ -959,6 +959,12 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada.sh)" **Omada Interface - https:// IP:8043** +`tpeap status` show the status of Controller + +`tpeap start` start the Omada Controller + +`tpeap stop` stop running the Omada Controller + ⚙️ **To Update Omada** Run in the LXC console From 777b8736137640a25127a35b311372b3ca70a9e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 08:25:33 -0400 Subject: [PATCH 1810/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07679ce0..be2e35d2 100644 --- a/README.md +++ b/README.md @@ -963,7 +963,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada.sh)" `tpeap start` start the Omada Controller -`tpeap stop` stop running the Omada Controller +`tpeap stop` stop the Omada Controller ⚙️ **To Update Omada** From 029e573702e6295f09dc5b2ce7986cd164472765 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 11:18:17 -0400 Subject: [PATCH 1811/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index be2e35d2..8954461e 100644 --- a/README.md +++ b/README.md @@ -959,11 +959,11 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada.sh)" **Omada Interface - https:// IP:8043** -`tpeap status` show the status of Controller +`tpeap status` show status of Omada Controller -`tpeap start` start the Omada Controller +`tpeap start` start Omada Controller -`tpeap stop` stop the Omada Controller +`tpeap stop` stop Omada Controller ⚙️ **To Update Omada** From 051a813d59d21f6db0c1597bf058150574a57504 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 11:34:12 -0400 Subject: [PATCH 1812/6505] Update vaultwarden-update.sh --- misc/vaultwarden-update.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index c6d61282..1f919e0d 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -29,8 +29,9 @@ while true; do * ) echo "Please answer yes or no.";; esac done -clear -update_info +#clear +#update_info +sleep 2 echo -e "${GN} Stopping Vaultwarden... ${CL}" systemctl stop vaultwarden.service sleep 1 From daec6c88b4b6e03c2c9da0d2c5d72a5470b18454 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 11:37:54 -0400 Subject: [PATCH 1813/6505] Update vaultwarden-update.sh --- misc/vaultwarden-update.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 1f919e0d..3a7b9493 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -29,8 +29,6 @@ while true; do * ) echo "Please answer yes or no.";; esac done -#clear -#update_info sleep 2 echo -e "${GN} Stopping Vaultwarden... ${CL}" systemctl stop vaultwarden.service From cee701626cc0f4a868139a4f78f4d345a631fc2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Mar 2022 18:33:38 -0400 Subject: [PATCH 1814/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 30c91325..ec67e047 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -72,6 +72,10 @@ cd /opt tar xvzf ${RELEASE}.tar.gz &>/dev/null echo -e "${CM}${CL} \r" +SER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') + echo -en "${GN} Creating Service... " service_path="/etc/systemd/system/heimdall.service" echo "[Unit] @@ -83,7 +87,7 @@ Restart=always RestartSec=5 Type=simple User=root -WorkingDirectory=/opt/Heimdall-2.4.6 +WorkingDirectory=/opt/Heimdall-${SER} ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 TimeoutStopSec=30 From 5a538240e2d32e47522c186b9c981cc62eaac5c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 01:55:08 -0400 Subject: [PATCH 1815/6505] Update debian.sh --- ct/debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index d36b6e82..ebd9f482 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -235,7 +235,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." + warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG From c57f10b90b1bcb323546982b605306b4c69be5dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 01:58:50 -0400 Subject: [PATCH 1816/6505] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 8954461e..5df89edc 100644 --- a/README.md +++ b/README.md @@ -1143,6 +1143,12 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldash **Heimdall Dashboard Interface - IP:7990** +⚙️ **To Update Heimdall Dashboard** + +Run in the LXC console +```yaml +Working On +``` __________________________________________________________________________________________
    From 457053041b0bdcf96dfa43573aa5b23fba406b32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 03:09:40 -0400 Subject: [PATCH 1817/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 630e87b7..8eace5bd 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -30,7 +30,7 @@ show_menu(){ header_info CK=$(uname -r) IP=$(hostname -I) - MAC=$(cat /sys/class/net/eno1/address) +# MAC=$(cat /sys/class/net/eno1/address) ACSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors) CCSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) echo -e "${YW}Proxmox IP ${BL}${IP}${CL}" From de268d6fedb70696cc87f6661e32e4362148114f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 13:50:16 -0400 Subject: [PATCH 1818/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index ec67e047..56b7fb5a 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -67,14 +67,14 @@ echo -e "${CM}${CL} \r" RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') echo -en "${GN} Installing Heimdall Dashboard ${RELEASE}... " -curl --silent -o /opt/${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -cd /opt +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null tar xvzf ${RELEASE}.tar.gz &>/dev/null -echo -e "${CM}${CL} \r" - -SER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') +rm -rf ${RELEASE}.tar.gz +mv Heimdall-${VER} /opt/Heimdall +echo -e "${CM}${CL} \r" echo -en "${GN} Creating Service... " service_path="/etc/systemd/system/heimdall.service" @@ -87,7 +87,7 @@ Restart=always RestartSec=5 Type=simple User=root -WorkingDirectory=/opt/Heimdall-${SER} +WorkingDirectory=/opt/Heimdall ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 TimeoutStopSec=30 From b02947611eca8f871a71fbaa82c57c01efc5f204 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 13:51:34 -0400 Subject: [PATCH 1819/6505] Create heimdalldashboard2.4.6-update.sh --- misc/heimdalldashboard2.4.6-update.sh | 88 +++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 misc/heimdalldashboard2.4.6-update.sh diff --git a/misc/heimdalldashboard2.4.6-update.sh b/misc/heimdalldashboard2.4.6-update.sh new file mode 100644 index 00000000..6848e869 --- /dev/null +++ b/misc/heimdalldashboard2.4.6-update.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +set -e +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will Update Heimdall Dashboard V2.4.6 to Current. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _ _ _ _ _ _ _____ _ _ _ + | | | | (_) | | | | | | __ \ | | | | | | + | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | + | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | + | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | + |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| + ${RD}UPDATE FROM V2.4.6 ONLY! +${CL}" +} + +header_info + +echo -en "${GN} Stopping Heimdall Dashboard... " +systemctl disable heimdall.service &>/dev/null +systemctl stop heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Backing up Data... " +cp -R /opt/Heimdall-2.4.6/database database-backup +cp -R /opt/Heimdall-2.4.6/public public-backup +sleep 1 +echo -e "${CM}${CL} \r" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null +tar xvzf ${RELEASE}.tar.gz &>/dev/null +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') +mv Heimdall-${VER}/* /opt/Heimdall +echo -e "${CM}${CL} \r" + +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target + +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 + +[Install] +WantedBy=multi-user.target" > $service_path + +echo -en "${GN} Restoring Data... " +cp -R database-backup/* /opt/Heimdall/database +cp -R public-backup/* /opt/Heimdall/public +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +rm -rf ${RELEASE}.tar.gz +rm -rf public-backup +rm -rf database-backup +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Heimdall Dashboard... " +systemctl enable --now heimdall.service &>/dev/null +sleep 2 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Finished! ${CL}\n" From 24b28878a21e111778bc3488198ae49e4e8ba3b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 13:52:54 -0400 Subject: [PATCH 1820/6505] Create heimdalldashboard-install.sh --- misc/heimdalldashboard-install.sh | 72 +++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 misc/heimdalldashboard-install.sh diff --git a/misc/heimdalldashboard-install.sh b/misc/heimdalldashboard-install.sh new file mode 100644 index 00000000..43320d81 --- /dev/null +++ b/misc/heimdalldashboard-install.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -e +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _ _ _ _ _ _ _____ _ _ _ + | | | | (_) | | | | | | __ \ | | | | | | + | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | + | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | + | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | + |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| + ${RD}UPDATE +${CL}" +} + +header_info + +echo -en "${GN} Stopping Heimdall Dashboard... " +systemctl stop heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Backing up Data... " +cp -R /opt/Heimdall/database database-backup +cp -R /opt/Heimdall/public public-backup +sleep 1 +echo -e "${CM}${CL} \r" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null +tar xvzf ${RELEASE}.tar.gz &>/dev/null +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') +cp -R Heimdall-${VER}/* /opt/Heimdall +echo -e "${CM}${CL} \r" + +echo -en "${GN} Restoring Data... " +cp -R database-backup/* /opt/Heimdall/database +cp -R public-backup/* /opt/Heimdall/public +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +rm -rf ${RELEASE}.tar.gz +rm -rf Heimdall-${VER} +rm -rf public-backup +rm -rf database-backup +rm -rf Heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Heimdall Dashboard... " +systemctl start heimdall +sleep 2 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Finished! ${CL}\n" From 4d43d7651488f97198303f473e3bd509d0849329 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:03:43 -0400 Subject: [PATCH 1821/6505] Update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5df89edc..a71b6a9c 100644 --- a/README.md +++ b/README.md @@ -1143,12 +1143,19 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldash **Heimdall Dashboard Interface - IP:7990** -⚙️ **To Update Heimdall Dashboard** +⚙️ **To Update Heimdall Dashboard (V2.4.6 Only!)** Run in the LXC console ```yaml -Working On +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard2.4.6-update.sh)" ``` +⚙️ **To Update Heimdall Dashboard (V2.4.8 & Above)** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard-update.sh)" +``` + __________________________________________________________________________________________
    From 1580c7c899055b0e47f5fdaa4aaf579e60492432 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:05:23 -0400 Subject: [PATCH 1822/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6c4d70c9..04f70bf8 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-27 + +### Changed + +- **Heimdall Dashboard LXC** + - New Update Script + ## 2022-03-26 ### Changed From 14a5f69311abf39a047e3f554ce5322d2bd6c0ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:07:45 -0400 Subject: [PATCH 1823/6505] Create heimdalldashboard-update.sh --- misc/heimdalldashboard-update.sh | 72 ++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 misc/heimdalldashboard-update.sh diff --git a/misc/heimdalldashboard-update.sh b/misc/heimdalldashboard-update.sh new file mode 100644 index 00000000..43320d81 --- /dev/null +++ b/misc/heimdalldashboard-update.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -e +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _ _ _ _ _ _ _____ _ _ _ + | | | | (_) | | | | | | __ \ | | | | | | + | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | + | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | + | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | + |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| + ${RD}UPDATE +${CL}" +} + +header_info + +echo -en "${GN} Stopping Heimdall Dashboard... " +systemctl stop heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Backing up Data... " +cp -R /opt/Heimdall/database database-backup +cp -R /opt/Heimdall/public public-backup +sleep 1 +echo -e "${CM}${CL} \r" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null +tar xvzf ${RELEASE}.tar.gz &>/dev/null +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') +cp -R Heimdall-${VER}/* /opt/Heimdall +echo -e "${CM}${CL} \r" + +echo -en "${GN} Restoring Data... " +cp -R database-backup/* /opt/Heimdall/database +cp -R public-backup/* /opt/Heimdall/public +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +rm -rf ${RELEASE}.tar.gz +rm -rf Heimdall-${VER} +rm -rf public-backup +rm -rf database-backup +rm -rf Heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Heimdall Dashboard... " +systemctl start heimdall +sleep 2 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Finished! ${CL}\n" From e452e1f9264486f07a01698818f0af627244326f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:09:29 -0400 Subject: [PATCH 1824/6505] Delete heimdalldashboard-install.sh --- misc/heimdalldashboard-install.sh | 72 ------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 misc/heimdalldashboard-install.sh diff --git a/misc/heimdalldashboard-install.sh b/misc/heimdalldashboard-install.sh deleted file mode 100644 index 43320d81..00000000 --- a/misc/heimdalldashboard-install.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash -set -e -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _ _ _ _ _ _ _____ _ _ _ - | | | | (_) | | | | | | __ \ | | | | | | - | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | - | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | - | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | - |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| - ${RD}UPDATE -${CL}" -} - -header_info - -echo -en "${GN} Stopping Heimdall Dashboard... " -systemctl stop heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Backing up Data... " -cp -R /opt/Heimdall/database database-backup -cp -R /opt/Heimdall/public public-backup -sleep 1 -echo -e "${CM}${CL} \r" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') -cp -R Heimdall-${VER}/* /opt/Heimdall -echo -e "${CM}${CL} \r" - -echo -en "${GN} Restoring Data... " -cp -R database-backup/* /opt/Heimdall/database -cp -R public-backup/* /opt/Heimdall/public -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf ${RELEASE}.tar.gz -rm -rf Heimdall-${VER} -rm -rf public-backup -rm -rf database-backup -rm -rf Heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting Heimdall Dashboard... " -systemctl start heimdall -sleep 2 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Finished! ${CL}\n" From 40ad8a81b1315134e36f8b7b4dd2b67a77d39d88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:35:30 -0400 Subject: [PATCH 1825/6505] Create heimdalldashboard2.4.8-update.sh --- misc/heimdalldashboard2.4.8-update.sh | 88 +++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 misc/heimdalldashboard2.4.8-update.sh diff --git a/misc/heimdalldashboard2.4.8-update.sh b/misc/heimdalldashboard2.4.8-update.sh new file mode 100644 index 00000000..5552ada8 --- /dev/null +++ b/misc/heimdalldashboard2.4.8-update.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +set -e +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will Update Heimdall Dashboard V2.4.6 to Current. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _ _ _ _ _ _ _____ _ _ _ + | | | | (_) | | | | | | __ \ | | | | | | + | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | + | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | + | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | + |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| + ${RD}UPDATE FROM V2.4.6 ONLY! +${CL}" +} + +header_info + +echo -en "${GN} Stopping Heimdall Dashboard... " +systemctl disable heimdall.service &>/dev/null +systemctl stop heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Backing up Data... " +cp -R /opt/Heimdall-2.4.8/database database-backup +cp -R /opt/Heimdall-2.4.8/public public-backup +sleep 1 +echo -e "${CM}${CL} \r" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null +tar xvzf ${RELEASE}.tar.gz &>/dev/null +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') +mv Heimdall-${VER}/* /opt/Heimdall +echo -e "${CM}${CL} \r" + +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target + +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 + +[Install] +WantedBy=multi-user.target" > $service_path + +echo -en "${GN} Restoring Data... " +cp -R database-backup/* /opt/Heimdall/database +cp -R public-backup/* /opt/Heimdall/public +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +rm -rf ${RELEASE}.tar.gz +rm -rf public-backup +rm -rf database-backup +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Heimdall Dashboard... " +systemctl enable --now heimdall.service &>/dev/null +sleep 2 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Finished! ${CL}\n" From 5455433182b550a8e1a15c306744b6f2fbacbcb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:41:08 -0400 Subject: [PATCH 1826/6505] Update heimdalldashboard2.4.6-update.sh --- misc/heimdalldashboard2.4.6-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/heimdalldashboard2.4.6-update.sh b/misc/heimdalldashboard2.4.6-update.sh index 6848e869..0d3a1627 100644 --- a/misc/heimdalldashboard2.4.6-update.sh +++ b/misc/heimdalldashboard2.4.6-update.sh @@ -47,6 +47,7 @@ tar xvzf ${RELEASE}.tar.gz &>/dev/null VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') +mkdir /opt/Heimdall mv Heimdall-${VER}/* /opt/Heimdall echo -e "${CM}${CL} \r" From c7fe5d9a9e2d2f8c2cbbe2703a257781cb900b69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:41:37 -0400 Subject: [PATCH 1827/6505] Update heimdalldashboard2.4.8-update.sh --- misc/heimdalldashboard2.4.8-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/heimdalldashboard2.4.8-update.sh b/misc/heimdalldashboard2.4.8-update.sh index 5552ada8..003e63d4 100644 --- a/misc/heimdalldashboard2.4.8-update.sh +++ b/misc/heimdalldashboard2.4.8-update.sh @@ -47,6 +47,7 @@ tar xvzf ${RELEASE}.tar.gz &>/dev/null VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') +mkdir /opt/Heimdall mv Heimdall-${VER}/* /opt/Heimdall echo -e "${CM}${CL} \r" From 7704e17155d8411f234d15ef5b2a23c49d740048 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 14:57:53 -0400 Subject: [PATCH 1828/6505] Update heimdalldashboard2.4.8-update.sh --- misc/heimdalldashboard2.4.8-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/heimdalldashboard2.4.8-update.sh b/misc/heimdalldashboard2.4.8-update.sh index 003e63d4..515e3152 100644 --- a/misc/heimdalldashboard2.4.8-update.sh +++ b/misc/heimdalldashboard2.4.8-update.sh @@ -47,7 +47,7 @@ tar xvzf ${RELEASE}.tar.gz &>/dev/null VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') -mkdir /opt/Heimdall + mv Heimdall-${VER}/* /opt/Heimdall echo -e "${CM}${CL} \r" From 0533079b6cb50e591f6ecc31c396cb046cb101ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 15:12:06 -0400 Subject: [PATCH 1829/6505] Update heimdalldashboard2.4.6-update.sh --- misc/heimdalldashboard2.4.6-update.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/heimdalldashboard2.4.6-update.sh b/misc/heimdalldashboard2.4.6-update.sh index 0d3a1627..6848e869 100644 --- a/misc/heimdalldashboard2.4.6-update.sh +++ b/misc/heimdalldashboard2.4.6-update.sh @@ -47,7 +47,6 @@ tar xvzf ${RELEASE}.tar.gz &>/dev/null VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') -mkdir /opt/Heimdall mv Heimdall-${VER}/* /opt/Heimdall echo -e "${CM}${CL} \r" From 961c49f1f54bceeb1733a7d4a5372c776f969b16 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 15:14:02 -0400 Subject: [PATCH 1830/6505] Update and rename heimdalldashboard2.4.8-update.sh to heimdalldashboard-weird-update.sh --- ...board2.4.8-update.sh => heimdalldashboard-weird-update.sh} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename misc/{heimdalldashboard2.4.8-update.sh => heimdalldashboard-weird-update.sh} (95%) diff --git a/misc/heimdalldashboard2.4.8-update.sh b/misc/heimdalldashboard-weird-update.sh similarity index 95% rename from misc/heimdalldashboard2.4.8-update.sh rename to misc/heimdalldashboard-weird-update.sh index 515e3152..afc40ae6 100644 --- a/misc/heimdalldashboard2.4.8-update.sh +++ b/misc/heimdalldashboard-weird-update.sh @@ -6,7 +6,7 @@ CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` while true; do - read -p "This will Update Heimdall Dashboard V2.4.6 to Current. Proceed(y/n)?" yn + read -p "This will Update Heimdall Dashboard weird to Current. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -22,7 +22,7 @@ echo -e "${PP} | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| - ${RD}UPDATE FROM V2.4.6 ONLY! + ${RD}UPDATE FROM WEIRD ONLY! ${CL}" } From bbdfeccbc002b1df64a5fcf5bc6466f6072390fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 15:18:42 -0400 Subject: [PATCH 1831/6505] Update heimdalldashboard-weird-update.sh --- misc/heimdalldashboard-weird-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/heimdalldashboard-weird-update.sh b/misc/heimdalldashboard-weird-update.sh index afc40ae6..92322be6 100644 --- a/misc/heimdalldashboard-weird-update.sh +++ b/misc/heimdalldashboard-weird-update.sh @@ -48,7 +48,7 @@ VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') -mv Heimdall-${VER}/* /opt/Heimdall +mv Heimdall-${VER} /opt/Heimdall echo -e "${CM}${CL} \r" service_path="/etc/systemd/system/heimdall.service" From d9a5713891d2f3c3b4f2e45e49566deb3707f745 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 15:19:08 -0400 Subject: [PATCH 1832/6505] Update heimdalldashboard2.4.6-update.sh --- misc/heimdalldashboard2.4.6-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/heimdalldashboard2.4.6-update.sh b/misc/heimdalldashboard2.4.6-update.sh index 6848e869..6083f4e1 100644 --- a/misc/heimdalldashboard2.4.6-update.sh +++ b/misc/heimdalldashboard2.4.6-update.sh @@ -47,7 +47,7 @@ tar xvzf ${RELEASE}.tar.gz &>/dev/null VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') -mv Heimdall-${VER}/* /opt/Heimdall +mv Heimdall-${VER} /opt/Heimdall echo -e "${CM}${CL} \r" service_path="/etc/systemd/system/heimdall.service" From ec030045b45ba0d37064815f3129c84fa67c0e22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 16:36:21 -0400 Subject: [PATCH 1833/6505] Update heimdalldashboard2.4.6-update.sh --- misc/heimdalldashboard2.4.6-update.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/heimdalldashboard2.4.6-update.sh b/misc/heimdalldashboard2.4.6-update.sh index 6083f4e1..09b1d1c9 100644 --- a/misc/heimdalldashboard2.4.6-update.sh +++ b/misc/heimdalldashboard2.4.6-update.sh @@ -77,6 +77,8 @@ echo -en "${GN} Cleanup... " rm -rf ${RELEASE}.tar.gz rm -rf public-backup rm -rf database-backup +rm -rf /opt/Heimdall-2.4.6 +rm -rf /opt/v2.4.6.tar.gz sleep 1 echo -e "${CM}${CL} \r" From b3c344a33692eabe13bd37d35a22ed7b77fe9a94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 16:37:03 -0400 Subject: [PATCH 1834/6505] Update heimdalldashboard-weird-update.sh --- misc/heimdalldashboard-weird-update.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/heimdalldashboard-weird-update.sh b/misc/heimdalldashboard-weird-update.sh index 92322be6..a622b20f 100644 --- a/misc/heimdalldashboard-weird-update.sh +++ b/misc/heimdalldashboard-weird-update.sh @@ -78,6 +78,8 @@ echo -en "${GN} Cleanup... " rm -rf ${RELEASE}.tar.gz rm -rf public-backup rm -rf database-backup +rm -rf /opt/Heimdall-2.4.8 +rm -rf /opt/v2.4.8.tar.gz sleep 1 echo -e "${CM}${CL} \r" From b4c9d5687a261549e9b0ecd53c32d914f4f0d882 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 17:28:43 -0400 Subject: [PATCH 1835/6505] Update heimdalldashboard-update.sh --- misc/heimdalldashboard-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/heimdalldashboard-update.sh b/misc/heimdalldashboard-update.sh index 43320d81..3ca71ca7 100644 --- a/misc/heimdalldashboard-update.sh +++ b/misc/heimdalldashboard-update.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -e +PP=`echo "\e[1;35m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' From 76d2c118813f9d71df65364286cd7742be18ba56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 17:29:06 -0400 Subject: [PATCH 1836/6505] Update heimdalldashboard2.4.6-update.sh --- misc/heimdalldashboard2.4.6-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/heimdalldashboard2.4.6-update.sh b/misc/heimdalldashboard2.4.6-update.sh index 09b1d1c9..0bbc86c3 100644 --- a/misc/heimdalldashboard2.4.6-update.sh +++ b/misc/heimdalldashboard2.4.6-update.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -e +PP=`echo "\e[1;35m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' From ff8d0d2b2002d1d6afceedb36e4e518f8edb846c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 17:29:29 -0400 Subject: [PATCH 1837/6505] Update heimdalldashboard-weird-update.sh --- misc/heimdalldashboard-weird-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/heimdalldashboard-weird-update.sh b/misc/heimdalldashboard-weird-update.sh index a622b20f..fe9341c0 100644 --- a/misc/heimdalldashboard-weird-update.sh +++ b/misc/heimdalldashboard-weird-update.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -e +PP=`echo "\e[1;35m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' From a24a548249ea8b285d666576fd6873f8ca6d21dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 19:01:06 -0400 Subject: [PATCH 1838/6505] Create heimdalldashboard-all-update.sh --- misc/heimdalldashboard-all-update.sh | 119 +++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 misc/heimdalldashboard-all-update.sh diff --git a/misc/heimdalldashboard-all-update.sh b/misc/heimdalldashboard-all-update.sh new file mode 100644 index 00000000..66539ed6 --- /dev/null +++ b/misc/heimdalldashboard-all-update.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +set -e +PP=`echo "\e[1;35m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +while true; do + read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _ _ _ _ _ _ _____ _ _ _ + | | | | (_) | | | | | | __ \ | | | | | | + | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | + | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | + | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | + |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| + ${RD}UPDATE +${CL}" +} + +header_info + +echo -en "${GN} Stopping Heimdall Dashboard... " +systemctl disable heimdall.service &>/dev/null +systemctl stop heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Backing up Data... " +if [ -d "/opt/Heimdall-2.4.6" ]; then + cp -R /opt/Heimdall-2.4.6/database database-backup + cp -R /opt/Heimdall-2.4.6/public public-backup + elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then + cp -R /opt/Heimdall-2.4.7b/database database-backup + cp -R /opt/Heimdall-2.4.7b/public public-backup + elif [[ -d "/opt/Heimdall-2.4.8" ]]; then + cp -R /opt/Heimdall-2.4.8/database database-backup + cp -R /opt/Heimdall-2.4.8/public public-backup + else + cp -R /opt/Heimdall/database database-backup + cp -R /opt/Heimdall/public public-backup +fi +sleep 1 +echo -e "${CM}${CL} \r" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null +tar xvzf ${RELEASE}.tar.gz &>/dev/null +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') + +if [ ! -d "/opt/Heimdall" ]; then + mv Heimdall-${VER} /opt/Heimdall + else + cp -R Heimdall-${VER}/* /opt/Heimdall +fi +echo -e "${CM}${CL} \r" + +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target + +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 + +[Install] +WantedBy=multi-user.target" > $service_path + +echo -en "${GN} Restoring Data... " +cp -R database-backup/* /opt/Heimdall/database +cp -R public-backup/* /opt/Heimdall/public +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +if [ -d "/opt/Heimdall-2.4.6" ]; then + rm -rf /opt/Heimdall-2.4.6 + rm -rf /opt/v2.4.6.tar.gz + elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then + rm -rf /opt/Heimdall-2.4.7b + rm -rf /opt/v2.4.7b.tar.gz + elif [[ -d "/opt/Heimdall-2.4.8" ]]; then + rm -rf /opt/Heimdall-2.4.8 + rm -rf /opt/v2.4.8.tar.gz +fi + +rm -rf ${RELEASE}.tar.gz +rm -rf Heimdall-${VER} +rm -rf public-backup +rm -rf database-backup +rm -rf Heimdall +sleep 1 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Starting Heimdall Dashboard... " +systemctl enable --now heimdall.service &>/dev/null +sleep 2 +echo -e "${CM}${CL} \r" + +echo -en "${GN} Finished! ${CL}\n" + From 63e85fc69abb630ce04bdf2189ca78bac3904147 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Mar 2022 19:08:15 -0400 Subject: [PATCH 1839/6505] Update README.md --- README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a71b6a9c..1e0beda6 100644 --- a/README.md +++ b/README.md @@ -1143,17 +1143,11 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldash **Heimdall Dashboard Interface - IP:7990** -⚙️ **To Update Heimdall Dashboard (V2.4.6 Only!)** +⚙️ **To Update Heimdall Dashboard** Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard2.4.6-update.sh)" -``` -⚙️ **To Update Heimdall Dashboard (V2.4.8 & Above)** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard-update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard-all-update.sh)" ``` __________________________________________________________________________________________ From 9edba57a232727413e41472985f4ef873125bf4d Mon Sep 17 00:00:00 2001 From: Willy Ovalle Date: Mon, 28 Mar 2022 10:20:43 +0200 Subject: [PATCH 1840/6505] Adding Docker Compose --- setup/docker-install.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index a34d5d59..26881f26 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -65,6 +65,7 @@ get_latest_release() { DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") +DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") echo -en "${GN} Installing Docker $DOCKER_LATEST_VERSION... " DOCKER_CONFIG_PATH='/etc/docker/daemon.json' @@ -99,6 +100,24 @@ docker run -d \ echo -e "${CM}${CL} \r" fi +read -r -p "Would you like to add Docker Compose? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +DOCKER_COMPOSE="Y" +else +DOCKER_COMPOSE="N" +fi + +if [[ $DOCKER_COMPOSE == "Y" ]]; then +echo -en "${GN} Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION... " + DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} + mkdir -p $DOCKER_CONFIG/cli-plugins + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose + chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose + docker compose version +echo -e "${CM}${CL} \r" +fi + PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then echo -en "${GN} Customizing Container... " From 21f8e33e1b6014280f02b9777e78552477922fdd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Mar 2022 06:16:12 -0400 Subject: [PATCH 1841/6505] Update docker-install.sh --- setup/docker-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 26881f26..6488925a 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -112,9 +112,9 @@ if [[ $DOCKER_COMPOSE == "Y" ]]; then echo -en "${GN} Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION... " DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins - curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose &>/dev/null chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose - docker compose version +# docker compose version echo -e "${CM}${CL} \r" fi From f0fe003b0238edee9dffe925d16f8ec985b8c955 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Mar 2022 06:25:33 -0400 Subject: [PATCH 1842/6505] Update docker-install.sh --- setup/docker-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 6488925a..71a038c1 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -112,9 +112,8 @@ if [[ $DOCKER_COMPOSE == "Y" ]]; then echo -en "${GN} Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION... " DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins - curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose &>/dev/null + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose -# docker compose version echo -e "${CM}${CL} \r" fi From 8c26255a9122765a547bca53b56c2e0e3fb9ed98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Mar 2022 06:28:01 -0400 Subject: [PATCH 1843/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e0beda6..d9e261ca 100644 --- a/README.md +++ b/README.md @@ -829,7 +829,7 @@ ________________________________________________________________________________

    Docker LXC

    -

    With Selectable Storage Drivers & Add Portainer Option

    +

    With Selectable Storage Drivers & Add Portainer/Docker Compose Option

    To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). From b507e33629cda9b4a311a56932f641e0f2fe95f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Mar 2022 06:32:02 -0400 Subject: [PATCH 1844/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 04f70bf8..4c9aca10 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-03-28 + +### Changed + +- **Docker LXC** + - Add Docker Compose Option (@wovalle) + ## 2022-03-27 ### Changed From b5f4961d1d1a49006d8be63dba40493799f7a438 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Mar 2022 17:00:13 -0400 Subject: [PATCH 1845/6505] Update technitiumdns-update.sh --- misc/technitiumdns-update.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/misc/technitiumdns-update.sh b/misc/technitiumdns-update.sh index 3f2b7c75..3cb30e42 100644 --- a/misc/technitiumdns-update.sh +++ b/misc/technitiumdns-update.sh @@ -14,7 +14,7 @@ echo "===============================" echo "Technitium DNS Server Update" echo "===============================" -if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 5.0."; +if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 6.0."; then dotnetFound="yes" else @@ -24,24 +24,24 @@ fi if [ -d $dotnetDir ] then dotnetUpdate="yes" - echo "Updating .NET 5 Runtime..." + echo "Updating .NET 6 Runtime..." fi - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 5.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >> $installLog 2>&1 + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 6.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >> $installLog 2>&1 if [ ! -f "/usr/bin/dotnet" ] then ln -s $dotnetDir/dotnet /usr/bin >> $installLog 2>&1 fi - if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 5.0."; + if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 6.0."; then if [ "$dotnetUpdate" = "yes" ] then - echo ".NET 5 Runtime was updated successfully!" + echo ".NET 6 Runtime was updated successfully!" fi else - echo "Failed to update .NET 5 Runtime. Please try again." + echo "Failed to update .NET 6 Runtime. Please try again." exit 1 fi From 396d910cf487e5a604dfedf02f1edf23b468af55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Mar 2022 08:23:00 -0400 Subject: [PATCH 1846/6505] Update haos_vm.sh --- vm/haos_vm.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 655e866a..54c48383 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -9,8 +9,11 @@ while true; do esac done clear -CL=`echo "\033[m"` +RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` function header_info { echo -e "${BL} _ _ ____ _____ From c7717eda0ef2e4a816c8027e4157f68179f6811d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Mar 2022 08:52:20 -0400 Subject: [PATCH 1847/6505] Create pimox-haos.sh --- vm/pimox-haos.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 vm/pimox-haos.sh diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh new file mode 100644 index 00000000..66be6f55 --- /dev/null +++ b/vm/pimox-haos.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + REASON=$1 + MSG="\e[91mERROR: \e[93m$EXIT@" + if [ -z "$REASON" ]; then + MSG="$MSG$LINE:" + REASON="Unknown failure occured." + else + MSG="$MSG`echo $(( $LINE - 1 ))`:" + fi + echo -e "$MSG \e[97m$REASON\e[39m\e[49m" + exit $EXIT +} +function cleanup() { + popd >/dev/null + rm -rf $TMP +} +trap cleanup EXIT +TMP=`mktemp -d` +pushd $TMP >/dev/null + +VMID=$(cat<&/dev/null && \ +qm importdisk $VMID ${FILE%".xz"} local 1>&/dev/null +echo -e "Completed Successfully, New VM ID is $VMID \n" From 90147907f7aa543b6014d6aad8d32150ccf52251 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Mar 2022 08:54:30 -0400 Subject: [PATCH 1848/6505] Rename pimox-haos.sh to pimox-haos-vm.sh --- vm/{pimox-haos.sh => pimox-haos-vm.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename vm/{pimox-haos.sh => pimox-haos-vm.sh} (100%) diff --git a/vm/pimox-haos.sh b/vm/pimox-haos-vm.sh similarity index 100% rename from vm/pimox-haos.sh rename to vm/pimox-haos-vm.sh From 09d5fa969b6eb3ccecb497f9eeee7441009026e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Mar 2022 09:04:16 -0400 Subject: [PATCH 1849/6505] Update pimox-haos-vm.sh --- vm/pimox-haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index 66be6f55..cb3b8fd4 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -61,7 +61,7 @@ xz -d $FILE echo -e "Creating new HAOS VM \n" qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -bootdisk scsi0 \ -efidisk0 local:vm-${VMID}-disk-0,size=128K \ - -name test -net0 virtio,bridge=vmbr0 \ + -name haos -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsi0 local:vm-${VMID}-disk-1,size=32G \ -scsihw virtio-scsi-pci && \ pvesm alloc local $VMID vm-${VMID}-disk-0 128 1>&/dev/null && \ From 164970fbce9978153ae35ea365dfb2585fd90bca Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Mar 2022 09:08:47 -0400 Subject: [PATCH 1850/6505] Update haos_vm.sh --- vm/haos_vm.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 54c48383..63eab989 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -9,10 +9,7 @@ while true; do esac done clear -RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` CL=`echo "\033[m"` function header_info { echo -e "${BL} From 380e387895c8ab77418e51d009b87642e7c453a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Mar 2022 13:32:28 -0400 Subject: [PATCH 1851/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index e58e6e54..03b8adab 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +# inspired by https://github.com/IndrekHaav/photoprism-debian set -o errexit set -o errtrace set -o nounset @@ -110,12 +110,6 @@ PHOTOPRISM_ADMIN_PASSWORD='photoprism' PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism' PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -# Uncomment below if using MariaDB/MySQL instead of SQLite (the default) -# PHOTOPRISM_DATABASE_DRIVER='mysql' -# PHOTOPRISM_DATABASE_SERVER='MYSQL_IP_HERE' -# PHOTOPRISM_DATABASE_NAME='DB_NAME' -# PHOTOPRISM_DATABASE_USER='USER_NAME' -# PHOTOPRISM_DATABASE_PASSWORD='PASSWORD' " > $env_path echo -en "${GN} Creating Service file photoprism.service... " From 813b4becc4fec4379441f7eed80d56c749544384 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Mar 2022 13:43:21 -0400 Subject: [PATCH 1852/6505] Update pimox-haos-vm.sh --- vm/pimox-haos-vm.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index cb3b8fd4..012208af 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -1,4 +1,5 @@ #!/bin/bash +# for testing only set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' From d72e734dad2a2bcb7c7a80c339a907f3ca9e7f2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Mar 2022 07:28:19 -0400 Subject: [PATCH 1853/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 03b8adab..01aa2f7b 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# inspired by https://github.com/IndrekHaav/photoprism-debian + set -o errexit set -o errtrace set -o nounset From 10d93f7b22c9e5329356bd7e4f81f915c0c0c94a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Mar 2022 09:48:16 -0400 Subject: [PATCH 1854/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 01aa2f7b..5159630f 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -71,42 +71,38 @@ sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Node.js... " -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null +apt-get install -y nodejs git make g++ gcc &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Golang... " -wget https://golang.org/dl/go1.17.8.linux-amd64.tar.gz &>/dev/null -sudo tar -C /usr/local -xzf go1.17.8.linux-amd64.tar.gz &>/dev/null -sudo ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null +wget https://golang.org/dl/go1.18.linux-amd64.tar.gz &>/dev/null +tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz &>/dev/null +ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Tensorflow... " wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null -sudo tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null -sudo ldconfig &>/dev/null +tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null +ldconfig &>/dev/null echo -e "${CM}${CL} \r" -sudo useradd --system photoprism &>/dev/null -sudo mkdir -p /opt/photoprism/bin -sudo mkdir /var/lib/photoprism -sudo chown photoprism:photoprism /var/lib/photoprism &>/dev/null - echo -en "${GN} Cloning PhotoPrism... " +mkdir -p /opt/photoprism/bin +mkdir /var/lib/photoprism git clone https://github.com/photoprism/photoprism.git &>/dev/null cd photoprism git checkout release &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Building PhotoPrism... " -sudo make all &>/dev/null -sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null -sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null -sudo chown -R photoprism:photoprism /opt/photoprism +make all &>/dev/null +./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null +cp -a assets/ /opt/photoprism/assets/ &>/dev/null echo -e "${CM}${CL} \r" env_path="/var/lib/photoprism/.env" echo " -PHOTOPRISM_ADMIN_PASSWORD='photoprism' +PHOTOPRISM_ADMIN_PASSWORD='admin' PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism' PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' @@ -121,8 +117,7 @@ After=network.target [Service] Type=forking -User=photoprism -Group=photoprism +User=root WorkingDirectory=/opt/photoprism EnvironmentFile=/var/lib/photoprism/.env ExecStart=/opt/photoprism/bin/photoprism up -d @@ -130,9 +125,7 @@ ExecStop=/opt/photoprism/bin/photoprism down [Install] WantedBy=multi-user.target" > $service_path -sudo systemctl daemon-reload -sudo systemctl start photoprism -sudo systemctl enable photoprism &>/dev/null +systemctl enable --now photoprism &>/dev/null echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -156,5 +149,5 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/go echo -e "${CM}${CL} \n" From 09366041923891bf257a17ad45ed339b59038bf5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Mar 2022 09:49:41 -0400 Subject: [PATCH 1855/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d9e261ca..bae3c759 100644 --- a/README.md +++ b/README.md @@ -1216,7 +1216,7 @@ After the script completes, If you're dissatisfied with the default settings, cl ``` **password** ```yaml - photoprism + admin ``` [PhotoSync](https://www.photosync-app.com/home.html) From dc08c15e8d14bbf607559010e25e39ef5a4f113d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Mar 2022 13:41:51 -0400 Subject: [PATCH 1856/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 5159630f..db077120 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -71,7 +71,7 @@ sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Node.js... " -apt-get install -y nodejs git make g++ gcc &>/dev/null +apt-get install -y nodejs &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Golang... " From eea7900b13098d264d4a7e96b978d17d49dafe31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Mar 2022 16:02:50 -0400 Subject: [PATCH 1857/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index db077120..08596b5c 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash - set -o errexit set -o errtrace set -o nounset @@ -81,9 +80,20 @@ ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Tensorflow... " -wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null -tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null -ldconfig &>/dev/null +AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) +if [[ "$AVX" == "avx2" ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + ldconfig &>/dev/null + elif [[ "$AVX" == "avx" ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + ldconfig &>/dev/null + else + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null + ldconfig &>/dev/null +fi echo -e "${CM}${CL} \r" echo -en "${GN} Cloning PhotoPrism... " From 2f0fdb038e071c7d42d99fb3321a0fa5a850d99f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Mar 2022 19:21:56 -0400 Subject: [PATCH 1858/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bae3c759..5f81a74d 100644 --- a/README.md +++ b/README.md @@ -976,7 +976,7 @@ ________________________________________________________________________________
    - 🔸Plex Media Server LXC + Plex Media Server LXC

    From ae59810180c6b6f899b55665e2b93721812b5f16 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 06:06:18 -0400 Subject: [PATCH 1859/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4c9aca10..f629d368 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,6 @@ # Change Log +

    All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) From 11122623bc5737a16b295399f65475f3c1472ae1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 06:27:13 -0400 Subject: [PATCH 1860/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f629d368..4c9aca10 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,6 +1,5 @@ # Change Log -

    All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) From 0b58a9e387836d9f904c9579aae2761fc7c5fa90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 11:58:43 -0400 Subject: [PATCH 1861/6505] Create podman-copy-data-docker.sh --- misc/podman-copy-data-docker.sh | 122 ++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 misc/podman-copy-data-docker.sh diff --git a/misc/podman-copy-data-docker.sh b/misc/podman-copy-data-docker.sh new file mode 100644 index 00000000..de5e0b1a --- /dev/null +++ b/misc/podman-copy-data-docker.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman-copy-data-docker.sh)" +while true; do + read -p "Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Home Assistant LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Podman LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.03.31" 13 50 || exit +info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi +msg "Mounting Container Disks..." +DOCKER_PATH=/var/lib/docker/volumes/hass_config/ +PODMAN_PATH=/var/lib/containers/storage/volumes/hass_config/ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${PODMAN_PATH}" ] || \ + die "Home Assistant directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_TO' not found." + +rm -rf ${CTID_TO_PATH}${DOCKER_PATH} +mkdir ${CTID_TO_PATH}${DOCKER_PATH} + +msg "Copying Data Between Containers..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${PODMAN_PATH} ${CTID_TO_PATH}${DOCKER_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman-copy-data-docker.sh)" From 930aeb648c1ed5b104731ff9aa903f45a9e2deb5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 12:27:23 -0400 Subject: [PATCH 1862/6505] Update podman-copy-data-docker.sh --- misc/podman-copy-data-docker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/podman-copy-data-docker.sh b/misc/podman-copy-data-docker.sh index de5e0b1a..f3849bc3 100644 --- a/misc/podman-copy-data-docker.sh +++ b/misc/podman-copy-data-docker.sh @@ -99,8 +99,8 @@ CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ [ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ die "Home Assistant directories in '$CTID_TO' not found." -rm -rf ${CTID_TO_PATH}${DOCKER_PATH} -mkdir ${CTID_TO_PATH}${DOCKER_PATH} +#rm -rf ${CTID_TO_PATH}${DOCKER_PATH} +#mkdir ${CTID_TO_PATH}${DOCKER_PATH} msg "Copying Data Between Containers..." RSYNC_OPTIONS=( From 57767c1aa6720a4a6b6f8c0e2a9335ad0c7e56f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 12:42:22 -0400 Subject: [PATCH 1863/6505] Update podman-copy-data-docker.sh --- misc/podman-copy-data-docker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/podman-copy-data-docker.sh b/misc/podman-copy-data-docker.sh index f3849bc3..de5e0b1a 100644 --- a/misc/podman-copy-data-docker.sh +++ b/misc/podman-copy-data-docker.sh @@ -99,8 +99,8 @@ CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ [ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ die "Home Assistant directories in '$CTID_TO' not found." -#rm -rf ${CTID_TO_PATH}${DOCKER_PATH} -#mkdir ${CTID_TO_PATH}${DOCKER_PATH} +rm -rf ${CTID_TO_PATH}${DOCKER_PATH} +mkdir ${CTID_TO_PATH}${DOCKER_PATH} msg "Copying Data Between Containers..." RSYNC_OPTIONS=( From 99d0bea3cafab46c1bb2253ee2fb464cccbd6f87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 14:50:58 -0400 Subject: [PATCH 1864/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f81a74d..da08fdbe 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Select a Proxmox Helper Below

    - +
    license
    checks 🔸 updated in the past 7 days [Changelog](https://github.com/tteck/Proxmox/blob/main/CHANGELOG.MD) From e0b4c85ee34258ad24169a6a05e71114d61aa3ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 15:01:12 -0400 Subject: [PATCH 1865/6505] Add files via upload --- misc/images/change.png | Bin 0 -> 5753 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/change.png diff --git a/misc/images/change.png b/misc/images/change.png new file mode 100644 index 0000000000000000000000000000000000000000..5543ec3e9623496d85062400384d3c90621eab76 GIT binary patch literal 5753 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 literal 0 HcmV?d00001 From 8309832aa2276901b1b23e644f5dae1ca2294362 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 15:12:07 -0400 Subject: [PATCH 1866/6505] Add files via upload --- misc/images/changelog.png | Bin 0 -> 2421 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/changelog.png diff --git a/misc/images/changelog.png b/misc/images/changelog.png new file mode 100644 index 0000000000000000000000000000000000000000..f762d00ee6a53d0987096a338da0e0523151a829 GIT binary patch literal 2421 zcmV-*35xcKP)Px;FG)l}R9HvNn0ruE*B!^dcVD0)zHmeVLrU5twoPqP-L9kJH~@afj&5PxI`4i-C}@Nz7v7bHqtrT z5IiIPZ&E!6foj&;L)XV7#QkDM@I*?B_=bUN??58f{z{`vK| zdv6GXLw1VV(b10W`jknbCIM>V^oa(x*LG_ZL~{aY#-$1}5+p=;JRUfm zPB=y!a5@}_T)Y@zv%_%p>Q(&eDnXM3f^(2IO1BKdFw6w7@lk)~j9K{j+?xyvWXNYXK1UWO8aM>)L%kFL$Q4Ma=6`YT)K1#8jS|OeECK2yr16Bo;{n+zhM4C z{P9prS^CawZb~5Y!A3S&pUU03LlgomR!b0!BpSt#KUt$uqqE~83JVMA_?tIxQlB9u zGBOfjVPR-*Z%1cmCswariMY7$(Z1*lCtm_YlZ7RR7& ze{EUjbP6?@>sdo`8m9pHd|tR*WR=NqG7P!2esqc|Ltr-T>4IV7Q{Z_Kk1Ptu-~%_D zZXa4ZEEu@!#L=SFh>MG(P;YGgHI_t16Cf^gXZF+zDL}V-rB&A5Z4EfLB#!jAqrH>D zba!`Cn5{28fz8i74i&?|>lfhi_~7>X;r8;l_;oK1pT33*#!aZGsK5?G5+WBxp{}8Z z%S_Lm#$-)KF4d65k~l=CmTfft-rRfusi~=0U;GKuH$8(FpN>JORt>e9fzL0%_V`E`78j+Wm_i#YI&8)B0Lm2tqN*}0WS#f^8!`J<@Mtq*Zbk)f%AX2;LvYhfXQT{>ekj) zmStxbOufqL>y2DmS{B>ae}@9yun?0`4+^ZXzFr&Fu3d+bkrAXdT*jW1bqLj}pw$o{ z&>V?u%981LT(;QYxCw9FTzOYPjsoX-sCSujVq+asuhcD2M{Y;M%pX z@%_hsK!LLMe~H~G&mvT(LWo8MjhcaqKnZ}C7hvffhRZ9^T5n+TvkR7+i&lqia17`@cKPaK}DB7iNacq8gs(uV`ylInrvUr&k+`?hE7fT zKvg1vs;6%lZode(PlVGa;-gRhjryFmXl`z%p`xm$qAWkRaB7p8>Z{p|v>eVpV3Pu) zg`^)6NbvRC+4D$ANx?6QKS9cdWq2}X9&{Q&qmnjc5~)3Yz{4|e`+=$xU*W^I)?mSc z1!!z+Kv7XKs%k5_{Op3MS6Q`bAD5GnM{{b)T+#*+0Fr&Fv7w2|-qX`VReC#l9cJlN zn5k1EL`TfVz{iW!hdeyMHMQex`397hmVzrQ#oRgbQCU?{R**l9LPk?Ho0XBn4Gi{E zMaVYbc6;dRm(k=<#Ng-$M^RK%1gq78*M8rHxAiNa)iBVir6B4T0ON@(=;?Eyja^3r zV@*vBlD6wHCwv|%Ybv;c+`_39GMe_WSs8g0h^S(*SSN)c6RK4zbaws?85tSWwCQ#K zg#Df;cx$3&(rUF>x^yWF1_S=}QUala2 z8lZjECQn*kt)(+RiB1%|9;FiHr+KfMA8ufK{VOBUn#_~-Brw;L-~tSBogd~51e_Wr(dZdcwYkg}~ z>eRA%f|tCM)5{Z!0(f44Kq_hDdFh$nlQE?7fyhnz4e8lP-?}^x0GYwE-N5$C>SJ=mWpI+kS3(Z9G+y1G6;p>DTv=MUCA@qMtpuhTuvukZZ}G} zcagj;0Rk`L$z_jYe`9k1Di}x&V6IlHjqC2VUW|&09Lm38YE=fqT-XRMMx6 zQO5gxJ~$i>np=^?E;D}@wrt)Aoh}4%k3EW}=9X7Zo;cY$UZJ@F7G-8<6vxIcO_Cs# zQ^hDBnS}U?l1~!=scqap9i*R2Zy`q_pN}4g2;7b9mecm(2QR(;+6J6E|2fW_{!0V^ z$9NzOfLQ=$03_L%vIPHDT7puU^Z+RLY2|m5IY`w-$HqQ&tEcBv0OVL}|E3=k^Zh>x nnU8!Z`EUY9uA~Y8+@$^wf+lo|W<$Yl00000NkvXXu0mjfBt3h1 literal 0 HcmV?d00001 From 57a954ae15a78af7937ff0ae5c8563d116e63358 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 15:26:22 -0400 Subject: [PATCH 1867/6505] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index da08fdbe..4b5aabcc 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,6 @@

    Select a Proxmox Helper Below

    -license
    checks - -🔸 updated in the past 7 days [Changelog](https://github.com/tteck/Proxmox/blob/main/CHANGELOG.MD) - +license checks
    🔸
    Proxmox VE 7 Post Install From 4c9d662b1066a4911c7fe2d3090cc16949e27dc6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 15:52:50 -0400 Subject: [PATCH 1868/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b5aabcc..49e9d03c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Select a Proxmox Helper Below

    -license checks 🔸 + 🔸
    Proxmox VE 7 Post Install From 8950cad627378d92645ea4cb856b30ab9577c3a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 16:10:30 -0400 Subject: [PATCH 1869/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4c9aca10..79005e57 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,3 +1,4 @@ + # Change Log All notable changes to this project will be documented in this file. From 1e17daed77a3fb57b92da28c5a5d1822e53746ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Mar 2022 18:05:45 -0400 Subject: [PATCH 1870/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49e9d03c..49b9f0a7 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ ________________________________________________________________________________
    - 🔸Proxmox CPU Scaling Governor + Proxmox CPU Scaling Governor

    From 5443f699d67426bf715b54d1f220eadb875b917a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 09:04:08 -0400 Subject: [PATCH 1871/6505] Update jellyfin_container.sh --- ct/jellyfin_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin_container.sh index cd6e7437..3b8e674a 100644 --- a/ct/jellyfin_container.sh +++ b/ct/jellyfin_container.sh @@ -109,7 +109,7 @@ echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" pveam update >/dev/null echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 +OSVERSION=${OSTYPE}-20.04 mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) TEMPLATE="${TEMPLATES[-1]}" pveam download local $TEMPLATE >/dev/null || From 29734f0ebda771e32ba8587876ae1b973d32fc5e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 09:26:58 -0400 Subject: [PATCH 1872/6505] Update debian.sh --- ct/debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index ebd9f482..19cc78a5 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -219,7 +219,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian -export PCT_OSVERSION=11 +export PCT_OSVERSION=11.3 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" -features $FEATURES From 4836a8ea547422c37c4e4739311d89b631084841 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 09:30:33 -0400 Subject: [PATCH 1873/6505] Update adguard.sh --- ct/adguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index ac8278f8..d695ab89 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -220,7 +220,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian -export PCT_OSVERSION=11 +export PCT_OSVERSION=11.3 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" -features $FEATURES From f9270e514bec84e9a63a3a11a3856e94bec238f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 09:32:31 -0400 Subject: [PATCH 1874/6505] Update adguard.sh --- ct/adguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index d695ab89..ac8278f8 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -220,7 +220,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian -export PCT_OSVERSION=11.3 +export PCT_OSVERSION=11 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" -features $FEATURES From 7cf31f54adc201f5b16f326355cefa94a9b2a129 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 09:32:59 -0400 Subject: [PATCH 1875/6505] Update debian.sh --- ct/debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index 19cc78a5..ebd9f482 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -219,7 +219,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian -export PCT_OSVERSION=11.3 +export PCT_OSVERSION=11 export PCT_DISK_SIZE=2 export PCT_OPTIONS=" -features $FEATURES From 6f33e4b8f2f2b954366fd7d40c666bed17cf09fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 10:22:55 -0400 Subject: [PATCH 1876/6505] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 49b9f0a7..98006616 100644 --- a/README.md +++ b/README.md @@ -691,7 +691,8 @@ npm start Run in the LXC console ```yaml -bash /opt/zigbee2mqtt/update.sh +cd /opt/zigbee2mqtt/ +bash update.sh ``` ⚙️ **Copy Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** From 2dd357b90aeca10d878de5f4de785483827cb87f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 10:56:08 -0400 Subject: [PATCH 1877/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 98006616..11a0cd7c 100644 --- a/README.md +++ b/README.md @@ -691,7 +691,7 @@ npm start Run in the LXC console ```yaml -cd /opt/zigbee2mqtt/ +cd /opt/zigbee2mqtt bash update.sh ``` ⚙️ **Copy Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** From e60d1ff5a8c1c1b5070406e45f6bf67bb5b88102 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 13:46:49 -0400 Subject: [PATCH 1878/6505] Update debian.sh --- ct/debian.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index ebd9f482..fc7f98d4 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 51e88181a5023ce3827ecd59cb54b60686e39e3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 13:51:10 -0400 Subject: [PATCH 1879/6505] Update adguard.sh --- ct/adguard.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index ac8278f8..9838585b 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -43,11 +43,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -71,7 +68,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -87,11 +83,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -115,7 +108,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -132,11 +124,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -160,7 +149,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 4f1d1a55fa607c65602fd1eaf21d686f7f162145 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 13:54:49 -0400 Subject: [PATCH 1880/6505] Update daemonsync.sh --- ct/daemonsync.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index c6403ba5..5b47dfa6 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -41,11 +41,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -69,7 +66,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -85,11 +81,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -113,7 +106,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -130,11 +122,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -158,7 +147,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From a1017df339eca804ae25d720bc0fa352a826376f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 13:56:14 -0400 Subject: [PATCH 1881/6505] Update dashy.sh --- ct/dashy.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index fc62084b..49e63390 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From d5683cb35ddb41970b079d33407d09c6e19cd922 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 13:57:56 -0400 Subject: [PATCH 1882/6505] Update docker.sh --- ct/docker.sh | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/ct/docker.sh b/ct/docker.sh index b1ad914a..43ceb81b 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -39,11 +39,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -67,7 +64,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -83,11 +79,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -111,7 +104,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${RD} If Using ZFS, You Have Storage Driver Options${CL}\n" @@ -130,11 +122,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -158,7 +147,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done show_menu4(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -176,11 +164,8 @@ option_picked(){ printf " ${YW}${message4}${CL}\n" } show_menu4 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -204,7 +189,6 @@ while [ $opt != '' ] show_menu4; ;; esac - fi done set -o errexit From e3f2ac13d03dc21b40ab66e4e1926d13e0e20ae6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:05:20 -0400 Subject: [PATCH 1883/6505] Update esphome.sh --- ct/esphome.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index 06f9d513..8fcbf29b 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From d0d2d5e6b7870d3892ecf09233f843082d2ead56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:06:57 -0400 Subject: [PATCH 1884/6505] Update grafana.sh --- ct/grafana.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/grafana.sh b/ct/grafana.sh index 0e7244df..04d65207 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 33ec3d13c37c77acf86fa6667e130a0134432f87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:10:27 -0400 Subject: [PATCH 1885/6505] Update homeassistant.sh --- ct/homeassistant.sh | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index e25ce4d5..938b6921 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${RD} If Using ZFS, You Have Storage Driver Options${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done show_menu4(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -177,11 +165,8 @@ option_picked(){ printf " ${YW}${message4}${CL}\n" } show_menu4 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -205,7 +190,6 @@ while [ $opt != '' ] show_menu4; ;; esac - fi done set -o errexit From 4c055c172ca94486e398ebf90ff6830e63fc84ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:11:38 -0400 Subject: [PATCH 1886/6505] Update homebridge.sh --- ct/homebridge.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 8f6eb118..3e045697 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -39,11 +39,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -67,7 +64,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -83,11 +79,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -111,7 +104,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -128,11 +120,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -156,7 +145,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From e8a345ad0f27abb6593955d0d761867b2c44c260 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:13:01 -0400 Subject: [PATCH 1887/6505] Update influxdb.sh --- ct/influxdb.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 119d2a4e..0d9e113c 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From dc94e229322cf04612f9294d3f882290a075fc03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:14:13 -0400 Subject: [PATCH 1888/6505] Update mariadb.sh --- ct/mariadb.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 73e2134a..233296d4 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 9a061db4c51928bb79f0cb0bc9c368b5a1621e89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:15:27 -0400 Subject: [PATCH 1889/6505] Update motioneye.sh --- ct/motioneye.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 92894a21..0c3449b3 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -41,11 +41,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -69,7 +66,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -85,11 +81,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -113,7 +106,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -130,11 +122,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -158,7 +147,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 455b3d50640ea297af54d5cec280890bfb4227bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:16:50 -0400 Subject: [PATCH 1890/6505] Update mqtt.sh --- ct/mqtt.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 254f4619..7bd70ed0 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From a7b3c581962b1d44651eec0012f1eaf21dc57699 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:18:24 -0400 Subject: [PATCH 1891/6505] Update nginx-proxy-manager.sh --- ct/nginx-proxy-manager.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager.sh index 670cbdcd..2b147d60 100644 --- a/ct/nginx-proxy-manager.sh +++ b/ct/nginx-proxy-manager.sh @@ -39,11 +39,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -67,7 +64,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -83,11 +79,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -111,7 +104,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -128,11 +120,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -156,7 +145,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 5fee6bfc0071dd19753d6654278bbde5b49e37b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:19:38 -0400 Subject: [PATCH 1892/6505] Update node-red.sh --- ct/node-red.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index 504ddc71..9ecc7d17 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 440a4933cee7713c4ba88216fe0d280d5bf9fdbc Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:20:53 -0400 Subject: [PATCH 1893/6505] Update omada.sh --- ct/omada.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/omada.sh b/ct/omada.sh index af8e3b65..6ec8036b 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From b7c9ce46d0db6d51b3468be00f2d02c11590de88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:22:05 -0400 Subject: [PATCH 1894/6505] Update photoprism.sh --- ct/photoprism.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 076aefef..31035d89 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 4a234005268ba74c23c96196d6843cb42cc24939 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:26:33 -0400 Subject: [PATCH 1895/6505] Update pihole.sh --- ct/pihole.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/pihole.sh b/ct/pihole.sh index 2667f184..9a0abcdd 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -41,11 +41,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -69,7 +66,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -85,11 +81,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -113,7 +106,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -130,11 +122,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -158,7 +147,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 70dc875f565e1bb80de849531526c11cf1c5f647 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:27:44 -0400 Subject: [PATCH 1896/6505] Update technitiumdns.sh --- ct/technitiumdns.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index 15ffdf42..2d960480 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 5bd16f8c63b16996fe9733b373953d02d9a38226 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:28:56 -0400 Subject: [PATCH 1897/6505] Update ubuntu.sh --- ct/ubuntu.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index d24150a7..4152e1d0 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 3bee43b1c03d741d358e32894d9d7d7a5b835814 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:30:02 -0400 Subject: [PATCH 1898/6505] Update unifi.sh --- ct/unifi.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/unifi.sh b/ct/unifi.sh index 6b485dd6..077f3cc1 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -41,11 +41,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -69,7 +66,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -85,11 +81,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -113,7 +106,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -130,11 +122,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -158,7 +147,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From a2783a03226541660ae2c10ff8892c79169b51a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:31:18 -0400 Subject: [PATCH 1899/6505] Update vaultwarden.sh --- ct/vaultwarden.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 6e8c43b7..fe16570c 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 0a54b61683c345a8f5e0b17e419b7602c5408ac1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:32:27 -0400 Subject: [PATCH 1900/6505] Update wireguard.sh --- ct/wireguard.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index e6774094..7137c4d3 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -40,11 +40,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -68,7 +65,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -84,11 +80,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -112,7 +105,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -129,11 +121,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -157,7 +146,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 987280d1e5b7ec20ffbcd24e59150c70e80a74f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:33:36 -0400 Subject: [PATCH 1901/6505] Update zigbee2mqtt.sh --- ct/zigbee2mqtt.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 9d0edba5..f4a0c0fd 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 9c7aaa6ba102ad96d460b8dd3116c721e59ba1d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:34:53 -0400 Subject: [PATCH 1902/6505] Update zwavejs2mqtt.sh --- ct/zwavejs2mqtt.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/zwavejs2mqtt.sh b/ct/zwavejs2mqtt.sh index 65034e6c..72669df9 100644 --- a/ct/zwavejs2mqtt.sh +++ b/ct/zwavejs2mqtt.sh @@ -43,11 +43,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -71,7 +68,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -87,11 +83,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -115,7 +108,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -132,11 +124,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -160,7 +149,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From e2e7357c604e9ad90ad8016f8ad66b16919b24a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:37:35 -0400 Subject: [PATCH 1903/6505] Update heimdalldashboard.sh --- ct/heimdalldashboard.sh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index fac092ed..1a60e74c 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -42,11 +42,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -70,7 +67,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done show_menu2(){ printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" @@ -86,11 +82,8 @@ option_picked(){ printf " ${YW}${message2}${CL}\n" } show_menu2 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -114,7 +107,6 @@ while [ $opt != '' ] show_menu2; ;; esac - fi done show_menu3(){ printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" @@ -131,11 +123,8 @@ option_picked(){ printf " ${YW}${message3}${CL}\n" } show_menu3 -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -159,7 +148,6 @@ while [ $opt != '' ] show_menu3; ;; esac - fi done set -o errexit From 37f0ec2a7d2f08b55838cb28a7709a2c1753c656 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 14:53:12 -0400 Subject: [PATCH 1904/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 79005e57..7b7b49fa 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-01 + +### Changed + +- **Scripts** (V2) + - FIX Pressing enter without making a selection first would cause an Error + ## 2022-03-28 ### Changed From 7e045dcf3f170cd632adb848192ed0a763ea81f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Apr 2022 19:40:26 -0400 Subject: [PATCH 1905/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 11a0cd7c..81debf77 100644 --- a/README.md +++ b/README.md @@ -910,7 +910,7 @@ ________________________________________________________________________________
    - 🔸UniFi Network Application LXC + UniFi Network Application LXC

    @@ -939,7 +939,7 @@ ________________________________________________________________________________
    - 🔸Omada Controller LXC + Omada Controller LXC

    From 6aadf042e2d4e256c0e2e0f148a00b02fb5159f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Apr 2022 08:58:03 -0400 Subject: [PATCH 1906/6505] Delete heimdalldashboard2.4.6-update.sh --- misc/heimdalldashboard2.4.6-update.sh | 91 --------------------------- 1 file changed, 91 deletions(-) delete mode 100644 misc/heimdalldashboard2.4.6-update.sh diff --git a/misc/heimdalldashboard2.4.6-update.sh b/misc/heimdalldashboard2.4.6-update.sh deleted file mode 100644 index 0bbc86c3..00000000 --- a/misc/heimdalldashboard2.4.6-update.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env bash -set -e -PP=`echo "\e[1;35m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will Update Heimdall Dashboard V2.4.6 to Current. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _ _ _ _ _ _ _____ _ _ _ - | | | | (_) | | | | | | __ \ | | | | | | - | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | - | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | - | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | - |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| - ${RD}UPDATE FROM V2.4.6 ONLY! -${CL}" -} - -header_info - -echo -en "${GN} Stopping Heimdall Dashboard... " -systemctl disable heimdall.service &>/dev/null -systemctl stop heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Backing up Data... " -cp -R /opt/Heimdall-2.4.6/database database-backup -cp -R /opt/Heimdall-2.4.6/public public-backup -sleep 1 -echo -e "${CM}${CL} \r" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') -mv Heimdall-${VER} /opt/Heimdall -echo -e "${CM}${CL} \r" - -service_path="/etc/systemd/system/heimdall.service" -echo "[Unit] -Description=Heimdall -After=network.target - -[Service] -Restart=always -RestartSec=5 -Type=simple -User=root -WorkingDirectory=/opt/Heimdall -ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 -TimeoutStopSec=30 - -[Install] -WantedBy=multi-user.target" > $service_path - -echo -en "${GN} Restoring Data... " -cp -R database-backup/* /opt/Heimdall/database -cp -R public-backup/* /opt/Heimdall/public -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf ${RELEASE}.tar.gz -rm -rf public-backup -rm -rf database-backup -rm -rf /opt/Heimdall-2.4.6 -rm -rf /opt/v2.4.6.tar.gz -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting Heimdall Dashboard... " -systemctl enable --now heimdall.service &>/dev/null -sleep 2 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Finished! ${CL}\n" From 44e4b4f1559374ec009efcaa92b26fa8e125bbc7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Apr 2022 08:58:19 -0400 Subject: [PATCH 1907/6505] Delete heimdalldashboard-weird-update.sh --- misc/heimdalldashboard-weird-update.sh | 92 -------------------------- 1 file changed, 92 deletions(-) delete mode 100644 misc/heimdalldashboard-weird-update.sh diff --git a/misc/heimdalldashboard-weird-update.sh b/misc/heimdalldashboard-weird-update.sh deleted file mode 100644 index fe9341c0..00000000 --- a/misc/heimdalldashboard-weird-update.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash -set -e -PP=`echo "\e[1;35m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will Update Heimdall Dashboard weird to Current. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _ _ _ _ _ _ _____ _ _ _ - | | | | (_) | | | | | | __ \ | | | | | | - | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | - | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | - | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | - |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| - ${RD}UPDATE FROM WEIRD ONLY! -${CL}" -} - -header_info - -echo -en "${GN} Stopping Heimdall Dashboard... " -systemctl disable heimdall.service &>/dev/null -systemctl stop heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Backing up Data... " -cp -R /opt/Heimdall-2.4.8/database database-backup -cp -R /opt/Heimdall-2.4.8/public public-backup -sleep 1 -echo -e "${CM}${CL} \r" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') - -mv Heimdall-${VER} /opt/Heimdall -echo -e "${CM}${CL} \r" - -service_path="/etc/systemd/system/heimdall.service" -echo "[Unit] -Description=Heimdall -After=network.target - -[Service] -Restart=always -RestartSec=5 -Type=simple -User=root -WorkingDirectory=/opt/Heimdall -ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 -TimeoutStopSec=30 - -[Install] -WantedBy=multi-user.target" > $service_path - -echo -en "${GN} Restoring Data... " -cp -R database-backup/* /opt/Heimdall/database -cp -R public-backup/* /opt/Heimdall/public -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf ${RELEASE}.tar.gz -rm -rf public-backup -rm -rf database-backup -rm -rf /opt/Heimdall-2.4.8 -rm -rf /opt/v2.4.8.tar.gz -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting Heimdall Dashboard... " -systemctl enable --now heimdall.service &>/dev/null -sleep 2 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Finished! ${CL}\n" From d500582b1b73c7fe2b991288989b250d2da8a336 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Apr 2022 08:59:14 -0400 Subject: [PATCH 1908/6505] Delete heimdalldashboard-update.sh --- misc/heimdalldashboard-update.sh | 73 -------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 misc/heimdalldashboard-update.sh diff --git a/misc/heimdalldashboard-update.sh b/misc/heimdalldashboard-update.sh deleted file mode 100644 index 3ca71ca7..00000000 --- a/misc/heimdalldashboard-update.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash -set -e -PP=`echo "\e[1;35m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _ _ _ _ _ _ _____ _ _ _ - | | | | (_) | | | | | | __ \ | | | | | | - | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | - | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | - | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | - |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| - ${RD}UPDATE -${CL}" -} - -header_info - -echo -en "${GN} Stopping Heimdall Dashboard... " -systemctl stop heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Backing up Data... " -cp -R /opt/Heimdall/database database-backup -cp -R /opt/Heimdall/public public-backup -sleep 1 -echo -e "${CM}${CL} \r" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') -cp -R Heimdall-${VER}/* /opt/Heimdall -echo -e "${CM}${CL} \r" - -echo -en "${GN} Restoring Data... " -cp -R database-backup/* /opt/Heimdall/database -cp -R public-backup/* /opt/Heimdall/public -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf ${RELEASE}.tar.gz -rm -rf Heimdall-${VER} -rm -rf public-backup -rm -rf database-backup -rm -rf Heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting Heimdall Dashboard... " -systemctl start heimdall -sleep 2 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Finished! ${CL}\n" From e7f9405332ca85e00784f4974136c51118202ce5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Apr 2022 09:04:33 -0400 Subject: [PATCH 1909/6505] Update photoprism-update.sh --- misc/photoprism-update.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/misc/photoprism-update.sh b/misc/photoprism-update.sh index 0c7cda8f..7ab7f8f6 100644 --- a/misc/photoprism-update.sh +++ b/misc/photoprism-update.sh @@ -47,11 +47,8 @@ option_picked(){ printf " ${YW}${message1}${CL}\n" } show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; header_info; @@ -75,7 +72,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done echo -en "${GN} Stopping PhotoPrism... " From d47603cc6c14baf4a39901b1d726204cb1a449f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Apr 2022 09:06:08 -0400 Subject: [PATCH 1910/6505] Update node-red-themes.sh --- misc/node-red-themes.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh index 8217f0bd..5f8738b1 100644 --- a/misc/node-red-themes.sh +++ b/misc/node-red-themes.sh @@ -41,11 +41,8 @@ option_picked(){ clear show_menu -while [ $opt != '' ] +while [ "$opt" != " " ] do - if [ $opt = '' ]; then - exit; - else case $opt in 1) clear; option_picked "Installing Default Theme"; @@ -93,7 +90,6 @@ while [ $opt != '' ] show_menu; ;; esac - fi done echo -en "${GN} Installing ${THEME} Theme... " cd /root/.node-red From 26702f90458e579ea0885edfc8a682374d104927 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Apr 2022 13:46:29 -0400 Subject: [PATCH 1911/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 81debf77..b20898a3 100644 --- a/README.md +++ b/README.md @@ -827,7 +827,7 @@ ________________________________________________________________________________

    Docker LXC

    -

    With Selectable Storage Drivers & Add Portainer/Docker Compose Option

    +

    With Selectable Storage Drivers & Add Portainer/Docker Compose Options

    To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). From 574fe3ac907ee75c06fc195f7be2d9a6e16eab26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Apr 2022 18:17:09 -0400 Subject: [PATCH 1912/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b20898a3..c12fe9a6 100644 --- a/README.md +++ b/README.md @@ -1124,7 +1124,7 @@ ________________________________________________________________________________
    - 🔸Heimdall Dashboard LXC + Heimdall Dashboard LXC

    From 0fcaa91cb9ec82145c6ac05eea8fb1d8ebcf36e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 18:00:20 -0400 Subject: [PATCH 1913/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 83dbb60e..1cdb7435 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -67,7 +67,7 @@ apt-get -y install podman &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Pulling Yacht Image... " -podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null +podman pull ghcr.io/selfhostedpro/yacht:latest &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Yacht... " From 2e64f86ecbf865effba65fcc31c7817a5f64328c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 18:09:18 -0400 Subject: [PATCH 1914/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 1cdb7435..dd828cc2 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -77,8 +77,6 @@ podman run -d \ --restart always \ -v /var/run/podman/podman.sock:/var/run/docker.sock \ -v yacht:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ -p 8000:8000 \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CM}${CL} \r" From 68c6fc28a704653a5e2ee6adea45cb401a785bd0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 18:18:59 -0400 Subject: [PATCH 1915/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index dd828cc2..569966b4 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -66,19 +66,20 @@ echo -en "${GN} Installing Podman... " apt-get -y install podman &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Pulling Yacht Image... " -podman pull ghcr.io/selfhostedpro/yacht:latest &>/dev/null -echo -e "${CM}${CL} \r" +#echo -en "${GN} Pulling Yacht Image... " +#podman pull ghcr.io/selfhostedpro/yacht:latest &>/dev/null +#echo -e "${CM}${CL} \r" echo -en "${GN} Installing Yacht... " podman volume create yacht >/dev/null -podman run -d \ - --name yacht \ - --restart always \ - -v /var/run/podman/podman.sock:/var/run/docker.sock \ - -v yacht:/config \ - -p 8000:8000 \ - selfhostedpro/yacht:latest &>/dev/null +podman run -v /var/run/podman/podman.sock:/var/run/docker.sock -v yacht:/config -p 8000:8000 --name -d ghcr.io/selfhostedpro/yacht:latest &>/dev/null +#podman run -d \ +# --name yacht \ +# --restart always \ +# -v /var/run/podman/podman.sock:/var/run/docker.sock \ +# -v yacht:/config \ +# -p 8000:8000 \ +# selfhostedpro/yacht:latest &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Pulling Home Assistant Image... " From 526deac5ef82c1fa4293be0bf598d351b3e56730 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 18:28:48 -0400 Subject: [PATCH 1916/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 569966b4..d4475d50 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -66,20 +66,19 @@ echo -en "${GN} Installing Podman... " apt-get -y install podman &>/dev/null echo -e "${CM}${CL} \r" -#echo -en "${GN} Pulling Yacht Image... " -#podman pull ghcr.io/selfhostedpro/yacht:latest &>/dev/null -#echo -e "${CM}${CL} \r" +echo -en "${GN} Pulling Yacht Image... " +podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null +echo -e "${CM}${CL} \r" echo -en "${GN} Installing Yacht... " podman volume create yacht >/dev/null -podman run -v /var/run/podman/podman.sock:/var/run/docker.sock -v yacht:/config -p 8000:8000 --name -d ghcr.io/selfhostedpro/yacht:latest &>/dev/null -#podman run -d \ -# --name yacht \ -# --restart always \ -# -v /var/run/podman/podman.sock:/var/run/docker.sock \ -# -v yacht:/config \ -# -p 8000:8000 \ -# selfhostedpro/yacht:latest &>/dev/null +podman run \ + --name yacht \ + --restart always \ + -v /var/run/podman/podman.sock:/var/run/docker.sock \ + -v yacht:/config \ + -p 8000:8000 \ + selfhostedpro/yacht:latest &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Pulling Home Assistant Image... " From 7aa9f19086295ef8bc77b5844da91d8dfc26ad22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 18:35:42 -0400 Subject: [PATCH 1917/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index d4475d50..2cb3188e 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -66,20 +66,20 @@ echo -en "${GN} Installing Podman... " apt-get -y install podman &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Pulling Yacht Image... " -podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null -echo -e "${CM}${CL} \r" +#echo -en "${GN} Pulling Yacht Image... " +#podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null +#echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Yacht... " -podman volume create yacht >/dev/null -podman run \ - --name yacht \ - --restart always \ - -v /var/run/podman/podman.sock:/var/run/docker.sock \ - -v yacht:/config \ - -p 8000:8000 \ - selfhostedpro/yacht:latest &>/dev/null -echo -e "${CM}${CL} \r" +#echo -en "${GN} Installing Yacht... " +#podman volume create yacht >/dev/null +#podman run \ +# --name yacht \ +# --restart always \ +# -v /var/run/podman/podman.sock:/var/run/docker.sock \ +# -v yacht:/config \ +# -p 8000:8000 \ +# selfhostedpro/yacht:latest &>/dev/null +#echo -e "${CM}${CL} \r" echo -en "${GN} Pulling Home Assistant Image... " podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null From 5ae370707fdfc6ee2c63efdbcdd328463c5736c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 18:53:58 -0400 Subject: [PATCH 1918/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 2cb3188e..e3a2b697 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -81,22 +81,22 @@ echo -e "${CM}${CL} \r" # selfhostedpro/yacht:latest &>/dev/null #echo -e "${CM}${CL} \r" -echo -en "${GN} Pulling Home Assistant Image... " -podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" +#echo -en "${GN} Pulling Home Assistant Image... " +#podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null +#echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Home Assistant... " -podman volume create hass_config >/dev/null -podman run -d \ - --name homeassistant \ - --restart unless-stopped \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" +#echo -en "${GN} Installing Home Assistant... " +#podman volume create hass_config >/dev/null +#podman run -d \ +# --name homeassistant \ +# --restart unless-stopped \ +# -v /dev:/dev \ +# -v hass_config:/config \ +# -v /etc/localtime:/etc/localtime:ro \ +# -v /etc/timezone:/etc/timezone:ro \ +# --net=host \ +# homeassistant/home-assistant:stable &>/dev/null +#echo -e "${CM}${CL} \r" echo -en "${GN} Creating Update Script... " file_path="/root/update.sh" @@ -137,16 +137,16 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -podman generate systemd \ - --new --name homeassistant \ - > /etc/systemd/system/homeassistant.service -systemctl enable homeassistant &>/dev/null +#podman generate systemd \ +# --new --name homeassistant \ +# > /etc/systemd/system/homeassistant.service +#systemctl enable homeassistant &>/dev/null -podman generate systemd \ - --new --name yacht \ - > /etc/systemd/system/yacht.service -systemctl enable yacht &>/dev/null -echo -e "${CM}${CL} \r" +#podman generate systemd \ +# --new --name yacht \ +# > /etc/systemd/system/yacht.service +#systemctl enable yacht &>/dev/null +#echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 6f6812d48178dac53810bf4d3787955bb7087610 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 19:06:48 -0400 Subject: [PATCH 1919/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 43 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index e3a2b697..01d77886 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -64,22 +64,29 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Podman... " apt-get -y install podman &>/dev/null +REG=/etc/containers/registries.conf +cat << EOF > $REG +[registries.insecure] +registries = [ ] +[registries.block] +registries = [ ] +EOF echo -e "${CM}${CL} \r" -#echo -en "${GN} Pulling Yacht Image... " -#podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null -#echo -e "${CM}${CL} \r" +echo -en "${GN} Pulling Yacht Image... " +podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null +echo -e "${CM}${CL} \r" -#echo -en "${GN} Installing Yacht... " -#podman volume create yacht >/dev/null -#podman run \ -# --name yacht \ -# --restart always \ -# -v /var/run/podman/podman.sock:/var/run/docker.sock \ -# -v yacht:/config \ -# -p 8000:8000 \ -# selfhostedpro/yacht:latest &>/dev/null -#echo -e "${CM}${CL} \r" +echo -en "${GN} Installing Yacht... " +podman volume create yacht >/dev/null +podman run -d \ + --name yacht \ + --restart always \ + -v /var/run/podman/podman.sock:/var/run/docker.sock \ + -v yacht:/config \ + -p 8000:8000 \ + selfhostedpro/yacht:latest &>/dev/null +echo -e "${CM}${CL} \r" #echo -en "${GN} Pulling Home Assistant Image... " #podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null @@ -142,11 +149,11 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') # > /etc/systemd/system/homeassistant.service #systemctl enable homeassistant &>/dev/null -#podman generate systemd \ -# --new --name yacht \ -# > /etc/systemd/system/yacht.service -#systemctl enable yacht &>/dev/null -#echo -e "${CM}${CL} \r" +podman generate systemd \ + --new --name yacht \ + > /etc/systemd/system/yacht.service +systemctl enable yacht &>/dev/null +echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From 46726780693a2bf22c303c8ebe0f87190ca23a3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 19:15:06 -0400 Subject: [PATCH 1920/6505] Update README.md --- README.md | 82 +------------------------------------------------------ 1 file changed, 1 insertion(+), 81 deletions(-) diff --git a/README.md b/README.md index c12fe9a6..d9733ef8 100644 --- a/README.md +++ b/README.md @@ -125,86 +125,6 @@ ________________________________________________________________________________
    - -
    - Home Assistant Container LXC (Podman) - -

    -@home-assistant

    - -

    Podman Home Assistant Container LXC

    -To create a new Proxmox Podman Home Assistant Container, run the following in the Proxmox Shell. - - ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman_ha_container.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    - -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - -**Home Assistant Interface - IP:8123** - -**Yacht Interface - IP:8000** - -⚙️ **Path to HA /config** -```yaml -/var/lib/containers/storage/volumes/hass_config/_data - ``` -⚙️ **To edit the HA configuration.yaml** - -Run in the LXC console -```yaml -nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -⚙️ **Copy Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data-podman.sh)" - ``` - -⚙️ **To allow USB device passthrough:** - -Run in the Proxmox Shell. (**replace `106` with your LXC ID**) -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 -``` - -Reboot the LXC to apply the changes - -⚙️ **To Install HACS:** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/podman_hacs.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. - -⚙️ **To Update Home Assistant:** - -Run in the LXC console -```yaml -./update.sh -``` -⚙️ **Initial Yacht Login** - -**username** - ```yaml - admin@yacht.local - ``` - **password** - ```yaml - pass - ``` - -____________________________________________________________________________________________ -
    - -
    Home Assistant Container LXC @@ -822,7 +742,7 @@ ________________________________________________________________________________
    - 🔸Docker LXC + Docker LXC

    From f2aaf067fc58d585763ffd6258a8d5066b2be1c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 19:18:51 -0400 Subject: [PATCH 1921/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7b7b49fa..1703dc6e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-03 + +### Changed + +- **Home Assistant Container LXC (Podman)** + - Removed due to breaking changes + + ## 2022-04-01 ### Changed From e1915dff846ddd4c98cec451e25e59b0b909d5fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 20:04:16 -0400 Subject: [PATCH 1922/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 49 +++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index 01d77886..d0d49360 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -64,13 +64,6 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Podman... " apt-get -y install podman &>/dev/null -REG=/etc/containers/registries.conf -cat << EOF > $REG -[registries.insecure] -registries = [ ] -[registries.block] -registries = [ ] -EOF echo -e "${CM}${CL} \r" echo -en "${GN} Pulling Yacht Image... " @@ -80,30 +73,34 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Yacht... " podman volume create yacht >/dev/null podman run -d \ + --privileged --name yacht \ --restart always \ -v /var/run/podman/podman.sock:/var/run/docker.sock \ -v yacht:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ -p 8000:8000 \ selfhostedpro/yacht:latest &>/dev/null echo -e "${CM}${CL} \r" -#echo -en "${GN} Pulling Home Assistant Image... " -#podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null -#echo -e "${CM}${CL} \r" +echo -en "${GN} Pulling Home Assistant Image... " +podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" -#echo -en "${GN} Installing Home Assistant... " -#podman volume create hass_config >/dev/null -#podman run -d \ -# --name homeassistant \ -# --restart unless-stopped \ -# -v /dev:/dev \ -# -v hass_config:/config \ -# -v /etc/localtime:/etc/localtime:ro \ -# -v /etc/timezone:/etc/timezone:ro \ -# --net=host \ -# homeassistant/home-assistant:stable &>/dev/null -#echo -e "${CM}${CL} \r" +echo -en "${GN} Installing Home Assistant... " +podman volume create hass_config >/dev/null +podman run -d \ + --privileged + --name homeassistant \ + --restart unless-stopped \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null +echo -e "${CM}${CL} \r" echo -en "${GN} Creating Update Script... " file_path="/root/update.sh" @@ -144,10 +141,10 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -#podman generate systemd \ -# --new --name homeassistant \ -# > /etc/systemd/system/homeassistant.service -#systemctl enable homeassistant &>/dev/null +podman generate systemd \ + --new --name homeassistant \ + > /etc/systemd/system/homeassistant.service +systemctl enable homeassistant &>/dev/null podman generate systemd \ --new --name yacht \ From 277e8354a4ef48cbf6bb2d93d2a2ef1fefa1cad6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 20:10:18 -0400 Subject: [PATCH 1923/6505] Update podman_ha_setup.sh --- setup/podman_ha_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh index d0d49360..8cc8d414 100644 --- a/setup/podman_ha_setup.sh +++ b/setup/podman_ha_setup.sh @@ -73,7 +73,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Yacht... " podman volume create yacht >/dev/null podman run -d \ - --privileged + --privileged \ --name yacht \ --restart always \ -v /var/run/podman/podman.sock:/var/run/docker.sock \ @@ -91,7 +91,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Installing Home Assistant... " podman volume create hass_config >/dev/null podman run -d \ - --privileged + --privileged \ --name homeassistant \ --restart unless-stopped \ -v /dev:/dev \ From bc63384c13bff0babe6520fbca18d5675a8887bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 20:19:51 -0400 Subject: [PATCH 1924/6505] Update README.md --- README.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/README.md b/README.md index d9733ef8..2bbe6bd5 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,83 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/latest-upd ____________________________________________________________________________________________
    +
    + Home Assistant Container LXC (Podman) + +

    +@home-assistant

    + +

    Podman Home Assistant Container LXC

    +To create a new Proxmox Podman Home Assistant Container, run the following in the Proxmox Shell. + + ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman_ha_container.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +**Home Assistant Interface - IP:8123** + +**Yacht Interface - IP:8000** + +⚙️ **Path to HA /config** +```yaml +/var/lib/containers/storage/volumes/hass_config/_data + ``` +⚙️ **To edit the HA configuration.yaml** + +Run in the LXC console +```yaml +nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + +⚙️ **Copy Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** + +Run in the Proxmox Shell +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data-podman.sh)" + ``` + +⚙️ **To allow USB device passthrough:** + +Run in the Proxmox Shell. (**replace `106` with your LXC ID**) +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 +``` + +Reboot the LXC to apply the changes + +⚙️ **To Install HACS:** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/podman_hacs.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + +⚙️ **To Update Home Assistant:** + +Run in the LXC console +```yaml +./update.sh +``` +⚙️ **Initial Yacht Login** + +**username** + ```yaml + admin@yacht.local + ``` + **password** + ```yaml + pass + ``` + +____________________________________________________________________________________________ +
    Homebridge LXC From 6c06bd3efaab6c4849cd47394d2d8fb7488bf3ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Apr 2022 20:20:26 -0400 Subject: [PATCH 1925/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1703dc6e..7b7b49fa 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,14 +5,6 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) -## 2022-04-03 - -### Changed - -- **Home Assistant Container LXC (Podman)** - - Removed due to breaking changes - - ## 2022-04-01 ### Changed From db498cd807c4afbf3ee4501a178f62e5a5d79a1e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 08:33:05 -0400 Subject: [PATCH 1926/6505] Create meshcentral.sh --- ct/meshcentral.sh | 259 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 ct/meshcentral.sh diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh new file mode 100644 index 00000000..3d4dda5f --- /dev/null +++ b/ct/meshcentral.sh @@ -0,0 +1,259 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Mesh Central" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + __ __ _ _____ _ _ + | \/ | | | / ____| | | | | + | \ / | ___ ___| |__ | | ___ _ __ | |_ _ __ __ _| | + | |\/| |/ _ \/ __| _ \ | | / _ \ _ \| __| __/ _ | | + | | | | __/\__ \ | | | | |___| __/ | | | |_| | | (_| | | + |_| |_|\___||___/_| |_| \_____\___|_| |_|\__|_| \__,_|_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From d353163f7f5ebd2f59934a33c3d17a3d8673d19e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 08:34:43 -0400 Subject: [PATCH 1927/6505] Create meshcentral-install.sh --- setup/meshcentral-install.sh | 99 ++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 setup/meshcentral-install.sh diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh new file mode 100644 index 00000000..8b6b542a --- /dev/null +++ b/setup/meshcentral-install.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +apt-get install -y nodejs &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Mesh Central... " +mkdir /opt/meshcentral +cd /opt/meshcentral +npm install meshcentral &>/dev/null +node node_modules/meshcentral --install &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 2b4ebdb70bdb36c448adcc45bee2de3d65b68a4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 09:06:36 -0400 Subject: [PATCH 1928/6505] Update README.md --- README.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2bbe6bd5..fbe7656c 100644 --- a/README.md +++ b/README.md @@ -962,7 +962,6 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada.sh)" ⚙️ **To Update Omada** -Run in the LXC console ```yaml Working On ``` @@ -970,6 +969,34 @@ ________________________________________________________________________________
    +
    + 🔸MeshCentral LXC + +

    + +

    MeshCentral LXC

    + +MeshCentral is a full computer management web site. With MeshCentral, you can run your own web server to remotely manage and control computers on a local network or anywhere on the internet. + +To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**MeshCentral Interface - http:// IP** + +⚙️ **To Update MeshCentral** + +```yaml +Update from the MeshCentral UI +``` +____________________________________________________________________________________________ + +
    +
    Plex Media Server LXC @@ -1332,6 +1359,8 @@ Benefits include automatic daily security updates, backup and restore, file mana Update from the Webmin UI ``` ⚙️ **To Uninstall Webmin** + +Run in the LXC console ```yaml bash /etc/webmin/uninstall.sh ``` From a3f590351469eb28b70d6504ce37a2142297de92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 09:08:16 -0400 Subject: [PATCH 1929/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7b7b49fa..6eca53f9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-05 + +### Changed + +- **MeshCentral LXC** + - New Script V2 + ## 2022-04-01 ### Changed From a11311709c65fc20ad9908592de44798d99af939 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 09:09:23 -0400 Subject: [PATCH 1930/6505] Update meshcentral.sh --- ct/meshcentral.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 3d4dda5f..27fa4c98 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -5,7 +5,7 @@ RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -APP="Mesh Central" +APP="MeshCentral" HN=$(echo ${APP,,} | tr -d ' ') while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn From dd358b26147a9341d81cb0b9306cce60e92e8511 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 09:19:45 -0400 Subject: [PATCH 1931/6505] Update meshcentral.sh --- ct/meshcentral.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 27fa4c98..f8df0b17 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -17,14 +17,13 @@ while true; do done clear function header_info { -echo -e "${RD} - - __ __ _ _____ _ _ - | \/ | | | / ____| | | | | - | \ / | ___ ___| |__ | | ___ _ __ | |_ _ __ __ _| | - | |\/| |/ _ \/ __| _ \ | | / _ \ _ \| __| __/ _ | | - | | | | __/\__ \ | | | | |___| __/ | | | |_| | | (_| | | - |_| |_|\___||___/_| |_| \_____\___|_| |_|\__|_| \__,_|_| +echo -e "${BL} + __ __ _ _____ _ _ + | \/ | | | / ____| | | | | + | \ / | ___ ___| |__ | | ___ _ __ | |_ _ __ __ _| | + | |\/| |/ _ \/ __| _ \| | / _ \ _ \| __| __/ _ | | + | | | | __/\__ \ | | | |___| __/ | | | |_| | | (_| | | + |_| |_|\___||___/_| |_|\_____\___|_| |_|\__|_| \__,_|_| ${CL}" } From 60054c0f3120447a47a9392e28b2bb1d58c8e5a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 09:20:20 -0400 Subject: [PATCH 1932/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 8b6b542a..c9103f34 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -67,7 +67,7 @@ echo -en "${GN} Installing Node.js... " apt-get install -y nodejs &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing Mesh Central... " +echo -en "${GN} Installing MeshCentral... " mkdir /opt/meshcentral cd /opt/meshcentral npm install meshcentral &>/dev/null From 8ebbbcdc4a05645fed79fc7a083b2133e59aae52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Apr 2022 09:25:04 -0400 Subject: [PATCH 1933/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fbe7656c..7159feed 100644 --- a/README.md +++ b/README.md @@ -972,7 +972,7 @@ ________________________________________________________________________________
    🔸MeshCentral LXC -

    +

    MeshCentral LXC

    From 90f564477d042bd790dacef50d64748527c609d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Apr 2022 06:03:48 -0400 Subject: [PATCH 1934/6505] Update unifi-install.sh --- setup/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 0f4bc5b1..f469df2d 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +#https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 set -o errexit set -o errtrace set -o nounset From f6d66f3491200843424db000ba3add67b6ca8242 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 00:47:49 -0400 Subject: [PATCH 1935/6505] Create debian-v3.sh --- ct/debian-v3.sh | 337 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 ct/debian-v3.sh diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh new file mode 100644 index 00000000..f66439e0 --- /dev/null +++ b/ct/debian-v3.sh @@ -0,0 +1,337 @@ +#!/usr/bin/env bash +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Debian" + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _ _ + | __ \ | | (_) + | | | | ___| |__ _ __ _ _ __ + | | | |/ _ \ _ \| |/ _ | _ \ + | |__| | __/ |_) | | (_| | | | | + |_v3__/ \___|_.__/|_|\__,_|_| |_| +${CL}" +} + +header_info +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${GN}Using CT Type Unprivileged${CL}" + CT_TYPE="1" + echo -e "${GN}Using CT Password Automatic Login${CL}" + PW=" " + echo -e "${GN}Using ID $NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${GN}Using CT Name $APP${CL}" + HN=$(echo ${APP,,} | tr -d ' ') + echo -e "${GN}Using Disk Size 2GB${CL}" + SIZEDISK="2" + echo -e "${GN}Using Storage local-lvm${CL}" + STORAGETYPE="local-lvm" + echo -e "${GN}Using 1vCPU${CL}" + CORE_COUNT="1" + echo -e "${GN}Using 512MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${GN}Using IP Address DHCP${CL}" + NET=dhcp + echo -e "${GN}Using VLAN Tag NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Enter the CT Type (Privileged/Unprivileged), or Press [ENTER] for Default: Unprivileged " + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE="0" + echo -en "${GN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${GN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${GN}Set CT Password ${BL}$PW1${CL}" + + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${YW}Enter CT Name, or Press [ENTER] for Default: $APP " + read CT_NAME + if [ -z $CT_NAME ]; then HN=$(echo ${APP,,} | tr -d ' '); + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi; + echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read SIZEDISK + if [ -z $SIZEDISK ]; then SIZEDISK="8"; fi; + if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${GN}Using Disk Size $SIZEDISK${CL}" + echo -e "${YW}Storages Available:${CL}" + echo " " + for stg in `pvesh get storage --noborder --noheader` + do + echo -e "${BL} - ${stg}${CL}" + done + echo " " + echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " + read STORAGETYPE + if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; + echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${GN}Using Disk Size $SIZEDISK${CL}" + echo -e "${GN}Using Storage $STORAGETYPE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 4 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="4"; fi; + echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${GN}Using Disk Size $SIZEDISK${CL}" + echo -e "${GN}Using Storage $STORAGETYPE${CL}" + echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${GN}Using Disk Size $SIZEDISK${CL}" + echo -e "${GN}Using Storage $STORAGETYPE${CL}" + echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${RAM_SIZE}MiB RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${GN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${GN}Using Disk Size $SIZEDISK${CL}" + echo -e "${GN}Using Storage $STORAGETYPE${CL}" + echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using IP Address $NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${GN}Using Disk Size $SIZEDISK${CL}" + echo -e "${GN}Using Storage $STORAGETYPE${CL}" + echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using IP Address $NET${CL}" + echo -e "${GN}Using VLAN Tag $VLAN1${CL}" + +} +function start_script() { + echo -e "${YW}Type Advanced Settings, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$SIZEDISK +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" From 0330ae6a3ec43c5a3af2e1ff21b4aaf32dc285de Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 09:39:25 -0400 Subject: [PATCH 1936/6505] Update debian-v3.sh --- ct/debian-v3.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index f66439e0..76280f09 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -30,6 +30,15 @@ ${CL}" } header_info +function pve_7() { +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" + echo -e "Exiting..." + sleep 2 + exit +fi +} + function default_settings() { clear header_info From 03e780a2f42a70d92e51af99960db4b8ac4c46cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 10:03:35 -0400 Subject: [PATCH 1937/6505] Update usb-passthrough.sh --- misc/usb-passthrough.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index 96a45ec3..00e55f5f 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -echo -e "\e[1;33m This script will allow USB passthrough to a LXC Container \e[0m" +echo -e "\e[1;33m This script will allow USB passthrough to a privileged LXC Container \e[0m" while true; do read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn case $yn in From b89d4c9434fcb80555721280dbfb96748ae154b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 10:06:20 -0400 Subject: [PATCH 1938/6505] Update usb-passthrough.sh --- misc/usb-passthrough.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index 00e55f5f..8b75c792 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -echo -e "\e[1;33m This script will allow USB passthrough to a privileged LXC Container \e[0m" +echo -e "\e[1;33m This script will allow USB passthrough to a PRIVILEGED LXC Container ONLY\e[0m" while true; do read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn case $yn in From 71b23fae9ee10747250d4dbdebb0806e2cce00ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 15:58:15 -0400 Subject: [PATCH 1939/6505] Update debian-v3.sh --- ct/debian-v3.sh | 133 ++++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 76280f09..3328c91c 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -5,7 +5,8 @@ YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Debian" @@ -25,7 +26,7 @@ echo -e "${RD} | | | | ___| |__ _ __ _ _ __ | | | |/ _ \ _ \| |/ _ | _ \ | |__| | __/ |_) | | (_| | | | | - |_v3__/ \___|_.__/|_|\__,_|_| |_| + |_${YW}v3${RD}__/ \___|_.__/|_|\__,_|_| |_| ${CL}" } @@ -45,23 +46,23 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${GN}Using CT Type Unprivileged${CL}" CT_TYPE="1" - echo -e "${GN}Using CT Password Automatic Login${CL}" + echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${GN}Using ID $NEXTID${CL}" + echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID - echo -e "${GN}Using CT Name $APP${CL}" + echo -e "${GN}Using CT Name ${BGN}$APP${CL}" HN=$(echo ${APP,,} | tr -d ' ') - echo -e "${GN}Using Disk Size 2GB${CL}" + echo -e "${GN}Using Disk Size ${BGN}2GB${CL}" SIZEDISK="2" - echo -e "${GN}Using Storage local-lvm${CL}" + echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" STORAGETYPE="local-lvm" - echo -e "${GN}Using 1vCPU${CL}" + echo -e "${GN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" - echo -e "${GN}Using 512MiB RAM${CL}" + echo -e "${GN}Using ${BGN}512MiB RAM${CL}" RAM_SIZE="512" - echo -e "${GN}Using IP Address DHCP${CL}" + echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${GN}Using VLAN Tag NONE${CL}" + echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" VLAN=" " } @@ -82,7 +83,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " read PW1 if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -97,8 +98,8 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " read CT_ID if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; @@ -108,9 +109,9 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name, or Press [ENTER] for Default: $APP " read CT_NAME if [ -z $CT_NAME ]; then HN=$(echo ${APP,,} | tr -d ' '); @@ -123,10 +124,10 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" - echo -e "${GN}Using CT Name $CT_NAME${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " read SIZEDISK if [ -z $SIZEDISK ]; then SIZEDISK="8"; fi; @@ -137,11 +138,11 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" - echo -e "${GN}Using CT Name $CT_NAME${CL}" - echo -e "${GN}Using Disk Size $SIZEDISK${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${YW}Storages Available:${CL}" echo " " for stg in `pvesh get storage --noborder --noheader` @@ -158,12 +159,12 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" - echo -e "${GN}Using CT Name $CT_NAME${CL}" - echo -e "${GN}Using Disk Size $SIZEDISK${CL}" - echo -e "${GN}Using Storage $STORAGETYPE${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 4 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="4"; fi; @@ -173,13 +174,13 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" - echo -e "${GN}Using CT Name $CT_NAME${CL}" - echo -e "${GN}Using Disk Size $SIZEDISK${CL}" - echo -e "${GN}Using Storage $STORAGETYPE${CL}" - echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; @@ -189,14 +190,14 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" - echo -e "${GN}Using CT Name $CT_NAME${CL}" - echo -e "${GN}Using Disk Size $SIZEDISK${CL}" - echo -e "${GN}Using Storage $STORAGETYPE${CL}" - echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -206,15 +207,15 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" - echo -e "${GN}Using CT Name $CT_NAME${CL}" - echo -e "${GN}Using Disk Size $SIZEDISK${CL}" - echo -e "${GN}Using Storage $STORAGETYPE${CL}" - echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${RAM_SIZE}MiB RAM${CL}" - echo -e "${GN}Using IP Address $NET${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -228,16 +229,16 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type $CT_TYPE1${CL}" - echo -e "${GN}Using CT Password $PW1${CL}" - echo -e "${GN}Using ID $CT_ID${CL}" - echo -e "${GN}Using CT Name $CT_NAME${CL}" - echo -e "${GN}Using Disk Size $SIZEDISK${CL}" - echo -e "${GN}Using Storage $STORAGETYPE${CL}" - echo -e "${GN}Using ${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${RAM_SIZE}MiB RAM${CL}" - echo -e "${GN}Using IP Address $NET${CL}" - echo -e "${GN}Using VLAN Tag $VLAN1${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" } function start_script() { From 73078305e5023456c79888cd071b7a738089c6e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 16:03:33 -0400 Subject: [PATCH 1940/6505] Update debian.sh --- ct/debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index fc7f98d4..36ed693b 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -3,7 +3,7 @@ YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` +GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Debian" HN=$(echo ${APP,,} | tr -d ' ') From df673499059d16207febe07162886605ba3db34d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 16:04:13 -0400 Subject: [PATCH 1941/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 3e7149c7..622a77b4 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -26,7 +26,7 @@ CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` +GN=`echo "\033[32m"` CL=`echo "\033[m"` RETRY_NUM=10 RETRY_EVERY=3 From d943203b9176a64a63b0d4c34e965441fd652131 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 16:10:09 -0400 Subject: [PATCH 1942/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 3328c91c..9810e32a 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -44,7 +44,7 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type Unprivileged${CL}" + echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL}" CT_TYPE="1" echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " From 86b85a660953be3fe1ae86cc7b7efaa44748a4ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 16:23:53 -0400 Subject: [PATCH 1943/6505] Update debian-v3.sh --- ct/debian-v3.sh | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 9810e32a..8af37efb 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -31,6 +31,7 @@ ${CL}" } header_info + function pve_7() { if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" @@ -41,11 +42,11 @@ fi } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL}" - CT_TYPE="1" + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL}" + CT_TYPE="1" echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" @@ -63,7 +64,7 @@ function default_settings() { echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN=" " } function advanced_settings() { @@ -75,7 +76,8 @@ function advanced_settings() { if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE="0" + CT_TYPE1="Privileged" + CT_TYPE="0" echo -en "${GN}Set CT Type ${BL}Privileged${CL}" fi; echo -e " ${CM}${CL} \r" @@ -270,20 +272,24 @@ function error_exit() { [ ! -z ${CTID-} ] && cleanup_ctid exit $EXIT } + function warn() { local REASON="\e[97m$1\e[39m" local FLAG="\e[93m[WARNING]\e[39m" msg "$FLAG $REASON" } + function info() { local REASON="$1" local FLAG="\e[36m[INFO]\e[39m" msg "$FLAG $REASON" } + function msg() { local TEXT="$1" echo -e "$TEXT" } + function cleanup_ctid() { if $(pct status $CTID &>/dev/null); then if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then @@ -294,11 +300,13 @@ function cleanup_ctid() { pvesm free $ROOTFS fi } + function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } - if [ "$CT_TYPE" == "1" ]; then + +if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" From 618bcd419ca79c46f873a0a747a27458fe3128e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 16:31:56 -0400 Subject: [PATCH 1944/6505] Update debian-v3.sh --- ct/debian-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 8af37efb..dc6a027d 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -59,7 +59,7 @@ function default_settings() { STORAGETYPE="local-lvm" echo -e "${GN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" - echo -e "${GN}Using ${BGN}512MiB RAM${CL}" + echo -e "${GN}Using ${BGN}512MiB${GN} RAM${CL}" RAM_SIZE="512" echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp @@ -199,7 +199,7 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${GN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -216,7 +216,7 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -238,7 +238,7 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB RAM${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 4a9eddfdc21e6694327bcdf53e6b443ae5f1148a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 18:12:27 -0400 Subject: [PATCH 1945/6505] Update debian-v3.sh --- ct/debian-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index dc6a027d..6dda4cb7 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -59,7 +59,7 @@ function default_settings() { STORAGETYPE="local-lvm" echo -e "${GN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" - echo -e "${GN}Using ${BGN}512MiB${GN} RAM${CL}" + echo -e "${GN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" RAM_SIZE="512" echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp @@ -199,7 +199,7 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${GN} RAM${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -216,7 +216,7 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${GN} RAM${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -238,7 +238,7 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${GN} RAM${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 7424ca837be90a31b8a07bf413d64790fdbe9475 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 18:25:45 -0400 Subject: [PATCH 1946/6505] Update debian-v3.sh --- ct/debian-v3.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 6dda4cb7..a6b120d2 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -71,7 +71,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Enter the CT Type (Privileged/Unprivileged), or Press [ENTER] for Default: Unprivileged " + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged " read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" @@ -130,9 +130,9 @@ header_info echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " read SIZEDISK - if [ -z $SIZEDISK ]; then SIZEDISK="8"; fi; + if [ -z $SIZEDISK ]; then SIZEDISK="2"; fi; if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" echo -e " ${CM}${CL} \r" @@ -167,9 +167,9 @@ header_info echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 4 " + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="4"; fi; + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" echo -e " ${CM}${CL} \r" sleep 1 @@ -183,9 +183,9 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" echo -e " ${CM}${CL} \n" sleep 1 From 9efa1817ea4aed47262c8e7da32154e05433a1d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Apr 2022 19:34:55 -0400 Subject: [PATCH 1947/6505] Update debian-v3.sh --- ct/debian-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index a6b120d2..b3f22a2d 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -116,7 +116,8 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name, or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then HN=$(echo ${APP,,} | tr -d ' '); + if [ -z $CT_NAME ]; then HN=$(echo ${APP,,} | tr -d ' ') + CT_NAME=$APP else HN=$(echo ${CT_NAME,,} | tr -d ' ') fi; From eb5cb60fa0e120ed402fad92a95f1c42c38da36e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 09:50:50 -0400 Subject: [PATCH 1948/6505] Update debian-v3.sh --- ct/debian-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index b3f22a2d..07a941c2 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -46,6 +46,7 @@ function default_settings() { header_info echo -e "${BL}Using Default Settings${CL}" echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL}" + echo -e "${RD} NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " @@ -71,7 +72,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged " + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" From 65774d3d6cb5ca0b364c7eb4102feed9ff497d78 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 10:09:14 -0400 Subject: [PATCH 1949/6505] Update debian-v3.sh --- ct/debian-v3.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 07a941c2..48f50c38 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -45,8 +45,7 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL}" - echo -e "${RD} NO DEVICE PASSTHROUGH${CL}" + echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " From 498c1fc42075d4fddd4283eefaa3191f278b1e2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 13:28:08 -0400 Subject: [PATCH 1950/6505] Create nocodb.sh --- ct/nocodb.sh | 256 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 ct/nocodb.sh diff --git a/ct/nocodb.sh b/ct/nocodb.sh new file mode 100644 index 00000000..2073e688 --- /dev/null +++ b/ct/nocodb.sh @@ -0,0 +1,256 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="NocoDB" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _ _____ ____ + | \ | | | __ \| _ \ + | \| | ___ ___ ___ | | | | |_) | + | |/ _ \ / __/ _ \| | | | _ < + | |\ | (_) | (_| (_) | |__| | |_) | + |_| \_|\___/ \___\___/|_____/|____/ +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" From 06046a9b0cc1f057c21ac1a86e04dcfb72468aef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 13:29:00 -0400 Subject: [PATCH 1951/6505] Create nocodb-install.sh --- setup/nocodb-install.sh | 116 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 setup/nocodb-install.sh diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh new file mode 100644 index 00000000..7cda013c --- /dev/null +++ b/setup/nocodb-install.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs git make g++ gcc &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing NocoDB... " +git clone https://github.com/nocodb/nocodb-seed &>/dev/null +mv nocodb-seed /opt/nocodb +cd /opt/nocodb +npm install &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Service file nocodb.service... " +service_path="/etc/systemd/system/nocodb.service" +echo "[Unit] +Description=nocodb + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/nocodb +ExecStart=/usr/bin/npm start + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now nocodb.service + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From 176c8504dc936659c782440d43c676f1c53bb76a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 13:31:52 -0400 Subject: [PATCH 1952/6505] Update nocodb.sh --- ct/nocodb.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 2073e688..1e1d38f5 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -253,4 +253,6 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8080/dashboard${CL}\n" From 308231fb9baeeca1e28694744f5efc20b227c620 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 13:44:09 -0400 Subject: [PATCH 1953/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 7cda013c..30527ddd 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -88,8 +88,9 @@ WorkingDirectory=/opt/nocodb ExecStart=/usr/bin/npm start [Install] -WantedBy=multi-user.target" > $service_path -systemctl enable --now nocodb.service +WantedBy=multi-user.target" > $service_path &>/dev/null +systemctl enable --now nocodb.service &>/dev/null +echo -e "${CM}${CL} \r" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From 876ee75aab0a3a47481c611fba02b773324c4b1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 13:47:38 -0400 Subject: [PATCH 1954/6505] Update nocodb.sh --- ct/nocodb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 1e1d38f5..4eafd1cf 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -207,14 +207,14 @@ pushd $TEMP_DIR >/dev/null export CTID=$(pvesh get /cluster/nextid) export PCT_OSTYPE=debian export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 +export PCT_DISK_SIZE=4 export PCT_OPTIONS=" -features $FEATURES -hostname $HN -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 - -memory 512 + -memory 1024 -unprivileged ${IM} ${PW} " From 8c5f4dfa6b085fdb73963255f517b25ac9c03dea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 13:56:51 -0400 Subject: [PATCH 1955/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 30527ddd..9d51169a 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -88,7 +88,7 @@ WorkingDirectory=/opt/nocodb ExecStart=/usr/bin/npm start [Install] -WantedBy=multi-user.target" > $service_path &>/dev/null +WantedBy=multi-user.target" > $service_path systemctl enable --now nocodb.service &>/dev/null echo -e "${CM}${CL} \r" From cc362b42262bb363b9aed5db8f52de13a9401484 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 14:20:35 -0400 Subject: [PATCH 1956/6505] Add files via upload --- misc/images/nocodb.png | Bin 0 -> 84837 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/nocodb.png diff --git a/misc/images/nocodb.png b/misc/images/nocodb.png new file mode 100644 index 0000000000000000000000000000000000000000..269f74acad4b99ee7332cd0bdabc99c01858fa77 GIT binary patch literal 84837 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'NiBsWM?m>Fr0G)=WYXtwI`u1_xVftw;` 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 literal 0 HcmV?d00001 From 2aa932c762bf8f0ba539b01f5453f4eaa2ff39d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 14:27:13 -0400 Subject: [PATCH 1957/6505] Update README.md --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 7159feed..b1539ecc 100644 --- a/README.md +++ b/README.md @@ -735,6 +735,38 @@ ________________________________________________________________________________
    +
    + 🔸NocoDB LXC + +

    + +

    NocoDB LXC

    + +Turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart-spreadsheet. + +To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell (V2). + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +**NocoDB Interface - IP:8080/dashboard** + +⚙️ **To Update** + + +```yaml +Working on +``` + +____________________________________________________________________________________________ + +
    +
    InfluxDB/Telegraf LXC From 6631759c98bafa484ba46c2f83c91cc7a824d8a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 14:28:18 -0400 Subject: [PATCH 1958/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6eca53f9..b25ae87d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-09 + +### Changed + +- **NocoDB LXC** + - New Script V2 + ## 2022-04-05 ### Changed From cde5636946893097edbef2e00b0bb901ea41d845 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 15:29:19 -0400 Subject: [PATCH 1959/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1539ecc..6efee211 100644 --- a/README.md +++ b/README.md @@ -742,7 +742,7 @@ ________________________________________________________________________________

    NocoDB LXC

    -Turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart-spreadsheet. +NocoDB is an open source #NoCode platform that turns any database into a smart spreadsheet. Airtable Alternative. To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell (V2). From eaec6af76c3714b3bda3418257d7158704e7368f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 19:55:50 -0400 Subject: [PATCH 1960/6505] Add files via upload --- misc/images/discussions.png | Bin 0 -> 17536 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/discussions.png diff --git a/misc/images/discussions.png b/misc/images/discussions.png new file mode 100644 index 0000000000000000000000000000000000000000..ea6678899a14853d59e2621fc2fbf124666209f1 GIT binary patch literal 17536 zcmZs@Wl)=4*9IEg-JwWvcS><6#ob+kySuvyL&i!zcc6GnYr^P zGka&-B0S`qA+w5W0DuA@^HWUSEBm6` z+ll(cef#Cb+=8@>F*^?awa22Q^oW}83p(GwiT^08$5TT(le#(^2yJ~yJ?P!m=4`~* z4AzrKk!9lZ&7+g7Nx3J*zc>%+{X-pX|4W2^bb6U_V$1GNehlLYRmQlGn9=(|r6Nk1 zsH1T#38m5Z_VfKeoeZ7us;UXco+sa{Cu~?T%>VzV;6mlB8|EymeoKI&ivQB*DrhF4 zsS~h-!->UTkjoz94QIAw zFBRTwCMoV5umv{^wZ6D9<5X10r&h=3PCI>KBseVp_bv2?)>U&Il(i0&-wll28N2t- ze&3Wm2V;WV6?Z5h*=S!TW+_{J3IsErU$&EFMSL7bw|i&vUGHaff2SOYX}o|SI+Hdr zYX&I41FWQyesS7&<`{%vQsmblTx8qsCnYO!?wW{=E<$uI?#M>Go;v~p@0Utm`nMKT z9MO7Y-tR15gQSF|k)MfRgpmbd?-`WtDXY7FZc}J-N)&nm%n7M|UOB3~77ju1#q9j3 zYsE=fCEQ#xd;(TtP z)i|hfsaJdB?pwOu?yo4?%`vHRMHyhs)AQ5wYTlNymI&?Fx70hWM*6E$=oOUMc|GDb z7VmIJYW6h8#;Wtnt65@KXrzscSpVq!d=Ffb`v z90hbZb|x(BI8>Ptqrw!UDkIaF(1qnU!&lF)!7UH5;?w`qr}RDi9)3pPeBom3tDkRd zi*Cel{U+j?uBC(9mwz3N>A=3EE`cr*abWdo3g2706Q~vQFDZwE#U#VQ=hBaN6XCL7 z*1hK75{cwXskZU!hI5G`c`+wfxW_roS+j-3)UI5u#moL@K*p{q*GiaPc-%b!vVC7B z;?5m;pLCWPx1a@mfKh+QtKmp?P1O!FL35zUWDTkniU~JKD0n{buB;8*&C_#E z68gCR;zy9Xtzs6z?f5;9bKi!ubLF$9C?o}v3(`5;zOZBA@rhGnj}@|A4)#BE#? zF}@Hv34P2dv-11hxy36593s=@X665N!9v9u*y)-niVy&R3qi5z9er z>erT8$lI!h`u4ZI_*t~--%|#95LFv&$XYjh7+JwgcwsBkkAv#=2&Y*Wf_t_XgE3_uyE{t?u77Fi(kF-fuCN3pEDAQj^G3V%YL{}b>^J`N#s88*F$6Y*T(E@3^RmJIk&*Zfh40GLFr$uXr z^1mC;>@U0X6Nbblk8=#jRB1;=9($+AU#;TQSXDD}3cowY%{}wTa^b9m6E$7rR}qe} zpXU0Gu}7Qx)bn$GFXlTpA*<$zC}cBtIVw=JV8#C~qCYsyMG3kbeN77WJ?Z%{fLJ<|b4GXB&Y^g4V}-qa+|j$xb06A+wUgOW4)b(( z4e$J&yLc39jB8)rqS30F1BXF$Q4m86Slq!rZ(!Iuu8%H=b*_;0rHgAIPOGGi-E@B^ zS}(m1PC^;BZb%ys%I`six!9{WdN6bACM7dg}&tv&+_HXH8ErfQkQ=8tnS zE@_eJB%L986R}xL8~nQaDaa|7!wl1UVUks*!cjl&y^-!dVslXZr!}z7o7(nk6sJBu z5Vf>%+u6S^1V6a^XvJ)04yqN7DcBJfzd?|_scThFJYH8^276+jor{a#Z!RrD6m_em z#N`Vn9I9vfPU-g}*=gK0#gZ0c=$(|9LC)@l2Kd=r#LRNm>~@{2ji08BuWu&jm+amr zi&a|bzpV;zu5$YOlY&u*4JTAGa{5>&u;rc#QJG!^7m2C1f`3ma=Ms&u__}K=47IG!+X-h3a$q~ON6 zSW&;#8JpivALW*$G?>Tc-Xl#PMLjr2Tr1DVm7Fks>hzsSFgkF0FvY^MBXN)c82O|i z$Pdx|E=1{S&^XD7ly=xW)37g}J<`hV8otlas&`ep%b5zPL;s)XYPmV0MEIH&ox|QJ z7J_k{EMxPgRu_d7x!kMnzL~svWR`zk%bAh&wT*vL4zPd}PTOEcX2$M%U zFTUZ2)FE4S%G2aY5LwvEVM}MqDjdWve;=EJf)9wDHg9K-!E1}( zNCAL%V7^2Vz4I0y!_`*E`78@*p9nXdNpeTdEx6xmDaJe_vBY{Xu7q2sU=7Gy%+#O@ z<#m7cB9g@!puftf8bwdG?-ckB?naW-W^}95KOe+%fYM|RViS@T1YXnig~|d$D7QLe zjB`(Zoe7jcj6df097h=_gfA<75)il+t3%+<;c1_ zwOb|>`(V8c@pZfjGp$M2b$JifT;fM)%9ys|C=6;spCy#2Hs)r)zy{Dcd^r&hX(u+} zza~_$k>5czwjKuN*_U5rYZhq?@i|3;{su1ZVJ#qr=>m54q@15La!lrhzd=*pN=0fh z@rtoyiOf>8j418F{gTFvnmhdUg(iL_dr*Qma?tclVqKP6ZoPS?YPmgP<`%H}r3^-* zn3)kC^wavKoB|OZ=TUe1IA>q_qDlemco~<37=CuVp8EzyOYaMa-U@%a>LR%9poDLP zt9}jD0>~?9h3H-%fyHlBn=qCRski@VvI`eZaMo}x)MwU)QttbgBIrOfnL6wth7m*2swkxAWUf5mmx;-ZtH z3dtiNN!H=ZNKIJonQrLnY-~dpe_BalDc$ggh|piMRNcS_;wZef5^XfcvS;?XQlCIh zftH|#8LXOWwe0?>xZsp}>^0Jn5>BoVtSgYT8K{*5C%ru2{G<}#M)<|6F7oYj5BsQ` z#b=JAC!U)+Xxk?$CFH4)Xa-pnSkk&@gQge-=s;Htz_wJ>Hv*dO;9Az9sA)@5zVm(4 z1ycLWjG;X0!~|D6Uv||dPu%EOlsUd=IAa0zxrjMiefKxeH{vPL^Y<8{if7_U*0NQh zd>xQarZB&ut_@Aa?W!MwrhT97H^9ojF&EfG-Waq$UwP6N@(9|XZU}%9sHV9UmfsN0H2-)2G;8Dz!;njEld<&aO zSVhOl{w&&f@d1z53$4tz^`#$SrDR8x=Lv%fiZR~9t&C|$^Ux`lOJUntOdDfE72jTq zvNMnyKi!afMR`y_;n6QYA;6}ydk?)9=Yd6Zh|Jh{xA^yu=_4T)@lLBw#2Ue7g_Zm^ zybW2X(DbM5EOSD7u4s?0idmWDU>JtiV3nvQ=uH}O_RqW@OGuUS22kpC;^LnmXsX>s z2^5*YSqHe*?Btoqx&r5MF5?nqo0sp<)p%=BZ2B-rp#}m1gaAdAZ8-dTJ=0U<{9QN^ zeC9s5CoPuG>LxX@^>B?%F)=G1H@-*`S7pg`xH3^1e8VAB_zvb4OtN!C*YJ-hifcNi)8XjON)QE6`x@R0zUmisBf!~YG zT@Z}J{ecOz<7|eVslz4e<9*dD>i$acHA{frK<8i+Cv54bt&qs8X*-~z&(x4bg4TZW zXx1kT$x!3`eViJvWOShkpdf+abx_;)Srn-kq-$Fb2%il0poE*zt4*!SNc$OBCq8D> z3_wE**Gr#AKgPz?+_Mn|P$JXY!MhRNe*wN0J1e)v>7xJ>je%(8EJ49h5rx0RQp=1q zzp~cV@hPhx)`pio$i;;PY3a)y4;~nZ6SGDk=cmMGCfFf?EF>A?3hT3%UwoeW{Y0FD z^@4m81fS z`={Car&ar>H>#_Xxt*GXA2YR|>=j#DE1??$OU;6mK_qa+QJyq1kEJq?CDERA(NAue zSMu0$bW!Hm=`tvbzbd86M&e(VTn6RC;k9fV@<*BvBQA~oD{Q8 zpn+*-ac6dia{o~OXitkzuvFmvVE9HU`Ac(}B9_7Z*XOEzcb0cXeB)RXTIScwt>GmE zkNJ9@#*IBLlNnEpiYqep2J(qNbUq<9OLrdP=EMM{=; zj|88mdTG7aSHk`lE&Yl!DK_A0?TRkJ7K>ut9u8<2MloE^c`)+!Or za6}RNkyqG~%gVG?&*(xBy(L?blwlYMZRQe`yhA#9JShKC+xy&omiN{@olTlEwf=24 zb*CdLUtfVmw2G_0<>}IVWZ=zT4lkXwtfy1u<0?d(&T3{Y{yp1D--)yf!wFw;s*D=} zh?9>hI=OA8&<7|ol&B#lPg@O_1#@4nsH6)bc|gsi#{`3GRvh0!k*!bmC%^npw*y`$ z4#tayIL8fkDEf_M)G(p+EwQ^v&;8E7wQTiXyz? zyLq*g)uE3sV1lDp@EWakfRj~={Zw1gAN1`it4$0tBOeq{8D+t|GMvESF{vs`9+J<8 zC;Lg)+P9)YA0OJnfjinWwZaBocx!nq#W~D-KQuzk>E>2thUxEYH@Xj*FEN&6)&h{P z4{fFQOQo22HhLIyB_CfHZ!2w0rizEgqD-czjqpATs~;IUW-PhuHM?fsqT))gK%Jd)dlh6)z+`R7GJS+t=C;Gk0g|NoX8kc z=xRn;cJRByY?eE{=}d+<*ITJO&@bh4yie3Ud`foI7d3V_qdyKyA6c||UNj_NopPid zWE!8yzx;W6tcFNK?Y6zE6F{n`^Qv8OUEY>;I>>m7`7B28nl} zG!KU_7b#u9^oJ=U)F^WRg6w>5EUE>+HJRVPp4^+>=cQ`~{OUe>TcEaZ3ysMe#LrtP>9<4MIj9m1({gW9|a9A_HW z%nf%zpP`p%5Fiz}2K#nQ3xhY}fcW9nYa!2R+YN{@fEuWq8rb#i&d5uD|MaDnjiRv&E<>d=zsx$#-|I{x^Ap3I61IpeHWBaV&$&HV&T zy3e|t#S)8(xGH9O0k zzBCQDa2mupGfsg{BEKhA{+2)ZYKA`O1#<%3Ch#h$dA3ECY~mh&v9p}TOoMgYY)6TV5WA~NMQ`Ity9kQGH-^>Qj2nBSP<=l)NY4M^sF6!N~bW{O%S}& zD-__S!)L^Y6-;f@cik`j{tGwX|hG zHoCZz!_Ae}Mdya}qmzpl*#g>r<4}VYWA!H#eDoSG$Fj4 zZSh^C6ixf%nt8Bx(U7SLJfhQ*eXK+xAZVXHMl>_>9w09_0X`m!XTFyQqi!O!FfWkO zY@HlPSu1Fh<-xPf3HV|$m{Hi#H(kKpn=nLqN-YsAj0*oP#SaO{_~U(?=V!GpZsg@~ zA8j&Jy##mvgrdnLw>_tJK#kZimW~vA-=c_Zu;|=9Rv85x7IH?hbyyXUVf0?w4){%L z|69*{_|74lGI2SGv%nO9p|HW}aX}*8b0)PlJ1^lz@h=sIat@(wjJhNF{`~48z&A+S zMOa`KvoZmclXJ_RwRPc^c)tvcTKPpdj7XN zI>6ivu265RbnLKkvxiy;E?34eXXJn7m$sMLC*_9IB>wf%l*ZnK(hg+MXSB1+PU3Y~ zk@cY@hyeN&HzFIlxG_3x1U%&~7_9s3j~rGGEu12tb_}3JoA|4#4Augx{zx26IZXU~ zD0iUMCN*SfD$_5Mog(=`jYyKSN1b9h>p=6a3vkT7es`^5QF}o37{T}`db)qWVfE8U zBXnpGP}1Mg7?d6UYd6ij#a%V{V>>UtBN10Jk)sDx(pN6ZA&^Im^HnGU&SJzb@VgoR z1k6=;qwR8OkMBPGLs9=CN;xpCtp=dk$r--p70$lrW+zkcG4+Tqzf1UVG?0y$iPi*!UB$8=`ud-q1G99n}HE@ z0a)d1K}W9<)DkG5h#>~wW&jRt;f_*(uwNP1-Q3JM>Vt%nL=;Mw zEFnkey(rIfu;myDKF{5&tjPyb)_=EEX#{1Il6#CW>Znax&#k=nWM1dFm*BJr3s+_W zVHEl|!?$v#D9WJ9Ff1+^v_Av{^f>H=EP~6AHf4}zvnc856()|DH*j9J%r93a^UYy< zivytlXpeP>9ShfHNLT_1=yt0a23O%%5+IZ&@{a7a_)3`7h`{Im$+3M(yA#V0%i{L$ zZ(Mh_Htl^(_+nUn8W8BN9*7Wef>$(C_CjagK1)_(0MIA0ptqB45;`)MDLXcf%Ix(r zp%uyq%P0gR{{hzV;GWg>1GT%1<%ZA^KvGdXso{58E#7Ycoy>*`v@b=AfDD2k z$yJJoA2X^kB)OXpE9UIZup#~E&@>)^fYKN_%`9p2DIfYe>{Q3&{KurMoHBs)kRIDB zot^H+%litkWTx&Hk?jml&vSD5=gl3)))aI#H9#yYmjV0yaiqOw3h=*k8C4DLT8#g! zP@D|kQ|R;SqGvs3NtiJ^=AfzxY7)bbD%n((5Gyy-DVtCTYYfX;C>E$!)GE3K(qb^b zcmDdK37jv=A+|O_2iuOR53;Dei~}{S2S4JPkZpB?(vJS3)Bcq$YY@YKW!YGR)^0{E z#!z0FXhWa%54!W=35@%LJsf}0UH{85Ru`{8YXlD5yG{AD8JV$=$r*#FrvZS5&#xif zovVq;qxkud2$P?Nk2K3)F)b($OH$&1yRxLuiD|L`;mV<-zBWfeI6;>5uUZ zz-b7n?{a@1+~)_j-yvM)Draeuj6*tQ(5^ZR#U3=uk7O&w!=K{Fum9-N3?{v+2^edU z#eTlQ7I;55Fl)n&*UF0H@9b+ae6k66(VE_Tg+tIh%X9ob2#p(d=xm#&WyLSgLgVhQ z_B8f|&6b*&84<*fX|KPL#Itgp^?A*_Y?pS_oO-KW5OqU`XfHJYr&5czYm>-!rEsGb zQ6hy*4Vy?2MZt}>nXMm-rx6BDbL70AjP&9MHYkZLS6nG%HC#7BNSYsdD${Ttp%*TR zz0N>wTL!CESS%4SD*?@o;AgoJLPkD8sK4U&5XOciQ(f$&ge=Cbrf+*=b2Nb{)AzS- zcXqaiR4g7nqJr5&ZLQ>xZ8XWdqoR{X#{^w4sNzbclX8y^QK5*BD%epta`iu{l==MHTC0 zdz+>SR7bG)6G6hwsd~7GN3$Tm+Mp63ZaofHo6X4Z#>P#~gw1XWH{>jwQJJ)brNddX#rh@=B4 z9Iks7SLz>&WV)L|D7Y`?Ix>X&4vNGN=>t!(M_BQmy@n1}Y_81oW}t&Pt>?bk>1FF^ zIPgS!i{UCwsJ@TKzF(^bi_kl2V&TFT@KyCZLNR#;S2A#*oUr$JKgAKn1p37v1%7<{ z<HC{b7Mt~7hkw|*h5jKkf^NwhRapw5NR8n4yT^CS&d&qEqlC$8^3PQ=R>$Z&F8p(~ z)1`SwT^tn%dyA}aYSDrB71=esa*2GRa{w?MpX~3EE%I69`#r!iGcb|8eLIM(IVPc1 zFEDdn>MP=pJ9fvLk3~ZvQm+f6+KRJ0vi+F-+tWu_SLe`Q<;QBLsZYR74wlgBR`+CS zN96%c%%zN&qDDtUM&Zwe=ncf&+~>~q?3csWlC@R?jl9$h`c_8aOo>@N%#OZSnlr_N zzkwg{Qjf*o=Wzx&aglI3toA__5$1Idj}F-7D?V2-6n4^rP}#oVa-0_pyuL+tosb$Q z_8ArTaF*?^8wAVmKE9a+fz4?c7neJs49So(i-0QOg7;`miutL9nJJmfTD#~XQkj|` zNUX2qlr@Sx#buh^`F$kOAr_^?D zZ%G!h0TK6p{%jiG@8frGYF|E1#2k8ACJVN{dloC8d!%nTF#2dZi)4u>WAng?<Detm=O$=Q!HyVIO@)NtTBm+1gZCE>L`Jr8&N8I6jHzNas9}%dl(2 zB~nX_AwdO16#vzR_g8o~oQ(n_{cyEPG(n8RoIt6f2`PXk^z%2%JWsT4==1Jd$)#wg zl5z1(s!56d%^u~c`)3Zn+?W65?<2LyeAtx+$^T`DOmiss${|>Zx{j(;K*!x%t2}0H z8ofT7N*~Tpxciew(rVsbF0Ef)hZlTD8H6K_Jk&RsMAut7!wEY`HCBcV9Zy9vaqppv zNaX%o)r@*_YBUQ;JjfjiAr!y`Y?04zix=;jM%9u|0dilctZTGB^A-lN!wzQy#4tsg zU*ST-@hb3lV+JwUJ!oZ$sK7zX&vXHpv~ zo_a`7Hr1n?(^aJeEO_+y^zCrI*JAvMx;iyZ1J1Mxb5i?5)GN5Q4u?KxRq@N{9z;2U zQhRktxrnnLPkZS~omp{1hYU$}1#!0k5}FC(D!QJqm5te`Le`>*l!=G7YwQ)=dS;+i(z& z4=Z=0#51_Oj$pw4J_x`KYbmscyKcNPA-NW54mtGV!2DnCo3~PZQtd>}$KriXk5Ffl zo&pI=lSAYRUoG^#x&0&5xR$q`3jJ(!NmIUKX$|#6Ah_w8<1>&3C)Q>?2(53%J~a)6 z;2sO>tS^(d_MFFauI)K{ z*IYP06bsjLeVBdIZX&U5bqmA{Qy9_LG3w;FFw44Gwcm%nQgUup6>QiF$EdJU@LoDR z9@Xgq^A2>qTm7mz&-N82)p}d<-G&8HB{Fpk9F1J)LVL}p8tWnMeCs&FUK3Q@k=W8+k>!LFq2A{OWI;0K>@icHztvR4`$ zP@F?=?kE9GYidH{$K7WkGYBu*SPq54aCp`R_% z4ydCvLN+b%UU~0jLK90=tPPL$c4}3rTm8F%X|iN;0adHD4AlGG8wK!MxcJ#Szjl>s zq5}HJs)358=OY{lKCJ$-Sm!G=tJm;;QgHhZqReK4&Ec1y6W?bxgb2doWP1J?3JUA< zxp+)4U-kjzI2-$L08&5 zd~T`>8_OY6%#;EXZ1zN)csy1Q_SX4&uA@-|C2{}=yCwwLM$cG={6@kZwab1jouQu! z<*7nbAv3CN#J&wX=pU1|uC?j}DsQ@WZduB@x1gr}mi!Ior)3YKyk@?~d&0ceOF{zw zN==i8Rc3Z82KF4@V&Hn^+;6gc6}lX1WIa;KY0Icc1J3TwX2X21kxBalKyeMPl;aWSrL zA2BOE?zZ-Zp6g=Xm^|-y=@Z7-WtHYz{gq~mMz2YhPB6X*e`YFfA7sYt<5|9DIrMGTrMvIoh~^7>zCZ`Ec9|HonoVkzqp4 zhxP&{?IFAp#*&~iuGDI3n^c^;T=*o`emW)93i6GW-*D2TA{(U-5eSxfC195c9Wf?EZd) z%P5^2yr;cA&bXO$F$FL-righ&R%*ip+)T8 z(`MqwCS)s5s4r|q(*)@oiT~6=#)Dx{aC*wSv$k5vUI#UYw4>1xc>`)EcwO{@@1_*uL zyQv_+5HdLj7EunmTU$fHE;PmYSjX6bcA8K`>Ubi9k*XQmGIjL0l3cw48bFPu7B3TW z$%1d^umrT-A;kf+l~e1?t*?cz&meTCnOl^A9;5e^TIaoveQFlgF59$bE(aIo0$olF zHO!@uR;i2L4_>43&&~Cs%P(@9OOhMgdM)65_j%4=qKy^v9}KE*YWKwooT3}Egr??W ztH_VV&_gfhCuQ%$b%*q5fKfgon(!C`!+bo z@lfPtQth`h=kUfv)=<2Uo2*RnP5nG3+o8Gr_B#SA^+_ zk5#SsG^s--A-K+x3eb|(zt&eGrUr0+Gh7`%k6&%`RrB`HeP`|iWtSLE2iELe=VYD! zdts0G3Pu6Iu+uJWyUQlLS!Y!j*xvE|gkP#=Wg7g?VCgb! z$iBio5JRkuM!(75VdG`YF|hI4GVsmkC8F|(U|G=@$s91gcaS|C6Gei6(ZR3RF zN$&HeynW>8?cKP2@eo52UZPfW%4mUS4YQgt2r~*EVd}Z8bEQpIhIDC?1-cE&;S}64u`P0V4qZM&FB6V_Mc2Oxrq;oX zXU&7Pxp-c3!5AXd%t0!we**p4-3$#h@%nd+PwHR@Q)m2`G`D4YMndp>Z3e5qbnbTf z9|bwr@Rq|Xgp!GucSLW8%)~&Dnc30(jbpFD%bC&3*hV7(-KLH8TmBF}Z2<5G;bD2d zLPw8=t`6Yq4y&Xc4*to*6Wz~fWAz`6pFF`YdLLxX`aVM0i;wfA7fhi!!_obU1Hbg_ zIB>1;5}#QRt0R_HXtHK2=P#c`T-)9=w!xY=lkH=iMU-A2646GG;E?op9DNO4BIq+# zbxy~8!H}PUM)gR29hxn_A^WtfJ$wqXN;8CF)Ef5RWASxiJ|bJ+E*(~No+}Y+{lW8b z0|;@tv$9LuFcTvea9ISO_I`NWj3@M}v1#!3F|!m1biML*8! zC90+O96}gu?Vd88G)oD7iS)=SHv)^kgFVmLMcQbJ$z+Gxmz8ZK7M)>%&CUh}Q}_?% zyH&!kAh@I7N?qE-#2JfV-K<4x^;j3*(DB08L&q0gdpfAF184%=WFJ_J6QVtpnAVFqCW&IJOkC$Mrl76?KyM<9M6dOn3UWlE=Q{S?mqj z__tnkd`;T522#f*6aJ6BR}u2qi+0PbcH6)_=XGPr%`BO+bphtb^a$DNT~DlU6fKn~ zFUV=7$Ues|OG5q*pzhl>Jj>_kufBdA(ld(>(~(HV$_vEJubH#~Ghk@KKe-e&t;cZf zI#~J*6Y7MXb{eAz8xCma7d)>X9_3&N)Ju4aRm;<3FwBluGc`j?3ifoxL6oa$s=gGQDN8Lck>!N`n=C5qgTS&6!9m#xqBQ(T#F4) zp!vE~=tP$O%oIbL+{-xfr9M7=t$FKho)MSP=XrlR?K97@$J_|Ui6=Wp`*!10_s3CQ zf{W+J-2*IpTh)>!FC4@0DzSQ?ap(b^u12~YXlU}fn~gpUY`;;?2YC$OyXif&#H+hn zn&02MzMcD>ZTnLT-%_<^d^T`>btiyI!e7@%D;;rnx5~_;-?cVdD+AOlY}(tjY6wvO zaHI_xor^<<`c)BzqfeF%y2W9y%2cfWTyC(pi63)4%4TxK^M9TRnoWzTcWo4j5DmV0 zhdZ)mGx8|a7B0(Q;?`FF!;i*fxD$90xTRQ!D6{gSo1^(uSq_i*C^n<8!QV$mHP_CAOacsSQN8hX0oxwu4sB$D;4iqrf|Z2OKc>lX6s zk;s)!JIwNg&wAX%OY!`<9~?=M-)kerf2IfiCy`TlgV(;>Ob zR;9SpFXIV1*Btf0YR$#eI+99~^n{MYT0Y94i(tqQ42Zyuu8_Z_h`CpHuXPK5!$v0< z?2Yz)*^(jfwC?WpV|^jxBFAQi^O(a}4L83Tb&jg>wVi;q!?dOI-#a2nlBOJN(NDIv zs?_4vL(M#LtiH#uR%oYvF4{h-679s`@<8G9_{|#ojI;4ul3@7zzW$E}z}uR4UAt-%%r~^3WeG*;%FJ9_G^Z(%`8i941SEsJY__Kl0>CvK$SEh z&0VpQVUC+s!XhNEQd>IX6#??r@!8xhj#*`u6VQJtpC+Q2RUYlQAvEA1Cbv6#@#t;-)Wj2- z3fM5IY}W>AG(h?#5;)|aS!|+-*IAd6staM`CT?wYegb$|RZIx=2{s(MhboCoq8x?K zLHe{2N2O(g{!^rix~CH@sNrteP-?T?iF4*jscWyVJWrKJrRk>S0LcR=Nu9;TmljMR z5z3&fP~DK_zaAG`h!c_R{rw~W36iImSRbE~vS|zK?5!l#59d&O5*kqx`n?<^MZcGn z9%-*_LrDA4Ro_&6t+9$J^2ceu>gUh3)mtPSacv(JDY*Z>^NnqcYu&qZ*Ipf~7RzUc z%G&?R?(ae0e27kaz+uJ{4eT|X*^A{*wU0*3pP@gqAKH{fd5n~dD}!u7U|bUR_7Tf3 zkThS~k(9lWyURMCU%F|qmoB4K^CyqbFOFFbj+Jl$u@U-4VI3Pw6v%~na@cSW?V;m< z#ELaq;2a~;RaL90{{aFUQq2+_Z8bkbEBw5;EO{<3dS#cZ7AEx~wSWsj%%^C=3y7^t z#Ur#qg7#?%d%MMJn1*22p31ydPq$mEH{nv9EK-h+9#65rGs$@D@$lMIJVXdhGvmQ+ zf)+vt9cF)KbFU3`bftLO*fO5{gjUh*97`Isswi9!jVi9w*|8YTma}k#M9_1}sqOPC zg!jJ|aahQKB;>|YC|@G*u8sI(4zDCZe}22uF=%#++LJg2eU08*w_x%Tc621+tn}y{ zPL8dL&1v8PCI*0-#?Id@vTSs@2a=d6k2-j~bUoFv zfcLh5;&bLvgkLsw?`_Sb|0AQMy8$xp#JJF(E`~%Fhs~8;-Xr)m57Zj9<};;M7ZlN| zjQG6KN8_)>%QYP0Zq#1l5}^_RI3NR)Oj~B;F+mH)VU#Wxmy|E#Z|@1BEsOWE_6RNV#hLR-c z9YGS#>3DH$Rz+2!%8{JYw4%%}o+z(9mO+30TF!C1FolF#g4~=#!VFE17>8w!rpc0D zhRn5SuODPeH6aujJrBb$_2^cn&p*70Y+k*&To%ch0y>sue?L&m&N3p@yyvdKO@%m~ zoiV7Y-&mQV?E{-5n{_wfjhTu|BErMnxtgn=bzEI9vvr(lK>5#JNhZnYiD@ZadXWb^ z^$OaIre;25byYUKZJlg7Pn(_o%_v7qWUY&ZUPNmrwmQGb2KtyyaF6Ibr}RB_`|V=u zcY>8GdX(0s8!Jf8fZIJp(hUupcuQl!iI3*XzA`fV^UtY*ceMBt)>lFNfyXh8WI+9o zX~~$<4A0eM7oTWWwx9V$sXu^&gUcB-VzStwxCm|#wCiNr9SE0vC4s8kYYhiu1G;`s+zIi&D zvyxiYLY*`#=6*w4%wf-%)ViPXGo)Y+WTtH@$D@ZBbn@#24SI~2c6bKOy5V2d_jiu? zjqcwC{ff=&+$+%9#LX6zgssQ1M5sc(!Ay9(O%y-e1B=Kw7yoyC;Kv;zWM#j`r^h&K zUB`Jemp;?#>%saPJ5K7F4LzqVPs|{7m&l%R5Q=VHd`mPvnv4W zetz!%bs`oOO=EGWq|^7a<&2l}tgh$3WDPk;9SRZ&Hn+(q7IN7>?%L#J#B@q+07(`c zC|p=zF#TDLY_(ek&7D&2u0DTFg8kWGOx8WItUE6gp$p%5vJuJLh}2z*|J!U7VoTNk zMah|XH9!V(mH492s8iO%B_2nhW8o*GA(N_5a){a zvcA9SygxUvN?3rTWe@=rg!QGCHCV4-Py@Ic_w5M^uV2^a`#Lz+l~8uo8eFZNoGJ0f za~Jr|4=yv#(&vNtg)dALMF0gss7bA$N7S~32o_1GK1{w=icHHO0w@TrLsbO*^DD9jD=zMdQ3|Ig^u^8u zXFC(Bn6MbU*)hdhYkMru_rLm<{>Jw%GVa@#FbmNCIL%;^v5}`SAjklcS7G74@q-I@MglVymI(hUG))wASuig>ysW`ty$; z(_i}1DK3tA;uo~`f-TAgZfOB*sV7nif)I%jGVh=In-wx|0mcK{$?WZ+>m&P(`*(Kp zo(_v$ag+YC%gl6JlP6bd$w;{ZB>yh`_>0r%OL_N2Iq;_2>shu-`{eG0186;u@Y;r zDtuv9VN?tL4}YNpJ7gMcL80`2MoS@mfP&C|L7XD@aK1P3^9W1rt{QZ9Z zzCPPGUu|KD(a@rOfFgi`(4MR$KoZSIL76f5ks0xiiw6*0D-rwi4v`-M0_WuPx zBP9cdcp0& z2ophQQ}F{4Ktb5Z)UyVw)3Et4!UQfThHc~if(W1>YzD%FusYwU_*ID#LI1Mge9IyN zC Date: Sat, 9 Apr 2022 20:00:10 -0400 Subject: [PATCH 1961/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6efee211..c539b091 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Select a Proxmox Helper Below

    -
    🔸 + 🔸
    Proxmox VE 7 Post Install From 4e322a2c0d78c15d4c23c37c6846250a612f4ca7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 20:24:50 -0400 Subject: [PATCH 1962/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c539b091..6f88a776 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

    Select a Proxmox Helper Below

    +

    Select a Proxmox Helper

    🔸 From 4cde942785df4c46b61184fbb9536c9d2767b043 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Apr 2022 20:54:35 -0400 Subject: [PATCH 1963/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 48f50c38..36015c07 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -245,7 +245,7 @@ header_info } function start_script() { - echo -e "${YW}Type Advanced Settings, or Press [ENTER] for Default Settings " + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " read SETTINGS if [ -z $SETTINGS ]; then default_settings; else From 2480208789f9d8548bf2917d9f7c8bd3c8d38e48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Apr 2022 07:28:27 -0400 Subject: [PATCH 1964/6505] Update README.md --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6f88a776..ded748c2 100644 --- a/README.md +++ b/README.md @@ -856,7 +856,7 @@ ________________________________________________________________________________

    Docker LXC

    -

    With Selectable Storage Drivers & Add Portainer/Docker Compose Options

    +

    With Selectable ZFS Storage Drivers & Option to Add Portainer and/or Docker Compose

    To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). @@ -888,11 +888,16 @@ ________________________________________________________________________________

    Debian 11 LXC

    -To create a new Proxmox Debian 11 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Debian 11 (curl. sudo) LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian.sh)" ``` +An early look at the v3 install script, run the following in the Proxmox Shell (V3). + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v3.sh)" +```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -917,7 +922,7 @@ ________________________________________________________________________________

    Ubuntu 21.10 LXC

    -To create a new Proxmox Ubuntu 21.10 (curl. sudo, auto login) LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Ubuntu 21.10 (curl. sudo) LXC, run the following in the Proxmox Shell (V2). ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu.sh)" From 3bb4ce5d5450528a0af0ea0131867beac69735bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Apr 2022 07:41:04 -0400 Subject: [PATCH 1965/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b25ae87d..d008913e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-10 + +### Changed + +- **Debian 11 LXC** + - ADD An early look at the v3 install script + ## 2022-04-09 ### Changed From bfffac2cf5ddf2abeceaaae9eb86f1d12947afe8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Apr 2022 07:43:34 -0400 Subject: [PATCH 1966/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ded748c2..6be799e5 100644 --- a/README.md +++ b/README.md @@ -882,7 +882,7 @@ ________________________________________________________________________________
    - Debian 11 LXC + 🔸Debian 11 LXC

    Debian

    From 39a13ef12422eee2a54b6ce990894e04e2529458 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Apr 2022 09:21:45 -0400 Subject: [PATCH 1967/6505] Update debian-v3.sh --- ct/debian-v3.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 36015c07..1d6eb1f6 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -242,7 +242,14 @@ header_info echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" - +while true; do + read -p "Are these settings correct(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) clear; header_info; start_script;; + * ) echo "Please answer yes or no";; + esac +done } function start_script() { echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " From 726c984d509a60104c347d80cd2b95317a1f1e31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Apr 2022 10:44:15 -0400 Subject: [PATCH 1968/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 1d6eb1f6..f601a94e 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -116,9 +116,7 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name, or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then HN=$(echo ${APP,,} | tr -d ' ') - CT_NAME=$APP - else + if [ -z $CT_NAME ]; then CT_NAME=${APP} HN=$(echo ${CT_NAME,,} | tr -d ' ') fi; echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" From 4a5de17681342691bfc051cc6d28ed9f521b9d44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Apr 2022 11:08:33 -0400 Subject: [PATCH 1969/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index f601a94e..a18b6b98 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -114,7 +114,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name, or Press [ENTER] for Default: $APP " + echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " read CT_NAME if [ -z $CT_NAME ]; then CT_NAME=${APP} HN=$(echo ${CT_NAME,,} | tr -d ' ') From 9e45482198fc5c45e8663009a6f51b19d9a4bcbb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Apr 2022 12:02:05 -0400 Subject: [PATCH 1970/6505] Update debian-v3.sh --- ct/debian-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index a18b6b98..3b6472c6 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -116,9 +116,8 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then CT_NAME=${APP} - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi; + if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 From 9cb82fc8d6522c174936356cde585daeba553b85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 07:57:53 -0400 Subject: [PATCH 1971/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index b20a0ea3..369631f4 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -37,9 +37,19 @@ function update_container() { echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" } +read -p "Skip stopped containers? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + skip=no +else + skip=yes +fi + for container in $containers do status=`pct status $container` + if [ "$skip" == "no" ]; then if [ "$status" == "status: stopped" ]; then echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container @@ -51,5 +61,12 @@ do elif [ "$status" == "status: running" ]; then update_container $container fi + fi + if [ "$skip" == "yes" ]; then + if [ "$status" == "status: running" ]; then + update_container $container + fi + fi done; wait + echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From db6f9f2a77e94f31d95a5785297b91535483147d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 08:03:54 -0400 Subject: [PATCH 1972/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6be799e5..f5c02a97 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ ________________________________________________________________________________
    - Proxmox LXC Updater + 🔸Proxmox LXC Updater

    From 617017fd7ad9a779a9bb8e097db0e588a642af7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 08:05:39 -0400 Subject: [PATCH 1973/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d008913e..f69a5c36 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,13 @@ All notable changes to this project will be documented in this file. ### Changed +- **Proxmox LXC Updater** + - ADD option to skip stopped containers + +## 2022-04-10 + +### Changed + - **Debian 11 LXC** - ADD An early look at the v3 install script From 3615832d85c448e454ce94c5ff88e5dce013f04d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 08:13:08 -0400 Subject: [PATCH 1974/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f69a5c36..4a620686 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) -## 2022-04-10 +## 2022-04-11 ### Changed From 40f3ee97e9fa9af890f2ee7cefec89696b52411c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 08:41:44 -0400 Subject: [PATCH 1975/6505] Update post_install.sh --- misc/post_install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/misc/post_install.sh b/misc/post_install.sh index f6dc0947..7aa5cdb9 100644 --- a/misc/post_install.sh +++ b/misc/post_install.sh @@ -9,6 +9,12 @@ while true; do * ) echo "Please answer yes or no.";; esac done +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" + echo -e "Exiting..." + sleep 2 + exit +fi clear echo -e "\e[1;33m Disable Enterprise Repository... \e[0m" sleep 1 From 8342bb1d16ed092c12f892b40f0ad5dc95e602ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 08:44:31 -0400 Subject: [PATCH 1976/6505] Update post_install.sh --- misc/post_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post_install.sh b/misc/post_install.sh index 7aa5cdb9..d529fb3c 100644 --- a/misc/post_install.sh +++ b/misc/post_install.sh @@ -10,7 +10,7 @@ while true; do esac done if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" + echo -e "This script requires Proxmox Virtual Environment 7.0 or greater" echo -e "Exiting..." sleep 2 exit From 0b4aee07672357132203f8af750cc9aeebe3dd68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 08:47:46 -0400 Subject: [PATCH 1977/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4a620686..f1ef5d26 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - **Proxmox LXC Updater** - ADD option to skip stopped containers +- **Proxmox VE 7 Post Install** + - ADD PVE 7 check ## 2022-04-10 From ff4107fd3a43fc206fc3a51929140dd76293bccb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Apr 2022 08:48:44 -0400 Subject: [PATCH 1978/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f5c02a97..81b265d0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 🔸
    -Proxmox VE 7 Post Install + 🔸Proxmox VE 7 Post Install

    From 2ea0eea518ef8dbd38debe927dae6002912d9902 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Apr 2022 08:27:53 -0400 Subject: [PATCH 1979/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 81b265d0..3b8409c5 100644 --- a/README.md +++ b/README.md @@ -1007,7 +1007,7 @@ ________________________________________________________________________________
    - 🔸MeshCentral LXC + MeshCentral LXC

    From bf23503c6562eff97f1d54fbd7c009fea4dd39b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Apr 2022 14:08:30 -0400 Subject: [PATCH 1980/6505] Update debian-v3.sh --- ct/debian-v3.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 3b6472c6..560a98e1 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -239,15 +239,15 @@ header_info echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" -while true; do - read -p "Are these settings correct(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) clear; header_info; start_script;; - * ) echo "Please answer yes or no";; - esac -done + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi } + function start_script() { echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " read SETTINGS From 99d2a40050584bfda5cf1cdfc6484cddc3ad879f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Apr 2022 12:09:15 -0400 Subject: [PATCH 1981/6505] Create uptimekuma.sh --- ct/uptimekuma.sh | 259 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 ct/uptimekuma.sh diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh new file mode 100644 index 00000000..098eaea7 --- /dev/null +++ b/ct/uptimekuma.sh @@ -0,0 +1,259 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +APP="Uptime Kuma" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${DGN} + _ _ _ _ _ __ + | | | | | | (_) | |/ / + | | | |_ __ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ + | | | | _ \| __| | _ _ \ / _ \ | <| | | | _ _ \ / _ | + | |__| | |_) | |_| | | | | | | __/ | . \ |_| | | | | | | (_| | + \____/| .__/ \__|_|_| |_| |_|\___| |_|\_\__,_|_| |_| |_|\__,_| + | | + |_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" From 2cd089fbbf1c7838fb40f8528a23f625a9c55e36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Apr 2022 12:11:06 -0400 Subject: [PATCH 1982/6505] Create uptimekuma-install.sh --- setup/uptimekuma-install.sh | 117 ++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 setup/uptimekuma-install.sh diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh new file mode 100644 index 00000000..5c41ff6c --- /dev/null +++ b/setup/uptimekuma-install.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap 'die "Script interrupted."' INT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM + +echo -en "${GN} Setting up Container OS... " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +echo -e "${CM}${CL} \r" +echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " +echo -e "${CM}${CL} \r" + +echo -en "${GN} Updating Container OS... " +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Dependencies... " +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Setting up Node.js Repository... " +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Node.js... " +sudo apt-get install -y nodejs &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Installing Uptime Kuma... " +git clone https://github.com/louislam/uptime-kuma.git &>/dev/null +mv uptime-kuma /opt/uptime-kuma +cd /opt/uptime-kuma +npm run setup &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Creating Service file uptime-kuma.service... " +service_path="/etc/systemd/system/uptime-kuma.service" +echo "[Unit] +Description=uptime-kuma + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/uptime-kuma +ExecStart=/usr/bin/npm start + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now uptime-kuma.service &>/dev/null +echo -e "${CM}${CL} \r" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +echo -en "${GN} Customizing Container... " +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +echo -e "${CM}${CL} \r" + fi + +echo -en "${GN} Cleanup... " +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +echo -e "${CM}${CL} \n" From fa322abba1f5789520353ded075cb7cdd69736c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Apr 2022 12:13:47 -0400 Subject: [PATCH 1983/6505] Update uptimekuma.sh --- ct/uptimekuma.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 098eaea7..b40519ba 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -256,4 +256,6 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:3001${CL}\n" From dc467993b56846861bf1f3370bd48c73a45c0605 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Apr 2022 12:28:27 -0400 Subject: [PATCH 1984/6505] Update README.md --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 3b8409c5..ade9a08b 100644 --- a/README.md +++ b/README.md @@ -1184,6 +1184,38 @@ ________________________________________________________________________________
    +
    + 🔸Uptime Kuma LXC + +

    + +

    Uptime Kuma LXC

    + +Uptime Kuma is a self-hosted, open source, fancy uptime monitoring and alerting system. It can monitor HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server. + +To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell (V2). + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. + +**Uptime Kuma Interface - IP:3001** + +⚙️ **To Update** + + +```yaml +Working on +``` + +____________________________________________________________________________________________ + +
    +
    Heimdall Dashboard LXC From d040da3c78009fb478f5c9955274649c7512340d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Apr 2022 12:29:57 -0400 Subject: [PATCH 1985/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f1ef5d26..35d04e97 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-13 + +### Changed + +- **Uptime Kuma LXC** + - New Script V2 + ## 2022-04-11 ### Changed From 815988cb96c395ebcbe8dabf035c7c324dd733de Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Apr 2022 15:54:36 -0400 Subject: [PATCH 1986/6505] Add files via upload --- misc/images/proxcord.png | Bin 0 -> 109791 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/proxcord.png diff --git a/misc/images/proxcord.png b/misc/images/proxcord.png new file mode 100644 index 0000000000000000000000000000000000000000..619f32bd963eb07595000623adf5a61f5d2915c7 GIT binary patch literal 109791 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%0Aj8Ao80ccb!|y*xCb@*TRWu!$Ut5R7O2( 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

    #u)m)t2wf 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 Kyjs*K=zjocysa4k literal 0 HcmV?d00001 From 99ff264f40714504bb7dca112efa0911d63a5e1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 11:47:01 -0400 Subject: [PATCH 1987/6505] Create homeassistant-v3.sh --- ct/homeassistant-v3.sh | 364 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 ct/homeassistant-v3.sh diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh new file mode 100644 index 00000000..032a2fea --- /dev/null +++ b/ct/homeassistant-v3.sh @@ -0,0 +1,364 @@ +#!/usr/bin/env bash +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +BGN=`echo "\033[4;92m"` +GN=`echo "\033[32m"` +CL=`echo "\033[m"` +APP="Home Assistant" + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _ _ _ _ + | | (_) | | | | + | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ + | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| +${CL}" +} + +header_info + +function pve_7() { +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" + echo -e "Exiting..." + sleep 2 + exit +fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${GN}Using CT Name ${BGN}$APP${CL}" + HN=$(echo ${APP,,} | tr -d ' ') + echo -e "${GN}Using Disk Size ${BGN}16GB${CL}" + SIZEDISK="2" + echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" + STORAGETYPE="local-lvm" + echo -e "${GN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="1" + echo -e "${GN}Using ${BGN}4096MiB${CL}${GN} RAM${CL}" + RAM_SIZE="512" + echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${GN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${GN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${GN}Set CT Password ${BL}$PW1${CL}" + + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " + read CT_NAME + if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " + read SIZEDISK + if [ -z $SIZEDISK ]; then SIZEDISK="16"; fi; + if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${YW}Storages Available:${CL}" + echo " " + for stg in `pvesh get storage --noborder --noheader` + do + echo -e "${BL} - ${stg}${CL}" + done + echo " " + echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " + read STORAGETYPE + if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; + echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${GN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} +pve_7 +start_script + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} + +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} + +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} + +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$SIZEDISK +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} +${BL}Portainer${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:9000${CL}\n" From bdf48425aca063450e008094a96c2e9579b1d257 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 11:53:38 -0400 Subject: [PATCH 1988/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 032a2fea..485b4b22 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -9,7 +9,7 @@ BGN=`echo "\033[4;92m"` GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Home Assistant" - +NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -20,7 +20,7 @@ while true; do done clear function header_info { -echo -e "${RD} +echo -e "${BL} _ _ _ _ | | (_) | | | | | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ @@ -51,7 +51,7 @@ function default_settings() { PW=" " echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID - echo -e "${GN}Using CT Name ${BGN}$APP${CL}" + echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" HN=$(echo ${APP,,} | tr -d ' ') echo -e "${GN}Using Disk Size ${BGN}16GB${CL}" SIZEDISK="2" @@ -116,7 +116,7 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + if [ -z $CT_NAME ]; then CT_NAME=$NSAPP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" From d5bfd4e833d6ed378944394b0233257e29f3ab15 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 13:49:19 -0400 Subject: [PATCH 1989/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 485b4b22..42e30225 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -116,8 +116,12 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then CT_NAME=$NSAPP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi - if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + if [ -z $CT_NAME ]; then + CT_NAME=$NSAPP; + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 @@ -131,7 +135,7 @@ header_info echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " read SIZEDISK if [ -z $SIZEDISK ]; then SIZEDISK="16"; fi; - if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; + if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" echo -e " ${CM}${CL} \r" sleep 1 From fb27c9bd342daaf88f6ec7efd2653203481f00ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 13:50:14 -0400 Subject: [PATCH 1990/6505] Update debian-v3.sh --- ct/debian-v3.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 560a98e1..616de1fc 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -116,8 +116,12 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi - if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + if [ -z $CT_NAME ]; then + CT_NAME=$NSAPP; + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 @@ -131,7 +135,7 @@ header_info echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " read SIZEDISK if [ -z $SIZEDISK ]; then SIZEDISK="2"; fi; - if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; + if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" echo -e " ${CM}${CL} \r" sleep 1 From 4cc1329b40a306e22742bd7190f06cf21c8f46c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 13:56:55 -0400 Subject: [PATCH 1991/6505] Update debian-v3.sh --- ct/debian-v3.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 616de1fc..8a6d44b8 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -119,9 +119,10 @@ header_info if [ -z $CT_NAME ]; then CT_NAME=$NSAPP; HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi + fi + if [ $CT_NAME ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 From 02a791895e0b8d5dabe71976e8228f3b1dfd0353 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 14:01:22 -0400 Subject: [PATCH 1992/6505] Update debian-v3.sh --- ct/debian-v3.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 8a6d44b8..1adeb340 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -116,14 +116,9 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then - CT_NAME=$NSAPP; - HN=$NSAPP - fi - if [ $CT_NAME ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear From 2044b18edbb126223b88379eb8caaa5a27d9bb8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 14:05:15 -0400 Subject: [PATCH 1993/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 42e30225..4c696d2e 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -121,8 +121,9 @@ header_info HN=$NSAPP else HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + fi +# echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear From f874f038ab9094d4ee2b8b49477342e29e8eb21d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 14:12:15 -0400 Subject: [PATCH 1994/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 4c696d2e..29174306 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -115,15 +115,15 @@ header_info echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " - read CT_NAME - if [ -z $CT_NAME ]; then + read CT_NAME1 + if [ -z $CT_NAME1 ]; then CT_NAME=$NSAPP; HN=$NSAPP else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + CT_NAME=$CT_NAME1; + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi -# echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear From 03442f2289351477e1852f163b807972f86c372e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 14:16:26 -0400 Subject: [PATCH 1995/6505] Update debian-v3.sh --- ct/debian-v3.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 1adeb340..d38b9971 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -115,10 +115,15 @@ header_info echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " - read CT_NAME - if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi - if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi - echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + read CT_NAME1 + if [ -z $CT_NAME1 ]; then + CT_NAME=$NSAPP; + HN=$NSAPP + else + CT_NAME=$CT_NAME1; + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear From 9c4cb4e6b9f2473eb6c240eaf9443227dacfc228 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 14:18:13 -0400 Subject: [PATCH 1996/6505] Update debian-v3.sh --- ct/debian-v3.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index d38b9971..7527965d 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -9,6 +9,7 @@ BGN=`echo "\033[4;92m"` GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Debian" +NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn From 59474e96eb21c04e219938cf96ad6163c36bad6b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 14:24:15 -0400 Subject: [PATCH 1997/6505] Update debian-v3.sh --- ct/debian-v3.sh | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 7527965d..493b3f74 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -116,15 +116,10 @@ header_info echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " - read CT_NAME1 - if [ -z $CT_NAME1 ]; then - CT_NAME=$NSAPP; - HN=$NSAPP - else - CT_NAME=$CT_NAME1; - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + read CT_NAME + if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi + echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear From eff887647912b9ee8cf0f9de0f68080c04fba2c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 15:25:11 -0400 Subject: [PATCH 1998/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 29174306..22c65528 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -10,6 +10,7 @@ GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -22,7 +23,7 @@ clear function header_info { echo -e "${BL} _ _ _ _ - | | (_) | | | | + | | ${YW}v3${CL}${BL} (_) | | | | | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ @@ -52,7 +53,7 @@ function default_settings() { echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$(echo ${APP,,} | tr -d ' ') + HN=$NSAPP echo -e "${GN}Using Disk Size ${BGN}16GB${CL}" SIZEDISK="2" echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" @@ -114,16 +115,14 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " - read CT_NAME1 - if [ -z $CT_NAME1 ]; then - CT_NAME=$NSAPP; + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then HN=$NSAPP else - CT_NAME=$CT_NAME1; - HN=$(echo ${CT_NAME,,} | tr -d ' ') + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + echo -en "${GN}Set CT Name To ${BL}$HN${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -132,11 +131,11 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " read SIZEDISK if [ -z $SIZEDISK ]; then SIZEDISK="16"; fi; - if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" echo -e " ${CM}${CL} \r" sleep 1 @@ -146,7 +145,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${YW}Storages Available:${CL}" echo " " @@ -167,7 +166,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -182,7 +181,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -198,7 +197,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -215,7 +214,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -237,7 +236,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" From 0965bb5a57843aea45aaf747afe554353e232cfe Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 15:25:45 -0400 Subject: [PATCH 1999/6505] Update debian-v3.sh --- ct/debian-v3.sh | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 493b3f74..421edc19 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -52,8 +52,8 @@ function default_settings() { PW=" " echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID - echo -e "${GN}Using CT Name ${BGN}$APP${CL}" - HN=$(echo ${APP,,} | tr -d ' ') + echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP echo -e "${GN}Using Disk Size ${BGN}2GB${CL}" SIZEDISK="2" echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" @@ -115,11 +115,14 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no spaces), or Press [ENTER] for Default: $APP " + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $APP " read CT_NAME - if [ -z $CT_NAME ]; then CT_NAME=$APP; HN=$(echo ${CT_NAME,,} | tr -d ' '); fi - if [ $CT_NAME ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); fi - echo -en "${GN}Set CT Name To ${BL}$CT_NAME${CL}" + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${GN}Set CT Name To ${BL}$HN${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -128,7 +131,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " read SIZEDISK if [ -z $SIZEDISK ]; then SIZEDISK="2"; fi; @@ -142,7 +145,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${YW}Storages Available:${CL}" echo " " @@ -163,7 +166,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " @@ -178,7 +181,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -194,7 +197,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -211,7 +214,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -233,7 +236,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$CT_NAME${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" From 99baec7b05391a7e6f1136076f1ca08f571699fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 15:39:46 -0400 Subject: [PATCH 2000/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 421edc19..c6162ffa 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -115,7 +115,7 @@ header_info echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $APP " + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then HN=$NSAPP From c8b5a592f797137e77e2bbcfd651292dc8e09d94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 15:44:05 -0400 Subject: [PATCH 2001/6505] Update debian-v3.sh --- ct/debian-v3.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index c6162ffa..d310ecd2 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -345,11 +345,6 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF echo -en "${GN} Starting LXC Container... " pct start $CTID From ca997e7ba841adaf88ce686f1ff0a6edf7371001 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 16:20:56 -0400 Subject: [PATCH 2002/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 22c65528..6c18f194 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -10,7 +10,7 @@ GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') - +PVE=$(pveversion | grep "pve-manager/7" | wc -l) while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -33,14 +33,12 @@ ${CL}" header_info -function pve_7() { -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" echo -e "Exiting..." sleep 2 exit fi -} function default_settings() { clear @@ -260,7 +258,7 @@ function start_script() { advanced_settings fi; } -pve_7 + start_script set -o errexit From 512da0f278e32034bba1fa7e1c93f6cf59cf5453 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 16:37:51 -0400 Subject: [PATCH 2003/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 6c18f194..57f9bc76 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -33,12 +33,14 @@ ${CL}" header_info +function PVE_CHECK() { if [[ $PVE != 1 ]]; then echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" echo -e "Exiting..." sleep 2 exit fi +} function default_settings() { clear @@ -259,6 +261,7 @@ function start_script() { fi; } +PVE_CHECK start_script set -o errexit From 58c1d281a07623580e73563f77cf3cba51057ff1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Apr 2022 16:39:57 -0400 Subject: [PATCH 2004/6505] Update debian-v3.sh --- ct/debian-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index d310ecd2..39d35dd4 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -10,7 +10,7 @@ GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Debian" NSAPP=$(echo ${APP,,} | tr -d ' ') - +PVE=$(pveversion | grep "pve-manager/7" | wc -l) while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -33,9 +33,9 @@ ${CL}" header_info -function pve_7() { -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" +function PVE_CHECK() { +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" echo -e "Exiting..." sleep 2 exit From b15bd4d2e5d4097632096f731d0106edb3fa2960 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 07:43:04 -0400 Subject: [PATCH 2005/6505] Update kernel-clean.sh --- misc/kernel-clean.sh | 129 ++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 0561c105..054144fd 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -1,28 +1,29 @@ #!/bin/bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +RED=$(tput setaf 1) +GREEN=$(tput setaf 2) +YELLOW=$(tput setaf 3) +BLUE=$(tput setaf 4) +WHITE=$(tput setaf 7) +NORMAL=$(tput sgr0) while true; do - read -p "This will Clean unused Kernel images. Proceed(y/n)?" yn + read -p "${YELLOW}This will Clean unused Kernel images. Proceed(y/n)?${NORMAL}" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + * ) echo -e "${RED}Please answer y/n${NORMAL}";; esac done clear current_kernel=$(uname -r) +pve=$(pveversion) function check_root { if [[ $EUID -ne 0 ]]; then - printf "[!] Error: this script must be ran as the root user.\n" + echo -e "${RED}Error: This script must be ran as the root user.\n${NORMAL}" exit 1 fi } function header_info { -echo -e "${RD} +echo -e "${RED} _ __ _ _____ _ | |/ / | | / ____| | | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ @@ -30,64 +31,66 @@ echo -e "${RD} | \ __/ | | | | | __/ | | |____| | __/ (_| | | | | |_|\_\___|_| |_| |_|\___|_| \_____|_|\___|\__,_|_| |_| -${CL}" +${NORMAL}" } -function kernel_info { - latest_kernel=$(dpkg --list| grep 'pve-kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) - printf "OS: $(cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $0}')\n" - printf "Current Kernel: pve-kernel-$current_kernel\n" - if [[ "$current_kernel" == *"pve"* ]]; then - if [[ "$latest_kernel" != *"$current_kernel"* ]]; then - printf "Latest Kernel: $latest_kernel\n" - fi +function kernel_info() { + latest_kernel=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) + echo -e "${YELLOW}OS: ${GREEN}$(cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $0}')\r${NORMAL}" + echo -e "${YELLOW}PVE Version: ${GREEN}$pve\n${NORMAL}" + if [[ "$current_kernel" == *"pve"* ]]; then + if [[ "$latest_kernel" != *"$current_kernel"* ]]; then + echo -e "${GREEN}Latest Kernel: $latest_kernel\n${NORMAL}" + fi + else + echo -e "\n${RED}ERROR: No PVE Kernel found\n${NORMAL}" + exit 1 + fi +} + +function kernel_clean() { + kernels=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | sort -V) + kernels_to_remove="" + for kernel in $kernels + do + if [ "$(echo $kernel | grep $current_kernel)" ]; then + break else - printf "___________________________________________\n\n" - printf "[!] Warning, you're not running a PVE Kernel\n" - exit 1 + echo -e "${RED}'$kernel' ${NORMAL}${YELLOW}has been added to the Kernel remove list\n${NORMAL}" + kernels_to_remove+=" $kernel" fi + done +echo -e "${YELLOW}Kernel Search Complete!\n${NORMAL}" + if [[ "$kernels_to_remove" != *"pve"* ]]; then + echo -e "${GREEN}It appears there are no old Kernels on your system \n${NORMAL}" + else + read -p "${YELLOW}Would you like to remove the${RED} $(echo $kernels_to_remove | awk '{print NF}') ${NORMAL}${YELLOW}selected Kernels listed above? [y/n]: ${NORMAL}" -n 1 -r + fi + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "${YELLOW}\nRemoving ${NORMAL}${RED}$(echo $kernels_to_remove | awk '{print NF}') ${NORMAL}${YELLOW}old Kernels...${NORMAL}" + /usr/bin/apt purge -y $kernels_to_remove > /dev/null 2>&1 + echo -e "${YELLOW}Finished!\n${NORMAL}" + echo -e "${YELLOW}Updating GRUB... \n${NORMAL}" + /usr/sbin/update-grub > /dev/null 2>&1 + echo -e "${YELLOW}Finished!\n${NORMAL}" + else + echo -e "${YELLOW}Exiting...\n${NORMAL}" + sleep 1 + fi } -function kernel_clean { - kernels=$(dpkg --list| grep 'pve-kernel-.*-pve' | awk '{print $2}' | sort -V) - kernels_to_remove="" - for kernel in $kernels - do - if [ "$(echo $kernel | grep $current_kernel)" ]; then - break - else - printf "\"$kernel\" has been added to the Kernel remove list\n" - kernels_to_remove+=" $kernel" - fi - done - printf "Kernel Search Complete!\n" - if [[ "$kernels_to_remove" != *"pve"* ]]; then - printf "It appears there are no old Kernels on your system \n" - else - read -p "[!] Would you like to remove the $(echo $kernels_to_remove | awk '{print NF}') selected Kernels listed above? [y/n]: " -n 1 -r - printf "\n" - fi - if [[ $REPLY =~ ^[Yy]$ ]]; then - printf "Removing $(echo $kernels_to_remove | awk '{print NF}') old Kernels..." - /usr/bin/apt purge -y $kernels_to_remove > /dev/null 2>&1 - printf "Finished!\n" - printf "Updating GRUB... \n" - /usr/sbin/update-grub > /dev/null 2>&1 - printf "Finished!\n" - else - printf "\nExiting...\n" - fi -} -function main { - check_root - header_info - kernel_info + +function main() { + check_root + header_info + kernel_info } + while true; do - case "$1" in - * ) - main - kernel_clean - exit 1 - ;; + case "$1" in + * ) + main + kernel_clean + exit 1 + ;; esac - shift + shift done From 3bc13746d9cb43a228ae9f29c1b69edf47f2ead6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 07:44:27 -0400 Subject: [PATCH 2006/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 57f9bc76..b6e3493b 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -55,13 +55,13 @@ function default_settings() { echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP echo -e "${GN}Using Disk Size ${BGN}16GB${CL}" - SIZEDISK="2" + SIZEDISK="16" echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" STORAGETYPE="local-lvm" echo -e "${GN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="1" + CORE_COUNT="2" echo -e "${GN}Using ${BGN}4096MiB${CL}${GN} RAM${CL}" - RAM_SIZE="512" + RAM_SIZE="4096" echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" From 778a9a69c79b32f3d50d467f3390471b2cc65524 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 07:46:20 -0400 Subject: [PATCH 2007/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index b6e3493b..a9dafaa0 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -60,8 +60,8 @@ function default_settings() { STORAGETYPE="local-lvm" echo -e "${GN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${GN}Using ${BGN}4096MiB${CL}${GN} RAM${CL}" - RAM_SIZE="4096" + echo -e "${GN}Using ${BGN}2048MiB${CL}${GN} RAM${CL}" + RAM_SIZE="2048" echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" @@ -185,9 +185,9 @@ header_info echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" echo -e " ${CM}${CL} \n" sleep 1 From 9afc160cc55931be1caf59096145651569e6ee90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 07:49:24 -0400 Subject: [PATCH 2008/6505] Create zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 378 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 ct/zigbee2mqtt-v3.sh diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh new file mode 100644 index 00000000..65be63b1 --- /dev/null +++ b/ct/zigbee2mqtt-v3.sh @@ -0,0 +1,378 @@ +#!/usr/bin/env bash +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +BGN=`echo "\033[4;92m"` +GN=`echo "\033[32m"` +CL=`echo "\033[m"` +APP="Zigbee2MQTT" +NSAPP=$(echo ${APP,,} | tr -d ' ') +PVE=$(pveversion | grep "pve-manager/7" | wc -l) +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _______ _ ___ __ __ ____ _______ _______ + |___ (_) | | |__ \| \/ |/ __ \__ __|__ __| + / / _ __ _| |__ ___ ___ ) | \ / | | | | | | | | + / / | |/ _ | _ \ / _ \/ _ \ / /| |\/| | | | | | | | | + / /__| | (_| | |_) | __/ __// /_| | | | |__| | | | | | + /_____|_|\__, |____/ \___|\___|____|_| |_|\___\_\ |_| |_| + v3 __/ | + |___/ +${CL}" +} + +header_info +function pve_check() { +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" + echo -e "Exiting..." + sleep 2 + exit +fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${GN}Using Disk Size ${BGN}4GB${CL}" + SIZEDISK="4" + echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" + STORAGETYPE="local-lvm" + echo -e "${GN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${GN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${GN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${GN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${GN}Set CT Password ${BL}$PW1${CL}" + + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${GN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read SIZEDISK + if [ -z $SIZEDISK ]; then SIZEDISK="4"; fi; + if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${YW}Storages Available:${CL}" + echo " " + for stg in `pvesh get storage --noborder --noheader` + do + echo -e "${BL} - ${stg}${CL}" + done + echo " " + echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " + read STORAGETYPE + if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; + echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${GN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" + echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} +pve_check +start_script + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$SIZEDISK +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" From 55a211c0e599f67edcd2e7e863e479ca924b2dc9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 08:11:50 -0400 Subject: [PATCH 2009/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 65be63b1..87b38d47 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -47,8 +47,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${GN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" @@ -73,14 +73,14 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Privileged " read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${GN}Set CT Type ${BL}Privileged${CL}" + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${GN}Set CT Type ${BL}Unprivileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 From 714de2f2c49fb97c1582e3bca2b69bc65499c476 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 08:18:00 -0400 Subject: [PATCH 2010/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 87b38d47..432fbd17 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -73,7 +73,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Privileged " + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged " read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" @@ -310,7 +310,7 @@ function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } - if [ "$IM" == "1" ]; then + if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" From c0867fb73cb7f722a2410be5fb95fcb3996aa0d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 08:24:27 -0400 Subject: [PATCH 2011/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 432fbd17..c36c2bb5 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -10,7 +10,7 @@ GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Zigbee2MQTT" NSAPP=$(echo ${APP,,} | tr -d ' ') -PVE=$(pveversion | grep "pve-manager/7" | wc -l) + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -35,6 +35,7 @@ ${CL}" header_info function pve_check() { +PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" echo -e "Exiting..." @@ -261,7 +262,7 @@ function start_script() { advanced_settings fi; } -pve_check +#pve_check start_script set -o errexit From 9d6186d4e94f4771bac7541feadb996f7a541d03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 08:27:38 -0400 Subject: [PATCH 2012/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index a9dafaa0..4e100ff6 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -10,7 +10,7 @@ GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') -PVE=$(pveversion | grep "pve-manager/7" | wc -l) + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -34,6 +34,7 @@ ${CL}" header_info function PVE_CHECK() { +PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" echo -e "Exiting..." From 798cf374a875a919a6dbc34c618cfc08526ecabc Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 08:32:34 -0400 Subject: [PATCH 2013/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index c36c2bb5..803456d1 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -76,12 +76,13 @@ function advanced_settings() { echo -e "${RD}Using Advanced Settings${CL}" echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged " read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" + CT_TYPE="0" echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Unprivileged" CT_TYPE="1" - echo -en "${GN}Set CT Type ${BL}Unprivileged${CL}" + echo -en "${GN}Set CT Type ${BL}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 From 39ef2b7d10bfe46d8efb816939493efe42e8b515 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 08:38:01 -0400 Subject: [PATCH 2014/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 803456d1..eefa163f 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -263,7 +263,7 @@ function start_script() { advanced_settings fi; } -#pve_check +pve_check start_script set -o errexit From e754ffc82ef57d4e1c532e4ee4a49ef4ae288c09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 13:19:42 -0400 Subject: [PATCH 2015/6505] Update kernel-clean.sh --- misc/kernel-clean.sh | 58 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 054144fd..9f534d1c 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -1,29 +1,33 @@ #!/bin/bash -RED=$(tput setaf 1) -GREEN=$(tput setaf 2) -YELLOW=$(tput setaf 3) -BLUE=$(tput setaf 4) -WHITE=$(tput setaf 7) -NORMAL=$(tput sgr0) +RD=$(tput setaf 1) +GN=$(tput setaf 2) +LYW=$(tput setaf 190) +WH=$(tput setaf 7) +BRT=$(tput bold) +CL=$(tput sgr0) +UL=$(tput smul) +current_kernel=$(uname -r) +pve=$(pveversion) + while true; do - read -p "${YELLOW}This will Clean unused Kernel images. Proceed(y/n)?${NORMAL}" yn + read -p "${WH}This will Clean unused Kernel images. Proceed(y/n)?${CL}" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; - * ) echo -e "${RED}Please answer y/n${NORMAL}";; + * ) echo -e "${RD}Please answer y/n${CL}";; esac done clear -current_kernel=$(uname -r) -pve=$(pveversion) + function check_root { if [[ $EUID -ne 0 ]]; then - echo -e "${RED}Error: This script must be ran as the root user.\n${NORMAL}" + echo -e "${RD}Error: This script must be ran as the root user.\n${CL}" exit 1 fi } + function header_info { -echo -e "${RED} +echo -e "${RD} _ __ _ _____ _ | |/ / | | / ____| | | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ @@ -31,18 +35,18 @@ echo -e "${RED} | \ __/ | | | | | __/ | | |____| | __/ (_| | | | | |_|\_\___|_| |_| |_|\___|_| \_____|_|\___|\__,_|_| |_| -${NORMAL}" +${CL}" } + function kernel_info() { latest_kernel=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) - echo -e "${YELLOW}OS: ${GREEN}$(cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $0}')\r${NORMAL}" - echo -e "${YELLOW}PVE Version: ${GREEN}$pve\n${NORMAL}" + echo -e "${LYW}PVE Version: ${UL}${WH}$pve\n${CL}" if [[ "$current_kernel" == *"pve"* ]]; then if [[ "$latest_kernel" != *"$current_kernel"* ]]; then - echo -e "${GREEN}Latest Kernel: $latest_kernel\n${NORMAL}" + echo -e "${GN}Latest Kernel: $latest_kernel\n${CL}" fi else - echo -e "\n${RED}ERROR: No PVE Kernel found\n${NORMAL}" + echo -e "\n${RD}ERROR: No PVE Kernel found\n${CL}" exit 1 fi } @@ -55,26 +59,26 @@ function kernel_clean() { if [ "$(echo $kernel | grep $current_kernel)" ]; then break else - echo -e "${RED}'$kernel' ${NORMAL}${YELLOW}has been added to the Kernel remove list\n${NORMAL}" + echo -e "${RD}'$kernel' ${CL}${LYW}has been added to the Kernel remove list\n${CL}" kernels_to_remove+=" $kernel" fi done -echo -e "${YELLOW}Kernel Search Complete!\n${NORMAL}" +echo -e "${LYW}Kernel Search Complete!\n${CL}" if [[ "$kernels_to_remove" != *"pve"* ]]; then - echo -e "${GREEN}It appears there are no old Kernels on your system \n${NORMAL}" + echo -e "${BRT}${GN}It appears there are no old Kernels on your system. \n${CL}" else - read -p "${YELLOW}Would you like to remove the${RED} $(echo $kernels_to_remove | awk '{print NF}') ${NORMAL}${YELLOW}selected Kernels listed above? [y/n]: ${NORMAL}" -n 1 -r + read -p "${LYW}Would you like to remove the${RD} $(echo $kernels_to_remove | awk '{print NF}') ${CL}${LYW}selected Kernels listed above? [y/n]: ${CL}" -n 1 -r fi if [[ $REPLY =~ ^[Yy]$ ]]; then - echo -e "${YELLOW}\nRemoving ${NORMAL}${RED}$(echo $kernels_to_remove | awk '{print NF}') ${NORMAL}${YELLOW}old Kernels...${NORMAL}" + echo -e "${LYW}\nRemoving ${CL}${RD}$(echo $kernels_to_remove | awk '{print NF}') ${CL}${LYW}old Kernels...${CL}" /usr/bin/apt purge -y $kernels_to_remove > /dev/null 2>&1 - echo -e "${YELLOW}Finished!\n${NORMAL}" - echo -e "${YELLOW}Updating GRUB... \n${NORMAL}" + echo -e "${LYW}Finished!\n${CL}" + echo -e "${LYW}Updating GRUB... \n${CL}" /usr/sbin/update-grub > /dev/null 2>&1 - echo -e "${YELLOW}Finished!\n${NORMAL}" + echo -e "${LYW}Finished!\n${CL}" else - echo -e "${YELLOW}Exiting...\n${NORMAL}" - sleep 1 + echo -e "${LYW}Exiting...\n${CL}" + sleep 2 fi } From 16a8d14dad6a60305c907e2e9549f1d4fa72c202 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 13:24:43 -0400 Subject: [PATCH 2016/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index eefa163f..78efaead 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -353,19 +353,6 @@ lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create= lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 8841ec39ad0a6f6a6d8eb8267826b541e5e6925c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 14:20:56 -0400 Subject: [PATCH 2017/6505] Update debian-v3.sh --- ct/debian-v3.sh | 56 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 39d35dd4..1bc670fe 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -56,8 +56,8 @@ function default_settings() { HN=$NSAPP echo -e "${GN}Using Disk Size ${BGN}2GB${CL}" SIZEDISK="2" - echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" - STORAGETYPE="local-lvm" +# echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" +# STORAGETYPE="local-lvm" echo -e "${GN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" echo -e "${GN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" @@ -141,34 +141,34 @@ echo -e " ${CM}${CL} \r" sleep 1 clear header_info +# echo -e "${RD}Using Advanced Settings${CL}" +# echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" +# echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" +# echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" +# echo -e "${GN}Using CT Name ${BGN}$HN${CL}" +# echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" +# echo -e "${YW}Storages Available:${CL}" +# echo " " +# for stg in `pvesh get storage --noborder --noheader` +# do +# echo -e "${BL} - ${stg}${CL}" +# done +# echo " " +# echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " +# read STORAGETYPE +# if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; +# echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" +#echo -e " ${CM}${CL} \r" +#sleep 1 +#clear +#header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${YW}Storages Available:${CL}" - echo " " - for stg in `pvesh get storage --noborder --noheader` - do - echo -e "${BL} - ${stg}${CL}" - done - echo " " - echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " - read STORAGETYPE - if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; - echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" +# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; @@ -183,7 +183,7 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" +# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE @@ -199,7 +199,7 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" +# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " @@ -216,7 +216,7 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" +# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" @@ -238,7 +238,7 @@ header_info echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" echo -e "${GN}Using CT Name ${BGN}$HN${CL}" echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" +# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${GN}Using IP Address ${BGN}$NET${CL}" From a753cbf12cca113e64cded60e609b703c07341fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 14:39:21 -0400 Subject: [PATCH 2018/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 622a77b4..3e7149c7 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -26,7 +26,7 @@ CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' -GN=`echo "\033[32m"` +GN=`echo "\033[1;92m"` CL=`echo "\033[m"` RETRY_NUM=10 RETRY_EVERY=3 From c556ab569ca88f8ff81cd75850148a53b0902571 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 14:58:46 -0400 Subject: [PATCH 2019/6505] Update debian-v3.sh --- ct/debian-v3.sh | 276 ++++++++++++++++++++++-------------------------- 1 file changed, 124 insertions(+), 152 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 1bc670fe..4528b371 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -10,7 +10,6 @@ GN=`echo "\033[32m"` CL=`echo "\033[m"` APP="Debian" NSAPP=$(echo ${APP,,} | tr -d ' ') -PVE=$(pveversion | grep "pve-manager/7" | wc -l) while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -34,30 +33,30 @@ ${CL}" header_info function PVE_CHECK() { -if [[ $PVE != 1 ]]; then + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" echo -e "Exiting..." sleep 2 exit -fi + fi } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP echo -e "${GN}Using Disk Size ${BGN}2GB${CL}" - SIZEDISK="2" -# echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" -# STORAGETYPE="local-lvm" + DISK_SIZE="2" echo -e "${GN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" echo -e "${GN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" @@ -65,184 +64,157 @@ function default_settings() { echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN=" " } function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${GN}Set CT Type ${BL}Privileged${CL}" - fi; + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${GN}Set CT Type ${BL}Privileged${CL}" + fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${GN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${GN}Set CT Password ${BL}$PW1${CL}" - - fi; + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${GN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${GN}Set CT Password ${BL}$PW1${CL}" + fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${GN}Set CT Name To ${BL}$HN${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${GN}Set CT Name To ${BL}$HN${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " - read SIZEDISK - if [ -z $SIZEDISK ]; then SIZEDISK="2"; fi; - if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${GN}Set Disk Size To ${BL}$DISK_SIZE${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info -# echo -e "${RD}Using Advanced Settings${CL}" -# echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" -# echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" -# echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" -# echo -e "${GN}Using CT Name ${BGN}$HN${CL}" -# echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" -# echo -e "${YW}Storages Available:${CL}" -# echo " " -# for stg in `pvesh get storage --noborder --noheader` -# do -# echo -e "${BL} - ${stg}${CL}" -# done -# echo " " -# echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " -# read STORAGETYPE -# if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; -# echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" -#echo -e " ${CM}${CL} \r" -#sleep 1 -#clear -#header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" -# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" -# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" -# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${GN}Set IP Address To ${BL}$NET${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${GN}Set IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" -# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN="-tag $VLAN1" - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" -# echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" - echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -327,7 +299,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$CT_ID export PCT_OSTYPE=debian export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$SIZEDISK +export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN From 42797e88458fbad847919a9f9239ffacf1f22713 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 16:06:35 -0400 Subject: [PATCH 2020/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ade9a08b..64ac58fa 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    Select a Proxmox Helper

    🔸 From 7ee3420756a6771d2d0e5930d7545229891d66b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 16:10:42 -0400 Subject: [PATCH 2021/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64ac58fa..c4e984d3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    +

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    Select a Proxmox Helper

    🔸 From d03d9ea7b79e24358216d2dabebf116d77ffe481 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 16:13:38 -0400 Subject: [PATCH 2022/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4e984d3..9f7d85b9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    Select a Proxmox Helper

    +

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    🔸 From 9db3d8ad408bd4e633a81c0336cbe70891e92eb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Apr 2022 18:10:17 -0400 Subject: [PATCH 2023/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f7d85b9..7a9fa723 100644 --- a/README.md +++ b/README.md @@ -737,7 +737,7 @@ ________________________________________________________________________________
    - 🔸NocoDB LXC + NocoDB LXC

    From 27dd16a103a1bdc542b52339ec99df43581a12d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:12:04 -0400 Subject: [PATCH 2024/6505] Update debian-install.sh --- setup/debian-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 3e7149c7..4d84d480 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 04d863a474dff05437d5874e620dfa64949caa8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:18:33 -0400 Subject: [PATCH 2025/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 4528b371..c5022af6 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -4,10 +4,10 @@ INTEGER='^[0-9]+$' YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' BGN=`echo "\033[4;92m"` GN=`echo "\033[32m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" APP="Debian" NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do From 59922332fdae2b446f0bd068ad362ca328302815 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:21:54 -0400 Subject: [PATCH 2026/6505] Update create_lxc.sh --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 509a73d4..a27b11bd 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -8,9 +8,9 @@ shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" trap die ERR function error_exit() { From 4267666368f13ccdd7e6214973f1a43386b7dfab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:23:41 -0400 Subject: [PATCH 2027/6505] Update adguard-install.sh --- setup/adguard-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index a920546f..91e09ab3 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From eeacdc1d44058f6285cdb4662e30ac34c23d1766 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:24:40 -0400 Subject: [PATCH 2028/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 077c9f91..bce69f48 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From c7f83b318b767c28fee0a40ec5dc36925b9f7d8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:25:36 -0400 Subject: [PATCH 2029/6505] Update dashy-install.sh --- setup/dashy-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 003b87c1..ddbf0864 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 430b2f218cc7595cc913ce96da68d38c35a75c22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:26:38 -0400 Subject: [PATCH 2030/6505] Update docker-install.sh --- setup/docker-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 71a038c1..f2a7081c 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 43e031a9f823112c6d0f4ad1cb667891ed2d6aee Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:27:14 -0400 Subject: [PATCH 2031/6505] Update esphome-install.sh --- setup/esphome-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 6311925e..24e23f72 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From d3ce05c712b88c1456924959abcd0d175b263030 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:27:45 -0400 Subject: [PATCH 2032/6505] Update grafana-install.sh --- setup/grafana-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index e683a417..7dc47536 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 5196ca95380658910a85b6b85f17c3e9ab7747a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:28:11 -0400 Subject: [PATCH 2033/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 56b7fb5a..74f120bd 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From b465b62f980174434f2112593c498a1ca326a7dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:28:39 -0400 Subject: [PATCH 2034/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index a9814b81..56059107 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From df878688d9086f6db4042b37ef178c6b60cf6a43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:29:15 -0400 Subject: [PATCH 2035/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 61c8178e..7f9f289e 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From e76087547bef0ef07749b6be303cac498b8ddc3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:29:39 -0400 Subject: [PATCH 2036/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 6f592dda..220f9bae 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 577a96ffcfb6cb82a2a594ed5bafe50ad13bf3ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:30:17 -0400 Subject: [PATCH 2037/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index d8cec842..e4cb0062 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 286ae9671752ffe1a63dd3f3f089ce2f699a6ac0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:30:52 -0400 Subject: [PATCH 2038/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index c9103f34..13ec017e 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 3d8011f1ca41ef380228054cd597d92edf482755 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:31:27 -0400 Subject: [PATCH 2039/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 8a8393e9..c1564884 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 76be96005a368676fb6c128e8ecc6a6135f5133b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:31:52 -0400 Subject: [PATCH 2040/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 59202b35..d96fac5a 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From b9e7fb6cbb8369742ab28fa2c02a6adb960b5530 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:32:19 -0400 Subject: [PATCH 2041/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 00df49be..3708a726 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From c6fa21538b9f5116e13846251b81531f0f0127b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:32:48 -0400 Subject: [PATCH 2042/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 9d51169a..32a5e0c1 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 2c93140df7e1ee1916e6680b37e880849b66e880 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:33:50 -0400 Subject: [PATCH 2043/6505] Update node-red-install.sh --- setup/node-red-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index f68c5e32..7bf0de50 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -22,15 +22,16 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM + echo -en "${GN} Setting up Container OS... " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null From 9e2b18a92cdfa5baae82c229ca2500b666023e36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:34:22 -0400 Subject: [PATCH 2044/6505] Update omada-install.sh --- setup/omada-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index f4587b2c..52edef5c 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From bd61ad6529c067dfb96f0d91f8aaa4828d515dfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:35:03 -0400 Subject: [PATCH 2045/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 08596b5c..5ef65f42 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -21,12 +21,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 99605baaf2ec7c6a35583b201c297979e2314cf5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:40:15 -0400 Subject: [PATCH 2046/6505] Update kernel-clean.sh --- misc/kernel-clean.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 9f534d1c..9a883003 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -46,32 +46,32 @@ function kernel_info() { echo -e "${GN}Latest Kernel: $latest_kernel\n${CL}" fi else - echo -e "\n${RD}ERROR: No PVE Kernel found\n${CL}" + echo -e "\n${RD}ERROR: No PVE Kernel Found\n${CL}" exit 1 fi } function kernel_clean() { kernels=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | sort -V) - kernels_to_remove="" + remove_kernels="" for kernel in $kernels do if [ "$(echo $kernel | grep $current_kernel)" ]; then break else - echo -e "${RD}'$kernel' ${CL}${LYW}has been added to the Kernel remove list\n${CL}" - kernels_to_remove+=" $kernel" + echo -e "${RD}'$kernel' ${CL}${LYW}has been added to the remove Kernel list\n${CL}" + remove_kernels+=" $kernel" fi done echo -e "${LYW}Kernel Search Complete!\n${CL}" - if [[ "$kernels_to_remove" != *"pve"* ]]; then + if [[ "$remove_kernels" != *"pve"* ]]; then echo -e "${BRT}${GN}It appears there are no old Kernels on your system. \n${CL}" else - read -p "${LYW}Would you like to remove the${RD} $(echo $kernels_to_remove | awk '{print NF}') ${CL}${LYW}selected Kernels listed above? [y/n]: ${CL}" -n 1 -r + read -p "${LYW}Would you like to remove the${RD} $(echo $remove_kernels | awk '{print NF}') ${CL}${LYW}selected Kernels listed above? [y/n]: ${CL}" -n 1 -r fi if [[ $REPLY =~ ^[Yy]$ ]]; then - echo -e "${LYW}\nRemoving ${CL}${RD}$(echo $kernels_to_remove | awk '{print NF}') ${CL}${LYW}old Kernels...${CL}" - /usr/bin/apt purge -y $kernels_to_remove > /dev/null 2>&1 + echo -e "${LYW}\nRemoving ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${LYW}old Kernels...${CL}" + /usr/bin/apt purge -y $remove_kernels > /dev/null 2>&1 echo -e "${LYW}Finished!\n${CL}" echo -e "${LYW}Updating GRUB... \n${CL}" /usr/sbin/update-grub > /dev/null 2>&1 From 2cbb8f15dbd384ccadfe2864ac4a7cae827becb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:40:42 -0400 Subject: [PATCH 2047/6505] Update pihole-install.sh --- setup/pihole-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 74eae09a..29b0721a 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From dd3c4b390b47e99378086203fc13f95a79a62188 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:41:12 -0400 Subject: [PATCH 2048/6505] Update technitiumdns-install.sh --- setup/technitiumdns-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 3f258dce..525ed33b 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 4d9f1502779c966482050b588caaee23ed7a3778 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:41:38 -0400 Subject: [PATCH 2049/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index c3bbca0f..3ba3ae2f 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 7e6fd2effb12d6fab41e0d5a9b06a6ef531a3812 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:42:13 -0400 Subject: [PATCH 2050/6505] Update unifi-install.sh --- setup/unifi-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index f469df2d..3c00fe08 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 3cb61ff7cb4ab991b3ad5efead87c1ac925b2eac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:42:44 -0400 Subject: [PATCH 2051/6505] Update uptimekuma-install.sh --- setup/uptimekuma-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 5c41ff6c..cdb110ab 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 978331001e8e2791c9d27f132913800c93035820 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:43:20 -0400 Subject: [PATCH 2052/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 09e1c824..ce9d60e2 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -22,13 +22,13 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=5 +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 3a838e91d749f9c14d2c640025964ab564f1154a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:43:45 -0400 Subject: [PATCH 2053/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 037a5eb6..194b7f0c 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From bb396b06017ff7bb68bac846abac7eb4864884a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:44:11 -0400 Subject: [PATCH 2054/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index d0a50072..e752e3b8 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 4c6bd1a66c8e79a27fff87d76d682a472d330d59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 07:44:41 -0400 Subject: [PATCH 2055/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 7c5aaa19..ca1f71d0 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -22,12 +22,12 @@ function msg() { echo -e "$TEXT" } -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM From 8365c6eb60ceb66428fd7c796ffd48a628223b45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 09:31:31 -0400 Subject: [PATCH 2056/6505] Update debian-install.sh --- setup/debian-install.sh | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 4d84d480..45fa3716 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -22,17 +22,31 @@ function msg() { echo -e "$TEXT" } +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` +OVER="\\r\\033[K" GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="[-]" -echo -en "${GN} Setting up Container OS... " +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,23 +59,22 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Setting up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updating Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installing Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -74,11 +87,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customizing Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleanup" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleanup" From 66ffaf1aa93a5afd518ed6b180d0c1ec7633ce83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 09:36:09 -0400 Subject: [PATCH 2057/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 45fa3716..c2707367 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -38,7 +38,7 @@ HOLD="[-]" msg_info() { local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + echo -ne " ${HOLD} ${YW}${msg}..." } msg_ok() { From cfa2ab2bda5e2b43fd359dbe8fa4a6446dc633b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 09:40:27 -0400 Subject: [PATCH 2058/6505] Update debian-v3.sh --- ct/debian-v3.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index c5022af6..6cdf3f29 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -7,6 +7,8 @@ RD=`echo "\033[01;31m"` BGN=`echo "\033[4;92m"` GN=`echo "\033[32m"` CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="[-]" CM="${GN}✓${CL}" APP="Debian" NSAPP=$(echo ${APP,,} | tr -d ' ') @@ -32,6 +34,16 @@ ${CL}" header_info +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) @@ -318,9 +330,9 @@ if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." fi -echo -en "${GN} Starting LXC Container... " +msg_info "Starting LXC Container" pct start $CTID -echo -e "${CM}${CL} \r" +msg_ok "Starting LXC Container" alias lxc-cmd="lxc-attach -n $CTID --" From b907db97f2eb4f0d8bf5bdb6376f05fb2d0ac75f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 09:52:57 -0400 Subject: [PATCH 2059/6505] Update create_lxc.sh --- ct/create_lxc.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index a27b11bd..ed4a114b 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -11,8 +11,20 @@ RD=`echo "\033[01;31m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` CM="${GN}✓${CL}" +BFR="\\r\\033[K" +HOLD="[-]" trap die ERR +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + function error_exit() { trap - ERR local DEFAULT='Unknown failure occured.' @@ -92,9 +104,9 @@ info "Using ${BL}$TEMPLATE_STORAGE${CL} for Template Storage." CONTAINER_STORAGE=$(select_storage container) || exit info "Using ${BL}$CONTAINER_STORAGE${CL} for Container Storage." -echo -en "${GN} Updating LXC Template List... " +msg_info "Updating LXC Template List" pveam update >/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updating LXC Template List" TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) @@ -102,8 +114,8 @@ mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLA TEMPLATE="${TEMPLATES[-1]}" if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - echo -en "${GN} Downloading LXC Template... " - echo -e "${CM}${CL} \r" + msg_info "Downloading LXC Template" + msg_ok "Downloading LXC Template" pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." fi From 102fbc3ce8d0b9469a9dc9b0d9c2c55966e6776f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 09:55:27 -0400 Subject: [PATCH 2060/6505] Update create_lxc.sh --- ct/create_lxc.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index ed4a114b..c9756899 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -6,6 +6,7 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' +YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` GN=`echo "\033[1;92m"` From 054b207ffe472bed377555b3a7f2f60fbfa77915 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 09:59:57 -0400 Subject: [PATCH 2061/6505] Update create_lxc.sh --- ct/create_lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index c9756899..31fd6bb5 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -16,12 +16,12 @@ BFR="\\r\\033[K" HOLD="[-]" trap die ERR -msg_info() { +function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } -msg_ok() { +function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } From 76a662e837fcc75a09c267cf66ba5a1155c88acb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:01:33 -0400 Subject: [PATCH 2062/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 6cdf3f29..1a161d69 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -34,12 +34,12 @@ ${CL}" header_info -msg_info() { +function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } -msg_ok() { +function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } From 735822d6dab3a38f317299f684b335d5b688be13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:02:12 -0400 Subject: [PATCH 2063/6505] Update debian-install.sh --- setup/debian-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index c2707367..ef6af938 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -36,12 +36,12 @@ CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="[-]" -msg_info() { +function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } -msg_ok() { +function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } From 9e0fb19df28b357c3f714909acd7c503cc3cc0c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:05:03 -0400 Subject: [PATCH 2064/6505] Update create_lxc.sh --- ct/create_lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 31fd6bb5..06570df1 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -127,8 +127,8 @@ DEFAULT_PCT_OPTIONS=( PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) [[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) -echo -en "${GN} Creating LXC Container... " +msg_info "Creating LXC Container" pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -echo -e "${CM}${CL} \r" +msg_ok "Creating LXC Container" info "LXC Container ${BL}$CTID${CL} was successfully created." From d8ebbc568b1042ac06ec32fdc898c0192eaed928 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:11:31 -0400 Subject: [PATCH 2065/6505] Update create_lxc.sh --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 06570df1..54068e9d 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -13,7 +13,7 @@ GN=`echo "\033[1;92m"` CL=`echo "\033[m"` CM="${GN}✓${CL}" BFR="\\r\\033[K" -HOLD="[-]" +HOLD="-" trap die ERR function msg_info() { From 75126ff6016bf269280c63715b75864f48ad8c3a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:12:13 -0400 Subject: [PATCH 2066/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 1a161d69..00046aec 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -8,7 +8,7 @@ BGN=`echo "\033[4;92m"` GN=`echo "\033[32m"` CL=`echo "\033[m"` BFR="\\r\\033[K" -HOLD="[-]" +HOLD="-" CM="${GN}✓${CL}" APP="Debian" NSAPP=$(echo ${APP,,} | tr -d ' ') From 61dab4d64ae399740c36e78e66f94a5bf905dad2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:12:49 -0400 Subject: [PATCH 2067/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index ef6af938..c58b9a6f 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -34,7 +34,7 @@ NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" -HOLD="[-]" +HOLD="-" function msg_info() { local msg="$1" From 65b4364db0f1d1c39ff214f044313fe89ba2ad8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:31:42 -0400 Subject: [PATCH 2068/6505] Update debian-v3.sh --- ct/debian-v3.sh | 135 ++++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 00046aec..6a94126f 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -5,7 +5,8 @@ YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` BGN=`echo "\033[4;92m"` -GN=`echo "\033[32m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" @@ -59,23 +60,23 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID - echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP - echo -e "${GN}Using Disk Size ${BGN}2GB${CL}" + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" DISK_SIZE="2" - echo -e "${GN}Using ${BGN}1vCPU${CL}" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" - echo -e "${GN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" RAM_SIZE="512" - echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN=" " } @@ -86,45 +87,45 @@ function advanced_settings() { echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Privileged" CT_TYPE="0" - echo -en "${GN}Set CT Type ${BL}Privileged${CL}" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " read PW1 if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${GN}Set CT ${BL}$PW1${CL}" + echo -en "${DGN}Set CT ${BL}$PW1${CL}" else PW="-password $PW1" - echo -en "${GN}Set CT Password ${BL}$PW1${CL}" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " read CT_ID if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -132,101 +133,101 @@ header_info else HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - echo -en "${GN}Set CT Name To ${BL}$HN${CL}" + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${GN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${GN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN="-tag $VLAN1" - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" - echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo From 0679a2f060d18aa78506fabab5675950701501dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 10:56:28 -0400 Subject: [PATCH 2069/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 313 +++++++++++++++++++---------------------- 1 file changed, 148 insertions(+), 165 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 4e100ff6..9ef4eb38 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -4,13 +4,15 @@ INTEGER='^[0-9]+$' YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' BGN=`echo "\033[4;92m"` -GN=`echo "\033[32m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" APP="Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') - while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -33,217 +35,199 @@ ${CL}" header_info +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + function PVE_CHECK() { -PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" echo -e "Exiting..." sleep 2 exit -fi + fi } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID - echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP - echo -e "${GN}Using Disk Size ${BGN}16GB${CL}" - SIZEDISK="16" - echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" - STORAGETYPE="local-lvm" - echo -e "${GN}Using ${BGN}2vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}16GB${CL}" + DISK_SIZE="16" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${GN}Using ${BGN}2048MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${GN} RAM${CL}" RAM_SIZE="2048" - echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${GN}Set CT Type ${BL}Privileged${CL}" - fi; + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${GN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${GN}Set CT Password ${BL}$PW1${CL}" - - fi; + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${GN}Set CT Name To ${BL}$HN${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " - read SIZEDISK - if [ -z $SIZEDISK ]; then SIZEDISK="16"; fi; - if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="16"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${YW}Storages Available:${CL}" - echo " " - for stg in `pvesh get storage --noborder --noheader` - do - echo -e "${BL} - ${stg}${CL}" - done - echo " " - echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " - read STORAGETYPE - if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; - echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${GN}Set IP Address To ${BL}$NET${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN="-tag $VLAN1" - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" - echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -262,7 +246,6 @@ function start_script() { fi; } -PVE_CHECK start_script set -o errexit @@ -329,7 +312,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$CT_ID export PCT_OSTYPE=debian export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$SIZEDISK +export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN @@ -353,9 +336,9 @@ lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF -echo -en "${GN} Starting LXC Container... " +msg_info "Starting LXC Container" pct start $CTID -echo -e "${CM}${CL} \r" +msg_ok "Starting LXC Container" alias lxc-cmd="lxc-attach -n $CTID --" From e6297b88a1862dae328af292caeb5e9d78cfa00a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:16:14 -0400 Subject: [PATCH 2070/6505] Update debian-install.sh --- setup/debian-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index c58b9a6f..001b4ccf 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -25,7 +25,6 @@ function msg() { YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -OVER="\\r\\033[K" GN=`echo "\033[1;92m"` CL=`echo "\033[m"` RETRY_NUM=10 From 792c41dfd97ba5c718dc1d1fa966d63eaa04f799 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:18:00 -0400 Subject: [PATCH 2071/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 68 ++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 56059107..bc17a233 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -22,17 +22,30 @@ function msg() { echo -e "$TEXT" } +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,23 +58,22 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Setting up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updating Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installing Dependencies" -echo -en "${GN} Installing pip3... " +msg_info "Installing pip3" apt-get install -y python3-pip &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installing pip3" get_latest_release() { curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 @@ -71,7 +83,7 @@ DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") -echo -en "${GN} Installing Docker $DOCKER_LATEST_VERSION... " +msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) cat >$DOCKER_CONFIG_PATH <<'EOF' @@ -80,13 +92,13 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' } EOF sh <(curl -sSL https://get.docker.com) &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installing Docker $DOCKER_LATEST_VERSION" -echo -en "${GN} Pulling Portainer $PORTAINER_LATEST_VERSION Image... " +msg_info "Pulling Portainer $PORTAINER_LATEST_VERSION Image" docker pull portainer/portainer-ce:latest &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Pulling Portainer $PORTAINER_LATEST_VERSION Image" -echo -en "${GN} Installing Portainer $PORTAINER_LATEST_VERSION... " +msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null docker run -d \ -p 8000:8000 \ @@ -96,13 +108,13 @@ docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installing Portainer $PORTAINER_LATEST_VERSION" -echo -en "${GN} Pulling Home Assistant $CORE_LATEST_VERSION Image... " +msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" docker pull homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Pulling Home Assistant $CORE_LATEST_VERSION Image" -echo -en "${GN} Installing Home Assistant $CORE_LATEST_VERSION... " +msg_info "Installing Home Assistant $CORE_LATEST_VERSION" docker volume create hass_config >/dev/null docker run -d \ --name homeassistant \ @@ -114,9 +126,9 @@ docker run -d \ -v /etc/localtime:/etc/localtime:ro \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installing Home Assistant $CORE_LATEST_VERSION" -echo -en "${GN} Creating Update Menu Script... " +msg_info "Creating Update Menu Script" pip3 install runlike &>/dev/null UPDATE_PATH='/root/update' UPDATE_CONTAINERS_PATH='/root/update-containers.sh' @@ -297,11 +309,11 @@ for container in ${CONTAINER_LIST}; do done EOF sudo chmod +x /root/update-containers.sh -echo -e "${CM}${CL} \r" +msg_ok "Creating Update Menu Script" mkdir /root/hass_config PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -314,11 +326,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customizing Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleanup" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_info "Cleanup" From b6afdd8ac228d4f11cb267ee630e2fb668cf04c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:30:58 -0400 Subject: [PATCH 2072/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 6a94126f..1706e7c4 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -333,7 +333,7 @@ fi msg_info "Starting LXC Container" pct start $CTID -msg_ok "Starting LXC Container" +msg_ok "Started LXC Container" alias lxc-cmd="lxc-attach -n $CTID --" From 4eea0b5f90b14bc7419d3fb9a3da15ce97d135b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:36:49 -0400 Subject: [PATCH 2073/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index bc17a233..a27d5f8d 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -58,22 +58,22 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -msg_ok "Setting up Container OS" +msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -msg_ok "Updating Container OS" +msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -msg_ok "Installing Dependencies" +msg_ok "Installed Dependencies" msg_info "Installing pip3" apt-get install -y python3-pip &>/dev/null -msg_ok "Installing pip3" +msg_ok "Installed pip3" get_latest_release() { curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 @@ -92,11 +92,11 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' } EOF sh <(curl -sSL https://get.docker.com) &>/dev/null -msg_ok "Installing Docker $DOCKER_LATEST_VERSION" +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" msg_info "Pulling Portainer $PORTAINER_LATEST_VERSION Image" docker pull portainer/portainer-ce:latest &>/dev/null -msg_ok "Pulling Portainer $PORTAINER_LATEST_VERSION Image" +msg_ok "Pulled Portainer $PORTAINER_LATEST_VERSION Image" msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null @@ -108,11 +108,11 @@ docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest &>/dev/null -msg_ok "Installing Portainer $PORTAINER_LATEST_VERSION" +msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" docker pull homeassistant/home-assistant:stable &>/dev/null -msg_ok "Pulling Home Assistant $CORE_LATEST_VERSION Image" +msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" msg_info "Installing Home Assistant $CORE_LATEST_VERSION" docker volume create hass_config >/dev/null @@ -126,7 +126,7 @@ docker run -d \ -v /etc/localtime:/etc/localtime:ro \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -msg_ok "Installing Home Assistant $CORE_LATEST_VERSION" +msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" msg_info "Creating Update Menu Script" pip3 install runlike &>/dev/null @@ -309,7 +309,7 @@ for container in ${CONTAINER_LIST}; do done EOF sudo chmod +x /root/update-containers.sh -msg_ok "Creating Update Menu Script" +msg_ok "Created Update Menu Script" mkdir /root/hass_config PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then @@ -326,11 +326,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customizing Container" +msg_ok "Customized Container" fi -msg_info "Cleanup" +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -msg_info "Cleanup" +msg_ok "Cleaned" From 4f6f2e083b7b35f1d779380c33df4a29f95f0f43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:38:17 -0400 Subject: [PATCH 2074/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 9ef4eb38..0ffdcd7f 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -338,7 +338,7 @@ EOF msg_info "Starting LXC Container" pct start $CTID -msg_ok "Starting LXC Container" +msg_ok "Started LXC Container" alias lxc-cmd="lxc-attach -n $CTID --" From c4a1791dbceb7aeb289fc15c8d9f6e1b047ba0fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:40:39 -0400 Subject: [PATCH 2075/6505] Update create_lxc.sh --- ct/create_lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 54068e9d..0331cbab 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -130,5 +130,5 @@ PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) msg_info "Creating LXC Container" pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -msg_ok "Creating LXC Container" -info "LXC Container ${BL}$CTID${CL} was successfully created." +msg_ok "LXC Container ${BL}$CTID${CL} was successfully created." + From 4bebe0a0d4beed4ac28abbc717492dcc77f0e37a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:42:32 -0400 Subject: [PATCH 2076/6505] Update debian-install.sh --- setup/debian-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 001b4ccf..db41b5ce 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -58,18 +58,18 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -msg_ok "Setting up Container OS" +msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -msg_ok "Updating Container OS" +msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -msg_ok "Installing Dependencies" +msg_ok "Installed Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then @@ -86,11 +86,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customizing Container" +msg_ok "Customized Container" fi -msg_info "Cleanup" +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -msg_ok "Cleanup" +msg_ok "Cleaned" From 1de9c90afd3ce4157fe571ee5b7610d3f92c509d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:46:18 -0400 Subject: [PATCH 2077/6505] Update create_lxc.sh --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 0331cbab..1fbb87f4 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -130,5 +130,5 @@ PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) msg_info "Creating LXC Container" pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -msg_ok "LXC Container ${BL}$CTID${CL} was successfully created." +msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created." From 094168735116eeec0082bc4e21946f6d7b0acc31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:50:12 -0400 Subject: [PATCH 2078/6505] Update create_lxc.sh --- ct/create_lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 1fbb87f4..2c20ae72 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -100,10 +100,10 @@ if pct status $CTID &>/dev/null; then fi TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using ${BL}$TEMPLATE_STORAGE${CL} for Template Storage." +msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." CONTAINER_STORAGE=$(select_storage container) || exit -info "Using ${BL}$CONTAINER_STORAGE${CL} for Container Storage." +msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." msg_info "Updating LXC Template List" pveam update >/dev/null From fed1ea033e97e009f1a32d85f33b7143e16889b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:53:07 -0400 Subject: [PATCH 2079/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 1706e7c4..5b2c01bb 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -341,4 +341,4 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" +echo -e "${GN}Successfully created ${APP} LXC to ${BL}$CTID${CL}. \n" From e6221cdfbee7759cdbe35603928b7adde080efff Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 11:57:11 -0400 Subject: [PATCH 2080/6505] Update create_lxc.sh --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 2c20ae72..9ea496e9 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -107,7 +107,7 @@ msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." msg_info "Updating LXC Template List" pveam update >/dev/null -msg_ok "Updating LXC Template List" +msg_ok "Updated LXC Template List" TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) From d49ad57a3c31c30d99133c101145fbb53d676b96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 12:29:29 -0400 Subject: [PATCH 2081/6505] Update haos-vm.sh --- vm/haos-vm.sh | 59 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index f5b821e6..ad9827ea 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -1,5 +1,13 @@ #!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" + while true; do read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn case $yn in @@ -9,8 +17,7 @@ while true; do esac done clear -CL=`echo "\033[m"` -BL=`echo "\033[36m"` + function header_info { echo -e "${BL} _ _ ____ _____ @@ -23,6 +30,17 @@ echo -e "${BL} ${CL}" } header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + set -o errexit set -o errtrace set -o nounset @@ -94,10 +112,10 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -info "Using ${BL}$STORAGE${CL} for Storage Location." +msg_ok "Using ${BL}$STORAGE${CL} for Storage Location." VMID=$(pvesh get /cluster/nextid) -info "Container ID is ${BL}$VMID${CL}." -echo -en "${GN} Getting URL for Latest Home Assistant Disk Image... " +msg_ok "Container ID is ${BL}$VMID${CL}." +msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 URL=$(cat</dev/null set +o errtrace ( -echo -e "${CM} ${CL} \r" - echo -en "${GN} Adding Serial Port and Configuring Console... " +msg_info "Created HAOS VM" + + msg_info "Adding Serial Port and Configuring Console" trap ' warn "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then @@ -167,12 +188,12 @@ echo -e "${CM} ${CL} \r" fi exit ' ERR - echo -e "${CM} ${CL} \r" + msg_ok "Added Serial Port and Configured Console" if [ "$(command -v kpartx)" = "" ]; then - echo -en "${GN} Installing kpartx... " + msg_info "Installing kpartx" apt-get update >/dev/null apt-get -qqy install kpartx &>/dev/null - echo -e "${CM} ${CL} \r" + msg_ok "Installed kpartx" fi DISK1_PATH="$(pvesm path $DISK1_REF)" DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" @@ -188,8 +209,8 @@ echo -e "${CM} ${CL} \r" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) -#echo -en "${GN} Starting Home Assistant OS VM... " -#qm start $VMID -#echo -e "${CM} ${CL} \n" +msg_info "Starting Home Assistant OS (${VM_NAME}) VM" +qm start $VMID +msg_ok "Started Home Assistant OS (${VM_NAME}) VM" echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" From cb0cad67ae38d132b4193824cdc9f1fc51bff805 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 12:43:35 -0400 Subject: [PATCH 2082/6505] Update haos-vm.sh --- vm/haos-vm.sh | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index ad9827ea..8be5ed0c 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -47,8 +47,6 @@ set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` trap die ERR trap cleanup EXIT function error_exit() { @@ -112,7 +110,7 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -msg_ok "Using ${BL}$STORAGE${CL} for Storage Location." +msg_ok "Using ${BL}$STORAGE${CL} ${GN}for Storage Location." VMID=$(pvesh get /cluster/nextid) msg_ok "Container ID is ${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" @@ -124,7 +122,7 @@ r = requests.get(url).json() if "message" in r: exit() for release in r: - if release["prerelease"]: + if release["release"]: continue for asset in release["assets"]: if asset["name"].find("$RELEASE_TYPE") != -1: @@ -137,8 +135,6 @@ if [ -z "$URL" ]; then die "Github has returned an error. A rate limit may have been applied to your connection." fi msg_ok "Found URL for Latest Home Assistant Disk Image" -msg_info "${BL}${URL}${CL}" -sleep 2 msg_ok "${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" @@ -180,15 +176,15 @@ set +o errtrace ( msg_info "Created HAOS VM" - msg_info "Adding Serial Port and Configuring Console" - trap ' - warn "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VMID --delete serial0 >/dev/null - fi - exit +msg_info "Adding Serial Port and Configuring Console" +trap ' + warn "Unable to configure serial port. VM is still functional." + if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VMID --delete serial0 >/dev/null + fi + exit ' ERR - msg_ok "Added Serial Port and Configured Console" +msg_ok "Added Serial Port and Configured Console" if [ "$(command -v kpartx)" = "" ]; then msg_info "Installing kpartx" apt-get update >/dev/null @@ -213,4 +209,4 @@ msg_info "Starting Home Assistant OS (${VM_NAME}) VM" qm start $VMID msg_ok "Started Home Assistant OS (${VM_NAME}) VM" -echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" +msg_ok "Completed Successfully!\n" From 4822a2d377726ef86f13a8c517f2cee977772705 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 13:10:52 -0400 Subject: [PATCH 2083/6505] Update haos-vm.sh --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 8be5ed0c..639ec10f 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -122,7 +122,7 @@ r = requests.get(url).json() if "message" in r: exit() for release in r: - if release["release"]: + if not release["prerelease"]: continue for asset in release["assets"]: if asset["name"].find("$RELEASE_TYPE") != -1: From f37e3770cfa3eb47134dd7797edaa5d074a48d17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 13:34:06 -0400 Subject: [PATCH 2084/6505] Update haos-vm.sh --- vm/haos-vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 639ec10f..dc7c1e22 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -117,14 +117,14 @@ msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 URL=$(cat< Date: Sat, 16 Apr 2022 13:37:57 -0400 Subject: [PATCH 2085/6505] Update haos-vm.sh --- vm/haos-vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index dc7c1e22..1d499d81 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -117,12 +117,12 @@ msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 URL=$(cat< Date: Sat, 16 Apr 2022 13:56:29 -0400 Subject: [PATCH 2086/6505] Update haos-vm.sh --- vm/haos-vm.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 1d499d81..a7f95560 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -122,13 +122,16 @@ r = requests.get(url).json() if "message" in r: exit() for release in r: - if release["prerelease"]: - continue - if asset in release["assets"]: - if asset["name"].find("$RELEASE_TYPE") != -1: - image_url = asset["browser_download_url"] - print(image_url) - exit() + if not release['prerelease']: + continue + for asset in release['assets']: + if asset['name'].endswith('$RELEASE_EXT'): + global image_url + image_url = asset['browser_download_url'] + break + if 'image_url' in globals(): + print(image_url) + break EOF ) if [ -z "$URL" ]; then From 48222394aa609ea964a7f7d25e3f2071163cb5ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 14:00:19 -0400 Subject: [PATCH 2087/6505] Update haos-vm.sh --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index a7f95560..70329274 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -125,7 +125,7 @@ for release in r: if not release['prerelease']: continue for asset in release['assets']: - if asset['name'].endswith('$RELEASE_EXT'): + if asset['name'].endswith('$RELEASE_TYPE'): global image_url image_url = asset['browser_download_url'] break From c6d525fa4296f9cb7f8922db3c52659bc7cc05fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 14:06:49 -0400 Subject: [PATCH 2088/6505] Update haos-vm.sh --- vm/haos-vm.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 70329274..9963951c 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -122,16 +122,13 @@ r = requests.get(url).json() if "message" in r: exit() for release in r: - if not release['prerelease']: - continue - for asset in release['assets']: - if asset['name'].endswith('$RELEASE_TYPE'): - global image_url - image_url = asset['browser_download_url'] - break - if 'image_url' in globals(): - print(image_url) - break + if release["prerelease"]: + continue + for asset in release["assets"]: + if asset["name"].find("$RELEASE_TYPE") != -1: + image_url = asset["browser_download_url"] + print(image_url) + exit() EOF ) if [ -z "$URL" ]; then From e98e3a0f2a01a39ebabbd2b1faa0efaf30a48132 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 14:15:42 -0400 Subject: [PATCH 2089/6505] Update haos-vm.sh --- vm/haos-vm.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 9963951c..b44c9857 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -110,9 +110,9 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -msg_ok "Using ${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." VMID=$(pvesh get /cluster/nextid) -msg_ok "Container ID is ${BL}$VMID${CL}." +msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 URL=$(cat</dev/null set +o errtrace ( -msg_info "Created HAOS VM" +msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" msg_info "Adding Serial Port and Configuring Console" trap ' @@ -205,8 +205,8 @@ msg_ok "Added Serial Port and Configured Console" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) -msg_info "Starting Home Assistant OS (${VM_NAME}) VM" +msg_info "Starting Home Assistant OS VM" qm start $VMID -msg_ok "Started Home Assistant OS (${VM_NAME}) VM" +msg_ok "Started Home Assistant OS VM" msg_ok "Completed Successfully!\n" From 11bb79cfed0bc3d1624eda065d7edea2e202b01f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 14:27:33 -0400 Subject: [PATCH 2090/6505] Update haos_vm.sh --- vm/haos_vm.sh | 73 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 63eab989..adb14cf7 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,5 +1,13 @@ #!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" + while true; do read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn case $yn in @@ -9,8 +17,7 @@ while true; do esac done clear -BL=`echo "\033[36m"` -CL=`echo "\033[m"` + function header_info { echo -e "${BL} _ _ ____ _____ @@ -23,14 +30,23 @@ echo -e "${BL} ${CL}" } header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + set -o errexit set -o errtrace set -o nounset set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` trap die ERR trap cleanup EXIT function error_exit() { @@ -94,10 +110,10 @@ else "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi -info "Using ${BL}$STORAGE${CL} for Storage Location." +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." VMID=$(pvesh get /cluster/nextid) -info "Container ID is ${BL}$VMID${CL}." -echo -en "${GN} Getting URL for Latest Home Assistant Disk Image... " +msg_ok "Container ID is ${CL}${BL}$VMID${CL}." +msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 URL=$(cat</dev/null set +o errtrace ( -echo -e "${CM} ${CL} \r" - echo -en "${GN} Adding Serial Port and Configuring Console... " - trap ' - warn "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VMID --delete serial0 >/dev/null - fi - exit +msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" + +msg_info "Adding Serial Port and Configuring Console" +trap ' + warn "Unable to configure serial port. VM is still functional." + if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VMID --delete serial0 >/dev/null + fi + exit ' ERR - echo -e "${CM} ${CL} \r" +msg_ok "Added Serial Port and Configured Console" if [ "$(command -v kpartx)" = "" ]; then - echo -en "${GN} Installing kpartx... " + msg_info "Installing kpartx" apt-get update >/dev/null apt-get -qqy install kpartx &>/dev/null - echo -e "${CM} ${CL} \r" + msg_ok "Installed kpartx" fi DISK1_PATH="$(pvesm path $DISK1_REF)" DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" @@ -188,8 +205,8 @@ echo -e "${CM} ${CL} \r" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) -echo -en "${GN} Starting Home Assistant OS VM... " +msg_info "Starting Home Assistant OS VM" qm start $VMID -echo -e "${CM} ${CL} \n" +msg_ok "Started Home Assistant OS VM" -echo -e "${GN} Completed Successfully!${CL} (${VM_NAME}) VM ID is ${BL}${VMID}${CL} \n" +msg_ok "Completed Successfully!\n" From 192f158fbd694ff0a273cfe6758a7c03c49f835b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 15:42:50 -0400 Subject: [PATCH 2091/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 0ffdcd7f..22ab2ed3 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -346,8 +346,8 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL} -${BL}Portainer${CL} should be reachable by going to the following URL. +Portainer should be reachable by going to the following URL. ${BL}http://${IP}:9000${CL}\n" From 21d9f95833d4e6be2a11dcecd09bf368d36c9adf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 15:43:41 -0400 Subject: [PATCH 2092/6505] Update README.md --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7a9fa723..34dcb3a5 100644 --- a/README.md +++ b/README.md @@ -133,17 +133,14 @@ ________________________________________________________________________________ @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    Home Assistant Container LXC

    -

    With Selectable Storage Drivers

    -To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell (V2). +To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    - -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. **Home Assistant Interface - IP:8123** From 7611fb0cc21778e0c0ff2157c5ec761951ab681a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 15:45:42 -0400 Subject: [PATCH 2093/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 5b2c01bb..4c53e850 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -341,4 +341,4 @@ lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/m IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to ${BL}$CTID${CL}. \n" +msg_ok "Completed Successfully!\n" From 7c6d65512e9f342c3f91a38a37a76c804745b4be Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 15:50:53 -0400 Subject: [PATCH 2094/6505] Update README.md --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 34dcb3a5..2fa17f20 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ ________________________________________________________________________________
    - Home Assistant Container LXC + 🔸Home Assistant Container LXC

    Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    @@ -886,12 +886,7 @@ ________________________________________________________________________________

    Debian 11 LXC

    -To create a new Proxmox Debian 11 (curl. sudo) LXC, run the following in the Proxmox Shell (V2). - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian.sh)" -``` -An early look at the v3 install script, run the following in the Proxmox Shell (V3). +To create a new Proxmox Debian 11 (curl. sudo) LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v3.sh)" @@ -899,8 +894,6 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v3.sh

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - ⚙️ **To Update Debian 11** Run in the LXC console From a9b33fd92ae47b3ce4b524ac987175fccf27bfc4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 15:55:44 -0400 Subject: [PATCH 2095/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 35d04e97..2755fceb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-16 + +### Changed + +- **Home Assistant OS VM** + - New "Limited" V3 Install Script +- **Home Assistant Container LXC** + - New V3 Install Script +- **Debian LXC** + - New V3 Install Script + ## 2022-04-13 ### Changed From 97846354986a2a41b9ef7dcc085599c706213755 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 15:58:09 -0400 Subject: [PATCH 2096/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2755fceb..6c9e95b7 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -13,7 +13,7 @@ All notable changes to this project will be documented in this file. - New "Limited" V3 Install Script - **Home Assistant Container LXC** - New V3 Install Script -- **Debian LXC** +- **Debian 11 LXC** - New V3 Install Script ## 2022-04-13 From ee260186c95eece72a63e15f3bb84d32927585f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 15:59:06 -0400 Subject: [PATCH 2097/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2fa17f20..ad56061d 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ ________________________________________________________________________________
    - Home Assistant OS VM + 🔸Home Assistant OS VM

    @home-assistant

    From 641652c76b1f1eddcabf5160ba93098279c8e8b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 16:00:32 -0400 Subject: [PATCH 2098/6505] Rename homeassistant.sh to homeassistant-v2.sh --- ct/{homeassistant.sh => homeassistant-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{homeassistant.sh => homeassistant-v2.sh} (100%) diff --git a/ct/homeassistant.sh b/ct/homeassistant-v2.sh similarity index 100% rename from ct/homeassistant.sh rename to ct/homeassistant-v2.sh From 6d695311eb626e0a45ca0954534f893414c1df17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 16:01:03 -0400 Subject: [PATCH 2099/6505] Rename debian.sh to debian-v2.sh --- ct/{debian.sh => debian-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{debian.sh => debian-v2.sh} (100%) diff --git a/ct/debian.sh b/ct/debian-v2.sh similarity index 100% rename from ct/debian.sh rename to ct/debian-v2.sh From 66ff3ba43f888336c317567e8115bb25fb70ad73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 16:29:40 -0400 Subject: [PATCH 2100/6505] Update haos-vm.sh --- vm/haos-vm.sh | 90 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index b44c9857..29bc7efe 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +NEXTID=$(pvesh get /cluster/nextid) YW=`echo "\033[33m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` @@ -40,6 +40,89 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Disk Size ${BGN}32GB${CL}" + DISK_SIZE="32G" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}4096MiB${CL}${GN} RAM${CL}" + RAM_SIZE="4096" +} +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 32Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="32G"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script set -o errexit set -o errtrace @@ -111,7 +194,6 @@ else done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -VMID=$(pvesh get /cluster/nextid) msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 @@ -163,13 +245,13 @@ msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) -qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ +qm create $CT_ID -agent 1 -bios ovmf -cores ${CORE_COUNT} -memory ${RAM_SIZE} -name $VM_NAME -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},size=32G >/dev/null + -scsi0 ${DISK1_REF},size=${DISK_SIZE} >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null set +o errtrace From 87f12a0be191a022bd6447d20a0e2f5dcef60bb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 16:36:17 -0400 Subject: [PATCH 2101/6505] Update haos-vm.sh --- vm/haos-vm.sh | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 29bc7efe..47e58e6a 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -1,8 +1,12 @@ #!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' YW=`echo "\033[33m"` BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" @@ -45,7 +49,7 @@ function default_settings() { header_info echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID + VM_ID=$NEXTID echo -e "${DGN}Using Disk Size ${BGN}32GB${CL}" DISK_SIZE="32G" echo -e "${DGN}Using ${BGN}2vCPU${CL}" @@ -57,16 +61,16 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" + echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read VM_ID + if [ -z $CT_ID ]; then VM_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$VM_ID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 32Gb " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="32G"; fi; @@ -77,7 +81,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT @@ -88,7 +92,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " @@ -100,7 +104,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" @@ -245,7 +249,7 @@ msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) -qm create $CT_ID -agent 1 -bios ovmf -cores ${CORE_COUNT} -memory ${RAM_SIZE} -name $VM_NAME -net0 virtio,bridge=vmbr0 \ +qm create $VM_ID -agent 1 -bios ovmf -cores ${CORE_COUNT} -memory ${RAM_SIZE} -name $VM_NAME -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null From c98f2efbbb36c99a1a520b685e4589aa598bec78 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 16:43:57 -0400 Subject: [PATCH 2102/6505] Update haos-vm.sh --- vm/haos-vm.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 47e58e6a..93d12069 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -63,8 +63,8 @@ function advanced_settings() { echo -e "${RD}Using Advanced Settings${CL}" echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " read VM_ID - if [ -z $CT_ID ]; then VM_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$VM_ID${CL}" + if [ -z $VM_ID ]; then VM_ID=$NEXTID; fi; + echo -en "${DGN}Set VM ID To ${BL}$VM_ID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -73,7 +73,7 @@ header_info echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 32Gb " read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="32G"; fi; + if [ -z $DISK_SIZE ]; then DISK_SIZE="32"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" echo -e " ${CM}${CL} \r" @@ -198,7 +198,7 @@ else done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Container ID is ${CL}${BL}$VMID${CL}." +msg_ok "Virtual Machine ID is ${CL}${BL}$VM_ID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 URL=$(cat<1 {print $2}') case $STORAGE_TYPE in btrfs|nfs|dir) DISK_EXT=".qcow2" - DISK_REF="$VMID/" + DISK_REF="$VM_ID/" IMPORT_OPT="-format qcow2" esac for i in {0,1}; do disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}=vm-${VM_ID}-disk-${i}${DISK_EXT:-} eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done msg_ok "Extracted Disk Image" @@ -255,7 +255,7 @@ pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},size=${DISK_SIZE} >/dev/null + -scsi0 ${DISK1_REF},size=${DISK_SIZE}G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null set +o errtrace From e9e9bbd00f2e7226652dae4bf888094ad5b65875 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 16:48:35 -0400 Subject: [PATCH 2103/6505] Update haos-vm.sh --- vm/haos-vm.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 93d12069..43be5f82 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -251,12 +251,12 @@ msg_info "Creating HAOS VM" VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) qm create $VM_ID -agent 1 -bios ovmf -cores ${CORE_COUNT} -memory ${RAM_SIZE} -name $VM_NAME -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null -qm set $VMID \ +pvesm alloc $STORAGE $VM_ID $DISK0 128 1>&/dev/null +qm importdisk $VM_ID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm set $VM_ID \ -efidisk0 ${DISK0_REF},size=128K \ -scsi0 ${DISK1_REF},size=${DISK_SIZE}G >/dev/null -qm set $VMID \ +qm set $VM_ID \ -boot order=scsi0 >/dev/null set +o errtrace ( @@ -265,8 +265,8 @@ msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" msg_info "Adding Serial Port and Configuring Console" trap ' warn "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VMID --delete serial0 >/dev/null + if [ "$(qm config $VM_ID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VM_ID --delete serial0 >/dev/null fi exit ' ERR @@ -292,7 +292,7 @@ msg_ok "Added Serial Port and Configured Console" qm set $VMID -serial0 socket >/dev/null ) msg_info "Starting Home Assistant OS VM" -qm start $VMID +qm start $VM_ID msg_ok "Started Home Assistant OS VM" msg_ok "Completed Successfully!\n" From 2da1b289f1cbc000fe6b9c33871f2005717656d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 16:55:14 -0400 Subject: [PATCH 2104/6505] Update haos-vm.sh --- vm/haos-vm.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 43be5f82..c02f45c4 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -51,7 +51,7 @@ function default_settings() { echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" VM_ID=$NEXTID echo -e "${DGN}Using Disk Size ${BGN}32GB${CL}" - DISK_SIZE="32G" + DISK_SIZE="32" echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" echo -e "${DGN}Using ${BGN}4096MiB${CL}${GN} RAM${CL}" @@ -75,7 +75,7 @@ header_info read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="32"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZEGB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -142,7 +142,7 @@ function error_exit() { local REASON="\e[97m${1:-$DEFAULT}\e[39m" local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" msg "$FLAG $REASON" - [ ! -z ${VMID-} ] && cleanup_vmid + [ ! -z ${VM_ID-} ] && cleanup_vm_id exit $EXIT } function warn() { @@ -159,12 +159,12 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID +function cleanup_vm_id() { + if $(qm status $VM_ID &>/dev/null); then + if [ "$(qm status $VM_ID | awk '{print $2}')" == "running" ]; then + qm stop $VM_ID fi - qm destroy $VMID + qm destroy $VM_ID fi } function cleanup() { @@ -289,7 +289,7 @@ msg_ok "Added Serial Port and Configured Console" mkdir $TEMP_MOUNT mount $DISK1_PART1_PATH $TEMP_MOUNT sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt - qm set $VMID -serial0 socket >/dev/null + qm set $VM_ID -serial0 socket >/dev/null ) msg_info "Starting Home Assistant OS VM" qm start $VM_ID From 6d804617b2814550644bf1e2f609bd130b0076d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 17:02:32 -0400 Subject: [PATCH 2105/6505] Update haos-vm.sh --- vm/haos-vm.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index c02f45c4..0f2c9022 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -75,25 +75,25 @@ header_info read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="32"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZEGB${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}${DISK_SIZE}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}${CORE_COUNT}${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}${DISK_SIZE}GB${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE @@ -105,7 +105,7 @@ clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}${DISK_SIZE}GB${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" From d5891a8e0f5d75e0d329d6394716d7cc77f37e7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 17:21:33 -0400 Subject: [PATCH 2106/6505] Update haos-vm.sh --- vm/haos-vm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 0f2c9022..d0d02428 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -51,7 +51,7 @@ function default_settings() { echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" VM_ID=$NEXTID echo -e "${DGN}Using Disk Size ${BGN}32GB${CL}" - DISK_SIZE="32" + DISK_SIZE=16 echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" echo -e "${DGN}Using ${BGN}4096MiB${CL}${GN} RAM${CL}" @@ -73,7 +73,7 @@ header_info echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 32Gb " read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="32"; fi; + if [ -z $DISK_SIZE ]; then DISK_SIZE=32; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" echo -e " ${CM}${CL} \r" @@ -107,7 +107,7 @@ header_info echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" echo -e "${DGN}Using Disk Size ${BGN}${DISK_SIZE}GB${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo From 320a9c2b279d4a89f40beba4d47e8c288dd8902c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 20:24:39 -0400 Subject: [PATCH 2107/6505] Update haos-vm.sh --- vm/haos-vm.sh | 112 +++++++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index d0d02428..3e3b3145 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -29,8 +28,7 @@ echo -e "${BL} | |__| | / \ | | | | (___ | __ | / /\ \| | | |\___ \ | | | |/ ____ \ |__| |____) | - |_| |_/_/ \_\____/|_____/ - + |_| |_/_/ ${CL}${YW}v3${CL}${BL} \_\____/|_____/ ${CL}" } header_info @@ -48,41 +46,47 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" - VM_ID=$NEXTID - echo -e "${DGN}Using Disk Size ${BGN}32GB${CL}" - DISK_SIZE=16 + echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using VM Name ${BGN}haos${CL}" + VM_NAME=haos echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}4096MiB${CL}" RAM_SIZE="4096" + echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" + START_VM="yes" + } function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read VM_ID - if [ -z $VM_ID ]; then VM_ID=$NEXTID; fi; - echo -en "${DGN}Set VM ID To ${BL}$VM_ID${CL}" + read VMID + if [ -z $VMID ]; then VMID=$NEXTID; fi; + echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 32Gb " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE=32; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: hoas " + read VMNAME + if [ -z $VMNAME ]; then + VM_NAME=haos + else + VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$VM_NAME${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" - echo -e "${DGN}Using Disk Size ${BGN}${DISK_SIZE}GB${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; @@ -92,8 +96,8 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" - echo -e "${DGN}Using Disk Size ${BGN}${DISK_SIZE}GB${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE @@ -104,10 +108,26 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using ID ${BGN}$VM_ID${CL}" - echo -e "${DGN}Using Disk Size ${BGN}${DISK_SIZE}GB${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " + read START_VM + if [ -z $START_VM ]; then START_VM="yes"; + else + START_VM="no"; fi; + echo -en "${DGN}Starting VM when completed ${BL}$START_VM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -142,7 +162,7 @@ function error_exit() { local REASON="\e[97m${1:-$DEFAULT}\e[39m" local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" msg "$FLAG $REASON" - [ ! -z ${VM_ID-} ] && cleanup_vm_id + [ ! -z ${VMID-} ] && cleanup_vmid exit $EXIT } function warn() { @@ -159,12 +179,12 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } -function cleanup_vm_id() { - if $(qm status $VM_ID &>/dev/null); then - if [ "$(qm status $VM_ID | awk '{print $2}')" == "running" ]; then - qm stop $VM_ID +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID fi - qm destroy $VM_ID + qm destroy $VMID fi } function cleanup() { @@ -198,7 +218,7 @@ else done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Virtual Machine ID is ${CL}${BL}$VM_ID${CL}." +msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" RELEASE_TYPE=qcow2 URL=$(cat<1 {print $2}') case $STORAGE_TYPE in btrfs|nfs|dir) DISK_EXT=".qcow2" - DISK_REF="$VM_ID/" + DISK_REF="$VMID/" IMPORT_OPT="-format qcow2" esac for i in {0,1}; do disk="DISK$i" - eval DISK${i}=vm-${VM_ID}-disk-${i}${DISK_EXT:-} + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) -qm create $VM_ID -agent 1 -bios ovmf -cores ${CORE_COUNT} -memory ${RAM_SIZE} -name $VM_NAME -net0 virtio,bridge=vmbr0 \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VM_ID $DISK0 128 1>&/dev/null -qm importdisk $VM_ID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null -qm set $VM_ID \ +pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},size=${DISK_SIZE}G >/dev/null -qm set $VM_ID \ + -scsi0 ${DISK1_REF},size=32G >/dev/null +qm set $VMID \ -boot order=scsi0 >/dev/null set +o errtrace ( @@ -265,8 +284,8 @@ msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" msg_info "Adding Serial Port and Configuring Console" trap ' warn "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VM_ID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VM_ID --delete serial0 >/dev/null + if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then + qm set $VMID --delete serial0 >/dev/null fi exit ' ERR @@ -289,10 +308,11 @@ msg_ok "Added Serial Port and Configured Console" mkdir $TEMP_MOUNT mount $DISK1_PART1_PATH $TEMP_MOUNT sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt - qm set $VM_ID -serial0 socket >/dev/null + qm set $VMID -serial0 socket >/dev/null ) +if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" -qm start $VM_ID +qm start $VMID msg_ok "Started Home Assistant OS VM" - +fi msg_ok "Completed Successfully!\n" From c14b0673ed42f35e3e94fd747fed1943bdb025ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Apr 2022 20:25:24 -0400 Subject: [PATCH 2108/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad56061d..507ff0aa 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos_vm.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm.sh)" ```

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

    From 5a7f47b6c2a1c3f4e0222c156183c2dad5b10e67 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 12:41:40 -0400 Subject: [PATCH 2109/6505] Update debian-install.sh --- setup/debian-install.sh | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index db41b5ce..bc0fd4d7 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -1,27 +1,6 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From d9790a2795a097d18ceec988c9f4d60784e224db Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 12:49:32 -0400 Subject: [PATCH 2110/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 4c53e850..d2e4d972 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -335,9 +335,9 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -alias lxc-cmd="lxc-attach -n $CTID --" +#alias lxc-cmd="lxc-attach -n $CTID --" -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From ef9d8c626611bb20a3689beed90a3bda0af3d237 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 12:54:56 -0400 Subject: [PATCH 2111/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index d2e4d972..0c11983d 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -335,9 +335,9 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -#alias lxc-cmd="lxc-attach -n $CTID --" +alias lxc-cmd="lxc-attach -n $CTID --" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.s> IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 6acae8962487b217307c385b17d0fb220a0f8899 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:02:18 -0400 Subject: [PATCH 2112/6505] Update debian-v3.sh --- ct/debian-v3.sh | 61 ++++--------------------------------------------- 1 file changed, 5 insertions(+), 56 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 0c11983d..1567da12 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -1,4 +1,7 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -248,58 +251,6 @@ function start_script() { start_script -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} - -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} - -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} - -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} - -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -335,9 +286,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.s> +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From fbda3fcf67ae02f115e04c7374ce3618a469ba01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:04:56 -0400 Subject: [PATCH 2113/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 60 +++--------------------------------------- 1 file changed, 4 insertions(+), 56 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 22ab2ed3..636d0fb1 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -248,58 +250,6 @@ function start_script() { start_script -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} - -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} - -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} - -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} - -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -340,9 +290,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From c34239ba6a8aedcde6b846fdbc18452f14eb9bdf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:06:03 -0400 Subject: [PATCH 2114/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index a27d5f8d..967f0765 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -1,26 +1,6 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` From 3b7f157ed01532d05fb0cc537688605c2f54d89a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:10:08 -0400 Subject: [PATCH 2115/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 636d0fb1..ce111c33 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -290,7 +290,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/homeassistant-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 895747d1ad573a0af8e5e85e7226ab2caa9c74ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:22:51 -0400 Subject: [PATCH 2116/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index ce111c33..636d0fb1 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -290,7 +290,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/homeassistant-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 660cff074fee71483bfe34130c8c6564ac128502 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:41:31 -0400 Subject: [PATCH 2117/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 390 ++++++++++++++++++------------------------- 1 file changed, 164 insertions(+), 226 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 78efaead..0b1b13bb 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -1,16 +1,20 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' BGN=`echo "\033[4;92m"` -GN=`echo "\033[32m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" APP="Zigbee2MQTT" NSAPP=$(echo ${APP,,} | tr -d ' ') - while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -34,218 +38,200 @@ ${CL}" } header_info -function pve_check() { -PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater" + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" echo -e "Exiting..." sleep 2 exit -fi + fi } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${GN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${GN}Using ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${GN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${GN}Using Disk Size ${BGN}4GB${CL}" - SIZEDISK="4" - echo -e "${GN}Using Storage ${BGN}local-lvm${CL}" - STORAGETYPE="local-lvm" - echo -e "${GN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${GN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${GN}Using IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${GN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged " - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${GN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${GN}Set CT Type ${BL}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - fi; + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${GN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${GN}Set CT Password ${BL}$PW1${CL}" - - fi; + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${GN}Set CT ID To ${BL}$CT_ID${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${GN}Set CT Name To ${BL}$HN${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " - read SIZEDISK - if [ -z $SIZEDISK ]; then SIZEDISK="4"; fi; - if ! [[ $SIZEDISK =~ $INTEGER ]] ; then echo "ERROR! SIZEDISK MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${GN}Set Disk Size To ${BL}$SIZEDISK${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${YW}Storages Available:${CL}" - echo " " - for stg in `pvesh get storage --noborder --noheader` - do - echo -e "${BL} - ${stg}${CL}" - done - echo " " - echo -e "${YW}Enter which storage to create the CT, or Press [ENTER] for Default: local-lvm " - read STORAGETYPE - if [ -z $STORAGETYPE ]; then STORAGETYPE="local-lvm"; fi; - echo -en "${GN}Set Storage To ${BL}$STORAGETYPE${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${GN}Set Cores To ${BL}$CORE_COUNT${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${GN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${GN}Set IP Address To ${BL}$NET${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN="-tag $VLAN1" - echo -en "${GN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${GN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${GN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${GN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${GN}Using CT Name ${BGN}$HN${CL}" - echo -e "${GN}Using Disk Size ${BGN}$SIZEDISK${CL}" - echo -e "${GN}Using Storage ${BGN}$STORAGETYPE${CL}" - echo -e "${GN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${GN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${GN}Using IP Address ${BGN}$NET${CL}" - echo -e "${GN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -263,56 +249,10 @@ function start_script() { advanced_settings fi; } -pve_check + start_script -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$CT_TYPE" == "1" ]; then +if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" @@ -324,7 +264,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$CT_ID export PCT_OSTYPE=debian export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$SIZEDISK +export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN @@ -354,14 +294,12 @@ lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file EOF -echo -en "${GN} Starting LXC Container... " +msg_info "Starting LXC Container" pct start $CTID -echo -e "${CM}${CL} \r" +msg_ok "Started LXC Container" -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/zigbee2mqtt-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" +msg_ok "Completed Successfully!\n" From 013718dff9d1717532a3fe2275d843ea11e3c2c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:48:35 -0400 Subject: [PATCH 2118/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 84 +++++++++++++++-------------------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index ca1f71d0..5fe2f04c 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -1,38 +1,31 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,32 +38,29 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - unzip &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y unzip &>/dev/null +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Zwavejs2MQTT... " +msg_info "Installing Zwavejs2MQTT" mkdir /opt/zwavejs2mqtt cd /opt/zwavejs2mqtt mkdir store curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null unzip zwavejs2mqtt-v*.zip zwavejs2mqtt &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Zwavejs2MQTT" -echo -en "${GN} Creating Service... " +msg_info "Creating Service" service_path="/etc/systemd/system/zwavejs2mqtt.service" echo "[Unit] Description=ZWavejs2MQTT @@ -84,11 +74,11 @@ ExecStart=/opt/zwavejs2mqtt/zwavejs2mqtt WantedBy=multi-user.target" > $service_path systemctl start zwavejs2mqtt systemctl enable zwavejs2mqtt &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -101,12 +91,12 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" rm zwavejs2mqtt-v*.zip apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From b3eb4ce5e63fbded06b9d0b21a31db96047692ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 13:56:08 -0400 Subject: [PATCH 2119/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 84 ++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index e752e3b8..bd49c878 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -1,38 +1,31 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,37 +38,34 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Sett up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" sudo apt-get install -y nodejs git make g++ gcc &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Setting up Zigbee2MQTT Repository... " +msg_info "Setting up Zigbee2MQTT Repository" sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Sett up Zigbee2MQTT Repository" -echo -en "${GN} Installing Zigbee2MQTT... " +msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt &>/dev/null npm ci &>/dev/null -echo -e "${CM}${CL} \r" - service_path="/etc/systemd/system/zigbee2mqtt.service" echo "[Unit] Description=zigbee2mqtt @@ -90,9 +80,11 @@ User=root [Install] WantedBy=multi-user.target" > $service_path systemctl enable zigbee2mqtt.service &>/dev/null +msg_ok "Installed Zigbee2MQTT" + PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -105,11 +97,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 47ae7f8c7dc8e4078e36b2a74d1b4c5014c4de74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:05:25 -0400 Subject: [PATCH 2120/6505] Create zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 321 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 ct/zwavejs2mqtt-v3.sh diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh new file mode 100644 index 00000000..39589e3f --- /dev/null +++ b/ct/zwavejs2mqtt-v3.sh @@ -0,0 +1,321 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Zwavejs2MQTT" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + ______ _ ___ __ __ ____ _______ _______ + |___ / (_) |__ \| \/ |/ __ \__ __|__ __| + / /_ ____ ___ _____ _ ___ ) | \ / | | | | | | | | + / /\ \ /\ / / _ \ \ / / _ \ / __| / /| |\/| | | | | | | | | + / /__\ V V / (_| |\ V / __/ \__ \/ /_| | | | |__| | | | | | + /_____|\_/\_/ \__,_| \_/ \___| |___/____|_| |_|\___\_\ |_| v3 |_| + _/ | + |__/ +${CL}" +} +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:8091${CL} \n" From c610d853142ac9f33b7de4b1f8a2a9d1fa188657 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:14:42 -0400 Subject: [PATCH 2121/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index bd49c878..05fc2350 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -53,7 +53,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null -msg_ok "Sett up Node.js Repository" +msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" sudo apt-get install -y nodejs git make g++ gcc &>/dev/null @@ -61,7 +61,7 @@ msg_ok "Installed Node.js" msg_info "Setting up Zigbee2MQTT Repository" sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null -msg_ok "Sett up Zigbee2MQTT Repository" +msg_ok "Set up Zigbee2MQTT Repository" msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt &>/dev/null From 6974cd4ccb24fd5bfa07f3db1de6636d82a45873 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:17:31 -0400 Subject: [PATCH 2122/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 05fc2350..9a0efcda 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -66,6 +66,9 @@ msg_ok "Set up Zigbee2MQTT Repository" msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt &>/dev/null npm ci &>/dev/null +msg_ok "Installed Zigbee2MQTT" + +msg_info "Creating Service" service_path="/etc/systemd/system/zigbee2mqtt.service" echo "[Unit] Description=zigbee2mqtt @@ -80,7 +83,7 @@ User=root [Install] WantedBy=multi-user.target" > $service_path systemctl enable zigbee2mqtt.service &>/dev/null -msg_ok "Installed Zigbee2MQTT" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From 5723ed4d56a2dabc444674453c0d85f98efd375d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:21:13 -0400 Subject: [PATCH 2123/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 39589e3f..c4c52d1e 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -310,12 +310,10 @@ echo -en "${GN} Starting LXC Container... " pct start $CTID echo -e "${CM}${CL} \r" -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/zwavejs2mqtt-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. +msg_ok "Completed Successfully!\n" +${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8091${CL} \n" From cf2961e5a23ac3808754a843f60c9e43af135a45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:24:51 -0400 Subject: [PATCH 2124/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index c4c52d1e..0250de1e 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -75,7 +75,7 @@ function default_settings() { DISK_SIZE="4" echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp @@ -191,7 +191,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -207,7 +207,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 9f99ef2b22200693f9148099a267461aa412e16f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:26:06 -0400 Subject: [PATCH 2125/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 0250de1e..31f632a0 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -292,19 +292,6 @@ lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi echo -en "${GN} Starting LXC Container... " pct start $CTID From 9e96acc7ca66beabf57a305271cee50352a94384 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:31:36 -0400 Subject: [PATCH 2126/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 31f632a0..c2d506c5 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -297,7 +297,7 @@ echo -en "${GN} Starting LXC Container... " pct start $CTID echo -e "${CM}${CL} \r" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/zwavejs2mqtt-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zwavejs2mqtt-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 777479aedc74f14dca82ab60a0100f20720cb44f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:32:14 -0400 Subject: [PATCH 2127/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 0b1b13bb..597d2bb0 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -298,7 +298,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/zigbee2mqtt-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 2cda118b4b7022e92db714222e2b79e18977b46e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:33:49 -0400 Subject: [PATCH 2128/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index c2d506c5..5a47c301 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -302,5 +302,5 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') msg_ok "Completed Successfully!\n" -${APP} should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8091${CL} \n" From 500ba0f85cd7ac20e47a6de2c18d2033c6fb9dc4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:48:00 -0400 Subject: [PATCH 2129/6505] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 507ff0aa..52312421 100644 --- a/README.md +++ b/README.md @@ -620,17 +620,17 @@ ________________________________________________________________________________
    - Zigbee2MQTT LXC + 🔸Zigbee2MQTT LXC

    Zigbee2MQTT LXC

    -To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -701,16 +701,16 @@ ________________________________________________________________________________
    - Zwavejs2MQTT LXC + 🔸Zwavejs2MQTT LXC -

    +

    Zwavejs2MQTT LXC

    -To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwavejs2mqtt.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwavejs2mqtt-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    From 7a994a17aca1d19d796797ff5fcab5185b5af8fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:49:33 -0400 Subject: [PATCH 2130/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6c9e95b7..db356a11 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-17 + +### Changed + +- **Zigbee2MQTT LXC** + - New V3 Install Script +- **Zwavejs2MQTT LXC** + - New V3 Install Script + ## 2022-04-16 ### Changed From b2b6bfb644ab8a315520add736ec7d1970e4a03b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:50:11 -0400 Subject: [PATCH 2131/6505] Rename zwavejs2mqtt.sh to zwavejs2mqtt-v2.sh --- ct/{zwavejs2mqtt.sh => zwavejs2mqtt-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{zwavejs2mqtt.sh => zwavejs2mqtt-v2.sh} (100%) diff --git a/ct/zwavejs2mqtt.sh b/ct/zwavejs2mqtt-v2.sh similarity index 100% rename from ct/zwavejs2mqtt.sh rename to ct/zwavejs2mqtt-v2.sh From 23d7329167e38369f785dd271c0e2749682fafec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 14:50:49 -0400 Subject: [PATCH 2132/6505] Rename zigbee2mqtt.sh to zigbee2mqtt-v2.sh --- ct/{zigbee2mqtt.sh => zigbee2mqtt-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{zigbee2mqtt.sh => zigbee2mqtt-v2.sh} (100%) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt-v2.sh similarity index 100% rename from ct/zigbee2mqtt.sh rename to ct/zigbee2mqtt-v2.sh From 4838a96dfbdc7b1c06f44afa095860e97bf9e26c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:25:05 -0400 Subject: [PATCH 2133/6505] Update technitiumdns.sh --- ct/technitiumdns.sh | 430 ++++++++++++++++++++++++-------------------- 1 file changed, 233 insertions(+), 197 deletions(-) diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index 2d960480..9bab2b03 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -1,12 +1,21 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' +BGN=`echo "\033[4;92m"` GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` CL=`echo "\033[m"` -APP="Technitium DNS" -HN=$(echo ${APP,,} | tr -d ' ') +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Debian" +NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -18,10 +27,9 @@ done clear function header_info { echo -e "${RD} - _______ _ _ _ _ |__ __| | | (_) | (_) - | | ___ ___| |__ _ __ _| |_ _ _ _ _ __ ___ + | | ___v3___| |__ _ __ _| |_ _ _ _ _ __ ___ | |/ _ \/ __| _ \| _ \| | __| | | | | _ _ \ | | __/ (__| | | | | | | | |_| | |_| | | | | | | |_|\___|\___|_| |_|_| |_|_|\__|_|\__,_|_| |_| |_| @@ -29,174 +37,221 @@ ${CL}" } header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi } -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } - if [ "$IM" == "1" ]; then + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" @@ -205,19 +260,20 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -export CTID=$(pvesh get /cluster/nextid) +export CTID=$CT_ID export PCT_OSTYPE=debian export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 +export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit @@ -225,35 +281,15 @@ STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F " if [ "$STORAGE_TYPE" == "zfspool" ]; then warn "Some addons may not work due to ZFS not supporting 'fallocate'." fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " +msg_info "Starting LXC Container" pct start $CTID -echo -e "${CM}${CL} \r" +msg_ok "Started LXC Container" -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/technitiumdns-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5380${CL} \n" From d7c78e8575f7f0590d4f89ed5eef23328763bf31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:27:14 -0400 Subject: [PATCH 2134/6505] Create technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 295 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 ct/technitiumdns-v3.sh diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh new file mode 100644 index 00000000..9bab2b03 --- /dev/null +++ b/ct/technitiumdns-v3.sh @@ -0,0 +1,295 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Debian" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _______ _ _ _ _ + |__ __| | | (_) | (_) + | | ___v3___| |__ _ __ _| |_ _ _ _ _ __ ___ + | |/ _ \/ __| _ \| _ \| | __| | | | | _ _ \ + | | __/ (__| | | | | | | | |_| | |_| | | | | | | + |_|\___|\___|_| |_|_| |_|_|\__|_|\__,_|_| |_| |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/technitiumdns-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5380${CL} \n" From a091aae1840e7952a503230979c000a26973a08e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:28:11 -0400 Subject: [PATCH 2135/6505] Update and rename technitiumdns.sh to technitiumdns-v2.sh --- ct/technitiumdns-v2.sh | 259 ++++++++++++++++++++++++++++++++++++ ct/technitiumdns.sh | 295 ----------------------------------------- 2 files changed, 259 insertions(+), 295 deletions(-) create mode 100644 ct/technitiumdns-v2.sh delete mode 100644 ct/technitiumdns.sh diff --git a/ct/technitiumdns-v2.sh b/ct/technitiumdns-v2.sh new file mode 100644 index 00000000..2d960480 --- /dev/null +++ b/ct/technitiumdns-v2.sh @@ -0,0 +1,259 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +APP="Technitium DNS" +HN=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + _______ _ _ _ _ + |__ __| | | (_) | (_) + | | ___ ___| |__ _ __ _| |_ _ _ _ _ __ ___ + | |/ _ \/ __| _ \| _ \| | __| | | | | _ _ \ + | | __/ (__| | | | | | | | |_| | |_| | | | | | | + |_|\___|\___|_| |_|_| |_|_|\__|_|\__,_|_| |_| |_| +${CL}" +} + +header_info +show_menu(){ + printf " ${YW} 1)${YW} Privileged ${CL}\n" + printf " ${YW} 2)${GN} Unprivileged ${CL}\n" + + printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message1=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" +} +show_menu +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Privileged Install"; + IM=0 + break; + ;; + 2) clear; + header_info; + option_picked "Using Unprivileged Install"; + IM=1 + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Install Method from the menu"; + show_menu; + ;; + esac + done +show_menu2(){ + printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" + printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" + + printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message2=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" +} +show_menu2 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic Login"; + PW=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Password (changeme)"; + PW="-password changeme" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a Password Type from the menu"; + show_menu2; + ;; + esac + done +show_menu3(){ + printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" + printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" + + printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." + read opt +} + +option_picked(){ + message3=${@:-"${CL}Error: No message passed"} + printf " ${YW}${message1}${CL}\n" + printf " ${YW}${message2}${CL}\n" + printf " ${YW}${message3}${CL}\n" +} +show_menu3 +while [ "$opt" != " " ] + do + case $opt in + 1) clear; + header_info; + option_picked "Using Automatic DHCP"; + DHCP=" " + break; + ;; + 2) clear; + header_info; + option_picked "Using Manual DHCP"; + DHCP="1" + break; + ;; + + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose a DHCP Type from the menu"; + show_menu3; + ;; + esac + done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if $(pct status $CTID &>/dev/null); then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then + pvesm free $ROOTFS + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + if [ "$IM" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$(pvesh get /cluster/nextid) +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=2 +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -onboot 1 + -cores 1 + -memory 512 + -unprivileged ${IM} + ${PW} +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$DHCP" == "1" ]; then +MAC=$(pct config $CTID \ +| grep -i hwaddr \ +| awk '{print substr($2, 31, length($3) 17 ) }') \ + +echo -e "MAC Address ${BL}$MAC${CL}" + +dhcp_reservation(){ + printf "Please set DHCP reservation and press Enter." + read +} +dhcp_reservation +fi + +echo -en "${GN} Starting LXC Container... " +pct start $CTID +echo -e "${CM}${CL} \r" + +alias lxc-cmd="lxc-attach -n $CTID --" + +lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. +${BL}${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh deleted file mode 100644 index 9bab2b03..00000000 --- a/ct/technitiumdns.sh +++ /dev/null @@ -1,295 +0,0 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Debian" -NSAPP=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _______ _ _ _ _ - |__ __| | | (_) | (_) - | | ___v3___| |__ _ __ _| |_ _ _ _ _ __ ___ - | |/ _ \/ __| _ \| _ \| | __| | | | | _ _ \ - | | __/ (__| | | | | | | | |_| | |_| | | | | | | - |_|\___|\___|_| |_|_| |_|_|\__|_|\__,_|_| |_| |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN="-tag $VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET - $VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/technitiumdns-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5380${CL} \n" From eaab213b0516cac1be1e50e7e86248611080758c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:31:57 -0400 Subject: [PATCH 2136/6505] Update technitiumdns-install.sh --- setup/technitiumdns-install.sh | 71 +++++++++++++++------------------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 525ed33b..934a053d 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,27 +37,26 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Technitium DNS... " +msg_info "Installing Technitium DNS" curl -sSL https://download.technitium.com/dns/install.sh | sudo bash &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Technitium DNS" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -78,11 +69,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 6c89c3d48ab3e3ef284576a025e58e8fb383ec27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:36:13 -0400 Subject: [PATCH 2137/6505] Rename esphome.sh to esphome-v2.sh --- ct/{esphome.sh => esphome-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{esphome.sh => esphome-v2.sh} (100%) diff --git a/ct/esphome.sh b/ct/esphome-v2.sh similarity index 100% rename from ct/esphome.sh rename to ct/esphome-v2.sh From 17fad9e4b7adf4be732900235876232ef6d5b197 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:44:23 -0400 Subject: [PATCH 2138/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 9bab2b03..f922fb0d 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -14,7 +14,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -APP="Debian" +APP="Technitium DNS" NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn From f4fdb8c72c09584d08fef4a91c1c29a52fa21bef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:48:25 -0400 Subject: [PATCH 2139/6505] Create esphome-v3.sh --- ct/esphome-v3.sh | 296 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 ct/esphome-v3.sh diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh new file mode 100644 index 00000000..f5180e74 --- /dev/null +++ b/ct/esphome-v3.sh @@ -0,0 +1,296 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="ESPHome" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + ______ _____ _____ _ _ ____ __ __ ______ + | ____|/ ____| __ \| | | |/ __ \| \/ | ____| + | |__ | (___ | |__) | |__| | | | | \ / | |__ + | __| \___ \| ___/| __ | | | | |\/| | __| + | |____ ____) | | | | | | |__| | | | | |____ + |______|_____/|_| v3 |_| |_|\____/|_| |_|______| + +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + warn "Some addons may not work due to ZFS not supporting 'fallocate'." +fi + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/esphome-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6052${CL} \n" From dd6fae7f776cac2aa8171d618b6c193f04d668fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:49:47 -0400 Subject: [PATCH 2140/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index f922fb0d..2ff5df72 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -75,7 +75,7 @@ function default_settings() { DISK_SIZE="2" echo -e "${DGN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp @@ -191,7 +191,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -207,7 +207,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 962ce024ff02bb28472157715e6803e9cb029206 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:50:36 -0400 Subject: [PATCH 2141/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index f5180e74..d738561d 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -76,7 +76,7 @@ function default_settings() { DISK_SIZE="4" echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp From 9b06cdc9cf8b80fb221bc9ab013e7031b86dcb7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:51:43 -0400 Subject: [PATCH 2142/6505] Update debian-v3.sh --- ct/debian-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 1567da12..d83514d7 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -75,7 +75,7 @@ function default_settings() { DISK_SIZE="2" echo -e "${DGN}Using ${BGN}1vCPU${CL}" CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp @@ -191,7 +191,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -207,7 +207,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 034b88caa993eb534cce88d43dcd2657e733e602 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:53:26 -0400 Subject: [PATCH 2143/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 636d0fb1..54be579d 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -74,7 +74,7 @@ function default_settings() { DISK_SIZE="16" echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp @@ -190,7 +190,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -206,7 +206,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From d16d459aa487efc4fc05319c2555374a9f037cb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 15:54:43 -0400 Subject: [PATCH 2144/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 597d2bb0..83da0308 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -76,7 +76,7 @@ function default_settings() { DISK_SIZE="4" echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp @@ -192,7 +192,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -208,7 +208,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -229,7 +229,7 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${GN} RAM${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 8942614fd2c847f7608dcaa07a415adcfe76d907 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:12:14 -0400 Subject: [PATCH 2145/6505] Update esphome-install.sh --- setup/esphome-install.sh | 90 ++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 24e23f72..8017f631 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -1,38 +1,31 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,31 +38,28 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null +msg_info "Updating Container OS" +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" -echo -en "${GN} Installing pip3... " -apt-get install python3-pip -y &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "Installing pip3" +apt-get install -y python3-pip &>/dev/null +msg_ok "Installed pip3" -echo -en "${GN} Installing ESPHome... " +msg_info "Installing ESPHome" pip3 install esphome &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed ESPHome" -echo -en "${GN} Installing ESPHome Dashboard... " +msg_info "Installing ESPHome Dashboard" pip3 install tornado esptool &>/dev/null service_path="/etc/systemd/system/esphomeDashboard.service" @@ -84,11 +74,11 @@ User=root WantedBy=multi-user.target" > $service_path systemctl enable esphomeDashboard.service &>/dev/null systemctl start esphomeDashboard -echo -e "${CM}${CL} \r" +msg_ok "Installed ESPHome Dashboard" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -101,11 +91,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 4a604154b844f791f3a6602a350921a47d79b8cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:15:46 -0400 Subject: [PATCH 2146/6505] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 52312421..3a32393d 100644 --- a/README.md +++ b/README.md @@ -335,16 +335,16 @@ Update from the Homebridge UI
    - ESPHome LXC + 🔸ESPHome LXC

    ESPHome LXC

    -To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -1120,17 +1120,17 @@ ________________________________________________________________________________
    - Technitium DNS LXC + 🔸Technitium DNS LXC

    Technitium DNS LXC

    An open source authoritative as well as recursive DNS server -To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    From 7220c355eec028e7e782c3a377fca1824c045f6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:31:51 -0400 Subject: [PATCH 2147/6505] Update esphome-install.sh --- setup/esphome-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 8017f631..0daeac42 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -49,6 +49,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing pip3" From c5a47551f442cd6a1db55c548211f0ba7782406b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:33:30 -0400 Subject: [PATCH 2148/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index db356a11..ad0fcada 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -13,6 +13,10 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Zwavejs2MQTT LXC** - New V3 Install Script +- **ESPHome LXC** + - New V3 Install Script +- **Technitium DNS LXC** + - New V3 Install Script ## 2022-04-16 From ed113f47c37b4ebdf1ad99d05fc32d0fe5346d15 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:44:25 -0400 Subject: [PATCH 2149/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 54be579d..0d6e482c 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -278,7 +278,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG From 5b05c39d22c0d8acebd387df1ac9f43482d8effe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:45:11 -0400 Subject: [PATCH 2150/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index d738561d..75d44abc 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -280,7 +280,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" fi msg_info "Starting LXC Container" From 0f535f86659a0ea361c6aaa27a6d794af4c3798d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:45:47 -0400 Subject: [PATCH 2151/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index d83514d7..7e2e371d 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -279,7 +279,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" fi msg_info "Starting LXC Container" From a71b1762cbfdafa7ce4493a775aed4e72c0fb2fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:46:55 -0400 Subject: [PATCH 2152/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 2ff5df72..332221a8 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -279,7 +279,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" fi msg_info "Starting LXC Container" From 2a22fd76b47353f5d7b2b400731aa17917ba4b55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:47:27 -0400 Subject: [PATCH 2153/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 83da0308..e4dd28d3 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -280,7 +280,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf From 6193f0afcab882129874b3e4ed3ebd5dd02e69a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 16:48:01 -0400 Subject: [PATCH 2154/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 5a47c301..74a2e586 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -279,7 +279,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG From 06ea0964c4462b30b23c12019f6eee51dc739bb2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 17:44:50 -0400 Subject: [PATCH 2155/6505] Create podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 307 ++++++++++++++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 ct/podman-homeassistant-v3.sh diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh new file mode 100644 index 00000000..927c9183 --- /dev/null +++ b/ct/podman-homeassistant-v3.sh @@ -0,0 +1,307 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="PHome Assistant" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _____ _ + | __ \ | | + | |__) |__ __| |_ __ ___ __ _ _ __ + | ___/ _ \ / _ | _ _ \ / _ | _ \ + | | | (_) | (_| | | | | | | (_| | | | | + |_| \___/ \__,_|_| |_| |_|\__,_|_| |_| _ _ _ + | | v3 (_) | | | | + | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ + | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| + +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}16GB${CL}" + DISK_SIZE="16" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="16"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} +PVE_CHECK +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman-homeassistant-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} +Yacht should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL}\n" From e8ee4849520940906ddc5f0a1ef0f1331bbb2ba4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 17:45:39 -0400 Subject: [PATCH 2156/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 0d6e482c..72bae187 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -248,6 +248,7 @@ function start_script() { fi; } +PVE_CHECK start_script if [ "$CT_TYPE" == "1" ]; then From b8353e346cdebb85cfde40cfff54622926040123 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:00:51 -0400 Subject: [PATCH 2157/6505] Create podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 124 ++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 setup/podman-homeassistant-install.sh diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh new file mode 100644 index 00000000..da39c87d --- /dev/null +++ b/setup/podman-homeassistant-install.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y runc &>/dev/null +msg_ok "Installed Dependencies" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") +YACHT_LATEST_VERSION=$(get_latest_release "selfhostedpro/yacht") + +msg_info "Installing Podman" +apt-get -y install podman &>/dev/null +msg_ok "Installed Podman" + +msg_info "Pulling Yacht $YACHT_LATEST_VERSION Image" +podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null +msg_ok "Pulled Yacht $YACHT_LATEST_VERSION Image" + +msg_info "Installing Yacht $YACHT_LATEST_VERSION" +podman volume create yacht >/dev/null +podman run -d \ + --privileged \ + --name yacht \ + --restart always \ + -v /var/run/podman/podman.sock:/var/run/docker.sock \ + -v yacht:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + -p 8000:8000 \ + selfhostedpro/yacht:latest &>/dev/null +msg_ok "Installed Yacht $YACHT_LATEST_VERSION" + +msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" +podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null +msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" + +msg_info "Installing Home Assistant $CORE_LATEST_VERSION" +podman volume create hass_config >/dev/null +podman run -d \ + --privileged \ + --name homeassistant \ + --restart unless-stopped \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:stable &>/dev/null +msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 6972e77617e84c44b58f8b8ae9207dbe20dbf736 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:02:26 -0400 Subject: [PATCH 2158/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 927c9183..dab3ca05 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -296,7 +296,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman-homeassistant-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/podman-homeassistant-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 40102d1c7968730f737f2a9d4f6267e13aa9812c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:09:53 -0400 Subject: [PATCH 2159/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index da39c87d..3e80c9e2 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -52,22 +52,15 @@ apt-get install -y sudo &>/dev/null apt-get install -y runc &>/dev/null msg_ok "Installed Dependencies" -get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} - -CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") -YACHT_LATEST_VERSION=$(get_latest_release "selfhostedpro/yacht") - msg_info "Installing Podman" apt-get -y install podman &>/dev/null msg_ok "Installed Podman" -msg_info "Pulling Yacht $YACHT_LATEST_VERSION Image" +msg_info "Pulling Yacht Image" podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null msg_ok "Pulled Yacht $YACHT_LATEST_VERSION Image" -msg_info "Installing Yacht $YACHT_LATEST_VERSION" +msg_info "Installing Yacht" podman volume create yacht >/dev/null podman run -d \ --privileged \ @@ -81,11 +74,11 @@ podman run -d \ selfhostedpro/yacht:latest &>/dev/null msg_ok "Installed Yacht $YACHT_LATEST_VERSION" -msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" +msg_info "Pulling Home Assistant Image" podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null -msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" +msg_ok "Pulled Home Assistant Image" -msg_info "Installing Home Assistant $CORE_LATEST_VERSION" +msg_info "Installing Home Assistant" podman volume create hass_config >/dev/null podman run -d \ --privileged \ From 5b4b6fc1bfca695fa245788a448451af5dfbba7a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:17:25 -0400 Subject: [PATCH 2160/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 3e80c9e2..e2b1108e 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -58,7 +58,7 @@ msg_ok "Installed Podman" msg_info "Pulling Yacht Image" podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null -msg_ok "Pulled Yacht $YACHT_LATEST_VERSION Image" +msg_ok "Pulled Yacht Image" msg_info "Installing Yacht" podman volume create yacht >/dev/null @@ -72,7 +72,7 @@ podman run -d \ -v /etc/timezone:/etc/timezone:ro \ -p 8000:8000 \ selfhostedpro/yacht:latest &>/dev/null -msg_ok "Installed Yacht $YACHT_LATEST_VERSION" +msg_ok "Installed Yacht" msg_info "Pulling Home Assistant Image" podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null @@ -90,7 +90,7 @@ podman run -d \ -v /etc/timezone:/etc/timezone:ro \ --net=host \ homeassistant/home-assistant:stable &>/dev/null -msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" +msg_ok "Installed Home Assistant" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From d3bc24699493727f0aecdaf7b96249fd579d8a98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:37:19 -0400 Subject: [PATCH 2161/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index e2b1108e..9cb2ad86 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -110,6 +110,16 @@ systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +podman generate systemd \ + --new --name homeassistant \ + > /etc/systemd/system/homeassistant.service +systemctl enable homeassistant &>/dev/null + +podman generate systemd \ + --new --name yacht \ + > /etc/systemd/system/yacht.service +systemctl enable yacht &>/dev/null + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null From 6685ba3676136d4883fd5ad5c874663b6efdfd83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:38:02 -0400 Subject: [PATCH 2162/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index dab3ca05..c3e459d4 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -13,7 +13,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -APP="PHome Assistant" +APP="P-Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn From d2cbc9f725284be9d0bf6894539a0d58d458ecdc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:41:52 -0400 Subject: [PATCH 2163/6505] Update README.md --- README.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3a32393d..4d099718 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ ________________________________________________________________________________
    - Home Assistant Container LXC (Podman) + 🔸Home Assistant Container LXC (Podman)

    @home-assistant

    @@ -212,12 +212,10 @@ To create a new Proxmox Podman Home Assistant Container, run the following in th ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman_ha_container.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **Home Assistant Interface - IP:8123** **Yacht Interface - IP:8000** @@ -258,12 +256,6 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/podman_hac ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **To Update Home Assistant:** - -Run in the LXC console -```yaml -./update.sh -``` ⚙️ **Initial Yacht Login** **username** From 4b00d1fcb14fd39b70ebbd5918243da8443a5711 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:43:08 -0400 Subject: [PATCH 2164/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ad0fcada..4a1f8abb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Technitium DNS LXC** - New V3 Install Script +- **Podman Home Assistant LXC** + - New V3 Install Script ## 2022-04-16 From 24e5fd667ae04f227146b297d9dc6f7cd02fbd55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:46:05 -0400 Subject: [PATCH 2165/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4d099718..b6a785c2 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ ________________________________________________________________________________

    Home Assistant Container LXC

    -To create a new Proxmox Home Assistant Container, run the following in the Proxmox Shell. +To create a new Proxmox Home Assistant Container LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-v3.sh)" @@ -201,13 +201,13 @@ ________________________________________________________________________________
    - 🔸Home Assistant Container LXC (Podman) + 🔸Podman Home Assistant Container LXC

    @home-assistant

    Podman Home Assistant Container LXC

    -To create a new Proxmox Podman Home Assistant Container, run the following in the Proxmox Shell. +To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) From 56dfc4cf27fbdc8b05052c8a43558bf41e9578fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 18:48:30 -0400 Subject: [PATCH 2166/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index c3e459d4..c92ac739 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -296,7 +296,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/podman-homeassistant-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman-homeassistant-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 3bbaeb1b6bdc4700d43577ccb8b28467c8269fc3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 19:20:02 -0400 Subject: [PATCH 2167/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b6a785c2..e8b67992 100644 --- a/README.md +++ b/README.md @@ -209,7 +209,7 @@ ________________________________________________________________________________

    Podman Home Assistant Container LXC

    To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. - ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) + ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ⚠️ Podman seems to need a priviliged LXC ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v3.sh)" From 68e58d497acef13bfccadf23b90c0587249b7b8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 19:21:22 -0400 Subject: [PATCH 2168/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e8b67992..7c9c28fd 100644 --- a/README.md +++ b/README.md @@ -209,7 +209,7 @@ ________________________________________________________________________________

    Podman Home Assistant Container LXC

    To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. - ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ⚠️ Podman seems to need a priviliged LXC + ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ⚠️ Podman seems to need a privileged LXC ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v3.sh)" From a194c1428338eaad1837356783a6d9e0eafdcdfc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 19:33:36 -0400 Subject: [PATCH 2169/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7c9c28fd..1b58179e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 🔸
    - 🔸Proxmox VE 7 Post Install + Proxmox VE 7 Post Install

    @@ -64,7 +64,7 @@ ________________________________________________________________________________
    - 🔸Proxmox LXC Updater + Proxmox LXC Updater

    From 51874d8ac1ad59523e573489207c62faaabdb314 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 19:53:15 -0400 Subject: [PATCH 2170/6505] Create docker-v3.sh --- ct/docker-v3.sh | 298 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 ct/docker-v3.sh diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh new file mode 100644 index 00000000..1420c176 --- /dev/null +++ b/ct/docker-v3.sh @@ -0,0 +1,298 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Docker" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _____ _ + | __ \ | | + | | | | ___ ___| | _____ _ __ + | |v3| |/ _ \ / __| |/ / _ \ __| + | |__| | (_) | (__| < __/ | + |_____/ \___/ \___|_|\_\___|_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +PVE_CHECK +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" +fi +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/docker-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" From 9074e48a2770f839ebdbe536a8dc18143e84a531 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 19:59:59 -0400 Subject: [PATCH 2171/6505] Update docker-install.sh --- setup/docker-install.sh | 79 ++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index f2a7081c..196d3a89 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,19 +37,18 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" get_latest_release() { curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 @@ -67,7 +58,7 @@ DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") -echo -en "${GN} Installing Docker $DOCKER_LATEST_VERSION... " +msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) cat >$DOCKER_CONFIG_PATH <<'EOF' @@ -76,7 +67,7 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' } EOF sh <(curl -sSL https://get.docker.com) &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" read -r -p "Would you like to add Portainer? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] @@ -87,7 +78,7 @@ PORTAINER="N" fi if [[ $PORTAINER == "Y" ]]; then -echo -en "${GN} Installing Portainer $PORTAINER_LATEST_VERSION... " +msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null docker run -d \ -p 8000:8000 \ @@ -97,7 +88,7 @@ docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" fi read -r -p "Would you like to add Docker Compose? " prompt @@ -109,17 +100,17 @@ DOCKER_COMPOSE="N" fi if [[ $DOCKER_COMPOSE == "Y" ]]; then -echo -en "${GN} Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION... " +msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose -echo -e "${CM}${CL} \r" +msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" fi PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -132,11 +123,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 97f1dac0fd2b8a4efe40f387fffdf85e61e76cee Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:01:10 -0400 Subject: [PATCH 2172/6505] Update docker-v3.sh --- ct/docker-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 1420c176..a23a3e70 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -291,7 +291,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/docker-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/docker-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From c4164d4140a33bb864f9849b131f0871a7699c4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:08:42 -0400 Subject: [PATCH 2173/6505] Update docker-v3.sh --- ct/docker-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index a23a3e70..1420c176 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -291,7 +291,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v3/setup/docker-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/docker-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 46f6d38b866809ecc5d718045441dbe4b490f360 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:12:16 -0400 Subject: [PATCH 2174/6505] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1b58179e..8c4cb807 100644 --- a/README.md +++ b/README.md @@ -841,23 +841,21 @@ ________________________________________________________________________________
    - Docker LXC + 🔸Docker LXC

    Docker LXC

    -

    With Selectable ZFS Storage Drivers & Option to Add Portainer and/or Docker Compose

    +

    Options to Install Portainer and/or Docker Compose

    -To create a new Proxmox Docker LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Docker LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **Portainer Interface - IP:9000** ⚙️ **To Update** From 8727760c4727f17a703a6c598123b2bda7d7611e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:13:31 -0400 Subject: [PATCH 2175/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4a1f8abb..4fdaef36 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -19,6 +19,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Podman Home Assistant LXC** - New V3 Install Script +- **Docker LXC** + - New V3 Install Script ## 2022-04-16 From 1c504b9d305b5416495deccaad464154d111f601 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:14:01 -0400 Subject: [PATCH 2176/6505] Rename docker.sh to docker-v2.sh --- ct/{docker.sh => docker-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{docker.sh => docker-v2.sh} (100%) diff --git a/ct/docker.sh b/ct/docker-v2.sh similarity index 100% rename from ct/docker.sh rename to ct/docker-v2.sh From 02a1d525ddd2d73b2e56caa4b00f58f44ab1d323 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:24:58 -0400 Subject: [PATCH 2177/6505] Create photoprism-v3.sh --- ct/photoprism-v3.sh | 295 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 ct/photoprism-v3.sh diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh new file mode 100644 index 00000000..71a9ef3e --- /dev/null +++ b/ct/photoprism-v3.sh @@ -0,0 +1,295 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +PP=`echo "\e[1;35m"` +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="PhotoPrism" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _____ _ _ _____ _ + | __ \| | | | | __ \ (_) + | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ + | ___/| _ \ / _ \| __/ _ \| ___/ __| / __| _ _ \ + | | | | | | (_) | || (_) | | | | | \__ \ | | | | | + |_| v3 |_| |_|\___/ \__\___/|_| |_| |_|___/_| |_| |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN="-tag $VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET + $VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') +if [ "$STORAGE_TYPE" == "zfspool" ]; then + echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" +fi + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/photoprism-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:2342${CL} \n" From 5aba72533c64e3ae26b2ae86dd1a81fa1c305116 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:36:15 -0400 Subject: [PATCH 2178/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 96 +++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 52 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 5ef65f42..52c24c4a 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,37 +1,30 @@ -#!/usr/bin/env bash -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -44,16 +37,15 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y gcc &>/dev/null @@ -63,23 +55,23 @@ apt-get install -y gnupg &>/dev/null apt-get install -y make &>/dev/null apt-get install -y zip &>/dev/null apt-get install -y unzip &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Installing Golang... " +msg_info "Installing Golang" wget https://golang.org/dl/go1.18.linux-amd64.tar.gz &>/dev/null tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Golang" -echo -en "${GN} Installing Tensorflow... " +msg_info "Installing Tensorflow" AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) if [[ "$AVX" == "avx2" ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null @@ -94,21 +86,21 @@ if [[ "$AVX" == "avx2" ]]; then tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null ldconfig &>/dev/null fi -echo -e "${CM}${CL} \r" +msg_ok "Installed Tensorflow" -echo -en "${GN} Cloning PhotoPrism... " +msg_info "Cloning PhotoPrism" mkdir -p /opt/photoprism/bin mkdir /var/lib/photoprism git clone https://github.com/photoprism/photoprism.git &>/dev/null cd photoprism git checkout release &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Cloned PhotoPrism" -echo -en "${GN} Building PhotoPrism... " +msg_info "Building PhotoPrism" make all &>/dev/null ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null cp -a assets/ /opt/photoprism/assets/ &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Built PhotoPrism" env_path="/var/lib/photoprism/.env" echo " @@ -118,7 +110,7 @@ PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' " > $env_path -echo -en "${GN} Creating Service file photoprism.service... " +msg_info "Creating Service" service_path="/etc/systemd/system/photoprism.service" echo "[Unit] @@ -136,11 +128,11 @@ ExecStop=/opt/photoprism/bin/photoprism down [Install] WantedBy=multi-user.target" > $service_path systemctl enable --now photoprism &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -153,11 +145,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/go -echo -e "${CM}${CL} \n" +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 0adf5d10507f3dce16261f5ad72edd30f1e6a2c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:36:55 -0400 Subject: [PATCH 2179/6505] Rename photoprism.sh to photoprism-v2.sh --- ct/{photoprism.sh => photoprism-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{photoprism.sh => photoprism-v2.sh} (100%) diff --git a/ct/photoprism.sh b/ct/photoprism-v2.sh similarity index 100% rename from ct/photoprism.sh rename to ct/photoprism-v2.sh From d559cbf000a98f52a622a2b6e4412e0c4383a1a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:39:56 -0400 Subject: [PATCH 2180/6505] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8c4cb807..ad40af0a 100644 --- a/README.md +++ b/README.md @@ -1260,7 +1260,7 @@ ________________________________________________________________________________
    - PhotoPrism LXC + 🔸PhotoPrism LXC

    @@ -1268,16 +1268,14 @@ ________________________________________________________________________________ PhotoPrism® is an AI-powered app for browsing, organizing & sharing your photo collection. -To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **PhotoPrism Interface - IP:2342** ⚙️ **Initial Login** From 93234cd36cf524d7f19bcc1434923cfa61e05c1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 20:41:08 -0400 Subject: [PATCH 2181/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4fdaef36..9a3e8682 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -21,6 +21,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Docker LXC** - New V3 Install Script +- **PhotoPrism LXC** + - New V3 Install Script ## 2022-04-16 From bba671fd044d70aefaa9a568fc5c93ae26e6c1ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:30:00 -0400 Subject: [PATCH 2182/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 332221a8..85e9e3e0 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -209,6 +209,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="-gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -230,6 +253,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r @@ -267,7 +291,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,$GATE,ip=$NET $VLAN -onboot 1 -cores $CORE_COUNT From 9c19cf871c443f07e2848a630c850401d5e9c67a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:35:59 -0400 Subject: [PATCH 2183/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 85e9e3e0..761150f1 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -79,8 +79,10 @@ function default_settings() { RAM_SIZE="512" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { @@ -214,7 +216,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="-gw=$GATE1" + GATE="gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" From b9bb0d6784eede36c7ee4e040c2e6836c86f29e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:42:13 -0400 Subject: [PATCH 2184/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 71a9ef3e..582ff69c 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -79,8 +79,10 @@ function default_settings() { RAM_SIZE="2048" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { @@ -209,6 +211,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="-gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -230,6 +255,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From 710b6ce3294c20548c95e953ab8dcf112137b407 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:49:30 -0400 Subject: [PATCH 2185/6505] Update debian-v3.sh --- ct/debian-v3.sh | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 7e2e371d..b6ec7ea8 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -79,8 +79,10 @@ function default_settings() { RAM_SIZE="512" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { @@ -209,6 +211,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -230,6 +255,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From 98f949a5ecb80c5e592473d85e76024ef054f4ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:52:55 -0400 Subject: [PATCH 2186/6505] Update docker-v3.sh --- ct/docker-v3.sh | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 1420c176..6b05fe5a 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -77,9 +77,11 @@ function default_settings() { echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { @@ -208,6 +210,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -229,6 +254,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From 5fd42b8f3b6337d50146b333a389243502d71533 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:54:50 -0400 Subject: [PATCH 2187/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 75d44abc..2d6fa4c3 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -80,8 +80,10 @@ function default_settings() { RAM_SIZE="1024" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { @@ -210,6 +212,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -231,8 +256,8 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - read -p "Are these settings correct(y/n)? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]] From e2ff9a51aa42e7446e72cab7b4351142757fe8ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:56:44 -0400 Subject: [PATCH 2188/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 72bae187..f147cfe7 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -78,8 +78,10 @@ function default_settings() { RAM_SIZE="2048" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { @@ -208,6 +210,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -229,6 +254,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From 1fee62841f159f420b8ad04eb00fa84541eeb265 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 21:58:20 -0400 Subject: [PATCH 2189/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index c92ac739..15c837b7 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -84,8 +84,10 @@ function default_settings() { RAM_SIZE="2048" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " } function advanced_settings() { @@ -214,6 +216,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -235,6 +260,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From 014500782b179f39afe4abf6e3321e9520ae6551 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:00:29 -0400 Subject: [PATCH 2190/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index e4dd28d3..aafd2f5f 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -80,7 +80,9 @@ function default_settings() { RAM_SIZE="1024" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN=" " } @@ -210,6 +212,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -231,8 +256,8 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - read -p "Are these settings correct(y/n)? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]] From 372ecedb383afc2b8e45fa3e9b0d14486becb2f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:03:45 -0400 Subject: [PATCH 2191/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 74a2e586..0d9d226e 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -79,7 +79,9 @@ function default_settings() { RAM_SIZE="1024" echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" NET=dhcp - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN=" " } @@ -209,6 +211,29 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE="gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; @@ -230,6 +255,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From 643b3c9ce47d068a25474b490d96314e18fba3e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:06:20 -0400 Subject: [PATCH 2192/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 582ff69c..7c90ac2e 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -216,7 +216,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="-gw=$GATE1" + GATE="gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" From 93caefd41c6a969c410ef3faf07885e963e9e197 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:17:21 -0400 Subject: [PATCH 2193/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 761150f1..090497b1 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -216,7 +216,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,$GATE,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 671eedb5c1a8056aaf10754ffecfb2475ecefa80 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:20:57 -0400 Subject: [PATCH 2194/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index b6ec7ea8..06dab24a 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -216,7 +216,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 2605172b88068b17c14ab2452f50cdecd1b0e265 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:23:33 -0400 Subject: [PATCH 2195/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 2d6fa4c3..67eada7f 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -217,7 +217,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 2d83c76ddd8e41c9a3d799e211bd58929d7ac5f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:25:17 -0400 Subject: [PATCH 2196/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index f147cfe7..6dc3bee3 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -215,7 +215,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 74d947a9321bf4ae3380fda8cbf96c623191dd23 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:26:11 -0400 Subject: [PATCH 2197/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 7c90ac2e..fb685417 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -216,7 +216,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 98a97aa7b4c18341bf3304895a084c46b1cda6f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:26:53 -0400 Subject: [PATCH 2198/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 15c837b7..44e32429 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -221,7 +221,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -298,7 +298,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From f77939f3372b25db545ad02e202770fdf3b2c169 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:28:14 -0400 Subject: [PATCH 2199/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index aafd2f5f..c4d08d77 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -217,7 +217,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 8fc96bac41bd920eba876bb036b3d9269e42d1a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:29:19 -0400 Subject: [PATCH 2200/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 0d9d226e..d5a907e3 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -216,7 +216,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 3f41b0cfe42c068a67db19be2b114a1cd9a45df6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 22:31:53 -0400 Subject: [PATCH 2201/6505] Update docker-v3.sh --- ct/docker-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 6b05fe5a..9b0a96f0 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -215,7 +215,7 @@ header_info if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From c6abeae945802d48b643d14b677b60911507c77c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:12:16 -0400 Subject: [PATCH 2202/6505] Update docker-v3.sh --- ct/docker-v3.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 6b05fe5a..1ecf319d 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -76,7 +76,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -193,10 +193,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -209,13 +209,13 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else - GATE="gw=$GATE1" + GATE=",gw=$GATE1" echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -231,7 +231,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -253,7 +253,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE $VLAN -onboot 1 -cores $CORE_COUNT From 8e96dd6b3fbe5ec5ba60f285db45b67f6d8f9985 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:17:41 -0400 Subject: [PATCH 2203/6505] Update docker-v3.sh --- ct/docker-v3.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 1ecf319d..c4a49b96 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -66,7 +66,7 @@ function default_settings() { CT_TYPE="1" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -129,7 +129,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -145,7 +145,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " read DISK_SIZE @@ -159,7 +159,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -173,7 +173,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -188,7 +188,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -204,7 +204,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -226,7 +226,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -248,7 +248,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" From dcf8799dfb3f3bb96f79167cf350209005a840d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:26:55 -0400 Subject: [PATCH 2204/6505] Update debian-v3.sh --- ct/debian-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 06dab24a..53b1480c 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -67,7 +67,7 @@ function default_settings() { CT_TYPE="1" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -130,7 +130,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -146,7 +146,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " read DISK_SIZE @@ -160,7 +160,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " @@ -174,7 +174,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -189,15 +189,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -205,12 +205,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -227,12 +227,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -249,12 +249,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From f610003bb4aed83c7dacdae5327ed51e1ff3b7fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:29:28 -0400 Subject: [PATCH 2205/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 67eada7f..e7daabbb 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -68,7 +68,7 @@ function default_settings() { CT_TYPE="1" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -78,7 +78,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -131,7 +131,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -147,7 +147,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " read DISK_SIZE @@ -161,7 +161,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -175,7 +175,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -190,15 +190,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -206,12 +206,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -228,12 +228,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -250,12 +250,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From bed024ed5c37fea28acfcbe9eb53e7079a2f60b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:31:55 -0400 Subject: [PATCH 2206/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 6dc3bee3..c9603c33 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -66,7 +66,7 @@ function default_settings() { CT_TYPE="1" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -76,7 +76,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -129,7 +129,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -145,7 +145,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " read DISK_SIZE @@ -159,7 +159,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -173,7 +173,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -188,15 +188,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -204,12 +204,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -226,12 +226,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -248,12 +248,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 1cf553754d3b9e7f84610e6d29736c10f1e683fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:34:18 -0400 Subject: [PATCH 2207/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index fb685417..38e63f5c 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -67,7 +67,7 @@ function default_settings() { CT_TYPE="1" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -130,7 +130,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -146,7 +146,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " read DISK_SIZE @@ -160,7 +160,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -174,7 +174,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -189,15 +189,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -205,12 +205,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -227,12 +227,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -249,12 +249,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 869285029819badc01c03133521f63b9a8067f2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:36:25 -0400 Subject: [PATCH 2208/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 44e32429..f6eddabb 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -72,7 +72,7 @@ function default_settings() { CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -82,7 +82,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -135,7 +135,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -151,7 +151,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " read DISK_SIZE @@ -165,7 +165,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -179,7 +179,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -194,15 +194,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,12 +210,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -232,12 +232,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -254,12 +254,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From b24c5995640a8099765466d3963136ef3f496cc3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:40:59 -0400 Subject: [PATCH 2209/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 090497b1..ee85ca21 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -67,7 +67,7 @@ function default_settings() { CT_TYPE="1" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -130,7 +130,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -146,7 +146,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " read DISK_SIZE @@ -160,7 +160,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " @@ -174,7 +174,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -189,15 +189,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -205,12 +205,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -227,12 +227,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -249,12 +249,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 5801b47b04e0da5b1fd91d71bb4b8077c7399907 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:43:14 -0400 Subject: [PATCH 2210/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index c4d08d77..7dec3b70 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -68,7 +68,7 @@ function default_settings() { CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -78,7 +78,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -131,7 +131,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -147,7 +147,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " read DISK_SIZE @@ -161,7 +161,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -175,7 +175,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -190,15 +190,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -206,12 +206,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -228,12 +228,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -250,12 +250,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r From 07be6671c52d14109734293649e33adf80e55e77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Apr 2022 23:46:29 -0400 Subject: [PATCH 2211/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index d5a907e3..5c8ae40d 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -67,7 +67,7 @@ function default_settings() { CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " - echo -e "${DGN}Using ID ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using IP Address ${BGN}DHCP${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" GATE=" " @@ -130,7 +130,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " read CT_NAME if [ -z $CT_NAME ]; then @@ -146,7 +146,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " read DISK_SIZE @@ -160,7 +160,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -174,7 +174,7 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -189,15 +189,15 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set IP Address To ${BL}$NET${CL}" + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -205,12 +205,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; @@ -227,12 +227,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 @@ -249,12 +249,12 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" From 4f2c242f30422ace91ff33c66083dd00718fc793 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 00:00:38 -0400 Subject: [PATCH 2212/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9a3e8682..663f60b0 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,7 +10,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Zigbee2MQTT LXC** - - New V3 Install Script + - New [V3 Install Script](https://github.com/tteck/Proxmox/issues/162) - **Zwavejs2MQTT LXC** - New V3 Install Script - **ESPHome LXC** From e05c651189764f426a62dec36201095f048de4c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:08:25 -0400 Subject: [PATCH 2213/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index ee85ca21..97d40b84 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -239,7 +239,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag $VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 2e5cacaa3b84cf331c6d7a6dc261419a714012f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:17:42 -0400 Subject: [PATCH 2214/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 97d40b84..fe686355 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -239,7 +239,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN=",tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" From 9b34f012c219b8f407a817dfcf7e59ec0ab6fb91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:27:10 -0400 Subject: [PATCH 2215/6505] Update debian-v3.sh --- ct/debian-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 53b1480c..f48e55fb 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -239,7 +239,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 3801f9e83fdc5652aac128bcbcba42a506df92ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:28:33 -0400 Subject: [PATCH 2216/6505] Update docker-v3.sh --- ct/docker-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index c4a49b96..b11e1921 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -238,7 +238,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 6a7c190b8a15a5ef1ade113b20f4bb49d91a5004 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:29:36 -0400 Subject: [PATCH 2217/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index e7daabbb..456c7549 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -240,7 +240,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From fce3b0934f1b55e498f3b22656cbee2dba6d30a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:30:52 -0400 Subject: [PATCH 2218/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index c9603c33..061d494a 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -238,7 +238,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 58c5e3a76fc678c1857a0b9ebaabee8e92fdf8a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:31:58 -0400 Subject: [PATCH 2219/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 38e63f5c..b6c970e8 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -239,7 +239,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 8ed9a3c6a3d3fe70c6a60811f73e6aa1ab17785c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:33:03 -0400 Subject: [PATCH 2220/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index f6eddabb..09fb0b11 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -244,7 +244,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -298,8 +298,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 995b671473c35f6e13ac8f10106feb608687534a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:34:12 -0400 Subject: [PATCH 2221/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index ee85ca21..fe686355 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -239,7 +239,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From ab7812a170dcda4683ddf2ca3f8a0c76da73e3c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:35:14 -0400 Subject: [PATCH 2222/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 7dec3b70..9833a07d 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -240,7 +240,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From c55779c61a4d1216e1b8809e9058346ab09c7885 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 01:36:20 -0400 Subject: [PATCH 2223/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 5c8ae40d..dbc2e72d 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -239,7 +239,7 @@ header_info if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else - VLAN="-tag $VLAN1" + VLAN=",tag=$VLAN1" echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" fi; echo -e " ${CM}${CL} \n" @@ -293,8 +293,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE - $VLAN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 5478baa23a4e07dd20d141dd29a3773c8e9a3212 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:12:28 -0400 Subject: [PATCH 2224/6505] Update debian-v3.sh --- ct/debian-v3.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index f48e55fb..e5b98317 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -302,11 +302,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi - msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From 2a5da896eab7e3adccac8f9fe23d095811757bf7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:14:05 -0400 Subject: [PATCH 2225/6505] Update docker-v3.sh --- ct/docker-v3.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index b11e1921..46da64aa 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -302,10 +302,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a From b0bc05068399c10ec33d4f552961c975da48d5b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:14:56 -0400 Subject: [PATCH 2226/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 456c7549..fbfac335 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -302,11 +302,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi - msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From 28d1481360a73063457e97558e0f18683c697ede Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:15:42 -0400 Subject: [PATCH 2227/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 061d494a..c8242a8c 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -302,10 +302,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a From f4c168033ef80caa181b9706f9fbb9cc29914f3e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:16:39 -0400 Subject: [PATCH 2228/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index b6c970e8..67547300 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -302,11 +302,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi - msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From 3acbd66d5d371de875d1edd617658c161e3307c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:17:55 -0400 Subject: [PATCH 2229/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 09fb0b11..75893d4b 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -307,10 +307,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a From f9f58b6a0f6847484768f8d0a6e65984d9e7e8fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:18:47 -0400 Subject: [PATCH 2230/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index fe686355..5a466254 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -302,11 +302,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi - msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From b542207982e79b62dcdd02bdf82179735c6b6ac6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:20:25 -0400 Subject: [PATCH 2231/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 9833a07d..c1da0388 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -275,6 +275,7 @@ function start_script() { fi; } +PVE_CHECK start_script if [ "$CT_TYPE" == "1" ]; then @@ -302,11 +303,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a From 3c6a3846aea9dd6087f7b6864a1e5f7f2c9d5d6d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:21:29 -0400 Subject: [PATCH 2232/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index dbc2e72d..12e5d42c 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -275,6 +275,7 @@ function start_script() { fi; } +PVE_CHECK start_script if [ "$CT_TYPE" == "1" ]; then @@ -302,10 +303,6 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - echo -e "${RD}Some applications may not work properly due to ZFS not supporting 'fallocate'.${CL}" -fi LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a From c9bb46536db6d41d018ce6e95bb4b3f795f92353 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:27:34 -0400 Subject: [PATCH 2233/6505] Create adguard-v3.sh --- ct/adguard-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/adguard-v3.sh diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh new file mode 100644 index 00000000..aa22f949 --- /dev/null +++ b/ct/adguard-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Adguard" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${GN} + _ _ + /\ | | | | + / \ __| | __ _ _ _ __ _ _ __ __| | + / /\ \ / _ |/ _ | | | |/ _ | __/ _ | + / ____ \ (_| | (_| | |_| | (_| | | | (_| | + /_/ \_\__,_|\__, |\__,_|\__,_|_| \__,_| + v3__/ | + |___/ +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" From 6593b554b6e9ade9a078919e115643c3c36c9526 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:31:08 -0400 Subject: [PATCH 2234/6505] Update adguard-install.sh --- setup/adguard-install.sh | 73 ++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 91e09ab3..f28f4425 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,27 +37,26 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing AdGuard Home... " +msg_info "Installing AdGuard Home" curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed AdGuard Home" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -78,11 +69,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From d00572379425f9a5e4fbd7db9f640ad1f843653a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:38:24 -0400 Subject: [PATCH 2235/6505] Create homebridge-v3.sh --- ct/homebridge-v3.sh | 315 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/homebridge-v3.sh diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh new file mode 100644 index 00000000..826573bc --- /dev/null +++ b/ct/homebridge-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Homebridge" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _ ____ __ __ ______ ____ _____ _____ _____ _____ ______ + | | | |/ __ \| \/ | ____| _ \| __ \|_ _| __ \ / ____| ____| + | |__| | | | | \ / | |__ | |_) | |__) | | | | | | | | __| |__ + | __ | | | | |\/| | __| | _ <| _ / | | | | | | | |_ | __| + | | | | |__| | | | | |____| |_) | | \ \ _| |_| |__| | |__| | |____ + |_|v3|_|\____/|_| |_|______|____/|_| \_\_____|_____/ \_____|______| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homebridge-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "Homebridge should be reachable by going to the following URL. + ${BL}http://${IP}:8581${CL} \n" From f5efbec80270174bf1dd9502479aed477bdc5088 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:39:47 -0400 Subject: [PATCH 2236/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index aa22f949..5deca39f 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -313,3 +313,5 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') msg_ok "Completed Successfully!\n" +echo -e "Adguard Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 95363971aa01c620ce2cc6c1a576a1d8c1e6611b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:40:32 -0400 Subject: [PATCH 2237/6505] Rename adguard.sh to adguard-v2.sh --- ct/{adguard.sh => adguard-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{adguard.sh => adguard-v2.sh} (100%) diff --git a/ct/adguard.sh b/ct/adguard-v2.sh similarity index 100% rename from ct/adguard.sh rename to ct/adguard-v2.sh From 7a7f59a5de965556a34dcb720a352b645bc26972 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:41:05 -0400 Subject: [PATCH 2238/6505] Rename homebridge.sh to homebridge-v2.sh --- ct/{homebridge.sh => homebridge-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{homebridge.sh => homebridge-v2.sh} (100%) diff --git a/ct/homebridge.sh b/ct/homebridge-v2.sh similarity index 100% rename from ct/homebridge.sh rename to ct/homebridge-v2.sh From 06b94c09e303162718b5f30167df466452213ded Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:43:33 -0400 Subject: [PATCH 2239/6505] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ad40af0a..3a0c8a90 100644 --- a/README.md +++ b/README.md @@ -271,17 +271,17 @@ ________________________________________________________________________________
    - Homebridge LXC + 🔸Homebridge LXC

    Homebridge LXC

    Homebridge allows you to integrate with smart home devices that do not natively support HomeKit -To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -1138,16 +1138,16 @@ ________________________________________________________________________________
    - AdGuard Home LXC + 🔸AdGuard Home LXC

    AdGuard Home LXC

    -To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    From 347269396e1920e4c96e02dbd94d168eee992cd7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:49:52 -0400 Subject: [PATCH 2240/6505] Create uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 317 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 ct/uptimekuma-v3.sh diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh new file mode 100644 index 00000000..18be8995 --- /dev/null +++ b/ct/uptimekuma-v3.sh @@ -0,0 +1,317 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Uptime Kuma" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${DGN} + _ _ _ _ _ __ + | | | | | | (_) | |/ / + | | | |_ __ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ + | | | | _ \| __| | _ _ \ / _ \ | <| | | | _ _ \ / _ | + | |__| | |_) | |_| | | | | | | __/ | . \ |_| | | | | | | (_| | + \____/| .__/ \__|_|_| |_| |_|\___| |_|\_\__,_|_| |_| |_|\__,_| + | | + |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/uptimekuma-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3001${CL}\n" From 27e95b0cc638e4428a81b46a1591c4101d07eeb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:50:49 -0400 Subject: [PATCH 2241/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index 18be8995..af05bb94 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -29,7 +29,7 @@ function header_info { echo -e "${DGN} _ _ _ _ _ __ | | | | | | (_) | |/ / - | | | |_ __ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ + | | | |_v3_ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ | | | | _ \| __| | _ _ \ / _ \ | <| | | | _ _ \ / _ | | |__| | |_) | |_| | | | | | | __/ | . \ |_| | | | | | | (_| | \____/| .__/ \__|_|_| |_| |_|\___| |_|\_\__,_|_| |_| |_|\__,_| From 5c5dc2337cc430312d9e64e96b7278045a4a78a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:51:23 -0400 Subject: [PATCH 2242/6505] Rename uptimekuma.sh to uptimekuma-v2.sh --- ct/{uptimekuma.sh => uptimekuma-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{uptimekuma.sh => uptimekuma-v2.sh} (100%) diff --git a/ct/uptimekuma.sh b/ct/uptimekuma-v2.sh similarity index 100% rename from ct/uptimekuma.sh rename to ct/uptimekuma-v2.sh From a4234a3a4294d4cdcf44c4ff9d0f809cfe63dcf9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:52:33 -0400 Subject: [PATCH 2243/6505] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3a0c8a90..9f89185d 100644 --- a/README.md +++ b/README.md @@ -1174,16 +1174,14 @@ ________________________________________________________________________________ Uptime Kuma is a self-hosted, open source, fancy uptime monitoring and alerting system. It can monitor HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server. -To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **Uptime Kuma Interface - IP:3001** ⚙️ **To Update** From 569096cc08024e9607d4355ec05a44f5e638245d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 06:55:06 -0400 Subject: [PATCH 2244/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 663f60b0..e4a4df19 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,12 +5,23 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-18 + +### Changed + +- **Adguard LXC** + - New [V3 Install Script](https://github.com/tteck/Proxmox/issues/162) +- **Homebridge LXC** + - New V3 Install Script +- **Uptime Kuma LXC** + - New V3 Install Script + ## 2022-04-17 ### Changed - **Zigbee2MQTT LXC** - - New [V3 Install Script](https://github.com/tteck/Proxmox/issues/162) + - New V3 Install Script - **Zwavejs2MQTT LXC** - New V3 Install Script - **ESPHome LXC** From 4fcd2fff62b991793750403fb6429c88d1616e96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:06:25 -0400 Subject: [PATCH 2245/6505] Create vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/vaultwarden-v3.sh diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh new file mode 100644 index 00000000..8149e55c --- /dev/null +++ b/ct/vaultwarden-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Vaultwarden" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + __ __ _ _ _ + \ \ v3 / / | | | | | + \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ + \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ + \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | + \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}4vCPU${CL}" + CORE_COUNT="4" + echo -e "${DGN}Using ${BGN}4096MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 4 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="4"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vaultwarden-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From bff567e4f13b6daa710339b4b1ffc2bdd287ab7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:07:07 -0400 Subject: [PATCH 2246/6505] Rename vaultwarden.sh to vaultwarden-v2.sh --- ct/{vaultwarden.sh => vaultwarden-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{vaultwarden.sh => vaultwarden-v2.sh} (100%) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden-v2.sh similarity index 100% rename from ct/vaultwarden.sh rename to ct/vaultwarden-v2.sh From 8cb2ec9433b40e3dc4ec7a5b7809b072dd994d7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:16:55 -0400 Subject: [PATCH 2247/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 93 ++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index ce9d60e2..71f3f34f 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,16 +37,15 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null +msg_info "Updating Container OS" +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get update &>/dev/null apt-get -qqy install \ git \ @@ -67,36 +58,36 @@ apt-get -qqy install \ libssl-dev \ curl \ sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Build Essentials... " +msg_info "Installing Build Essentials" apt-get install -y build-essential &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Build Essentials" -echo -en "${GN} Installing Rust... " +msg_info "Installing Rust" curl https://sh.rustup.rs -sSf | sh -s -- -y &>/dev/null echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null export PATH=~/.cargo/bin:$PATH &>/dev/null which rustc &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Rust" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null apt-get install -y nodejs &>/dev/null npm -g install npm@7 &>/dev/null which npm &>/dev/null npm i npm@latest -g &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Building Vaultwarden (Patience)... " +msg_info "Building Vaultwarden (Patience)" git clone https://github.com/dani-garcia/vaultwarden &>/dev/null pushd vaultwarden &>/dev/null cargo clean &>/dev/null cargo build --features sqlite --release &>/dev/null file target/release/vaultwarden &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Built Vaultwarden" -echo -en "${GN} Building Web-Vault... " +msg_info "Building Web-Vault" pushd target/release/ &>/dev/null git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null cd web-vault.git &>/dev/null @@ -110,9 +101,9 @@ npm run --silent dist:oss:selfhost &>/dev/null cp -a build ../web-vault &>/dev/null cd .. mkdir data -echo -e "${CM}${CL} \r" +msg_ok "Built Web-Vault" -echo -en "${GN} Create Systemd Service... " +msg_info "Creating Service" cp ../../.env.template /etc/vaultwarden.env &>/dev/null cp vaultwarden /usr/bin/vaultwarden &>/dev/null chmod +x /usr/bin/vaultwarden &>/dev/null @@ -145,11 +136,11 @@ WantedBy=multi-user.target" > $service_path systemctl daemon-reload systemctl enable vaultwarden.service &>/dev/null systemctl start vaultwarden.service &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -162,11 +153,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 8d2c5d0ba7bf134b84f51e353d700743dfcfdc8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:18:22 -0400 Subject: [PATCH 2248/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9f89185d..f21ca091 100644 --- a/README.md +++ b/README.md @@ -1468,7 +1468,7 @@ ________________________________________________________________________________
    - Vaultwarden LXC + 🔸Vaultwarden LXC

    @@ -1477,7 +1477,7 @@ ________________________________________________________________________________ To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden-v3.sh)" ``` ⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. From da8f7d7873dfa260ce3d587e7936f3eab4faa6e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:19:35 -0400 Subject: [PATCH 2249/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e4a4df19..d593a664 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -15,6 +15,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Uptime Kuma LXC** - New V3 Install Script +- **Vaultwarden LXC** + - New V3 Install Script ## 2022-04-17 From 5aec95f9835a6248c2d2f26fe1fd1d1b4d69f0d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:26:58 -0400 Subject: [PATCH 2250/6505] Create motioneye-v3.sh --- ct/motioneye-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/motioneye-v3.sh diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh new file mode 100644 index 00000000..8a76ccf9 --- /dev/null +++ b/ct/motioneye-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Motioneye" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + __ __ ____ _______ _____ ____ _ _ ________ ________ + | \/ |/ __ \__ __|_ _/ __ \| \ | | ____\ \ / / ____| + | \ / | | | | | | | || | | | \| | |__ \ \_/ /| |__ + | |\/| | | | | | | | || | | | | __| \ / | __| + | | | | |__| | | | v3_| || |__| | |\ | |____ | | | |____ + |_| |_|\____/ |_| |_____\____/|_| \_|______| |_| |______| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/motioneye-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8765${CL} \n" From 5fa17902d8ca3ca3169e8f7caf03d5578ccc8b9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:27:24 -0400 Subject: [PATCH 2251/6505] Rename motioneye.sh to motioneye-v2.sh --- ct/{motioneye.sh => motioneye-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{motioneye.sh => motioneye-v2.sh} (100%) diff --git a/ct/motioneye.sh b/ct/motioneye-v2.sh similarity index 100% rename from ct/motioneye.sh rename to ct/motioneye-v2.sh From 064d3d54bfa47c16822caf5116078f7e3279574e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:33:08 -0400 Subject: [PATCH 2252/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 90 ++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index c1564884..159baf93 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,16 +37,18 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" echo -en "${GN} Installing Motion... " apt-get install motion -y &>/dev/null @@ -62,36 +56,36 @@ echo -en "${GN} Installing Motion... " systemctl disable motion &>/dev/null echo -e "${CM}${CL} \r" -echo -en "${GN} Installing FFmpeg... " +msg_info "Installing FFmpeg" apt-get install ffmpeg v4l-utils -y &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed FFmpeg" -echo -en "${GN} Installing Python... " +msg_info "Installing Python" apt-get update &>/dev/null apt-get install python2 -y &>/dev/null curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null python2 get-pip.py &>/dev/null apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null - echo -e "${CM}${CL} \r" + msg_ok "Installed Python" -echo -en "${GN} Installing MotionEye... " +msg_info "Installing MotionEye" apt-get update &>/dev/null sudo pip install motioneye &>/dev/null mkdir -p /etc/motioneye cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye -echo -e "${CM}${CL} \r" +msg_ok "Installed MotionEye" -echo -en "${GN} Creating Service file motioneye.service... " +msg_info "Creating Service" cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service &>/dev/null systemctl enable motioneye &>/dev/null systemctl start motioneye -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -104,11 +98,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 7a76669ebfbb0140e9a4df883d8502f3e53e007d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:34:53 -0400 Subject: [PATCH 2253/6505] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f21ca091..444b0d78 100644 --- a/README.md +++ b/README.md @@ -1326,22 +1326,20 @@ ________________________________________________________________________________
    - MotionEye VMS LXC + 🔸MotionEye VMS LXC

    MotionEye VMS LXC

    -To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **MotionEye Interface - IP:8765** ⚙️ **Initial Login** From bb89c7566474aaa5e9ed7f4ada59fc2e7ef7c6f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:35:53 -0400 Subject: [PATCH 2254/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d593a664..b885e996 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Vaultwarden LXC** - New V3 Install Script +- **Motioneye LXC** + - New V3 Install Script ## 2022-04-17 From 5f0d4250cdb307c6d9581824d97ab0c4e08c8c4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:43:00 -0400 Subject: [PATCH 2255/6505] Create nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 315 +++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/nginx-proxy-manager-v3.sh diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh new file mode 100644 index 00000000..aab3e5c5 --- /dev/null +++ b/ct/nginx-proxy-manager-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Nginx Proxy Manager" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _ _ _____ __ __ + | \ | | __ \| \/ | + | \| | |__) | \ / | + | | ___/| |\/| | + | |\ | | | | | | + |_| \_|_| v3 |_| |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}3GB${CL}" + DISK_SIZE="3" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nginx-proxy-manager-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:81${CL} \n" From 4f2aa20a73130648ed0866bb0d7d3fe22a4d1918 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 07:43:32 -0400 Subject: [PATCH 2256/6505] Rename nginx-proxy-manager.sh to nginx-proxy-manager-v2.sh --- ct/{nginx-proxy-manager.sh => nginx-proxy-manager-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{nginx-proxy-manager.sh => nginx-proxy-manager-v2.sh} (100%) diff --git a/ct/nginx-proxy-manager.sh b/ct/nginx-proxy-manager-v2.sh similarity index 100% rename from ct/nginx-proxy-manager.sh rename to ct/nginx-proxy-manager-v2.sh From 9b183c7bd8f171ede2b6f419db3628bdc5f26277 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:00:11 -0400 Subject: [PATCH 2257/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 113 ++++++++++++--------------- 1 file changed, 52 insertions(+), 61 deletions(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 3708a726..47d65c37 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,16 +37,15 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get update &>/dev/null apt-get -qqy install \ sudo \ @@ -69,9 +60,9 @@ apt-get -qqy install \ python3-dev \ git \ lsb-release &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" - echo -en "${GN} Installing Python... " +msg_info "Installing Dependencies" apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null pip3 install --upgrade setuptools &>/dev/null pip3 install --upgrade pip &>/dev/null @@ -80,38 +71,38 @@ echo -e "${CM}${CL} \r" python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null fi python3 -m pip install --no-cache-dir cffi certbot &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Openresty... " +msg_info "Installing Openresty" wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null apt-get -y update &>/dev/null apt-get -y install --no-install-recommends openresty &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Openresty" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Installing Yarn... " +msg_info "Installing Yarn" npm install --global yarn &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Yarn" RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') \ -echo -en "${GN} Downloading NPM v${RELEASE}... " +msg_info "Downloading Nginx Proxy Manager v${RELEASE}" wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null cd ./nginx-proxy-manager-${RELEASE} -echo -e "${CM}${CL} \r" +msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" -echo -en "${GN} Setting up Enviroment... " +msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx @@ -155,7 +146,7 @@ chmod -R 777 /var/cache/nginx chown root /tmp/nginx echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf -echo -e "${CM}${CL} \r" + if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then echo -en "${GN} Generating dummy SSL Certificate... " openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null @@ -164,18 +155,18 @@ fi mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global -echo -e "${CM}${CL} \r" +msg_ok "Set up Enviroment" -echo -en "${GN} Building Frontend... " +msg_info "Building Frontend" cd ./frontend export NODE_ENV=development yarn install --network-timeout=30000 &>/dev/null yarn build &>/dev/null cp -r dist/* /app/frontend cp -r app-images/* /app/frontend/images -echo -e "${CM}${CL} \r" +msg_ok "Built Frontend" -echo -en "${GN} Initializing Backend... " +msg_info "Initializing Backend" rm -rf /app/config/default.json &>/dev/null if [ ! -f /app/config/production.json ]; then cat << 'EOF' > /app/config/production.json @@ -195,9 +186,9 @@ fi cd /app export NODE_ENV=development yarn install --network-timeout=30000 &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Initialized Backend" -echo -en "${GN} Creating NPM Service... " +msg_info "Creating Service" cat << 'EOF' > /lib/systemd/system/npm.service [Unit] Description=Nginx Proxy Manager @@ -215,11 +206,11 @@ Restart=on-failure [Install] WantedBy=multi-user.target EOF -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -232,17 +223,17 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Starting Services... " +msg_info "Starting Services" systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm -echo -e "${CM}${CL} \r" +msg_ok "Started Services" -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 9d8f92a7b417cab662510ed0f1d2dd80cf10a96c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:01:46 -0400 Subject: [PATCH 2258/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 444b0d78..442c9b0e 100644 --- a/README.md +++ b/README.md @@ -357,17 +357,17 @@ ________________________________________________________________________________
    - Nginx Proxy Manager LXC + 🔸Nginx Proxy Manager LXC

    hero

    Nginx Proxy Manager LXC

    -To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell (V2). +To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. ```yaml - bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager.sh)" + bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

    From 478df7e3912f9f9d4bf0e1527fbb75dd933ec674 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:02:41 -0400 Subject: [PATCH 2259/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b885e996..657858f2 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -19,6 +19,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Motioneye LXC** - New V3 Install Script +- **Nginx Proxy Manager LXC** + - New V3 Install Script ## 2022-04-17 From 28abc55408aefed1da353cb072144c0d24d137c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:06:32 -0400 Subject: [PATCH 2260/6505] Rename adguard_container.sh to adguard-v1.sh --- ct/{adguard_container.sh => adguard-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{adguard_container.sh => adguard-v1.sh} (100%) diff --git a/ct/adguard_container.sh b/ct/adguard-v1.sh similarity index 100% rename from ct/adguard_container.sh rename to ct/adguard-v1.sh From c565cbabbd914daee74d789844611786689db3a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:07:13 -0400 Subject: [PATCH 2261/6505] Rename debian11_container.sh to debian-v1.sh --- ct/{debian11_container.sh => debian-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{debian11_container.sh => debian-v1.sh} (100%) diff --git a/ct/debian11_container.sh b/ct/debian-v1.sh similarity index 100% rename from ct/debian11_container.sh rename to ct/debian-v1.sh From bc843af3a2e6d997bfef11fc699e7b18792e7280 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:07:50 -0400 Subject: [PATCH 2262/6505] Rename esphome_container.sh to esphome-v1.sh --- ct/{esphome_container.sh => esphome-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{esphome_container.sh => esphome-v1.sh} (100%) diff --git a/ct/esphome_container.sh b/ct/esphome-v1.sh similarity index 100% rename from ct/esphome_container.sh rename to ct/esphome-v1.sh From 596bda08bb0748db01b95c13f0eb4579ed72ed52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:09:01 -0400 Subject: [PATCH 2263/6505] Rename ha_container.sh to homeassistant-v1.sh --- ct/{ha_container.sh => homeassistant-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{ha_container.sh => homeassistant-v1.sh} (100%) diff --git a/ct/ha_container.sh b/ct/homeassistant-v1.sh similarity index 100% rename from ct/ha_container.sh rename to ct/homeassistant-v1.sh From 7f35db22393a36047efe40812054f84142b2f0a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:09:41 -0400 Subject: [PATCH 2264/6505] Rename motioneye_container.sh to motioneye-v1.sh --- ct/{motioneye_container.sh => motioneye-v1.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename ct/{motioneye_container.sh => motioneye-v1.sh} (99%) diff --git a/ct/motioneye_container.sh b/ct/motioneye-v1.sh similarity index 99% rename from ct/motioneye_container.sh rename to ct/motioneye-v1.sh index 28a88567..944ee9b6 100644 --- a/ct/motioneye_container.sh +++ b/ct/motioneye-v1.sh @@ -165,4 +165,4 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 info "Successfully Created MotionEye LXC to $CTID." echo -e "\e[1;92m MotionEye NVR should be reachable by going to the following URL. http://${IP}:8765 -\e[0m" \ No newline at end of file +\e[0m" From a6af2826a38594e6e0f3e2baf5c98493ca64a8d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:10:49 -0400 Subject: [PATCH 2265/6505] Rename npm_container.sh to nginx-proxy-manager-v1.sh --- ct/{npm_container.sh => nginx-proxy-manager-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{npm_container.sh => nginx-proxy-manager-v1.sh} (100%) diff --git a/ct/npm_container.sh b/ct/nginx-proxy-manager-v1.sh similarity index 100% rename from ct/npm_container.sh rename to ct/nginx-proxy-manager-v1.sh From 1fc7ec265087e8179f5edfa919eef51fc64ce8da Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:12:22 -0400 Subject: [PATCH 2266/6505] Rename podman_ha_container.sh to podman-homeassistant-v1.sh --- ct/{podman_ha_container.sh => podman-homeassistant-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{podman_ha_container.sh => podman-homeassistant-v1.sh} (100%) diff --git a/ct/podman_ha_container.sh b/ct/podman-homeassistant-v1.sh similarity index 100% rename from ct/podman_ha_container.sh rename to ct/podman-homeassistant-v1.sh From b9df30c47f383ded3bbe1688cd2150a57dd0dd0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:13:24 -0400 Subject: [PATCH 2267/6505] Rename vault_container.sh to vaultwarden-v1.sh --- ct/{vault_container.sh => vaultwarden-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{vault_container.sh => vaultwarden-v1.sh} (100%) diff --git a/ct/vault_container.sh b/ct/vaultwarden-v1.sh similarity index 100% rename from ct/vault_container.sh rename to ct/vaultwarden-v1.sh From c0069a425ac856d27e299d76e75a4c8e5b1dd73f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:14:04 -0400 Subject: [PATCH 2268/6505] Rename zigbee2mqtt_container.sh to zigbee2mqtt-v1.sh --- ct/{zigbee2mqtt_container.sh => zigbee2mqtt-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{zigbee2mqtt_container.sh => zigbee2mqtt-v1.sh} (100%) diff --git a/ct/zigbee2mqtt_container.sh b/ct/zigbee2mqtt-v1.sh similarity index 100% rename from ct/zigbee2mqtt_container.sh rename to ct/zigbee2mqtt-v1.sh From 17688b6784c121276ef909121f1e71f46d571994 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 08:15:00 -0400 Subject: [PATCH 2269/6505] Rename zwavejs2mqtt_container.sh to zwavejs2mqtt-v1.sh --- ct/{zwavejs2mqtt_container.sh => zwavejs2mqtt-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{zwavejs2mqtt_container.sh => zwavejs2mqtt-v1.sh} (100%) diff --git a/ct/zwavejs2mqtt_container.sh b/ct/zwavejs2mqtt-v1.sh similarity index 100% rename from ct/zwavejs2mqtt_container.sh rename to ct/zwavejs2mqtt-v1.sh From 47715b85fd565a3b754348fb75f6f29db14de334 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:30:35 -0400 Subject: [PATCH 2270/6505] Create daemonsync-v3.sh --- ct/daemonsync-v3.sh | 317 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 ct/daemonsync-v3.sh diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh new file mode 100644 index 00000000..3d8ad2ff --- /dev/null +++ b/ct/daemonsync-v3.sh @@ -0,0 +1,317 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Daemon Sync" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _____ _____ + | __ \ / ____| + | | | | __ _v3___ _ __ ___ ___ _ __ | (___ _ _ _ __ ___ + | | | |/ _ |/ _ \ _ _ \ / _ \| _ \ \___ \| | | | _ \ / __| + | |__| | (_| | __/ | | | | | (_) | | | | ____) | |_| | | | | (__ + |_____/ \__,_|\___|_| |_| |_|\___/|_| |_| |_____/ \__, |_| |_|\___| + __/ | + |___/ +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/daemonsync-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8084${CL} \n" From 3654b22d2e2003d3e7f965fe5a1e4e008f91efbb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:31:05 -0400 Subject: [PATCH 2271/6505] Rename daemonsync.sh to daemonsync-v2.sh --- ct/{daemonsync.sh => daemonsync-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{daemonsync.sh => daemonsync-v2.sh} (100%) diff --git a/ct/daemonsync.sh b/ct/daemonsync-v2.sh similarity index 100% rename from ct/daemonsync.sh rename to ct/daemonsync-v2.sh From b346021571607323fc314c7161aa7f3803f1bd4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:41:29 -0400 Subject: [PATCH 2272/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 73 ++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index bce69f48..b6fe12ab 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,29 +37,28 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y g++-multilib &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Daemon Sync Server... " +msg_info "Installing Daemon Sync Server" wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_amd64.deb &>/dev/null sudo dpkg -i daemonsync_2.2.0.0059_amd64.deb &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Daemon Sync Server" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -80,11 +71,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 3335ee5dbd8f1ae1491b915aed5b9ea77051a667 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:42:57 -0400 Subject: [PATCH 2273/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 442c9b0e..011a07b7 100644 --- a/README.md +++ b/README.md @@ -1301,7 +1301,7 @@ ________________________________________________________________________________
    - Daemon Sync Server LXC + 🔸Daemon Sync Server LXC

    @@ -1309,10 +1309,10 @@ ________________________________________________________________________________ Sync files from app to server, share photos & videos, back up your data and stay secure inside local network. -To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    From 2f1419e5e5bb1dd69be0df5fdc6d19a73be84ca7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:44:39 -0400 Subject: [PATCH 2274/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 657858f2..dd5d2f13 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -21,6 +21,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Nginx Proxy Manager LXC** - New V3 Install Script +- **Daemon Sync Server LXC** + - New V3 Install Script ## 2022-04-17 From 1a49cdb4868ea20ca1eadc29f7acd6ef069bdbb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:50:35 -0400 Subject: [PATCH 2275/6505] Create dashy-v3.sh --- ct/dashy-v3.sh | 317 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 ct/dashy-v3.sh diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh new file mode 100644 index 00000000..7d789f1e --- /dev/null +++ b/ct/dashy-v3.sh @@ -0,0 +1,317 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Dashy" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _ + | __ \ | | + | | | | __ _ ___| |__ _ _ + | | | |/ _ / __| _ \| | | | + | |__| | (_| \__ \ | | | |_| | + |_____/ \__,_|___/_| |_|\__, | + v3__/ | + |___/ +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}3GB${CL}" + DISK_SIZE="3" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/dashy-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:4000${CL} \n" From aaae8a2dbcfa7b91623f6afd7083f350637079fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:52:04 -0400 Subject: [PATCH 2276/6505] Rename dashy.sh to dashy-v2.sh --- ct/{dashy.sh => dashy-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{dashy.sh => dashy-v2.sh} (100%) diff --git a/ct/dashy.sh b/ct/dashy-v2.sh similarity index 100% rename from ct/dashy.sh rename to ct/dashy-v2.sh From baddebf8b61e54aa34e8c88ec1207260b9cfdf9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 10:59:24 -0400 Subject: [PATCH 2277/6505] Update dashy-install.sh --- setup/dashy-install.sh | 89 +++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index ddbf0864..7d309299 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,42 +37,41 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y git &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" sudo apt-get install -y nodejs git make g++ gcc &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Installing Yarn... " +msg_info "Installing Yarn" npm install --global yarn &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Yarn" -echo -en "${GN} Installing Dashy (Patience)... " +msg_info "Installing Dashy (Patience)" git clone https://github.com/Lissy93/dashy.git &>/dev/null cd /dashy yarn &>/dev/null export NODE_OPTIONS=--max-old-space-size=1000 &>/dev/null yarn build &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dashy" -echo -en "${GN} Creating Dashy Service... " +msg_info "Creating Service" cat < /etc/systemd/system/dashy.service [Unit] Description=dashy @@ -94,11 +85,11 @@ WantedBy=multi-user.target EOF sudo systemctl start dashy &>/dev/null sudo systemctl enable dashy &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -111,11 +102,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 89a259555718ee130653d96dfd3fbb7926295c6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:00:25 -0400 Subject: [PATCH 2278/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 011a07b7..f4796a2d 100644 --- a/README.md +++ b/README.md @@ -1226,7 +1226,7 @@ ________________________________________________________________________________
    - Dashy LXC + 🔸Dashy LXC

    @@ -1234,10 +1234,10 @@ ________________________________________________________________________________ Dashy helps you organize your self-hosted services by making them accessible from a single place -To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    From 42f82fb8fde5333595b754ba2cd6cdccc98768dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:01:21 -0400 Subject: [PATCH 2279/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index dd5d2f13..406b6815 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -23,6 +23,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Daemon Sync Server LXC** - New V3 Install Script +- **Dashy LXC** + - New V3 Install Script ## 2022-04-17 From 5d4d5c8bcf2959af9d0580a2996b830bf1267f47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:07:24 -0400 Subject: [PATCH 2280/6505] Create heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 316 +++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 ct/heimdalldashboard-v3.sh diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh new file mode 100644 index 00000000..16de9e56 --- /dev/null +++ b/ct/heimdalldashboard-v3.sh @@ -0,0 +1,316 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +PP=`echo "\e[1;35m"` +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Heimdall Dashboard" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + _ _ _ _ _ _ _____ _ _ _ + | | | | (_) | | | | | | __ \ | | | | | | + | |__| | ___ _ _ __ ___ __| | __v3| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | + | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | + | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | + |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/heimdalldashboard-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7990${CL} \n" From c62bb99b4771d5c12b27743e5579f21bed0e6a30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:08:36 -0400 Subject: [PATCH 2281/6505] Rename heimdalldashboard.sh to heimdalldashboard-v2.sh --- ct/{heimdalldashboard.sh => heimdalldashboard-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{heimdalldashboard.sh => heimdalldashboard-v2.sh} (100%) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard-v2.sh similarity index 100% rename from ct/heimdalldashboard.sh rename to ct/heimdalldashboard-v2.sh From 4c9dc86b5862e43afbcb265645e66e268b4b299a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:13:47 -0400 Subject: [PATCH 2282/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 79 +++++++++++++----------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 74f120bd..25856f2c 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,28 +37,27 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing PHP... " +msg_info "Installing PHP" apt-get install -y php &>/dev/null apt-get install -y php-sqlite3 &>/dev/null apt-get install -y php-zip &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed PHP" RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -echo -en "${GN} Installing Heimdall Dashboard ${RELEASE}... " +msg_info "Installing Heimdall Dashboard ${RELEASE}" curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null tar xvzf ${RELEASE}.tar.gz &>/dev/null VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ @@ -74,9 +65,9 @@ VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | awk '{print substr($2, 3, length($2)-4) }') rm -rf ${RELEASE}.tar.gz mv Heimdall-${VER} /opt/Heimdall -echo -e "${CM}${CL} \r" +msg_ok "Installed Heimdall Dashboard ${RELEASE}" -echo -en "${GN} Creating Service... " +msg_info "Creating Service" service_path="/etc/systemd/system/heimdall.service" echo "[Unit] Description=Heimdall @@ -94,11 +85,11 @@ TimeoutStopSec=30 [Install] WantedBy=multi-user.target" > $service_path sudo systemctl enable --now heimdall.service &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -111,11 +102,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 8648ee3046a9c7e5182f95b88f1c7dabb191a6ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:14:49 -0400 Subject: [PATCH 2283/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f4796a2d..d1c1b8b6 100644 --- a/README.md +++ b/README.md @@ -1196,7 +1196,7 @@ ________________________________________________________________________________
    - Heimdall Dashboard LXC + 🔸Heimdall Dashboard LXC

    @@ -1204,10 +1204,10 @@ ________________________________________________________________________________ [Heimdall Application Dashboard](https://camo.githubusercontent.com/bcfd4f74c93b25bea7b14eacbafd649206bf754a3d4b596329968f0ee569cf3c/68747470733a2f2f692e696d6775722e636f6d2f4d72433451704e2e676966) is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like. -To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    From 62a5d0023d83f5f849d5621862db9d8eaa2057d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:16:13 -0400 Subject: [PATCH 2284/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 406b6815..0c571c83 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -25,6 +25,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Dashy LXC** - New V3 Install Script +- **Heimdall Dashboard LXC** + - New V3 Install Script ## 2022-04-17 From aee6bbd3aea76d74c35611f70a2ca11ec578fd1c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:21:20 -0400 Subject: [PATCH 2285/6505] Create wireguard-v3.sh --- ct/wireguard-v3.sh | 316 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 ct/wireguard-v3.sh diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh new file mode 100644 index 00000000..7584a91e --- /dev/null +++ b/ct/wireguard-v3.sh @@ -0,0 +1,316 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Wireguard" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + __ ___ _____ _ + \ \ / (_) / ____| | | + \ \ /\ / / _ _ __ ___| | __ _ _ __ _ _ __ __| | + \ \/ \/ / | | __/ _ \ | |_ | | | |/ _ | __/ _ | + \ /\ / | | | | __/ |__| | |_| | (_| | | | (_| | + \/ \/ v3|_|_| \___|\_____|\__,_|\__,_|_| \__,_| + ${YW}With WGDashboard +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/wireguard-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "WGDashboard should be reachable by going to the following URL. + ${BL}http://${IP}:10086${CL} \n" From ea268a1c8c9a6e241f4796ca601f820af68039d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:21:42 -0400 Subject: [PATCH 2286/6505] Rename wireguard.sh to wireguard-v2.sh --- ct/{wireguard.sh => wireguard-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{wireguard.sh => wireguard-v2.sh} (100%) diff --git a/ct/wireguard.sh b/ct/wireguard-v2.sh similarity index 100% rename from ct/wireguard.sh rename to ct/wireguard-v2.sh From d6ebbc5ea6e23e68a692ecf1841d57315ab70c34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:34:07 -0400 Subject: [PATCH 2287/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 88 ++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 194b7f0c..48965f77 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,12 +37,8 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" -MAC=$(cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address) -echo -en "${GN} MAC Address: ${BL}${MAC}${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" OPTIONS_PATH='/options.conf' cat >$OPTIONS_PATH <<'EOF' @@ -69,32 +57,32 @@ pivpnPERSISTENTKEEPALIVE=25 UNATTUPG=1 EOF -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y gunicorn &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing WireGuard (using pivpn.io)... " +msg_info "Installing WireGuard (using pivpn.io)" curl -s -L https://install.pivpn.io > install.sh chmod +x install.sh ./install.sh --unattended options.conf &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed WireGuard" -echo -en "${GN} Installing pip3... " +msg_info "Installing pip3" apt-get install python3-pip -y &>/dev/null pip install flask &>/dev/null pip install ifcfg &>/dev/null pip install flask_qrcode &>/dev/null pip install icmplib &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed pip3" -echo -en "${GN} Installing WGDashboard... " +msg_info "Installing WGDashboard" WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 2, length($2)-3) }') \ @@ -104,9 +92,9 @@ cd /ect/wgdashboard/src sudo chmod u+x wgd.sh sudo ./wgd.sh install &>/dev/null sudo chmod -R 755 /etc/wireguard -echo -e "${CM}${CL} \r" +msg_ok "Installed WGDashboard" -echo -en "${GN} Creating wg-dashboard.service... " +msg_info "Creating Service" service_path="/etc/systemd/system/wg-dashboard.service" echo "[Unit] After=netword.service @@ -123,11 +111,11 @@ sudo chmod 664 /etc/systemd/system/wg-dashboard.service sudo systemctl daemon-reload sudo systemctl enable wg-dashboard.service &>/dev/null sudo systemctl start wg-dashboard.service -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -140,11 +128,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 439d78886c074ef0eec8a5142a3fa5c1c54a7530 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:35:34 -0400 Subject: [PATCH 2288/6505] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d1c1b8b6..21f43a96 100644 --- a/README.md +++ b/README.md @@ -1413,23 +1413,21 @@ ________________________________________________________________________________
    - WireGuard LXC + 🔸WireGuard LXC

    WireGuard LXC

    With WGDashboard

    -To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **WGDashboard Interface - http:// IP:10086** ⚙️ **Initial Login** From e92bff11aa3e8f7e3011b6c013bf985b05eee7fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 11:36:44 -0400 Subject: [PATCH 2289/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0c571c83..bc5802e1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -27,6 +27,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Heimdall Dashboard LXC** - New V3 Install Script +- **Wireguard LXC** + - New V3 Install Script ## 2022-04-17 From 7f3f5a5b1834bf11ed6998a9f8d7362db5070658 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:39:43 -0400 Subject: [PATCH 2290/6505] Create node-red-v3.sh --- ct/node-red-v3.sh | 315 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/node-red-v3.sh diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh new file mode 100644 index 00000000..1f0d38bb --- /dev/null +++ b/ct/node-red-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Node Red" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _ _ _ _____ _ + | \ | | | | | __ \ | | + | \| | ___ __| | ___ ______| |__) |___ __| | + | |/ _ \ / _ |/ _ \__v3__| _ // _ \/ _ | + | |\ | (_) | (_| | __/ | | \ \ __/ (_| | + |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:1880${CL} \n" From 4cfc8717ac4ba2f9654ec0d8f2ae82433d751a3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:40:18 -0400 Subject: [PATCH 2291/6505] Rename node-red.sh to node-red-v2.sh --- ct/{node-red.sh => node-red-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{node-red.sh => node-red-v2.sh} (100%) diff --git a/ct/node-red.sh b/ct/node-red-v2.sh similarity index 100% rename from ct/node-red.sh rename to ct/node-red-v2.sh From e31b153c05128e33b10c34c5b50019da9b923060 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:40:49 -0400 Subject: [PATCH 2292/6505] Rename node-red_container.sh to node-red-v1.sh --- ct/{node-red_container.sh => node-red-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{node-red_container.sh => node-red-v1.sh} (100%) diff --git a/ct/node-red_container.sh b/ct/node-red-v1.sh similarity index 100% rename from ct/node-red_container.sh rename to ct/node-red-v1.sh From 5cb09b81ab3ff6d1fbdee43fcd6ffcb1b28ad8e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:44:52 -0400 Subject: [PATCH 2293/6505] Update node-red-install.sh --- setup/node-red-install.sh | 73 +++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 7bf0de50..1a891678 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,29 +37,28 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Node-Red... " +msg_info "Installing Node-Red" bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul sudo systemctl enable nodered.service &>/dev/null sudo systemctl start nodered.service &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node-Red" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -80,11 +71,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From b85ca5dbc4614bef7edce6d7d8c3643d3b3f2751 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:46:11 -0400 Subject: [PATCH 2294/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 21f43a96..c1184fbc 100644 --- a/README.md +++ b/README.md @@ -458,17 +458,17 @@ ________________________________________________________________________________
    - Node-Red LXC + 🔸Node-Red LXC

    Node-Red LXC

    -To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    From 0171edc356b00214a43733b39397878a529ed0fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:47:17 -0400 Subject: [PATCH 2295/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bc5802e1..6ca7f90f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -29,6 +29,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Wireguard LXC** - New V3 Install Script +- **Node-Red LXC** + - New V3 Install Script ## 2022-04-17 From b4c4e94d5a0f1aac39bc0c20c3e38bacdba1729b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:51:53 -0400 Subject: [PATCH 2296/6505] Create mqtt-v3.sh --- ct/mqtt-v3.sh | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 ct/mqtt-v3.sh diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh new file mode 100644 index 00000000..d2e43ca5 --- /dev/null +++ b/ct/mqtt-v3.sh @@ -0,0 +1,313 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="MQTT" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + __ __ ____ _______ _______ + | \/ |/ __ \__ __|__ __| + | \ / | | | | | | | | + | |\/| | | | | | | | | + | | | | |__| | | | | | + |_| |_|\___\_\ |_| v3 |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" From d1a8ad3925de4ffa90b2400c625e23659801a124 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:52:19 -0400 Subject: [PATCH 2297/6505] Rename mqtt.sh to mqtt-v2.sh --- ct/{mqtt.sh => mqtt-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{mqtt.sh => mqtt-v2.sh} (100%) diff --git a/ct/mqtt.sh b/ct/mqtt-v2.sh similarity index 100% rename from ct/mqtt.sh rename to ct/mqtt-v2.sh From 4d6667064ce461c9c87f16e0c3c7a293bcf2c5a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:52:49 -0400 Subject: [PATCH 2298/6505] Rename mqtt_container.sh to mqtt-v1.sh --- ct/{mqtt_container.sh => mqtt-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{mqtt_container.sh => mqtt-v1.sh} (100%) diff --git a/ct/mqtt_container.sh b/ct/mqtt-v1.sh similarity index 100% rename from ct/mqtt_container.sh rename to ct/mqtt-v1.sh From 70f5cba58f98a3aaf28620f0a816052088a08652 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:56:14 -0400 Subject: [PATCH 2299/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 73 +++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index d96fac5a..1a54f90d 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,22 +37,21 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y gnupg &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Mosquitto MQTT Broker... " +msg_info "Installing Mosquitto MQTT Broker" wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null apt-key add mosquitto-repo.gpg.key &>/dev/null cd /etc/apt/sources.list.d/ @@ -68,11 +59,11 @@ wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list &>/dev/null apt-get update >/dev/null apt-get -y install mosquitto &>/dev/null apt-get -y install mosquitto-clients &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Mosquitto MQTT Broker" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -85,11 +76,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From adb8ace3b0b955bd8b800233f6805164184fe1be Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:57:30 -0400 Subject: [PATCH 2300/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c1184fbc..7bf4a0c9 100644 --- a/README.md +++ b/README.md @@ -407,17 +407,17 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update
    - MQTT LXC + 🔸MQTT LXC

    MQTT LXC

    -To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    From afbf922ae480ae565002a4ef5e9fd5574ecffe71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 14:58:23 -0400 Subject: [PATCH 2301/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6ca7f90f..4d859861 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -31,6 +31,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Node-Red LXC** - New V3 Install Script +- **MQTT LXC** + - New V3 Install Script ## 2022-04-17 From ee6405bcbdd9b198a7933f2cd2b9eacdc7a98ec0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:03:35 -0400 Subject: [PATCH 2302/6505] Create mariadb-v3.sh --- ct/mariadb-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/mariadb-v3.sh diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh new file mode 100644 index 00000000..15c26710 --- /dev/null +++ b/ct/mariadb-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="MariaDB" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + __ __ _ _ _ + | \/ | (_) | | | + | \ / | __ _ _ __ _ __ _ __| | |__ + | |\/| |/ _ | __| |/ _ |/ _ | _ \ + | | | | (_| | | | | (_| | (_| | |_) | + |_| |_|\__,_|_|v3|_|\__,_|\__,_|_.__/ +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "Adminer should be reachable by going to the following URL. + ${BL}http://${IP}/adminer/${CL} \n" From ddde2be574cf4942220215082931b56e6fc235e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:04:04 -0400 Subject: [PATCH 2303/6505] Rename mariadb.sh to mariadb-v2.sh --- ct/{mariadb.sh => mariadb-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{mariadb.sh => mariadb-v2.sh} (100%) diff --git a/ct/mariadb.sh b/ct/mariadb-v2.sh similarity index 100% rename from ct/mariadb.sh rename to ct/mariadb-v2.sh From 6cbbc402ace9a50b6f93fb77c1eb7247273703ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:04:38 -0400 Subject: [PATCH 2304/6505] Rename mariadb_container.sh to mariadb-v1.sh --- ct/{mariadb_container.sh => mariadb-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{mariadb_container.sh => mariadb-v1.sh} (100%) diff --git a/ct/mariadb_container.sh b/ct/mariadb-v1.sh similarity index 100% rename from ct/mariadb_container.sh rename to ct/mariadb-v1.sh From 80699306ae7ef8843c798efd39e9f45569481ba7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:09:42 -0400 Subject: [PATCH 2305/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 75 ++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index e4cb0062..ced8fe7f 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,35 +37,34 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing MariaDB... " +msg_info "Installing MariaDB" curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed MariaDB" -echo -en "${GN} Installing Adminer... " +msg_info "Installing Adminer" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Adminer" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -86,13 +77,13 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* mkdir /var/log/apache2 chmod 750 /var/log/apache2 -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From b6403ea4034e13c575f19bc3b0bc1c4a8c377a24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:10:40 -0400 Subject: [PATCH 2306/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7bf4a0c9..51831d26 100644 --- a/README.md +++ b/README.md @@ -501,16 +501,16 @@ ________________________________________________________________________________
    - Mariadb LXC + 🔸Mariadb LXC

    MariaDB

    Mariadb LXC

    -To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    From 7275fefb44d416d63b1afcb5c8688efe6744f9c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:13:57 -0400 Subject: [PATCH 2307/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4d859861..ef1ea9a0 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -33,6 +33,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **MQTT LXC** - New V3 Install Script +- **Mariadb LXC** + - New V3 Install Script ## 2022-04-17 From 335b72f73adf8f355192b31b37be3f502a5152b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:32:36 -0400 Subject: [PATCH 2308/6505] Create ubuntu-v3.sh --- ct/ubuntu-v3.sh | 313 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 ct/ubuntu-v3.sh diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh new file mode 100644 index 00000000..c430232a --- /dev/null +++ b/ct/ubuntu-v3.sh @@ -0,0 +1,313 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Ubuntu" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _ _ _ + | | | | | | | + | | | | |__ _ v3_ _ __ | |_ _ _ + | | | | _ \| | | | _ \| __| | | | + | |__| | |_) | |_| | | | | |_| |_| | + \____/|_.__/ \__,_|_| |_|\__|\__,_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=21.10 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" From 9b5e4fe21eecbac74afd709ef7b7b9531132a390 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:33:09 -0400 Subject: [PATCH 2309/6505] Rename ubuntu.sh to ubuntu-v2.sh --- ct/{ubuntu.sh => ubuntu-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{ubuntu.sh => ubuntu-v2.sh} (100%) diff --git a/ct/ubuntu.sh b/ct/ubuntu-v2.sh similarity index 100% rename from ct/ubuntu.sh rename to ct/ubuntu-v2.sh From 48ab25470e7c5d8efc890b6b9d908a4312b24838 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:33:43 -0400 Subject: [PATCH 2310/6505] Rename ubuntu_container.sh to ubuntu-v1.sh --- ct/{ubuntu_container.sh => ubuntu-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{ubuntu_container.sh => ubuntu-v1.sh} (100%) diff --git a/ct/ubuntu_container.sh b/ct/ubuntu-v1.sh similarity index 100% rename from ct/ubuntu_container.sh rename to ct/ubuntu-v1.sh From 3b92f4e93d002d277a55c92e941c2dde686d49ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:36:49 -0400 Subject: [PATCH 2311/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 69 ++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 3ba3ae2f..dab51639 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,23 +37,22 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" chmod -x /etc/update-motd.d/* touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" @@ -73,11 +64,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 07c7d1de7fcf80516bc4b0f92a64c4cae7caa74b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:38:37 -0400 Subject: [PATCH 2312/6505] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 51831d26..b5acf9fe 100644 --- a/README.md +++ b/README.md @@ -897,22 +897,20 @@ ________________________________________________________________________________
    - Ubuntu 21.10 LXC + 🔸Ubuntu 21.10 LXC

    Ubuntu

    Ubuntu 21.10 LXC

    -To create a new Proxmox Ubuntu 21.10 (curl. sudo) LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Ubuntu 21.10 (curl. sudo) LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - ⚙️ **To Update Ubuntu 21.10** Run in the LXC console From ee3e4ed0d0ddf146386aa97222e3de0b9849bb77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:39:29 -0400 Subject: [PATCH 2313/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ef1ea9a0..6f6ddeb0 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -35,6 +35,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Mariadb LXC** - New V3 Install Script +- **Ubuntu 21.10 LXC** + - New V3 Install Script ## 2022-04-17 From 3425578c48673f92c12c15e898f051b7aad2615f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:48:04 -0400 Subject: [PATCH 2314/6505] Create nocodb-v3.sh --- ct/nocodb-v3.sh | 315 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/nocodb-v3.sh diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh new file mode 100644 index 00000000..8eb3fc47 --- /dev/null +++ b/ct/nocodb-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="NocoDB" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _ _____ ____ + | \ | | | __ \| _ \ + | \| | ___ v3___ ___ | | | | |_) | + | |/ _ \ / __/ _ \| | | | _ < + | |\ | (_) | (_| (_) | |__| | |_) | + |_| \_|\___/ \___\___/|_____/|____/ +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nocodb-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080/dashboard${CL}\n" From 0f608ddbd341c93b1c4e3c62ad9c9e82057227e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:48:27 -0400 Subject: [PATCH 2315/6505] Rename nocodb.sh to nocodb-v2.sh --- ct/{nocodb.sh => nocodb-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{nocodb.sh => nocodb-v2.sh} (100%) diff --git a/ct/nocodb.sh b/ct/nocodb-v2.sh similarity index 100% rename from ct/nocodb.sh rename to ct/nocodb-v2.sh From fbbedc1eca516a927c6827fa2322865daf19d1ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:54:47 -0400 Subject: [PATCH 2316/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 83 ++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 32a5e0c1..bb7d0b78 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,37 +37,36 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y git &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" sudo apt-get install -y nodejs git make g++ gcc &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Installing NocoDB... " +msg_info "Installing NocoDB" git clone https://github.com/nocodb/nocodb-seed &>/dev/null mv nocodb-seed /opt/nocodb cd /opt/nocodb npm install &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed NocoDB" -echo -en "${GN} Creating Service file nocodb.service... " +msg_info "Creating Service" service_path="/etc/systemd/system/nocodb.service" echo "[Unit] Description=nocodb @@ -90,11 +81,11 @@ ExecStart=/usr/bin/npm start [Install] WantedBy=multi-user.target" > $service_path systemctl enable --now nocodb.service &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -107,11 +98,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From fb720704144c52557ee380782aed6e0061d08ed6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:56:08 -0400 Subject: [PATCH 2317/6505] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b5acf9fe..ed124ac5 100644 --- a/README.md +++ b/README.md @@ -726,7 +726,7 @@ ________________________________________________________________________________
    - NocoDB LXC + 🔸NocoDB LXC

    @@ -734,16 +734,14 @@ ________________________________________________________________________________ NocoDB is an open source #NoCode platform that turns any database into a smart spreadsheet. Airtable Alternative. -To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **NocoDB Interface - IP:8080/dashboard** ⚙️ **To Update** From 2ca09a9c5cf0a73cd75e7133d3eab70b40619c93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 15:57:12 -0400 Subject: [PATCH 2318/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6f6ddeb0..1eaec401 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -37,6 +37,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Ubuntu 21.10 LXC** - New V3 Install Script +- **NocoDB LXC** + - New V3 Install Script ## 2022-04-17 From fd9b238575b15ce63f23729193cfdb833076ad24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:02:47 -0400 Subject: [PATCH 2319/6505] Create plex-v3.sh --- ct/plex-v3.sh | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 ct/plex-v3.sh diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh new file mode 100644 index 00000000..e22bb51e --- /dev/null +++ b/ct/plex-v3.sh @@ -0,0 +1,326 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +APP="Plex" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _ _ _ _ + | | ${YW}v3${CL}${BL} (_) | | | | + | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ + | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| + | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ + |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +PVE_CHECK +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "Plex Media Server should be reachable by going to the following URL. + ${BL}http://${IP}:32400/web${CL}\n" From 5a7df00f20595af9ff3513d84ca3360b786cde2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:11:49 -0400 Subject: [PATCH 2320/6505] Create plex-install.sh --- setup/plex-install.sh | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 setup/plex-install.sh diff --git a/setup/plex-install.sh b/setup/plex-install.sh new file mode 100644 index 00000000..d934d292 --- /dev/null +++ b/setup/plex-install.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting Up Hardware Acceleration" +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* +msg_ok "Set Up Hardware Acceleration" + +msg_info "Setting Up Plex Media Server Repository" +wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://downloads.plex.tv/repo/deb/ public main" | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null +msg_ok "Set Up Plex Media Server Repository" + +msg_info "Installing Plex Media Server" +apt-get update &>/dev/null +apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver &>/dev/null +msg_ok "Installed Plex Media Server" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" + From b4508b009433f5c97b28b3df4b4437aa91983eed Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:14:33 -0400 Subject: [PATCH 2321/6505] Update plex-v3.sh --- ct/plex-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index e22bb51e..7f1569c5 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -288,8 +288,8 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=20.04 export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES From 92ecf5a39debbf3c75bc843e6b70985b7914329e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:16:49 -0400 Subject: [PATCH 2322/6505] Update plex-install.sh --- setup/plex-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/plex-install.sh b/setup/plex-install.sh index d934d292..d91ef8a9 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -75,8 +75,7 @@ msg_ok "Installed Plex Media Server" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname +chmod -x /etc/update-motd.d/* touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) From ff86e9dc959f6f7d0485b344529eb0926b45fa4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:20:05 -0400 Subject: [PATCH 2323/6505] Update plex-v3.sh --- ct/plex-v3.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 7f1569c5..4f7c796e 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -26,13 +26,13 @@ while true; do done clear function header_info { -echo -e "${BL} - _ _ _ _ - | | ${YW}v3${CL}${BL} (_) | | | | - | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ - | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| +echo -e "${YW} + _____ _ + | __ \| | + | |__) | | _____ __ + | ___/| |/ _ \ \/ / + | | | | __/> < + |_| v3 |_|\___/_/\_\ ${CL}" } From b4526eeb7bb70cbef44221d6b4a1578a1066a952 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:26:01 -0400 Subject: [PATCH 2324/6505] Update plex-v3.sh --- ct/plex-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 4f7c796e..ebed4526 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -89,7 +89,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS} ${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From af51999c11989bf729c5ea1ca31907cb8f35f545 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:29:14 -0400 Subject: [PATCH 2325/6505] Update create_lxc.sh --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 9ea496e9..405bd0c9 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -116,7 +116,7 @@ TEMPLATE="${TEMPLATES[-1]}" if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_info "Downloading LXC Template" - msg_ok "Downloading LXC Template" + msg_ok "Downloaded LXC Template" pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." fi From 1b675e8a6656c4838604782490a3a4f5fc8615ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:43:38 -0400 Subject: [PATCH 2326/6505] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ed124ac5..171da886 100644 --- a/README.md +++ b/README.md @@ -1012,7 +1012,7 @@ ________________________________________________________________________________
    - Plex Media Server LXC + 🔸Plex Media Server LXC

    @@ -1021,12 +1021,10 @@ ________________________________________________________________________________ To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex_container.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **Plex Media Server Interface - IP:32400/web** ⚙️ **To Update Plex Media Server:** From 6cecf966ebceac3d336d7e4b157d584a10dd8287 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:44:23 -0400 Subject: [PATCH 2327/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1eaec401..23e931e5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -39,6 +39,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **NocoDB LXC** - New V3 Install Script +- **Plex Media Server LXC** + - New V3 Install Script ## 2022-04-17 From 3c50b763019297fd465fdee770af60244482394e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 18:45:35 -0400 Subject: [PATCH 2328/6505] Rename plex_container.sh to plex-v1.sh --- ct/{plex_container.sh => plex-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{plex_container.sh => plex-v1.sh} (100%) diff --git a/ct/plex_container.sh b/ct/plex-v1.sh similarity index 100% rename from ct/plex_container.sh rename to ct/plex-v1.sh From 2a153a5e318922156a7c1c3e9e1467022c3ed7c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 20:49:14 -0400 Subject: [PATCH 2329/6505] Create jellyfin-v3.sh --- ct/jellyfin-v3.sh | 328 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 ct/jellyfin-v3.sh diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh new file mode 100644 index 00000000..2fd5a1ac --- /dev/null +++ b/ct/jellyfin-v3.sh @@ -0,0 +1,328 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +APP="Jellyfin" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${DGN} + _ _ _ __ _ + | | | | | / _(_) + | | ___| | |_v3 _| |_ _ _ __ + _ | |/ _ \ | | | | | _| | _ \ + | |__| | __/ | | |_| | | | | | | | + \____/ \___|_|_|\__, |_| |_|_| |_| + __/ | + |___/ +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type ${CROSS} ${YW}Unprivileged, or Press [ENTER] for Default: Privileged" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +PVE_CHECK +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=20.04 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "Jellyfin Media Server should be reachable by going to the following URL. + ${BL}http://${IP}:8096${CL}\n" From 0ac892597eda1669d2599af08bb978e14aa6292a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 20:59:49 -0400 Subject: [PATCH 2330/6505] Create jellyfin-install.sh --- setup/jellyfin-install.sh | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 setup/jellyfin-install.sh diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh new file mode 100644 index 00000000..257117ae --- /dev/null +++ b/setup/jellyfin-install.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y apt-transport-https &>/dev/null +apt-get install -y software-properties-common &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting Up Hardware Acceleration" +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* +msg_ok "Set Up Hardware Acceleration" + +msg_info "Setting Up Jellyfin Repository" +sudo add-apt-repository universe -y &>/dev/null +wget -q -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null +echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +msg_ok "Set Up Jellyfin Repository" + +msg_info "Installing Jellyfin" +apt-get update &>/dev/null +sudo apt install jellyfin-server -y &>/dev/null +msg_ok "Installed Jellyfin" + +msg_info "Creating Service" +cat << 'EOF' > /lib/systemd/system/jellyfin.service +[Unit] +Description = Jellyfin Media Server +After = network.target +[Service] +Type = simple +EnvironmentFile = /etc/default/jellyfin +User = root +ExecStart = /usr/bin/jellyfin ${JELLYFIN_WEB_OPT} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELL> +Restart = on-failure +TimeoutSec = 15 +[Install] +WantedBy = multi-user.target +EOF +ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From d97d80238ab9616b055b9c7de47a19b81a21d4c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 21:00:36 -0400 Subject: [PATCH 2331/6505] Rename jellyfin_container.sh to jellyfin-v1.sh --- ct/{jellyfin_container.sh => jellyfin-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{jellyfin_container.sh => jellyfin-v1.sh} (100%) diff --git a/ct/jellyfin_container.sh b/ct/jellyfin-v1.sh similarity index 100% rename from ct/jellyfin_container.sh rename to ct/jellyfin-v1.sh From dbb2dcf13d84f867f464cf2cd87d50d0aa6540cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 21:02:30 -0400 Subject: [PATCH 2332/6505] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 171da886..89b7de8e 100644 --- a/README.md +++ b/README.md @@ -1045,7 +1045,7 @@ ________________________________________________________________________________
    - Jellyfin Media Server LXC + 🔸Jellyfin Media Server LXC

    Jellyfin Media Server LXC

    @@ -1054,12 +1054,10 @@ ________________________________________________________________________________ To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin_container.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **Jellyfin Media Server Interface - IP:8096** ⚙️ **To Update Jellyfin Media Server** From 8e0c2250071357fef9870541c2d76dda08be3f58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Apr 2022 21:03:40 -0400 Subject: [PATCH 2333/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 23e931e5..dc4074fb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -41,6 +41,8 @@ All notable changes to this project will be documented in this file. - New V3 Install Script - **Plex Media Server LXC** - New V3 Install Script +- **Jellyfin Media Server LXC** + - New V3 Install Script ## 2022-04-17 From 25fcca086dbbeaa64e416e00d3eda3d488c5085a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:35:36 -0400 Subject: [PATCH 2334/6505] Create pihole-v3.sh --- ct/pihole-v3.sh | 315 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/pihole-v3.sh diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh new file mode 100644 index 00000000..1d9c5723 --- /dev/null +++ b/ct/pihole-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Pihole" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _____ _ _ ____ _ ______ + | __ \_ _| | | |/ __ \| | | ____| + | |__) || | | |__| | | | | | | |__ + | ___/ | | | __ | | | | | | __| + | | v3 _| |_| | | | |__| | |____| |____ + |_| |_____|_| |_|\____/|______|______| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/pihole-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP}${CL} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From c0f8c301163da041441c36a2e5d3fceeb0e1cc10 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:36:01 -0400 Subject: [PATCH 2335/6505] Rename pihole.sh to pihole-v2.sh --- ct/{pihole.sh => pihole-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{pihole.sh => pihole-v2.sh} (100%) diff --git a/ct/pihole.sh b/ct/pihole-v2.sh similarity index 100% rename from ct/pihole.sh rename to ct/pihole-v2.sh From f0e981cf8ea23a8c5a835194418693d03a1dbf82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:36:39 -0400 Subject: [PATCH 2336/6505] Rename pihole_container.sh to pihole-v1.sh --- ct/{pihole_container.sh => pihole-v1.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{pihole_container.sh => pihole-v1.sh} (100%) diff --git a/ct/pihole_container.sh b/ct/pihole-v1.sh similarity index 100% rename from ct/pihole_container.sh rename to ct/pihole-v1.sh From 555dd55cbbf47a7bbb460259e8cf0ed625bad899 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:39:57 -0400 Subject: [PATCH 2337/6505] Update pihole-install.sh --- setup/pihole-install.sh | 79 ++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 29b0721a..7547937a 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,29 +37,26 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null +msg_info "Updating Container OS" +apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Pi-hole... " +msg_info "Installing Pi-hole" curl -sSL https://install.pi-hole.net | bash -echo -e "${CM}${CL} \r" +msg_ok "Installed Pi-hole" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -80,11 +69,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 870a2a6029813bf3244e6e3e991cadfbc7f5124a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:44:25 -0400 Subject: [PATCH 2338/6505] Create grafana-v3.sh --- ct/grafana-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/grafana-v3.sh diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh new file mode 100644 index 00000000..3fc2d0ba --- /dev/null +++ b/ct/grafana-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Grafana" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _____ __ + / ____| / _| + | | __ _ __ __ _| |_ __ _ _ __ __ _ + | | |_ | __/ _ | _/ _ | _ \ / _ | + | |__| | | | (_| | || (_| | | | | (_| | + \_____|_|v3\__,_|_| \__,_|_| |_|\__,_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/grafana-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 00bfa3f89b91fc5fffd6af2e51f46ee032a4da0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:44:51 -0400 Subject: [PATCH 2339/6505] Rename grafana.sh to grafana-v2.sh --- ct/{grafana.sh => grafana-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{grafana.sh => grafana-v2.sh} (100%) diff --git a/ct/grafana.sh b/ct/grafana-v2.sh similarity index 100% rename from ct/grafana.sh rename to ct/grafana-v2.sh From 810ee98a673040526f7c19c8b5fe766db077b16a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:49:39 -0400 Subject: [PATCH 2340/6505] Update grafana-install.sh --- setup/grafana-install.sh | 76 ++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 7dc47536..3fb1037b 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,36 +37,35 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y gnupg &>/dev/null apt-get install -y apt-transport-https &>/dev/null apt-get install -y software-properties-common &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Grafana Repository... " +msg_info "Setting up Grafana Repository" wget -qO- https://packages.grafana.com/gpg.key | sudo apt-key add - &>/dev/null echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Grafana Repository" -echo -en "${GN} Installing Grafana... " +msg_info "Installing Grafana" apt-get update &>/dev/null apt-get install -y grafana &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Grafana" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -87,12 +78,13 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi systemctl start grafana-server systemctl enable grafana-server.service &>/dev/null -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 1a2d4a8eb88303fcce4837f7b879cde57f79e58f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:54:36 -0400 Subject: [PATCH 2341/6505] Create influxdb-v3.sh --- ct/influxdb-v3.sh | 314 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 ct/influxdb-v3.sh diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh new file mode 100644 index 00000000..11572293 --- /dev/null +++ b/ct/influxdb-v3.sh @@ -0,0 +1,314 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="InfluxDB" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _____ __ _ _____ ____ + |_ _| / _| | | __ \| _ \ + | | _ __ | |_| |_ v3___ _| | | | |_) | + | | | _ \| _| | | | \ \/ / | | | _ < + _| |_| | | | | | | |_| |> <| |__| | |_) | + |_____|_| |_|_| |_|\__,_/_/\_\_____/|____/ + with Telegraf +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/influxdb-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" From 419044ee27f87fad532e8295198d6effb973a013 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 03:54:58 -0400 Subject: [PATCH 2342/6505] Rename influxdb.sh to influxdb-v2.sh --- ct/{influxdb.sh => influxdb-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{influxdb.sh => influxdb-v2.sh} (100%) diff --git a/ct/influxdb.sh b/ct/influxdb-v2.sh similarity index 100% rename from ct/influxdb.sh rename to ct/influxdb-v2.sh From fd2199f8a0477dc342e212592bfadff55b1126c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:00:02 -0400 Subject: [PATCH 2343/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 81 +++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 220f9bae..b1156a0c 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,40 +37,39 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y lsb-base &>/dev/null apt-get install -y lsb-release &>/dev/null apt-get install -y gnupg2 &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up InfluxDB Repository... " +msg_info "Setting up InfluxDB Repository" wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add - &>/dev/null echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up InfluxDB Repository" -echo -en "${GN} Installing InfluxDB... " +msg_info "Installing InfluxDB" apt-get update &>/dev/null apt-get install -y influxdb &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed InfluxDB" -echo -en "${GN} Installing Telegraf... " +msg_info "Installing Telegraf" apt-get install -y telegraf &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Telegraf" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -91,11 +82,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From fc19e6b239bc929fb10b8fe3ea250701253b6a74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:04:52 -0400 Subject: [PATCH 2344/6505] Create meshcentral-v3.sh --- ct/meshcentral-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/meshcentral-v3.sh diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh new file mode 100644 index 00000000..776f2752 --- /dev/null +++ b/ct/meshcentral-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="MeshCentral" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + __ __ _ _____ _ _ + | \/ | | | / ____| | | | | + | \ / | ___ ___| |__ | | ___ _ __ | |_ _ __ __ _| | + | |\/| |/ _ \/ __| _ \| | v3 / _ \ _ \| __| __/ _ | | + | | | | __/\__ \ | | | |___| __/ | | | |_| | | (_| | | + |_| |_|\___||___/_| |_|\_____\___|_| |_|\__|_| \__,_|_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/meshcentral-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From 10c7f01d7219c759cabc7e5d892f58a32eea0d59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:05:15 -0400 Subject: [PATCH 2345/6505] Rename meshcentral.sh to meshcentral-v2.sh --- ct/{meshcentral.sh => meshcentral-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{meshcentral.sh => meshcentral-v2.sh} (100%) diff --git a/ct/meshcentral.sh b/ct/meshcentral-v2.sh similarity index 100% rename from ct/meshcentral.sh rename to ct/meshcentral-v2.sh From 2f9868d9b640c8d4a828c760556cb55446de2a03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:10:10 -0400 Subject: [PATCH 2346/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 79 ++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 13ec017e..936c1663 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,38 +37,37 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_lnfo "Installing Node.js" apt-get install -y nodejs &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Installing MeshCentral... " +msg_info "Installing MeshCentral" mkdir /opt/meshcentral cd /opt/meshcentral npm install meshcentral &>/dev/null node node_modules/meshcentral --install &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed MeshCentral" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -89,11 +80,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 4b9763411d0452a0fb0750688f4b885f341da9b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:15:53 -0400 Subject: [PATCH 2347/6505] Create omada-v3.sh --- ct/omada-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/omada-v3.sh diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh new file mode 100644 index 00000000..5d4e3f47 --- /dev/null +++ b/ct/omada-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Omada" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + ____ _ _____ _ _ _ + / __ \ | | / ____| | | | | | + | | | |_ __ ___ v3__ _ __| | __ _ | | ___ _ __ | |_ _ __ ___ | | | ___ _ __ + | | | | _ _ \ / _ |/ _ |/ _ | | | / _ \| _ \| __| __/ _ \| | |/ _ \ __| + | |__| | | | | | | (_| | (_| | (_| | | |___| (_) | | | | |_| | | (_) | | | __/ | + \____/|_| |_| |_|\__,_|\__,_|\__,_| \_____\___/|_| |_|\__|_| \___/|_|_|\___|_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/omada-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:8043${CL} \n" From d2c59f9aebcafe897543b70d6ec6ca6868c3d69c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:16:22 -0400 Subject: [PATCH 2348/6505] Rename omada.sh to omada-v2.sh --- ct/{omada.sh => omada-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{omada.sh => omada-v2.sh} (100%) diff --git a/ct/omada.sh b/ct/omada-v2.sh similarity index 100% rename from ct/omada.sh rename to ct/omada-v2.sh From 603ab6d6f22f5fecbf7bbc1818a54e996f1969f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:21:01 -0400 Subject: [PATCH 2349/6505] Update omada-install.sh --- setup/omada-install.sh | 79 +++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 52edef5c..c03a47ff 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,16 +37,15 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get -y install curl &>/dev/null apt-get -y install sudo &>/dev/null apt-get -y install gnupg &>/dev/null @@ -65,16 +56,16 @@ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list &>/dev/null apt-get update &>/dev/null apt-get -y install mongodb-org &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing Omada Controller... " +msg_info "Installing Omada Controller" wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" chmod -x /etc/update-motd.d/* touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" @@ -86,11 +77,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleaning Up... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /tmp/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From ceef851aa78dc4a3b3e8f908efb9505389e40ced Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:22:15 -0400 Subject: [PATCH 2350/6505] Update omada-v3.sh --- ct/omada-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index 5d4e3f47..fbd3b664 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -287,8 +287,8 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 +export PCT_OSTYPE=ubuntu +export PCT_OSVERSION=20.04 export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES From 1bd3052db10360083d6594ca772740e03adb838f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:28:19 -0400 Subject: [PATCH 2351/6505] Create unifi-v3.sh --- ct/unifi-v3.sh | 315 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/unifi-v3.sh diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh new file mode 100644 index 00000000..16fa88a9 --- /dev/null +++ b/ct/unifi-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Unifi" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _ _ _ ______ _ + | | | | (_) ____(_) + | | | |_ __ _| |__ _ + | | | | _ \| | __| | | + | |__| | | | | | | | | + \____/|_| |_|_|_| v3 |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/unifi-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP}${CL} should be reachable by going to the following URL. + ${BL}https://${IP}:8443${CL} \n" From 462f2a11ce3759ba6b0fa5c23f85cfc17e4a5cc7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:28:58 -0400 Subject: [PATCH 2352/6505] Rename unifi.sh to unifi-v2.sh --- ct/{unifi.sh => unifi-v2.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{unifi.sh => unifi-v2.sh} (100%) diff --git a/ct/unifi.sh b/ct/unifi-v2.sh similarity index 100% rename from ct/unifi.sh rename to ct/unifi-v2.sh From 10b88cb53ea8a71153cfb6a6937e534654e47b16 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:32:27 -0400 Subject: [PATCH 2353/6505] Update unifi-install.sh --- setup/unifi-install.sh | 70 +++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 3c00fe08..79ff07d2 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -1,38 +1,31 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash -ex #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,27 +38,26 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Installing UniFi Network Application... " +msg_info "Installing UniFi Network Application" wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed UniFi Network Application" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -78,11 +70,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From f01fa8246f20c0af023c3faef6f320b8b877cf02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:41:50 -0400 Subject: [PATCH 2354/6505] Update README.md --- README.md | 76 ++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 89b7de8e..dfd796fe 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant OS VM + Home Assistant OS VM

    @home-assistant

    @@ -127,7 +127,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant Container LXC + Home Assistant Container LXC

    Docker Logos | Docker @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    @@ -201,7 +201,7 @@ ________________________________________________________________________________
    - 🔸Podman Home Assistant Container LXC + Podman Home Assistant Container LXC

    @home-assistant

    @@ -271,7 +271,7 @@ ________________________________________________________________________________
    - 🔸Homebridge LXC + Homebridge LXC

    @@ -327,7 +327,7 @@ Update from the Homebridge UI
    - 🔸ESPHome LXC + ESPHome LXC

    @@ -357,7 +357,7 @@ ________________________________________________________________________________
    - 🔸Nginx Proxy Manager LXC + Nginx Proxy Manager LXC

    hero

    @@ -407,7 +407,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update
    - 🔸MQTT LXC + MQTT LXC

    @@ -458,7 +458,7 @@ ________________________________________________________________________________
    - 🔸Node-Red LXC + Node-Red LXC

    @@ -501,7 +501,7 @@ ________________________________________________________________________________
    - 🔸Mariadb LXC + Mariadb LXC

    MariaDB

    @@ -612,7 +612,7 @@ ________________________________________________________________________________
    - 🔸Zigbee2MQTT LXC + Zigbee2MQTT LXC

    @@ -693,7 +693,7 @@ ________________________________________________________________________________
    - 🔸Zwavejs2MQTT LXC + Zwavejs2MQTT LXC

    @@ -726,7 +726,7 @@ ________________________________________________________________________________
    - 🔸NocoDB LXC + NocoDB LXC

    @@ -762,16 +762,14 @@ ________________________________________________________________________________

    InfluxDB/Telegraf LXC

    -To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - ⚙️ **InfluxDB Configuration** Run in the LXC console @@ -804,16 +802,14 @@ ________________________________________________________________________________

    Grafana LXC

    -To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -After the script completes, If you're dissatisfied with the default settings, click on the LXC, then on the **_Resources_** tab and change the settings to what you desire. Changes are immediate. - **Grafana Interface - IP:3000** ⚙️ **Initial Login** @@ -839,7 +835,7 @@ ________________________________________________________________________________
    - 🔸Docker LXC + Docker LXC

    @@ -868,7 +864,7 @@ ________________________________________________________________________________
    - 🔸Debian 11 LXC + Debian 11 LXC

    Debian

    @@ -895,7 +891,7 @@ ________________________________________________________________________________
    - 🔸Ubuntu 21.10 LXC + Ubuntu 21.10 LXC

    Ubuntu

    @@ -932,7 +928,7 @@ An application designed to optimize UniFi home and business networks with ease. To create a new Proxmox UniFi Network Application LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -961,7 +957,7 @@ Omada Controller is software which is used to manage the EAP To create a new Proxmox Omada Controller LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v3.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -995,7 +991,7 @@ MeshCentral is a full computer management web site. With MeshCentral, you can ru To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1012,7 +1008,7 @@ ________________________________________________________________________________
    - 🔸Plex Media Server LXC + Plex Media Server LXC

    @@ -1045,7 +1041,7 @@ ________________________________________________________________________________
    - 🔸Jellyfin Media Server LXC + Jellyfin Media Server LXC

    Jellyfin Media Server LXC

    @@ -1077,10 +1073,10 @@ ________________________________________________________________________________

    Pi-hole LXC

    -To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell (V2). +To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v3.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1102,7 +1098,7 @@ ________________________________________________________________________________
    - 🔸Technitium DNS LXC + Technitium DNS LXC

    @@ -1130,7 +1126,7 @@ ________________________________________________________________________________
    - 🔸AdGuard Home LXC + AdGuard Home LXC

    @@ -1158,7 +1154,7 @@ ________________________________________________________________________________
    - 🔸Uptime Kuma LXC + Uptime Kuma LXC

    @@ -1188,7 +1184,7 @@ ________________________________________________________________________________
    - 🔸Heimdall Dashboard LXC + Heimdall Dashboard LXC

    @@ -1218,7 +1214,7 @@ ________________________________________________________________________________
    - 🔸Dashy LXC + Dashy LXC

    @@ -1250,7 +1246,7 @@ ________________________________________________________________________________
    - 🔸PhotoPrism LXC + PhotoPrism LXC

    @@ -1293,7 +1289,7 @@ ________________________________________________________________________________
    - 🔸Daemon Sync Server LXC + Daemon Sync Server LXC

    @@ -1318,7 +1314,7 @@ ________________________________________________________________________________
    - 🔸MotionEye VMS LXC + MotionEye VMS LXC

    @@ -1405,7 +1401,7 @@ ________________________________________________________________________________
    - 🔸WireGuard LXC + WireGuard LXC

    @@ -1456,7 +1452,7 @@ ________________________________________________________________________________
    - 🔸Vaultwarden LXC + Vaultwarden LXC

    From 69a25b9d1cd405ca3e10efd1fb77326d02f6a728 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:44:44 -0400 Subject: [PATCH 2355/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 66 ++-------------------------------------------------- 1 file changed, 2 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index dc4074fb..3addae7a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,74 +5,12 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) -## 2022-04-18 +## 2022-04-19 ### Changed -- **Adguard LXC** +- **ALL LXC's** - New [V3 Install Script](https://github.com/tteck/Proxmox/issues/162) -- **Homebridge LXC** - - New V3 Install Script -- **Uptime Kuma LXC** - - New V3 Install Script -- **Vaultwarden LXC** - - New V3 Install Script -- **Motioneye LXC** - - New V3 Install Script -- **Nginx Proxy Manager LXC** - - New V3 Install Script -- **Daemon Sync Server LXC** - - New V3 Install Script -- **Dashy LXC** - - New V3 Install Script -- **Heimdall Dashboard LXC** - - New V3 Install Script -- **Wireguard LXC** - - New V3 Install Script -- **Node-Red LXC** - - New V3 Install Script -- **MQTT LXC** - - New V3 Install Script -- **Mariadb LXC** - - New V3 Install Script -- **Ubuntu 21.10 LXC** - - New V3 Install Script -- **NocoDB LXC** - - New V3 Install Script -- **Plex Media Server LXC** - - New V3 Install Script -- **Jellyfin Media Server LXC** - - New V3 Install Script - -## 2022-04-17 - -### Changed - -- **Zigbee2MQTT LXC** - - New V3 Install Script -- **Zwavejs2MQTT LXC** - - New V3 Install Script -- **ESPHome LXC** - - New V3 Install Script -- **Technitium DNS LXC** - - New V3 Install Script -- **Podman Home Assistant LXC** - - New V3 Install Script -- **Docker LXC** - - New V3 Install Script -- **PhotoPrism LXC** - - New V3 Install Script - -## 2022-04-16 - -### Changed - -- **Home Assistant OS VM** - - New "Limited" V3 Install Script -- **Home Assistant Container LXC** - - New V3 Install Script -- **Debian 11 LXC** - - New V3 Install Script ## 2022-04-13 From 7d53720e5ad5919f575807e443515a5cc5e49065 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:46:10 -0400 Subject: [PATCH 2356/6505] Update plex-v3.sh --- ct/plex-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index ebed4526..1a5c6fde 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -89,7 +89,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS} ${YW}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From b5d1fb21fd2cecfee4e45b05fce326c8ec47299e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:47:11 -0400 Subject: [PATCH 2357/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 2fd5a1ac..4df0bc04 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -91,7 +91,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS} ${YW}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From 229539f58d1e8221a36fd52026695152c18378e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:48:35 -0400 Subject: [PATCH 2358/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index c1da0388..462c3bf9 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -13,6 +13,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" APP="Zigbee2MQTT" NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do @@ -90,7 +91,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From 090a658fe53d10997012dfc4ece080fe7b36193d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:49:38 -0400 Subject: [PATCH 2359/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 12e5d42c..9135bd34 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -13,6 +13,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" APP="Zwavejs2MQTT" NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do @@ -89,7 +90,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From ec644df2b8398ab092fab33c01f58de0267bcb0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:56:37 -0400 Subject: [PATCH 2360/6505] Delete gamuntu.sh --- ct/gamuntu.sh | 224 -------------------------------------------------- 1 file changed, 224 deletions(-) delete mode 100644 ct/gamuntu.sh diff --git a/ct/gamuntu.sh b/ct/gamuntu.sh deleted file mode 100644 index f390625a..00000000 --- a/ct/gamuntu.sh +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="GamUntu" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${GN} - _____ _ _ _ - / ____| | | | | | | - | | __ __ _ _ __ ___ | | | |_ __ | |_ _ _ - | | |_ |/ _ | _ _ \| | | | _ \| __| | | | - | |__| | (_| | | | | | | |__| | | | | |_| |_| | - \_____|\__,_|_| |_| |_|\____/|_| |_|\__|\__,_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${GN} Privileged ${CL}\n" - printf " ${YW} 2)${RD} Unprivileged (no device passthrough)${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - fi - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message}${CL}\n" -} -show_menu2 -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - fi - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=21.10 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/uinput dev/uinput none bind,optional,create=dir -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}Webmin${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:10000${CL} \n" From 7b0911931dc7ccf8dcf4ca928a276e1c92fbd843 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 04:56:58 -0400 Subject: [PATCH 2361/6505] Delete gamuntu_container.sh --- ct/gamuntu_container.sh | 188 ---------------------------------------- 1 file changed, 188 deletions(-) delete mode 100644 ct/gamuntu_container.sh diff --git a/ct/gamuntu_container.sh b/ct/gamuntu_container.sh deleted file mode 100644 index d0fbe6fb..00000000 --- a/ct/gamuntu_container.sh +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New GamUntu LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/gamuntu_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=gamuntu -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -if [ "$STORAGE_TYPE" == "zfspool" ]; then - CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" -else - CT_FEATURES="nesting=1" -fi -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/uinput dev/uinput none bind,optional,create=dir -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -info "Using fuse-overlayfs." -fi -pct push $CTID gamuntu_setup.sh /gamuntu_setup.sh -perms 755 -pct exec $CTID /gamuntu_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a GamUntu LXC Container to $CTID at IP Address ${IP}" -echo -e "\e[1;92m Webmin should be reachable by going to the following URL. - https://${IP}:10000 -\e[0m" \ No newline at end of file From 785ff0fb61f7f8ad6e62e085afb6a3e9b9db9ca3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 06:34:44 -0400 Subject: [PATCH 2362/6505] Create iobroker-v3.sh --- ct/iobroker-v3.sh | 315 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 ct/iobroker-v3.sh diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh new file mode 100644 index 00000000..645910ed --- /dev/null +++ b/ct/iobroker-v3.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob + +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="ioBroker" +NSAPP=$(echo ${APP,,} | tr -d ' ') +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _ ____ _ + (_) | _ \ | | + _ ___ | |_) |_ __ ___ | | _____ _ __ + | |/ _ \| _ <| __/ _ \| |/ / _ \ __| + | | (_) | |_) | | | (_) | < __/ | + |_|\___/|____/|_|v3\___/|_|\_\___|_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE=" " + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN=" " +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/iobroker-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8081${CL} \n" From ae5e2f4ad93fc933e8f798b87dac72c6d06c2aec Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 06:37:51 -0400 Subject: [PATCH 2363/6505] Create iobroker-install.sh --- setup/iobroker-install.sh | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 setup/iobroker-install.sh diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh new file mode 100644 index 00000000..1922beab --- /dev/null +++ b/setup/iobroker-install.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing ioBroker" +curl -sLf https://iobroker.net/install.sh | bash - &>/dev/null +msg_ok "Installed ioBroker" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 8f9a3323ce194e8d109aa86fb0ec12607c88af26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 07:11:44 -0400 Subject: [PATCH 2364/6505] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index dfd796fe..d61ddc6a 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,35 @@ After install, reboot Home Assistant and **clear browser cache** then Add HACS i ____________________________________________________________________________________________
    +
    + 🔸ioBroker LXC + +

    + +

    ioBroker LXC

    + +[ioBroker](https://www.iobroker.net/#en/intro) is an open source automation platform. + +To create a new Proxmox ioBroker LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/iobroker-v3.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**ioBroker Interface - IP:8081** + +⚙️ **To Update ioBroker** + +```yaml +update from the ioBroker UI +``` + +____________________________________________________________________________________________ + +
    +
    Homebridge LXC From cf831d4cb3d104b511db6ec1ea04334c3d7412ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 07:13:13 -0400 Subject: [PATCH 2365/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3addae7a..d4bd2092 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - **ALL LXC's** - New [V3 Install Script](https://github.com/tteck/Proxmox/issues/162) +- **ioBroker LXC** + - New Script V3 ## 2022-04-13 From 9669e36b4d0d6392ae2cf5e227abd590ab24768e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 07:15:55 -0400 Subject: [PATCH 2366/6505] Update iobroker-install.sh --- setup/iobroker-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 1922beab..f63611fc 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -50,7 +50,7 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing ioBroker" +msg_info "Installing ioBroker (10 min)" curl -sLf https://iobroker.net/install.sh | bash - &>/dev/null msg_ok "Installed ioBroker" From cedd77c46b9c20ad83e34e79a6094538113328fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:35:57 -0400 Subject: [PATCH 2367/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index 8a76ccf9..dd93d417 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From fd677d7cbfdb795beb2565df482c7dd18c6461de Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:40:32 -0400 Subject: [PATCH 2368/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index 8a76ccf9..dd93d417 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From d1cf1ea7e6815e392802c525a3f059cdcac97602 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:49:19 -0400 Subject: [PATCH 2369/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index 5deca39f..a461d709 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -67,24 +67,24 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -215,7 +215,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -238,7 +238,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 3173b250e4fd9964c74c3cfb7ed890a0f864931d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:50:33 -0400 Subject: [PATCH 2370/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index 3d8ad2ff..c1b763ca 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -82,9 +82,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -215,7 +215,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -238,7 +238,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 64561422e9aa8bd9ace065cf223fb0de81df0f1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:51:25 -0400 Subject: [PATCH 2371/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index 7d789f1e..9d86c691 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -82,9 +82,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -215,7 +215,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -238,7 +238,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From bfa72b0ce1a2d455f79e5a409610c6a5736ce313 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:52:42 -0400 Subject: [PATCH 2372/6505] Update debian-v3.sh --- ct/debian-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index e5b98317..023939fc 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From d4f49ade1abca521612b6477f8033eaf5188b8ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:53:33 -0400 Subject: [PATCH 2373/6505] Update docker-v3.sh --- ct/docker-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 46da64aa..05b49f8e 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -79,9 +79,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -212,7 +212,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -235,7 +235,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From a8c1510e8c46bbebf65be65f905116b3c88281ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:54:23 -0400 Subject: [PATCH 2374/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index fbfac335..2c451cda 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -81,9 +81,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -214,7 +214,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -237,7 +237,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From bd7425877cc369d0759c7db64df302df47174882 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:55:13 -0400 Subject: [PATCH 2375/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index 3fc2d0ba..71b7f3cd 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 8fdf6b5d3d855bc9c48bba6f9930eeb823539124 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:56:02 -0400 Subject: [PATCH 2376/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index 16de9e56..15929ea2 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -81,9 +81,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -214,7 +214,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -237,7 +237,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From a535001280bb59e03fd1e9f58052c6e7b4cd30ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:56:57 -0400 Subject: [PATCH 2377/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index c8242a8c..b7d52358 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -79,9 +79,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -212,7 +212,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -235,7 +235,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 003ddc5cd3bba62573dfe80ea1c1e17732195710 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:57:55 -0400 Subject: [PATCH 2378/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 826573bc..7238548f 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 9e4e5242c0b22f67d01eaa9732619a803cf7a544 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:58:41 -0400 Subject: [PATCH 2379/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index 11572293..dc75e8ce 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -81,9 +81,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -214,7 +214,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -237,7 +237,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 88eb54e41fb51b04264ca032b1579264179b206b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 11:59:27 -0400 Subject: [PATCH 2380/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 645910ed..b41da184 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 7ca20beeb059b4dcf6463969ca048238689dd049 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:00:14 -0400 Subject: [PATCH 2381/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 4df0bc04..0893d1c2 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -82,9 +82,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -215,7 +215,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -238,7 +238,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From af825b68319439d9c90e98098b5d7534f3e3dbf6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:01:08 -0400 Subject: [PATCH 2382/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 15c26710..1b40846c 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From d2922c67fa09a84e4fc3472645a162d055e71e83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:01:52 -0400 Subject: [PATCH 2383/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index 776f2752..bb5f8441 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 799b720fa3d31b3a894ab94c51fc4b6d9f9348e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:02:50 -0400 Subject: [PATCH 2384/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index d2e43ca5..f1ed01df 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 821a8a141dd64c1ad2ef3b258e459b2937b0c7da Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:03:32 -0400 Subject: [PATCH 2385/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index aab3e5c5..49dd42c3 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 1bdbf9a604dab4afe0a7b6126f293ba14995dc88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:04:17 -0400 Subject: [PATCH 2386/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index 8eb3fc47..ccb8735c 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From a8e800cb32d060ba3e372e0b8188d1ce396dc7ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:05:09 -0400 Subject: [PATCH 2387/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index 1f0d38bb..601b8237 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 4b020d598df1ad0a332bc3ab6799b0e7e4256cc9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:05:51 -0400 Subject: [PATCH 2388/6505] Update omada-v3.sh --- ct/omada-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index fbd3b664..b308f58d 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 33d5cff2022a7e1bea610acec48f9989942e3f95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:06:38 -0400 Subject: [PATCH 2389/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 67547300..2688a16a 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 505cdc3108a23155a2ec2f007c3dd45f588acf99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:07:24 -0400 Subject: [PATCH 2390/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 1d9c5723..f0d7029a 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From d5f7983bb415a6c8ff2898dcde8e706b1fa894aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:08:15 -0400 Subject: [PATCH 2391/6505] Update plex-v3.sh --- ct/plex-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 1a5c6fde..27307445 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 7a1cb26efb9690c77975f1ae4ec1a3d3cc6ccf64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:08:58 -0400 Subject: [PATCH 2392/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 75893d4b..2d23e779 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -85,9 +85,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -218,7 +218,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -241,7 +241,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 521c48dbde0b30c57d2e766062766e8bfdceca83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:09:44 -0400 Subject: [PATCH 2393/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 5a466254..c679db72 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 1daf0a465912b40339f3e8bca6b0bdc232e7e857 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:10:26 -0400 Subject: [PATCH 2394/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index c430232a..2e56f7c1 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 1dc3bd968cabc865a3a6b6ea2dc3db363e73f474 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:11:11 -0400 Subject: [PATCH 2395/6505] Update unifi-v3.sh --- ct/unifi-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index 16fa88a9..18c9c419 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From e7125046f516ad1ae2bd6c039b1b71df8b634461 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:11:51 -0400 Subject: [PATCH 2396/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index af05bb94..cf070784 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -82,9 +82,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -215,7 +215,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -238,7 +238,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 02e8e4ba4d4ea720d41f172e0043e8b56cbd2fbf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:12:35 -0400 Subject: [PATCH 2397/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index 8149e55c..01c5df98 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -80,9 +80,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -213,7 +213,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -236,7 +236,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 4c3b3dfb255a3a9a53be15f8fef074f75c29a273 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:13:21 -0400 Subject: [PATCH 2398/6505] Update wireguard-v3.sh --- ct/wireguard-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index 7584a91e..5e0b0108 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -81,9 +81,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -214,7 +214,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -237,7 +237,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From f8cfe6237c37c7c661e0867c29c2a18c5f171a37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:14:04 -0400 Subject: [PATCH 2399/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 462c3bf9..796b7124 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -82,9 +82,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -215,7 +215,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -238,7 +238,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 556746ad303235fb4f10ba661b993c6eea70d35c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 12:14:44 -0400 Subject: [PATCH 2400/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 9135bd34..8b70fb41 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -81,9 +81,9 @@ function default_settings() { echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE=" " + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN=" " + VLAN="" } function advanced_settings() { @@ -214,7 +214,7 @@ header_info echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=" "; + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" else GATE=",gw=$GATE1" @@ -237,7 +237,7 @@ header_info echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=" "; + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" else VLAN=",tag=$VLAN1" From 549e697467fe59a558e1ed25f0ed0e49651b5a71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 15:43:16 -0400 Subject: [PATCH 2401/6505] Update uptimekuma-install.sh --- setup/uptimekuma-install.sh | 83 +++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index cdb110ab..67dd3749 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,37 +37,36 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y git &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" sudo apt-get install -y nodejs &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Installing Uptime Kuma... " +msg_info "Installing Uptime Kuma" git clone https://github.com/louislam/uptime-kuma.git &>/dev/null mv uptime-kuma /opt/uptime-kuma cd /opt/uptime-kuma npm run setup &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Uptime Kuma" -echo -en "${GN} Creating Service file uptime-kuma.service... " +msg_info "Creating Service" service_path="/etc/systemd/system/uptime-kuma.service" echo "[Unit] Description=uptime-kuma @@ -90,11 +81,11 @@ ExecStart=/usr/bin/npm start [Install] WantedBy=multi-user.target" > $service_path systemctl enable --now uptime-kuma.service &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -107,11 +98,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi -echo -en "${GN} Cleanup... " +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 57e09fc20e062103bf7d4c0b4f116c64559c921e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 15:47:24 -0400 Subject: [PATCH 2402/6505] Delete gamuntu-install.sh --- setup/gamuntu-install.sh | 131 --------------------------------------- 1 file changed, 131 deletions(-) delete mode 100644 setup/gamuntu-install.sh diff --git a/setup/gamuntu-install.sh b/setup/gamuntu-install.sh deleted file mode 100644 index 46efea00..00000000 --- a/setup/gamuntu-install.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - libnet-ssleay-perl \ - libauthen-pam-perl \ - libio-pty-perl \ - unzip \ - shared-mime-info &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Downloading Webmin... " -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Webmin... " -dpkg --install webmin_1.984_all.deb &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Setting Default Webmin usermame & password to root... " -/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /root/webmin_1.984_all.deb -echo -e "${CM}${CL} \r" - -echo -en "${GN} Setting Up Hardware Acceleration... " -apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Docker... " -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF -sh <(curl -sSL https://get.docker.com) &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Docker Compose... " -sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose &>/dev/null -sudo chmod +x /usr/local/bin/docker-compose -docker network create proxy &>/dev/null -echo -e "${CM}${CL} \r" - -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - fi - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From d981693fa8c92ed5ba267aaece8001aa041713bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 15:47:43 -0400 Subject: [PATCH 2403/6505] Delete gamuntu_setup.sh --- setup/gamuntu_setup.sh | 109 ----------------------------------------- 1 file changed, 109 deletions(-) delete mode 100644 setup/gamuntu_setup.sh diff --git a/setup/gamuntu_setup.sh b/setup/gamuntu_setup.sh deleted file mode 100644 index 4930a0a0..00000000 --- a/setup/gamuntu_setup.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - libnet-ssleay-perl \ - libauthen-pam-perl \ - libio-pty-perl \ - unzip \ - shared-mime-info &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading Webmin... \e[0m" -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.984_all.deb &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Webmin... \e[0m" -dpkg --install webmin_1.984_all.deb &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting Default Webmin usermame & password to root... \e[0m" -/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /root/webmin_1.984_all.deb - -echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" -apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* - -echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF -sh <(curl -sSL https://get.docker.com) &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Docker Compose... \e[0m" -sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose &>/dev/null -sudo chmod +x /usr/local/bin/docker-compose -docker network create proxy &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /gamuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* From e41a1b45e47f60b65ba178a7451c955b9fca785a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 15:52:11 -0400 Subject: [PATCH 2404/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 85 +++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 7f9f289e..436c387e 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -1,38 +1,30 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" -echo -en "${GN} Setting up Container OS... " +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -45,39 +37,38 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" -echo -en "${GN} Updating Container OS... " +msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Updated Container OS" -echo -en "${GN} Installing Dependencies... " +msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Dependencies" -echo -en "${GN} Setting up Node.js Repository... " +msg_info "Setting up Node.js Repository" curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Set up Node.js Repository" -echo -en "${GN} Installing Node.js... " +msg_info "Installing Node.js" sudo apt-get install -y nodejs gcc g++ make python net-tools &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Node.js" -echo -en "${GN} Installing Homebridge... " +msg_info "nstalling Homebridge" sudo npm install -g --unsafe-perm homebridge homebridge-config-ui-x &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "nstalled Homebridge" -echo -en "${GN} Creating Homebridge Service... " +msg_info "Creating Service" sudo hb-service install --user homebridge &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " +msg_info "Customizing Container" rm /etc/motd rm /etc/update-motd.d/10-uname touch ~/.hushlogin @@ -90,11 +81,11 @@ ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,3840 EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" +msg_ok "Customized Container" fi - -echo -en "${GN} Cleanup... " + +msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" +msg_ok "Cleaned" From 19dcd6dc74ebabef36f5901949473c524036db57 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Apr 2022 16:16:54 -0400 Subject: [PATCH 2405/6505] Delete zwavejs2mqtt-install.nodejs --- setup/zwavejs2mqtt-install.nodejs | 119 ------------------------------ 1 file changed, 119 deletions(-) delete mode 100644 setup/zwavejs2mqtt-install.nodejs diff --git a/setup/zwavejs2mqtt-install.nodejs b/setup/zwavejs2mqtt-install.nodejs deleted file mode 100644 index 2c921eb9..00000000 --- a/setup/zwavejs2mqtt-install.nodejs +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - unzip &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Setting up Node.js Repository... " -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Node.js... " -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing yarn... " -npm install --global yarn &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Build/Install Zwavejs2MQTT (5-6 min)... " -sudo git clone https://github.com/zwave-js/zwavejs2mqtt /opt/zwavejs2mqtt &>/dev/null -cd /opt/zwavejs2mqtt &>/dev/null -yarn install &>/dev/null -yarn run build &>/dev/null -echo -e "${CM}${CL} \r" -echo -en "${GN} Creating Service file zwavejs2mqtt.service... " -service_path="/etc/systemd/system/zwavejs2mqtt.service" - -echo "[Unit] -Description=zwavejs2mqtt -After=network.target -[Service] -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zwavejs2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path -systemctl start zwavejs2mqtt -systemctl enable zwavejs2mqtt &>/dev/null -echo -e "${CM}${CL} \r" - -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - fi - -echo -en "${GN} Cleanup... " -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" From 9409ddcf5b627e36c8dd609dbed4fe30327375f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 10:03:07 -0400 Subject: [PATCH 2406/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 2e56f7c1..21be5cc9 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -60,12 +60,14 @@ function PVE_CHECK() { } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using Version ${BGN}21.10${CL}" + VER="21.10" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID @@ -89,6 +91,19 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type 20.04, or Press [ENTER] for Default: 21.10" + read VER + if [ -z $VER ]; then VER="21.10"; + else + VER="20.04" + fi + echo -en "${DGN}Set Version To ${BL}$VER${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; @@ -103,6 +118,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " read PW1 @@ -117,6 +133,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " @@ -128,6 +145,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -144,6 +162,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -158,6 +177,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -172,6 +192,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -187,6 +208,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -203,6 +225,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -225,6 +248,7 @@ clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -247,6 +271,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -288,7 +313,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$CT_ID export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=21.10 +export PCT_OSVERSION=$VER export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES From f7c82125c828c2a953f7ca756167eb24658ef866 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 10:04:53 -0400 Subject: [PATCH 2407/6505] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d61ddc6a..0596f7ec 100644 --- a/README.md +++ b/README.md @@ -920,13 +920,13 @@ ________________________________________________________________________________
    - Ubuntu 21.10 LXC + 🔸Ubuntu 20.04/21.10 LXC

    Ubuntu

    -

    Ubuntu 21.10 LXC

    +

    Ubuntu 20.04/21.10 LXC

    -To create a new Proxmox Ubuntu 21.10 (curl. sudo) LXC, run the following in the Proxmox Shell. +To create a new Proxmox Ubuntu 20.04/21.10 (curl. sudo) LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh)" @@ -934,7 +934,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -⚙️ **To Update Ubuntu 21.10** +⚙️ **To Update Ubuntu 20.04/21.10** Run in the LXC console ```yaml From bd6674ed8b09a9f0c493ca6fc60dfb20905cc114 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 10:07:29 -0400 Subject: [PATCH 2408/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d4bd2092..05f7c90c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-20 + +### Changed + +- **Ubuntu LXC** + - ADD option to install version 20.04 or 21.10 + ## 2022-04-19 ### Changed From 3f14c62f2edebd631cdd5e647b6d41a932a180ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 14:27:25 -0400 Subject: [PATCH 2409/6505] Update create_lxc.sh --- ct/create_lxc.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 405bd0c9..c02f22bc 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -119,6 +119,7 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_ok "Downloaded LXC Template" pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." + msg_ok "Downloaded LXC Template" fi DEFAULT_PCT_OPTIONS=( From ea37a7f2f0d6d3869208f43785e6d56718e04e6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 14:34:22 -0400 Subject: [PATCH 2410/6505] Update create_lxc.sh --- ct/create_lxc.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index c02f22bc..c0db635d 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -116,7 +116,6 @@ TEMPLATE="${TEMPLATES[-1]}" if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_info "Downloading LXC Template" - msg_ok "Downloaded LXC Template" pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." msg_ok "Downloaded LXC Template" From fb423eb3166a744d85d85ccf706c6ad527d68650 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 14:56:58 -0400 Subject: [PATCH 2411/6505] Update docker-v3.sh --- ct/docker-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 05b49f8e..a51ab9d7 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -193,10 +193,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then NET="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -209,6 +209,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -231,6 +249,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -253,6 +272,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From aa59cfa65e23097744de01fe10c5a7fe35b696d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:00:19 -0400 Subject: [PATCH 2412/6505] Update docker-v3.sh --- ct/docker-v3.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index a51ab9d7..dc04fe73 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -76,6 +76,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" @@ -195,7 +197,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG - if [ -z $BRG ]; then NET="vmbr0"; fi; + if [ -z $BRG ]; then BRG="vmbr0"; fi; echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 From 016e25a3854b5fe95d34439f195e6f32e69b67b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:02:06 -0400 Subject: [PATCH 2413/6505] Update docker-v3.sh --- ct/docker-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index dc04fe73..8bfc27dc 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -77,7 +77,7 @@ function default_settings() { echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 81a9d15199ce7332b2362cfe83ddc15cae2d4b7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:11:34 -0400 Subject: [PATCH 2414/6505] Update docker-v3.sh --- ct/docker-v3.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 8bfc27dc..4e1eeb5b 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -59,12 +59,12 @@ function PVE_CHECK() { } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" CT_ID=$NEXTID From 37e8183316502d35b07c14609201067ff30906a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:14:45 -0400 Subject: [PATCH 2415/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index a461d709..7361dbd2 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -196,10 +196,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -212,6 +212,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -234,6 +252,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -256,6 +275,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -295,7 +315,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From b78086cf9cf8d2bc158220648f0f9e8812be802a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:16:29 -0400 Subject: [PATCH 2416/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index c1b763ca..40056cec 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -196,10 +196,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -212,6 +212,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -234,6 +252,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -256,6 +275,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -295,7 +315,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From cd49330b4e136d7eb7b0b8ddb671eafaf8e17c66 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:18:12 -0400 Subject: [PATCH 2417/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index 9d86c691..ed96e379 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -196,10 +196,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -212,6 +212,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -234,6 +252,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -256,6 +275,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -295,7 +315,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From acb8833f494c0aa158334e670e72c152c9849bda Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:19:27 -0400 Subject: [PATCH 2418/6505] Update debian-v3.sh --- ct/debian-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 023939fc..91bf5c21 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From b6ef987043b44afb86a4d205ebbc32d5c467b999 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:20:46 -0400 Subject: [PATCH 2419/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 2c451cda..2873de28 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -195,10 +195,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -211,6 +211,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -233,6 +251,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -255,9 +274,11 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + read -p "Are these settings correct(y/n)? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]] @@ -293,7 +314,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From a887af1caeebcee2a3dfdb70d96b97944412a905 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:21:49 -0400 Subject: [PATCH 2420/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index 71b7f3cd..0ed4f77d 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From c2a1ebfdcb088172ae130ce8db72b10c37b334ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:22:52 -0400 Subject: [PATCH 2421/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index 15929ea2..d0ec35a9 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -195,10 +195,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -211,6 +211,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -233,6 +251,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -255,6 +274,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -294,7 +314,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 05ad6c61df3d85a578e42e03f9f49b9b0a8e33a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:24:28 -0400 Subject: [PATCH 2422/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index b7d52358..d724e892 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -193,10 +193,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -209,6 +209,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -231,6 +249,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -253,6 +272,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 07e82201bd450225cce19418d779e780b6ecb8a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:25:34 -0400 Subject: [PATCH 2423/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 7238548f..10bfdb1e 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From dbf9ed68c0519df93ef339cb3a50076986a54e1e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:27:06 -0400 Subject: [PATCH 2424/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index dc75e8ce..e452b32f 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -195,10 +195,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -211,6 +211,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -233,6 +251,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -255,6 +274,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -294,7 +314,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 036c1c4811d6d96e475b9374b6c0d816b9a30b65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:28:05 -0400 Subject: [PATCH 2425/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index b41da184..60954cb9 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From d675e7957372a29dce77f0b973911062d9d89f91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:29:15 -0400 Subject: [PATCH 2426/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 0893d1c2..134e5fc7 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -196,10 +196,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -212,6 +212,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -234,6 +252,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -256,6 +275,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -296,7 +316,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From ab97682cf404979e69d851d4f67f4c29617f52ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:30:18 -0400 Subject: [PATCH 2427/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 1b40846c..44069f94 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From f8f857ee4bf0a65700f0bdfc73be4e2f6b5f54d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:31:19 -0400 Subject: [PATCH 2428/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index bb5f8441..33c58953 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From be6c674f91a1435eac93ed9ce965d44f5ab2c3b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:32:14 -0400 Subject: [PATCH 2429/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index dd93d417..e07f66d6 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From a319db4377998013df469c9e315d44141aaa2297 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:33:10 -0400 Subject: [PATCH 2430/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index f1ed01df..0491a021 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From fbdbcb16ddcd9ddc6efc3b2bc82825df47300919 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:34:04 -0400 Subject: [PATCH 2431/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 49dd42c3..ff0d0cfd 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From f82a7e10e6be2f6f0b4c65a53c74b00d11b04eaf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:35:03 -0400 Subject: [PATCH 2432/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index ccb8735c..40f93942 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 294b3eb6ed778f0ef27e5c12b08e649d5d21a937 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:35:58 -0400 Subject: [PATCH 2433/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index 601b8237..ffe6ff74 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 4a78e27e38997621f050925dc3261759cd44886f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:36:56 -0400 Subject: [PATCH 2434/6505] Update omada-v3.sh --- ct/omada-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index b308f58d..a52c5758 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 12b99e0971404a175467dfcb1bb160f45aac610b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:37:49 -0400 Subject: [PATCH 2435/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 2688a16a..d6229ab1 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 78d0aa710f80397b36f293bb5c46567b9b348aeb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:38:38 -0400 Subject: [PATCH 2436/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index f0d7029a..08fb56aa 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 2f9ec0b1275a3b73208e23d7baec98d74b54aaa6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:39:35 -0400 Subject: [PATCH 2437/6505] Update plex-v3.sh --- ct/plex-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 27307445..d3aa085c 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -294,7 +314,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 0d2871315f3e59273a00c06c6e872156025d94bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:41:01 -0400 Subject: [PATCH 2438/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 2d23e779..a2f3ca54 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -199,10 +199,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -215,6 +215,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -237,6 +255,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -259,6 +278,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -298,7 +318,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 41a3597c5cb0a278e628c8e053e9378fd6236db3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:42:04 -0400 Subject: [PATCH 2439/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index c679db72..1a2ef35c 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 728d8de05b9f060dd74f1ba03ff126958dd62f60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:43:12 -0400 Subject: [PATCH 2440/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 21be5cc9..281952ef 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -208,7 +208,6 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -216,6 +215,23 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -224,8 +240,7 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -233,6 +248,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -248,7 +264,6 @@ clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -256,6 +271,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -271,7 +287,6 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -279,6 +294,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -318,7 +334,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 42c10657dee99d50341e573bc51d35651801b07d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:44:08 -0400 Subject: [PATCH 2441/6505] Update unifi-v3.sh --- ct/unifi-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index 18c9c419..1b60014f 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From a3dd3607d7586e9c6b16414e88e5b03d444427d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:45:01 -0400 Subject: [PATCH 2442/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index cf070784..a9e1059f 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -196,10 +196,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -212,6 +212,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -234,6 +252,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -256,6 +275,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -295,7 +315,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From a010e15c792fd24dcf26e5402a2ea882de88121e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:45:56 -0400 Subject: [PATCH 2443/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index 01c5df98..f765e3de 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -194,10 +194,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -210,6 +210,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -232,6 +250,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -254,6 +273,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -293,7 +313,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 58459614f4558daf3e8ef1843e42eb4538ed1e18 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:46:51 -0400 Subject: [PATCH 2444/6505] Update wireguard-v3.sh --- ct/wireguard-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index 5e0b0108..c6d54ef6 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -195,10 +195,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -211,6 +211,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -233,6 +251,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -255,6 +274,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -294,7 +314,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 6e026e205642d0313dea25c0b02622411769c466 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:47:41 -0400 Subject: [PATCH 2445/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 796b7124..e1a45f8b 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -196,10 +196,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -212,6 +212,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -234,6 +252,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -256,9 +275,11 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + read -p "Are these settings correct(y/n)? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]] @@ -295,7 +316,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 459a326cc4e789d47b0ed2dc89f3421fba7bc1a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:48:45 -0400 Subject: [PATCH 2446/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 8b70fb41..6c59c9f0 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -195,10 +195,10 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -211,6 +211,24 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -233,6 +251,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " @@ -255,6 +274,7 @@ header_info echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" @@ -295,7 +315,7 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 82fc616ada8339d4f394c6d0215cf16324a2f36d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:50:36 -0400 Subject: [PATCH 2447/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index 7361dbd2..d58a83ae 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -79,6 +79,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From f1d3a46c6bbc66eae3a779a51f560991c7c76906 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:51:11 -0400 Subject: [PATCH 2448/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index 40056cec..34c8fa65 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -79,6 +79,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From b82b2a1389d79cf81de1ed06383b714e27fa099a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:51:59 -0400 Subject: [PATCH 2449/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index ed96e379..fafdad24 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -79,6 +79,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From fd3c358075589aec0e738e33035ba02e9da0c8d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:52:30 -0400 Subject: [PATCH 2450/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 91bf5c21..3a101fc7 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 0da2001844cb7178ba97a6dee67f6e5288dbc9b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:53:00 -0400 Subject: [PATCH 2451/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 2873de28..99161f91 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -78,6 +78,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From e849cafb1782d9d937d4e87476466c9625f68a65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:53:27 -0400 Subject: [PATCH 2452/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index 0ed4f77d..df348a3a 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From e2109eb722e2ea6aca1bac3da03558e68bfb109a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:53:52 -0400 Subject: [PATCH 2453/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index d0ec35a9..088b1169 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -78,6 +78,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 303cce9cbe6fd391b0b7f43fe4c79e6f2e2def8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:54:16 -0400 Subject: [PATCH 2454/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index d724e892..0d3b4544 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -76,6 +76,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 5234e3322ab9b7373c648592a107891063b198e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:54:45 -0400 Subject: [PATCH 2455/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 10bfdb1e..5adbcb6a 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 5666d2c9a6ea542a326438776c9df92256653b58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:56:08 -0400 Subject: [PATCH 2456/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index e452b32f..fe541641 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -76,8 +76,10 @@ function default_settings() { DISK_SIZE="8" echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 82af595d5eeac756161edbae5ff3fb5a075cce37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:56:50 -0400 Subject: [PATCH 2457/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 60954cb9..9fdb5474 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 1a28645e4a40d105f9782cf4886630a5d6c1b55a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:57:18 -0400 Subject: [PATCH 2458/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 134e5fc7..fb38c532 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -79,6 +79,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 4cde2c138171149ed4f7e023148e4eff380c0542 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:57:45 -0400 Subject: [PATCH 2459/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 44069f94..a75feda8 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From e1aa2cce8086212318eaacb58991b0f856bdc609 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:58:17 -0400 Subject: [PATCH 2460/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index 33c58953..e16e4e68 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 8d2c29659082dc473d6474bb65c485c082e8465c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:58:50 -0400 Subject: [PATCH 2461/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index e07f66d6..5bcd0eed 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 22cb74a1ae457aa4e709a60d0101acf31ea514d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:59:14 -0400 Subject: [PATCH 2462/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index 0491a021..9e3596cf 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From c31ebf7a0a4b9a9b76ca9ed2ad3e5a778750ec36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 15:59:42 -0400 Subject: [PATCH 2463/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index ff0d0cfd..34e6ebc0 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 3cac626b5885c10abe6c1a72db22d37adb439c94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:00:10 -0400 Subject: [PATCH 2464/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index 40f93942..e0235ad0 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 4d0c9fbcd9526dc55fedc685e5ad611330d72341 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:00:42 -0400 Subject: [PATCH 2465/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index ffe6ff74..53165a58 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From e61676c9584aae228ee06e8b70aa879c5caa7eac Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:01:13 -0400 Subject: [PATCH 2466/6505] Update omada-v3.sh --- ct/omada-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index a52c5758..cf633463 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 9dd9e6547bcdcb915b470df215170dfd2515a821 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:01:41 -0400 Subject: [PATCH 2467/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index d6229ab1..dbc0a2fa 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 3557a3cbf3bc9f394eb06302f7890ebe9c53d72b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:02:08 -0400 Subject: [PATCH 2468/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 08fb56aa..369ea1f7 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 531fa8643b3ccc8adce0178d500f1cbf8849ac28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:02:36 -0400 Subject: [PATCH 2469/6505] Update plex-v3.sh --- ct/plex-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index d3aa085c..73546aa2 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From be82639ac69957ac76d31175c377868a240d52b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:02:58 -0400 Subject: [PATCH 2470/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index a2f3ca54..63f18a70 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -82,6 +82,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 3679fb1df8ac3f6866e98de9a5671a2406e1fbd7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:04:57 -0400 Subject: [PATCH 2471/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 1a2ef35c..30049b4d 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 084c5fb77b8d8f383642b08c158229cf1ee896ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:05:34 -0400 Subject: [PATCH 2472/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 281952ef..f3196c9d 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -79,6 +79,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From cc887143872c120ed87545d6f0cefd23aaef6e6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:06:44 -0400 Subject: [PATCH 2473/6505] Update unifi-v3.sh --- ct/unifi-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index 1b60014f..30afaa14 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 4e8f444248edb7621a601a743ee23de1ace6bada Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:07:20 -0400 Subject: [PATCH 2474/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index a9e1059f..0db9f544 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -79,6 +79,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 6024b869715db5fa64e152f7b969967a70d21c6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:07:45 -0400 Subject: [PATCH 2475/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index f765e3de..bf1350a3 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -77,6 +77,8 @@ function default_settings() { CORE_COUNT="4" echo -e "${DGN}Using ${BGN}4096MiB${CL}${DGN} RAM${CL}" RAM_SIZE="4096" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From b226e4d262be4c355b560d7cc25b045e10ba3aac Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:08:10 -0400 Subject: [PATCH 2476/6505] Update wireguard-v3.sh --- ct/wireguard-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index c6d54ef6..32260de4 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -78,6 +78,8 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From 45ba48dcb64249bd3fdb6d7fc112348d57e6a7ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:08:49 -0400 Subject: [PATCH 2477/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index e1a45f8b..4f94055f 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -79,6 +79,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From d929af4f88cedfb02d888ace6ef3227b268e235a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:09:35 -0400 Subject: [PATCH 2478/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 6c59c9f0..73fe7b0c 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -78,6 +78,8 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" From a94e5e6421e5d0989f357c325b5357dda4a2f58c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:10:01 -0400 Subject: [PATCH 2479/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index d58a83ae..9e66cf32 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -79,7 +79,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 2f37abb18908270364995e8b6a2116557a7ea0e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:10:34 -0400 Subject: [PATCH 2480/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index 34c8fa65..a7ea2e2e 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -79,7 +79,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 1aeb5861caedc9a992d30a059dd2f58545b0bc63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:11:02 -0400 Subject: [PATCH 2481/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index fafdad24..df810071 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -79,7 +79,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 817271019a101d625a303e30d5611d09d6f0ba6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:11:29 -0400 Subject: [PATCH 2482/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 3a101fc7..6c31c4b7 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 8bbd3ad6afedd18e2d42fbfd4c7ef50eaf334d5c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:12:05 -0400 Subject: [PATCH 2483/6505] Update docker-v3.sh --- ct/docker-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 4e1eeb5b..06bd7a28 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -76,7 +76,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From a921f1e8f5c2de415de50314595e2790dc10abb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:12:36 -0400 Subject: [PATCH 2484/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 99161f91..c678f8e0 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -78,7 +78,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 46a9a2fcb2b9081d7bf27031060d908e55beca02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:13:03 -0400 Subject: [PATCH 2485/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index df348a3a..8db92e66 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From eb9c307aa3577a1a74348bd9a0866fe94d9209fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:13:31 -0400 Subject: [PATCH 2486/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index 088b1169..67180050 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -78,7 +78,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From e4c535cb49dafdb73fd3194346518610d9b266bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:14:06 -0400 Subject: [PATCH 2487/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 0d3b4544..c9b14131 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -76,7 +76,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 1d623b914cb03c2b6565b49753e297c2d7ee512e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:14:43 -0400 Subject: [PATCH 2488/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 5adbcb6a..6af26e1c 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 8cb6ab5f81a9590342eff78d74c56461b91ffe81 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:15:21 -0400 Subject: [PATCH 2489/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index fe541641..8be00411 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -78,7 +78,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 669c49c59a7a03c1a3c57486dc9de38b143740b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:15:54 -0400 Subject: [PATCH 2490/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 9fdb5474..6e90130a 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From ef81d5e16bf20b215aec44a6d090c6163d692360 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:16:20 -0400 Subject: [PATCH 2491/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index fb38c532..b28a9145 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -79,7 +79,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From bef00e7fc03115da544ee89b080b9e87c2cfc15e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:16:49 -0400 Subject: [PATCH 2492/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index a75feda8..2bd18595 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From e5af50372ddc2e21124bdc4ca01ec5eb57a45a55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:17:14 -0400 Subject: [PATCH 2493/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index e16e4e68..4625af09 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 223b4720b37747d502fdd1e36ec54891febc33a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:17:46 -0400 Subject: [PATCH 2494/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index 5bcd0eed..03db1088 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 1492598459a7019de36d285fae79df97a984bdad Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:18:17 -0400 Subject: [PATCH 2495/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index 9e3596cf..11112e9c 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 4636c03ec4c7c7d96bb6b8b981a0a1a67c056bb0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:18:50 -0400 Subject: [PATCH 2496/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 34e6ebc0..018a6a9a 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From a66cbeffd8720a3603b3280240fb874f67847725 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:19:13 -0400 Subject: [PATCH 2497/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index e0235ad0..e0681b52 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 2c541574cdaf1bba5f3214a75b66c6c449170579 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:19:41 -0400 Subject: [PATCH 2498/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index 53165a58..dd9145f0 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 496582ef73f2f4457ce3d1d1509f3fd4092607cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:20:12 -0400 Subject: [PATCH 2499/6505] Update omada-v3.sh --- ct/omada-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index cf633463..c2f53b8f 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From e99507af176638682aa14b303539486465e2471a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:20:38 -0400 Subject: [PATCH 2500/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index dbc0a2fa..4f07a6e0 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From e109f2a2bd9f238c19836de6216de97032b72f68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:21:11 -0400 Subject: [PATCH 2501/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 369ea1f7..d50a0ebf 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 53f6037ba8744b6c1bf2c2a753cbaec04bb34eb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:21:49 -0400 Subject: [PATCH 2502/6505] Update plex-v3.sh --- ct/plex-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 73546aa2..3b24632c 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -77,7 +77,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 36239ec311429669f00add116b167f0b26940521 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:22:25 -0400 Subject: [PATCH 2503/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 63f18a70..48f024f5 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -82,7 +82,7 @@ function default_settings() { CORE_COUNT="2" echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" NET=dhcp From 89243d9fc1b86cab4962262592b4856c4b97104d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Apr 2022 16:36:07 -0400 Subject: [PATCH 2504/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 05f7c90c..87c8e7f7 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - **Ubuntu LXC** - ADD option to install version 20.04 or 21.10 +- **v3 Script** + - ADD option to set Bridge ## 2022-04-19 From 1cc8577ea8bea81a9c8c33cf52e670b5a6a9b045 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 03:40:54 -0400 Subject: [PATCH 2505/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 936c1663..fc21c4bb 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -54,7 +54,7 @@ msg_info "Setting up Node.js Repository" sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null msg_ok "Set up Node.js Repository" -msg_lnfo "Installing Node.js" +msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" From e0dd8b280216a5e14fc08ea51609cc38d1961b73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:04:42 -0400 Subject: [PATCH 2506/6505] Update debian-v3.sh --- ct/debian-v3.sh | 90 ++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 6c31c4b7..8de9dca6 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From bdb728927c0b20e499be944254ce7a9beebc2c97 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:06:20 -0400 Subject: [PATCH 2507/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 86 ++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index 9e66cf32..251e56af 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -67,24 +67,24 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN="" } @@ -152,11 +152,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -166,11 +166,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -180,12 +180,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -195,9 +195,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -211,10 +211,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -223,15 +223,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -251,9 +251,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -274,9 +274,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 456735b300c6c2b93c43359cb2bee181ca83500b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:08:38 -0400 Subject: [PATCH 2508/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 90 ++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index a7ea2e2e..ca457749 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -67,26 +67,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -152,11 +152,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -166,11 +166,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -180,12 +180,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -195,9 +195,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -211,10 +211,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -223,15 +223,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -251,9 +251,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -274,9 +274,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 106a337f69f2e7b01aaa630ea68bb773d2edd680 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:11:52 -0400 Subject: [PATCH 2509/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 90 +++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index df810071..bca7028f 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -67,26 +67,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}3GB${CL}" - DISK_SIZE="3" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}3${CL}${DGN}GB${CL}" + DISK_SIZE="3" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -152,11 +152,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -166,11 +166,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -180,12 +180,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -195,9 +195,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -211,10 +211,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -223,15 +223,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -251,9 +251,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -274,9 +274,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From e373b8248c9a1c49d88daae5a92edcbeb4013d59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:15:19 -0400 Subject: [PATCH 2510/6505] Update docker-v3.sh --- ct/docker-v3.sh | 100 ++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 06bd7a28..42160fbc 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -59,31 +59,31 @@ function PVE_CHECK() { } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -149,11 +149,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -163,11 +163,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -177,12 +177,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -192,9 +192,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -208,10 +208,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -220,15 +220,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -248,9 +248,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -271,9 +271,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From c6ff814e6776ea395510316b76c5715138050ca9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:18:32 -0400 Subject: [PATCH 2511/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 90 ++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index c678f8e0..113dfb8d 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -66,26 +66,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -151,11 +151,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -165,11 +165,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -179,12 +179,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -194,9 +194,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -210,10 +210,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -222,15 +222,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -250,9 +250,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -273,9 +273,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 11171f80d3b5bd6df23bf81588198f4a15d6cbec Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:19:45 -0400 Subject: [PATCH 2512/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 90 ++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index 8db92e66..451a07bb 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From e69f8fd67044007070413cd88874c695a64dd7cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:21:15 -0400 Subject: [PATCH 2513/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 90 +++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index 67180050..7439f163 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -66,26 +66,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -151,11 +151,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -165,11 +165,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -179,12 +179,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -194,9 +194,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -210,10 +210,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -222,15 +222,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -250,9 +250,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -273,9 +273,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 09c08b3deb2e8fe255f1eed85d91e9f49b9cbc0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:23:53 -0400 Subject: [PATCH 2514/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 90 +++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index c9b14131..e77b131e 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -64,26 +64,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}16GB${CL}" - DISK_SIZE="16" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}16${CL}${DGN}GB${CL}" + DISK_SIZE="16" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -149,11 +149,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="16"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -163,11 +163,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -177,12 +177,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -192,9 +192,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -208,10 +208,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -220,15 +220,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -248,9 +248,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -271,9 +271,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 916d4f3eed098fcbfc5d30f1f346087d6a825c73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:26:08 -0400 Subject: [PATCH 2515/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 90 ++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 6af26e1c..67a671be 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 279aedb7a832d6ab2ab271aee009023d7e2d0406 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:28:58 -0400 Subject: [PATCH 2516/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 90 +++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index 8be00411..61641441 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -66,26 +66,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -151,11 +151,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -165,11 +165,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -179,12 +179,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -194,9 +194,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -210,10 +210,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -222,15 +222,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -250,9 +250,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -273,9 +273,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From d1ca4dd2dd94bd3e32b531dba9e86e837ce7bc26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:31:48 -0400 Subject: [PATCH 2517/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 90 +++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 6e90130a..d19fb1ea 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 2b64f8ba443d1c8c25134ffb44d5620acde9d05d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:34:10 -0400 Subject: [PATCH 2518/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 104 +++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index b28a9145..d8968d70 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -65,42 +65,42 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 @@ -152,11 +152,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -166,11 +166,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -180,12 +180,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -195,9 +195,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -211,10 +211,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -223,15 +223,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -251,9 +251,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -274,9 +274,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 517aacfb91ecb17a299fdde175de5fa2756b1d59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:39:46 -0400 Subject: [PATCH 2519/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 90 ++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 2bd18595..3bfa751e 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From ca3092295ea26819a2032fd64a4c14e26d0f9ed7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:41:08 -0400 Subject: [PATCH 2520/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index 4625af09..e813645b 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 5871669e78b81099eac2a522979378533e2d8d63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:43:41 -0400 Subject: [PATCH 2521/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 90 +++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index 03db1088..fa2430d7 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 462ca06284d261b81e482b474baa80e98a665230 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:44:35 -0400 Subject: [PATCH 2522/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 90 +++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index 11112e9c..deeed5c8 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 31c49b095bbee3da805b2cc7d388d69f3096b0d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:46:55 -0400 Subject: [PATCH 2523/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 90 ++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 018a6a9a..97ba9d2a 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}3GB${CL}" - DISK_SIZE="3" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}3${CL}${DGN}GB${CL}" + DISK_SIZE="3" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From f1330bb666fa2018f2e320e15d409b8bbca758cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:48:58 -0400 Subject: [PATCH 2524/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 90 ++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index e0681b52..56d4c1e0 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From c4e6269e365362ffe9dc807aa30aa2ef6d7c6299 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:51:19 -0400 Subject: [PATCH 2525/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 90 +++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index dd9145f0..38868600 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 17724e072c3cb904a13107a980fc1fe33225a71a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:53:30 -0400 Subject: [PATCH 2526/6505] Update omada-v3.sh --- ct/omada-v3.sh | 90 +++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index c2f53b8f..dfe64bce 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From c57093faa4385dd310246378fb89e7cbb6d5b9ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:56:00 -0400 Subject: [PATCH 2527/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 90 ++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 4f07a6e0..5549ca57 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From bf92c72f55e8f4367047a627d020a3cced52b1ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 09:56:56 -0400 Subject: [PATCH 2528/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 90 ++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index d50a0ebf..7de4ca44 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From e415568c02881471df0bab6721acb849cbf7b0ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:00:05 -0400 Subject: [PATCH 2529/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 104 +++++++++++++++++----------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 48f024f5..ba2482c2 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -68,42 +68,42 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}16GB${CL}" - DISK_SIZE="16" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}16${CL}${DGN}GB${CL}" + DISK_SIZE="16" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 @@ -155,11 +155,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="16"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -169,11 +169,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -183,12 +183,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -198,9 +198,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -214,10 +214,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -226,15 +226,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -254,9 +254,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -277,9 +277,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 16e582dfac1d4a78380f3dfe51dbea7f8dfbaeb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:01:01 -0400 Subject: [PATCH 2530/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 90 +++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 30049b4d..f22f3103 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From f39dc40352f7b4a68a3cf28409c58666d8582ba9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:03:37 -0400 Subject: [PATCH 2531/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index f3196c9d..c32dd0c0 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -210,6 +210,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -226,6 +227,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -243,6 +245,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -266,6 +269,7 @@ clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" @@ -289,6 +293,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$VER${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" From 336b977e8f677a150ac519a52daef03f2ee08fb6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:12:11 -0400 Subject: [PATCH 2532/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index c32dd0c0..2d7cc48a 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -73,11 +73,11 @@ function default_settings() { CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" RAM_SIZE="512" echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" @@ -169,11 +169,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -184,11 +184,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -199,8 +199,8 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; @@ -215,9 +215,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -232,9 +232,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET @@ -250,9 +250,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " @@ -274,9 +274,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -298,9 +298,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 3c3a0bd3731399452954576ff6b64c7811686b0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:14:50 -0400 Subject: [PATCH 2533/6505] Update unifi-v3.sh --- ct/unifi-v3.sh | 90 +++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index 30afaa14..d5d2735a 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From acfbbd62f7827e018854f0aede72d6399d40a36b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:16:06 -0400 Subject: [PATCH 2534/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 90 ++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index 0db9f544..de54b7fc 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -67,26 +67,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -152,11 +152,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -166,11 +166,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -180,12 +180,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -195,9 +195,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -211,10 +211,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -223,15 +223,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -251,9 +251,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -274,9 +274,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From d51855834b01fc0fa4af2b3e473f44a94d18b2bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:19:01 -0400 Subject: [PATCH 2535/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index bf1350a3..7745aff4 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}4vCPU${CL}" - CORE_COUNT="4" - echo -e "${DGN}Using ${BGN}4096MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}4${CL}${DGN}vCPU${CL}" + CORE_COUNT="4" + echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,11 +164,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 4 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="4"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -178,12 +178,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,10 +209,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -221,15 +221,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From f19ab07d4cf68a4229f59f68d7be3d7cd66e08d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:20:01 -0400 Subject: [PATCH 2536/6505] Update wireguard-v3.sh --- ct/wireguard-v3.sh | 90 +++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index 32260de4..b1c0afd1 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -66,26 +66,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" + DISK_SIZE="2" + echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" + CORE_COUNT="1" + echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="512" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -151,11 +151,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -165,11 +165,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -179,12 +179,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -194,9 +194,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -210,10 +210,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -222,15 +222,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -250,9 +250,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -273,9 +273,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 9534476f63e746823c65885690068bf329db0f0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:22:54 -0400 Subject: [PATCH 2537/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 100 +++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 4f94055f..def5b900 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -65,26 +65,26 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN="" } @@ -93,14 +93,14 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 @@ -152,11 +152,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -166,11 +166,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -180,12 +180,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -195,9 +195,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -211,10 +211,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -223,15 +223,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -251,9 +251,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -274,9 +274,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From a7df78145300cfc66abc3a9b4fc59bcc1122cb6d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:25:10 -0400 Subject: [PATCH 2538/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 100 +++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 73fe7b0c..e416861c 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -64,26 +64,26 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN="" } @@ -92,14 +92,14 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 @@ -151,11 +151,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -165,11 +165,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -179,12 +179,12 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 clear @@ -194,9 +194,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -210,10 +210,10 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; @@ -222,15 +222,15 @@ echo -e " ${CM}${CL} \n" sleep 1 clear header_info - echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " read GATE1 @@ -250,9 +250,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -273,9 +273,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 541c525144b5778ff218716400114665dec15336 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:58:39 -0400 Subject: [PATCH 2539/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index def5b900..e25b53e2 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -65,8 +65,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" @@ -93,9 +93,9 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Privileged" From 87eee5a8f72ca53f4aeac6fb4ebd58b0c86c2634 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 10:59:40 -0400 Subject: [PATCH 2540/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index e416861c..20d2c6aa 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -64,8 +64,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" @@ -92,9 +92,9 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Privileged" From 19a573a847c8fa4522f80b938abe5b0f7a5f6e21 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 11:01:44 -0400 Subject: [PATCH 2541/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index ba2482c2..438ee715 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -68,8 +68,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" @@ -96,14 +96,14 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}UnPrivileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 From f840437f79d8410e746c7632fc766bee475f7d9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 11:03:12 -0400 Subject: [PATCH 2542/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index e25b53e2..7238351c 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -95,7 +95,7 @@ function advanced_settings() { echo -e "${RD}Using Advanced Settings${CL}" echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Privileged" From c1ab74861f422e51bdba978add466cdb6222bd16 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 11:04:06 -0400 Subject: [PATCH 2543/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 20d2c6aa..87ce858c 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -94,7 +94,7 @@ function advanced_settings() { echo -e "${RD}Using Advanced Settings${CL}" echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Privileged" From 11a54d0d67ddc6f5723abe44b865c4565b47baec Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 11:10:48 -0400 Subject: [PATCH 2544/6505] Update plex-v3.sh --- ct/plex-v3.sh | 80 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 3b24632c..d6695976 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -65,26 +65,26 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048MiB${CL}${DGN} RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" } function advanced_settings() { @@ -150,11 +150,11 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8Gb " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " read DISK_SIZE if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}" + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear @@ -164,7 +164,7 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; @@ -178,8 +178,8 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; @@ -193,9 +193,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " read BRG if [ -z $BRG ]; then BRG="vmbr0"; fi; @@ -209,9 +209,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " read NET @@ -226,9 +226,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " @@ -249,9 +249,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" @@ -272,9 +272,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}${DGN} RAM${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" From 23118362423745a42eccca02d0ac99c1a5777eaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 11:11:39 -0400 Subject: [PATCH 2545/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 7238351c..f5f66112 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -93,7 +93,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From 87c71d59482f8b7e55bee51b2df4172aaaaf1d36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 11:12:31 -0400 Subject: [PATCH 2546/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 87ce858c..f9c495d8 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -92,7 +92,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From 428e3534843b0b99e957184a5bfd838381bbf240 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 11:13:16 -0400 Subject: [PATCH 2547/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 438ee715..68073d26 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -96,7 +96,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}Unprivileged, or Press [ENTER] for Default: Privileged" + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From a8ad439499e8e2331ab549dd107b086d6e9b3653 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 12:23:59 -0400 Subject: [PATCH 2548/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 68073d26..4546bd2d 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -98,7 +98,7 @@ function advanced_settings() { echo -e "${RD}Using Advanced Settings${CL}" echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="0"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Unprivileged" From da001eb17f80d0f90e6d1c621fc831080a44a2f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 12:36:16 -0400 Subject: [PATCH 2549/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 4546bd2d..90a688e7 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -13,6 +13,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" APP="P-Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do From 38bc13e429294b76f3064713cc64df65a059f4d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 15:51:39 -0400 Subject: [PATCH 2550/6505] Update omada-install.sh --- setup/omada-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index c03a47ff..c98a12bd 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -59,8 +59,8 @@ apt-get -y install mongodb-org &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller" -wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.1.7_linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 5ed2e906a269c699ce7d4984703498ab555f6d6c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 17:04:32 -0400 Subject: [PATCH 2551/6505] Update omada-install.sh --- setup/omada-install.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index c98a12bd..a8c10d5a 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -59,8 +59,10 @@ apt-get -y install mongodb-org &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller" -wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.1.7_linux_x64.deb &>/dev/null +#wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb +#sudo dpkg -i Omada_SDN_Controller_v5.1.7_linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 89f7669c37c13f51ee6f3fe5bbfc10b4423aff44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 19:05:16 -0400 Subject: [PATCH 2552/6505] Update omada-install.sh --- setup/omada-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index a8c10d5a..d173cfc3 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -59,10 +59,10 @@ apt-get -y install mongodb-org &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller" -#wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb -#sudo dpkg -i Omada_SDN_Controller_v5.1.7_linux_x64.deb &>/dev/null -wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.1.7_Linux_x64.deb &>/dev/null +#wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb +#sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 3ad7884dbe39846a53e78e1497b30a1df85bdc82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Apr 2022 19:18:19 -0400 Subject: [PATCH 2553/6505] Update omada-install.sh --- setup/omada-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index d173cfc3..b381d463 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -59,10 +59,10 @@ apt-get -y install mongodb-org &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller" -wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.1.7_Linux_x64.deb &>/dev/null -#wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb -#sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null +#wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb +#sudo dpkg -i Omada_SDN_Controller_v5.1.7_Linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 5f9485d9339c51e28f410dca03f272e5877a1e4b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 07:03:18 -0400 Subject: [PATCH 2554/6505] Update omada-v3.sh --- ct/omada-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index dfe64bce..b0d264aa 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -310,7 +310,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$CT_ID export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=20.04 +export PCT_OSVERSION=18.04 export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES From 34e7d4db06fedae4ce3f7e800bfa582d6348ef97 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 07:04:16 -0400 Subject: [PATCH 2555/6505] Update omada-install.sh --- setup/omada-install.sh | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index b381d463..f8642836 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -40,7 +40,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Updating Container OS" +msg_info "Updating Container OS (216 packages)" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg_ok "Updated Container OS" @@ -51,18 +51,13 @@ apt-get -y install sudo &>/dev/null apt-get -y install gnupg &>/dev/null apt-get -y install openjdk-8-jre-headless &>/dev/null apt-get -y install jsvc &>/dev/null - -wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add &>/dev/null -echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list &>/dev/null -apt-get update &>/dev/null -apt-get -y install mongodb-org &>/dev/null +wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb +sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller" -#wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb -#sudo dpkg -i Omada_SDN_Controller_v5.1.7_Linux_x64.deb &>/dev/null -wget -qL https://static.tp-link.com/upload/software/2022/202201/20220120/Omada_SDN_Controller_v5.0.30_linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.0.30_linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.1.7_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 7648e55f96e1f233d9cbe701142f649653388517 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 07:33:42 -0400 Subject: [PATCH 2556/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0596f7ec..c0be7787 100644 --- a/README.md +++ b/README.md @@ -975,7 +975,7 @@ ________________________________________________________________________________
    - Omada Controller LXC + 🔸Omada Controller LXC

    From 9f58284c4b70fa5a991d2ac55abb4c390bf1e702 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 07:35:29 -0400 Subject: [PATCH 2557/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 87c8e7f7..2199c60d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,13 @@ All notable changes to this project will be documented in this file. ### Changed +- **Omada Controller LXC** + - Update script to install version 5.1.7 + +## 2022-04-20 + +### Changed + - **Ubuntu LXC** - ADD option to install version 20.04 or 21.10 - **v3 Script** From 293869c8f5848b9f18c8bed96f08cdd8215d511e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 07:36:06 -0400 Subject: [PATCH 2558/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2199c60d..086d3568 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) -## 2022-04-20 +## 2022-04-22 ### Changed From 3c7cf891e4ec3d4e9c1f1b33976a5b366bcde7e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 14:58:18 -0400 Subject: [PATCH 2559/6505] Update debian-v3.sh --- ct/debian-v3.sh | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 8de9dca6..d6da01c2 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -1,9 +1,16 @@ #!/usr/bin/env bash -ex set -euo pipefail shopt -s inherit_errexit nullglob - +APP="Debian" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -14,8 +21,6 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -APP="Debian" -NSAPP=$(echo ${APP,,} | tr -d ' ') while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -71,12 +76,12 @@ function default_settings() { CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" @@ -150,9 +155,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" @@ -165,9 +170,9 @@ header_info echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 @@ -180,9 +185,9 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 @@ -305,12 +310,9 @@ if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1" fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES @@ -328,7 +330,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 8ea19e2b15628c1094515ae24e197911ec9e4af6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 14:59:37 -0400 Subject: [PATCH 2560/6505] Update debian-install.sh --- setup/debian-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index bc0fd4d7..dab51639 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -53,8 +53,7 @@ msg_ok "Installed Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname +chmod -x /etc/update-motd.d/* touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) From 9dc635a4b44aba9add4a22f81abcca56669fd855 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 15:01:17 -0400 Subject: [PATCH 2561/6505] Update debian-v3.sh --- ct/debian-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index d6da01c2..462a0942 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -330,7 +330,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 23aa781abc5f8eb606eb871f9a188b5265fb115c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 15:54:50 -0400 Subject: [PATCH 2562/6505] Create uptimekuma-update.sh --- misc/uptimekuma-update.sh | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 misc/uptimekuma-update.sh diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh new file mode 100644 index 00000000..cad0a1bc --- /dev/null +++ b/misc/uptimekuma-update.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Uptime Kuma" +while true; do + read -p "This will Update ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${DGN} + _ _ _ _ _ __ + | | | | | | (_) | |/ / + | | | |_v3_ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ + | | | | _ \| __| | _ _ \ / _ \ | <| | | | _ _ \ / _ | + | |__| | |_) | |_| | | | | | | __/ | . \ |_| | | | | | | (_| | + \____/| .__/ \__|_|_| |_| |_|\___| |_|\_\__,_|_| |_| |_|\__,_| + | | + |_| UPDATE +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +cd /opt/uptime-kuma +if which systemctl 2> /dev/null > /dev/null; then + msg_info "Stopping Uptime Kuma" + sudo systemctl stop uptime-kuma &>/dev/null + msg_ok "Stopped Uptime Kuma" +else + echo "Skipped stopping Uptime Kuma, no systemctl found" +fi + + +msg_info "Updating" +git checkout HEAD -- npm-shrinkwrap.json &>/dev/null +git fetch &>/dev/null +git checkout master &>/dev/null +git pull &>/dev/null +msg_ok "Updated" + +msg_info "Installing Dependencies" +npm ci &>/dev/null +msg_ok "Installed Dependencies" + +if which systemctl 2> /dev/null > /dev/null; then + msg_info "Starting Uptime Kuma" + sudo systemctl start uptime-kuma &>/dev/null + msg_ok "Started Uptime Kuma" +else + echo "Skipped starting Uptime Kuma, no systemctl found" +fi + +msg_ok "Done!" From 9655ed070a1c575efa401c4fde4a7e944f3771ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 15:57:23 -0400 Subject: [PATCH 2563/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index cad0a1bc..568045b2 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -57,7 +57,6 @@ fi msg_info "Updating" -git checkout HEAD -- npm-shrinkwrap.json &>/dev/null git fetch &>/dev/null git checkout master &>/dev/null git pull &>/dev/null From f61f6e7c1c176f196a747ade6d04f4bd7dd30a0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 15:59:42 -0400 Subject: [PATCH 2564/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index 568045b2..35f91888 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -57,13 +57,13 @@ fi msg_info "Updating" -git fetch &>/dev/null -git checkout master &>/dev/null -git pull &>/dev/null +git fetch +git checkout master +git pull msg_ok "Updated" msg_info "Installing Dependencies" -npm ci &>/dev/null +npm ci msg_ok "Installed Dependencies" if which systemctl 2> /dev/null > /dev/null; then From a8b7a6e5adf0351a773062f6545cc8b96e000240 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:04:59 -0400 Subject: [PATCH 2565/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index 35f91888..f9d8ae35 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -1,6 +1,4 @@ #!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -46,15 +44,12 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -cd /opt/uptime-kuma -if which systemctl 2> /dev/null > /dev/null; then - msg_info "Stopping Uptime Kuma" - sudo systemctl stop uptime-kuma &>/dev/null - msg_ok "Stopped Uptime Kuma" -else - echo "Skipped stopping Uptime Kuma, no systemctl found" -fi +msg_info "Stopping Uptime Kuma" +sudo systemctl stop uptime-kuma &>/dev/null +msg_ok "Stopped Uptime Kuma" + +cd /opt/uptime-kuma msg_info "Updating" git fetch @@ -66,12 +61,8 @@ msg_info "Installing Dependencies" npm ci msg_ok "Installed Dependencies" -if which systemctl 2> /dev/null > /dev/null; then - msg_info "Starting Uptime Kuma" - sudo systemctl start uptime-kuma &>/dev/null - msg_ok "Started Uptime Kuma" -else - echo "Skipped starting Uptime Kuma, no systemctl found" -fi +msg_info "Starting Uptime Kuma" +sudo systemctl start uptime-kuma &>/dev/null +msg_ok "Started Uptime Kuma" msg_ok "Done!" From c2f9224ded036e83d607510ba3d362ff0a184f87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:08:16 -0400 Subject: [PATCH 2566/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index f9d8ae35..eb21e064 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -52,13 +52,13 @@ msg_ok "Stopped Uptime Kuma" cd /opt/uptime-kuma msg_info "Updating" -git fetch -git checkout master -git pull +git fetch &>/dev/null +git checkout master &>/dev/null +git pull &>/dev/null msg_ok "Updated" msg_info "Installing Dependencies" -npm ci +npm ci &>/dev/null msg_ok "Installed Dependencies" msg_info "Starting Uptime Kuma" From 1f9a5ee2c98913e9a53ec86b424bdc1d1d9063a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:15:31 -0400 Subject: [PATCH 2567/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index eb21e064..87e55a25 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -51,11 +51,11 @@ msg_ok "Stopped Uptime Kuma" cd /opt/uptime-kuma -msg_info "Updating" +msg_info "Updating Uptime Kuma" git fetch &>/dev/null git checkout master &>/dev/null git pull &>/dev/null -msg_ok "Updated" +msg_ok "Updated Uptime Kuma" msg_info "Installing Dependencies" npm ci &>/dev/null From 2f53542a324cfaec05660b8a064bd31c34c843a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:18:19 -0400 Subject: [PATCH 2568/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index 87e55a25..f0fe745c 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -57,7 +57,7 @@ git checkout master &>/dev/null git pull &>/dev/null msg_ok "Updated Uptime Kuma" -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" npm ci &>/dev/null msg_ok "Installed Dependencies" From ef76c326cd44fb41b89cdaf60861369f15124329 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:24:54 -0400 Subject: [PATCH 2569/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index f0fe745c..2106071d 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -51,15 +51,15 @@ msg_ok "Stopped Uptime Kuma" cd /opt/uptime-kuma -msg_info "Updating Uptime Kuma" +msg_info "Pulling Uptime Kuma" git fetch &>/dev/null git checkout master &>/dev/null git pull &>/dev/null -msg_ok "Updated Uptime Kuma" +msg_ok "Pulled Uptime Kuma" -msg_info "Installing Dependencies (Patience)" +msg_info "Updating Uptime Kuma (Patience)" npm ci &>/dev/null -msg_ok "Installed Dependencies" +msg_ok "Updated Uptime Kuma" msg_info "Starting Uptime Kuma" sudo systemctl start uptime-kuma &>/dev/null From a870cc5c6e8ab73a9fb7f170131dacd7a330d713 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:27:41 -0400 Subject: [PATCH 2570/6505] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c0be7787..7189d5b3 100644 --- a/README.md +++ b/README.md @@ -1183,7 +1183,7 @@ ________________________________________________________________________________
    - Uptime Kuma LXC + 🔸Uptime Kuma LXC

    @@ -1201,11 +1201,12 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v **Uptime Kuma Interface - IP:3001** -⚙️ **To Update** - +⚙️ **To Update Uptime Kuma** +Run in the LXC console ```yaml -Working on +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/uptimekuma-update.sh)" +``` ``` ____________________________________________________________________________________________ From b3dcda7344bede942af3160ec6c80689f5eb3939 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:29:24 -0400 Subject: [PATCH 2571/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 086d3568..e13fa1d1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - **Omada Controller LXC** - Update script to install version 5.1.7 +- **Uptime Kuma LXC** + - ADD Update script ## 2022-04-20 From 930df06f6c61da078b4a788377497b33b8604695 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:30:56 -0400 Subject: [PATCH 2572/6505] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 7189d5b3..a9d04f94 100644 --- a/README.md +++ b/README.md @@ -1207,8 +1207,6 @@ Run in the LXC console ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/uptimekuma-update.sh)" ``` -``` - ____________________________________________________________________________________________
    From 51b2d4f27a91b4b4993ec795022825f1c15ade37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:33:27 -0400 Subject: [PATCH 2573/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9d04f94..e8aef55d 100644 --- a/README.md +++ b/README.md @@ -1144,7 +1144,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdn **Technitium DNS Interface - IP:5380** -⚙️ **To Update** +⚙️ **To Update Technitium DNS** ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/technitiumdns-update.sh)" From 02c4f582f2769a2a3927df022bda2438bd7e32b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Apr 2022 16:52:39 -0400 Subject: [PATCH 2574/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index de54b7fc..9697a04a 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -73,8 +73,8 @@ function default_settings() { CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" + echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" + DISK_SIZE="4" echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" CORE_COUNT="1" echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" @@ -152,9 +152,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; + if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" From 6f04dca41faae1360711e232210ee41b715d2718 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 11:15:56 -0400 Subject: [PATCH 2575/6505] Create post-install-v3.sh --- misc/post-install-v3.sh | 107 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 misc/post-install-v3.sh diff --git a/misc/post-install-v3.sh b/misc/post-install-v3.sh new file mode 100644 index 00000000..880cf3e8 --- /dev/null +++ b/misc/post-install-v3.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +echo -e "\e[1;33m This script will Preform Post Install Routines. PVE7 ONLY \e[0m" +while true; do + read -p "Start the PVE7 Post Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then + echo -e "This script requires Proxmox Virtual Environment 7.0 or greater" + echo -e "Exiting..." + sleep 2 + exit +fi +function header_info { +echo -e "${RD} + _______ ________ ______ _____ _ _____ _ _ _ + | __ \ \ / / ____|____ | | __ \ | | |_ _| | | | | | + | |__) \ \ / /| |__ / / | |__) |__ ___| |_ | | _ __ ___| |_ __ _| | | + | ___/ \ \/ / | __| v3 / / | ___/ _ \/ __| __| | | | _ \/ __| __/ _ | | | + | | \ / | |____ / / | | | (_) \__ \ |_ _| |_| | | \__ \ || (_| | | | + |_| \/ |______|/_/ |_| \___/|___/\__| |_____|_| |_|___/\__\__,_|_|_| +${CL}" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +clear +header_info +read -r -p "Disable Enterprise Repository? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Disabling Enterprise Repository" +sleep 2 +sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list +msg_ok "Disabled Enterprise Repository" +fi + +read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Adding or Correcting PVE7 Sources" +cat < /etc/apt/sources.list +deb http://ftp.debian.org/debian bullseye main contrib +deb http://ftp.debian.org/debian bullseye-updates main contrib +deb http://security.debian.org/debian-security bullseye-security main contrib +EOF +sleep 2 +msg_ok "Added or Corrected PVE7 Sources" +fi + +read -r -p "Enable No-Subscription Repository? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Enabling No-Subscription Repository" +cat <> /etc/apt/sources.list +deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription +EOF +sleep 2 +msg_ok "Enabled No-Subscription Repository" +fi + +read -r -p "Add (Disabled) Beta/Test Repository? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Adding Beta/Test Repository and set disabled" +cat <> /etc/apt/sources.list +# deb http://download.proxmox.com/debian/pve bullseye pvetest +EOF +sleep 2 +msg_ok "Added Beta/Test Repository" +fi + +read -r -p "Disable Subscription Nag? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg-info "Disabling Subscription Nag" +echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script +apt --reinstall install proxmox-widget-toolkit &>/dev/null +msg-ok "Disabled Subscription Nag" +fi +msg_ok "Finished....Please Update Proxmox" + From 7f417065720f18ee2826a631683072c2ce56c4f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 11:17:44 -0400 Subject: [PATCH 2576/6505] Create kernel-clean-v3.sh --- misc/kernel-clean-v3.sh | 114 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 misc/kernel-clean-v3.sh diff --git a/misc/kernel-clean-v3.sh b/misc/kernel-clean-v3.sh new file mode 100644 index 00000000..8b5ccf46 --- /dev/null +++ b/misc/kernel-clean-v3.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +PARTY="🎉" +current_kernel=$(uname -r) +pve=$(pveversion) + +while true; do + read -p "This will Clean Unused Kernel Images. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo -e "${RD}Please answer y/n${CL}";; + esac +done +clear + +function header_info { +echo -e "${RD} + _ __ _ _____ _ + | |/ / | | / ____| | + | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ + | < / _ \ __| _ \ / _ \ | | | | |/ _ \/ _ | _ \ + | \ __/ | | | | | __/ | | |____| | __/ (_| | | | | + |_|\_\___|_| |_| |_|\___|_|v3\_____|_|\___|\__,_|_| |_| + +${CL}" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function check_root() { + if [[ $EUID -ne 0 ]]; then + echo -e "${CROSS}${RD}Error: This script must be ran as the root user.\n${CL}" + exit 1 + else + header_info + kernel_info + kernel_clean + fi +} + +function kernel_info() { + latest_kernel=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) + echo -e "${YW}PVE Version: ${BL}$pve\n${CL}" + if [[ "$current_kernel" == *"pve"* ]]; then + if [[ "$latest_kernel" != *"$current_kernel"* ]]; then + echo -e "${GN}Latest Kernel: $latest_kernel\n${CL}" + fi + else + echo -e "\n${CROSS}${RD}ERROR: No PVE Kernel Found\n${CL}" + exit 1 + fi +} + +function kernel_clean() { + kernels=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | sort -V) + remove_kernels="" + for kernel in $kernels + do + if [ "$(echo $kernel | grep $current_kernel)" ]; then + break + else + echo -e "${BL}'$kernel' ${CL}${YW}has been added to the remove Kernel list\n${CL}" + remove_kernels+=" $kernel" + fi + done +msg_ok "Kernel Search Completed\n" + if [[ "$remove_kernels" != *"pve"* ]]; then + echo -e "${PARTY} ${GN}It appears there are no old Kernels on your system. \n${CL}" + msg_info "Exiting" + sleep 2 + msg_ok "Done" + else + read -p "${YW}Would you like to remove the${BL} $(echo $remove_kernels | awk '{print NF}') ${CL}${YW}selected Kernels listed above? [y/n]: ${CL}" -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels...${CL}" + /usr/bin/apt purge -y $remove_kernels > /dev/null 2>&1 + msg_ok "Successfully Removed Kernels" + msg_info "Updating GRUB" + /usr/sbin/update-grub > /dev/null 2>&1 + msg_ok "Successfully Updated GRUB" + msg_info "Exiting" + sleep 2 + msg_ok "Done" + else + msg_info "Exiting" + sleep 2 + msg_ok "Done" + fi + fi +} + +check_root From cb25648e76432c4e4e68ddf09a266b239c00ba30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 11:27:54 -0400 Subject: [PATCH 2577/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8aef55d..ca1b4a9b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ and attempt the *No-Nag* fix. Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post_install.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-install-v3.sh)" ``` It's recommended to update Proxmox after running this script, before adding any VM/CT. @@ -37,7 +37,7 @@ Cleaning unused kernel images is not only good because of a reduced grub menu, b Run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean-v3.sh)" ``` ____________________________________________________________________________________________ From 53e7ac0dcd9c61294d14a5b89febac4000d99ddd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 11:31:02 -0400 Subject: [PATCH 2578/6505] Update post-install-v3.sh --- misc/post-install-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-install-v3.sh b/misc/post-install-v3.sh index 880cf3e8..80335866 100644 --- a/misc/post-install-v3.sh +++ b/misc/post-install-v3.sh @@ -13,7 +13,7 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -echo -e "\e[1;33m This script will Preform Post Install Routines. PVE7 ONLY \e[0m" +echo -e "\e[1;33m This script will Perform Post Install Routines. PVE7 ONLY \e[0m" while true; do read -p "Start the PVE7 Post Install Script (y/n)?" yn case $yn in From 200e91d8fa15b32769792307a2e6f060a97dd4c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 11:53:16 -0400 Subject: [PATCH 2579/6505] Update README.md --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ca1b4a9b..c369959e 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,13 @@ 🔸
    - Proxmox VE 7 Post Install + 🔸Proxmox VE 7 Post Install

    Proxmox VE 7 Post Install

    -This script will Disable the Enterprise Repo, Add & Enable the No-Subscription Repo, Add & Disable Test Repo (repo's can be enabled/disabled via the UI in Repositories) -and attempt the *No-Nag* fix. +This script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add & Disable Test Repo and Disable Subscription Nag. Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** @@ -26,7 +25,7 @@ ________________________________________________________________________________
    - Proxmox Kernel Clean + 🔸Proxmox Kernel Clean

    From 63b32f29a195dcb4b5ec3f0503da07fa79d178b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 11:56:42 -0400 Subject: [PATCH 2580/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e13fa1d1..3071b34c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-23 + +### Changed + +- **Proxmox VE 7 Post Install** + - NEW v3 Script +- **Proxmox Kernel Clean** + - NEW v3 Script + ## 2022-04-22 ### Changed From cdb8b736fb629f2b7322a09e549ce24922008bcc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 12:13:52 -0400 Subject: [PATCH 2581/6505] Update debian-install.sh --- setup/debian-install.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index dab51639..8d4ae254 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -33,13 +33,20 @@ while [ "$(hostname -I)" = "" ]; do ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From b66dadf3b3487ad97437e549a2d495fe8412265e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:36:36 -0400 Subject: [PATCH 2582/6505] Update adguard-install.sh --- setup/adguard-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index f28f4425..f2736eba 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 2815bd82b7e94fe0ae92a7b6363942698530a6ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:37:08 -0400 Subject: [PATCH 2583/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index b6fe12ab..367bf16e 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 83d7121fe68c014f1417622965961cbcd0b22cfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:37:40 -0400 Subject: [PATCH 2584/6505] Update dashy-install.sh --- setup/dashy-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 7d309299..f651c15a 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 5e118fb4f31e0f9221fc12dd87bd97e12f71ff12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:38:07 -0400 Subject: [PATCH 2585/6505] Update docker-install.sh --- setup/docker-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 196d3a89..e5949a3d 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 9c68915136ead7296132620109fe1a18da867343 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:38:33 -0400 Subject: [PATCH 2586/6505] Update esphome-install.sh --- setup/esphome-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 0daeac42..bd959777 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -41,6 +41,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 0ff218f5dd1951e06a06bdf1358b231f284c786e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:38:58 -0400 Subject: [PATCH 2587/6505] Update grafana-install.sh --- setup/grafana-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 3fb1037b..eb69dc53 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 2133d7bf5dd1b6fe9d4e80b95a4417245505af0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:39:26 -0400 Subject: [PATCH 2588/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 25856f2c..c08cb854 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 00ec87e46b8b062a84f96335b6436ea64d335d9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:40:09 -0400 Subject: [PATCH 2589/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 967f0765..1bbfbe22 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -41,6 +41,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 0efcc45582609324f777140bf68c407f1afe1b81 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:40:37 -0400 Subject: [PATCH 2590/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 436c387e..1592c674 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 59b203f40dcbd96cfef9a352c4610ff478babc55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:41:19 -0400 Subject: [PATCH 2591/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index b1156a0c..a8e81043 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From c4a32fb32047726a7e2e9ebd17323c75ac4bc9cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:41:47 -0400 Subject: [PATCH 2592/6505] Update iobroker-install.sh --- setup/iobroker-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index f63611fc..c65b9dc3 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 0eab6d5554e983181733d19884658418aea12062 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:42:19 -0400 Subject: [PATCH 2593/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 257117ae..293f8e6e 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 2f098628c596ded4f5cea30562a39efdcf704c52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:42:50 -0400 Subject: [PATCH 2594/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index ced8fe7f..b135d6f8 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From c4d58c7ebccdc152c4e8bc12fd357e58afc85dbf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:43:17 -0400 Subject: [PATCH 2595/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index fc21c4bb..703f3fd9 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 40b6f27065c12c40b68fdaa40268ffabdaba9825 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:43:45 -0400 Subject: [PATCH 2596/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 159baf93..2a001cf9 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From ad91f3e1e12509770419769f61c03effef16b839 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:44:19 -0400 Subject: [PATCH 2597/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 1a54f90d..fcab334d 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From b13113279ab5a15c3441d36605366af22ebbc654 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:44:49 -0400 Subject: [PATCH 2598/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 47d65c37..b8c0c880 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 7f4948ccd7e60415dd12bacdbac8e6b3287dd85e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:45:13 -0400 Subject: [PATCH 2599/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index bb7d0b78..48464294 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 742d0afaf0131f8fcc6fe1dc14badb17e9548725 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:45:43 -0400 Subject: [PATCH 2600/6505] Update node-red-install.sh --- setup/node-red-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 1a891678..948a8261 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 313f1fc438de1314d9f4c23a56d4190e00763504 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:46:13 -0400 Subject: [PATCH 2601/6505] Update omada-install.sh --- setup/omada-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index f8642836..b288f5ea 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS (216 packages)" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 6089fee6cb4415114179621af6d5ae47197bca01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:46:47 -0400 Subject: [PATCH 2602/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 52c24c4a..425dcb31 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 21b3317199a60a2d745b3faf70f50421bdda219a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:47:12 -0400 Subject: [PATCH 2603/6505] Update pihole-install.sh --- setup/pihole-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 7547937a..89eda75a 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From d8fdc91f24e61109b138f4f05d611509d04f2d95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:47:37 -0400 Subject: [PATCH 2604/6505] Update plex-install.sh --- setup/plex-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/plex-install.sh b/setup/plex-install.sh index d91ef8a9..349420f6 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 025f9f15070a08ec3771088c062e0cca4e278c17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:48:05 -0400 Subject: [PATCH 2605/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 9cb2ad86..4a78e08f 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -41,6 +41,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From fe77041968e48e79cc9e0b20ae13c78e9570386b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:48:35 -0400 Subject: [PATCH 2606/6505] Update technitiumdns-install.sh --- setup/technitiumdns-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 934a053d..e3f84efd 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 13488f06b476f5c3274f3464ae008b06d2df1728 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:49:03 -0400 Subject: [PATCH 2607/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index dab51639..271dea13 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 2b35ffeeb689c811a5a31aaaf52deedc854f1264 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:49:33 -0400 Subject: [PATCH 2608/6505] Update unifi-install.sh --- setup/unifi-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 79ff07d2..f190984b 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -41,6 +41,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 54bf57d36963074747c7c4ab241da02383112334 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:50:00 -0400 Subject: [PATCH 2609/6505] Update uptimekuma-install.sh --- setup/uptimekuma-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 67dd3749..006eedc6 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 5c6b1fd0bf0defd1674c21ae331db236ecf6a24e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:50:28 -0400 Subject: [PATCH 2610/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 71f3f34f..d41751fe 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From c228146d81fab47b63070cbe05b9ac894ee0566f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:50:53 -0400 Subject: [PATCH 2611/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 48965f77..9c7472cc 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -40,6 +40,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + OPTIONS_PATH='/options.conf' cat >$OPTIONS_PATH <<'EOF' IPv4dev=eth0 From c320b5550a94c008a4ceac5217b31e866c68b560 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:51:16 -0400 Subject: [PATCH 2612/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 9a0efcda..cc64eb66 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -41,6 +41,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 59c37adb0c4b3b0cf7c611365ca116d0a1869f98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:51:46 -0400 Subject: [PATCH 2613/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 5fe2f04c..3b6f1824 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -41,6 +41,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "{CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From df7dee021d312d7514cb797b84667640f64fd18a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Apr 2022 13:53:23 -0400 Subject: [PATCH 2614/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3071b34c..8c46f2c5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. ### Changed +- **v3 Script** + - ADD Internet Connection Check - **Proxmox VE 7 Post Install** - NEW v3 Script - **Proxmox Kernel Clean** From 46c5cbb99bf8dc68b5659f8331d0de92e7666921 Mon Sep 17 00:00:00 2001 From: srappan <26847675+srappan@users.noreply.github.com> Date: Sat, 23 Apr 2022 19:56:21 +0000 Subject: [PATCH 2615/6505] fix msg-info to msg_info, typo caused script to quit --- misc/post-install-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/post-install-v3.sh b/misc/post-install-v3.sh index 80335866..2d56301c 100644 --- a/misc/post-install-v3.sh +++ b/misc/post-install-v3.sh @@ -98,10 +98,10 @@ fi read -r -p "Disable Subscription Nag? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then -msg-info "Disabling Subscription Nag" +msg_info "Disabling Subscription Nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null -msg-ok "Disabled Subscription Nag" +msg_ok "Disabled Subscription Nag" fi msg_ok "Finished....Please Update Proxmox" From 28b0fcdce7ebdabfda1e9167b7e00d81d2abb537 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Apr 2022 04:14:46 -0400 Subject: [PATCH 2616/6505] Create internet-check.sh --- misc/internet-check.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 misc/internet-check.sh diff --git a/misc/internet-check.sh b/misc/internet-check.sh new file mode 100644 index 00000000..4edeb0b4 --- /dev/null +++ b/misc/internet-check.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash -ex +wget -q --tries=10 --timeout=5 --spider http://google.com +if [[ $? -eq 0 ]]; then + echo -e "Internet Online" +else + echo -e "Internet Offline" +fi From d7f10ae0140238aa7d1e5a3e69f09a0043bfb309 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Apr 2022 04:17:02 -0400 Subject: [PATCH 2617/6505] Update internet-check.sh --- misc/internet-check.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/internet-check.sh b/misc/internet-check.sh index 4edeb0b4..b41d7bfb 100644 --- a/misc/internet-check.sh +++ b/misc/internet-check.sh @@ -5,3 +5,4 @@ if [[ $? -eq 0 ]]; then else echo -e "Internet Offline" fi +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/internet-check.sh)" From 8053a2ffb04284539980c7a99e182e3654082a3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Apr 2022 04:29:20 -0400 Subject: [PATCH 2618/6505] Update internet-check.sh --- misc/internet-check.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/internet-check.sh b/misc/internet-check.sh index b41d7bfb..e3593772 100644 --- a/misc/internet-check.sh +++ b/misc/internet-check.sh @@ -1,8 +1,10 @@ #!/usr/bin/env bash -ex +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" wget -q --tries=10 --timeout=5 --spider http://google.com if [[ $? -eq 0 ]]; then - echo -e "Internet Online" + echo -e "${CM} Internet Online" else - echo -e "Internet Offline" + echo -e "${CROSS} Internet Offline" fi # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/internet-check.sh)" From 1f969e914cb3b316e2ef7428bacaf3a32c7fe318 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Apr 2022 04:31:37 -0400 Subject: [PATCH 2619/6505] Update internet-check.sh --- misc/internet-check.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/internet-check.sh b/misc/internet-check.sh index e3593772..e5758dec 100644 --- a/misc/internet-check.sh +++ b/misc/internet-check.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash -ex +RD=`echo "\033[01;31m"` +CL=`echo "\033[m"` +GN=`echo "\033[1;92m"` CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" wget -q --tries=10 --timeout=5 --spider http://google.com From 85beb59b11943a26cd7410700dd9b2868003e060 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Apr 2022 04:34:12 -0400 Subject: [PATCH 2620/6505] Update internet-check.sh --- misc/internet-check.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/internet-check.sh b/misc/internet-check.sh index e5758dec..6e0b44d4 100644 --- a/misc/internet-check.sh +++ b/misc/internet-check.sh @@ -6,8 +6,8 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" wget -q --tries=10 --timeout=5 --spider http://google.com if [[ $? -eq 0 ]]; then - echo -e "${CM} Internet Online" + echo -e " ${CM} Internet Online" else - echo -e "${CROSS} Internet Offline" + echo -e " ${CROSS} Internet Offline" fi # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/internet-check.sh)" From 7cf11056c82a6de22a7aa83278e32999a4572eed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Apr 2022 07:19:53 -0400 Subject: [PATCH 2621/6505] Delete internet-check.sh --- misc/internet-check.sh | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 misc/internet-check.sh diff --git a/misc/internet-check.sh b/misc/internet-check.sh deleted file mode 100644 index 6e0b44d4..00000000 --- a/misc/internet-check.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -ex -RD=`echo "\033[01;31m"` -CL=`echo "\033[m"` -GN=`echo "\033[1;92m"` -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -wget -q --tries=10 --timeout=5 --spider http://google.com -if [[ $? -eq 0 ]]; then - echo -e " ${CM} Internet Online" -else - echo -e " ${CROSS} Internet Offline" -fi -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/internet-check.sh)" From 503c3337506ca8b563684bc7b2d8b375eba6ac46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Apr 2022 13:35:31 -0400 Subject: [PATCH 2622/6505] Update haos-vm.sh --- vm/haos-vm.sh | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 3e3b3145..9d42f6fa 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -220,39 +220,28 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -RELEASE_TYPE=qcow2 URL=$(cat<1 {print $2}') case $STORAGE_TYPE in btrfs|nfs|dir) From 34450b083602db8fefdb94b4d2194062ce6b4ead Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:03:15 -0400 Subject: [PATCH 2623/6505] Update debian-v3.sh --- ct/debian-v3.sh | 51 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 462a0942..0870c851 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash APP="Debian" var_disk="2" var_cpu="1" @@ -21,6 +19,43 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function error_exit() { + trap - ERR + local DEFAULT="Unknown failure occured." + local REASON="${1:-$DEFAULT}" + local FLAG="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$FLAG $REASON" 1>&2 + exit $EXIT +} +function warn() { + local REASON="$1" + local FLAG="${YW}⚠ WARNING ${CL}" + echo -e "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="${BL}ℹ INFO ${CL}" + echo -e "$FLAG $REASON" +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in @@ -43,16 +78,6 @@ ${CL}" header_info -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) From 785ca697b376720a08aa4b0e116d10779027ccbe Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:18:13 -0400 Subject: [PATCH 2624/6505] Update debian-v3.sh --- ct/debian-v3.sh | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 0870c851..245c11bf 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -28,33 +28,23 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function error_exit() { trap - ERR - local DEFAULT="Unknown failure occured." - local REASON="${1:-$DEFAULT}" - local FLAG="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$FLAG $REASON" 1>&2 + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 exit $EXIT } -function warn() { - local REASON="$1" - local FLAG="${YW}⚠ WARNING ${CL}" - echo -e "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="${BL}ℹ INFO ${CL}" - echo -e "$FLAG $REASON" -} while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn From dc446ad10966aa52ddb9705862b90917f8eb3e47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:20:22 -0400 Subject: [PATCH 2625/6505] Update create_lxc.sh --- ct/create_lxc.sh | 56 ++++++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index c0db635d..1f70d623 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -1,11 +1,4 @@ #!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -14,40 +7,33 @@ CL=`echo "\033[m"` CM="${GN}✓${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - function error_exit() { trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 exit $EXIT } -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + function select_storage() { local CLASS=$1 local CONTENT @@ -100,10 +86,10 @@ if pct status $CTID &>/dev/null; then fi TEMPLATE_STORAGE=$(select_storage template) || exit -msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." +msg_ok "Using ${BL}ℹ $TEMPLATE_STORAGE${CL} ${GN}for Template Storage." CONTAINER_STORAGE=$(select_storage container) || exit -msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." +msg_ok "Using ${BL}ℹ $CONTAINER_STORAGE${CL} ${GN}for Container Storage." msg_info "Updating LXC Template List" pveam update >/dev/null From f72594e554ff534d9c0cf7f222c56387723949fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:21:16 -0400 Subject: [PATCH 2626/6505] Update debian-v3.sh --- ct/debian-v3.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 245c11bf..b8b46249 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -27,6 +27,15 @@ shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -37,15 +46,6 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 52604ccdc039e3ec36d8e71562657c5aecde05d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:23:00 -0400 Subject: [PATCH 2627/6505] Update debian-install.sh --- setup/debian-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 8d4ae254..ec5d62e7 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From ec03ccf08ed802e7e63df1ab7866e65791fd3733 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:24:07 -0400 Subject: [PATCH 2628/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index b8b46249..b0c3b9ac 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -339,13 +339,13 @@ export PCT_OPTIONS=" -unprivileged $CT_TYPE $PW " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/ct/create_lxc.sh)" || exit msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 094c9f56c2572ca88ef851d0910e8091c01070d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:27:30 -0400 Subject: [PATCH 2629/6505] Update create_lxc.sh --- ct/create_lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 1f70d623..219ace7d 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -86,10 +86,10 @@ if pct status $CTID &>/dev/null; then fi TEMPLATE_STORAGE=$(select_storage template) || exit -msg_ok "Using ${BL}ℹ $TEMPLATE_STORAGE${CL} ${GN}for Template Storage." +msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." CONTAINER_STORAGE=$(select_storage container) || exit -msg_ok "Using ${BL}ℹ $CONTAINER_STORAGE${CL} ${GN}for Container Storage." +msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." msg_info "Updating LXC Template List" pveam update >/dev/null From f7bcbf8a23a4aedb0766f2232ff64ffc79f53a7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:29:06 -0400 Subject: [PATCH 2630/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index b0c3b9ac..b8b46249 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -339,13 +339,13 @@ export PCT_OPTIONS=" -unprivileged $CT_TYPE $PW " -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/ct/create_lxc.sh)" || exit +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From 652d40d236219a4a314bd4944454e5641683a705 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:32:59 -0400 Subject: [PATCH 2631/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index 251e56af..3e75500a 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' @@ -16,6 +14,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Adguard" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 1338c49b7b5335337f6a3bb97f24044219a12834 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:33:58 -0400 Subject: [PATCH 2632/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index ca457749..77380ecb 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Daemon Sync" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 6e54e1ae36a85279c5097d26297bb11b3216b5da Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:34:38 -0400 Subject: [PATCH 2633/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index bca7028f..15c854ea 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Dashy" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 26f279161d500460f743fe2242022854b0681902 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:35:31 -0400 Subject: [PATCH 2634/6505] Update docker-v3.sh --- ct/docker-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 42160fbc..6017af58 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -15,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Docker" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 184b2b61910b662305a5af81e47a8343671a5f1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:36:10 -0400 Subject: [PATCH 2635/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 113dfb8d..753d2df3 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="ESPHome" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 7428b7f060ab89e82a6fa67eae6c7f28f5e62a64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:37:00 -0400 Subject: [PATCH 2636/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index 451a07bb..c8a8e0ef 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Grafana" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 9e4060688fa7e8d513abc3e54a3b1c94529679a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:37:59 -0400 Subject: [PATCH 2637/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index 7439f163..2b49da03 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' PP=`echo "\e[1;35m"` @@ -17,6 +14,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Heimdall Dashboard" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From cef10337b350832f989baddbda3b417d0c715b15 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:38:44 -0400 Subject: [PATCH 2638/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index e77b131e..0c402bba 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -15,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 2e557898dba071fa11ed0e7f1db30bd72e1a8c05 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:39:17 -0400 Subject: [PATCH 2639/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 67a671be..6b1f9a02 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Homebridge" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From fa38d2a5ed0ef99576b7f418a0feea882eacdd82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:39:55 -0400 Subject: [PATCH 2640/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index 61641441..014302fe 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="InfluxDB" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From e4e1d259228ed41a83e9cb459a3d7020cc3ab7a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:40:31 -0400 Subject: [PATCH 2641/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index d19fb1ea..9a7307f5 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="ioBroker" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From aeaadd4f90ab99ab2ef23697f8378a8160f1315b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:41:16 -0400 Subject: [PATCH 2642/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index d8968d70..44d46c22 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +14,23 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" APP="Jellyfin" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 278d0c792be45da3d63ac45c1c4fbae876c40e80 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:41:52 -0400 Subject: [PATCH 2643/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 3bfa751e..74f965f5 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="MariaDB" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From ec4474220e4d22ce0b77b55f5f7e012ce141b9d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:42:28 -0400 Subject: [PATCH 2644/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index e813645b..6eb9b4f2 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="MeshCentral" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 47876a6a0645bacbba41b8db8db8dd18c698ba98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:43:10 -0400 Subject: [PATCH 2645/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index fa2430d7..219d45da 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Motioneye" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 00a98def2b7997278245d811d9e0eb88e0e69c4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:44:04 -0400 Subject: [PATCH 2646/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index deeed5c8..210b531b 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="MQTT" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 5341c4e0047b42e8d8d559370bfaecff93d81172 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:44:51 -0400 Subject: [PATCH 2647/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 97ba9d2a..8aba78d3 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Nginx Proxy Manager" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 30c70189876c54de8681a5b2418d69c942277678 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:45:30 -0400 Subject: [PATCH 2648/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index 56d4c1e0..bc48a6f3 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="NocoDB" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 81381ac6e6b2d68c3cfde7468914e2759a34a739 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:48:46 -0400 Subject: [PATCH 2649/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index 38868600..ee40b13e 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Node Red" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 6cd864c440c1c3a92eb0af67ffa007b741eb4e36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:49:41 -0400 Subject: [PATCH 2650/6505] Update omada-v3.sh --- ct/omada-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index b0d264aa..b6b2a767 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Omada" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 140aa7fe95e17887938fc2295f32caa2755080cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:50:35 -0400 Subject: [PATCH 2651/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 5549ca57..979a40f1 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' PP=`echo "\e[1;35m"` @@ -16,6 +14,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="PhotoPrism" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From ecea03c2bf21b6147ca9766ca6c34c1f4ee11968 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:51:16 -0400 Subject: [PATCH 2652/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 7de4ca44..65fc2c54 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Pihole" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 0bcb965b63f20bb6f6d9138fa4986a550713bc94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:51:53 -0400 Subject: [PATCH 2653/6505] Update plex-v3.sh --- ct/plex-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index d6695976..cdb277a2 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +14,23 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" APP="Plex" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From ea9f343713bdb5474934988e1af5db2a5be24d84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:52:31 -0400 Subject: [PATCH 2654/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 90a688e7..0184dd3e 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +14,23 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" APP="P-Home Assistant" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 3f3baef79c957f7b2d47af038c2a46d1bef8da98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:53:11 -0400 Subject: [PATCH 2655/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index f22f3103..5e2d6062 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Technitium DNS" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 7320c2a3eda35a35de2b393e0b08ad9d17cb99ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:54:08 -0400 Subject: [PATCH 2656/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 2d7cc48a..908a55f0 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Ubuntu" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 955baebd421f313688be7c7b17173a716735f309 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:54:41 -0400 Subject: [PATCH 2657/6505] Update unifi-v3.sh --- ct/unifi-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index d5d2735a..ff37c0fc 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Unifi" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From a92f212640553a5b3963092580e78cde91b11c91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:55:36 -0400 Subject: [PATCH 2658/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index 9697a04a..3e746b4f 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Uptime Kuma" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 939ddae542bf7aa03af3cdac6cceebb04c76acb6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:56:13 -0400 Subject: [PATCH 2659/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index 7745aff4..657854fb 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Vaultwarden" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 12ce47f4be550e7dcc57c52b7e1994276490e50e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:56:47 -0400 Subject: [PATCH 2660/6505] Update wireguard-v3.sh --- ct/wireguard-v3.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index b1c0afd1..0166a5f0 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +13,23 @@ HOLD="-" CM="${GN}✓${CL}" APP="Wireguard" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From 04611764b494b151b8539ac3b482b869dfe8a350 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:57:45 -0400 Subject: [PATCH 2661/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index f5f66112..833e4cd1 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -16,6 +14,23 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" APP="Zigbee2MQTT" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in From a37523e9fe3d2f1d323a99b53e627ef67f615849 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 10:58:20 -0400 Subject: [PATCH 2662/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index f9c495d8..2586c588 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` From 64b019e19226ed914a9e59067f05eca86c9f4919 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:05:59 -0400 Subject: [PATCH 2663/6505] Update adguard-install.sh --- setup/adguard-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index f2736eba..1837bc32 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From c5118c256489e79f8ed291425dde94ce3d63722a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:06:36 -0400 Subject: [PATCH 2664/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 367bf16e..db7aff68 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 0b6c248561b74b5c5eba4194ec297d2d08f5cb0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:07:06 -0400 Subject: [PATCH 2665/6505] Update dashy-install.sh --- setup/dashy-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index f651c15a..afe8fed7 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 49f613fbb7e0778d0eed60bac0d1781f91aa980a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:07:44 -0400 Subject: [PATCH 2666/6505] Update docker-install.sh --- setup/docker-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index e5949a3d..ff9ef82a 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From a62c379c12012b7e3585848b9d572bcecf00aa5a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:08:14 -0400 Subject: [PATCH 2667/6505] Update esphome-install.sh --- setup/esphome-install.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index bd959777..531de099 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -14,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From a9dc03e8d3dd2e80a6e8ddac1bb82e0daf2b4aa9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:08:48 -0400 Subject: [PATCH 2668/6505] Update grafana-install.sh --- setup/grafana-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index eb69dc53..c502fbfb 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From aee8a6201f6a43fe4140f416064415803c3ab355 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:09:20 -0400 Subject: [PATCH 2669/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index c08cb854..e393d409 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 3aaace836b56663292f1ace40873450b6a9cca70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:09:58 -0400 Subject: [PATCH 2670/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 1bbfbe22..1e91c7c4 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -14,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 99a3fde53e4db53359cbf7b0049fe170b74f663b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:10:53 -0400 Subject: [PATCH 2671/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 1592c674..6d612ed6 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From b6463d39288ea8ad34386a837fb0b2727fc260fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:11:26 -0400 Subject: [PATCH 2672/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index a8e81043..15d10f2a 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 94e93591fdd10b0d44871b4fc70740c4692d97c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:11:59 -0400 Subject: [PATCH 2673/6505] Update iobroker-install.sh --- setup/iobroker-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index c65b9dc3..66ac393a 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 0e4daf6c4b34ef871bfb39deb8408994290cdfde Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:12:31 -0400 Subject: [PATCH 2674/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 293f8e6e..b578247f 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 96beb29701dfb1b021d7328199a056f76a5e71b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:13:01 -0400 Subject: [PATCH 2675/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index b135d6f8..049fc81f 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 5d6e35dc3f585d58be5c0f309be583cb23e32090 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:13:36 -0400 Subject: [PATCH 2676/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 703f3fd9..0077a99d 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 52a1b3c86ba82c532ecfefbc5c535e296f18783e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:14:09 -0400 Subject: [PATCH 2677/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 2a001cf9..e2934db9 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 48065741f005644e29da9d1c8430149664912e5a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:14:44 -0400 Subject: [PATCH 2678/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index fcab334d..a6b5a712 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From cf63556b824197c6a9acc603dd17e53e357f0e92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:15:17 -0400 Subject: [PATCH 2679/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index b8c0c880..caa2e0f8 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From c9f9840d07705ca1656a2ce1680f51b0b65fd825 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:15:53 -0400 Subject: [PATCH 2680/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 48464294..49296b42 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 4b565f251fc097f472c46f2432b684e529793f38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:16:28 -0400 Subject: [PATCH 2681/6505] Update node-red-install.sh --- setup/node-red-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 948a8261..0a138e21 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 6d6bfcd07776e0cf1e2d4f575f6a302d0d9dbf50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:17:06 -0400 Subject: [PATCH 2682/6505] Update omada-install.sh --- setup/omada-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index b288f5ea..9c654141 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From e441bcaeb6376a361b91d75b96ab9c003809387f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:17:39 -0400 Subject: [PATCH 2683/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 425dcb31..1e134b52 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From b457091ad03f74e10f9d793a0bb267fcf4850169 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:18:04 -0400 Subject: [PATCH 2684/6505] Update pihole-install.sh --- setup/pihole-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 89eda75a..632a2662 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 94682afe92fbb37cef8b890e99ec292b97399e65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:18:35 -0400 Subject: [PATCH 2685/6505] Update plex-install.sh --- setup/plex-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 349420f6..454754ba 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 6a7134cd8b5e834c1d9f58f75edba6ca5dadb1a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:19:06 -0400 Subject: [PATCH 2686/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 4a78e08f..4f5efb07 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -14,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From d3b4ca4beaf3835d6814aa66615887c278c25d0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:19:33 -0400 Subject: [PATCH 2687/6505] Update technitiumdns-install.sh --- setup/technitiumdns-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index e3f84efd..985f77d3 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 3de976cdc963d4a55705d25feb632e47073fdf20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:20:06 -0400 Subject: [PATCH 2688/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 271dea13..dff19754 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From f24a53fcf615f0a25e421a602ca8dc046797e140 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:20:39 -0400 Subject: [PATCH 2689/6505] Update unifi-install.sh --- setup/unifi-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index f190984b..821dd303 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -1,7 +1,5 @@ -#!/usr/bin/env bash -ex +#!/usr/bin/env bash #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 -set -euo pipefail -shopt -s inherit_errexit nullglob YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -14,6 +12,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 1631e6644049e6bd5e1ad2c477de3a531ce51983 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:21:11 -0400 Subject: [PATCH 2690/6505] Update uptimekuma-install.sh --- setup/uptimekuma-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 006eedc6..d44d4815 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From a5909fb4bf92471dde69f389d72694c1a114c815 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:21:41 -0400 Subject: [PATCH 2691/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index d41751fe..6d2614b8 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From b25b931abe807773b4928eec5cf92b86d0052f63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:22:09 -0400 Subject: [PATCH 2692/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 9c7472cc..db50be80 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -13,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 03527079d57f8bbbd424cff1fcc22aa800f236a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:22:35 -0400 Subject: [PATCH 2693/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index cc64eb66..13fa965b 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -14,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From c8cf7cebcae2aa432fdab1372545b202c6c91006 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 11:23:01 -0400 Subject: [PATCH 2694/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 3b6f1824..2f291ca2 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -1,7 +1,4 @@ -#!/usr/bin/env bash -ex -set -euo pipefail -shopt -s inherit_errexit nullglob - +#!/usr/bin/env bash YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -14,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" From 7fc97e4976436cdc56754b4adb929e706d04fd9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 12:07:48 -0400 Subject: [PATCH 2695/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 8c46f2c5..b6e1347e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-25 + +### Changed + +- **v3 Script** + - Improve Error Handling + ## 2022-04-23 ### Changed From b6d249cb90a4be72c44b4c8c336038e9acb050ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:49:14 -0400 Subject: [PATCH 2696/6505] Update adguard-install.sh --- setup/adguard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 1837bc32..d5b3943f 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From a4231ffb98787f7f1eaab7ff229268b06f3e5aa6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:49:36 -0400 Subject: [PATCH 2697/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index db7aff68..cf10ce67 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 435d6215e7b5143c6055cab5efc4945bdd9ffd31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:50:12 -0400 Subject: [PATCH 2698/6505] Update dashy-install.sh --- setup/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index afe8fed7..0be1dd45 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 681d482eeb66d89c7d8dc25292039247f876a593 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:50:39 -0400 Subject: [PATCH 2699/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index ec5d62e7..d11cc00c 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From c394833bef3187edcbad19a4ddc3cfbd604888f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:51:06 -0400 Subject: [PATCH 2700/6505] Update docker-install.sh --- setup/docker-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index ff9ef82a..74579fb1 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From a04c3cdbfba49e9c71050b94f7884407e545b230 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:51:35 -0400 Subject: [PATCH 2701/6505] Update esphome-install.sh --- setup/esphome-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 531de099..0e3e211b 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 7c3771ebd66adab3d6f953523c81100d172d47fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:53:59 -0400 Subject: [PATCH 2702/6505] Update grafana-install.sh --- setup/grafana-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index c502fbfb..a502575c 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 7e5be036555fc7d861cf23d3841ee8855947bacf Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:54:30 -0400 Subject: [PATCH 2703/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index e393d409..75e671d6 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From fc9dc9b7bdf3fa6d85db159344ff2ce6906cecb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 13:59:41 -0400 Subject: [PATCH 2704/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 1e91c7c4..877b2cc6 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From f14b1caefa4817ab00807bfe3ec659f3fe3370bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:00:05 -0400 Subject: [PATCH 2705/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 6d612ed6..3d23993c 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From bcd66f4bb347832ee4e1b85c2b46ce3fd078cca6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:00:29 -0400 Subject: [PATCH 2706/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 15d10f2a..3ee77e76 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From c983ce92dde99b97be764b25e9d1684bb182af9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:00:55 -0400 Subject: [PATCH 2707/6505] Update iobroker-install.sh --- setup/iobroker-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 66ac393a..baec9656 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 9fdb8f0e6438881660d1f9a19d1bf21bcfdc3fdf Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:01:19 -0400 Subject: [PATCH 2708/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index b578247f..8cf0e3dc 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 36beb776e0623607e66e95521519ebe78139c3bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:01:44 -0400 Subject: [PATCH 2709/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 049fc81f..2f2bd540 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 3c44965c4c1b3af77e4ea1c0605ca8ddf766bb5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:02:21 -0400 Subject: [PATCH 2710/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 0077a99d..1ec009cb 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 54b040d2cee72725dd216438bdd9428af917c16d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:02:49 -0400 Subject: [PATCH 2711/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index e2934db9..02a34dca 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 04cc7a753c4f1467f1b4941a6be2294275a211f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:03:17 -0400 Subject: [PATCH 2712/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index a6b5a712..2db4ae73 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From fd81fa4332c131828705de77ee755bb8aa2763a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:03:50 -0400 Subject: [PATCH 2713/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index caa2e0f8..5331c19e 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From c05e50061bdafc8f0da2cdc542f4e054a948b730 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:04:13 -0400 Subject: [PATCH 2714/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 49296b42..aecee008 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From b7af280c87dcb6d5c93e28bf05b899f1075c42bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:04:43 -0400 Subject: [PATCH 2715/6505] Update node-red-install.sh --- setup/node-red-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 0a138e21..cc886c74 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From fd9115f37f996756bc2890e61656cd05941386e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:05:16 -0400 Subject: [PATCH 2716/6505] Update omada-install.sh --- setup/omada-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 9c654141..0966ed74 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 4129a4bbfeca5abf1713fcc6607eee1b2bb8aaf6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:05:43 -0400 Subject: [PATCH 2717/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 1e134b52..b667f015 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From c13119da7b65a43180b83bbca44cab096aa06472 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:07:12 -0400 Subject: [PATCH 2718/6505] Update pihole-install.sh --- setup/pihole-install.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 632a2662..c5b6fc89 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -11,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" @@ -38,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From cd8fc33a3de8a31950c3f2a2224abd3fabe488a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:07:41 -0400 Subject: [PATCH 2719/6505] Update plex-install.sh --- setup/plex-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 454754ba..d55653aa 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 92aaaa60272ed5d978e038ff3263adc7d25ca48f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:08:06 -0400 Subject: [PATCH 2720/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 4f5efb07..cb84ec95 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From d8c17413ccc6421634a52c4cb82fa3beded8df13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:08:35 -0400 Subject: [PATCH 2721/6505] Update technitiumdns-install.sh --- setup/technitiumdns-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 985f77d3..db487fec 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 4f0df646612fe3066b4b7b5dd04c985903cdb752 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:09:00 -0400 Subject: [PATCH 2722/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index dff19754..dd6f282e 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From ca4dffe6f32ed1de19984fea70b1a7341e182b0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:09:25 -0400 Subject: [PATCH 2723/6505] Update unifi-install.sh --- setup/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 821dd303..ea88b35a 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -55,7 +55,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 993f71a5296b11a4008eef149cbf1f07b144eecd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:09:55 -0400 Subject: [PATCH 2724/6505] Update uptimekuma-install.sh --- setup/uptimekuma-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index d44d4815..20625dfa 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 55efeb834e47eb1be6e354f5b157bde507662b95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:11:14 -0400 Subject: [PATCH 2725/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index db50be80..ceff4d52 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From b8b4c1b6b495111065e8fb6e8b3b6209f794337e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:11:37 -0400 Subject: [PATCH 2726/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 6d2614b8..b502d0f2 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From cffd181b6fa9b4bef68be701726cbfda79978622 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:12:01 -0400 Subject: [PATCH 2727/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 13fa965b..18eea29c 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From d787338071fc31e1c53ff1ac127023d9071526b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Apr 2022 14:12:34 -0400 Subject: [PATCH 2728/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 2f291ca2..a675c978 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -54,7 +54,7 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider http://google.com +wget -q --tries=10 --timeout=5 --spider https://google.com if [[ $? -eq 0 ]]; then msg_ok "Internet Online" else From 4ae6d598db817056afe88e32f52e30bebb5b5897 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 06:24:16 -0400 Subject: [PATCH 2729/6505] Update haos-vm.sh --- vm/haos-vm.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 9d42f6fa..d86f3de5 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -220,15 +220,21 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" +RELEASE_TYPE=qcow2 URL=$(cat< Date: Tue, 26 Apr 2022 06:31:57 -0400 Subject: [PATCH 2730/6505] Update haos-vm.sh --- vm/haos-vm.sh | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index d86f3de5..17b7f754 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -220,23 +220,8 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -RELEASE_TYPE=qcow2 -URL=$(cat< Date: Tue, 26 Apr 2022 06:41:05 -0400 Subject: [PATCH 2731/6505] Update haos-vm.sh --- vm/haos-vm.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 17b7f754..1856136f 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -220,11 +220,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" - URL=https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz -if [ -z "$URL" ]; then - die "Github has returned an error, Please try again later." -fi msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From c93cb94297581a13d07aa4bc5b2627e87e212db2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 06:44:51 -0400 Subject: [PATCH 2732/6505] Update haos_vm.sh --- vm/haos_vm.sh | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index adb14cf7..7f50498f 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -114,26 +114,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." VMID=$(pvesh get /cluster/nextid) msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -RELEASE_TYPE=qcow2 -URL=$(cat< Date: Tue, 26 Apr 2022 06:47:14 -0400 Subject: [PATCH 2733/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 7f50498f..0bfee929 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -120,7 +120,7 @@ msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}${RELEASE_TYPE}${CL}${GN} Disk Image" +msg_ok "Downloaded ${CL}${BL}qcow2${CL}${GN} Disk Image" msg_info "Extracting Disk Image" case $FILE in *"gz") gunzip -f $FILE ;; From 86936443b78459b5fa07788d3addd8e610f81aa2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 06:49:08 -0400 Subject: [PATCH 2734/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 0bfee929..50a2fb0f 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -114,7 +114,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." VMID=$(pvesh get /cluster/nextid) msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -url="https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz" +url='https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz' msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From d24e58fee661f697aabc018f7d9362c31adb81a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 06:50:45 -0400 Subject: [PATCH 2735/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 50a2fb0f..abcc7dc4 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -114,7 +114,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." VMID=$(pvesh get /cluster/nextid) msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -url='https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz' +url=https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From 4dae8df6aecb941c09515273a269e920e073bf84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 06:54:41 -0400 Subject: [PATCH 2736/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index abcc7dc4..36a2bde9 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -114,7 +114,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." VMID=$(pvesh get /cluster/nextid) msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -url=https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz +URL="https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz" msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From 3d9c605dcce00c38694376e912e747d5f6e592b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 06:59:04 -0400 Subject: [PATCH 2737/6505] Update haos-vm.sh --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 1856136f..0eaadb8d 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -220,7 +220,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -URL=https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz +URL="https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz" msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From d308bbfec371f996f54dfef9cf4c46f5b9dd8c66 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 07:06:35 -0400 Subject: [PATCH 2738/6505] Update haos_vm.sh --- vm/haos_vm.sh | 127 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 114 insertions(+), 13 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 36a2bde9..0eaadb8d 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,8 +1,11 @@ #!/usr/bin/env bash - +NEXTID=$(pvesh get /cluster/nextid) YW=`echo "\033[33m"` BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" @@ -25,8 +28,7 @@ echo -e "${BL} | |__| | / \ | | | | (___ | __ | / /\ \| | | |\___ \ | | | |/ ____ \ |__| |____) | - |_| |_/_/ \_\____/|_____/ - + |_| |_/_/ ${CL}${YW}v3${CL}${BL} \_\____/|_____/ ${CL}" } header_info @@ -40,6 +42,111 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using VM Name ${BGN}haos${CL}" + VM_NAME=haos + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}4096MiB${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" + START_VM="yes" + +} +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read VMID + if [ -z $VMID ]; then VMID=$NEXTID; fi; + echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: hoas " + read VMNAME + if [ -z $VMNAME ]; then + VM_NAME=haos + else + VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$VM_NAME${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}${CORE_COUNT}${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " + read START_VM + if [ -z $START_VM ]; then START_VM="yes"; + else + START_VM="no"; fi; + echo -en "${DGN}Starting VM when completed ${BL}$START_VM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script set -o errexit set -o errtrace @@ -111,7 +218,6 @@ else done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -VMID=$(pvesh get /cluster/nextid) msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" URL="https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz" @@ -122,12 +228,7 @@ echo -en "\e[1A\e[0K" FILE=$(basename $URL) msg_ok "Downloaded ${CL}${BL}qcow2${CL}${GN} Disk Image" msg_info "Extracting Disk Image" -case $FILE in - *"gz") gunzip -f $FILE ;; - *"zip") gunzip -f -S .zip $FILE ;; - *"xz") xz -d $FILE ;; - *) die "Unable to handle file extension '${FILE##*.}'.";; -esac +unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in btrfs|nfs|dir) @@ -143,8 +244,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) -qm create $VMID -agent 1 -bios ovmf -cores 2 -memory 4096 -name $VM_NAME -net0 virtio,bridge=vmbr0 \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null @@ -186,8 +286,9 @@ msg_ok "Added Serial Port and Configured Console" sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt qm set $VMID -serial0 socket >/dev/null ) +if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID msg_ok "Started Home Assistant OS VM" - +fi msg_ok "Completed Successfully!\n" From 3bf93c1fc15212b39b82c120d4d1a489e0f4489b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 08:25:37 -0400 Subject: [PATCH 2739/6505] Update haos-vm.sh --- vm/haos-vm.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 0eaadb8d..296818d3 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) +RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -12,7 +13,7 @@ HOLD="-" CM="${GN}✓${CL}" while true; do - read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn + read -p "This will create a New ${RELEASE} Home Assistant OS VM. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -48,8 +49,8 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" VMID=$NEXTID - echo -e "${DGN}Using VM Name ${BGN}haos${CL}" - VM_NAME=haos + echo -e "${DGN}Using VM Name ${BGN}haos${RELEASE}${CL}" + VM_NAME=haos${RELEASE} echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" echo -e "${DGN}Using ${BGN}4096MiB${CL}" @@ -72,10 +73,10 @@ clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: hoas " + echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${RELEASE} " read VMNAME if [ -z $VMNAME ]; then - VM_NAME=haos + VM_NAME=haos${RELEASE} else VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') fi @@ -220,13 +221,13 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -URL="https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz" +URL=https://github.com/home-assistant/operating-system/releases/download/${RELEASE}/haos_ova-${RELEASE}.qcow2.xz msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}qcow2${CL}${GN} Disk Image" +msg_ok "Downloaded ${CL}${BL}${RELEASE}.qcow2${CL}${GN} Disk Image" msg_info "Extracting Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') From 4cb7fa4bde3155ada9feb14e15b72ee9d5e79b89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 08:30:17 -0400 Subject: [PATCH 2740/6505] Update haos_vm.sh --- vm/haos_vm.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 0eaadb8d..41d93514 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) +RELEASE="7.6" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -12,7 +13,7 @@ HOLD="-" CM="${GN}✓${CL}" while true; do - read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn + read -p "This will create a New ${RELEASE} Home Assistant OS VM. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -48,8 +49,8 @@ function default_settings() { echo -e "${BL}Using Default Settings${CL}" echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" VMID=$NEXTID - echo -e "${DGN}Using VM Name ${BGN}haos${CL}" - VM_NAME=haos + echo -e "${DGN}Using VM Name ${BGN}haos${RELEASE}${CL}" + VM_NAME=haos${RELEASE} echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" echo -e "${DGN}Using ${BGN}4096MiB${CL}" @@ -72,10 +73,10 @@ clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: hoas " + echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${RELEASE} " read VMNAME if [ -z $VMNAME ]; then - VM_NAME=haos + VM_NAME=haos${RELEASE} else VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') fi @@ -219,14 +220,14 @@ else fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Latest Home Assistant Disk Image" -URL="https://github.com/home-assistant/operating-system/releases/download/7.6/haos_ova-7.6.qcow2.xz" +msg_info "Getting URL for Stable Branch Home Assistant Disk Image" +URL=https://github.com/home-assistant/operating-system/releases/download/${RELEASE}/haos_ova-${RELEASE}.qcow2.xz msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}qcow2${CL}${GN} Disk Image" +msg_ok "Downloaded ${CL}${BL}${RELEASE}.qcow2${CL}${GN} Disk Image" msg_info "Extracting Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') From 2ea264923adbcd542fd410cad5631f79b3caa7a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:10:30 -0400 Subject: [PATCH 2741/6505] Update haos-vm.sh --- vm/haos-vm.sh | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 296818d3..0c500bd6 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +STABLE="7.6" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -13,7 +14,7 @@ HOLD="-" CM="${GN}✓${CL}" while true; do - read -p "This will create a New ${RELEASE} Home Assistant OS VM. Proceed(y/n)?" yn + read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -47,10 +48,12 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using Version ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" VMID=$NEXTID - echo -e "${DGN}Using VM Name ${BGN}haos${RELEASE}${CL}" - VM_NAME=haos${RELEASE} + echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" + VM_NAME=haos${STABLE} echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" echo -e "${DGN}Using ${BGN}4096MiB${CL}" @@ -63,20 +66,35 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Latest for Version ${RELEASE}, or Press [ENTER] for Stable Version ${STABLE} " + read BRANCH + if [ -z $BRANCH ]; then BRANCH=$STABLE; + else + BRANCH=$RELEASE; fi; + echo -en "${DGN}Set Version To ${BL}$BRANCH${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " read VMID if [ -z $VMID ]; then VMID=$NEXTID; fi; - echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" + echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${RELEASE} " + echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${BRANCH} " read VMNAME if [ -z $VMNAME ]; then - VM_NAME=haos${RELEASE} + VM_NAME=haos${BRANCH} else VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') fi @@ -86,6 +104,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -97,6 +116,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -109,6 +129,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -124,6 +145,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -221,13 +243,13 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" -URL=https://github.com/home-assistant/operating-system/releases/download/${RELEASE}/haos_ova-${RELEASE}.qcow2.xz +URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz msg_ok "Found URL for Latest Home Assistant Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}${RELEASE}.qcow2${CL}${GN} Disk Image" +msg_ok "Downloaded ${CL}${BL}${BRANCH}.qcow2${CL}${GN} Disk Image" msg_info "Extracting Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') From 6ef256324d4bafe6c9788588cc312a8dc3613eeb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:19:47 -0400 Subject: [PATCH 2742/6505] Update haos-vm.sh --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 0c500bd6..f25e8586 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -244,7 +244,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Latest Home Assistant Disk Image" URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -msg_ok "Found URL for Latest Home Assistant Disk Image" +msg_ok "Found URL for Home Assistant ${BRANCH} Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" From c6de32ae63020cf4f00c9c98340a343b96e48770 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:25:41 -0400 Subject: [PATCH 2743/6505] Rename haos-vm.sh to haos-vm-v3.sh --- vm/{haos-vm.sh => haos-vm-v3.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename vm/{haos-vm.sh => haos-vm-v3.sh} (100%) diff --git a/vm/haos-vm.sh b/vm/haos-vm-v3.sh similarity index 100% rename from vm/haos-vm.sh rename to vm/haos-vm-v3.sh From 1642ca5cf869c6075962c75dd594103887f2fb13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:26:09 -0400 Subject: [PATCH 2744/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c369959e..0f31ed4c 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ ________________________________________________________________________________ To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v3.sh)" ```

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

    From aad5414286ea65eb0bd57b242a54089db4e45d0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:30:58 -0400 Subject: [PATCH 2745/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b6e1347e..7984845a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-26 + +### Changed + +- **Home Assistant OS VM** + - Fixed bad path + - ADD Option to create VM using Latest or Stable image + ## 2022-04-25 ### Changed From 4b57d8dda258b7af0b7f03ed5d987c88810051fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:31:54 -0400 Subject: [PATCH 2746/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0f31ed4c..f7bee651 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ ________________________________________________________________________________
    - Home Assistant OS VM + 🔸Home Assistant OS VM

    @home-assistant

    @@ -270,7 +270,7 @@ ________________________________________________________________________________
    - 🔸ioBroker LXC + ioBroker LXC

    From 385b25a87598cda5319d058c88b09585dea32b4f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:39:36 -0400 Subject: [PATCH 2747/6505] Delete pimox-haos-vm.sh --- vm/pimox-haos-vm.sh | 70 --------------------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 vm/pimox-haos-vm.sh diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh deleted file mode 100644 index 012208af..00000000 --- a/vm/pimox-haos-vm.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash -# for testing only -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - REASON=$1 - MSG="\e[91mERROR: \e[93m$EXIT@" - if [ -z "$REASON" ]; then - MSG="$MSG$LINE:" - REASON="Unknown failure occured." - else - MSG="$MSG`echo $(( $LINE - 1 ))`:" - fi - echo -e "$MSG \e[97m$REASON\e[39m\e[49m" - exit $EXIT -} -function cleanup() { - popd >/dev/null - rm -rf $TMP -} -trap cleanup EXIT -TMP=`mktemp -d` -pushd $TMP >/dev/null - -VMID=$(cat<&/dev/null && \ -qm importdisk $VMID ${FILE%".xz"} local 1>&/dev/null -echo -e "Completed Successfully, New VM ID is $VMID \n" From 8c2ee09721ce01a5e7cdbce4e5ebac596596c09c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:42:52 -0400 Subject: [PATCH 2748/6505] Update haos_vm.sh --- vm/haos_vm.sh | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 41d93514..5b2a9a4f 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) -RELEASE="7.6" +RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +STABLE="7.6" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -13,7 +14,7 @@ HOLD="-" CM="${GN}✓${CL}" while true; do - read -p "This will create a New ${RELEASE} Home Assistant OS VM. Proceed(y/n)?" yn + read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -47,10 +48,12 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using Version ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" VMID=$NEXTID - echo -e "${DGN}Using VM Name ${BGN}haos${RELEASE}${CL}" - VM_NAME=haos${RELEASE} + echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" + VM_NAME=haos${STABLE} echo -e "${DGN}Using ${BGN}2vCPU${CL}" CORE_COUNT="2" echo -e "${DGN}Using ${BGN}4096MiB${CL}" @@ -63,20 +66,35 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Latest for Version ${RELEASE}, or Press [ENTER] for Stable Version ${STABLE} " + read BRANCH + if [ -z $BRANCH ]; then BRANCH=$STABLE; + else + BRANCH=$RELEASE; fi; + echo -en "${DGN}Set Version To ${BL}$BRANCH${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " read VMID if [ -z $VMID ]; then VMID=$NEXTID; fi; - echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" + echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" echo -e " ${CM}${CL} \r" sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${RELEASE} " + echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${BRANCH} " read VMNAME if [ -z $VMNAME ]; then - VM_NAME=haos${RELEASE} + VM_NAME=haos${BRANCH} else VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') fi @@ -86,6 +104,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " @@ -97,6 +116,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -109,6 +129,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -124,6 +145,7 @@ sleep 1 clear header_info echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" @@ -220,14 +242,14 @@ else fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Stable Branch Home Assistant Disk Image" -URL=https://github.com/home-assistant/operating-system/releases/download/${RELEASE}/haos_ova-${RELEASE}.qcow2.xz -msg_ok "Found URL for Latest Home Assistant Disk Image" +msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +msg_ok "Found URL for Home Assistant ${BRANCH} Disk Image" msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}${RELEASE}.qcow2${CL}${GN} Disk Image" +msg_ok "Downloaded ${CL}${BL}${BRANCH}.qcow2${CL}${GN} Disk Image" msg_info "Extracting Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') From 4891fe23152702525aa6356e3bde975c3efe5fed Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 09:43:45 -0400 Subject: [PATCH 2749/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index f25e8586..5b2a9a4f 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -242,7 +242,7 @@ else fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Container ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Latest Home Assistant Disk Image" +msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz msg_ok "Found URL for Home Assistant ${BRANCH} Disk Image" msg_ok "${CL}${BL}${URL}${CL}" From b8fcc40d455fc2f0394a0914741503590d2a67e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 11:08:50 -0400 Subject: [PATCH 2750/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f7bee651..b0311569 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ ________________________________________________________________________________

    @home-assistant

    Home Assistant OS VM

    +

    Option to create VM using the Latest or Stable Image

    To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell From b118060a0f347bb6bbbc3fe67f34472f67db8fda Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 11:10:51 -0400 Subject: [PATCH 2751/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0311569..04b1f62e 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox S ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v3.sh)" ``` -

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU ⚡

    +

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    After the script completes, click on the VM, then on the **_Summary_** tab to find the VM IP. From 9f8910144f7e05725eb2229d8e9efaafd026c0be Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 14:31:33 -0400 Subject: [PATCH 2752/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index ceff4d52..c1a11cec 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -108,8 +108,8 @@ WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/lat | grep "tag_name" \ | awk '{print substr($2, 2, length($2)-3) }') \ -git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /ect/wgdashboard &>/dev/null -cd /ect/wgdashboard/src +git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null +cd /etc/wgdashboard/src sudo chmod u+x wgd.sh sudo ./wgd.sh install &>/dev/null sudo chmod -R 755 /etc/wireguard @@ -121,8 +121,8 @@ echo "[Unit] After=netword.service [Service] -WorkingDirectory=/ect/wgdashboard/src -ExecStart=/usr/bin/python3 /ect/wgdashboard/src/dashboard.py +WorkingDirectory=/etc/wgdashboard/src +ExecStart=/usr/bin/python3 /etc/wgdashboard/src/dashboard.py Restart=always From afb61b5ecd1372bd0fee4ef2edef10bfcbcbb732 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 15:15:51 -0400 Subject: [PATCH 2753/6505] Update unifi-install.sh --- setup/unifi-install.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index ea88b35a..836add72 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -72,8 +72,16 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing UniFi Network Application" -wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip &>/dev/null +read -r -p "Local Controller? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +LOCAL="--local-controller" +else +LOCAL="" +fi + +msg_info "Installing UniFi Network Application (Patience)" +wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip --add-repository $LOCAL &>/dev/null msg_ok "Installed UniFi Network Application" PASS=$(grep -w "root" /etc/shadow | cut -b6); From cb556583990f07211fe66203139ebe2ffa17d4b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 15:22:43 -0400 Subject: [PATCH 2754/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 04b1f62e..c26a5dff 100644 --- a/README.md +++ b/README.md @@ -946,7 +946,7 @@ ________________________________________________________________________________
    - UniFi Network Application LXC + 🔸UniFi Network Application LXC

    From 3698f83f396237c4c4a797ee779c7ffa4fa7f22d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 15:28:09 -0400 Subject: [PATCH 2755/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7984845a..86c27a4a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. - **Home Assistant OS VM** - Fixed bad path - ADD Option to create VM using Latest or Stable image +- **UniFi Network Application LXC** + - ADD Local Controller Option ## 2022-04-25 From f869db076aec3d85409054d301e74d11931a7bcc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Apr 2022 19:09:29 -0400 Subject: [PATCH 2756/6505] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c26a5dff..8b3c545c 100644 --- a/README.md +++ b/README.md @@ -920,19 +920,20 @@ ________________________________________________________________________________
    - 🔸Ubuntu 20.04/21.10 LXC + Ubuntu LXC

    Ubuntu

    -

    Ubuntu 20.04/21.10 LXC

    +

    Ubuntu LXC

    +

    Option to select 20.04 or 21.10

    -To create a new Proxmox Ubuntu 20.04/21.10 (curl. sudo) LXC, run the following in the Proxmox Shell. +To create a new Proxmox Ubuntu (curl. sudo) LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh)" ``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 21.10⚡

    ⚙️ **To Update Ubuntu 20.04/21.10** From d6b725a0e11fe6402de79b09cbe0b70982e2aa4f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 02:23:31 -0400 Subject: [PATCH 2757/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 84 +++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 5b2a9a4f..360cee9e 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -12,6 +12,41 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} + +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null while true; do read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn @@ -171,51 +206,6 @@ function start_script() { start_script -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -228,7 +218,7 @@ while read -r line; do STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Disk image' needs to be selected for at least one storage location." + echo -e "'Disk image' needs to be selected for at least one storage location." die "Unable to detect valid storage location." elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} @@ -282,7 +272,7 @@ msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" msg_info "Adding Serial Port and Configuring Console" trap ' - warn "Unable to configure serial port. VM is still functional." + echo -e "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then qm set $VMID --delete serial0 >/dev/null fi From 5de6ee0a6ba07a417ed47b4364facce304ca39e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 04:24:18 -0400 Subject: [PATCH 2758/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b3c545c..d7e17584 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

    Proxmox VE 7 Post Install

    -This script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add & Disable Test Repo and Disable Subscription Nag. +This script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo and Disable Subscription Nag. Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** From bfb873f5ea4e76e6f77b03300aa123e4c18f0637 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 07:26:15 -0400 Subject: [PATCH 2759/6505] Update haos_vm.sh --- vm/haos_vm.sh | 109 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 11 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 5b2a9a4f..bafbfe13 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -54,10 +54,18 @@ function default_settings() { VMID=$NEXTID echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" VM_NAME=haos${STABLE} - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096MiB${CL}" - RAM_SIZE="4096" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" START_VM="yes" @@ -119,7 +127,7 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; @@ -132,8 +140,82 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " read START_VM if [ -z $START_VM ]; then START_VM="yes"; @@ -148,9 +230,13 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" - echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -267,7 +353,8 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=vmbr0 \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME \ + -net0 virtio,bridge=$BRG ip=$NET$GATE$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null From 9e4459c13b989e009be2d4769f16eba0596f4cc8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 07:32:01 -0400 Subject: [PATCH 2760/6505] Update haos_vm.sh --- vm/haos_vm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index bafbfe13..ed541add 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -353,8 +353,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME \ - -net0 virtio,bridge=$BRG ip=$NET$GATE$VLAN \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,ip=$NET$GATE$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null From 9941a47a8c8f9fb4dc46c7dc01ecc185daa10ab3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 07:36:30 -0400 Subject: [PATCH 2761/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index ed541add..9a992221 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -353,7 +353,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,ip=$NET$GATE$VLAN \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG -ipconfig ip=$NET$GATE$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null From 274a355414f6753599330571d29557ef2e4bed17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 07:42:28 -0400 Subject: [PATCH 2762/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 9a992221..9e89b953 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -353,7 +353,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG -ipconfig ip=$NET$GATE$VLAN \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG$VLAN -ipconfig0 ip=$NET$GATE \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null From 64d9231634c36cf2382fdd60ddad4081e0789685 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 08:12:50 -0400 Subject: [PATCH 2763/6505] Update haos_vm.sh --- vm/haos_vm.sh | 52 ++++++--------------------------------------------- 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 9e89b953..975e9918 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE="7.6" @@ -60,10 +61,7 @@ function default_settings() { RAM_SIZE="4096" echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN="" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" @@ -149,41 +147,6 @@ header_info echo -e " ${CM}${CL} \n" sleep 1 clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" @@ -192,8 +155,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " read VLAN1 if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; @@ -213,8 +175,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " read START_VM @@ -233,8 +194,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" @@ -353,7 +313,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG$VLAN -ipconfig0 ip=$NET$GATE \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null From 3681f86e66025920a1d9d5a5b29aef1656fe11de Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 08:32:01 -0400 Subject: [PATCH 2764/6505] Update haos_vm.sh --- vm/haos_vm.sh | 80 ++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 975e9918..2ed161f2 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -13,6 +13,41 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} + +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null while true; do read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn @@ -217,51 +252,6 @@ function start_script() { start_script -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') From 8db8608e7fd87b83ea5e191df1d12de8be1d4033 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 08:35:14 -0400 Subject: [PATCH 2765/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 68 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 360cee9e..66b3f40b 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE="7.6" @@ -89,10 +90,15 @@ function default_settings() { VMID=$NEXTID echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" VM_NAME=haos${STABLE} - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096MiB${CL}" - RAM_SIZE="4096" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" START_VM="yes" @@ -154,7 +160,7 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; @@ -167,8 +173,45 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " read START_VM if [ -z $START_VM ]; then START_VM="yes"; @@ -183,9 +226,12 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" - echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -257,7 +303,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=vmbr0 \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null From 6725b6cb5632fb15044347d864e7b3cc6471d869 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 08:36:09 -0400 Subject: [PATCH 2766/6505] Update haos_vm.sh --- vm/haos_vm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 2ed161f2..66b3f40b 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -264,7 +264,7 @@ while read -r line; do STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Disk image' needs to be selected for at least one storage location." + echo -e "'Disk image' needs to be selected for at least one storage location." die "Unable to detect valid storage location." elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} @@ -318,7 +318,7 @@ msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" msg_info "Adding Serial Port and Configuring Console" trap ' - warn "Unable to configure serial port. VM is still functional." + echo -e "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then qm set $VMID --delete serial0 >/dev/null fi From 75fd46e27d7f9c6983fddb81af3b7091f990448e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 08:59:10 -0400 Subject: [PATCH 2767/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 66b3f40b..2ea4c203 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE="7.6" @@ -96,7 +96,8 @@ function default_settings() { RAM_SIZE="4096" echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN="" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" @@ -182,6 +183,21 @@ header_info echo -e " ${CM}${CL} \n" sleep 1 clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Valid MAC Address, or Press [ENTER] for Generated MAC: $GEN_MAC " + read MAC + if [ -z $MAC ]; then MAC=$GEN_MAC; fi; + echo -en "${DGN}Set MAC Address To ${BL}$MAC${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear header_info echo -e "${RD}Using Advanced Settings${CL}" echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" From ee426dbe8dc12c977be21219edb1ab009729a8b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 09:05:49 -0400 Subject: [PATCH 2768/6505] Update haos_vm.sh --- vm/haos_vm.sh | 152 +++++++++++++++++++------------------------------- 1 file changed, 58 insertions(+), 94 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 66b3f40b..5b2a9a4f 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE="7.6" @@ -13,41 +12,6 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} - -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} - -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null while true; do read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn @@ -90,15 +54,10 @@ function default_settings() { VMID=$NEXTID echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" VM_NAME=haos${STABLE} - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" + echo -e "${DGN}Using ${BGN}2vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}4096MiB${CL}" + RAM_SIZE="4096" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" START_VM="yes" @@ -160,7 +119,7 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; @@ -173,45 +132,8 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " read START_VM if [ -z $START_VM ]; then START_VM="yes"; @@ -226,12 +148,9 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -252,6 +171,51 @@ function start_script() { start_script +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -264,7 +228,7 @@ while read -r line; do STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - echo -e "'Disk image' needs to be selected for at least one storage location." + warn "'Disk image' needs to be selected for at least one storage location." die "Unable to detect valid storage location." elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} @@ -303,7 +267,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=vmbr0 \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null @@ -318,7 +282,7 @@ msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" msg_info "Adding Serial Port and Configuring Console" trap ' - echo -e "Unable to configure serial port. VM is still functional." + warn "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then qm set $VMID --delete serial0 >/dev/null fi From d93e2ff9cdda7267beb015c1a468b23ba2d55b58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 09:24:55 -0400 Subject: [PATCH 2769/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 86c27a4a..5e4e8c65 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-27 + +### Changed + +- **Home Assistant OS VM** + - ADD Option to set Bridge, VLAN and MAC Address + ## 2022-04-26 ### Changed From 26d09286ea23fb5cbaa99daedba42299a63af7db Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 17:34:11 -0400 Subject: [PATCH 2770/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index b667f015..80716401 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -54,13 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then - msg_ok "Internet Online" -else - echo -e "{CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 05d488f00ce9ce8b8604bac5e8ebadcd6b4a5586 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:22:02 -0400 Subject: [PATCH 2771/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 80716401..5f9c0440 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -54,6 +54,15 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then + msg_ok "Internet Online" +else + echo -e "${CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 7839f6f66e577f6292cb9d08767da266cd17eab6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:24:01 -0400 Subject: [PATCH 2772/6505] Update debian-install.sh --- setup/debian-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index d11cc00c..1ba1d293 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From 2a14613acc95abbab595b35b09ca261f9c05d603 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:25:21 -0400 Subject: [PATCH 2773/6505] Update adguard-install.sh --- setup/adguard-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index d5b3943f..d73765c7 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From 2afc8f4080f41a3ec523337749854286afd01607 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:26:22 -0400 Subject: [PATCH 2774/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index cf10ce67..88815eb7 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From 0315753fd7f068d901bab92a428ae8516dbaa798 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:26:49 -0400 Subject: [PATCH 2775/6505] Update dashy-install.sh --- setup/dashy-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 0be1dd45..a5d16c29 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From fb4dcdca4c2b32c35709db8a4cebee12f1e2f15d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:27:17 -0400 Subject: [PATCH 2776/6505] Update docker-install.sh --- setup/docker-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 74579fb1..b80d0a6e 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From 1638fd89e5825750b02d7e2afdfbb673c94e00f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:27:48 -0400 Subject: [PATCH 2777/6505] Update esphome-install.sh --- setup/esphome-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 0e3e211b..9e809e1e 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From e0be38e35333be98c55a0afe86ef9d3b1d271cb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:28:20 -0400 Subject: [PATCH 2778/6505] Update grafana-install.sh --- setup/grafana-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index a502575c..d5cddb48 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From 5b18bbab44aab27e06666a7bf0f4203b698bbc85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:29:01 -0400 Subject: [PATCH 2779/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 75e671d6..0fd09c18 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ $INTER -eq 0 ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From d45235043fff72238f842221440f7d56a898cc71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:30:12 -0400 Subject: [PATCH 2780/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 1ba1d293..f9e7b5ee 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -57,7 +57,7 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ $INTER eq 0 ]]; then msg_ok "Internet Online" else echo -e "${CROSS}${RD} Internet Offline" From 8f0dd41640692c1fa5ed817fa272ba9cf04a8aad Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:32:28 -0400 Subject: [PATCH 2781/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index f9e7b5ee..f29622d1 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -57,7 +57,7 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER eq 0 ]]; then +if [[ $INTER == 0 ]]; then msg_ok "Internet Online" else echo -e "${CROSS}${RD} Internet Offline" From 289749584b96bbac1d54a6a8c4a59beaec7aa316 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:37:15 -0400 Subject: [PATCH 2782/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index f29622d1..82f0f945 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -57,7 +57,7 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER == 0 ]]; then +if [[ "$INTER" == "0" ]]; then msg_ok "Internet Online" else echo -e "${CROSS}${RD} Internet Offline" From bd477a90ef3b4c390bd86ddf78386a1d4e03690d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:40:59 -0400 Subject: [PATCH 2783/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 82f0f945..607cf01d 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -60,7 +60,7 @@ sleep 2 if [[ "$INTER" == "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From 3d5a3edf57262ca4bfc893c9f13cbfc23b7f5e1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:49:40 -0400 Subject: [PATCH 2784/6505] Update debian-install.sh --- setup/debian-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 607cf01d..c18abaea 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ "$INTER" == "0" ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 677887b8d76a8b996aa1c8b6006ef1c9de1ad687 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:50:13 -0400 Subject: [PATCH 2785/6505] Update adguard-install.sh --- setup/adguard-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index d73765c7..8a8a99f8 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 2b14b36cd323b19c31c967dfc9212abaebba242a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:50:59 -0400 Subject: [PATCH 2786/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 88815eb7..4785b25d 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 40bb06e7f6fa7bd965144da0367a8d6bc524d5a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:51:30 -0400 Subject: [PATCH 2787/6505] Update dashy-install.sh --- setup/dashy-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index a5d16c29..bddb476f 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From c7376f16a75c47c86f08180c260e3fc349ee51f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:52:00 -0400 Subject: [PATCH 2788/6505] Update docker-install.sh --- setup/docker-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index b80d0a6e..c942821f 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 9e16f7e6c06370a6392493355d4c1de877f7a633 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:52:28 -0400 Subject: [PATCH 2789/6505] Update esphome-install.sh --- setup/esphome-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 9e809e1e..44ff9711 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 97589eaf3780fa2aa7bb16b105339765273e64f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:52:54 -0400 Subject: [PATCH 2790/6505] Update grafana-install.sh --- setup/grafana-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index d5cddb48..a68c5aaf 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 25c2e36e1442022a9e6c92798963c2ef2b054c01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:53:21 -0400 Subject: [PATCH 2791/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 0fd09c18..39e89beb 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 868d7a53b8cf0e55d8b9c0b09e0324ab819e1fcb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:53:56 -0400 Subject: [PATCH 2792/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 877b2cc6..ad785862 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From a4ec758c343f41a8372fe0d3b63836574b27835c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:54:39 -0400 Subject: [PATCH 2793/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 3d23993c..14e0f3f6 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 5240267234c50c18c2380bf7f07c8fff56c1f94b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:55:07 -0400 Subject: [PATCH 2794/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 3ee77e76..95191707 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From b15d8258432bec63e6470f74592bf03fe91e20ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:55:41 -0400 Subject: [PATCH 2795/6505] Update iobroker-install.sh --- setup/iobroker-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index baec9656..4bf4f90c 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 932c707a854292db652f7500ecfc37404256dc93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:56:10 -0400 Subject: [PATCH 2796/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 8cf0e3dc..029aefaf 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From cc05e3efb44680eb7d5bb2ae1a2ee0c0aaf9498a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:56:40 -0400 Subject: [PATCH 2797/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 2f2bd540..4ebbd501 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From f9f4aa88558c48c4aeea93723f081502150cbb6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:57:12 -0400 Subject: [PATCH 2798/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 1ec009cb..6714eda6 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 329de56e57dd0a1c2fda85c742e33706ccb5e9cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:57:39 -0400 Subject: [PATCH 2799/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 02a34dca..03c1cd6a 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From a9269f7c1718d4b1d194b87d4ea7e0f908afda8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:58:22 -0400 Subject: [PATCH 2800/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 2db4ae73..5724f19f 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 1b5759eb6507c50402a5c5d6aa76358cb44babbb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:58:53 -0400 Subject: [PATCH 2801/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 5331c19e..735a83d5 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 5de16fd2fa63176cda100cdc426af3933f3ed7e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:59:22 -0400 Subject: [PATCH 2802/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index aecee008..9ee678b4 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 91850aa61954c3da7b2490eea81a306080910319 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 18:59:54 -0400 Subject: [PATCH 2803/6505] Update node-red-install.sh --- setup/node-red-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index cc886c74..33c22d6e 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From c7cefe366e07281a20b6a350066d158954ce8e50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:00:26 -0400 Subject: [PATCH 2804/6505] Update omada-install.sh --- setup/omada-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 0966ed74..b9ff4ba4 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS (216 packages)" From a870243dfed78bf23447713e11d0b7a7f27568fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:00:58 -0400 Subject: [PATCH 2805/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 5f9c0440..775d2904 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -57,10 +57,10 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Checking Internet Status" INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) sleep 2 -if [[ $INTER -eq 0 ]]; then +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "${CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From c0a363780a4803031ed38fa40e293aa1deb513fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:01:28 -0400 Subject: [PATCH 2806/6505] Update pihole-install.sh --- setup/pihole-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index c5b6fc89..78cdfd76 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 09b0924604b5397958c8db85d3f50c899c2d6d5d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:01:59 -0400 Subject: [PATCH 2807/6505] Update plex-install.sh --- setup/plex-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/plex-install.sh b/setup/plex-install.sh index d55653aa..2bcaf321 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From b866555fddf627c556c993e552cb4d95a0c6cbca Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:02:31 -0400 Subject: [PATCH 2808/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index cb84ec95..64af6ae1 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 4d8c2c53cd12ceaa51b139950b170df49622e752 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:02:57 -0400 Subject: [PATCH 2809/6505] Update technitiumdns-install.sh --- setup/technitiumdns-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index db487fec..6beb2b60 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From a398218b882667734d5c4d0b4141880068c48be1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:03:26 -0400 Subject: [PATCH 2810/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index dd6f282e..296a3538 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From c7be5be906411d0d099731c83a67bfa8994bab79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:04:01 -0400 Subject: [PATCH 2811/6505] Update unifi-install.sh --- setup/unifi-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 836add72..cea4b364 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -55,11 +55,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From ca0b0768bf046dd8cca11eeb78aaf88cf842e32e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:04:26 -0400 Subject: [PATCH 2812/6505] Update uptimekuma-install.sh --- setup/uptimekuma-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 20625dfa..7d810bbf 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From e793aa61174f542e970a1921b198bc15d3e68cb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:05:13 -0400 Subject: [PATCH 2813/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index b502d0f2..c8398396 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From df143d70ad92e6a9e215ed3c56e1b4bae1feef14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:05:37 -0400 Subject: [PATCH 2814/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index c1a11cec..555fe882 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi OPTIONS_PATH='/options.conf' From e3613521225e3ac2c5ae470820e7538918379b60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:06:10 -0400 Subject: [PATCH 2815/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 18eea29c..0e8c3c1d 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 36ada3e7e7117fd521f18fef6440ca28faf694a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:06:42 -0400 Subject: [PATCH 2816/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index a675c978..1d9fabe6 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -54,11 +54,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -wget -q --tries=10 --timeout=5 --spider https://google.com -if [[ $? -eq 0 ]]; then +msg_info "Checking Internet Status" +INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) +sleep 2 +if [[ "$INTER" != "0" ]]; then msg_ok "Internet Online" else - echo -e "{CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" fi msg_info "Updating Container OS" From 6ba6e6d2b2b75ae568734eb6ebe358ac1919c687 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Apr 2022 19:19:44 -0400 Subject: [PATCH 2817/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 5e4e8c65..9744716b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - **Home Assistant OS VM** - ADD Option to set Bridge, VLAN and MAC Address +- **v3 Script** + - Improve Internet Check (prevent ‼ ERROR 4@57) ## 2022-04-26 From 8216bc8c2f9f5f32fa8b6520be0a8677e164eccc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:45:13 -0400 Subject: [PATCH 2818/6505] Update debian-v3.sh --- ct/debian-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index b8b46249..764d3307 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -233,7 +233,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -251,7 +251,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 26875354812b7dbce7e3e520312bc7a81b8ceea3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:48:39 -0400 Subject: [PATCH 2819/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index 3e75500a..b9bf7a50 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -230,7 +230,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -248,7 +248,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 9188a82fb17545e67d5d53397bec957de9e4b136 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:49:55 -0400 Subject: [PATCH 2820/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index 77380ecb..f1f6c66d 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -229,7 +229,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -247,7 +247,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 303ed6ee69a251b0ce12fb8b275611fb042fa339 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:50:45 -0400 Subject: [PATCH 2821/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index 15c854ea..004197a8 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -229,7 +229,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -247,7 +247,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 249333d94108de87ca5ae0eb0d4cfb9bd01dffed Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:52:14 -0400 Subject: [PATCH 2822/6505] Update docker-v3.sh --- ct/docker-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 6017af58..c6f0f248 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From ff3a1372fff8a359399dcfaba82193e9d181a505 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:53:13 -0400 Subject: [PATCH 2823/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 753d2df3..b044cab7 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -246,7 +246,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 27fa3065f2479af02b16530c7ef6bcdc6a805a8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:54:23 -0400 Subject: [PATCH 2824/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index c8a8e0ef..052d3f82 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From bdcee3984c72583dc1fe81e75e0e7779370944a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:56:04 -0400 Subject: [PATCH 2825/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index 2b49da03..bcb2ec5b 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -246,7 +246,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 32ca4eb78a30f283a1070ba7850ae1ff510d686a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:58:05 -0400 Subject: [PATCH 2826/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 0c402bba..9da9f0c1 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 7bdca956f67cf94b354dcd0d4c84f71f91596ca9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 07:59:10 -0400 Subject: [PATCH 2827/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 6b1f9a02..e8af57b3 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 834417bae44c4767cce755b35f26e5379f9d503b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:00:14 -0400 Subject: [PATCH 2828/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index 014302fe..cecd1364 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -246,7 +246,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 786ab9c911d863e0b931f7983d1e830f30402672 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:01:25 -0400 Subject: [PATCH 2829/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 9a7307f5..48139515 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From e3610284514d277c0cbad418cbf8317b09419a8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:02:30 -0400 Subject: [PATCH 2830/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 44d46c22..aed0760b 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -230,7 +230,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -248,7 +248,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 793935073e0b4300a8f3d76cd6e80865b7c32a29 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:03:42 -0400 Subject: [PATCH 2831/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 74f965f5..3925d8fc 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 5d5842eae032ff52ccfee9f96deb35f5eab9e91c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:04:42 -0400 Subject: [PATCH 2832/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index 6eb9b4f2..1d6f2e1b 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 0e11b51cee8daba512496895ea1284f464159d00 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:05:37 -0400 Subject: [PATCH 2833/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index 219d45da..f83a2db8 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From ef3601a70c4bfb0f67370936e45779c6bbc96e7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:06:40 -0400 Subject: [PATCH 2834/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index 210b531b..3c8c4d14 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From d4a7ef0ff2bd692e6acd627038b3cc2c4b664be9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:07:37 -0400 Subject: [PATCH 2835/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 8aba78d3..40c4bba5 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 93ffabc7d3202aadc25fb84bc39ec685986ddd1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:08:36 -0400 Subject: [PATCH 2836/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index bc48a6f3..c32a23a4 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 7d561a6cfe3b273360109f28423335d11c0606ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:09:49 -0400 Subject: [PATCH 2837/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index ee40b13e..cbd8e44b 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From cd2ca32531a54ad98cb0e171fdc3e59375cb604a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:10:58 -0400 Subject: [PATCH 2838/6505] Update omada-v3.sh --- ct/omada-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index b6b2a767..14a0bb12 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 35679a3a871d3cc2f775f2c5867f979d95ce7c08 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:11:57 -0400 Subject: [PATCH 2839/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 979a40f1..c77bd81c 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -246,7 +246,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 5d71b9b803362f921fbe885bb5246a0d28020521 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:13:01 -0400 Subject: [PATCH 2840/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 65fc2c54..3e513be3 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 5c337bdffba4d45720c6f7cfed4b6462197946fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:14:11 -0400 Subject: [PATCH 2841/6505] Update plex-v3.sh --- ct/plex-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index cdb277a2..96fac292 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -246,7 +246,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 9004afe58a4bb60fd873ccfc6ce51bce44e70570 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:15:03 -0400 Subject: [PATCH 2842/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 0184dd3e..673ec92b 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -234,7 +234,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -252,7 +252,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 75c3eb059b394417f9ab0f2a5257c2bd20f9b21c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:16:01 -0400 Subject: [PATCH 2843/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 5e2d6062..615cdc64 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 1ec8c452878708322aadcf41631effbe1b74bf71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:16:56 -0400 Subject: [PATCH 2844/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 908a55f0..040af0b1 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -250,7 +250,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -269,7 +269,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 18ba0cd44a0d1c7ef21d1b4d8e5e8ea54edcf08b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:17:49 -0400 Subject: [PATCH 2845/6505] Update unifi-v3.sh --- ct/unifi-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index ff37c0fc..57f7fab8 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 7336eadf17860d00fe1359b4d8a5e9e74c79c72a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:18:39 -0400 Subject: [PATCH 2846/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index 3e746b4f..0820e29b 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -229,7 +229,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -247,7 +247,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From a8d148e8775c35d73a667644e516f3764feb9e2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:19:42 -0400 Subject: [PATCH 2847/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index 657854fb..c8d287f2 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -227,7 +227,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -245,7 +245,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 985527e264b640acdb6c13174fb682075229d5c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:20:30 -0400 Subject: [PATCH 2848/6505] Update wireguard-v3.sh --- ct/wireguard-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index 0166a5f0..528c57ed 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -228,7 +228,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -246,7 +246,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 989f45b91f8622ac649a53e00977094e607e8762 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:21:33 -0400 Subject: [PATCH 2849/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 833e4cd1..8d74ba7f 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -230,7 +230,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -248,7 +248,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From e2a39285080d7cc502b4623f87dd2ce0f60af843 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 08:22:25 -0400 Subject: [PATCH 2850/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 2586c588..82c1e86b 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -212,7 +212,7 @@ header_info echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IP Address, or Press [ENTER] for Default: DHCP " + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " read NET if [ -z $NET ]; then NET="dhcp"; fi; echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" @@ -230,7 +230,7 @@ header_info echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP, or Press [ENTER] for Default: NONE " + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " read GATE1 if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" From 4ef2d7fbdddfefb08718a7e5995ed9c5f453866a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 19:17:02 -0400 Subject: [PATCH 2851/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d7e17584..ec0c2a5f 100644 --- a/README.md +++ b/README.md @@ -976,7 +976,7 @@ ________________________________________________________________________________
    - 🔸Omada Controller LXC + Omada Controller LXC

    @@ -1184,7 +1184,7 @@ ________________________________________________________________________________
    - 🔸Uptime Kuma LXC + Uptime Kuma LXC

    From b805873ef179d2dfe37e324abbc47bc368c114d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 20:59:56 -0400 Subject: [PATCH 2852/6505] Update adguard-install.sh --- setup/adguard-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 8a8a99f8..9837589f 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 77d85cfebe436937434f5a7813a5a8d532ce37ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:00:25 -0400 Subject: [PATCH 2853/6505] Update daemonsync-install.sh --- setup/daemonsync-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 4785b25d..60d6e1cf 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From bdae76cd887b3adcccf1ee5c95f66e22384c1932 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:00:52 -0400 Subject: [PATCH 2854/6505] Update dashy-install.sh --- setup/dashy-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index bddb476f..f172a1c2 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From d23f925512141cad26bd10e633c2d577da1b37de Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:01:25 -0400 Subject: [PATCH 2855/6505] Update docker-install.sh --- setup/docker-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index c942821f..fed664cf 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 9d0ac5cef7e7aa9192053ea11a95e0929c79be79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:01:55 -0400 Subject: [PATCH 2856/6505] Update esphome-install.sh --- setup/esphome-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 44ff9711..44fe61fa 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 5c024237eb51b4d4824345b8c9b216093c299f4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:02:25 -0400 Subject: [PATCH 2857/6505] Update grafana-install.sh --- setup/grafana-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index a68c5aaf..12a96358 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From bb2e2ca70174821299fa28e75440a6f4d66ae12d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:03:01 -0400 Subject: [PATCH 2858/6505] Update heimdalldashboard-install.sh --- setup/heimdalldashboard-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 39e89beb..5ebef0e8 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From b1e012608851b0fb602711444904181e35c2ba97 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:03:37 -0400 Subject: [PATCH 2859/6505] Update zwavejs2mqtt-install.sh --- setup/zwavejs2mqtt-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 1d9fabe6..0d2c1ead 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From ef3dea2fc71a2197a671530a44f22722d3432c48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:04:03 -0400 Subject: [PATCH 2860/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 0e8c3c1d..d03e409e 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 6701c30d8236eb49208e77320a72697ad5cdacc0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:04:37 -0400 Subject: [PATCH 2861/6505] Update wireguard-install.sh --- setup/wireguard-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 555fe882..8109a2a0 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - OPTIONS_PATH='/options.conf' cat >$OPTIONS_PATH <<'EOF' IPv4dev=eth0 From 163b754ae85848f8033976f69eee66ffd53e5ba9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:05:06 -0400 Subject: [PATCH 2862/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index c8398396..92c616c7 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From fe510c99de0ce4a3e7c7283463b7ca32f18e56be Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:05:40 -0400 Subject: [PATCH 2863/6505] Update uptimekuma-install.sh --- setup/uptimekuma-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 7d810bbf..57c13fc2 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 172fccaf052240079a8c191934a98ed8995ed49e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:06:10 -0400 Subject: [PATCH 2864/6505] Update unifi-install.sh --- setup/unifi-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index cea4b364..071ef075 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -55,15 +55,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 1326bf931205ded624810953e22d046851b4437f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:06:46 -0400 Subject: [PATCH 2865/6505] Update homeassistant-install.sh --- setup/homeassistant-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index ad785862..77ab5de4 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From da5adbc310b0d4b110ce56fff335597cc36f14e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:07:15 -0400 Subject: [PATCH 2866/6505] Update homebridge-install.sh --- setup/homebridge-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 14e0f3f6..70e455d3 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From d509fb53d9e5d32711527e42541d6cda48092d08 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:07:44 -0400 Subject: [PATCH 2867/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 95191707..441f4070 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From aec535a7c5f85f4e5a422a5a122904ed663b450c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:08:09 -0400 Subject: [PATCH 2868/6505] Update iobroker-install.sh --- setup/iobroker-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 4bf4f90c..c9650bab 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From a17c6baf44b2dcd99d12c00564ead723575b4531 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:08:40 -0400 Subject: [PATCH 2869/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 029aefaf..38960670 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 482b3593a4b288a37c7d9b2142593feb610af2a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:09:11 -0400 Subject: [PATCH 2870/6505] Update mariadb-install.sh --- setup/mariadb-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 4ebbd501..e5680925 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 62938c682fc4d80082a24dc24e19438de65dbd51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:09:43 -0400 Subject: [PATCH 2871/6505] Update meshcentral-install.sh --- setup/meshcentral-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 6714eda6..2155cf4a 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From f82a4d02b01a56e2b6384d72730d1a7ed7623dc3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:10:16 -0400 Subject: [PATCH 2872/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 03c1cd6a..fc9f8136 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From dde04e86cf3c6932c9a905a1f7af8aca9c219d75 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:10:44 -0400 Subject: [PATCH 2873/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 5724f19f..c84f645d 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From eaf4a257d94b6a3801032269d81b906d03471b43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:11:14 -0400 Subject: [PATCH 2874/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 735a83d5..6dc047b5 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From df1b6b7288ddea49b855af4f74e833742eaacb81 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:11:39 -0400 Subject: [PATCH 2875/6505] Update nocodb-install.sh --- setup/nocodb-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 9ee678b4..7b9c96c7 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 8cd5c151b71780f8570abe053d83a4c69a415237 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:12:14 -0400 Subject: [PATCH 2876/6505] Update node-red-install.sh --- setup/node-red-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 33c22d6e..313da248 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From d523c880e05546426a8cec7f320a476cda588f4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:12:52 -0400 Subject: [PATCH 2877/6505] Update omada-install.sh --- setup/omada-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index b9ff4ba4..c3a4aa42 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS (216 packages)" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 9ecdca0d97f6080a3b352e271a7ed72129e8f536 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:13:20 -0400 Subject: [PATCH 2878/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 775d2904..80716401 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 52e5bef3fba1d6321b3e3845d7ac6b57de5d8a22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:13:51 -0400 Subject: [PATCH 2879/6505] Update pihole-install.sh --- setup/pihole-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 78cdfd76..e2ccbb03 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 02d6fd93bb44e62d6f65db37d40fd2b9ab76c7f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:14:17 -0400 Subject: [PATCH 2880/6505] Update plex-install.sh --- setup/plex-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 2bcaf321..08695424 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From d189951de6beb7c94cd02aa7fdd6c4bd8ce64be5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:14:58 -0400 Subject: [PATCH 2881/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 64af6ae1..0ed099da 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 53d8bf47a890a725f4747f5f2097b82baf7bf03d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:15:28 -0400 Subject: [PATCH 2882/6505] Update technitiumdns-install.sh --- setup/technitiumdns-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 6beb2b60..18d2eca6 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 1cf7b4ca6b155236c1fbf3851804f44794655707 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:15:57 -0400 Subject: [PATCH 2883/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 296a3538..bc311688 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 016843f1df91321f5b8faa5879481b0517fbab6d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:16:22 -0400 Subject: [PATCH 2884/6505] Update debian-install.sh --- setup/debian-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index c18abaea..b1f4bc0e 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -54,15 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Checking Internet Status" -INTER=$(wget -q --tries=10 --timeout=5 --spider https://google.com) -sleep 2 -if [[ "$INTER" != "0" ]]; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline${CL}" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From cac75afe5d08d7028cc193feb9266dd1c91cfbaf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Apr 2022 21:22:38 -0400 Subject: [PATCH 2885/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9744716b..1ff4ace7 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-04-28 + +### Changed + +- **v3 Script** + - Remove Internet Check + ## 2022-04-27 ### Changed From 48071b3011b1fd09d7d03dd4c96d2f8754437823 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Apr 2022 07:18:55 -0400 Subject: [PATCH 2886/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ec0c2a5f..d8fa8bcb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 🔸
    - 🔸Proxmox VE 7 Post Install + Proxmox VE 7 Post Install

    @@ -25,7 +25,7 @@ ________________________________________________________________________________
    - 🔸Proxmox Kernel Clean + Proxmox Kernel Clean

    From 56adfe6fb5fd9ad37c0dba5e5e3082904a20acaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 May 2022 10:47:50 -0400 Subject: [PATCH 2887/6505] Update dashy-update.sh --- misc/dashy-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index 2fd16c2a..6e7151de 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -36,6 +36,7 @@ sleep 1 echo -e "${CM}${CL} \r" echo -en "${GN} Backup conf.yml... " +cd ~ cp -R /dashy/public/conf.yml conf.yml sleep 1 echo -e "${CM}${CL} \r" From 54e4bab93c360e9ca5b1e7c9160a923e0b547fe7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 May 2022 05:33:55 -0400 Subject: [PATCH 2888/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d8fa8bcb..55dfcbd7 100644 --- a/README.md +++ b/README.md @@ -947,7 +947,7 @@ ________________________________________________________________________________
    - 🔸UniFi Network Application LXC + UniFi Network Application LXC

    From e1ef1da8bd17e2440a1bb02e81d8627a453253d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 May 2022 06:12:34 -0400 Subject: [PATCH 2889/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index fc9f8136..36785c07 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -64,11 +64,11 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -echo -en "${GN} Installing Motion... " +msg_info "Installing Motion" apt-get install motion -y &>/dev/null systemctl stop motion &>/dev/null systemctl disable motion &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Motion" msg_info "Installing FFmpeg" apt-get install ffmpeg v4l-utils -y &>/dev/null From c62cf4aea6e40834580519148f3a2a73d72e5084 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 May 2022 07:05:35 -0400 Subject: [PATCH 2890/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 80716401..4d39c9da 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -91,11 +91,13 @@ if [[ "$AVX" == "avx2" ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null ldconfig &>/dev/null - elif [[ "$AVX" == "avx" ]]; then +fi +if [[ "$AVX" == "avx" ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null ldconfig &>/dev/null - else +fi +if [[ "$AVX" == "" ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null ldconfig &>/dev/null From 34ea1a170c21a9c7021c534cece04e89c9bf0b77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 May 2022 19:06:41 -0400 Subject: [PATCH 2891/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 4d39c9da..24d90dc1 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -86,22 +86,9 @@ ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null msg_ok "Installed Golang" msg_info "Installing Tensorflow" -AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) -if [[ "$AVX" == "avx2" ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - ldconfig &>/dev/null -fi -if [[ "$AVX" == "avx" ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - ldconfig &>/dev/null -fi -if [[ "$AVX" == "" ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null ldconfig &>/dev/null -fi msg_ok "Installed Tensorflow" msg_info "Cloning PhotoPrism" From dc518e47a3e2a99ad85037afc204f1fca716c410 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 May 2022 22:27:41 -0400 Subject: [PATCH 2892/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55dfcbd7..07d7915c 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant OS VM + Home Assistant OS VM

    @home-assistant

    From 58aca2277ee5eb7f1ffdee0c92d2e2bd3b98add9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 May 2022 05:56:10 -0400 Subject: [PATCH 2893/6505] Update kernel-clean-v3.sh --- misc/kernel-clean-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean-v3.sh b/misc/kernel-clean-v3.sh index 8b5ccf46..fc9160a5 100644 --- a/misc/kernel-clean-v3.sh +++ b/misc/kernel-clean-v3.sh @@ -91,7 +91,7 @@ msg_ok "Kernel Search Completed\n" sleep 2 msg_ok "Done" else - read -p "${YW}Would you like to remove the${BL} $(echo $remove_kernels | awk '{print NF}') ${CL}${YW}selected Kernels listed above? [y/n]: ${CL}" -n 1 -r + read -p "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') selected Kernels listed above? [y/n]: " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels...${CL}" From ea5b2d9001add588d2d203ae3908daf318e316bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 May 2022 06:08:21 -0400 Subject: [PATCH 2894/6505] Update kernel-clean-v3.sh --- misc/kernel-clean-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean-v3.sh b/misc/kernel-clean-v3.sh index fc9160a5..f2ba9c41 100644 --- a/misc/kernel-clean-v3.sh +++ b/misc/kernel-clean-v3.sh @@ -94,7 +94,7 @@ msg_ok "Kernel Search Completed\n" read -p "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') selected Kernels listed above? [y/n]: " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then - msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels...${CL}" + msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" /usr/bin/apt purge -y $remove_kernels > /dev/null 2>&1 msg_ok "Successfully Removed Kernels" msg_info "Updating GRUB" From b85a683f438f6531e8bdeffb434008764601ea71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 05:47:36 -0400 Subject: [PATCH 2895/6505] Update debian-install.sh --- setup/debian-install.sh | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index b1f4bc0e..9c9476f8 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -28,6 +28,37 @@ function error_exit() { exit $EXIT } +function internet() { + test_urls="\ + https://www.google.com/ \ + https://www.microsoft.com/ \ + https://www.cloudflare.com/ \ + " + processes="0" + pids="" + for test_url in $test_urls; do + curl --silent --head "$test_url" > /dev/null & + pids="$pids $!" + processes=$(($processes + 1)) + done + while [ $processes -gt 0 ]; do + for pid in $pids; do + if ! ps | grep "^[[:blank:]]*$pid[[:blank:]]" > /dev/null; then + processes=$(($processes - 1)) + pids=$(echo "$pids" | sed --regexp-extended "s/(^| )$pid($| )/ /g") + + if wait $pid; then + kill -TERM $pids > /dev/null 2>&1 || true + wait $pids + return 0 + fi + fi + done + sleep 0.1 + done + return 1 +} + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -54,6 +85,12 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if internet; then + msg_ok "Internet Online" +else + echo -e "${BFR} {CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 26bbfdee8b159eafb2736d860c5cde4d07180713 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 05:52:51 -0400 Subject: [PATCH 2896/6505] Update debian-install.sh --- setup/debian-install.sh | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 9c9476f8..a4cd2825 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -28,37 +28,6 @@ function error_exit() { exit $EXIT } -function internet() { - test_urls="\ - https://www.google.com/ \ - https://www.microsoft.com/ \ - https://www.cloudflare.com/ \ - " - processes="0" - pids="" - for test_url in $test_urls; do - curl --silent --head "$test_url" > /dev/null & - pids="$pids $!" - processes=$(($processes + 1)) - done - while [ $processes -gt 0 ]; do - for pid in $pids; do - if ! ps | grep "^[[:blank:]]*$pid[[:blank:]]" > /dev/null; then - processes=$(($processes - 1)) - pids=$(echo "$pids" | sed --regexp-extended "s/(^| )$pid($| )/ /g") - - if wait $pid; then - kill -TERM $pids > /dev/null 2>&1 || true - wait $pids - return 0 - fi - fi - done - sleep 0.1 - done - return 1 -} - function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -85,10 +54,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if internet; then +if : >/dev/tcp/8.8.8.8/53; then msg_ok "Internet Online" else - echo -e "${BFR} {CROSS}${RD} Internet Offline" + echo -e "${BFR} ${CROSS}${RD} Internet Offline" fi msg_info "Updating Container OS" From f8010a3fdfc205677ef011c363ae9a4329ea4dcf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 05:56:57 -0400 Subject: [PATCH 2897/6505] Update debian-install.sh --- setup/debian-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index a4cd2825..665613d6 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -42,7 +42,7 @@ msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] From dbe0eb3fd520d0e130217488a9026097e1ff06ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:11:08 -0400 Subject: [PATCH 2898/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 040af0b1..7b20a0a0 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -107,12 +107,9 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type 20.04, or Press [ENTER] for Default: 21.10" + echo -e "${YW}Type 18.04 20.04 21.10 22.04 or Press [ENTER] for Default: 21.10" read VER - if [ -z $VER ]; then VER="21.10"; - else - VER="20.04" - fi + if [ -z $VER ]; then VER="21.10"; fi; echo -en "${DGN}Set Version To ${BL}$VER${CL}" echo -e " ${CM}${CL} \r" sleep 1 From db239bc358d14e77ff68400764055b673c335808 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:20:31 -0400 Subject: [PATCH 2899/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1ff4ace7..e4945b8a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-05 + +### Changed + +- **Ubuntu LXC** + - ADD option to define version (18.04 20.04 21.10 22.04). + ## 2022-04-28 ### Changed From fb943917dc84c2bbfe654a77ae1dc7b0469ada55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:27:09 -0400 Subject: [PATCH 2900/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 07d7915c..6a99a046 100644 --- a/README.md +++ b/README.md @@ -920,12 +920,12 @@ ________________________________________________________________________________
    - Ubuntu LXC + 🔸Ubuntu LXC

    Ubuntu

    Ubuntu LXC

    -

    Option to select 20.04 or 21.10

    +

    Option to define version 18.04, 20.04, 21.10 or 22.04

    To create a new Proxmox Ubuntu (curl. sudo) LXC, run the following in the Proxmox Shell. From cbe6796f6b32138510ffe7c838d9851957765f52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:38:10 -0400 Subject: [PATCH 2901/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 7b20a0a0..396abc13 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -77,8 +77,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using Version ${BGN}21.10${CL}" - VER="21.10" + echo -e "${DGN}Using Version ${BGN}22.04${CL}" + VER="22.04" echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" @@ -107,9 +107,9 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type 18.04 20.04 21.10 22.04 or Press [ENTER] for Default: 21.10" + echo -e "${YW}Type 18.04, 20.04, 21.10 or Press [ENTER] for Default: 22.04" read VER - if [ -z $VER ]; then VER="21.10"; fi; + if [ -z $VER ]; then VER="22.04"; fi; echo -en "${DGN}Set Version To ${BL}$VER${CL}" echo -e " ${CM}${CL} \r" sleep 1 From c59988e25e636f8ba5f4165ff2cc710c949d8daa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:42:36 -0400 Subject: [PATCH 2902/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a99a046..a93574d7 100644 --- a/README.md +++ b/README.md @@ -933,7 +933,7 @@ To create a new Proxmox Ubuntu (curl. sudo) LXC, run the following in the Proxmo bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh)" ``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 21.10⚡

    +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04⚡

    ⚙️ **To Update Ubuntu 20.04/21.10** From 4cd3f9cedf9b585189d04cfe5510059f5206973c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:43:34 -0400 Subject: [PATCH 2903/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a93574d7..6b5cfb96 100644 --- a/README.md +++ b/README.md @@ -935,7 +935,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04⚡

    -⚙️ **To Update Ubuntu 20.04/21.10** +⚙️ **To Update Ubuntu** Run in the LXC console ```yaml From e31f4047bf811102541dcc8d53451f09b4eb0f09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:48:31 -0400 Subject: [PATCH 2904/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b5cfb96..2bdf38ba 100644 --- a/README.md +++ b/README.md @@ -933,7 +933,7 @@ To create a new Proxmox Ubuntu (curl. sudo) LXC, run the following in the Proxmo bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh)" ``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04⚡

    +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04 ⚡

    ⚙️ **To Update Ubuntu** From 74592c19ebf6ecd9787da25986fa2388382ec460 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 May 2022 10:54:09 -0400 Subject: [PATCH 2905/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2bdf38ba..604e490f 100644 --- a/README.md +++ b/README.md @@ -953,6 +953,8 @@ ________________________________________________________________________________

    UniFi Network Application LXC

    +

    With Local Controller Option

    + An application designed to optimize UniFi home and business networks with ease. To create a new Proxmox UniFi Network Application LXC, run the following in the Proxmox Shell. From 5477cc60b0627508c552e6f147d97d58bbe5f60b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 May 2022 06:23:05 -0400 Subject: [PATCH 2906/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 24d90dc1..474d0f54 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -54,6 +54,12 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if : >/dev/tcp/8.8.8.8/53; then + msg_ok "Internet Online" +else + echo -e "${BFR} ${CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 52ceb89569896e6064986d501cef52809fcc9b8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 May 2022 06:24:06 -0400 Subject: [PATCH 2907/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index bc311688..854317a0 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -54,6 +54,12 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if : >/dev/tcp/8.8.8.8/53; then + msg_ok "Internet Online" +else + echo -e "${BFR} ${CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From a385125fbd61a76be9097de479c42fbb09d09251 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 May 2022 17:33:49 -0400 Subject: [PATCH 2908/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 474d0f54..62479898 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -42,12 +42,12 @@ msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -89,6 +89,14 @@ msg_info "Installing Golang" wget https://golang.org/dl/go1.18.linux-amd64.tar.gz &>/dev/null tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null +go install github.com/tianon/gosu@latest &>/dev/null +go install golang.org/x/tools/cmd/goimports@latest &>/dev/null +go install github.com/psampaz/go-mod-outdated@latest &>/dev/null +go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest &>/dev/null +go install github.com/mikefarah/yq/v4@latest &>/dev/null +go install github.com/kyoh86/richgo@latest &>/dev/null +cp /root/go/bin/* /usr/local/go/bin/ +cp /root/go/bin/* /usr/local/bin/ msg_ok "Installed Golang" msg_info "Installing Tensorflow" @@ -99,7 +107,7 @@ msg_ok "Installed Tensorflow" msg_info "Cloning PhotoPrism" mkdir -p /opt/photoprism/bin -mkdir /var/lib/photoprism +mkdir -p /var/lib/photoprism/storage git clone https://github.com/photoprism/photoprism.git &>/dev/null cd photoprism git checkout release &>/dev/null @@ -114,7 +122,9 @@ msg_ok "Built PhotoPrism" env_path="/var/lib/photoprism/.env" echo " PHOTOPRISM_ADMIN_PASSWORD='admin' -PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism' +PHOTOPRISM_HTTP_HOST='0.0.0.0' +PHOTOPRISM_HTTP_PORT=2342 +PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' " > $env_path @@ -160,5 +170,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/go msg_ok "Cleaned" From 290a095da61b6e786190c587b0571b9d45791707 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 May 2022 18:23:48 -0400 Subject: [PATCH 2909/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e4945b8a..cf204284 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-06 + +### Changed + +- **Photoprism LXC** + - ADD GO Dependencies for full functionality. + ## 2022-05-05 ### Changed From d5c8d78303eae4066a71dc82efebbea87d06bf98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 May 2022 18:24:57 -0400 Subject: [PATCH 2910/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 604e490f..8248c056 100644 --- a/README.md +++ b/README.md @@ -1277,7 +1277,7 @@ ________________________________________________________________________________
    - PhotoPrism LXC + 🔸PhotoPrism LXC

    From 1a237ffb2bc13b46c1d4d2c3ceaa771a107e194d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 May 2022 18:25:16 -0400 Subject: [PATCH 2911/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index cf204284..13c4a421 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **Photoprism LXC** +- **PhotoPrism LXC** - ADD GO Dependencies for full functionality. ## 2022-05-05 From a9e7547510a0e1c1b6d61956c6bd0cf33719a21d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 07:01:17 -0400 Subject: [PATCH 2912/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 82c1e86b..7e3e8107 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -336,9 +336,9 @@ lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create= lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF -echo -en "${GN} Starting LXC Container... " +msg_info "Starting LXC Container" pct start $CTID -echo -e "${CM}${CL} \r" +msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zwavejs2mqtt-install.sh)" || exit From 284729b5012dfb8748870a7779ec73d5011d0a7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 07:24:08 -0400 Subject: [PATCH 2913/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 62479898..710b599d 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -100,9 +101,17 @@ cp /root/go/bin/* /usr/local/bin/ msg_ok "Installed Golang" msg_info "Installing Tensorflow" +if [[ "$AVX" == "avx2" ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + elif [[ "$AVX" == "avx" ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + elif [[ "$AVX" == " " ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null - ldconfig &>/dev/null +fi +ldconfig &>/dev/null msg_ok "Installed Tensorflow" msg_info "Cloning PhotoPrism" From 8840fabc1f67aca7d41deed0daf1274c8fe1835f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 09:01:29 -0400 Subject: [PATCH 2914/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 710b599d..2375721a 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -123,7 +123,7 @@ git checkout release &>/dev/null msg_ok "Cloned PhotoPrism" msg_info "Building PhotoPrism" -make all &>/dev/null +NODE_OPTIONS=--max_old_space_size=2048 make all &>/dev/null ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null cp -a assets/ /opt/photoprism/assets/ &>/dev/null msg_ok "Built PhotoPrism" From 28a714a4f70823c533fb5e40a375eafe85fd588e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 11:36:44 -0400 Subject: [PATCH 2915/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 2375721a..1c699738 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -100,14 +100,29 @@ cp /root/go/bin/* /usr/local/go/bin/ cp /root/go/bin/* /usr/local/bin/ msg_ok "Installed Golang" +read -p "Check For Advanced Vector Extensions? " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + check=yes +else + check=no +fi + msg_info "Installing Tensorflow" -if [[ "$AVX" == "avx2" ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - elif [[ "$AVX" == "avx" ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - elif [[ "$AVX" == " " ]]; then +if [ "$check" == "yes" ]; then + if [[ "$AVX" == "avx2" ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + elif [[ "$AVX" == "avx" ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + elif [[ "$AVX" == " " ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null + fi +fi +if [ "$check" == "no" ]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null fi From 8b14a3353a913aab44461ef648b904575947121a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 12:37:35 -0400 Subject: [PATCH 2916/6505] Create nocodb-update.sh --- misc/nocodb-update.sh | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 misc/nocodb-update.sh diff --git a/misc/nocodb-update.sh b/misc/nocodb-update.sh new file mode 100644 index 00000000..9a4e0399 --- /dev/null +++ b/misc/nocodb-update.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="NocoDB" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +while true; do + read -p "This will Update ${APP}. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _ _____ ____ + | \ | | | __ \| _ \ + | \| | ___ v3___ ___ | | | | |_) | + | |/ _ \ / __/ _ \| | | | _ < + | |\ | (_) | (_| (_) | |__| | |_) | + |_| \_|\___/ \___\___/|_____/|____/ + UPDATE +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Updating ${APP}" +cd /opt/nocodb +npm uninstall -s --save nocodb &>/dev/null +npm install -s --save nocodb &>/dev/null +msg_ok "Updated ${APP}" + +read -p "${APP} LXC needs to reboot to apply the update. Reboot now? " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + reboot=yes +else + reboot=no +fi + +if [ "$reboot" == "yes" ]; then +msg_info "Rebooting ${APP} LXC" +reboot +fi + +if [ "$reboot" == "no" ]; then +msg_ok "Finished Updating ${APP}. Reboot to apply the update." +fi From 0788d07359d0bda56c462f10dff88d84a8b41d72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 13:11:39 -0400 Subject: [PATCH 2917/6505] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8248c056..594c79b8 100644 --- a/README.md +++ b/README.md @@ -755,7 +755,7 @@ ________________________________________________________________________________
    - NocoDB LXC + 🔸NocoDB LXC

    @@ -773,11 +773,11 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v3.sh **NocoDB Interface - IP:8080/dashboard** -⚙️ **To Update** - +⚙️ **To Update NocoDB** +Run in the LXC console ```yaml -Working on +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/nocodb-update.sh)" ``` ____________________________________________________________________________________________ From 0c3e0777fa4526548178147887dda2732d4e9159 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 13:13:30 -0400 Subject: [PATCH 2918/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 13c4a421..91c29c3d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-07 + +### Changed + +- **NocoDB LXC** + - ADD update script. + ## 2022-05-06 ### Changed From 81d957999b52e5b5ab721dd7a6e375c18ab02ca7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 16:48:26 -0400 Subject: [PATCH 2919/6505] Update omada-install.sh --- setup/omada-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index c3a4aa42..0423e373 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -70,8 +70,8 @@ sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller" -wget -qL https://static.tp-link.com/upload/software/2022/202203/20220322/Omada_SDN_Controller_v5.1.7_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.1.7_Linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202205/20220507/Omada_SDN_Controller_v5.3.1_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.3.1_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From ef710165a7dce8ac520a80c03e955e18501ca49c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 May 2022 19:38:55 -0400 Subject: [PATCH 2920/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 1c699738..60fe201a 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -87,8 +87,8 @@ apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Golang" -wget https://golang.org/dl/go1.18.linux-amd64.tar.gz &>/dev/null -tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz &>/dev/null +wget https://golang.org/dl/go1.18.1.linux-amd64.tar.gz &>/dev/null +tar -xzf go1.18.1.linux-amd64.tar.gz -C /usr/local &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null go install github.com/tianon/gosu@latest &>/dev/null go install golang.org/x/tools/cmd/goimports@latest &>/dev/null @@ -97,7 +97,10 @@ go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest &>/dev/nu go install github.com/mikefarah/yq/v4@latest &>/dev/null go install github.com/kyoh86/richgo@latest &>/dev/null cp /root/go/bin/* /usr/local/go/bin/ -cp /root/go/bin/* /usr/local/bin/ +cp /usr/local/go/bin/richgo /usr/local/bin/richgo +cp /usr/local/go/bin/gosu /usr/local/sbin/gosu +chown root:root /usr/local/sbin/gosu +chmod 755 /usr/local/sbin/gosu msg_ok "Installed Golang" read -p "Check For Advanced Vector Extensions? " -n 1 -r @@ -194,5 +197,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/go +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" From 68830d02e3685dbcc1fd542bbda2e9d69e189e6a Mon Sep 17 00:00:00 2001 From: aurelpec <105117622+aurelpec@users.noreply.github.com> Date: Sun, 8 May 2022 09:52:44 +0200 Subject: [PATCH 2921/6505] Update photoprism-install.sh Use regex to determine if CPU has avx capabilities If no avx capabilities detected swith to cpu tensorflow automatically --- setup/photoprism-install.sh | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 60fe201a..17c9a601 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -103,29 +103,14 @@ chown root:root /usr/local/sbin/gosu chmod 755 /usr/local/sbin/gosu msg_ok "Installed Golang" -read -p "Check For Advanced Vector Extensions? " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - check=yes -else - check=no -fi - msg_info "Installing Tensorflow" -if [ "$check" == "yes" ]; then - if [[ "$AVX" == "avx2" ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - elif [[ "$AVX" == "avx" ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - elif [[ "$AVX" == " " ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null - fi -fi -if [ "$check" == "no" ]; then +if [[ "$AVX" =~ avx2 ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null + elif [[ "$AVX" =~ avx ]]; then + wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null + else wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null fi From 2f108cf705537fa46d697ac59cb3bf61883e92b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 07:53:04 -0400 Subject: [PATCH 2922/6505] Create deconz.sh --- ct/deconz.sh | 352 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 ct/deconz.sh diff --git a/ct/deconz.sh b/ct/deconz.sh new file mode 100644 index 00000000..cf4eea6c --- /dev/null +++ b/ct/deconz.sh @@ -0,0 +1,352 @@ +#!/usr/bin/env bash +APP="deConz" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="ubuntu" +var_version="20.04" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _____ + | | / ____| + __| | v3_| | ___ _ __ ____ + / _ |/ _ \ | / _ \| _ \|_ / + | (_| | __/ |___| (_) | | | |/ / + \__,_|\___|\_____\___/|_| |_/___| +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" From 6c68d6dc5aa2994ec68fc43549b127d51149f98f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:11:36 -0400 Subject: [PATCH 2923/6505] Create deconz-install.sh --- setup/deconz-install.sh | 124 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 setup/deconz-install.sh diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh new file mode 100644 index 00000000..34d10b60 --- /dev/null +++ b/setup/deconz-install.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if : >/dev/tcp/8.8.8.8/53; then + msg_ok "Internet Online" +else + echo -e "${BFR} ${CROSS}${RD} Internet Offline" +fi + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting Phoscon Repository" +wget -q http://phoscon.de/apt/deconz.pub.key -O - | sudo apt-key add - +sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" +msg_ok "Setup Phoscon Repository" + +msg_info "Installing deConz" +apt-get update +apt install deconz +msg_ok "Installed deConz" + +msg_info "Creating Service" +service_path="/lib/systemd/system/deconz.service" +echo "[Unit] +Description=deCONZ: ZigBee gateway -- REST API +Wants=deconz-init.service deconz-update.service +StartLimitIntervalSec=0 + +[Service] +User=root +ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80 +Restart=on-failure +RestartSec=30 +AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl start deconz +systemctl enable deconz &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 91b8409ad6205ddc008acfeafc615395f3daa562 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:12:04 -0400 Subject: [PATCH 2924/6505] Rename deconz.sh to deconz-v3.sh --- ct/{deconz.sh => deconz-v3.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{deconz.sh => deconz-v3.sh} (100%) diff --git a/ct/deconz.sh b/ct/deconz-v3.sh similarity index 100% rename from ct/deconz.sh rename to ct/deconz-v3.sh From 7523639af1b28f9dadf2cfc395a92b791352ca93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:18:50 -0400 Subject: [PATCH 2925/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index cf4eea6c..fe5a7497 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -83,8 +83,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" @@ -111,14 +111,14 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Privileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 @@ -341,6 +341,18 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF + msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From ed6a25180b532f7c09a158005560385c00790dea Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:22:06 -0400 Subject: [PATCH 2926/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index fe5a7497..f882fdf7 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -111,7 +111,7 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Privileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" From 5d67940c59d5b34de0ef7158e13cc7bb2b582a7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:35:26 -0400 Subject: [PATCH 2927/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index f882fdf7..4726606a 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -4,7 +4,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="ubuntu" -var_version="20.04" +var_version="22.04" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' NSAPP=$(echo ${APP,,} | tr -d ' ') From 79e38f3ab01968b3a500b3de17d43abf24c369a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:36:23 -0400 Subject: [PATCH 2928/6505] Update deconz-install.sh --- setup/deconz-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index 34d10b60..398e181d 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -68,6 +68,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting Phoscon Repository" From d03c84e5b60b5ed1d384069a1b327075201bd15d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:41:31 -0400 Subject: [PATCH 2929/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index 4726606a..f882fdf7 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -4,7 +4,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="ubuntu" -var_version="22.04" +var_version="20.04" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' NSAPP=$(echo ${APP,,} | tr -d ' ') From ba9c020f698feaff107fdb41c6f0175110908951 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 08:56:50 -0400 Subject: [PATCH 2930/6505] Update deconz-install.sh --- setup/deconz-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index 398e181d..a0fbe4b5 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -72,13 +72,13 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting Phoscon Repository" -wget -q http://phoscon.de/apt/deconz.pub.key -O - | sudo apt-key add - -sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" +wget -q http://phoscon.de/apt/deconz.pub.key -O - | sudo apt-key add - &>/dev/null +sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" &>/dev/null msg_ok "Setup Phoscon Repository" msg_info "Installing deConz" -apt-get update -apt install deconz +apt-get update &>/dev/null +apt-get install -y deconz &>/dev/null msg_ok "Installed deConz" msg_info "Creating Service" From 7a98140305166bcd907eb41935d704ad5dd2a459 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 09:10:45 -0400 Subject: [PATCH 2931/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index f882fdf7..c404d128 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -362,3 +362,5 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From 2e74656737d9791674753c1bdb0929e461d385f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 09:29:55 -0400 Subject: [PATCH 2932/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index c404d128..96593fc3 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash APP="deConz" -var_disk="2" -var_cpu="1" -var_ram="512" +var_disk="4" +var_cpu="2" +var_ram="1024" var_os="ubuntu" var_version="20.04" NEXTID=$(pvesh get /cluster/nextid) From 66c39d172bcd891893615bdfa03006ccc6c0799a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 09:45:31 -0400 Subject: [PATCH 2933/6505] Update README.md --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 594c79b8..d5c00377 100644 --- a/README.md +++ b/README.md @@ -721,6 +721,33 @@ ________________________________________________________________________________
    +
    + 🔸deConz LXC + +

    + +

    deConz LXC

    + +To create a new Proxmox deConz LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/deconz-v3.sh)" +``` +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +**deConz Interface - IP:80** + +⚙️ **To Update deConz** + +Run in the LXC Console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    +
    Zwavejs2MQTT LXC From 5b76e1fc8fea20c8d811b6c80e2d9a536fe413dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 09:47:01 -0400 Subject: [PATCH 2934/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 91c29c3d..6b3fc460 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-10 + +### Changed + +- **deConz LXC** + - NEW Script. + ## 2022-05-07 ### Changed From e036b10ed1d57503c513df69fee00a15a99964fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 09:58:13 -0400 Subject: [PATCH 2935/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index 96593fc3..8667d0ac 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -APP="deConz" +APP="deCONZ" var_disk="4" var_cpu="2" var_ram="1024" From aa924f296dcbe97f0ac1c82780f1f99a6b19b9e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 10:00:26 -0400 Subject: [PATCH 2936/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d5c00377..d171456e 100644 --- a/README.md +++ b/README.md @@ -722,22 +722,22 @@ ________________________________________________________________________________
    - 🔸deConz LXC + 🔸deCONZ LXC

    -

    deConz LXC

    +

    deCONZ LXC

    -To create a new Proxmox deConz LXC, run the following in the Proxmox Shell. +To create a new Proxmox deCONZ LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/deconz-v3.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    -**deConz Interface - IP:80** +**deCONZ Interface - IP:80** -⚙️ **To Update deConz** +⚙️ **To Update deCONZ** Run in the LXC Console ```yaml From 8ad08591ccbf62af33073c7724bc78b8c1f00c03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 May 2022 10:01:57 -0400 Subject: [PATCH 2937/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6b3fc460..acad408e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **deConz LXC** +- **deCONZ LXC** - NEW Script. ## 2022-05-07 From 6a69b6662fcf6bbeda0ffab4ccbd321ec21ef6be Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 May 2022 10:29:14 -0400 Subject: [PATCH 2938/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 5b2a9a4f..a7f2cf3a 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="7.6" +STABLE="8.0" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From aa98bf9e1147a7acf76bc447adc19669c5aa0ef1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 May 2022 10:29:39 -0400 Subject: [PATCH 2939/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 2ea4c203..4c3a88e4 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="7.6" +STABLE="8.0" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From 917c650ff5a9c81016d19a8e14cc39964a376f60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 May 2022 11:01:26 -0400 Subject: [PATCH 2940/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d171456e..ca596d8b 100644 --- a/README.md +++ b/README.md @@ -947,7 +947,7 @@ ________________________________________________________________________________
    - 🔸Ubuntu LXC + Ubuntu LXC

    Ubuntu

    From 2a9b48b2d5fef22d553ae0a65d4e57f98ad9be09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 May 2022 17:21:31 -0400 Subject: [PATCH 2941/6505] Update zwavejs2mqtt-update.sh --- misc/zwavejs2mqtt-update.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/misc/zwavejs2mqtt-update.sh b/misc/zwavejs2mqtt-update.sh index f5654ba1..f72db32a 100644 --- a/misc/zwavejs2mqtt-update.sh +++ b/misc/zwavejs2mqtt-update.sh @@ -5,6 +5,22 @@ BL=`echo "\033[36m"` CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} echo -en "${GN} Updating Zwavejs2MQTT... " systemctl stop zwavejs2mqtt.service From 865947b8babdbab9a944de133bcac9669a30b7c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 May 2022 17:34:37 -0400 Subject: [PATCH 2942/6505] Update zwavejs2mqtt-update.sh --- misc/zwavejs2mqtt-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/zwavejs2mqtt-update.sh b/misc/zwavejs2mqtt-update.sh index f72db32a..cf02af01 100644 --- a/misc/zwavejs2mqtt-update.sh +++ b/misc/zwavejs2mqtt-update.sh @@ -26,7 +26,7 @@ echo -en "${GN} Updating Zwavejs2MQTT... " systemctl stop zwavejs2mqtt.service cd /opt/zwavejs2mqtt curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null -unzip -u zwavejs2mqtt-v*.zip zwavejs2mqtt &>/dev/null +unzip -o zwavejs2mqtt-v*.zip zwavejs2mqtt &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Checking Service... " From f806087ec9b2de4b01715b60020466f7abf06fde Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 May 2022 18:24:05 -0400 Subject: [PATCH 2943/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca596d8b..b289aecb 100644 --- a/README.md +++ b/README.md @@ -1304,7 +1304,7 @@ ________________________________________________________________________________
    - 🔸PhotoPrism LXC + PhotoPrism LXC

    From 6d5309486c02726be64a16844e9be39da12855b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 14:08:18 -0400 Subject: [PATCH 2944/6505] Create postgresql-install.sh --- setup/postgresql-install.sh | 104 ++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 setup/postgresql-install.sh diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh new file mode 100644 index 00000000..7acc0daa --- /dev/null +++ b/setup/postgresql-install.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if : >/dev/tcp/8.8.8.8/53; then + msg_ok "Internet Online" +else + echo -e "${BFR} ${CROSS}${RD} Internet Offline" +fi + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing PostgreSQL" +apt-get install -y postgresql postgresql-contrib &>/dev/null +msg_ok "Installed PostgreSQL" + +msg_info "Installing Adminer" +sudo apt install adminer -y &>/dev/null +sudo a2enconf adminer &>/dev/null +sudo systemctl reload apache2 &>/dev/null +msg_ok "Installed Adminer" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From e42c098cc381d1ad9f44a241b5eb08295f88240c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 14:11:31 -0400 Subject: [PATCH 2945/6505] Create postgresql-v3.sh --- ct/postgresql-v3.sh | 356 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 ct/postgresql-v3.sh diff --git a/ct/postgresql-v3.sh b/ct/postgresql-v3.sh new file mode 100644 index 00000000..6c26d8b4 --- /dev/null +++ b/ct/postgresql-v3.sh @@ -0,0 +1,356 @@ +#!/usr/bin/env bash +APP="PostgreSQL" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _____ _ _____ ____ _ + | __ \ | | / ____|/ __ \| | + | |__) |__ ___| |_ __ _ _ __ ___| (___ | | | | | + | ___/ _ \/ __| __/ _ | __/ _ \\___ \| | | | | + | | | (_) \__ \ || (_| | | | __/____) | |__| | |____ + |_| \___/|___/\__\__, |_| \___|_____/ \___\_\______| + __/ | + v3|___/ +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "Adminer should be reachable by going to the following URL. + ${BL}http://${IP}/adminer/${CL} \n" From d717eb078528f55a0fd8a2f7fb95602ae30b71cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 15:23:06 -0400 Subject: [PATCH 2946/6505] Update README.md --- README.md | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/README.md b/README.md index b289aecb..5f4233f7 100644 --- a/README.md +++ b/README.md @@ -640,6 +640,112 @@ ________________________________________________________________________________
    +
    + 🔸PostgreSQL LXC + +

    + +

    PostgreSQL LXC

    + +To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v3.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +To enable PostgreSQL to listen to remote connections, you need to edit your defaults file. To do this, open the console in your PostgreSQL LXC +```yaml +nano /etc/postgresql/13/main/postgresql.conf +``` +Un-comment `listen_addresses` and replace localhost with * sign to allow all Ip-address to connect to the Database server. +``` +listen_addresses = '*' # what IP address(es) to listen on; +``` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". + +```yaml +nano /etc/postgresql/13/main/pg_hba.conf +``` +Change values to match as shown below +``` +# Database administrative login by Unix domain socket +local all postgres md5 + +# TYPE DATABASE USER ADDRESS METHOD + +# "local" is for Unix domain socket connections only +local all all md5 +# IPv4 local connections: +host all all 0.0.0.0/0 md5 +# IPv6 local connections: +host all all ::0/0 md5 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 md5 +host replication all ::1/128 md5 +``` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". + +Restart the Database server to apply the changes: +``` +sudo systemctl restart postgresql +``` + +To make sure our PostgreSQL is secured with a strong password, set a password for its system user and then change the default database admin user account + +Change user password +```yaml +passwd postgres +``` +Login using Postgres system account + +``` +su - postgres +``` +Now, change the Admin database password +``` +psql -c "ALTER USER postgres WITH PASSWORD 'your-password';" +``` +Create a new user. +```yaml +psql +``` +```yaml +CREATE USER admin WITH PASSWORD 'your-password'; +``` +Create a new database: +```yaml +CREATE DATABASE homeassistant; +``` +Grant all rights or privileges on created database to the user +```yaml +GRANT ALL ON DATABASE homeassistant TO admin; +``` +To check that the database has been created +```yaml +\l +``` +Change the recorder: `db_url:` in your HA configuration.yaml + +Example: `db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8` + +⚙️ **To Update PostgreSQL** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` +⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool + + `http://your-PostgreSQL-lxc-ip/adminer/` + +____________________________________________________________________________________________ + +
    +
    Zigbee2MQTT LXC From 58cc004652afed27af88714e5c92ff43f562bfd6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 15:24:59 -0400 Subject: [PATCH 2947/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index acad408e..4bde0ea0 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-13 + +### Changed + +- **PostgreSQL LXC** + - NEW Script. + ## 2022-05-10 ### Changed From 9c1c702a9c9f18011b700068fd0411c3bf6218c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 15:52:44 -0400 Subject: [PATCH 2948/6505] Update postgresql-install.sh --- setup/postgresql-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 7acc0daa..41f7489e 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -101,4 +101,6 @@ msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +mkdir /var/log/apache2 +chmod 750 /var/log/apache2 msg_ok "Cleaned" From 05cb5312b435e2fa0c36044d3b26191778ecba2b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 18:39:39 -0400 Subject: [PATCH 2949/6505] Update README.md --- README.md | 105 ------------------------------------------------------ 1 file changed, 105 deletions(-) diff --git a/README.md b/README.md index 5f4233f7..842d55be 100644 --- a/README.md +++ b/README.md @@ -640,111 +640,6 @@ ________________________________________________________________________________
    -
    - 🔸PostgreSQL LXC - -

    - -

    PostgreSQL LXC

    - -To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v3.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -To enable PostgreSQL to listen to remote connections, you need to edit your defaults file. To do this, open the console in your PostgreSQL LXC -```yaml -nano /etc/postgresql/13/main/postgresql.conf -``` -Un-comment `listen_addresses` and replace localhost with * sign to allow all Ip-address to connect to the Database server. -``` -listen_addresses = '*' # what IP address(es) to listen on; -``` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". - -```yaml -nano /etc/postgresql/13/main/pg_hba.conf -``` -Change values to match as shown below -``` -# Database administrative login by Unix domain socket -local all postgres md5 - -# TYPE DATABASE USER ADDRESS METHOD - -# "local" is for Unix domain socket connections only -local all all md5 -# IPv4 local connections: -host all all 0.0.0.0/0 md5 -# IPv6 local connections: -host all all ::0/0 md5 -# Allow replication connections from localhost, by a user with the -# replication privilege. -local replication all peer -host replication all 127.0.0.1/32 md5 -host replication all ::1/128 md5 -``` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". - -Restart the Database server to apply the changes: -``` -sudo systemctl restart postgresql -``` - -To make sure our PostgreSQL is secured with a strong password, set a password for its system user and then change the default database admin user account - -Change user password -```yaml -passwd postgres -``` -Login using Postgres system account - -``` -su - postgres -``` -Now, change the Admin database password -``` -psql -c "ALTER USER postgres WITH PASSWORD 'your-password';" -``` -Create a new user. -```yaml -psql -``` -```yaml -CREATE USER admin WITH PASSWORD 'your-password'; -``` -Create a new database: -```yaml -CREATE DATABASE homeassistant; -``` -Grant all rights or privileges on created database to the user -```yaml -GRANT ALL ON DATABASE homeassistant TO admin; -``` -To check that the database has been created -```yaml -\l -``` -Change the recorder: `db_url:` in your HA configuration.yaml - -Example: `db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8` - -⚙️ **To Update PostgreSQL** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool - - `http://your-PostgreSQL-lxc-ip/adminer/` - -____________________________________________________________________________________________ - -
    Zigbee2MQTT LXC From 1d2f0f0652c3b065933e2cac287628e997b2e774 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 18:40:48 -0400 Subject: [PATCH 2950/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4bde0ea0..acad408e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,13 +5,6 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) -## 2022-05-13 - -### Changed - -- **PostgreSQL LXC** - - NEW Script. - ## 2022-05-10 ### Changed From 74e4b3405e869a1f935d4893b0fce017c4fbe05b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 19:27:49 -0400 Subject: [PATCH 2951/6505] Update postgresql-install.sh --- setup/postgresql-install.sh | 896 +++++++++++++++++++++++++++++++++++- 1 file changed, 895 insertions(+), 1 deletion(-) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 41f7489e..c90e7867 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -68,12 +68,906 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y gnupg2 &>/dev/null +apt-get install -y lsb-release &>/dev/null msg_ok "Installed Dependencies" +msg_info "Setting up PostgreSQL Repository" +sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' &>/dev/null +wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - &>/dev/null +msg_ok "Setup PostgreSQL Repository" + msg_info "Installing PostgreSQL" -apt-get install -y postgresql postgresql-contrib &>/dev/null +apt-get update &>/dev/null +apt-get install -y postgresql &>/dev/null msg_ok "Installed PostgreSQL" +cat < /etc/postgresql/14/main/pg_hba.conf +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: "local" is a Unix-domain +# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, +# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a +# non-SSL TCP/IP socket. Similarly, "hostgssenc" uses a +# GSSAPI-encrypted TCP/IP socket, while "hostnogssenc" uses a +# non-GSSAPI socket. +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + + + + +# DO NOT DISABLE! +# If you change this first entry you will need to make sure that the +# database superuser can access the database using some other method. +# Noninteractive access to all databases is required during automatic +# maintenance (custom daily cronjobs, replication, and similar tasks). +# +# Database administrative login by Unix domain socket +local all postgres trust +# TYPE DATABASE USER ADDRESS METHOD + +# "local" is for Unix domain socket connections only +local all all trust +# IPv4 local connections: +host all all 127.0.0.1/32 scram-sha-256 +host all all 0.0.0.0/24 md5 +# IPv6 local connections: +host all all ::1/128 scram-sha-256 +host all all 0.0.0.0/0 md5 +EOF + +cat < /etc/postgresql/14/main/postgresql.conf +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, run "pg_ctl reload", or execute +# "SELECT pg_reload_conf()". Some parameters, which are marked below, +# require a server shutdown and restart to take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: B = bytes Time units: us = microseconds +# kB = kilobytes ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +data_directory = '/var/lib/postgresql/14/main' # use data in another directory + # (change requires restart) +hba_file = '/etc/postgresql/14/main/pg_hba.conf' # host-based authentication file + # (change requires restart) +ident_file = '/etc/postgresql/14/main/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +external_pid_file = '/var/run/postgresql/14-main.pid' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '*' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +port = 5432 # (change requires restart) +max_connections = 100 # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - TCP settings - +# see "man tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default +#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; + # 0 selects the system default + +# - Authentication - + +#authentication_timeout = 1min # 1s-600s +#password_encryption = md5 # md5 or scram-sha-256 +#db_user_namespace = off + +# GSSAPI using Kerberos +#krb_caseins_users = off + +# - SSL - + +#ssl = on +#ssl_ca_file = '' +#ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' +#ssl_crl_file = '' +#ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers +#ssl_prefer_server_ciphers = on +#ssl_ecdh_curve = 'prime256v1' +#ssl_min_protocol_version = 'TLSv1.2' +#ssl_max_protocol_version = '' +#ssl_dh_params_file = '' +#ssl_passphrase_command = '' +#ssl_passphrase_command_supports_reload = off + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +shared_buffers = 128MB # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +#hash_mem_multiplier = 1.0 # 1-1000.0 multiplier on hash table work_mem +#maintenance_work_mem = 64MB # min 1MB +#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem +#logical_decoding_work_mem = 64MB # min 64kB +#max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) +dynamic_shared_memory_type = posix # the default is the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # (change requires restart) + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kilobytes, or -1 for no limit + +# - Kernel Resources - + +#max_files_per_process = 1000 # min 64 + # (change requires restart) + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 10 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 512kB # measured in pages, 0 disables + +# - Asynchronous Behavior - + +#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching +#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching +#max_worker_processes = 8 # (change requires restart) +#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers +#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers +#parallel_leader_participation = on +#max_parallel_workers = 8 # maximum number of max_worker_processes that + # can be used in parallel operations +#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate + # (change requires restart) +#backend_flush_after = 0 # measured in pages, 0 disables + + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = replica # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux and FreeBSD) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_compression = off # enable compression of full-page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_init_zero = on # zero-fill new WAL files +#wal_recycle = on # recycle WAL files +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables +#wal_skip_threshold = 2MB + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +#checkpoint_timeout = 5min # range 30s-1d +max_wal_size = 1GB +min_wal_size = 80MB +#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_flush_after = 256kB # measured in pages, 0 disables +#checkpoint_warning = 30s # 0 disables + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_command = '' # command to use to archive a logfile segment + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a logfile segment switch after this + # number of seconds; 0 disables + +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived logfile segment + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' + # (change requires restart) +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +# Set these on the master and on any standby that will send replication data. + +#max_wal_senders = 10 # max number of walsender processes + # (change requires restart) +#wal_keep_size = 0 # in megabytes; 0 disables +#max_slot_wal_keep_size = -1 # in megabytes; -1 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables + +#max_replication_slots = 10 # max number of replication slots + # (change requires restart) +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Master Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # method to choose sync standbys, number of sync standbys, + # and comma-separated list of application_name + # from standby(s); '*' = all +#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed + +# - Standby Servers - + +# These settings are ignored on a master server. + +#primary_conninfo = '' # connection string to sending server +#primary_slot_name = '' # replication slot on sending server +#promote_trigger_file = '' # file name whose presence ends recovery +#hot_standby = on # "off" disallows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name + # is not set +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from master + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery + +# - Subscribers - + +# These settings are ignored on a publisher. + +#max_logical_replication_workers = 4 # taken from max_worker_processes + # (change requires restart) +#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_bitmapscan = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_parallel_append = on +#enable_seqscan = on +#enable_sort = on +#enable_incremental_sort = on +#enable_tidscan = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off +#enable_parallel_hash = on +#enable_partition_pruning = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#parallel_setup_cost = 1000.0 # same scale as above + +#jit_above_cost = 100000 # perform JIT compilation if available + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; + # -1 disables + +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB +#effective_cache_size = 4GB + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#force_parallel_mode = off +#jit = on # allow JIT compilation +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan + + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +#log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + +# This is used when logging to stderr: +#logging_collector = off # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +#log_directory = 'log' # directory where log files are written, + # can be absolute or relative to PGDATA +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + # can include strftime() escapes +#log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +#log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. +#log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +#log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (win32): +# (change requires restart) +#event_source = 'PostgreSQL' + +# - When to Log - + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + +#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements + # and their durations, > 0 logs only a sample of + # statements running at least this number + # of milliseconds; + # sample fraction is determined by log_statement_sample_rate + +#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding + # log_min_duration_sample to be logged; + # 1.0 logs all such statements, 0.0 never logs + + +#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements + # are logged regardless of their duration; 1.0 logs all + # statements from all transactions, 0.0 never logs + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_checkpoints = off +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +log_line_prefix = '%m [%p] %q%u@%d ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %b = backend type + # %p = process ID + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %n = timestamp with milliseconds (as a Unix epoch) + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +#log_lock_waits = off # log lock waits >= deadlock_timeout +#log_parameter_max_length = -1 # when logging statements, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_parameter_max_length_on_error = 0 # when logging an error, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_statement = 'none' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +log_timezone = 'Etc/UTC' + +#------------------------------------------------------------------------------ +# PROCESS TITLE +#------------------------------------------------------------------------------ + +cluster_name = '14/main' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +# - Query and Index Statistics Collector - + +#track_activities = on +#track_counts = on +#track_io_timing = off +#track_functions = none # none, pl, all +#track_activity_query_size = 1024 # (change requires restart) +stats_temp_directory = '/var/run/postgresql/14-main.pg_stat_tmp' + + +# - Monitoring - + +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off +#log_statement_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts + # before vacuum; -1 disables insert + # vacuums +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table + # size before insert vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error +#row_security = on +#default_tablespace = '' # a tablespace name, '' uses the default +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#default_table_access_method = 'heap' +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_min_age = 50000000 +#vacuum_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples + # before index cleanup, 0 always performs + # index cleanup +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_fuzzy_search_limit = 0 +#gin_pending_list_limit = 4MB + +# - Locale and Formatting - + +datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +timezone = 'Etc/UTC' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +lc_messages = 'C' # locale for system error message + # strings +lc_monetary = 'C' # locale for monetary formatting +lc_numeric = 'C' # locale for number formatting +lc_time = 'C' # locale for time formatting + +# default configuration for text search +default_text_search_config = 'pg_catalog.english' + +# - Shared Library Preloading - + +#shared_preload_libraries = '' # (change requires restart) +#local_preload_libraries = '' +#session_preload_libraries = '' +#jit_provider = 'llvmjit' # JIT library to use + +# - Other Defaults - + +#extension_destdir = '' # prepend path when loading extensions + # and shared objects (added by Debian) + + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_relation = -2 # negative values mean + # (max_pred_locks_per_transaction + # / -max_pred_locks_per_relation) - 1 +#max_pred_locks_per_page = 2 # min 0 + + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#operator_precedence_warning = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? +#data_sync_retry = off # retry or panic on failure to fsync + # data? + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. + +include_dir = 'conf.d' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here +EOF + +sudo systemctl restart postgresql + msg_info "Installing Adminer" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null From 908ccb36ed7508ddb8d7001a22de987d3f3f42c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 19:30:09 -0400 Subject: [PATCH 2952/6505] Update README.md --- README.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/README.md b/README.md index 842d55be..14212f24 100644 --- a/README.md +++ b/README.md @@ -640,6 +640,74 @@ ________________________________________________________________________________
    +
    + 🔸PostgreSQL LXC + +

    + +

    PostgreSQL LXC

    + +To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v3.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +To make sure our PostgreSQL is secured with a strong password, set a password for its system user and then change the default database admin user account + +Change user password +```yaml +passwd postgres +``` +Login using Postgres system account + +``` +su - postgres +``` +Now, change the Admin database password +``` +psql -c "ALTER USER postgres WITH PASSWORD 'your-password';" +``` +Create a new user. +```yaml +psql +``` +```yaml +CREATE USER admin WITH PASSWORD 'your-password'; +``` +Create a new database: +```yaml +CREATE DATABASE homeassistant; +``` +Grant all rights or privileges on created database to the user +```yaml +GRANT ALL ON DATABASE homeassistant TO admin; +``` +To exit psql +```yaml +\q +``` +Then type exit to get back to root + +Change the recorder: `db_url:` in your HA configuration.yaml + +Example: `db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8` + +⚙️ **To Update PostgreSQL** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` +⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool + + `http://your-PostgreSQL-lxc-ip/adminer/` + +____________________________________________________________________________________________ + +
    Zigbee2MQTT LXC From 929b75531e12c5bdd67e673da5d1e279b550478e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 19:31:12 -0400 Subject: [PATCH 2953/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index acad408e..4bde0ea0 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-13 + +### Changed + +- **PostgreSQL LXC** + - NEW Script. + ## 2022-05-10 ### Changed From b3ddc8efbb4d1e257c07a1a0b74f9bc48a1a4133 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 19:38:42 -0400 Subject: [PATCH 2954/6505] Update postgresql-install.sh --- setup/postgresql-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index c90e7867..43b8ed1a 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -80,7 +80,6 @@ msg_ok "Setup PostgreSQL Repository" msg_info "Installing PostgreSQL" apt-get update &>/dev/null apt-get install -y postgresql &>/dev/null -msg_ok "Installed PostgreSQL" cat < /etc/postgresql/14/main/pg_hba.conf # PostgreSQL Client Authentication Configuration File @@ -967,6 +966,7 @@ include_dir = 'conf.d' # include files ending in '.conf' from EOF sudo systemctl restart postgresql +msg_ok "Installed PostgreSQL" msg_info "Installing Adminer" sudo apt install adminer -y &>/dev/null From 4ba675c2c9c94aab44ae67526a28afbff9c6f011 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 May 2022 22:13:54 -0400 Subject: [PATCH 2955/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 14212f24..a1517d0b 100644 --- a/README.md +++ b/README.md @@ -663,11 +663,11 @@ passwd postgres ``` Login using Postgres system account -``` +```yaml su - postgres ``` Now, change the Admin database password -``` +```yaml psql -c "ALTER USER postgres WITH PASSWORD 'your-password';" ``` Create a new user. From ce2ff7900e7688c67bafe6af8502975d2bfe56d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 May 2022 06:12:29 -0400 Subject: [PATCH 2956/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a1517d0b..cb3a91c3 100644 --- a/README.md +++ b/README.md @@ -851,7 +851,7 @@ ________________________________________________________________________________
    - 🔸NocoDB LXC + NocoDB LXC

    From 2ffe87c533ab8010fa7542c24a67b1df29826a0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 16 May 2022 13:11:20 -0400 Subject: [PATCH 2957/6505] Add files via upload --- misc/images/social.png | Bin 0 -> 15182 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/social.png diff --git a/misc/images/social.png b/misc/images/social.png new file mode 100644 index 0000000000000000000000000000000000000000..a49cefc3e946fcb177fc7bf0f62e1b868e70d12f GIT binary patch literal 15182 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 Date: Mon, 16 May 2022 13:16:39 -0400 Subject: [PATCH 2958/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb3a91c3..ddae5782 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ ________________________________________________________________________________
    Home Assistant OS VM -

    @home-assistant

    +

    Home Assistant OS VM

    Option to create VM using the Latest or Stable Image

    From 527dd4da445bd061286d6874ae78b01d32ad318b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 16 May 2022 13:19:12 -0400 Subject: [PATCH 2959/6505] Add files via upload --- misc/images/social.png | Bin 15182 -> 19402 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/social.png b/misc/images/social.png index a49cefc3e946fcb177fc7bf0f62e1b868e70d12f..396c884827d732554048eca39ba558119e61924d 100644 GIT binary patch literal 19402 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 Date: Mon, 16 May 2022 13:20:32 -0400 Subject: [PATCH 2960/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ddae5782..f9d5275a 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ ________________________________________________________________________________
    Home Assistant OS VM -

    +

    Home Assistant OS VM

    Option to create VM using the Latest or Stable Image

    From 7d1de84468cc248b1b41a92ff3ee9bdd3fda2539 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 May 2022 06:38:15 -0400 Subject: [PATCH 2961/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9d5275a..00a954f0 100644 --- a/README.md +++ b/README.md @@ -791,7 +791,7 @@ ________________________________________________________________________________
    - 🔸deCONZ LXC + deCONZ LXC

    From 2c766cf5bca796bfad0d98091b8ca5384f96c049 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 May 2022 12:30:20 -0400 Subject: [PATCH 2962/6505] Add files via upload --- misc/images/haos.png | Bin 0 -> 14652 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/haos.png diff --git a/misc/images/haos.png b/misc/images/haos.png new file mode 100644 index 0000000000000000000000000000000000000000..2057e1eed1cd49d0f38c002a20415015923172c2 GIT binary patch literal 14652 zcmV-CIm5<@P)PyA07*naRCr$PT?JHDS=WBv4mt%D6uSj6#~2)IuyqtW#<9B^YXYc*&IOp>4|Kqz$fcM>>ARiCV-rpzy-iZ^f zM0|M ze4$t?v9ga6I~9Io;Zp9odF5Ic&-s*p``xAci4X9@gYb*ry&};U4|a;Udc-H`^$T~6 zTFo~xZ+d)K zh--eNBa+Gt1#2`s;ns8fLKJysoUQBd(M1e=$8{BR(6pNO>#T=d8KSLY9P z_;itHer1_V25V~@7z_r)$0tCeQ9;1xqh#ye>q_;QJ?2O&hvd8n>1!YRLxC`Dnvs9- z<*+%AcP$^w&EdQc9*+-aXJ?cyT^bUJ7$G5V@HR9QiqsVFc|4SC)pK*Pz6(d3Y-*R3 z_p5)MGkz!#YR~j*dv{Ln9V&%VmfzPU5DFJ|LA7e0aB^}+WK<-cKYNbXAt6vIQo-l* zQK8p_X>B*moH>oh%P-dXeY_mc`(Z#J3VLTsi<99GZ`97K{m@?A|fN9*J&Y^$yA=>*Y~D6re0)4&V`HIKtJtOON>zMTebxc5lRhP*^Lwu^b>0sF zg4e|;^OvK4JNo|a6|c{IF+N`aN5=vvSg;@yctk`5Qc_ZgUO}hRK(E&`rp1F1mHJN~ z|8ULJd7pdF&prQ#0HNNNYZdR0X>%btCer@1Ux>$pOeTj&B!)_*gj%fzkTcJ+E>twM z>XPGizISx}LxAwptnI(up3!TsR-^rb&qJ5`ILW10qVkv(eILvlwBd8X|D5x`;7jNK zF+BQB8Fzo(jJf&0LjKQm@oIIj=D$zrT=5TOuKx%3#Vq&6U%q8W) z5M>@bs`c@=_pa5;>7{IJY(N5i|2~{!Hn|L`RLUY{dwY8*6bgighqJUrks?L$_U&6F zB*f=>ZrN^QWI->^$n7|7phVmftJG`a^*5Y)IP+;V&Lm zDOIX8x_9r!QVy=JuHXy!h>MNGv17-uc<~ZuW-<HG_+b3+Vqsp^%v& zrBcO$v`d#RVcN85h>VQPb$;7<)Vtt0*T3bNCQhl}SP9teehd(Xwml#I{Gn&_<}EOO z{1~{oxgk0_7S7HE;OOXt`1n|K?b;nDPMpXjqsEOJW8M07C|aZl3`PTP-Mobd4<54f ze){PrNTo77e*A=iaQ5uk+(B@!bJ26&z83#k5GZkXdqU%L5l`<|pErL#diU;ysZ*!p zGx0W*4nmxJ4%);ffg-V zLZwopT)A@i<(K-HHf;)S-MWqT?R^jz7su?q!C=IofdepMk}o17qtUHf51c=D7Ut#_ zs8y>bbK+gPbVlF4{c!5kNp$VnjV17M8g`ZIT=Ja%9|obt(Qx^LNo~%AKD=3b0~#fukXvzCG^ih2o@{Ra*p_*D=l`3{9qp8~N&0KHxSw-WAHwqhN$S}j_(Y>BXU z?=s1_PMx|qcI*gl-@eU&rIdC~!?w~-m#Z!~(DXkGg7=9)Nx;nhhhAMj|0~)5jvYIo zefti0^@__PIM~}^&(^7UA9M^_<#QA*Vgb3C3<)VbghlF5!LvPVog2ZY;}G1vdoz=a z`}gmU6)Tow_wL>3-+urDHb)RD*1A%4;X&{JEC^l~jl%b{TJL^&{_tsHK~JqL230=-*1p?m8>u(Q=bWF`P#ECK{#gumBAtI@*6%^X5`DXiWSg856&BQAkU zZxk^_TzuH;QYVj)|11cVx(u8D$Zy#g5*(eNK5P~E{&bcFz zSfZ^uXP@`=Q7z8@XF;ekXx8w1t0paOQBBSp(#jF`b|RRW333KOB8E_A2cgIUfB{AW zF`i^9;{!ZB(}Ku%YCOB21Y0p51sx=~@*okzSA`=kCFd+EImXH(77l-~Wc0HCEC`;y zt9v|JFlh7OW>)-`KiR_4f)8_ZVP+7>CrEe@$jl&;If5?`!DvvyNM?wqfq<`rPNzp` zkOI-KRG{uLa~U5(As>4##$wjaXlOoC7b@Z1d1uhcon8L3AXJ~Vqs@bvzwd5WLn3Zl z+XgNLC9ts;LL%csA{RhNJ|PVRp_wH_Qrom5z6w0P8a$&8iHRz_ewGAfq!#va0VHBR z_{(7Lu2DwdR>fTI{vvkV{*JCaEul$e3XG(iicLWStC6odsPL!vRj z-dY5akn6P2>Uek)C&9cu5xDYzi|S2z{)`kv0MP20O0fZ5aQt7wNh9aN{dIzAaV# zAwa0J;fm+Iv8^vD;$zKg*RG98lP5!w7=hS(n;}uWguSyA)(&DwBmxM@q-c%c(^@sw z%xGjYTBkQ6!Qg}#c|!5}zI%O$YJHpWLx50g;h`q?CU-ujRw{&z8a2d(2@@F8i4A>-#HYI; zQND$_r5JLl5K;*-9v%ej$qmr!jZpKX-@XbY_7z}eZVQ=A z3M(s1Hp8jrETGf|0IgPsVZ(-F+qP}#vZdx>s>*4#nsk;#zjSNt<5$FYPtQyBd3kGg z$|q{yT@xB@`N#eKgbshlynkm&-4+WL%ty0kO<4g(sZ@em<(0{CNR564O~PB~HL2i> z#1L6HL2OkRGRp!GOD!N4i5URY4sQZLEEY3LN{wGap$Ml>pJsK1+$wA)8Hz+go%^Is zU2jkAu_vE$&C_Y$6@@dAOgTN=vZ1XGJN<5{PovgxeF<6fudtM z&wC!z4mJ7~nbq$Hg3-wH>^o`lqs?=sYxM>u#O2GEqeqW!tX(BOJ`T~*F-T5MX4Eq4 zU;qe3tXa&`(gGG17VH|NO(qjW=a_&XZ4d~Atm~pjkDd(VTu0jag;MPYEPc6W^~kSH zS-%?yRmUyw_jrZxGPNR=t;!!Tpg-o#o6GDt(MBrNQ$!mR6N{7-0z$`F5KUAPKD9k^ zGv6{@_*rLvMol0PIBiHm-@g6f@9+PwCPOF|Yb%agKH&bG{+s^w;LkYVyMRzNf|$YyCg& zk7jl|8W$Q|n4XL}r>Ug*+iz_%F%K+|7cOA7+$6M&ZS1ChlQ~LGPGJm)0LUs}x*h>Src9wwvN*vMsAcpElvCpI z1(-Z#8s^NNoon4WU9RLGj7GRM?y%F2(?eD(_)S9B#YctJSdP~lZ3s@iNx^-(=hjsDd#W8T;K$Iy{nrVtjz$EbJ&!1z} zsx^4^Dv0&74jMEF4i1hm81(5>mChlyb>_@jbnVg&iHQlHBv2Am37-K=-P^4m_oY|$ zd=n7ZLXi0r)&`y2)gxnVt4o(I*sx(8bFvu)nprA*rYVaTFGlOutyzO_)v8q)D8!6R znnKNDef##s_3PKsv}sf9+qWMB2lmH=2@}&>;^|n@D3w}`_u=nZL)hcTk3R_nI*5QS z*1gc|ALQC2N(=w>$z+YnG2e^CN@JX ziJT}U-?nYridnN}|za9Q@TmsJ`$}lgBf99#AGF z$TP0gr_O7C|6Qn3#ghq$X5>HrTmz-D>(;HyoGxhx+4+qdH^J9;0*VxIWldqliWSGc zeS1-?STPnu5IdsPI6gid@$A_%w#XznI2bc$PRAdA{K1?%ffx`F$bh4Kkz7u3$qLMv zG2_!^ndYeF)()}mQ@8qD8`1Q_r=OhrkzW;rI>+AFyd2-*bo7%O)v`VU(NgM;qnS&+ zK|_ZQW5F2-ebS_f=-an<`s}49;5~cx;`Z%Z>@ufLoksooUM#pPSg;Vn!a^}@*a%#_ zcmWL?He|^^GFiX<)`qQVzH#F^=FFMLfFKaYj~|ET&70%Gg^TFjyARW%PabJN*jK7~ z(|wU&lXH!V=i%g>@A6eas624?s7GriEzD`rUcGwtFmK*G*xA`K^Kt$94J=>24C~i# zKuAak4j(=QC#M3;hSN-@KjefdAGB%HW=xzo5se!+!RXPWSep9SvE!IBWfFe>y%$T! z(LGHIMW#)gj)xB)qF1lqv2*7xxVpMv#flY-Ws$F0xpEa_Rn$yO*QXdIrzkz62nmaF zy(dq8x?$$5PX;iT1HT#wb@xAWeln`{wfK;LqNaPB_&fc-e*OAvZ2{Tsl`B`W^<}eW z&48cZF18Y%SQFO*&&3L~N{1XV*>@5WfkjT2C@b0cS+iy`$4sV)G=X9YIxZz86@vy1 zW^3OjOz_3hrAyi3k!8!4!pX^rMdoy!UAwrwMofDp(LHI+9QmuKS$ZHH4GL+@~$zCsB zybvv0wnz)!cubfiEQ%$_3DX~Pva@IZ30jjja^y(NoH>K}k*q5`>DZGePh!M~kq8fe z&(^e!7%`l!jT4JSaCCIUyLa! z|J(L_9T1F0Ua{ugw+A2J&RR$;Ev?xsj*gCGLZUYIIdf*S^#>$ap-_wq7tWz$$Ii^W zj2$~REjs2>5d<8W2~+SzKch9y$BrFk%!$kxEg+#;Yf4RUr4o*5@puC4*s%=*2M)&c z>C;%vf@V2A3q6;EgB`YR-Hs6>Mlmgyv~0{ z_uf|lq0z1v1#ge_zMT;Ix*%x)seO2O7&9rf=wr>A)vUB=N;!}~Z``=X*v*6qay?Yl__UzTG7h4=czoT=G965}B{rWQ#)1dzyE-lFj~Vveu4y>8H5gOrk*)-hA}N#5JG@2UAhDf8Z^Y2 zGpE>+Dq>_5n_RzsjYZV2UInw+P9~5vgV++S`lRwFWppW}PW25klSF$dp_p}8xfBoa zm~*P`rLHA2uTuF$RK5xbC4B}h5AnawtGbd+*9a9}?wRjQPpEhT?J0{!Qo ztLWIVBcrGN`VC+O9dGZZC|1mkQBe{c)eH9S-NQ^1nV75~q@*OFXV2f+MpL6lk7R*e zsZyn|efxHtKYxy`0A0CqIa`E6sdHN2Owss?6)Tw;TfcrCdiDAPSFT)PW~y4XYKVx4 zL{Ly5Tkk+VA}}x@+kP2*q0mre!p5$5X7tS0PGVmi1X`hgYxJ*|5?|c)C|98(Q{k{M zuBnX*_%miqPm9?;WHSFbqzQ{`iDJ%~^JkjP z&aMdrLbq<+k&uwcG-~qXsc>;A%(^Vjo;{NZ1Tt*|Jgo{{v}h4a4$?78moCGkNs}0B zBN|PGAc|wiL6T8TMl&KzbI$l2!P6G$)= zNsk>no;gx-=;g|lW#vrrFP%Gg#hNv%P@zHvR$aS)|2|_v78aJwL=u1$*!}ifJJ{Ph zFfAni^Y(2R9zA-1(xuBnBoZt`DfkMU;6MUmS!|t$S|_IJEH( zH@6Z{sT6Eu5HdM~1`Wjg`STbX$~dTRh#rEpfo$>AsZ*JGpyMf++qrWmMvorDgzM#1 zKOMmAK7kxF7au%-{sQmbg)#e0OQp!>Q@vu%nziWDr#H)>(&mJ7=gxtxtqt3_koL@@ ziXCZgyLLXfcke#Yh_NJ- z2u#-{r%#E!b?dU{=P1bY@bF*`nzS_QaH-eg=pVlvX`R=Y;fsRcK6K%*M=QrHb#Qco zP#{297)KWB)~$!#yZzYafW$!3YXC6fW*o43&k@8N-v|dsNBH{sGBZFkc>VhIjNy;~ zckd<;>VFgjQ%04la72G8cq1X7J$srtdz$@36evP()20oKM#|P^79}~~HEY&j@ZcfY zDt(mJAP}f!=FOYzE30f=+}>7RbfHFGD{x;71ZrP-G_LK1s7KeU7cE*GF)>lBs7?YW zS~+v(Ob7%Y>cI5wM!o=3_Fcj1k-gBcdS%AjX`>KIKM;>6{{Q63Qx@eOI&={A>izr? zbJPJ^ts49HAAq0VPT1I3W5|%fjNwp8$OA0LW>O7M(tQiur}COK$01 z%9pReOcODttV1G^Xsb@$-tM0XK1cFmlD-%S)qL0fesBJu&6KsIiW#XanFlK?E9}^@ z9kh8!#_Aa*z}{+v=saf&68-1n^trRxzHK{8S#y0u+&<-|1Rj}`sZ*!G!or+sQ%1*3 zc_5;&fB$_6R4AghcZw72?Ch~`pFau}a!C)?R;^me1e{w=h%|v5HrpZK&6{kpq}ECD z5di@&vi**PS)u#rd5^a(9RJNhXyPAg`*3F4a}kekdlV=@n?A`A9Ly~S_w@8+tcW7g zjHZa(K#D<#3Hz>M$FL5lUb#Gi0s>K{Y#CO*q(F~sIPrI)j+-|9g<->nV#bVVjM32S zHpK}h5GbA?26gV-8Mc)Ir6CR-I)Hlhym0>fS;me`!CLMh@L9Cou3dWuM%GcOk~`Cc zoIs#sUF-aMy2j9xE%Q=X(N6W{ores~=!mdmMh!xTJ{r8^CwiDCHILI8) zk3v&)@ZYf=7mpoe^plcn)GDQFXs9wD~3)tSh zYsW3wcJUTxjA{-4GG-BGY zcI{f`CkQBFOPe-rWP2!OG>aK)944U=_#HZQ%C^ZBQEhU}L?9@ql+zH)#IfGfGP7W?G)~vEm4wNx@ZESU9VC5sf5= zO#MSNz7@rC?Aa&jUjPMpm4zo5vMc7r$Bc>;`Rag!$A@bdZ@K0fW)en%u|GDAd_ zi5$@2GPqpvpHdU1<^no4HxOuNNg^HOD@+@oXBD(iDAZP+u&LXP8K2(K{aKn&b@cLn z4;Bw!t4mt}DH2Ojp;}EOM7_uBz?Uphcl`KK_B{i7$(#mhz}2f)mlPN}nm}mUv^fjPl9CeH?>BAQ08h`%W$w^- zZ?S&edOUsllz~NY1H~04b3}gQ^y$pzs9d=UOp5{nUgo;9q<{xw<&n$!-&-_n{a4on z+AQkPpFI!1xqhah>1G98-B6=#cZA)!gj-ktW;K8lCyud>>744!^ukmzqdZPf&?}az zpbZCU=PsJvRQDwxK{Jm^kW?oiwnga%+KhzK8Ge3#*t~fY+P81d9)rx0w|8^41d1wW zv}GGT2i1&Oi@it&qfUz*TQ=g+qsL5JiB7LwyBaN9wr24It>z)e{P*8~r^}H{E78-? z(042b%5CrgqxPbXFRC6bm zVWrY1758bK8MU;S95Y>?=qZ&dDNZ0WLzVW3ufg8_>cEkyhF?a-`Q3$_jD z;>C;DBU1YeQPkVF@1#F6b@EYhifYvv_uP69s9;68Rmzq@k>Z~W>Y)bV>%?9r&E z7n361W%&FS4-O6mP^L^NJa}-Qbwl|1ZA(iZ&I9XWkJ(Z6Kvf9*v^p~H*944 zu2!yGnPq8-#gRr5F`)WK+qUhPz?rAx@lc{fN%nkH5C0elBC%NQF=cC~ylnfNZ=cZk zK#=3T@omn;1U#-R5d$(Y4;rlz3N=u?L@7{)f_jUn&5_IDa3f=?#&mNsI~OioU?zz= zCn)G5b3;`zclXNJxN#$9%$Uhan?!#p8%s9(=+Pt0@lwgMKmjN8=|g*-8yS0|{??C; zYuBz~;lf3%XhT{seE2Yy9-(3pRoz;*Zo{;Rwuq)?0P-zdD-74gK}3UE^{E0#zRTpO zrIt3ao^ua0|7T$R8(&=$YF#tRBIk5lZ~0_b*B;FsQO-?>MQYJQZBam@gNw3d4nORW&|A`KDn1)$6;r8X!%L8%W4KB;x)!vYlv z^K(SU9UUFmbx3ELBnk`nB*MYDIDCD%4F*l!ZQM6)J`7XyFHz9Iz#ule zsLyoA4nM|#$ZmUjR$>3AxZQWVCDd8%s@(9XpQYkEr;5`0zp0s#Tlai_8%@ z;y?eKg+6`yr2)WWw%WvqOkay6KQVjuY-ZCbT}~+tDz(18^B1D-%|ii4J}m8MLn}Zi z;$zj0DEKZ7W2;7UA3RozE>x%>;^GnvR%R(FHKwc``^vf9rmqe{>x=Q$o!^YyR>^p! zg^j%oGP!_lYh!A-A|Uiy175sVV)(L9+<2~H!lxdgv13QErYe()lUmd9vu4d=-Pa`i zqeqXjZoE2mYBO^|j*|E}fk3HgZ|`PIE~YFhIdW5+KpPHHS(Li!h|LfPWZS7E>Eq+W zfF(cD-lskOoIMjy&(1``i(POjWDYA^34~G}j0Qbsu6v8cJ3s#QFM2i>1AzxcYBHwx zEr70Ft6-C6NZT1+jX(LL76U0oFEBSlb98kUrs0l40GiuBY5a@+QjmSnFQo3-$jhY43&uf~Q^M%&d+%{<<5qVk8 zCvcpcHU|WBS|j2UwOHXFffWbhpi5J2YGEN0LW1Jh5ubf0fy`AzL=;O)3?4iPef#!d z|0aMba;7u_HFlLMRg!g3kO`x>ff!Te%9U8p5N+8^g_~BbTBiF3x(9V*Q!^Pk&`Omm zb8Y$MO5@qNc}RS*14Rm(b07$KP$g@zY*!fO`sW@QX9S{nArV%MEsommR#2p9k(^|} zTB}737B+40N$VG~fzbX`sO_(@t7nu?KGnlqkYX+p(7G^grxaR8Y@m+@iA6Az3z!)a z(GFVznr|QIj*0D1x=5`t;6+F(d{>9z>XQ#2>Y!RJ)stJcY@XhMLFtKGw{Edq6LoEK z%b`B3OQXBc`eOouw8Y!{SJu`}U{P9|09dht`cksa{TE4rx z5y~Jx6mc7Hbx`eob;J4hg!=AJA(2xIBYU>sqL6?5oK; z%jvGPwz88$CgX$0?dFuJD}l^|DcIteU>ZF&-O&UBC~pJMwh0tJEc`1R8;&PrikfM* zckSARed~ZU-~%Vma?MPE9iMg8(dr!99>Lk!i3M_`0bH6Q^ZI3uwNZz*fw3&=-XOE2 z(;1K$bP)V-e-tS!=gbkG2em?r#8?f&BUQNgFbRJ@PDN;p25PMl7BW7{6qcev6${j^ zWCdp@2_!Nh+oz8{o=3h=uTa^FliEyK%YK+ z&MJ7+z(w3Y>#F{Y&us#M8q7=}kiZgO9Rfdm4~i6$!`fB?L7GWPNz#J;D3k^yq-YV7 zsD)M!SjYu%wiCnJiuTnILQW=G%59)ao1QR}t<@qzSLo$z*^=fv>X!)mH*LryKKc-; zZ}{NDWdsj@v9yswNFZbhd@^3}Bfny%h*M%RV@8lhr>G6seIydIwnZaZnO(&jHEN7i zt5&cNS!9hRvI;bF1k9PQoHQU^IWuSiwMddVA`lV+4}$;RA8w=xwj4XsYYb2+^iZVg zpj7Lj(HKB68_9yqvslE3R3cyiNMr&QSMY@#9j3`gKXvL@TUEq1jFJ61EAv@5fZAxl+~d)aWnHria3qpVaSjn zOe46CiZ3^~=P)uqVgf;{)gwM&FZkj6;pWQu1QMu$?7CVHl~Tuu1^G1sj7%?S3T^i( zk<#`K+)kAQT*gKQ#tb!j=rl+=A^3e!&n5$Aer%_hEG-a5-r9Y$=QmPp8Es`RXE!2q zl#%)5RV?Y0l|Xv-<&7wv{V{FG`*Uz05F;XUl#r0XibgR{ zcR>(&7{y%8VPnUEK$>gN8lX|rdO6CR(mqR^CJ==ci}_rNLzK2TB5PJ4QGW2BOdGU% ztwzO5IwkJD>_pPwdAVssHfug_@2XL)6BjPDb~J;GzE{8;bI$hpQv_iGfiWIpOO)hG z)M4(1Fl;)WeMFRws3n;;Y~Y5`k2 z2}BYBn{)=f0S3|l9k%o*m7%yu^}G~z4- z_gA)&ZUM+q6A*eMbV@a1l@?(~CBHAcAndi~WK-JeK8MqXA3oNs%e#^L9qk1YOKWi& zL;A8HFtY^UeY6T24=Qjcv=GD+8LOi8=+T4G)GrD^S{2E_6X53KmzX_qEKVIe3W*39 z;BAe@)otNcL=Jlbfixj4BmD1B=SHKs$(B(I2?UC!lM+;jisL2jFF3RB!ZvN#_G8&F zoUqrg`)`qxwmKA$!O}_u0jm>y84x(r#A0d2mK0hYLc;hEx%7rxl@745uwwP$4{7K; z=NGfdjjW1*$Ag|Hz{y*W@#mCDxN+tvGd0$79tJhFK^=E1#*XY9GJ=q~=8=;&d=PSG zp_@$b2eU*b$q1!Fi}(aBVk44p*RlJ`BW|lYdjYPOVmkk&iWi$oDpoIlqm)QcAvb2B~!=a`MnRT znOyAn7~pM-DrGI;R)l;)77+er4rC-9>^;-`H)qDU_=x-hHJE8sIwU3Q5ErL5#>c66 zS4vDB^3d*&4P=rs-KN>G1e@OBJr9Nkf=psTq<7KG~RQp+}xpOnmDmE zZ6*)~?K|1DZoh}ZpsEvdetOjRRZSTOLZ+wW@vU43>Q$r3B1i?rY2zw0%7(*K~dwbs_jNdhx-+UPqi zTbiTbxgX}&Oqo<#t1%!kL5H{RR0w#JiZgc-aqYD^Jge7c+v|H&@j&511z|3ivQ!4O zq_EUF%h4F1(rA&a(jq!ViI?x=!_S^SFFd_-t7BN;)3ncj<;-zJ0-#eJ3;g0?!9XZn zSPn~~jS2@+5)5SY|)4ZwfA z)lIg|^sj$U?r}$IHAbW)>R8(N)ms%F2B%`{*#tx+QHnsoc7Z8gt|BV5@3-HvXo+ws z^wvTiU#Am_la=5nB&hW9v3f~xvcN1pK`4oPw||}Qn++4VZ{uW{{Tbn~kOH0STB24t z^K=kcTtweu$hx23l@(rzu;(VnZ3&kqtT$VHdv-c zIl^%F81%@p#ZCF?JNi7E-hI9C<82bKv*4j~9ZOU$VTKZ}a<~+da^^_FF+x)wD9svj z4p(mgaR#lLX1$JOS(B5sNJ!ElAw`FjR25Q%4pHGnTW=38+HnitP&x45GN_pxbNfU0 z$~AmAVwZ#JWhL?lGMNZ6i2x!YAN09Pk%$1HoC(+_;aujB))S|N@q8ZlHIKBcYi2X` z!O3OHB^dyXN{^Hz9ipN&c>P|5pm$0fzm1;;vZJFOMX$=ToYbGBGB>a%T3g6MtOA7 z5)q&3&9r?!S9=zT1Pmy$t(+N4%Ql*NPt%wNMUccM6scMykvWRfA~-^gfHx_)no#^@ zkg@m^qax8lY-JZOcPaVYzG>HOw|vUH{+MuU`G?xR-Y{-QYVhN-x}<0eb!@awj~KQ#V#rNJnzVLJ0)euqL^+A^q$>1COw}VkS%-vV6{78`Uwl<{ zqVMjGb#CQ%clnPJPAc*!WzixlO_GgM)ZIGHakpyOCO)icsSGVEF{D_F`Fc=m5A_C7 zZk;Ml60rbMF%L2+6+XC+4v`t7$ko(_%D#c4p&*792kMwj4Uf^_Rk#8{@$#fs%{R44 zbZUG@3L_3Lv3M84;1R`JD#BIB z)5yeP0b~;LDMFaBKYZp}#Pp3cmV2j2nd~bqku@M$p=0&i&?pUpLlY2DqQmyM##{U3 zMezUjuJqi3xVKX6+qcCM-#)LX4trgkAN{ISnYeR4j&da&tR!%>62i_x1WUPqeYZ!H zHfdP0k<6yXfE1MxNlNO_RwJThyPZL`=8QVg%<;1~G0%7C<$1>_QU-%pTt-R|WNR7u zpt^0$o!Vvz&&pUPy)I?0k8zPp3=%UlF)XMcPA^7gii+W;7gJLaU5ChcE#5{b5UF!` z8{OWo&9QE^?){r!Kj-)D{f&(ODDO`36`z|s)6!f7TMH3v%muKJ3L%s5nE&JI3iQ!D zBa~VLQYju#8xT{r)20BgdE?GEwEXlIy^lO_zCp<8nl$4qlagfSDS?g_(f8^W2s!R; z6LY(sxlmMo5;3Fgc@cSGA=jB|lgYniD zhkCE)Jv`XnOfH6{nF!_*GN)i55J@r`dC=0bEtM7;qX_X;`z#3Y96tY2i-I|Ch?kcK zNIUk6f{^k4G~42B;?1qzU9RmIbgZp)*cC6SDx#Q(Z{QhuJgzBBsbin#O|&U{JGt)Y zxe-5gKANAMv-0uY>8CW=AL1;$vUDW>_O9MSMYJ`UQz^wq1Okggxs-|Cq0EcKp9U|8 zb#LwerMK_@Y9M4347JioqNAN`-u>NB9&))pQX(AmTBA@Svq?}EYj`rDVzYynnth!Q zM0^TB)212uH%i^CAbEK7H{+{ozwi{%_I#~UCXmQgd~2r&W9f#+6Dzmccc$gX+1aPu zE2m?=2?!Z)%sI(K*3TjrsWfLA7f|Gv+U579b3M;!cvODPJH~B}*Jq yuQs=i|Kj(`aKUd5!q Date: Tue, 17 May 2022 12:37:43 -0400 Subject: [PATCH 2963/6505] Add files via upload --- misc/images/haos.png | Bin 14652 -> 13846 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/haos.png b/misc/images/haos.png index 2057e1eed1cd49d0f38c002a20415015923172c2..4fce16eb74c4deefd2d32ce78e80283bfef0b06c 100644 GIT binary patch literal 13846 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 Y2M)vu>(hxgkN^Mx07*qoM6N<$f^m4D+5i9m literal 14652 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 yuQs=i|Kj(`aKUd5!q Date: Tue, 17 May 2022 12:38:30 -0400 Subject: [PATCH 2964/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00a954f0..20d9d0a0 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ ________________________________________________________________________________
    Home Assistant OS VM -

    +

    Home Assistant OS VM

    Option to create VM using the Latest or Stable Image

    From ecc7dae17fce85cdcc7b9c54bee17df7ab89822d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 21:47:54 -0400 Subject: [PATCH 2965/6505] Create filebrowser-v3.sh --- misc/filebrowser-v3.sh | 89 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 misc/filebrowser-v3.sh diff --git a/misc/filebrowser-v3.sh b/misc/filebrowser-v3.sh new file mode 100644 index 00000000..07285238 --- /dev/null +++ b/misc/filebrowser-v3.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="FileBrowser" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +while true; do + read -p "This will Install ${APP}. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${DGN} + + ______ _ _ ____ + | ____(_) | | _ \ + | |__ _| | ___| |_) |_ __ _____ v3 _____ ___ _ __ + | __| | | |/ _ \ _ <| __/ _ \ \ /\ / / __|/ _ \ __| + | | | | | __/ |_) | | | (_) \ V V /\__ \ __/ | + |_| |_|_|\___|____/|_| \___/ \_/\_/ |___/\___|_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Installing ${APP}" +curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null +filebrowser config init -a '0.0.0.0' +filebrowser config set -a '0.0.0.0' +filebrowser users add admin changeme --perm.admin +msg_ok "Installed ${APP}" + +msg_info "Creating Service" +service_path="/etc/systemd/system/filebrowser.service" +echo "[Unit] +Description=Filebrowser +After=network-online.target + +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r / + +[Install] +WantedBy=default.target" > $service_path + +systemctl enable --now filebrowser.service +msg_ok "Created Service" + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://$(hostname -I):8080${CL} \n" From bc15323663d317b414f8d7c0d629410e822bec02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 21:53:34 -0400 Subject: [PATCH 2966/6505] Update filebrowser-v3.sh --- misc/filebrowser-v3.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/filebrowser-v3.sh b/misc/filebrowser-v3.sh index 07285238..d69bfa44 100644 --- a/misc/filebrowser-v3.sh +++ b/misc/filebrowser-v3.sh @@ -62,9 +62,9 @@ function msg_ok() { msg_info "Installing ${APP}" curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null -filebrowser config init -a '0.0.0.0' -filebrowser config set -a '0.0.0.0' -filebrowser users add admin changeme --perm.admin +filebrowser config init -a '0.0.0.0' &>/dev/null +filebrowser config set -a '0.0.0.0' &>/dev/null +filebrowser users add admin changeme --perm.admin &>/dev/null msg_ok "Installed ${APP}" msg_info "Creating Service" From ca63675c6bf2aee58a049599bdf65bc8d8f9b549 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 21:59:38 -0400 Subject: [PATCH 2967/6505] Update filebrowser-v3.sh --- misc/filebrowser-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/filebrowser-v3.sh b/misc/filebrowser-v3.sh index d69bfa44..78cf8ab2 100644 --- a/misc/filebrowser-v3.sh +++ b/misc/filebrowser-v3.sh @@ -81,7 +81,7 @@ ExecStart=/usr/local/bin/filebrowser -r / [Install] WantedBy=default.target" > $service_path -systemctl enable --now filebrowser.service +systemctl enable --now filebrowser.service &>/dev/null msg_ok "Created Service" msg_ok "Completed Successfully!\n" From 87a877a8e9e6d253175f7448ba48743a62862b0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 22:36:18 -0400 Subject: [PATCH 2968/6505] Add files via upload --- misc/images/filebrowser.png | Bin 0 -> 4747 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/filebrowser.png diff --git a/misc/images/filebrowser.png b/misc/images/filebrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..0c250d0a35e7f940dfbfe2fb5f3badccb13c3da8 GIT binary patch literal 4747 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 Z{|}7#OW(DQmPP;o002ovPDHLkV1h>s7s~(u literal 0 HcmV?d00001 From 34b165898b0c7fff8265dc2169c02b05a18993f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 22:44:56 -0400 Subject: [PATCH 2969/6505] Update README.md --- README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/README.md b/README.md index 20d9d0a0..7ff29054 100644 --- a/README.md +++ b/README.md @@ -1480,6 +1480,45 @@ ________________________________________________________________________________
    +
    + 🔸File Browser + +

    + +

    File Browser

    + +To Install File Browser, ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/filebrowser-v3.sh)" +``` + +[File Browser](https://filebrowser.org/features) is a create-your-own-cloud-kind of software where you can install it on a server, direct it to a path and then access your files through a nice web interface. Many available features! + + + +**File Browser Interface - http:// IP:8080** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + changeme + ``` + +⚙️ **To Update File Browser** + +```yaml +Working On +``` +___________________________________________________________________________________________ + +
    +
    Webmin System Administration From 4334a899a36fad1107f8c42618b253c5b9ccb1ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 22:46:26 -0400 Subject: [PATCH 2970/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4bde0ea0..ca91fb37 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-18 + +### Changed + +- **File Browser LXC** + - NEW Script. + ## 2022-05-13 ### Changed From b55756046fca5628ad30bec0edd56dbcd2937106 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 22:46:58 -0400 Subject: [PATCH 2971/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ca91fb37..92b01adb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **File Browser LXC** +- **File Browser** - NEW Script. ## 2022-05-13 From 431c62b63e66c2906bd7cef9209ae76efdccb838 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 22:55:04 -0400 Subject: [PATCH 2972/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ff29054..42951596 100644 --- a/README.md +++ b/README.md @@ -1513,7 +1513,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/filebrowse ⚙️ **To Update File Browser** ```yaml -Working On +curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash ``` ___________________________________________________________________________________________ From ec8cb77186c636dd953f8affdcedb839e51f03a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 May 2022 22:58:24 -0400 Subject: [PATCH 2973/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42951596..6b7ce3a1 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistan ```yaml /var/lib/docker/volumes/hass_config/_data ``` -⚙️ **To Edit the HA configuration.yaml** (Recommend Using Webmin System Administration) +⚙️ **To Edit the HA configuration.yaml** (Recommend Using File Browser) Run in the LXC console ```yaml From 38dd3d04a6cd469248e73d2ed6f1999bf38f5234 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 16:59:48 -0400 Subject: [PATCH 2974/6505] Create keycloak-v3.sh --- ct/keycloak-v3.sh | 355 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 ct/keycloak-v3.sh diff --git a/ct/keycloak-v3.sh b/ct/keycloak-v3.sh new file mode 100644 index 00000000..f78b5052 --- /dev/null +++ b/ct/keycloak-v3.sh @@ -0,0 +1,355 @@ +#!/usr/bin/env bash +APP="Keycloak" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + + _ __________ _______ _ ____ _ __ + | |/ / ____\ \ / / ____| | / __ \ /\ | |/ / + | ' /| |__ \ \_/ / | | | | | | | / \ | ' / + | < | __| \ /| | v3 | | | | | |/ /\ \ | < + | . \| |____ | | | |____| |___| |__| / ____ \| . \ + |_|\_\______| |_| \_____|______\____/_/ \_\_|\_\ +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" From b158277b1bf4e8c40ba4a535593854af33f240b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 17:00:46 -0400 Subject: [PATCH 2975/6505] Create keycloak-install.sh --- setup/keycloak-install.sh | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 setup/keycloak-install.sh diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh new file mode 100644 index 00000000..47ad6547 --- /dev/null +++ b/setup/keycloak-install.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if : >/dev/tcp/8.8.8.8/53; then + msg_ok "Internet Online" +else + echo -e "${BFR} ${CROSS}${RD} Internet Offline" +fi + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y openjdk-11-jdk &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Keycloak" +cd /opt +wget https://github.com/keycloak/keycloak/releases/download/18.0.0/keycloak-18.0.0.tar.gz &>/dev/null +tar -xvf keycloak-18.0.0.tar.gz &>/dev/null +mv keycloak-18.0.0 keycloak +msg_ok "Installed Keycloak" + +msg_info "Creating Service" +service_path="/etc/systemd/system/keycloak.service" +echo "[Unit] +Description=Keycloak +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/keycloak +ExecStart=/opt/keycloak/bin/kc.sh start-dev +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now keycloak.service &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From ba1f516efd6b716dc46ceee9014f25e95cd8ce42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 17:43:09 -0400 Subject: [PATCH 2976/6505] Update README.md --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index 6b7ce3a1..ccb2397a 100644 --- a/README.md +++ b/README.md @@ -1617,6 +1617,50 @@ ________________________________________________________________________________
    +
    + 🔸Keycloak + +

    + +

    Keycloak

    + +To create a new Proxmox Keycloak LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/keycloak-v3.sh)" +``` + +[Keycloak](https://www.keycloak.org/) is an Open Source Identity and Access Management solution for modern Applications and Services. + +**Keycloak Interface - http:// IP:8080** (First start can take a few minutes) + +⚙️ **Initial Login** + +The initial admin user can be added manually using the web frontend when accessed from localhost or automatically using environment variables. + +To add the initial admin user using environment variables, set `KEYCLOAK_ADMIN` for the initial admin username and `KEYCLOAK_ADMIN_PASSWORD` for the initial admin password. + +First, stop Keycloak +``` +systemctl stop keycloak.service +``` +then start Keycloak by coping & pasting the following (only needed once) +``` +cd /opt/keycloak +export KEYCLOAK_ADMIN=admin +export KEYCLOAK_ADMIN_PASSWORD=changeme + +bin/kc.sh start-dev +``` +⚙️ **To Update Keycloak** + +```yaml +working On +``` +___________________________________________________________________________________________ + +
    +
    Vaultwarden LXC From 4207aea3199d8111e8e6dff7b1276d648fe3a9d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 17:43:54 -0400 Subject: [PATCH 2977/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 92b01adb..55c90f6d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-19 + +### Changed + +- **Keycloak LXC** + - NEW Script. + ## 2022-05-18 ### Changed From 12db366edc232a21588e6166d62beffe7d5ff0e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 17:46:55 -0400 Subject: [PATCH 2978/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccb2397a..ad511661 100644 --- a/README.md +++ b/README.md @@ -1618,11 +1618,11 @@ ________________________________________________________________________________
    - 🔸Keycloak + 🔸Keycloak LXC

    -

    Keycloak

    +

    Keycloak LXC

    To create a new Proxmox Keycloak LXC, run the following in the Proxmox Shell. From 753d7d96fd0c4a681b9a00c24d73c7b59b96ffc6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 18:33:35 -0400 Subject: [PATCH 2979/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 38960670..bf480cff 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -72,9 +72,9 @@ apt-get -y install \ ocl-icd-libopencl1 \ beignet-opencl-icd &>/dev/null -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* +#/bin/chgrp video /dev/dri +#/bin/chmod 755 /dev/dri +#/bin/chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" msg_info "Setting Up Jellyfin Repository" From f498525dd969c60a30299b03b9f90b8665434923 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 18:35:40 -0400 Subject: [PATCH 2980/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index bf480cff..9a003ab4 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -73,8 +73,8 @@ apt-get -y install \ beignet-opencl-icd &>/dev/null #/bin/chgrp video /dev/dri -#/bin/chmod 755 /dev/dri -#/bin/chmod 660 /dev/dri/* +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" msg_info "Setting Up Jellyfin Repository" From 7ad35ac3ad61ab41fb90d845d8df07603310bd09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 20:49:49 -0400 Subject: [PATCH 2981/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad511661..d1f263b9 100644 --- a/README.md +++ b/README.md @@ -641,7 +641,7 @@ ________________________________________________________________________________
    - 🔸PostgreSQL LXC + PostgreSQL LXC

    From bc953559dd8ff9c9c34f3e3b7a26c41716170555 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 20:55:09 -0400 Subject: [PATCH 2982/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 4c3a88e4..7478b7fe 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.0" +STABLE="8.1" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From 2def24e8a1a483247f0bd47c77e84655b5d53c8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 May 2022 22:52:25 -0400 Subject: [PATCH 2983/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d1f263b9..2df0dd33 100644 --- a/README.md +++ b/README.md @@ -1641,11 +1641,11 @@ The initial admin user can be added manually using the web frontend when accesse To add the initial admin user using environment variables, set `KEYCLOAK_ADMIN` for the initial admin username and `KEYCLOAK_ADMIN_PASSWORD` for the initial admin password. First, stop Keycloak -``` +```yaml systemctl stop keycloak.service ``` then start Keycloak by coping & pasting the following (only needed once) -``` +```yaml cd /opt/keycloak export KEYCLOAK_ADMIN=admin export KEYCLOAK_ADMIN_PASSWORD=changeme From b9d2260e5da0a200cde33a779c9413f288b54707 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 May 2022 17:48:41 -0400 Subject: [PATCH 2984/6505] Update omada-v3.sh --- ct/omada-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index 14a0bb12..be57d41d 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -324,7 +324,7 @@ pushd $TEMP_DIR >/dev/null export CTID=$CT_ID export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=18.04 +export PCT_OSVERSION=20.04 export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES From 4f682df9d6ee7819eeaceaf23996628986a54349 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 May 2022 19:11:54 -0400 Subject: [PATCH 2985/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index aed0760b..c6616cfb 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -80,8 +80,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL} + CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" @@ -108,13 +108,13 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged " read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Privileged" - CT_TYPE="0" + CT_TYPE1="Unprivileged" + CT_TYPE="1" echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" fi; echo -e " ${CM}${CL} \r" From 06ac9aebb500aaca50f0c2bb02eb0232de5f178d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 06:56:03 -0400 Subject: [PATCH 2986/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index c6616cfb..53ce0ab8 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -108,14 +108,14 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged " + echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else CT_TYPE1="Unprivileged" CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 From e7301f364e752629329327d68fe3741310b21dfa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 06:59:49 -0400 Subject: [PATCH 2987/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 53ce0ab8..651d395c 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -80,26 +80,26 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL} + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" + DISK_SIZE="8" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" VLAN="" } From 3be3cbcdaeb2dac311c1bedeb3551541b07f37b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 07:11:10 -0400 Subject: [PATCH 2988/6505] Update create_lxc.sh --- ct/create_lxc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 219ace7d..5bcce863 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -58,7 +58,7 @@ function select_storage() { done < <(pvesm status -content $CONTENT | awk 'NR>1') if [ $((${#MENU[@]}/3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + echo -e "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." elif [ $((${#MENU[@]}/3)) -eq 1 ]; then printf ${MENU[0]} @@ -80,7 +80,7 @@ function select_storage() { [ "$CTID" -ge "100" ] || die "ID cannot be less than 100." if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." + echo -e "ID '$CTID' is already in use." unset CTID die "Cannot use ID that is already in use." fi From 72ab9089ff8a3427de313d5dcc73d6548cda501f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 09:22:17 -0400 Subject: [PATCH 2989/6505] Update README.md --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 2df0dd33..24e4c91f 100644 --- a/README.md +++ b/README.md @@ -190,13 +190,6 @@ Run in the LXC console ```yaml ./update ``` -⚙️ **Migrate to the latest Update Menu** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/latest-update-menu.sh)" -``` - ____________________________________________________________________________________________
    From cee33ed1135b036677bdcc636b0645f6a7704466 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 11:59:21 -0400 Subject: [PATCH 2990/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index d03e409e..f1758c0c 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -65,7 +65,7 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null +sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 2850e53102f47d529415145102890d445bec8f4f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 16:42:26 -0400 Subject: [PATCH 2991/6505] Update haos_vm.sh --- vm/haos_vm.sh | 170 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 59 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a7f2cf3a..7478b7fe 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.0" +STABLE="8.1" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -12,6 +13,41 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} + +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null while true; do read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn @@ -54,10 +90,16 @@ function default_settings() { VMID=$NEXTID echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" VM_NAME=haos${STABLE} - echo -e "${DGN}Using ${BGN}2vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096MiB${CL}" - RAM_SIZE="4096" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" START_VM="yes" @@ -119,7 +161,7 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " read RAM_SIZE if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; @@ -132,8 +174,60 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Valid MAC Address, or Press [ENTER] for Generated MAC: $GEN_MAC " + read MAC + if [ -z $MAC ]; then MAC=$GEN_MAC; fi; + echo -en "${DGN}Set MAC Address To ${BL}$MAC${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " read START_VM if [ -z $START_VM ]; then START_VM="yes"; @@ -148,9 +242,12 @@ header_info echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}MiB${CL}" - echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" read -p "Are these settings correct(y/n)? " -n 1 -r echo @@ -171,51 +268,6 @@ function start_script() { start_script -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -228,7 +280,7 @@ while read -r line; do STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Disk image' needs to be selected for at least one storage location." + echo -e "'Disk image' needs to be selected for at least one storage location." die "Unable to detect valid storage location." elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} @@ -267,7 +319,7 @@ done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=vmbr0 \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null @@ -282,7 +334,7 @@ msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" msg_info "Adding Serial Port and Configuring Console" trap ' - warn "Unable to configure serial port. VM is still functional." + echo -e "Unable to configure serial port. VM is still functional." if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then qm set $VMID --delete serial0 >/dev/null fi From 35c74484d9591929229cf18bec0ad5083b311c6c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 17:55:21 -0400 Subject: [PATCH 2992/6505] Update haos_vm.sh --- vm/haos_vm.sh | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 7478b7fe..a2e6e109 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -328,39 +328,6 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null -set +o errtrace -( -msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" - -msg_info "Adding Serial Port and Configuring Console" -trap ' - echo -e "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VMID --delete serial0 >/dev/null - fi - exit - ' ERR -msg_ok "Added Serial Port and Configured Console" - if [ "$(command -v kpartx)" = "" ]; then - msg_info "Installing kpartx" - apt-get update >/dev/null - apt-get -qqy install kpartx &>/dev/null - msg_ok "Installed kpartx" - fi - DISK1_PATH="$(pvesm path $DISK1_REF)" - DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" - DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" - TEMP_MOUNT="${TEMP_DIR}/mnt" - trap ' - findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT - command -v kpartx >/dev/null && kpartx -d $DISK1_PATH - ' EXIT - kpartx -a $DISK1_PATH - mkdir $TEMP_MOUNT - mount $DISK1_PART1_PATH $TEMP_MOUNT - sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt - qm set $VMID -serial0 socket >/dev/null -) if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID From 26d922f837a5fe7b43ccd2293ddf379aec0d4bfe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 18:02:01 -0400 Subject: [PATCH 2993/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a2e6e109..f872c68d 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -328,6 +328,8 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null +msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" + if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID From b38e54392d5d957a682c0d8915b7e4c75a407ccd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 18:57:42 -0400 Subject: [PATCH 2994/6505] Update haos_vm.sh --- vm/haos_vm.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index f872c68d..27262f3a 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -328,6 +328,7 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null +qm set $VMID --delete local-lvm:vm-$VMID-disk-2 msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" if [ "$START_VM" == "yes" ]; then From c6dbf87328962e70d4faa7d8cda3c8a55c8f3551 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 19:05:38 -0400 Subject: [PATCH 2995/6505] Update haos_vm.sh --- vm/haos_vm.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 27262f3a..f872c68d 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -328,7 +328,6 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null -qm set $VMID --delete local-lvm:vm-$VMID-disk-2 msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" if [ "$START_VM" == "yes" ]; then From e5c6edae9f818668f001e9323a4aaf8e4a6844c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 19:13:58 -0400 Subject: [PATCH 2996/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index f872c68d..13147c8e 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -322,7 +322,7 @@ msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ -scsi0 ${DISK1_REF},size=32G >/dev/null From d1fb13f5aa7efa05cce2362f25a216d91f5554de Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 19:19:02 -0400 Subject: [PATCH 2997/6505] Update haos_vm.sh --- vm/haos_vm.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 13147c8e..ef59d398 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -309,7 +309,6 @@ case $STORAGE_TYPE in btrfs|nfs|dir) DISK_EXT=".qcow2" DISK_REF="$VMID/" - IMPORT_OPT="-format qcow2" esac for i in {0,1}; do disk="DISK$i" From 46e8dc3d296c62b6881e5f4409905ba3437e8112 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 19:33:55 -0400 Subject: [PATCH 2998/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 7478b7fe..ef59d398 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -309,7 +309,6 @@ case $STORAGE_TYPE in btrfs|nfs|dir) DISK_EXT=".qcow2" DISK_REF="$VMID/" - IMPORT_OPT="-format qcow2" esac for i in {0,1}; do disk="DISK$i" @@ -322,45 +321,14 @@ msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null -set +o errtrace -( msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" -msg_info "Adding Serial Port and Configuring Console" -trap ' - echo -e "Unable to configure serial port. VM is still functional." - if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then - qm set $VMID --delete serial0 >/dev/null - fi - exit - ' ERR -msg_ok "Added Serial Port and Configured Console" - if [ "$(command -v kpartx)" = "" ]; then - msg_info "Installing kpartx" - apt-get update >/dev/null - apt-get -qqy install kpartx &>/dev/null - msg_ok "Installed kpartx" - fi - DISK1_PATH="$(pvesm path $DISK1_REF)" - DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" - DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" - TEMP_MOUNT="${TEMP_DIR}/mnt" - trap ' - findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT - command -v kpartx >/dev/null && kpartx -d $DISK1_PATH - ' EXIT - kpartx -a $DISK1_PATH - mkdir $TEMP_MOUNT - mount $DISK1_PART1_PATH $TEMP_MOUNT - sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt - qm set $VMID -serial0 socket >/dev/null -) if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID From 5c0a1b683ff59482599484a16858aa8fc8f320aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 19:58:46 -0400 Subject: [PATCH 2999/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 55c90f6d..96cc5c61 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-21 + +### Changed + +- **Home Assistant OS VM** + - Code refactoring + ## 2022-05-19 ### Changed From 5568e7b40713b059a97dd6ddfeb4bb6949efddc1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 May 2022 19:59:28 -0400 Subject: [PATCH 3000/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 24e4c91f..ada310ec 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ ________________________________________________________________________________
    - Home Assistant OS VM + 🔸Home Assistant OS VM

    From 850272ffe0fd3558ca58c25d6df13757437f44e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 24 May 2022 10:43:25 -0400 Subject: [PATCH 3001/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 9a003ab4..38960670 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -72,7 +72,7 @@ apt-get -y install \ ocl-icd-libopencl1 \ beignet-opencl-icd &>/dev/null -#/bin/chgrp video /dev/dri +/bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" From 52e8fb5e14e34016a985925c5a0f827391bdec83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 24 May 2022 22:39:15 -0400 Subject: [PATCH 3002/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ada310ec..d67adc18 100644 --- a/README.md +++ b/README.md @@ -1474,7 +1474,7 @@ ________________________________________________________________________________
    - 🔸File Browser + File Browser

    From 5e318281b1345b07d7c52fd6a91f984293ad094e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 May 2022 20:28:10 -0400 Subject: [PATCH 3003/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d67adc18..19a5ca41 100644 --- a/README.md +++ b/README.md @@ -1611,7 +1611,7 @@ ________________________________________________________________________________
    - 🔸Keycloak LXC + Keycloak LXC

    From 95096cc89c2dffb4461f3a85a40ecbf5dd5ac963 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 May 2022 12:45:46 -0400 Subject: [PATCH 3004/6505] Update motioneye-install.sh --- setup/motioneye-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 36785c07..730a5266 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -62,6 +62,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y cifs-utils &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Motion" From 540f73305f97478b433abbe0ffa812fde229fec6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 May 2022 16:19:11 -0400 Subject: [PATCH 3005/6505] Create crowdsec-v3.sh --- misc/crowdsec-v3.sh | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 misc/crowdsec-v3.sh diff --git a/misc/crowdsec-v3.sh b/misc/crowdsec-v3.sh new file mode 100644 index 00000000..8c4b83e2 --- /dev/null +++ b/misc/crowdsec-v3.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="CrowdSec" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +while true; do + read -p "This will Install ${APP}. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + _____ _ _____ + / ____| | |/ ____| + | | _ __ _____ ____| | (___ ___ ___ + | | v3 | __/ _ \ \ /\ / / _ |\___ \ / _ \/ __| + | |____| | | (_) \ V V / (_| |____) | __/ (__ + \_____|_| \___/ \_/\_/ \__ _|_____/ \___|\___| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up ${APP} Repository" +curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash &>/dev/null +msg_ok "Setup ${APP} Repository" + +msg_info "Installing ${APP}" +apt-get update &>/dev/null +apt-get install -y crowdsec &>/dev/null +msg_ok "Installed ${APP}" + +msg_info "Installing ${APP} Common Bouncer" +apt-get install -y crowdsec-firewall-bouncer-iptables &>/dev/null +msg_ok "Installed ${APP} Common Bouncer" + +msg_ok "Completed Successfully!\n" From 32e2d75369f5e8779e9d2ec6113a4b0f6e483a43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 May 2022 22:03:35 -0400 Subject: [PATCH 3006/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 19a5ca41..2f381a86 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant OS VM + Home Assistant OS VM

    From b8ba61629a48ec8768d1cdef32c6640a3e059aea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 10:59:00 -0400 Subject: [PATCH 3007/6505] Update vaultwarden-update.sh --- misc/vaultwarden-update.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 3a7b9493..3f918c61 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -35,13 +35,12 @@ systemctl stop vaultwarden.service sleep 1 echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" -wget https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null -tar -xzf bw_web_$VWRELEASE.tar.gz &>/dev/null -cp -R web-vault /var/lib/vaultwarden/ &>/dev/null - -echo -e "${GN} Cleanup... ${CL}" -rm -r bw_web_$VWRELEASE.tar.gz web-vault -sleep 2 +curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null +if [ -d "/var/lib/vaultwarden" ]; then +tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null +else +tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null +fi echo -e "${GN} Starting Vaultwarden... ${CL}" systemctl start vaultwarden.service From e5e43d6611677fdea86d9f0b827eccde508def68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 11:06:14 -0400 Subject: [PATCH 3008/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index c8d287f2..8295542d 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -85,8 +85,8 @@ function default_settings() { CT_ID=$NEXTID echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" + echo -e "${DGN}Using Disk Size ${BGN}6${CL}${DGN}GB${CL}" + DISK_SIZE="6" echo -e "${DGN}Using ${BGN}4${CL}${DGN}vCPU${CL}" CORE_COUNT="4" echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" @@ -164,9 +164,9 @@ header_info echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 6 " read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; + if [ -z $DISK_SIZE ]; then DISK_SIZE="6"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e " ${CM}${CL} \r" @@ -346,6 +346,11 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 512 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8000${CL} \n" From c18c620c221ee6be1325f5d4673c02ef077b5962 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 11:09:34 -0400 Subject: [PATCH 3009/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 120 +++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 92c616c7..39d2f29a 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -42,7 +42,7 @@ msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] @@ -51,9 +51,15 @@ while [ "$(hostname -I)" = "" ]; do exit 1 fi done -msg_ok "Set up Container OS" +msg_ok "Setup Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if : >/dev/tcp/8.8.8.8/53; then + msg_ok "Internet Online" +else + echo -e "${BFR} ${CROSS}${RD} Internet Offline" +fi + msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null @@ -63,69 +69,63 @@ msg_info "Installing Dependencies" apt-get update &>/dev/null apt-get -qqy install \ git \ - nano \ - wget \ - htop \ - pkg-config \ - openssl \ - libssl1.1 \ + build-essential \ + pkgconf \ libssl-dev \ + libmariadb-dev-compat \ + libpq-dev \ curl \ sudo &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing Build Essentials" -apt-get install -y build-essential &>/dev/null -msg_ok "Installed Build Essentials" +WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ + +VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ msg_info "Installing Rust" -curl https://sh.rustup.rs -sSf | sh -s -- -y &>/dev/null +curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal &>/dev/null echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null export PATH=~/.cargo/bin:$PATH &>/dev/null which rustc &>/dev/null msg_ok "Installed Rust" -msg_info "Installing Node.js" -curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -apt-get install -y nodejs &>/dev/null -npm -g install npm@7 &>/dev/null -which npm &>/dev/null -npm i npm@latest -g &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Building Vaultwarden (Patience)" +msg_info "Building Vaultwarden ${VAULT} (Patience)" git clone https://github.com/dani-garcia/vaultwarden &>/dev/null -pushd vaultwarden &>/dev/null -cargo clean &>/dev/null -cargo build --features sqlite --release &>/dev/null -file target/release/vaultwarden &>/dev/null -msg_ok "Built Vaultwarden" +cd vaultwarden +cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null +msg_ok "Built Vaultwarden ${VAULT}" -msg_info "Building Web-Vault" -pushd target/release/ &>/dev/null -git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null -cd web-vault.git &>/dev/null -git checkout v2.25.1 &>/dev/null -git submodule update --init --recursive &>/dev/null -wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null -git apply v2.25.0.patch &>/dev/null -npm ci --silent --legacy-peer-deps &>/dev/null -npm audit fix --silent --legacy-peer-deps || true &>/dev/null -npm run --silent dist:oss:selfhost &>/dev/null -cp -a build ../web-vault &>/dev/null -cd .. -mkdir data -msg_ok "Built Web-Vault" +addgroup --system vaultwarden &>/dev/null +adduser --system --home /opt/vaultwarden --shell /usr/sbin/nologin --no-create-home --gecos 'vaultwarden' --ingroup vaultwarden --disabled-login --disabled-password vaultwarden &>/dev/null +mkdir -p /opt/vaultwarden/bin +mkdir -p /opt/vaultwarden/data +cp target/release/vaultwarden /opt/vaultwarden/bin/ + +msg_info "Downloading Web-Vault ${WEBVAULT}" +wget https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null +tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ &>/dev/null +rm -f bw_web_$WEBVAULT.tar.gz +msg_ok "Downloaded Web-Vault ${WEBVAULT}" + +cat < /opt/vaultwarden/.env +## https://github.com/dani-garcia/vaultwarden/blob/main/.env.template +ROCKET_ADDRESS=0.0.0.0 +DATA_FOLDER=/opt/vaultwarden/data +DATABASE_MAX_CONNS=10 +WEB_VAULT_FOLDER=/opt/vaultwarden/web-vault +WEB_VAULT_ENABLED=true +EOF msg_info "Creating Service" -cp ../../.env.template /etc/vaultwarden.env &>/dev/null -cp vaultwarden /usr/bin/vaultwarden &>/dev/null -chmod +x /usr/bin/vaultwarden &>/dev/null -useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null -sudo cp -R data /var/lib/vaultwarden/ &>/dev/null -cp -R web-vault /var/lib/vaultwarden/ &>/dev/null -chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null - +chown -R vaultwarden:vaultwarden /opt/vaultwarden/ +chown root:root /opt/vaultwarden/bin/vaultwarden +chmod +x /opt/vaultwarden/bin/vaultwarden +chown -R root:root /opt/vaultwarden/web-vault/ +chmod +r /opt/vaultwarden/.env service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null echo "[Unit] @@ -135,21 +135,29 @@ After=network.target [Service] User=vaultwarden Group=vaultwarden -EnvironmentFile=/etc/vaultwarden.env -ExecStart=/usr/bin/vaultwarden -LimitNOFILE=1048576 +EnvironmentFile=-/opt/vaultwarden/.env +ExecStart=/opt/vaultwarden/bin/vaultwarden +LimitNOFILE=65535 +LimitNPROC=4096 PrivateTmp=true PrivateDevices=true ProtectHome=true ProtectSystem=strict -WorkingDirectory=/var/lib/vaultwarden -ReadWriteDirectories=/var/lib/vaultwarden +DevicePolicy=closed +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictNamespaces=yes +RestrictRealtime=yes +MemoryDenyWriteExecute=yes +LockPersonality=yes +WorkingDirectory=/opt/vaultwarden +ReadWriteDirectories=/opt/vaultwarden/data AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target" > $service_path systemctl daemon-reload -systemctl enable vaultwarden.service &>/dev/null -systemctl start vaultwarden.service &>/dev/null +systemctl enable --now vaultwarden.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 091dc4b758c5945151b9e485db9ee6715645e176 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 11:12:34 -0400 Subject: [PATCH 3010/6505] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2f381a86..4de88c19 100644 --- a/README.md +++ b/README.md @@ -1661,22 +1661,20 @@ ________________________________________________________________________________

    Vaultwarden LXC

    +Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream [Bitwarden clients](https://bitwarden.com/download/), perfect for self-hosted deployment where running the official resource-heavy service might not be ideal. + To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden-v3.sh)" ``` ⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. - -⚠️ If you find the Vaultwarden Interface unreachable, `nano /etc/vaultwarden.env` and uncomment `ROCKET_ADDRESS=0.0.0.0` and reboot -It builds from source, which takes time and resources. After the installation, resources can be set to Normal Settings. +The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. Expect 30+ minute install time. -

    ⚡ Normal Settings: 512Mib RAM - 8GB Storage - 1vCPU ⚡

    +

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    -[Clients](https://bitwarden.com/download/) - **Vaultwarden Interface - IP:8000** ⚙️ **To Update Vaultwarden** From b3d1982c312f78267d7b73edbf3e3b2e70a30b8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 11:16:41 -0400 Subject: [PATCH 3011/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4de88c19..e37362f8 100644 --- a/README.md +++ b/README.md @@ -1655,7 +1655,7 @@ ________________________________________________________________________________
    - Vaultwarden LXC + 🔸Vaultwarden LXC

    From 1633fff3016dcd534c2ee945d3c6564ebe93dcb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 11:19:12 -0400 Subject: [PATCH 3012/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 96cc5c61..3fe18354 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-05-29 + +### Changed + +- **Vaultwarden LXC** + - Code refactoring + ## 2022-05-21 ### Changed From 376735a2b35e5f3ae17a64dc26233fffd6acf089 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 11:35:07 -0400 Subject: [PATCH 3013/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 39d2f29a..5f685643 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -106,9 +106,10 @@ mkdir -p /opt/vaultwarden/data cp target/release/vaultwarden /opt/vaultwarden/bin/ msg_info "Downloading Web-Vault ${WEBVAULT}" -wget https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null +#wget https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null +curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ &>/dev/null -rm -f bw_web_$WEBVAULT.tar.gz +#rm -f bw_web_$WEBVAULT.tar.gz msg_ok "Downloaded Web-Vault ${WEBVAULT}" cat < /opt/vaultwarden/.env From c5e16ecec7aee56242a407bf6b7030ab55365618 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 12:10:32 -0400 Subject: [PATCH 3014/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 5f685643..ec2380c2 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -107,7 +107,7 @@ cp target/release/vaultwarden /opt/vaultwarden/bin/ msg_info "Downloading Web-Vault ${WEBVAULT}" #wget https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null -curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null +curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ &>/dev/null #rm -f bw_web_$WEBVAULT.tar.gz msg_ok "Downloaded Web-Vault ${WEBVAULT}" From c79c2c684e9b2a27020ff7bfb55c3bc612970296 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 12:51:21 -0400 Subject: [PATCH 3015/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index ec2380c2..9908bf0b 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -106,10 +106,8 @@ mkdir -p /opt/vaultwarden/data cp target/release/vaultwarden /opt/vaultwarden/bin/ msg_info "Downloading Web-Vault ${WEBVAULT}" -#wget https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ &>/dev/null -#rm -f bw_web_$WEBVAULT.tar.gz msg_ok "Downloaded Web-Vault ${WEBVAULT}" cat < /opt/vaultwarden/.env From 72f11a3b976aa0e036da9c1f4d92269b35b59929 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 14:48:31 -0400 Subject: [PATCH 3016/6505] Update README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index e37362f8..fd1a3a3d 100644 --- a/README.md +++ b/README.md @@ -1610,6 +1610,27 @@ ________________________________________________________________________________
    +
    + 🔸CrowdSec + +

    + +

    CrowdSec

    + +To Install CrowdSec, ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec-v3.sh)" +``` + +[CrowdSec](https://crowdsec.net/) is a free, open-source and collaborative IPS. Analyze behaviors, respond to attacks & share signals across the community. + +[**Control center for your CrowdSec machines.**](https://app.crowdsec.net/product-tour) + +___________________________________________________________________________________________ + +
    +
    Keycloak LXC From eb9ab108efa85c9c3a2084172037efc0f309ddea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 May 2022 14:51:05 -0400 Subject: [PATCH 3017/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3fe18354..d687202c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - **Vaultwarden LXC** - Code refactoring +- **CrowdSec** + - NEW Script. ## 2022-05-21 From 4c695676094aa484a0b740d9d7d5ff28f14327b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Jun 2022 09:09:21 -0400 Subject: [PATCH 3018/6505] Update README.md --- README.md | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/README.md b/README.md index fd1a3a3d..e37362f8 100644 --- a/README.md +++ b/README.md @@ -1610,27 +1610,6 @@ ________________________________________________________________________________
    -
    - 🔸CrowdSec - -

    - -

    CrowdSec

    - -To Install CrowdSec, ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec-v3.sh)" -``` - -[CrowdSec](https://crowdsec.net/) is a free, open-source and collaborative IPS. Analyze behaviors, respond to attacks & share signals across the community. - -[**Control center for your CrowdSec machines.**](https://app.crowdsec.net/product-tour) - -___________________________________________________________________________________________ - -
    -
    Keycloak LXC From 53ed649a79bdb1d5ef7d7c43f9def16d15c598f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Jun 2022 09:12:18 -0400 Subject: [PATCH 3019/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d687202c..cbf57931 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-06-01 + +### Changed + +- **CrowdSec** + - Removed until CrowdSec/packagecloud resolves issues + ## 2022-05-29 ### Changed From 5185927bfb50799bb4855dc7f8ceabe9d9851314 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Jun 2022 08:59:09 -0400 Subject: [PATCH 3020/6505] Update README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index e37362f8..fd1a3a3d 100644 --- a/README.md +++ b/README.md @@ -1610,6 +1610,27 @@ ________________________________________________________________________________
    +
    + 🔸CrowdSec + +

    + +

    CrowdSec

    + +To Install CrowdSec, ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec-v3.sh)" +``` + +[CrowdSec](https://crowdsec.net/) is a free, open-source and collaborative IPS. Analyze behaviors, respond to attacks & share signals across the community. + +[**Control center for your CrowdSec machines.**](https://app.crowdsec.net/product-tour) + +___________________________________________________________________________________________ + +
    +
    Keycloak LXC From 3c986d36b0de823ebf1d141830fe360002b4a3f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Jun 2022 09:01:11 -0400 Subject: [PATCH 3021/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index cbf57931..d687202c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,13 +5,6 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) -## 2022-06-01 - -### Changed - -- **CrowdSec** - - Removed until CrowdSec/packagecloud resolves issues - ## 2022-05-29 ### Changed From 9d27a09f0350cb2197bccf08f7eb2a5ef91cb59c Mon Sep 17 00:00:00 2001 From: Jonathan Dumont <5204724+JOduMonT@users.noreply.github.com> Date: Fri, 3 Jun 2022 05:48:51 +0700 Subject: [PATCH 3022/6505] gnupg is required by crowdsec/script.deb.sh --- misc/crowdsec-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/crowdsec-v3.sh b/misc/crowdsec-v3.sh index 8c4b83e2..77460345 100644 --- a/misc/crowdsec-v3.sh +++ b/misc/crowdsec-v3.sh @@ -60,11 +60,12 @@ function msg_ok() { } msg_info "Setting up ${APP} Repository" +apt-get update &>/dev/null +apt-get install -y gnupg &>/dev/null curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash &>/dev/null msg_ok "Setup ${APP} Repository" msg_info "Installing ${APP}" -apt-get update &>/dev/null apt-get install -y crowdsec &>/dev/null msg_ok "Installed ${APP}" From f1f815877db9fcc8cfeed229f2cb08067b98afb7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Jun 2022 20:02:57 -0400 Subject: [PATCH 3023/6505] Update crowdsec-v3.sh --- misc/crowdsec-v3.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/crowdsec-v3.sh b/misc/crowdsec-v3.sh index 77460345..0ab6d5c3 100644 --- a/misc/crowdsec-v3.sh +++ b/misc/crowdsec-v3.sh @@ -66,6 +66,7 @@ curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.de msg_ok "Setup ${APP} Repository" msg_info "Installing ${APP}" +apt-get update &>/dev/null apt-get install -y crowdsec &>/dev/null msg_ok "Installed ${APP}" From 0d737464e7c6545726d07ca49a6b0e3cdb026976 Mon Sep 17 00:00:00 2001 From: damda58 Date: Sat, 4 Jun 2022 13:41:17 +0200 Subject: [PATCH 3024/6505] add ffmpeg add install ffmpeg for video --- setup/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 17c9a601..82fae860 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -76,6 +76,7 @@ apt-get install -y gnupg &>/dev/null apt-get install -y make &>/dev/null apt-get install -y zip &>/dev/null apt-get install -y unzip &>/dev/null +apt-get install -y ffmpeg &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" From eb7207325b1fa38c819926590d7dd1d64d9c8bea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Jun 2022 04:57:56 -0400 Subject: [PATCH 3025/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fd1a3a3d..6c77de27 100644 --- a/README.md +++ b/README.md @@ -1611,7 +1611,7 @@ ________________________________________________________________________________
    - 🔸CrowdSec + CrowdSec

    @@ -1676,7 +1676,7 @@ ________________________________________________________________________________
    - 🔸Vaultwarden LXC + Vaultwarden LXC

    From 0eab8c58d44810fe0174b66dd7967f6c4143865b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Jun 2022 09:49:02 -0400 Subject: [PATCH 3026/6505] add jellyfin-ffmpeg --- setup/jellyfin-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 38960670..bc116748 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -86,6 +86,7 @@ msg_ok "Set Up Jellyfin Repository" msg_info "Installing Jellyfin" apt-get update &>/dev/null sudo apt install jellyfin-server -y &>/dev/null +apt install jellyfin-ffmpeg -y &>/dev/null msg_ok "Installed Jellyfin" msg_info "Creating Service" From edc28c0de739ef97828125bc770e25656c066bc2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 06:34:00 -0400 Subject: [PATCH 3027/6505] Create whoogle-v3.sh --- ct/whoogle-v3.sh | 355 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 ct/whoogle-v3.sh diff --git a/ct/whoogle-v3.sh b/ct/whoogle-v3.sh new file mode 100644 index 00000000..49860be8 --- /dev/null +++ b/ct/whoogle-v3.sh @@ -0,0 +1,355 @@ +#!/usr/bin/env bash +APP="Whoogle" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +PP=`echo "\e[1;35m"` +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${PP} + __ ___ _ ____ ____ _____ _ ______ + \ \ v3 / / | | |/ __ \ / __ \ / ____| | | ____| + \ \ /\ / /| |__| | | | | | | | | __| | | |__ + \ \/ \/ / | __ | | | | | | | | |_ | | | __| + \ /\ / | | | | |__| | |__| | |__| | |____| |____ + \/ \/ |_| |_|\____/ \____/ \_____|______|______| +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From 5092a0a36ca8582af030cf65ae0b2d12067cddc3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 06:34:57 -0400 Subject: [PATCH 3028/6505] Create whoogle-install.sh --- setup/whoogle-install.sh | 115 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 setup/whoogle-install.sh diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh new file mode 100644 index 00000000..e311786b --- /dev/null +++ b/setup/whoogle-install.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if : >/dev/tcp/8.8.8.8/53; then + msg_ok "Internet Online" +else + echo -e "${BFR} ${CROSS}${RD} Internet Offline" +fi + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing pip3" +apt-get install python3-pip -y &>/dev/null +msg_ok "Installed pip3" + +msg_info "Installing Whoogle" +pip install whoogle-search &>/dev/null + +service_path="/etc/systemd/system/whoogle.service" +echo "[Unit] +Description=ESPHome Dashboard +After=network.target +[Service] +ExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0 +Restart=always +User=root +[Install] +WantedBy=multi-user.target" > $service_path + +systemctl enable --now whoogle.service &>/dev/null +msg_ok "Installed Whoogle" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From eb4dd3e2be550e5e8247567e1e19a9bde0ecd839 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 06:41:56 -0400 Subject: [PATCH 3029/6505] Add files via upload --- misc/images/whoogle.png | Bin 0 -> 4477 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/whoogle.png diff --git a/misc/images/whoogle.png b/misc/images/whoogle.png new file mode 100644 index 0000000000000000000000000000000000000000..9a6a997cdd5e22734aaa2c02614f401035dce313 GIT binary patch literal 4477 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 Date: Mon, 6 Jun 2022 06:43:13 -0400 Subject: [PATCH 3030/6505] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 6c77de27..d63a70b5 100644 --- a/README.md +++ b/README.md @@ -1303,6 +1303,35 @@ ________________________________________________________________________________
    +
    + 🔸Whoogle LXC + +

    + +

    Whoogle LXC

    + +Get Google search results, but without any ads, javascript, AMP links, cookies, or IP address tracking. + +To create a new Proxmox Whoogle LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/whoogle-v3.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Whoogle Interface - IP:5000** + +⚙️ **To Update Whoogle** + +Run in the LXC console +```yaml +pip3 install whoogle-search --upgrade +``` +____________________________________________________________________________________________ + +
    +
    Heimdall Dashboard LXC From ba3d65c2f5136c5745548d27a6109a9d368318e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 06:45:26 -0400 Subject: [PATCH 3031/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d687202c..7fcb7e75 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. ### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) +## 2022-06-06 + +### Changed + +- **Whoogle LXC** + - NEW Script + ## 2022-05-29 ### Changed @@ -12,7 +19,7 @@ All notable changes to this project will be documented in this file. - **Vaultwarden LXC** - Code refactoring - **CrowdSec** - - NEW Script. + - NEW Script ## 2022-05-21 @@ -26,49 +33,49 @@ All notable changes to this project will be documented in this file. ### Changed - **Keycloak LXC** - - NEW Script. + - NEW Script ## 2022-05-18 ### Changed - **File Browser** - - NEW Script. + - NEW Script ## 2022-05-13 ### Changed - **PostgreSQL LXC** - - NEW Script. + - NEW Script ## 2022-05-10 ### Changed - **deCONZ LXC** - - NEW Script. + - NEW Script ## 2022-05-07 ### Changed - **NocoDB LXC** - - ADD update script. + - ADD update script ## 2022-05-06 ### Changed - **PhotoPrism LXC** - - ADD GO Dependencies for full functionality. + - ADD GO Dependencies for full functionality ## 2022-05-05 ### Changed - **Ubuntu LXC** - - ADD option to define version (18.04 20.04 21.10 22.04). + - ADD option to define version (18.04 20.04 21.10 22.04) ## 2022-04-28 From 3e1791709c7e6f4b9f2fc91054229c77e5e1ebe3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 06:47:36 -0400 Subject: [PATCH 3032/6505] Update whoogle-v3.sh --- ct/whoogle-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/whoogle-v3.sh b/ct/whoogle-v3.sh index 49860be8..01c2c1ca 100644 --- a/ct/whoogle-v3.sh +++ b/ct/whoogle-v3.sh @@ -346,7 +346,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') From b8e2c5f3f9bfa6d3c4d1561ba28731a511671032 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 09:05:27 -0400 Subject: [PATCH 3033/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d63a70b5..46e83ab5 100644 --- a/README.md +++ b/README.md @@ -1297,7 +1297,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/uptimekuma-update.sh)" + ``` ____________________________________________________________________________________________ From 1a79970d42d966cc0f3b5ff98301d65cb72a3b31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 09:27:41 -0400 Subject: [PATCH 3034/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 46e83ab5..d63a70b5 100644 --- a/README.md +++ b/README.md @@ -1297,7 +1297,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v Run in the LXC console ```yaml - +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/uptimekuma-update.sh)" ``` ____________________________________________________________________________________________ From 71c5193ed94057a450058afbd36893a0c5b1decc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Jun 2022 14:20:24 -0400 Subject: [PATCH 3035/6505] Update Golang Version to 1.18.3 --- setup/photoprism-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 82fae860..2dc628b1 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -88,8 +88,8 @@ apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Golang" -wget https://golang.org/dl/go1.18.1.linux-amd64.tar.gz &>/dev/null -tar -xzf go1.18.1.linux-amd64.tar.gz -C /usr/local &>/dev/null +wget https://golang.org/dl/go1.18.3.linux-amd64.tar.gz &>/dev/null +tar -xzf go1.18.3.linux-amd64.tar.gz -C /usr/local &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null go install github.com/tianon/gosu@latest &>/dev/null go install golang.org/x/tools/cmd/goimports@latest &>/dev/null From b39f830b665f3d9e96cf37e7c89fa87579eaaddd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:05:46 -0400 Subject: [PATCH 3036/6505] Remove Internet Check --- setup/debian-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 665613d6..e7c6af98 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -54,12 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 44daa16f77d5d8934fb32c78cf98601cba344535 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:06:32 -0400 Subject: [PATCH 3037/6505] Remove Internet Check --- setup/deconz-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index a0fbe4b5..e367205f 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -54,12 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 33a5d2b95fe1becabf7854b652c22ea0b3abd716 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:10:00 -0400 Subject: [PATCH 3038/6505] Remove Internet Check --- setup/keycloak-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index 47ad6547..53da44b8 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -54,12 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 8fe0e1f9702e7b2b3f43606d797c3ae57db458aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:12:18 -0400 Subject: [PATCH 3039/6505] Remove Internet Check --- setup/photoprism-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 2dc628b1..9ad97e85 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -55,12 +55,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From d98279bec7d5583b0880e7ef81ae43ddb2f30e25 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:13:34 -0400 Subject: [PATCH 3040/6505] Remove Internet Check --- setup/postgresql-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 43b8ed1a..8cbc6aa3 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -54,12 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -qqy upgrade &>/dev/null From 4e4d64c1006764b8eb4e4119874424f29191ef91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:14:31 -0400 Subject: [PATCH 3041/6505] Remove Internet Check --- setup/ubuntu-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 854317a0..bc311688 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -54,12 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From d696833540286078d6611dbf5f9be9ea80c70714 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:15:34 -0400 Subject: [PATCH 3042/6505] Remove Internet Check --- setup/vaultwarden-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 9908bf0b..5aa2554d 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -54,12 +54,6 @@ done msg_ok "Setup Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 40d565e9ad6a71e7edbf58c2f4d86d6ad543d6bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 07:16:05 -0400 Subject: [PATCH 3043/6505] Remove Internet Check --- setup/whoogle-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index e311786b..66c3614b 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -54,12 +54,6 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if : >/dev/tcp/8.8.8.8/53; then - msg_ok "Internet Online" -else - echo -e "${BFR} ${CROSS}${RD} Internet Offline" -fi - msg_info "Updating Container OS" apt update &>/dev/null apt-get -qqy upgrade &>/dev/null From 4fdfb565b9644be644eb2d06f82b91003f94f44b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Jun 2022 10:28:00 -0400 Subject: [PATCH 3044/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7fcb7e75..0f87091b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,7 +3,6 @@ # Change Log All notable changes to this project will be documented in this file. -### ⚠️ [IMPORTANT NOTICE](https://github.com/tteck/Proxmox/issues/71#issue-1169207591) ## 2022-06-06 From eba084217cc6140f6c5b2f5903de98a3111e7be2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Jun 2022 12:35:00 -0400 Subject: [PATCH 3045/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 5aa2554d..78c22b10 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -106,6 +106,7 @@ msg_ok "Downloaded Web-Vault ${WEBVAULT}" cat < /opt/vaultwarden/.env ## https://github.com/dani-garcia/vaultwarden/blob/main/.env.template +# ADMIN_TOKEN=Vy2VyYTTsKPv8W5aEOWUbB/Bt3DEKePbHmI4m9VcemUMS2rEviDowNAFqYi1xjmp ROCKET_ADDRESS=0.0.0.0 DATA_FOLDER=/opt/vaultwarden/data DATABASE_MAX_CONNS=10 From 52a305be7afcd2fa284662624f9e91035b9da21f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Jun 2022 08:39:00 -0400 Subject: [PATCH 3046/6505] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d63a70b5..1fa0cc48 100644 --- a/README.md +++ b/README.md @@ -1727,6 +1727,11 @@ Expect 30+ minute install time. **Vaultwarden Interface - IP:8000** +⚙️ **Path to Vaultwarden .env file** (to enable `ADMIN_TOKEN`) +```yaml +/opt/vaultwarden/.env +``` + ⚙️ **To Update Vaultwarden** Run in the LXC console From 0a04dbdd93c76ceb191e7823752eb14780336efc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Jun 2022 10:38:56 -0400 Subject: [PATCH 3047/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1fa0cc48..f9f33e64 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

    Select a Proxmox Helper

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    - 🔸 + 🔸
    Proxmox VE 7 Post Install From 4fab50641ed91359423b7144dd28c489138284b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Jun 2022 10:41:05 -0400 Subject: [PATCH 3048/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9f33e64..1fa0cc48 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

    Select a Proxmox Helper

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    - 🔸 + 🔸
    Proxmox VE 7 Post Install From ddcdf06660c9b17d5c2ef6ded478311a12faa80b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Jun 2022 04:34:01 -0400 Subject: [PATCH 3049/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1fa0cc48..1a604360 100644 --- a/README.md +++ b/README.md @@ -1304,7 +1304,7 @@ ________________________________________________________________________________
    - 🔸Whoogle LXC + Whoogle LXC

    From f68df8a372fffbbc3bcfdb15d758fbeeaad13213 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Tue, 14 Jun 2022 20:51:54 +0200 Subject: [PATCH 3050/6505] Update for Alpine Linux LXCs The script now take a look at the ostype of the LXC and afterwards will choose the right update commands to progress. --- misc/update-lxcs.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 369631f4..d179b866 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -35,7 +35,14 @@ function update_container() { clear header_info echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" - pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" + pct config $container > temp + os=`awk '/^ostype/' temp | cut -d' ' -f2` + if [ "$os" == "alpine" ] + then + pct exec $container -- ash -c "apk update && apk upgrade" + else + pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" + fi } read -p "Skip stopped containers? " -n 1 -r echo @@ -69,4 +76,5 @@ do fi done; wait +rm temp echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From e66363333a6ac8fd8fbb1126cd971a46ef674caa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Jun 2022 15:32:42 -0400 Subject: [PATCH 3051/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index 0820e29b..56b2afe9 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -91,8 +91,8 @@ function default_settings() { DISK_SIZE="4" echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" + echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="1024" echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" @@ -196,9 +196,9 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; + if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 From 3f62f3398f1b0d54069506cb54b2459663e53cd6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Jun 2022 15:41:27 -0400 Subject: [PATCH 3052/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a604360..e3c422d8 100644 --- a/README.md +++ b/README.md @@ -1289,7 +1289,7 @@ To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell. bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v3.sh)" ``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    +

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1vCPU ⚡

    **Uptime Kuma Interface - IP:3001** From fd24fe4cfed3b58b42d773e5b0de3548867f0fba Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Jun 2022 15:57:33 -0400 Subject: [PATCH 3053/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index 2106071d..70e77dcb 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash -ex +LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -11,7 +12,7 @@ HOLD="-" CM="${GN}✓${CL}" APP="Uptime Kuma" while true; do - read -p "This will Update ${APP} LXC. Proceed(y/n)?" yn + read -p "This will Update ${APP} to ${LATEST}. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -45,24 +46,24 @@ function msg_ok() { } -msg_info "Stopping Uptime Kuma" +msg_info "Stopping ${APP}" sudo systemctl stop uptime-kuma &>/dev/null -msg_ok "Stopped Uptime Kuma" +msg_ok "Stopped ${APP}" cd /opt/uptime-kuma -msg_info "Pulling Uptime Kuma" +msg_info "Pulling ${APP} ${LATEST}" git fetch &>/dev/null -git checkout master &>/dev/null +git checkout $LATEST &>/dev/null git pull &>/dev/null -msg_ok "Pulled Uptime Kuma" +msg_ok "Pulled ${APP} ${LATEST}" -msg_info "Updating Uptime Kuma (Patience)" +msg_info "Updating ${APP} to ${LATEST} (Patience)" npm ci &>/dev/null -msg_ok "Updated Uptime Kuma" +msg_ok "Updated ${APP}" -msg_info "Starting Uptime Kuma" +msg_info "Starting ${APP}" sudo systemctl start uptime-kuma &>/dev/null -msg_ok "Started Uptime Kuma" +msg_ok "Started ${APP}" msg_ok "Done!" From c44576efbfd4229ed40d838fe88610b8951847c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Jun 2022 08:15:01 -0400 Subject: [PATCH 3054/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index ef59d398..9e0e26e1 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.1" +STABLE="8.2" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From e21e413ee5401213232b4c128b04e211c452ac13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Jun 2022 13:21:53 -0400 Subject: [PATCH 3055/6505] Update whoogle-install.sh --- setup/whoogle-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index 66c3614b..ce4803f6 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -73,7 +73,7 @@ pip install whoogle-search &>/dev/null service_path="/etc/systemd/system/whoogle.service" echo "[Unit] -Description=ESPHome Dashboard +Description=Whoogle-Search After=network.target [Service] ExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0 From 758004ac18b830ed7db1d083fbcb2b012b803ca8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Jun 2022 08:46:55 -0400 Subject: [PATCH 3056/6505] Update post-install-v3.sh --- misc/post-install-v3.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/misc/post-install-v3.sh b/misc/post-install-v3.sh index 2d56301c..19926093 100644 --- a/misc/post-install-v3.sh +++ b/misc/post-install-v3.sh @@ -103,5 +103,10 @@ echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxli apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag" fi -msg_ok "Finished....Please Update Proxmox" + +msg_info "Updating Proxmox" +sleep 2 +apt-get update +apt-get dist-upgrade +msg_ok "Finished" From 95b59f5aaa8235a06456d9f83f28ad779377eb37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Jun 2022 16:26:04 -0400 Subject: [PATCH 3057/6505] Set up a Home Assistant OS VM using Proxmox VE 7 (2022) --- misc/set-up-haosvm-using-proxmox-7.md | 75 +++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 misc/set-up-haosvm-using-proxmox-7.md diff --git a/misc/set-up-haosvm-using-proxmox-7.md b/misc/set-up-haosvm-using-proxmox-7.md new file mode 100644 index 00000000..1ddab901 --- /dev/null +++ b/misc/set-up-haosvm-using-proxmox-7.md @@ -0,0 +1,75 @@ +# Set up a Home Assistant OS VM using Proxmox VE 7 (2022) + +This guide will help you set up a Home Assistant OS VM, on almost any x86/64 machine type you choose using Proxmox VE 7 as the operating system. +This guide also utilizes scripts to simplify the installation process, always remember to use due diligence when sourcing scripts and automation tasks from third-party sites. + +This installation uses an **Official KVM Image provided by the Home Assistant Team and is considered a supported installation method**. This method of installation is considered easy/medium difficulty and some knowledge of how to use and interact with Linux is suggested. + +If you have an existing Home Assistant installation and would like to know how to backup your current configuration to restore later, please see the documentation on [backing up and restoring your configuration](https://www.home-assistant.io/common-tasks/supervised/#making-a-backup-from-the-ui). + +## Installing Proxmox VE 7 + +* You will want to ensure **UEFI Boot & Virtualisation is enabled and Secure Boot is disabled** in the [bios](https://www.lifewire.com/how-to-enter-bios-2624481) of your machine. + +* Download the [Proxmox VE 7.x ISO Installer](https://www.proxmox.com/en/downloads/category/iso-images-pve). + +* You will now need to make a bootable USB drive using [balenaEtcher](https://www.balena.io/etcher/). Using a USB drive of at least **8gb**, insert it into your PC, open Etcher, select the Proxmox VE image you just downloaded, select your USB drive, then click Flash. + +* Insert the bootable USB drive you just made into the machine you wish to install Proxmox VE on. Connect a monitor, Ethernet cable, keyboard, mouse, and power on the machine. If the machine doesn't boot from the USB drive automatically, you will need to enter the boot options menu by pressing Esc, F2, F10 or F12, (This relies on the company of the computer or motherboard) on your keyboard immediately when the machine is powering on. + +* When you see the first screen, select Install Proxmox VE and press Enter. The installer will perform some automated tasks for 1-2 minutes. + +* On the EULA screen, select, I Agree. + +* On the Proxmox Virtualization Environment (PVE) screen, you will get the option to choose which disk you want to install Proxmox VE on. When finished, click Next. + +* On the Location and Time Zone selection, Type your country, then select your time zone and change the keyboard layout if needed. When finished, click Next + +* On the Administration password and E-mail address screen, choose a password (**make sure you don’t forget it**), confirm your password and enter a valid email address. When finished, click Next + +* On the Management network configuration screen. + * Management interface Should auto populate with the network interface (Ethernet) of your machine. If not, select the network interface. + * Hostname (FQDN) - The first part of the hostname is what your node will be called under Datacenter, you might want to change this to something more friendly now, the default is “pve” (eg. proxmox.lan). + * IP Address - Should auto populate. If the IP address looks odd here and not at all like the address range of your other devices, it’s possible you may not be connected to your network, so check your network cable and start again. + * Netmask - Should auto populate and be something like `255.255.255.0` depending on your network configuration. + * Gateway - Should auto populate to the IP address of your router. If not, make sure you're connected to your network + * DNS server - Should auto populate to the same IP address as your gateway. Or, input one of your choosing. When finished, click Next + +* Next on the Summary screen, confirm that all of the details are correct. When confirmed click Install. + +Proxmox VE will install and is finished once it displays its IP address on the screen. **Take note of the IP address!** It's needed to access Proxmox via a web browser. Remove the USB drive, and click Reboot. While the machine is rebooting, you can unplug the monitor, keyboard and mouse, as they're no longer needed. + +After 1-2 minutes, you should be able to access Proxmox VE via a web browser using the noted IP address from above (eg. `http://192.168.1.10:8006`) If you see a message "Warning: Potential Security Risk Ahead", you can safely ignore this, accept the risk and continue. Login with User name: `root` and the password you created on the Administration password and E-mail address screen. + +## Configuring and Updating Proxmox VE 7 + +Before installing Home Assistant OS, you will want to make sure that Proxmox VE has the latest updates and security patches installed. This has been made very simple with a [script](https://github.com/tteck/Proxmox/raw/main/misc/post-install-v3.sh). + +To run the Proxmox VE 7 Post Install script, copy and paste the following command in the Proxmox Shell. +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-install-v3.sh)" +``` +It's recommended to answer `y` to all questions. + +## Installing Home Assistant OS + +Installing Home Assistant OS using Proxmox VE has been made very simple with a [script](https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v3.sh). + +To run the Home Assistant OS VM install script, copy and paste the following command in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v3.sh)" +``` +It's recommended to press [ENTER] to use the default settings. (Advanced settings are available for changing settings such as mac, bridge, vlan, ect...) It will then download the Official KVM Image from the Home Assistant github and configure it in Proxmox VE for you. This will take 2-20 minutes depending on your internet connection and machine. + +Once this has finished, you will see **✓ Completed Successfully!**. + +The Home Assistant OS VM will be assigned a different IP address than the one Proxmox VE is using. To find the IP address of the newly created Home Assistant OS VM, click on the VM (eg. haos8.2) then click Summary from the menu list, wait for Guest Agent to start. The IP address listed here is needed to access Home Assistant via a web browser using port 8123 (eg. `http://192.168.1.50:8123`). + +Once you can see the login screen, the setup has been completed and you can create a new account and password (or restore a backup). + +That’s it, you have now set up Home Assistant OS using Proxmox VE 7 + +This guide uses many resources from the famous "Installing Home Assistant OS using Proxmox 7" guide from @kanga_who + +The above scripts (and more) can be found at https://github.com/tteck/Proxmox From 2320ee8715beb99f5b73784338604eb483e548fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Jun 2022 22:08:17 -0400 Subject: [PATCH 3058/6505] Delete file --- misc/set-up-haosvm-using-proxmox-7.md | 75 --------------------------- 1 file changed, 75 deletions(-) delete mode 100644 misc/set-up-haosvm-using-proxmox-7.md diff --git a/misc/set-up-haosvm-using-proxmox-7.md b/misc/set-up-haosvm-using-proxmox-7.md deleted file mode 100644 index 1ddab901..00000000 --- a/misc/set-up-haosvm-using-proxmox-7.md +++ /dev/null @@ -1,75 +0,0 @@ -# Set up a Home Assistant OS VM using Proxmox VE 7 (2022) - -This guide will help you set up a Home Assistant OS VM, on almost any x86/64 machine type you choose using Proxmox VE 7 as the operating system. -This guide also utilizes scripts to simplify the installation process, always remember to use due diligence when sourcing scripts and automation tasks from third-party sites. - -This installation uses an **Official KVM Image provided by the Home Assistant Team and is considered a supported installation method**. This method of installation is considered easy/medium difficulty and some knowledge of how to use and interact with Linux is suggested. - -If you have an existing Home Assistant installation and would like to know how to backup your current configuration to restore later, please see the documentation on [backing up and restoring your configuration](https://www.home-assistant.io/common-tasks/supervised/#making-a-backup-from-the-ui). - -## Installing Proxmox VE 7 - -* You will want to ensure **UEFI Boot & Virtualisation is enabled and Secure Boot is disabled** in the [bios](https://www.lifewire.com/how-to-enter-bios-2624481) of your machine. - -* Download the [Proxmox VE 7.x ISO Installer](https://www.proxmox.com/en/downloads/category/iso-images-pve). - -* You will now need to make a bootable USB drive using [balenaEtcher](https://www.balena.io/etcher/). Using a USB drive of at least **8gb**, insert it into your PC, open Etcher, select the Proxmox VE image you just downloaded, select your USB drive, then click Flash. - -* Insert the bootable USB drive you just made into the machine you wish to install Proxmox VE on. Connect a monitor, Ethernet cable, keyboard, mouse, and power on the machine. If the machine doesn't boot from the USB drive automatically, you will need to enter the boot options menu by pressing Esc, F2, F10 or F12, (This relies on the company of the computer or motherboard) on your keyboard immediately when the machine is powering on. - -* When you see the first screen, select Install Proxmox VE and press Enter. The installer will perform some automated tasks for 1-2 minutes. - -* On the EULA screen, select, I Agree. - -* On the Proxmox Virtualization Environment (PVE) screen, you will get the option to choose which disk you want to install Proxmox VE on. When finished, click Next. - -* On the Location and Time Zone selection, Type your country, then select your time zone and change the keyboard layout if needed. When finished, click Next - -* On the Administration password and E-mail address screen, choose a password (**make sure you don’t forget it**), confirm your password and enter a valid email address. When finished, click Next - -* On the Management network configuration screen. - * Management interface Should auto populate with the network interface (Ethernet) of your machine. If not, select the network interface. - * Hostname (FQDN) - The first part of the hostname is what your node will be called under Datacenter, you might want to change this to something more friendly now, the default is “pve” (eg. proxmox.lan). - * IP Address - Should auto populate. If the IP address looks odd here and not at all like the address range of your other devices, it’s possible you may not be connected to your network, so check your network cable and start again. - * Netmask - Should auto populate and be something like `255.255.255.0` depending on your network configuration. - * Gateway - Should auto populate to the IP address of your router. If not, make sure you're connected to your network - * DNS server - Should auto populate to the same IP address as your gateway. Or, input one of your choosing. When finished, click Next - -* Next on the Summary screen, confirm that all of the details are correct. When confirmed click Install. - -Proxmox VE will install and is finished once it displays its IP address on the screen. **Take note of the IP address!** It's needed to access Proxmox via a web browser. Remove the USB drive, and click Reboot. While the machine is rebooting, you can unplug the monitor, keyboard and mouse, as they're no longer needed. - -After 1-2 minutes, you should be able to access Proxmox VE via a web browser using the noted IP address from above (eg. `http://192.168.1.10:8006`) If you see a message "Warning: Potential Security Risk Ahead", you can safely ignore this, accept the risk and continue. Login with User name: `root` and the password you created on the Administration password and E-mail address screen. - -## Configuring and Updating Proxmox VE 7 - -Before installing Home Assistant OS, you will want to make sure that Proxmox VE has the latest updates and security patches installed. This has been made very simple with a [script](https://github.com/tteck/Proxmox/raw/main/misc/post-install-v3.sh). - -To run the Proxmox VE 7 Post Install script, copy and paste the following command in the Proxmox Shell. -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-install-v3.sh)" -``` -It's recommended to answer `y` to all questions. - -## Installing Home Assistant OS - -Installing Home Assistant OS using Proxmox VE has been made very simple with a [script](https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v3.sh). - -To run the Home Assistant OS VM install script, copy and paste the following command in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v3.sh)" -``` -It's recommended to press [ENTER] to use the default settings. (Advanced settings are available for changing settings such as mac, bridge, vlan, ect...) It will then download the Official KVM Image from the Home Assistant github and configure it in Proxmox VE for you. This will take 2-20 minutes depending on your internet connection and machine. - -Once this has finished, you will see **✓ Completed Successfully!**. - -The Home Assistant OS VM will be assigned a different IP address than the one Proxmox VE is using. To find the IP address of the newly created Home Assistant OS VM, click on the VM (eg. haos8.2) then click Summary from the menu list, wait for Guest Agent to start. The IP address listed here is needed to access Home Assistant via a web browser using port 8123 (eg. `http://192.168.1.50:8123`). - -Once you can see the login screen, the setup has been completed and you can create a new account and password (or restore a backup). - -That’s it, you have now set up Home Assistant OS using Proxmox VE 7 - -This guide uses many resources from the famous "Installing Home Assistant OS using Proxmox 7" guide from @kanga_who - -The above scripts (and more) can be found at https://github.com/tteck/Proxmox From ef534db843bbcb154aa210a578b39bdaa63bc061 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Jun 2022 11:05:30 -0400 Subject: [PATCH 3059/6505] Update post-install-v3.sh --- misc/post-install-v3.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/misc/post-install-v3.sh b/misc/post-install-v3.sh index 19926093..54d0e44e 100644 --- a/misc/post-install-v3.sh +++ b/misc/post-install-v3.sh @@ -104,9 +104,14 @@ apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag" fi -msg_info "Updating Proxmox" -sleep 2 -apt-get update -apt-get dist-upgrade -msg_ok "Finished" +read -r -p "Update Proxmox VE 7 now? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Updating Proxmox VE 7" +apt-get update &>/dev/null +apt-get -y dist-upgrade &>/dev/null +msg_ok "Updated Proxmox VE 7" +fi +sleep 2 +msg_ok "Finished Post Install Routines" From dc3ecbf4b0fb49b68df2233e8ccd82221b20dd87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Jun 2022 22:20:51 -0400 Subject: [PATCH 3060/6505] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e3c422d8..e5b8be88 100644 --- a/README.md +++ b/README.md @@ -617,7 +617,11 @@ sudo systemctl status mariadb ``` Change the recorder: `db_url:` in your HA configuration.yaml -Example: `mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4` +Example: +``` +recorder: + db_url: mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4 +``` ⚙️ **To Update Mariadb:** From ca7c7f9d5adab2faa17ee74799f5c2107d304b0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Jun 2022 22:22:19 -0400 Subject: [PATCH 3061/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e5b8be88..21a26235 100644 --- a/README.md +++ b/README.md @@ -618,7 +618,7 @@ sudo systemctl status mariadb Change the recorder: `db_url:` in your HA configuration.yaml Example: -``` +```yaml recorder: db_url: mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4 ``` From 5f7358ef621f02d2c15155fc55f6811e69a73047 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Jun 2022 22:44:36 -0400 Subject: [PATCH 3062/6505] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21a26235..4671db9f 100644 --- a/README.md +++ b/README.md @@ -690,8 +690,11 @@ Then type exit to get back to root Change the recorder: `db_url:` in your HA configuration.yaml -Example: `db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8` - +Example: +```yaml +recorder: + db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8 +``` ⚙️ **To Update PostgreSQL** Run in the LXC console From 87d4da1e8d2e5a7b0bdb78d5d4b487d5fe9a67eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 Jun 2022 23:35:45 -0400 Subject: [PATCH 3063/6505] Update haos_vm.sh --- vm/haos_vm.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index ef59d398..7e3bb535 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.1" +STABLE="8.2" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -287,7 +287,7 @@ elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ + "Which storage pool you would like to use for the HAOS VM?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done @@ -309,6 +309,7 @@ case $STORAGE_TYPE in btrfs|nfs|dir) DISK_EXT=".qcow2" DISK_REF="$VMID/" + DIR_IMPORT="-format qcow2" esac for i in {0,1}; do disk="DISK$i" @@ -321,12 +322,13 @@ msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DIR_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null + msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" if [ "$START_VM" == "yes" ]; then From 5a7ef1f712e65025e70351b89fd6ccffc1d131d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 Jun 2022 23:57:00 -0400 Subject: [PATCH 3064/6505] allow storage type "dir" --- vm/haos-vm-v3.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 9e0e26e1..7e3bb535 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -287,7 +287,7 @@ elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ + "Which storage pool you would like to use for the HAOS VM?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done @@ -309,6 +309,7 @@ case $STORAGE_TYPE in btrfs|nfs|dir) DISK_EXT=".qcow2" DISK_REF="$VMID/" + DIR_IMPORT="-format qcow2" esac for i in {0,1}; do disk="DISK$i" @@ -321,12 +322,13 @@ msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DIR_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},size=128K \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null + msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" if [ "$START_VM" == "yes" ]; then From 70510d745fd24cc0bf90b580be641e6d06c521c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Jun 2022 14:31:31 -0400 Subject: [PATCH 3065/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index f1758c0c..2cb532c8 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -69,11 +69,11 @@ sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null +sudo apt-get install -y nodejs npm git make g++ gcc &>/dev/null msg_ok "Installed Node.js" msg_info "Setting up Zigbee2MQTT Repository" -sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null +sudo git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null msg_ok "Set up Zigbee2MQTT Repository" msg_info "Installing Zigbee2MQTT" From 1e04867da284be5753c49fa2442e8246f687176f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Jun 2022 14:41:26 -0400 Subject: [PATCH 3066/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 2cb532c8..98fa1b7a 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -65,11 +65,11 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +sudo curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -sudo apt-get install -y nodejs npm git make g++ gcc &>/dev/null +apt-get install -y nodejs npm git make g++ gcc &>/dev/null msg_ok "Installed Node.js" msg_info "Setting up Zigbee2MQTT Repository" From f95ee7667d0b2777cd1629c959a482530aa9cd4f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Jun 2022 14:51:21 -0400 Subject: [PATCH 3067/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 98fa1b7a..0e7f6ad6 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -62,14 +62,18 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +apt-get install -y make &>/dev/null +apt-get install -y g++ &>/dev/null +apt-get install -y gcc &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash - &>/dev/null +curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -apt-get install -y nodejs npm git make g++ gcc &>/dev/null +apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Setting up Zigbee2MQTT Repository" From c88e438b0d0f079cce50aa6c23ed98800679085f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 06:09:01 -0400 Subject: [PATCH 3068/6505] Create prometheus-install.sh --- setup/prometheus-install.sh | 122 ++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 setup/prometheus-install.sh diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh new file mode 100644 index 00000000..884e2deb --- /dev/null +++ b/setup/prometheus-install.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Prometheus" +mkdir -p /etc/prometheus +mkdir -p /var/lib/prometheus +wget https://github.com/prometheus/prometheus/releases/download/v2.36.2/prometheus-2.36.2.linux-amd64.tar.gz &>/dev/null +tar -xvf prometheus-2.36.2.linux-amd64.tar.gz &>/dev/null +cd prometheus-2.36.2.linux-amd64 +mv prometheus promtool /usr/local/bin/ +mv consoles/ console_libraries/ /etc/prometheus/ +mv prometheus.yml /etc/prometheus/prometheus.yml +msg_ok "Installed Prometheus" + +msg_info "Creating Service" +service_path="/etc/systemd/system/prometheus.service" +echo "[Unit] +Description=Prometheus +Wants=network-online.target +After=network-online.target + +[Service] +User=root +Restart=always +Type=simple +ExecStart=/usr/local/bin/prometheus \ + --config.file=/etc/prometheus/prometheus.yml \ + --storage.tsdb.path=/var/lib/prometheus/ \ + --web.console.templates=/etc/prometheus/consoles \ + --web.console.libraries=/etc/prometheus/console_libraries \ + --web.listen-address=0.0.0.0:9090 + +[Install] +WantedBy=multi-user.target" > $service_path +sudo systemctl enable --now prometheus &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 06ef335aa989386e0631f41b8974106bfbbdea40 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 06:10:51 -0400 Subject: [PATCH 3069/6505] Create prometheus-v3.sh --- ct/prometheus-v3.sh | 354 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 ct/prometheus-v3.sh diff --git a/ct/prometheus-v3.sh b/ct/prometheus-v3.sh new file mode 100644 index 00000000..d2ec1ec6 --- /dev/null +++ b/ct/prometheus-v3.sh @@ -0,0 +1,354 @@ +#!/usr/bin/env bash +APP="Prometheus" +var_disk="4" +var_cpu="1" +var_ram="2048" +var_os="debian" +var_version="11" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + _____ _____ ____ __ __ ______ _______ _ _ ______ _ _ _____ + | __ \| __ \ / __ \| \/ | ____|__ __| | | | ____| | | |/ ____| + | |__) | |__) | | | | \ / | |__ | | | |__| | |__ | | | | (___ + | ___/| _ /| | | | |\/| | __| v3 | | | __ | __| | | | |\___ \ + | | | | \ \| |__| | | | | |____ | | | | | | |____| |__| |____) | + |_| |_| \_\\_____/|_| |_|______| |_| |_| |_|______|\____/|_____/ +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9090${CL} \n" From fb4781cbb7159a6d16190520259663d3bca58ec4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 06:53:09 -0400 Subject: [PATCH 3070/6505] Update prometheus-install.sh --- setup/prometheus-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 884e2deb..87338f49 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -118,5 +118,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/prometheus-2.36.2.linux-amd64 /root/prometheus-2.36.2.linux-amd64.tar.gz msg_ok "Cleaned" From 4e5753a8d2e5f4e12ebd5034efe87f80b9213f94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 07:18:04 -0400 Subject: [PATCH 3071/6505] Add files via upload --- misc/images/prome.png | Bin 0 -> 31467 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/prome.png diff --git a/misc/images/prome.png b/misc/images/prome.png new file mode 100644 index 0000000000000000000000000000000000000000..faf1eb89ad040eb16619bece5efae04b4d49e6be GIT binary patch literal 31467 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 Date: Thu, 30 Jun 2022 07:22:39 -0400 Subject: [PATCH 3072/6505] Add files via upload --- misc/images/prome.png | Bin 31467 -> 16637 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/prome.png b/misc/images/prome.png index faf1eb89ad040eb16619bece5efae04b4d49e6be..1ab45f27cd6a3ff31e5b2bc8fff6e40365a4f7d1 100644 GIT binary patch literal 16637 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 Date: Thu, 30 Jun 2022 07:29:36 -0400 Subject: [PATCH 3074/6505] Add files via upload --- misc/images/prome.png | Bin 16637 -> 44686 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/prome.png b/misc/images/prome.png index 1ab45f27cd6a3ff31e5b2bc8fff6e40365a4f7d1..0f6f3de4d29d5d914b93c7690ec229feb4f84f28 100644 GIT binary patch literal 44686 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 z z)|oKo*CAqn=r-hGG*MtNt!3F0Uhf{Y!u@-@g)NO|ubtY5y*{YJYnYSUWhV>Gmv98s zY+TEg3(LEyVauKNAH;5`RKS%;*o#hAiUkdL_P)m#sxZ3M&y02a6g}Uz8-I|eNV6iFO(8;#mFg$VYW_JIo0w$0n=03rg3=S(P(&)y znufw{L<=u<732xWhm&gTlD$3QrwMwM=QTKF(+fzg~P27^trct;H~?K=-uX>&+TTb==G1gY9yVKtu4W_Z|$eXMQutvhGZ`ViC1c+OL?in>%eF8SRjnHiVtIq(rM*GDR}tV!Fc?4R_>gIlJbrM9QK&HKw=3G8|gGfq4UaZS4vl z(h4@rbzn-eBZB9GH&;)mW>Ll4xE$Z`kdJd7T_IIkSAIU9OQo{gKrxPZ#6x~S z5OgLDYdR5bj^iMnuUlTG#4ngKqJj{dHA=R|pclgW_B<;Ej*JK4P)UCD($&y~jc032 zeT!Fl#i(ENKLRZ_E)l(vkxe8=<987D%)Fbyw_Pj}GTW zbPL&#b`{kv-3vc@&wisDyvwI97z`#QcxnmT9)ZO}=;&^y0lt=VF)qdrP}&pcddDo@ z=_6-ZNvbl^R-MmzThIC!20F|gCI8Z0^%zQ0Ac|iRcKaO}s%bx03jNa%u`WY5|NY&2 z-ly{w+u<|pE$;jDZ`VzPV0l0VZ4_DGsr(TSbg`dEpW=Di);HexrC!I90 zPG=@9HoKh*b3YI6@cKS6)EA8pD<_9I%7xfeuSJ@26Ic+-w9qzLan5o;YcqpyQ@EG+ zTdh|8O%=dO>-s#nRFL#JeV3ABUIGdI_MP;6!*9{A_@4xYMPY+peRe^3FI4jSdX!@w zhAv&9RKn;p3icb;M76Zo<{il=Dk$n9D{e<)J-1cIsEnKU$nTLuNR=)u{d>Bec9JZ8 zKu)}Kz}eq4b9fruGDVMC7y ztC6k}b&(co@4DgxoE&0~_iFg8ehmB8haYNt?I z$;5$&#WE1Tv5D0w>(P=)L9|rXw<^K8tyLFryUFJ1gc+WBy-Jw zt5^zl@ zmKMhL2B+@nc8WGH4s2spNQM|pr6 z9Uy^izu04H&-NqX?ep3u-A@v|FIxpw84Z={1g}}`4V>&BQj*QaxioY1n3c5x&60iq z5PScUdTJPg=)#k2#1hJx8%DcdIQeJ$OtjHO)a3^KI3CPb&ujd!c5L6?vafj3zd1BM z@SUsGmixV#4t3k}kyZ5Tk ztTx1niw0fB&md1QKjYkon`uH_#Ed!Ipx03n z&_-UZYx0;snsE{|&E3}fx5&FvX6VH|TWYM(n&^CH;HJ;DRA!iAEdg&O$!fjKLtQaI zEtZ>Am~+~=qu&{;x>#rnfuQ_kpIv}&{7>`1&CDn-`r|XY&Azr$J_cVXC*b>YHfsOW zK{!$R8W&xqcP?F)3M)#c3EA;$yrM<$*NI|7ZK@khD$BxI*F1OisA8_SrImg=Wt(Dy ziUA(06xCPJ58iH;H+l-@RpSlwijSR0zC#lXe1o1KvA$8a0VVwl959;cm%K*^SA;)vEc1|Lj`qH3S z{fIlm0*`o_bEmxdpG1DNg)|uDhGh7y{Jl3kFu|Cd{0>bwS1SEP4Tz zJju*_PvvnhoIDnvl#+e~>rvLrr47f(e}H-AFYkXI1fAzpRTpuN7x5!Mx8)#+_JsyxenotF?m zJtf?i`kPg?@XYw(NsFRFv|LW%TcpdB+8sVj)oVA4jE(^HFU^-mZ!Qs4<&@X;c?2@7Gf0Pu@&P=8o8^6|^?RdBx0#41IjluTuyjDx9e2+ddk#O18<0$sW_7VQpI8$<4pJB1(jC;)Suc{ zZIOSaU7nki@vB>OPsWMU+{<7o$Y}xje8u|Eu=qnLK#jmF`n*SwpNVV}qS2Bf~%nfy`N?PHwaCs=mjWPwURpDY=_>d6Ap-bU}HNhirX zA=}GEjs3*>JcM)SmQ~za@vMG~)okP{cvHn-DUmpJ!$Pnad??2CpR=(yN~G!{gyC$E zLtiG5y7jz5S#?ZWf!%k{es$1B1d8UuHh-PsMm?7MklNuN?o=z9h6# zQo9u5A*1{em|nZI(CEkbHEf5>dY!i)b=4l;z_QrIJFB`{>J_{6Ic%Slc=yxGEeDq- zV2$Af{7HSQ=3b>~5x`Ahuf+A|Puxt)mEGOyx-Zq!Ip{A!hhviYBw&Avq+e?@G&mv2 zSjxqN@8saL4R-S8%m7cUmuaBa-)6RWIP0)mo{yAdL-q;dkOf!lLi1f?AEvy?dpG)( zz*c*RK-ILLUS{pIckSY5mU(pR)5Yo|FB@OqzHv^2r0?T16*(HRA`<#>54Z}mh#F!K z;!cL<`DEM`k8`+HY~RyBH*tmRf@RA(?eNmM?$$ z&_ulfM;sHh=)ZEtQTuXjvTt>fiWG1gX;=04Zn4n`cof)(q1N3mti3`8OJ=r`*Z0cG z{E4d>Ms#@nyncHWQf=>5@?7NEDBu0AA5gBnc%_+fK1F=R;C@cLE{bl}|6r!^+b;TR zYEBjxZBRLQ<9R*~QkpdbQGI$5!)H%a_U2n@=*a;W8;VVUZ%e)_RJpzI#}5bWr1{PE z;+Ht|uTD)Gh#7p1mufOpcnAd{3*q7HZRu}lN0JOalYjsK!_DAOBD6KN?@I;TFlfM; zI>CUzYj5&R>m*mQoq_>Xwjue%m#AUqmslA63{srlPr1TE?MZXOALl{HoORlktKqkH zJy{Q1|6Q!G`2ME5!A+UFXt3r6^tEcITx!uDH^qAf`Z{}BmtA*uOk{9ydUy`vQ@-(9 zlgzyy@9byxqHDemoon)4a-R;%SJz`QYzY3qS_!Mp~v{6GEonv|n1#wa5x}@kdP`Xb`~&MDOd{*Wuz8R8te5Gt`5%f_X#A zoS32#2Vn0#NeCVI6w`7Uud-aez1bW@`_@nRBz(2s%H9Elu=3qcg9oQyFPmLO+>WZA zn!SA5@n&-LSr$<=ESvtrOu);r{g=^7dh+Bysbr}>oq>!!Hf$0_j$TbWUq?$GNZiiU z#W4MJD^80>ij=;+9QN1o&cFg``pBJh#z#yyy=ENCNdqWAP$}^+| z1>jdA-b;d*Qyt)K7V0>!4iZyBd6R$gdHDEriucf8hb;xCpL5?#%IEJ*YkmQ+ZvSg+ zi-FEm#fn=b_JnsqOk8+{OjB|LeQws?YJ=HjwQ!x-K;dZ>!))EO9rk^A3Msqsn*J9Ntmx9Y-n_D3;)tT$$_AeiLpX$F}M#V?>&Y)cOr`wWq4v zt7Lb%==Pqwu-j4gXVX&{fX&%w44_Ig_(D^}?Ad0(`qeJ`ytkxrFe~sWwc`dN*9Zn8 zf=GnVMRIWD%B^m+kPP@Qd{&9hjfz&T0&5wQ%{FuxN_% z&3Z>Tf!b_6Cm8!pwl$u@8xioI@huG+L0pRQ-d#pwTf3dmWkk6IC?|@=N&Rm^tb!3w za+{8>+~?VinO^v|VnTY{$!(TFA3)5V^;s*I9Lu;|s6MS8%=mP#SCk=BER-k~<4Wql z@12>*m*(NJby9d|f4i{Xnw8If8evhI!z5p4Nln5v+Rcf0gx?qyqYB>Qp!`X=WkS4QLeAnkiYb4x(|a7j?J z4^xjHV{;Ufav1Rkans7xs|tSKa=psGRS6cxft8r@8=-~5&Au)&y{8XJJFV%@K;xay zE`Mf719VCF)12D%D4S->Bb;IsILlr4FaEX%-({{(uKWI$xO{Y!jLPl27rZA-sHe4<+7Rjb9MAaBPknIp)OfhkU#V%XvnWT0!?Y(!w)Qi)%~JL_mgUu#2F% zvX5(dsdmnc-t--f<72zF@l3IU))r|RFcOoTX%H2yDpYQZ-c=z^zg(aE9tl+u zM_Byi*9XS0@Moh-YSb;vNo_v34}fL5dzieR=sTNABTmmrk;8E|=8EeW8cdmG zAIGPi!`yt=4)QS#k5g|Oam;#$5lEn6?56)BIghhm|3i$INTj?Q{LXQ&7t`cW%;{Qo z^IWrQQx~a_YYLoW`47Z^Dc{J^}k1EpqPu;Z8xeBpX1!YE+OAmm+iR#MR4SeF*Rb(0*c0d4IaRb zo?H_}2IrST4{L(-My@^g&zlP-_5g3J16{aJH8%#Ir|Q+p8@bwxm`diuhzy6|n6AKI z?1eaIJ-egjI;sz~nt#1>o`6w#9kso)7-^yMRFy#XeDCZrnLd-SEBb-g8U~E8Hq##| zhXBv`pzcO~w=I6?xxhMd)}$J~a9$-WTK@D88)-k&r>9HDucZq)9*P~7dQ~wTv^&zz zv3KcQU3~6^5lOBd;nVGV!-$r@SV;XstM^4;F>oVFN{x1PXh6K5WWK$mN$w3+BMR6k zSB3dNYhGfT$7O{R*y4aG^$R`{p*+Vr&@T1LE*sO=Z@zKt-_jqKOF<2wx+)HGm^O8G`l z)?x^%tjT(R0P)nTC1u9>IQLv$QnEi07`}pR@7Hp8a2~5HMRF|RuEK5D>h7|4{m_KV zsP!7`;f9nVr&xFqseJf6H}<3RDWet-TP{<(sxk5wDoUMyBkuA#p^=SNDN~0Az3mN> z(RlLbgS;F>QnWE(4oQjS0qdBEG3rEQJv~Anh$9X6M#~wj)owcMfuX_!GF?d^g6Q`F zS@AZkxj?Dg_#@YZuSSwvKbD~#Gz=FxV7DvBmqLsC%uu7C&tc5$O(h)%k7Nzop^YjY z1J)@|ua2O)v>sk>11NSaw%;~zAug;xB{td@HU`ss9))e<@Jh=hQP&Wbv6qBgRzUAu z1Jj~wzUWhSudWqxf@|3Nq6>0d2;DuG^Jp)(?D>BO%$ximI`n2Kcik2~Z13?Qz8?dV z>At)V^ZhS=YQQ4H{d~5Bt6et7$4+vcO?Ze+u70GYFO)v%VtVRz@EG?s#jq0>ID9Ou zW|R|$7Lv_-Hoo2E$}#g6WACo0gt6Pl9^~UFQrm^1#78}EOlgG>5n$zZbVBED1hMWTwLYv)zk*NgFhBPika!SE^;7?PI1 zdvMIaYp8E5xM+8*r)U?U_9S-QYbd#|z=-GFV{-bj$365}R21GYqzVncbxY3bc%cT% z88&>;>i|NqR*iR(8?zeNAzJk$5cSS}u6M|$^RE;o4rcl-r8PV{X@f0Bqv|Wl!pUJ? z^gC>bpVJ33KMgiy~nt(Uba1f4nzoJ)1L${rTy3b?0> zKW)*4Rny9*_8~*sOmtI>>7qYaGX`8Gtl&iG(e0&G=i<==Ye{4G5q|5Rr6KS0XD;gX z@EEXL>NAMS)p3OX3yZ@;9EIQq=WS* z8!6R%t$IVbUfMzA=%n!6uRL*xw`vehDdRT-N*ZsDNkshGEJA{`N%~bV2&hT}K8T#u zfDy(_7hSb3d?rO+RlaJ_UFJ7LK}+>9Du}fcd2-dP8s*QM%w`gyGl=1w9Jf=doR;Fm z^~J@by)+}Lsq`fR{ks(p`;PYz1NJ;Ah;`0G|K zR|{UVei5cO48EP7fAe*&Gh^gaaNyo&4F0*v9{Rdbl(p!CW$xn-5OQAI{b;@4mF8Sy z%P;9>n+|zhQE-UpOM3}op{qLYl{do&-HBkb0x}@lTtOp4f-ptU);zz9((K7I_QWNd zE!6yhp0IotmaDt2-9VmXNAN+DFYxGqT^8UaotTHxOM?V%nT< zrMnAHS8uqgK%R9{&?3a{(GD;0fom2nNVY)y%z*(koLu{1nxjXo^2sR=%bxzHL4oi( zs{~O*_1l`_KwE0g5jV36`yR{r?;S8+e;)_JIq-M^i?f(ubMGG;&I&WH2JI8(u^)e| z*?4INdVgwbGdq4rQ6RSv*G|Y5Ak+7x_HX83aQDN0Ws;_xiFXf-@K;#l6NJT+I`Fj; zr_Ia!qfvr!8aY0dcYK#w7#eILQj%@6;kd0Bo%HKKeAwSJ_v3}ne?v6>=OW|&A3+E5 cJUhO7$R;cuhie#k{s4F=$g0YeNPqPIFVos+UjP6A literal 16637 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 Date: Thu, 30 Jun 2022 07:32:22 -0400 Subject: [PATCH 3075/6505] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 4671db9f..86222c4a 100644 --- a/README.md +++ b/README.md @@ -880,6 +880,35 @@ ________________________________________________________________________________
    +
    + 🔸Prometheus LXC + +

    + +

    Prometheus LXC

    + +[Prometheus](https://prometheus.io/) is an open-source systems monitoring and alerting toolkit + +To create a new Proxmox Prometheus LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/prometheus-v3.sh)" +``` + +

    ⚡ Default Settings: 12GB RAM - 4GB Storage - 1vCPU ⚡

    + +**Prometheus Interface - IP:9090** + +⚙️ **To Update Prometheus** + +```yaml +Working On +``` + +____________________________________________________________________________________________ + +
    +
    InfluxDB/Telegraf LXC From a5b4f0a503c825491dc2cd37bb2903fbd79b113b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 07:33:31 -0400 Subject: [PATCH 3076/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86222c4a..f51e82a3 100644 --- a/README.md +++ b/README.md @@ -895,7 +895,7 @@ To create a new Proxmox Prometheus LXC, run the following in the Proxmox Shell. bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/prometheus-v3.sh)" ``` -

    ⚡ Default Settings: 12GB RAM - 4GB Storage - 1vCPU ⚡

    +

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 1vCPU ⚡

    **Prometheus Interface - IP:9090** From 23c326e375fdb4afc4e75d72ddf810ddb6b63629 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 07:36:58 -0400 Subject: [PATCH 3077/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0f87091b..c7122851 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,12 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-06-30 + +### Changed + +- **Prometheus LXC** + - NEW Script ## 2022-06-06 From c5a53709e282e6d5b9b2efb150658b4802905b59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 07:59:20 -0400 Subject: [PATCH 3078/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f51e82a3..4b4ff076 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

    Proxmox VE 7 Post Install

    -This script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo and Disable Subscription Nag. +This script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag and Update Proxmox VE. Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** From b8650fa1c481367d1196137d21c9e401c9383395 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Jun 2022 08:54:15 -0400 Subject: [PATCH 3079/6505] Update nginx-proxy-manager-install.sh --- setup/nginx-proxy-manager-install.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 6dc047b5..686a4b60 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -61,12 +61,13 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get update &>/dev/null -apt-get -qqy install \ +apt-get -y install \ sudo \ curl \ - wget \ gnupg \ - openssl \ + make \ + g++ \ + gcc \ ca-certificates \ apache2-utils \ logrotate \ @@ -76,7 +77,7 @@ apt-get -qqy install \ lsb-release &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing Dependencies" +msg_info "Installing Python" apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null pip3 install --upgrade setuptools &>/dev/null pip3 install --upgrade pip &>/dev/null @@ -85,7 +86,7 @@ msg_info "Installing Dependencies" python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null fi python3 -m pip install --no-cache-dir cffi certbot &>/dev/null -msg_ok "Installed Dependencies" +msg_ok "Installed Python" msg_info "Installing Openresty" wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null @@ -96,11 +97,11 @@ apt-get -y install --no-install-recommends openresty &>/dev/null msg_ok "Installed Openresty" msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null +apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Yarn" From f6037d414c214d49f6cd3e66fd695e3dcacd02dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Jul 2022 07:25:41 -0400 Subject: [PATCH 3080/6505] set efitype & change size --- vm/haos-vm-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 7e3bb535..f28207ae 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -321,10 +321,10 @@ msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 528 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DIR_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},size=128K \ + -efidisk0 ${DISK0_REF},efitype=4m,size=528K \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From bf987d5bff1a3180fbfec44e0f6a6ed261550d5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Jul 2022 07:56:06 -0400 Subject: [PATCH 3081/6505] increase efi disk size --- vm/haos-vm-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index f28207ae..2e52013d 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -321,10 +321,10 @@ msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 528 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DIR_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=528K \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From 1d9a6860491d6a7f2e7611ecb1be960cfae644a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Jul 2022 08:49:10 -0400 Subject: [PATCH 3082/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c7122851..2c8aca7a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-01 + +### Changed + +- **Home Assistant OS VM** + - Fixed to use different storage types. + ## 2022-06-30 ### Changed From aa17af8c0d28049121b1f40cf905903a17e22198 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Jul 2022 09:02:42 -0400 Subject: [PATCH 3083/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2c8aca7a..f7f5d821 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Home Assistant OS VM** - - Fixed to use different storage types. + - Allow different storage types. ## 2022-06-30 From 6159b54915271109cd7bbcf802e06499af8c6226 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Jul 2022 10:48:52 -0400 Subject: [PATCH 3084/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 2e52013d..6101326d 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -293,7 +293,7 @@ else done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Container ID is ${CL}${BL}$VMID${CL}." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz msg_ok "Found URL for Home Assistant ${BRANCH} Disk Image" From 9bf7129ac8be01f93e41573999539a11190a44d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Jul 2022 12:59:51 -0400 Subject: [PATCH 3085/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 6101326d..28ba8c28 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -296,13 +296,13 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -msg_ok "Found URL for Home Assistant ${BRANCH} Disk Image" +sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}${BRANCH}.qcow2${CL}${GN} Disk Image" -msg_info "Extracting Disk Image" +msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" +msg_info "Extracting KVM Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in @@ -316,7 +316,7 @@ for i in {0,1}; do eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done -msg_ok "Extracted Disk Image" +msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ From 1f347f9ed128ff7f795db600b16f9daa34133045 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 13:36:31 -0400 Subject: [PATCH 3086/6505] Create add-tailscale-lxc.sh --- misc/add-tailscale-lxc.sh | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 misc/add-tailscale-lxc.sh diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh new file mode 100644 index 00000000..6ef0aea5 --- /dev/null +++ b/misc/add-tailscale-lxc.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will add Tailscale to an existing LXC Container ONLY\e[0m" +while true; do + read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +CTID=$1 +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +cat <> $CTID_CONFIG_PATH +lxc.cgroup2.devices.allow: c 10:200 rwm +lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file +EOF + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/add-tailscale-install.sh)" || exit + +msg "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" From e360a7f4bf77fe66adccc35431d8e8a7b2aef374 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 13:37:58 -0400 Subject: [PATCH 3087/6505] Create add-tailscale-install.sh --- misc/add-tailscale-install.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 misc/add-tailscale-install.sh diff --git a/misc/add-tailscale-install.sh b/misc/add-tailscale-install.sh new file mode 100644 index 00000000..a9f4b0da --- /dev/null +++ b/misc/add-tailscale-install.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +echo -e "Installing Tailscale..." +curl -fsSL https://tailscale.com/install.sh | sh &>/dev/null +echo -e "Installed Tailscale" From f3d29a78be19761688a037008edc713b53ecb10d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 14:21:12 -0400 Subject: [PATCH 3088/6505] Update README.md --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 4b4ff076..ad4a7c02 100644 --- a/README.md +++ b/README.md @@ -1673,6 +1673,34 @@ apt update && apt upgrade -y ``` ____________________________________________________________________________________________ +
    +
    + 🔸Tailscale + +

    + +

    Tailscale

    + +[Tailscale](https://tailscale.com/) Creates a secure network between your servers, computers, and cloud instances. Even when separated by firewalls or subnets, Tailscale just works. + +To Install Talescale on an existing LXC, run the following in the Proxmox Shell (replace `106` with your LXC ID). + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/add-tailscale-lxc.sh)" -s 106 +``` +After the script finishes, reboot the LXC then run `tailscale up` in the LXC console + +[**Tailscale Login**](https://login.tailscale.com/start) + +⚙️ **To Update Tailscale** + +Run in the LXC console + ```yaml +apt update && apt upgrade -y +``` + +___________________________________________________________________________________________ +
    From 480d1f68eac3aef2f73e6e3f1128a36bece39097 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 14:22:37 -0400 Subject: [PATCH 3089/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f7f5d821..1bdb668f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-03 + +### Changed + +- **Tailscale** + - NEW Script + ## 2022-07-01 ### Changed From d034f97612ea5ee77e03341ea7910f0119dbd9f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 16:27:49 -0400 Subject: [PATCH 3090/6505] Update add-tailscale-lxc.sh --- misc/add-tailscale-lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 6ef0aea5..766a3861 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -45,5 +45,5 @@ lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/add-tailscale-install.sh)" || exit - +# lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" || exit msg "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" From 29283581e454a43b1d2452be3dfe34a223e3977d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 19:35:48 -0400 Subject: [PATCH 3091/6505] Update add-tailscale-lxc.sh --- misc/add-tailscale-lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 766a3861..72d2993e 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -45,5 +45,5 @@ lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/add-tailscale-install.sh)" || exit -# lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" || exit +# lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" &>/dev/null || exit msg "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" From 42bf5b2ba531e48d6e2fb0d480dfaec2ed0571fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 19:53:08 -0400 Subject: [PATCH 3092/6505] Update add-tailscale-lxc.sh --- misc/add-tailscale-lxc.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 72d2993e..fd5aca7e 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -44,6 +44,9 @@ lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/add-tailscale-install.sh)" || exit -# lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" &>/dev/null || exit -msg "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" +msg "⏳ Installing Tailscale..." +lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" &>/dev/null || exit +msg "⌛ Installed Tailscale" +sleep 2 +msg "\e[1;32m ✔ Completed Successfully!\e[0m" +msg "Reboot ${CTID} LXC to apply the changes, then run tailscale up in the LXC console" From 2787814273df0eaf85ba4481446501a3b98af635 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 19:55:55 -0400 Subject: [PATCH 3093/6505] Delete add-tailscale-install.sh --- misc/add-tailscale-install.sh | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 misc/add-tailscale-install.sh diff --git a/misc/add-tailscale-install.sh b/misc/add-tailscale-install.sh deleted file mode 100644 index a9f4b0da..00000000 --- a/misc/add-tailscale-install.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -echo -e "Installing Tailscale..." -curl -fsSL https://tailscale.com/install.sh | sh &>/dev/null -echo -e "Installed Tailscale" From 02c2188ca416f2fb62d839d439a25af3836fc20e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Jul 2022 19:56:54 -0400 Subject: [PATCH 3094/6505] Update add-tailscale-lxc.sh --- misc/add-tailscale-lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index fd5aca7e..6b369ef7 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -49,4 +49,4 @@ lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" msg "⌛ Installed Tailscale" sleep 2 msg "\e[1;32m ✔ Completed Successfully!\e[0m" -msg "Reboot ${CTID} LXC to apply the changes, then run tailscale up in the LXC console" +msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run tailscale up in the LXC console\e[0m" From 9fc2363af70274246fc4ed7e297a8ba53384ff95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 4 Jul 2022 07:33:54 -0400 Subject: [PATCH 3095/6505] Update add-tailscale-lxc.sh --- misc/add-tailscale-lxc.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 6b369ef7..ba0e37a2 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -echo -e "\e[1;33m This script will add Tailscale to an existing LXC Container ONLY\e[0m" +echo -e "\e[1;33mThis script will add Tailscale to an existing LXC Container ONLY\e[0m" while true; do read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn case $yn in @@ -16,26 +16,19 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -trap cleanup EXIT function error_exit() { trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="\e[1;31m‼ ERROR\e[0m $EXIT@$LINE" + echo -e "$flag $msg" 1>&2 exit $EXIT } function msg() { local TEXT="$1" echo -e "$TEXT" } -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf From 995346d2fc42f8b19683286a2bb34d0ce6d96b94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 4 Jul 2022 10:48:42 -0400 Subject: [PATCH 3096/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1bdb668f..49df748e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -15,7 +15,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Home Assistant OS VM** - - Allow different storage types. + - Allow different storage types (lvmthin, nfs, dir). ## 2022-06-30 From f67afef4a62bfcfab872e1427300a75ef0824db4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Jul 2022 11:26:39 -0400 Subject: [PATCH 3097/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ad4a7c02..9908107f 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,8 @@ ________________________________________________________________________________

    Home Assistant OS VM

    Option to create VM using the Latest or Stable Image

    +The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip) installs of any kind. + To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell ```yaml From 3e411c1ee5ea0fc9ea1390545d0b59519eb88205 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Jul 2022 14:33:59 -0400 Subject: [PATCH 3098/6505] Update haos_vm.sh --- vm/haos_vm.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 7e3bb535..a5621c76 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.2" +STABLE="7.6" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -293,16 +293,16 @@ else done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Container ID is ${CL}${BL}$VMID${CL}." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -msg_ok "Found URL for Home Assistant ${BRANCH} Disk Image" +sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}${BRANCH}.qcow2${CL}${GN} Disk Image" -msg_info "Extracting Disk Image" +msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" +msg_info "Extracting KVM Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in @@ -316,15 +316,15 @@ for i in {0,1}; do eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done -msg_ok "Extracted Disk Image" +msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DIR_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},size=128K \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From 0ce856f9b6c6162c1bdf4fef5e2a6dc4d7ee7709 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Jul 2022 15:16:18 -0400 Subject: [PATCH 3099/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9908107f..9052ae54 100644 --- a/README.md +++ b/README.md @@ -1215,6 +1215,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin-v3. **Jellyfin Media Server Interface - IP:8096** +FFmpeg path: `/usr/lib/jellyfin-ffmpeg/ffmpeg` + ⚙️ **To Update Jellyfin Media Server** Run in the LXC console From b393592578e1fcac759b47d9e15f37e45a88975a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Jul 2022 19:14:27 -0400 Subject: [PATCH 3100/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9052ae54..e6cfe1aa 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

    Proxmox VE 7 Post Install

    -This script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag and Update Proxmox VE. +The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag and Update Proxmox VE. Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** @@ -883,7 +883,7 @@ ________________________________________________________________________________
    - 🔸Prometheus LXC + Prometheus LXC

    From a34c32f167ac30d87e50beb16313bcb56a14c9b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Jul 2022 04:48:48 -0400 Subject: [PATCH 3101/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6cfe1aa..4f0b20f6 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-install-v3.sh)" ``` -It's recommended to update Proxmox after running this script, before adding any VM/CT. +It's recommended to answer `y` to all options. ____________________________________________________________________________________________ From 07ff06d06ecb70fecabac83a1ca725bcf14602d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Jul 2022 12:31:24 -0400 Subject: [PATCH 3102/6505] 8.3 --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 28ba8c28..9f5f0a66 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.2" +STABLE="8.3" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From 14dbb4704bb5d6618257eb927b12aba1c39ba3b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Jul 2022 12:38:39 -0400 Subject: [PATCH 3103/6505] Create openhab-install.sh --- setup/openhab-install.sh | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 setup/openhab-install.sh diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh new file mode 100644 index 00000000..25e9f9ab --- /dev/null +++ b/setup/openhab-install.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +apt-get install -y apt-transport-https &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Azul Zulu" +apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 &>/dev/null +curl -O https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb &>/dev/null +apt-get install ./zulu-repo_1.0.0-3_all.deb &>/dev/null +apt-get update &>/dev/null +apt-get -y install zulu11-jdk &>/dev/null +msg_ok "Installed Azul Zulu" + +msg_info "Installing openHAB" +curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor > openhab.gpg +mv openhab.gpg /usr/share/keyrings +chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg +echo 'deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main' | tee /etc/apt/sources.list.d/openhab.list &>/dev/null +apt update &>/dev/null +apt-get -y install openhab &>/dev/null +systemctl daemon-reload +systemctl enable openhab.service &>/dev/null +systemctl start openhab.service +msg_ok "Installed openHAB" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 96d2c106a29911e971e680c3bb9c5f9764ffcd3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Jul 2022 12:40:00 -0400 Subject: [PATCH 3104/6505] Create openhab-v3.sh --- ct/openhab-v3.sh | 356 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 ct/openhab-v3.sh diff --git a/ct/openhab-v3.sh b/ct/openhab-v3.sh new file mode 100644 index 00000000..78312e12 --- /dev/null +++ b/ct/openhab-v3.sh @@ -0,0 +1,356 @@ +#!/usr/bin/env bash +APP="openHAB" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + _ _ ____ + | | | | /\ | _ \ + ___ _ __ ___ _ __ | |__| | / \ | |_) | + / _ \| _ \ / _ \ _ \| __ | / /\ \ | _ < + | (_) | |_) | __/ | | | | | |/ ____ \| |_) | + \___/| .__/ \___|_| |_|_| |_/_/ v3 \_\____/ + | | + |_| +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL}\n" From 4daf200902d7458078508f1865b2427d6e00996d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Jul 2022 12:53:50 -0400 Subject: [PATCH 3105/6505] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 4f0b20f6..1e074b28 100644 --- a/README.md +++ b/README.md @@ -294,6 +294,35 @@ ________________________________________________________________________________
    +
    + 🔸openHAB LXC + +

    + +

    openHAB LXC

    + +[openHAB](https://www.openhab.org/), a vendor and technology agnostic open source automation software for your home. + +To create a new Proxmox openHAB LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/openhab-v3.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**openHAB Interface - IP:8080** + +⚙️ **To Update openHAB** + +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    +
    Homebridge LXC From 8557dcb05bd9bff049868fa51f96c2554cedb022 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Jul 2022 12:54:55 -0400 Subject: [PATCH 3106/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 49df748e..157d5f10 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-08 + +### Changed + +- **openHAB LXC** + - NEW Script + ## 2022-07-03 ### Changed From 98990a196b2718f49cb4961bf01cff8f82f412dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Jul 2022 10:30:54 -0400 Subject: [PATCH 3107/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e074b28..0d3b774a 100644 --- a/README.md +++ b/README.md @@ -1025,7 +1025,7 @@ ________________________________________________________________________________

    Docker LXC

    -

    Options to Install Portainer and/or Docker Compose

    +

    Options to Install Portainer and/or Docker Compose V2

    To create a new Proxmox Docker LXC, run the following in the Proxmox Shell. @@ -1035,6 +1035,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v3.sh

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    +**⚠ Run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** + **Portainer Interface - IP:9000** ⚙️ **To Update** From 6bce073f90816b9fac552912539cdd8c9527975f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Jul 2022 10:31:28 -0400 Subject: [PATCH 3108/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d3b774a..c844a3a9 100644 --- a/README.md +++ b/README.md @@ -1710,7 +1710,7 @@ ________________________________________________________________________________
    - 🔸Tailscale + Tailscale

    From 3dd3521d907eb3a1e6c0f6b4f6e5a963ff10fbab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Jul 2022 10:48:09 -0400 Subject: [PATCH 3109/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c844a3a9..0f59fe70 100644 --- a/README.md +++ b/README.md @@ -1035,7 +1035,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v3.sh

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    -**⚠ Run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** +**⚠ You run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** **Portainer Interface - IP:9000** From 680e537e1b7812dd75c3cb73c64e3f61f8285a8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Jul 2022 10:49:28 -0400 Subject: [PATCH 3110/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f59fe70..c844a3a9 100644 --- a/README.md +++ b/README.md @@ -1035,7 +1035,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v3.sh

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    -**⚠ You run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** +**⚠ Run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** **Portainer Interface - IP:9000** From 4dd4a926ab1de57f2897cd59bbc02b9c46edbe6e Mon Sep 17 00:00:00 2001 From: schiz0phr3ne <22858496+schiz0phr3ne@users.noreply.github.com> Date: Sun, 10 Jul 2022 17:51:12 +0200 Subject: [PATCH 3111/6505] Delete tarball after update --- misc/vaultwarden-update.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 3f918c61..1a5e7a7d 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -42,6 +42,9 @@ else tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null fi +echo -e "${GN} Cleaning up... ${CL}" +rm bw_web_$VWRELEASE.tar.gz + echo -e "${GN} Starting Vaultwarden... ${CL}" systemctl start vaultwarden.service sleep 1 From 22601ffed1eb1be6bf4314607b3018d80ed1e49e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Jul 2022 16:53:35 -0400 Subject: [PATCH 3112/6505] Update README.md --- README.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c844a3a9..71a2df08 100644 --- a/README.md +++ b/README.md @@ -329,7 +329,8 @@ ________________________________________________________________________________

    Homebridge LXC

    -Homebridge allows you to integrate with smart home devices that do not natively support HomeKit + +[Homebridge](https://homebridge.io/) allows you to integrate with smart home devices that do not natively support HomeKit To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. @@ -386,6 +387,8 @@ Update from the Homebridge UI

    ESPHome LXC

    +[ESPHome](https://esphome.io/) is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems. + To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. ```yaml @@ -417,6 +420,8 @@ ________________________________________________________________________________

    Nginx Proxy Manager LXC

    +[Nginx Proxy Manager](https://nginxproxymanager.com/) Expose your services easily and securely + To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. ```yaml @@ -464,9 +469,10 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update

    -

    MQTT LXC

    +[Eclipse Mosquitto](https://mosquitto.org/) is an open source message broker that implements the MQTT protocol + To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. ```yaml @@ -517,6 +523,7 @@ ________________________________________________________________________________

    Node-Red LXC

    +[Node-RED](https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click. To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. @@ -560,6 +567,8 @@ ________________________________________________________________________________

    Mariadb LXC

    +[MariaDB](https://mariadb.org/) is a community-developed, commercially supported fork of the MySQL relational database management system. + To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. ```yaml @@ -675,6 +684,8 @@ ________________________________________________________________________________

    PostgreSQL LXC

    +[PostgreSQL](https://www.postgresql.org/), also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance. + To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. ```yaml @@ -748,6 +759,8 @@ ________________________________________________________________________________

    Zigbee2MQTT LXC

    +[Zigbee2MQTT](https://www.zigbee2mqtt.io/) is a standalone nodejs application that connects a zigbee network to MQTT + To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. ```yaml @@ -828,6 +841,8 @@ ________________________________________________________________________________

    deCONZ LXC

    +[deCONZ](https://www.phoscon.de/en/conbee2/software#deconz) is used to configure, control and display Zigbee networks. + To create a new Proxmox deCONZ LXC, run the following in the Proxmox Shell. ```yaml @@ -855,6 +870,8 @@ ________________________________________________________________________________

    Zwavejs2MQTT LXC

    +[Zwavejs2MQTT](https://zwave-js.github.io/zwavejs2mqtt/#/) is a fully configurable Z-Wave to MQTT Gateway and Control Panel. + To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell. ```yaml @@ -888,7 +905,7 @@ ________________________________________________________________________________

    NocoDB LXC

    -NocoDB is an open source #NoCode platform that turns any database into a smart spreadsheet. Airtable Alternative. +[NocoDB](https://www.nocodb.com/) is an open source #NoCode platform that turns any database into a smart spreadsheet. Airtable Alternative. To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell. From 832c73afb6a2cdf0fc2c0c2383e3f7665eb457f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Jul 2022 17:03:50 -0400 Subject: [PATCH 3113/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 71a2df08..0169721c 100644 --- a/README.md +++ b/README.md @@ -523,7 +523,7 @@ ________________________________________________________________________________

    Node-Red LXC

    -[Node-RED](https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click. +[Node-RED](https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. From 12c79ae15edf21a36eb5e970b5d9cbaea383bc10 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 07:23:26 -0400 Subject: [PATCH 3114/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 3e513be3..493d45b4 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -77,8 +77,8 @@ function default_settings() { clear header_info echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" PW=" " echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" @@ -105,14 +105,14 @@ function advanced_settings() { clear header_info echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + CT_TYPE1="Unprivileged" + CT_TYPE="1" + echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" fi; echo -e " ${CM}${CL} \r" sleep 1 @@ -348,4 +348,4 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 msg_ok "Completed Successfully!\n" echo -e "${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" + ${BL}http://${IP}/admin${CL} \n" From 0beb7da32829bd7aa4816c45209f84831f92370d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 07:24:44 -0400 Subject: [PATCH 3115/6505] Update pihole-install.sh --- setup/pihole-install.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index e2ccbb03..0e9b413d 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -55,17 +55,20 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y dist-upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y ufw &>/dev/null +apt-get install -y ntp &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Pi-hole" -curl -sSL https://install.pi-hole.net | bash +wget -O tteck-install.sh https://install.pi-hole.net &>/dev/null +bash tteck-install.sh msg_ok "Installed Pi-hole" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -89,5 +92,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/tteck-install.sh msg_ok "Cleaned" From fcff2c90dc49902442d216e38efa352f16a6de99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 07:38:35 -0400 Subject: [PATCH 3116/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0169721c..307a003f 100644 --- a/README.md +++ b/README.md @@ -1282,6 +1282,8 @@ ________________________________________________________________________________

    Pi-hole LXC

    +[Pi-hole](https://pi-hole.net/) is a Linux network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole and optionally a DHCP server. + To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. ```yaml From 94256429357a2dbe8b2ec11ef161f8c9b3df4dc6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 11:53:50 -0400 Subject: [PATCH 3117/6505] Update post-install-v3.sh --- misc/post-install-v3.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/misc/post-install-v3.sh b/misc/post-install-v3.sh index 54d0e44e..effa399d 100644 --- a/misc/post-install-v3.sh +++ b/misc/post-install-v3.sh @@ -51,7 +51,7 @@ function msg_ok() { clear header_info -read -r -p "Disable Enterprise Repository? " prompt +read -r -p "Disable Enterprise Repository? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Disabling Enterprise Repository" @@ -60,7 +60,7 @@ sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list msg_ok "Disabled Enterprise Repository" fi -read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt +read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Adding or Correcting PVE7 Sources" @@ -73,7 +73,7 @@ sleep 2 msg_ok "Added or Corrected PVE7 Sources" fi -read -r -p "Enable No-Subscription Repository? " prompt +read -r -p "Enable No-Subscription Repository? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Enabling No-Subscription Repository" @@ -84,7 +84,7 @@ sleep 2 msg_ok "Enabled No-Subscription Repository" fi -read -r -p "Add (Disabled) Beta/Test Repository? " prompt +read -r -p "Add (Disabled) Beta/Test Repository? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Adding Beta/Test Repository and set disabled" @@ -95,7 +95,7 @@ sleep 2 msg_ok "Added Beta/Test Repository" fi -read -r -p "Disable Subscription Nag? " prompt +read -r -p "Disable Subscription Nag? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Disabling Subscription Nag" @@ -104,7 +104,7 @@ apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag" fi -read -r -p "Update Proxmox VE 7 now? " prompt +read -r -p "Update Proxmox VE 7 now? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Updating Proxmox VE 7" From 29ba6893099273b4e9b6fa84498b77614a10bc1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 13:52:05 -0400 Subject: [PATCH 3118/6505] Update haos_vm.sh attempt zfspool|btrfs --- vm/haos_vm.sh | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a5621c76..9d6271b9 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="7.6" +STABLE="8.3" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -306,10 +306,19 @@ msg_info "Extracting KVM Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in - btrfs|nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DIR_IMPORT="-format qcow2" + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; + + zfspool|btrfs) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_FORMAT="subvol" + DISK_IMPORT="-format subvol" + ;; + esac for i in {0,1}; do disk="DISK$i" @@ -321,8 +330,8 @@ msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${DIR_IMPORT:-} 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null #--format ${DISK_FORMAT:-qcow2} +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=32G >/dev/null From 315218abc03dd8e350b50f2359ce7f8c583dd4e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 16:32:25 -0400 Subject: [PATCH 3119/6505] Update haos_vm.sh another attempt at BTRFS --- vm/haos_vm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 9d6271b9..b4eb76cd 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -313,10 +313,10 @@ case $STORAGE_TYPE in ;; zfspool|btrfs) - DISK_EXT=".qcow2" + DISK_EXT=".raw" DISK_REF="$VMID/" DISK_FORMAT="subvol" - DISK_IMPORT="-format subvol" + DISK_IMPORT="-format raw" ;; esac @@ -330,7 +330,7 @@ msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null #--format ${DISK_FORMAT:-qcow2} +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ From bc24e5c14b3c70459a14d8979d11178b6ad9c8f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 17:48:20 -0400 Subject: [PATCH 3120/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index b4eb76cd..a25de7fa 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -312,7 +312,7 @@ case $STORAGE_TYPE in DISK_IMPORT="-format qcow2" ;; - zfspool|btrfs) + btrfs) DISK_EXT=".raw" DISK_REF="$VMID/" DISK_FORMAT="subvol" From aa8f509588356ae9928ad380a8715f69a61acb42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 18:03:56 -0400 Subject: [PATCH 3121/6505] add BTRFS storage type --- vm/haos-vm-v3.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 9f5f0a66..a25de7fa 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -306,10 +306,19 @@ msg_info "Extracting KVM Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in - btrfs|nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DIR_IMPORT="-format qcow2" + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; + + btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_FORMAT="subvol" + DISK_IMPORT="-format raw" + ;; + esac for i in {0,1}; do disk="DISK$i" @@ -322,7 +331,7 @@ msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${DIR_IMPORT:-} 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=32G >/dev/null From eee6f9817eb2153ba856886d7a1b8134b7960696 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 18:23:38 -0400 Subject: [PATCH 3122/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 307a003f..cf2c12e0 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ ________________________________________________________________________________

    Home Assistant OS VM

    Option to create VM using the Latest or Stable Image

    -The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip) installs of any kind. +The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell From b42da4bfb56f378dd0a15ebb04ef797b386013bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 18:33:14 -0400 Subject: [PATCH 3123/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf2c12e0..9c0177b1 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ ________________________________________________________________________________

    Home Assistant OS VM

    Option to create VM using the Latest or Stable Image

    -The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. +The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip, ect...) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell From b63f732e354d1bb1d9ac32657cb5faefa08cf875 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 18:36:55 -0400 Subject: [PATCH 3124/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c0177b1..e327ff4b 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ ________________________________________________________________________________
    - Home Assistant OS VM + 🔸Home Assistant OS VM

    From dc4da55fc366187b40153bcf1bf2e15473f4e16b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Jul 2022 18:38:30 -0400 Subject: [PATCH 3125/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 157d5f10..ec3d06c4 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-11 + +### Changed + +- **Home Assistant OS VM** + - Supports lvmthin, zfspool, nfs, dir and btrfs storage types. + ## 2022-07-08 ### Changed From 24d0e9792ed175937ea01be281d0d3553538933b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Jul 2022 16:14:04 -0400 Subject: [PATCH 3126/6505] Update README.md --- README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e327ff4b..656d2bcc 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,9 @@ ________________________________________________________________________________ @home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    Home Assistant Container LXC

    - + +A standalone container-based installation of Home Assistant Core + To create a new Proxmox Home Assistant Container LXC, run the following in the Proxmox Shell. ```yaml @@ -202,9 +204,11 @@ ________________________________________________________________________________ @home-assistant

    Podman Home Assistant Container LXC

    -To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. +A standalone container-based installation of Home Assistant Core - ([What is Podman?](https://youtu.be/lkg5QJsoCCQ)) ⚠️ Podman seems to need a privileged LXC +⚠️ Podman seems to need a privileged LXC + +To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v3.sh)" @@ -964,6 +968,10 @@ ________________________________________________________________________________

    InfluxDB/Telegraf LXC

    +[InfluxDB](https://www.influxdata.com/) is an open-source time series database developed by the company InfluxData. + +[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) is an open source plugin-driven server agent for collecting and reporting metrics. + To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. ```yaml @@ -1004,6 +1012,8 @@ ________________________________________________________________________________

    Grafana LXC

    +[Grafana](https://grafana.com/) is a multi-platform open source analytics and interactive visualization web application. + To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. ```yaml @@ -1044,6 +1054,8 @@ ________________________________________________________________________________

    Docker LXC

    Options to Install Portainer and/or Docker Compose V2

    +[Docker](https://www.docker.com/) is an open-source project for automating the deployment of applications as portable, self-sufficient containers. + To create a new Proxmox Docker LXC, run the following in the Proxmox Shell. ```yaml From 35abefca0a1a9b57d96782fba8e9a2fb7338d5fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Jul 2022 17:33:36 -0400 Subject: [PATCH 3127/6505] Update webmin.sh --- misc/webmin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 6c77b12e..ec413018 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -22,11 +22,11 @@ apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip sh echo -e "${CM}${CL} \r" echo -en "${GN} Downloading Webmin... " -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.990_all.deb &>/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_1.996_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Webmin... " -dpkg --install webmin_1.990_all.deb &>/dev/null +dpkg --install webmin_1.996_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Setting Default Webmin usermame & password to root... " From 65449f97e65bd85ddacd7026ec48ad7ee491d221 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Jul 2022 17:50:42 -0400 Subject: [PATCH 3128/6505] Update webmin.sh --- misc/webmin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index ec413018..080b5611 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -31,7 +31,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Setting Default Webmin usermame & password to root... " /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /root/webmin_1.990_all.deb +rm -rf /root/webmin_1.996_all.deb echo -e "${CM}${CL} \r" IP=$(hostname -I | cut -f1 -d ' ') echo -e "${BL} Successfully Installed Webmin, Now Go To https://${IP}:10000 ${CL}" From 7cffd6f57bd28622deafc02d368fb17f7b379fe5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 11:38:10 -0400 Subject: [PATCH 3129/6505] Create edge-kernel.sh --- misc/edge-kernel.sh | 126 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 misc/edge-kernel.sh diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh new file mode 100644 index 00000000..c745475c --- /dev/null +++ b/misc/edge-kernel.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" +set -e +KERNEL_ON=$(uname -r) +PVE_KERNEL=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) +EDGE_KERNEL=$(dpkg --list| grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) +clear +while true; do + read -p "THIS IS A PROXMOX EDGE KERNEL TOOL, USE AT YOUR OWN RISK. +THE INFORMATION AND CONTENT MADE AVAILABLE TO YOU ON THE SITE IS PROVIDED 'AS IS' AND 'AS AVAILABLE.' +WE MAKE NO REPRESENTATIONS OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear + +show_menu(){ + normal=`echo "\033[m"` + safe=`echo "\033[32m"` + menu=`echo "\033[36m"` + number=`echo "\033[33m"` + bgred=`echo "\033[41m"` + fgred=`echo "\033[31m"` + proxmox-boot-tool kernel list + echo -e "\nCurrent Kernel: ${menu}${KERNEL_ON}${normal}" + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${normal} Install Proxmox 5.18 Edge Kernel & Reboot\n" + printf "${menu}**${number} 2)${normal} Switch to Proxmox PVE ${menu}${PVE_KERNEL}${normal} Kernel & Reboot\n" + printf "${menu}**${number} 3)${normal} Switch to Proxmox Edge ${menu}${EDGE_KERNEL}${normal} Kernel & Reboot\n" + printf "${menu}**${number} 4)${normal} Remove Proxmox Edge Kernel & Reboot\n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu and enter or ${fgred}x${normal} to exit." + read opt +} +option_picked(){ + msgcolor=`echo "\033[01;31m"` + normal=`echo "\033[00;00m"` + message=${@:-"${normal}Error: No message passed"} + printf "${msgcolor}${message}${normal}\n" +} +clear +show_menu +while [ $opt != '' ] + do + if [ $opt = '' ]; then + exit; + else + case $opt in + 1) while true; do + read -p "Are you sure you want to Install Proxmox 5.18 Edge Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Installing Proxmox 5.18 Edge Kernel & Rebooting"; + apt-get install -y gnupg + curl -1sLf 'https://dl.cloudsmith.io/public/pve-edge/kernel/gpg.8EC01CCF309B98E7.key' | apt-key add - + echo "deb https://dl.cloudsmith.io/public/pve-edge/kernel/deb/debian bullseye main" > /etc/apt/sources.list.d/pve-edge-kernel.list + apt-get -y update + apt-get -y install pve-kernel-5.18-edge + reboot + break; + ;; + 2) while true; do + read -p "Are you sure you want to Switch to Proxmox PVE ${PVE_KERNEL} Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Switching to Proxmox PVE Kernel & Rebooting"; + proxmox-boot-tool kernel pin ${PVE_KERNEL} + reboot + break; + ;; + 3) while true; do + read -p "Are you sure you want to Switch to Proxmox ${EDGE_KERNEL} Edge Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Switching to Proxmox Edge Kernel & Rebooting"; + proxmox-boot-tool kernel pin ${EDGE_KERNEL} + reboot + break; + ;; + 4) while true; do + read -p "Are you sure you want to Remove Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Removing Proxmox Edge Kernel & Rebooting"; + apt-get purge -y ${EDGE_KERNEL} + rm -rf /etc/apt/sources.list.d/pve-edge-kernel.list + proxmox-boot-tool kernel unpin + reboot + break; + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + option_picked "Please choose an option from the menu"; + show_menu; + ;; + esac + fi + done + +show_menu From f18e5145f2082a0e6a6979563ecd747134c92cc1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 11:44:31 -0400 Subject: [PATCH 3130/6505] Update edge-kernel.sh --- misc/edge-kernel.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index c745475c..e4c25cb3 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -6,9 +6,7 @@ PVE_KERNEL=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print substr($2, 12, leng EDGE_KERNEL=$(dpkg --list| grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) clear while true; do - read -p "THIS IS A PROXMOX EDGE KERNEL TOOL, USE AT YOUR OWN RISK. -THE INFORMATION AND CONTENT MADE AVAILABLE TO YOU ON THE SITE IS PROVIDED 'AS IS' AND 'AS AVAILABLE.' -WE MAKE NO REPRESENTATIONS OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED. Proceed(y/n)?" yn + read -p "THIS IS A PROXMOX EDGE KERNEL TOOL, USE AT YOUR OWN RISK. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From efc65a2a7e7ac06139f39d51c54866ea88370628 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 11:45:24 -0400 Subject: [PATCH 3131/6505] Update kernel-clean-v3.sh --- misc/kernel-clean-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean-v3.sh b/misc/kernel-clean-v3.sh index f2ba9c41..332cc7d8 100644 --- a/misc/kernel-clean-v3.sh +++ b/misc/kernel-clean-v3.sh @@ -17,7 +17,7 @@ current_kernel=$(uname -r) pve=$(pveversion) while true; do - read -p "This will Clean Unused Kernel Images. Proceed(y/n)?" yn + read -p "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From 09cff9fcdab6be9893ab84a2e844af85feb69162 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 11:47:40 -0400 Subject: [PATCH 3132/6505] Update edge-kernel.sh --- misc/edge-kernel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index e4c25cb3..fff7310b 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -6,7 +6,7 @@ PVE_KERNEL=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print substr($2, 12, leng EDGE_KERNEL=$(dpkg --list| grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) clear while true; do - read -p "THIS IS A PROXMOX EDGE KERNEL TOOL, USE AT YOUR OWN RISK. Proceed(y/n)?" yn + read -p "This is a Proxmox Edge Kernel Tool, USE AT YOUR OWN RISK. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; From f85a4638f622d9ff3590654e6cb7d06e43b5a02f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 12:07:52 -0400 Subject: [PATCH 3133/6505] Update edge-kernel.sh --- misc/edge-kernel.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index fff7310b..4df61649 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -28,7 +28,8 @@ show_menu(){ printf "${menu}**${number} 1)${normal} Install Proxmox 5.18 Edge Kernel & Reboot\n" printf "${menu}**${number} 2)${normal} Switch to Proxmox PVE ${menu}${PVE_KERNEL}${normal} Kernel & Reboot\n" printf "${menu}**${number} 3)${normal} Switch to Proxmox Edge ${menu}${EDGE_KERNEL}${normal} Kernel & Reboot\n" - printf "${menu}**${number} 4)${normal} Remove Proxmox Edge Kernel & Reboot\n" + printf "${menu}**${number} 4)${normal} Unpin Current Kernel\n" + printf "${menu}**${number} 5)${normal} Remove Proxmox Edge Kernel & Reboot\n" printf "${menu}*********************************************${normal}\n" printf "Please choose an option from the menu and enter or ${fgred}x${normal} to exit." read opt @@ -94,6 +95,19 @@ while [ $opt != '' ] break; ;; 4) while true; do + read -p "Are you sure you want to Unpin the Current Kernel? Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done + clear; + option_picked "Unpinning Current Kernel"; + proxmox-boot-tool kernel unpin + break; + ;; + 5) while true; do read -p "Are you sure you want to Remove Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn case $yn in [Yy]* ) break;; From b00fbaff085b07d8388e5cd54fae093d343fcdbe Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 12:53:14 -0400 Subject: [PATCH 3134/6505] Update edge-kernel.sh --- misc/edge-kernel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 4df61649..2d33940f 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -105,6 +105,7 @@ while [ $opt != '' ] clear; option_picked "Unpinning Current Kernel"; proxmox-boot-tool kernel unpin + clear; break; ;; 5) while true; do From 157ee78ed17c7b635b016180b655fe3d5cac1605 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 12:56:23 -0400 Subject: [PATCH 3135/6505] Update kernel-clean-v3.sh --- misc/kernel-clean-v3.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/misc/kernel-clean-v3.sh b/misc/kernel-clean-v3.sh index 332cc7d8..9ef8c753 100644 --- a/misc/kernel-clean-v3.sh +++ b/misc/kernel-clean-v3.sh @@ -54,11 +54,20 @@ function check_root() { exit 1 else header_info + edge_kernel kernel_info kernel_clean fi } +function edge_kernel() { + if [[ "$current_kernel" == *"edge"* ]]; then + echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" + echo -e "\nAn Active PVE Kernel is required to run Kernel Clean\n" + exit 1 + fi +} + function kernel_info() { latest_kernel=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) echo -e "${YW}PVE Version: ${BL}$pve\n${CL}" @@ -67,7 +76,7 @@ function kernel_info() { echo -e "${GN}Latest Kernel: $latest_kernel\n${CL}" fi else - echo -e "\n${CROSS}${RD}ERROR: No PVE Kernel Found\n${CL}" + echo -e "\n${CROSS} ${RD}ERROR: No PVE Kernel Found\n${CL}" exit 1 fi } From bc8295a18262e531a9486bbe9bd4b9909b2ef5c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 12:58:34 -0400 Subject: [PATCH 3136/6505] Update edge-kernel.sh --- misc/edge-kernel.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 2d33940f..e4c37235 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -26,7 +26,7 @@ show_menu(){ echo -e "\nCurrent Kernel: ${menu}${KERNEL_ON}${normal}" printf "\n${menu}*********************************************${normal}\n" printf "${menu}**${number} 1)${normal} Install Proxmox 5.18 Edge Kernel & Reboot\n" - printf "${menu}**${number} 2)${normal} Switch to Proxmox PVE ${menu}${PVE_KERNEL}${normal} Kernel & Reboot\n" + printf "${menu}**${number} 2)${normal} Switch to Proxmox VE 7 ${menu}${PVE_KERNEL}${normal} Kernel & Reboot\n" printf "${menu}**${number} 3)${normal} Switch to Proxmox Edge ${menu}${EDGE_KERNEL}${normal} Kernel & Reboot\n" printf "${menu}**${number} 4)${normal} Unpin Current Kernel\n" printf "${menu}**${number} 5)${normal} Remove Proxmox Edge Kernel & Reboot\n" @@ -67,7 +67,7 @@ while [ $opt != '' ] break; ;; 2) while true; do - read -p "Are you sure you want to Switch to Proxmox PVE ${PVE_KERNEL} Kernel & Reboot? Proceed(y/n)?" yn + read -p "Are you sure you want to Switch to Proxmox VE 7 ${PVE_KERNEL} Kernel & Reboot? Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -75,7 +75,7 @@ while [ $opt != '' ] esac done clear; - option_picked "Switching to Proxmox PVE Kernel & Rebooting"; + option_picked "Switching to Proxmox VE 7 Kernel & Rebooting"; proxmox-boot-tool kernel pin ${PVE_KERNEL} reboot break; From 3d2ecc2e0e1daaaac1090df720dc30a1a7348462 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 13:02:13 -0400 Subject: [PATCH 3137/6505] Update README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 656d2bcc..90e48c08 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,24 @@ ________________________________________________________________________________
    +
    + 🔸Proxmox Edge Kernel Tool + +

    + +

    Proxmox Edge Kernel Tool

    + +[Proxmox Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7, keeping up with new Kernel releases instead of LTS + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" +``` +____________________________________________________________________________________________ + +
    +
    Proxmox CPU Scaling Governor From 092c1114d5977d1b272cfca6448a533ac924b691 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 13:04:09 -0400 Subject: [PATCH 3138/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ec3d06c4..812f84c9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,12 @@ +## 2022-07-13 + +### Changed + +- **Proxmox Edge Kernel Tool** + - NEW Script + # Change Log All notable changes to this project will be documented in this file. From 5739f9d94ecdcda3fdc949adf58da8846e46276f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 13:05:07 -0400 Subject: [PATCH 3139/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90e48c08..147c2e77 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ ________________________________________________________________________________

    Proxmox Edge Kernel Tool

    -[Proxmox Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7, keeping up with new Kernel releases instead of LTS +Proxmox [Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7, keeping up with new Kernel releases instead of LTS Run the following in the Proxmox Shell. From f119d31a17fcaeeeb67d1e3adc3aa74e492c4c70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 13:06:39 -0400 Subject: [PATCH 3140/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 147c2e77..4bd30099 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ ________________________________________________________________________________

    Proxmox Edge Kernel Tool

    -Proxmox [Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7, keeping up with new Kernel releases instead of LTS +Proxmox [Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7. Keeping up with new Kernel releases instead of LTS Run the following in the Proxmox Shell. From 67a7537e0b6f90269170a3b38f43e202d44de474 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 14:06:57 -0400 Subject: [PATCH 3141/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 812f84c9..14a16080 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,8 @@ +# Change Log +All notable changes to this project will be documented in this file. + ## 2022-07-13 ### Changed @@ -7,9 +10,6 @@ - **Proxmox Edge Kernel Tool** - NEW Script -# Change Log -All notable changes to this project will be documented in this file. - ## 2022-07-11 ### Changed From f12b4e2ab4e3dbc523d1ac7a0628520be5369522 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Jul 2022 17:04:10 -0400 Subject: [PATCH 3142/6505] Update kernel-clean-v3.sh --- misc/kernel-clean-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean-v3.sh b/misc/kernel-clean-v3.sh index 9ef8c753..c079d7ea 100644 --- a/misc/kernel-clean-v3.sh +++ b/misc/kernel-clean-v3.sh @@ -63,7 +63,7 @@ function check_root() { function edge_kernel() { if [[ "$current_kernel" == *"edge"* ]]; then echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" - echo -e "\nAn Active PVE Kernel is required to run Kernel Clean\n" + echo -e "\nAn Active PVE Kernel is required to use Kernel Clean\n" exit 1 fi } From 342b842e40012319e96290ffbabf6397b5ccceae Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 14:42:40 -0400 Subject: [PATCH 3143/6505] Create magicmirror-v3.sh --- ct/magicmirror-v3.sh | 354 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 ct/magicmirror-v3.sh diff --git a/ct/magicmirror-v3.sh b/ct/magicmirror-v3.sh new file mode 100644 index 00000000..bacf531f --- /dev/null +++ b/ct/magicmirror-v3.sh @@ -0,0 +1,354 @@ +#!/usr/bin/env bash +APP="MagicMirror" +var_disk="3" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + __ __ _____ _____ _____ __ __ _____ _____ _____ ____ _____ + | \/ | /\ / ____|_ _/ ____| \/ |_ _| __ \| __ \ / __ \| __ \ + | \ / | / \ | | __ | || | | \ / | | | | |__) | |__) | | | | |__) | + | |\/| | / /\ \| | |_ | | || | v3 | |\/| | | | | _ /| _ /| | | | _ / + | | | |/ ____ \ |__| |_| || |____| | | |_| |_| | \ \| | \ \| |__| | | \ \ + |_| |_/_/ \_\_____|_____\_____|_| |_|_____|_| \_\_| \_\ ____/|_| \_\ +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" From a6967f1121daec3975f7886b806bc689d63f4d42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 14:43:52 -0400 Subject: [PATCH 3144/6505] Create magicmirror-install.sh --- setup/magicmirror-install.sh | 216 +++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 setup/magicmirror-install.sh diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh new file mode 100644 index 00000000..b3461fc7 --- /dev/null +++ b/setup/magicmirror-install.sh @@ -0,0 +1,216 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Setting up MagicMirror Repository" +git clone https://github.com/MichMich/MagicMirror /opt/magicmirror &>/dev/null +msg_ok "Set up MagicMirror Repository" + +msg_info "Installing MagicMirror" +cd /opt/magicmirror &>/dev/null +npm install --only=prod --omit=dev &>/dev/null + +cat < /opt/magicmirror/config/config.js +let config = { + address: "0.0.0.0", + port: 8080, + basePath: "/", + ipWhitelist: [], + useHttps: false, + httpsPrivateKey: "", + httpsCertificate: "", + language: "en", + locale: "en-US", + logLevel: ["INFO", "LOG", "WARN", "ERROR"], + timeFormat: 24, + units: "metric", + serverOnly: true, + modules: [ + { + module: "alert", + }, + { + module: "updatenotification", + position: "top_bar" + }, + { + module: "clock", + position: "top_left" + }, + { + module: "calendar", + header: "US Holidays", + position: "top_left", + config: { + calendars: [ + { + symbol: "calendar-check", + url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + } + ] + } + }, + { + module: "compliments", + position: "lower_third" + }, + { + module: "weather", + position: "top_right", + config: { + weatherProvider: "openweathermap", + type: "current", + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + apiKey: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "weather", + position: "top_right", + header: "Weather Forecast", + config: { + weatherProvider: "openweathermap", + type: "forecast", + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + apiKey: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "newsfeed", + position: "bottom_bar", + config: { + feeds: [ + { + title: "New York Times", + url: "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" + } + ], + showSourceTitle: true, + showPublishDate: true, + broadcastNewsFeeds: true, + broadcastNewsUpdates: true + } + }, + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} +EOF +msg_ok "Installed MagicMirror" + +msg_info "Creating Service" +service_path="/etc/systemd/system/magicmirror.service" +echo "[Unit] +Description=Magic Mirror +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +WorkingDirectory=/opt/magicmirror/ +ExecStart=/usr/bin/node serveronly + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now magicmirror &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 859a28198f2a333824e62bf14e9275fc5adf60cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 15:01:16 -0400 Subject: [PATCH 3145/6505] Update README.md --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 4bd30099..dbfb6d8b 100644 --- a/README.md +++ b/README.md @@ -1513,6 +1513,38 @@ ________________________________________________________________________________
    +
    + 🔸MagicMirror Server LXC + + + +

    MagicMirror Server LXC

    + +[MagicMirror²](https://docs.magicmirror.builders/) is an open source modular smart mirror platform. + +To create a new MagicMirror Server LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror-v3.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 3GB Storage - 1vCPU ⚡

    + +**MagicMirror Interface - IP:8080** + +⚙️ **To Update MagicMirror** + +Run in the LXC Console +```yaml +cd /opt/magicmirror +git pull && npm install --only=prod --omit=dev +``` + + +____________________________________________________________________________________________ + +
    +
    PhotoPrism LXC From f8afd9a9af5ccad1406c410100777571acb4c76c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 15:02:56 -0400 Subject: [PATCH 3146/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 14a16080..1455042f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-14 + +### Changed + +- **MagicMirror Server LXC** + - NEW Script + ## 2022-07-13 ### Changed From 79d81465fd64376a79b1b14a7344dd298d51402b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 15:15:48 -0400 Subject: [PATCH 3147/6505] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index dbfb6d8b..e7bbbad5 100644 --- a/README.md +++ b/README.md @@ -1532,6 +1532,10 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror- **MagicMirror Interface - IP:8080** +⚙️ **Configuration File** +``` +/opt/magicmirror/config/config.js +``` ⚙️ **To Update MagicMirror** Run in the LXC Console From b970212bd38bdd5f7bdaa0c980d3fbad0f554035 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 15:22:06 -0400 Subject: [PATCH 3148/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7bbbad5..12580b78 100644 --- a/README.md +++ b/README.md @@ -1533,7 +1533,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror- **MagicMirror Interface - IP:8080** ⚙️ **Configuration File** -``` +```yaml /opt/magicmirror/config/config.js ``` ⚙️ **To Update MagicMirror** From 37f86561d25b74bfb964001a6f7a06517f7893e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 15:56:42 -0400 Subject: [PATCH 3149/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12580b78..6a12c588 100644 --- a/README.md +++ b/README.md @@ -1515,8 +1515,8 @@ ________________________________________________________________________________
    🔸MagicMirror Server LXC - +

    MagicMirror Server LXC

    From cc46348c4da979e47f6c062dfa70d6b66b0dd7dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 16:07:01 -0400 Subject: [PATCH 3150/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6a12c588..f1a15914 100644 --- a/README.md +++ b/README.md @@ -1532,11 +1532,11 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror- **MagicMirror Interface - IP:8080** -⚙️ **Configuration File** +⚙️ **[Configuration](https://docs.magicmirror.builders/configuration/introduction.html#configuring-your-magicmirror)** ```yaml /opt/magicmirror/config/config.js ``` -⚙️ **To Update MagicMirror** +⚙️ **[Update MagicMirror](https://docs.magicmirror.builders/getting-started/upgrade-guide.html#upgrade-guide)** Run in the LXC Console ```yaml From cdcc8394d89519c6854482e255c82d93e52519c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Jul 2022 19:34:43 -0400 Subject: [PATCH 3151/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index a25de7fa..8232c560 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.3" +STABLE="8.2" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From b740252f134b29d304fec17bbc8f7048b7b162b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 01:46:27 -0400 Subject: [PATCH 3152/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f1a15914..b1c95ef2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@

    Select a Proxmox Helper

    +

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    +trackgit-views 🔸
    From da33b37f9b20c0c3585744e2c7756b797336364e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 01:57:06 -0400 Subject: [PATCH 3153/6505] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index b1c95ef2..7740b209 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    -trackgit-views 🔸
    From b5be4f6ca0f75710b15d30459768a9bfc0558b8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 11:58:40 -0400 Subject: [PATCH 3154/6505] Update adguard-v3.sh --- ct/adguard-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index b9bf7a50..655fa9de 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -349,6 +349,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# AdGuard Home LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "Adguard Setup should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" From 0b62bc9d65840bb9840ad5d214163eec7f2d463b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:01:20 -0400 Subject: [PATCH 3155/6505] Update debian-v3.sh --- ct/debian-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 764d3307..5c872b28 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -349,4 +349,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" From 4c734ed8f69056a27a453cafce43adb15c8f146f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:09:37 -0400 Subject: [PATCH 3156/6505] Update daemonsync-v3.sh --- ct/daemonsync-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index f1f6c66d..2930caaa 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -348,6 +348,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8084${CL} \n" From dde2e34144266e434a5e879fca73cd6fba6dfb2a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:10:09 -0400 Subject: [PATCH 3157/6505] Update dashy-v3.sh --- ct/dashy-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index 004197a8..3b2bf0d4 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -348,6 +348,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:4000${CL} \n" From 0793150a64529313c2cc33820aa319b17dd652bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:10:54 -0400 Subject: [PATCH 3158/6505] Update deconz-v3.sh --- ct/deconz-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index 8667d0ac..246c5616 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -361,6 +361,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}${CL} \n" From da4663a05e8a40b1a1e4a9ab3237d403529afdfe Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:11:43 -0400 Subject: [PATCH 3159/6505] Update docker-v3.sh --- ct/docker-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index c6f0f248..4dde4984 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -353,4 +353,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" From 3e00150ea0b830b3de1c7171e78c07cbb546d81b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:12:27 -0400 Subject: [PATCH 3160/6505] Update esphome-v3.sh --- ct/esphome-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index b044cab7..9f8b2456 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -347,6 +347,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:6052${CL} \n" From a379018bea6cdb0fe97dc6e8964c73c2cb82db98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:13:13 -0400 Subject: [PATCH 3161/6505] Update grafana-v3.sh --- ct/grafana-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index 052d3f82..3175cdc2 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" From c147f847dd079a072cbe62945321d7d5d8470124 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:13:53 -0400 Subject: [PATCH 3162/6505] Update heimdalldashboard-v3.sh --- ct/heimdalldashboard-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index bcb2ec5b..130e5587 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -347,6 +347,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:7990${CL} \n" From a6926733bdf3687e470d23f120f06f7159ac4031 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:14:33 -0400 Subject: [PATCH 3163/6505] Update homeassistant-v3.sh --- ct/homeassistant-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 9da9f0c1..382de9a8 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -353,6 +353,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL} From 5630e929177f794e2eef59a8329a7c66eba8584e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:15:14 -0400 Subject: [PATCH 3164/6505] Update homebridge-v3.sh --- ct/homebridge-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index e8af57b3..bb6a1473 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "Homebridge should be reachable by going to the following URL. ${BL}http://${IP}:8581${CL} \n" From 3c334ab730d8d5aa7bb12e8f7aacce116570c99f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:15:56 -0400 Subject: [PATCH 3165/6505] Update influxdb-v3.sh --- ct/influxdb-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index cecd1364..c8602b61 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -347,4 +347,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" From d6fae8788dcccf9d13b855541a09b9a422cfce75 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:16:30 -0400 Subject: [PATCH 3166/6505] Update iobroker-v3.sh --- ct/iobroker-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 48139515..3382c5a1 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8081${CL} \n" From be49ae171fd20be3982cf227aa183d9868b465a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:17:05 -0400 Subject: [PATCH 3167/6505] Update jellyfin-v3.sh --- ct/jellyfin-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 651d395c..df1784ff 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -360,6 +360,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "Jellyfin Media Server should be reachable by going to the following URL. ${BL}http://${IP}:8096${CL}\n" From ed99485f67eee202e390ae64b96897ee2596b924 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:17:36 -0400 Subject: [PATCH 3168/6505] Update keycloak-v3.sh --- ct/keycloak-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/keycloak-v3.sh b/ct/keycloak-v3.sh index f78b5052..5794a434 100644 --- a/ct/keycloak-v3.sh +++ b/ct/keycloak-v3.sh @@ -350,6 +350,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" From 5e1d0291554bddfb39cbc51badf8f808dff4199d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:18:13 -0400 Subject: [PATCH 3169/6505] Update magicmirror-v3.sh --- ct/magicmirror-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/magicmirror-v3.sh b/ct/magicmirror-v3.sh index bacf531f..b97f981f 100644 --- a/ct/magicmirror-v3.sh +++ b/ct/magicmirror-v3.sh @@ -349,6 +349,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" From 6c3654069af68959d7d74e6f74bcbedd69f76a3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:18:52 -0400 Subject: [PATCH 3170/6505] Update mariadb-v3.sh --- ct/mariadb-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 3925d8fc..da4485e8 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "Adminer should be reachable by going to the following URL. ${BL}http://${IP}/adminer/${CL} \n" From 36f4b26739ae9aa7fe369cdc71767842c842d7fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:19:30 -0400 Subject: [PATCH 3171/6505] Update meshcentral-v3.sh --- ct/meshcentral-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index 1d6f2e1b..ddefc38d 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}${CL} \n" From 57b28a0b4da8b6be256d5eb745677354e6cd343d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:20:05 -0400 Subject: [PATCH 3172/6505] Update motioneye-v3.sh --- ct/motioneye-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index f83a2db8..10ade0fd 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8765${CL} \n" From 8d46f1ab3c78a943cd28bd02805e4fb598effbc9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:20:44 -0400 Subject: [PATCH 3173/6505] Update mqtt-v3.sh --- ct/mqtt-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index 3c8c4d14..6da68624 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -346,4 +346,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" From 242d3ae64a52e945370fb2a6b32d0e4f651092cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:21:20 -0400 Subject: [PATCH 3174/6505] Update nginx-proxy-manager-v3.sh --- ct/nginx-proxy-manager-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 40c4bba5..16eff8e0 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:81${CL} \n" From e4c6ba493f08cce4dfe54adf46938c1fcfe5a18c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:21:57 -0400 Subject: [PATCH 3175/6505] Update nocodb-v3.sh --- ct/nocodb-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index c32a23a4..18370502 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080/dashboard${CL}\n" From da0f73a849e7b9ba49cac9622f3f9c77a99ae11e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:22:31 -0400 Subject: [PATCH 3176/6505] Update node-red-v3.sh --- ct/node-red-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index cbd8e44b..cb35cefb 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:1880${CL} \n" From c56cc4e94ef14792df9906bd6e5fa3a9792fc63e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:23:07 -0400 Subject: [PATCH 3177/6505] Update omada-v3.sh --- ct/omada-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index be57d41d..eb2e23e3 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}https://${IP}:8043${CL} \n" From 3927a1aa6937bf76317d3df7e94b9edec4a64874 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:23:45 -0400 Subject: [PATCH 3178/6505] Update openhab-v3.sh --- ct/openhab-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/openhab-v3.sh b/ct/openhab-v3.sh index 78312e12..f3c0bcc6 100644 --- a/ct/openhab-v3.sh +++ b/ct/openhab-v3.sh @@ -351,6 +351,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL}\n" From a6f802dbcd8d291633664fb7cc34d79d0329afcf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:24:27 -0400 Subject: [PATCH 3179/6505] Update photoprism-v3.sh --- ct/photoprism-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index c77bd81c..6a74a0fe 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -347,6 +347,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:2342${CL} \n" From 3455d8b2f210a322dffc9f7dec3aeaad7c677617 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:25:05 -0400 Subject: [PATCH 3180/6505] Update pihole-v3.sh --- ct/pihole-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 493d45b4..9bae1e0f 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP}${CL} should be reachable by going to the following URL. ${BL}http://${IP}/admin${CL} \n" From 5f98181052b0ec064fb801cb544f6b61feff220a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:25:40 -0400 Subject: [PATCH 3181/6505] Update plex-v3.sh --- ct/plex-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 96fac292..302b48df 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -358,6 +358,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "Plex Media Server should be reachable by going to the following URL. ${BL}http://${IP}:32400/web${CL}\n" From c614a279abfa3f45b827e4e3d254ffcd1f760f25 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:26:17 -0400 Subject: [PATCH 3182/6505] Update podman-homeassistant-v3.sh --- ct/podman-homeassistant-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 673ec92b..1464ac6f 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -359,6 +359,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL} From b72616cbc4855960d13a76e0e451ccc5fbd91b5d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:26:53 -0400 Subject: [PATCH 3183/6505] Update postgresql-v3.sh --- ct/postgresql-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/postgresql-v3.sh b/ct/postgresql-v3.sh index 6c26d8b4..8b120b89 100644 --- a/ct/postgresql-v3.sh +++ b/ct/postgresql-v3.sh @@ -351,6 +351,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "Adminer should be reachable by going to the following URL. ${BL}http://${IP}/adminer/${CL} \n" From 8a117108b053347157254fdb8c4da789a93dbbb2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:27:35 -0400 Subject: [PATCH 3184/6505] Update prometheus-v3.sh --- ct/prometheus-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/prometheus-v3.sh b/ct/prometheus-v3.sh index d2ec1ec6..aab32e44 100644 --- a/ct/prometheus-v3.sh +++ b/ct/prometheus-v3.sh @@ -349,6 +349,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:9090${CL} \n" From f088ff7f986671b502a55f5593ec3c45b244bf50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:28:13 -0400 Subject: [PATCH 3185/6505] Update technitiumdns-v3.sh --- ct/technitiumdns-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 615cdc64..192e0ab1 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5380${CL} \n" From bc81da55e455db02b286aa3f1d1e3689f7d86975 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:28:59 -0400 Subject: [PATCH 3186/6505] Update ubuntu-v3.sh --- ct/ubuntu-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 396abc13..a1384182 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -369,4 +369,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" From 4e119886e2925613e98ab46e9cf6996b37e5ee82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:29:42 -0400 Subject: [PATCH 3187/6505] Update unifi-v3.sh --- ct/unifi-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index 57f7fab8..3b237b86 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP}${CL} should be reachable by going to the following URL. ${BL}https://${IP}:8443${CL} \n" From 5b69499c002474ad5a59705420f9e12dc2a19cab Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:30:21 -0400 Subject: [PATCH 3188/6505] Update uptimekuma-v3.sh --- ct/uptimekuma-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index 56b2afe9..f2287af9 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -348,6 +348,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3001${CL}\n" From 9a44a198b174a28c06c7db4a0d758722e8a71e54 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:30:57 -0400 Subject: [PATCH 3189/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index 8295542d..b4f264c5 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -346,6 +346,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_info "Setting Container to Normal Resources" pct set $CTID -memory 512 pct set $CTID -cores 1 From 3c3283953dcefdbcbbc1e6767deec809f64871be Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:31:45 -0400 Subject: [PATCH 3190/6505] Update whoogle-v3.sh --- ct/whoogle-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/whoogle-v3.sh b/ct/whoogle-v3.sh index 01c2c1ca..8cc19d7e 100644 --- a/ct/whoogle-v3.sh +++ b/ct/whoogle-v3.sh @@ -350,6 +350,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5000${CL} \n" From 4982a59723669d337edb416e17acc9c48fc34927 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:32:18 -0400 Subject: [PATCH 3191/6505] Update wireguard-v3.sh --- ct/wireguard-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index 528c57ed..2bebc82a 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -347,6 +347,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "WGDashboard should be reachable by going to the following URL. ${BL}http://${IP}:10086${CL} \n" From ef09f25a448a19140b622c320ef4b9b7438aa702 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:32:51 -0400 Subject: [PATCH 3192/6505] Update zigbee2mqtt-v3.sh --- ct/zigbee2mqtt-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 8d74ba7f..81c57807 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -361,4 +361,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" From 1a6b8fb8b871562191abb370654de2fcdcb33d9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:33:41 -0400 Subject: [PATCH 3193/6505] Update zwavejs2mqtt-v3.sh --- ct/zwavejs2mqtt-v3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 7e3e8107..6b54e7c1 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -344,6 +344,9 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8091${CL} \n" From ea7902116e2f3dc1151b88cca1d797d789b434f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:42:05 -0400 Subject: [PATCH 3194/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 8232c560..7307b615 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -337,6 +337,8 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null +qm set $VMID -description "# Home Assistant OS +### https://github.com/tteck/Proxmox" msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" From 48889190d1ff9d52ecd9eead6b2361728eab0ace Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:48:01 -0400 Subject: [PATCH 3195/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 7307b615..cad4c934 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -338,7 +338,7 @@ qm set $VMID \ qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS -### https://github.com/tteck/Proxmox" +### https://github.com/tteck/Proxmox" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" From 9fa467647a696dc36e04b5e9fafe051617c5a72d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 12:55:17 -0400 Subject: [PATCH 3196/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index a25de7fa..d0f8f49d 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -337,7 +337,8 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null - +qm set $VMID -description "# Home Assistant OS +### https://github.com/tteck/Proxmox" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" if [ "$START_VM" == "yes" ]; then From 790434c6814b721e79073030689645731ec9ac7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Jul 2022 15:19:40 -0400 Subject: [PATCH 3197/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7740b209..5e3f51b2 100644 --- a/README.md +++ b/README.md @@ -318,7 +318,7 @@ ________________________________________________________________________________
    - 🔸openHAB LXC + openHAB LXC

    From 2b73af9c23beba8193baf36737b211fe37572b45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Jul 2022 12:14:29 -0400 Subject: [PATCH 3198/6505] test script --- vm/pimox-haos.sh | 343 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 vm/pimox-haos.sh diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh new file mode 100644 index 00000000..13aaae0b --- /dev/null +++ b/vm/pimox-haos.sh @@ -0,0 +1,343 @@ +#!/usr/bin/env bash +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +NEXTID=$(pvesh get /cluster/nextid) +RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +STABLE="8.2" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} + +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +while true; do + read -p "This will create a New PiMox Home Assistant OS VM. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear + +function header_info { +echo -e "${YW} + + _____ _ _ _ ____ _____ + | __ (_) | | | | /\ / __ \ / ____| + | |__) | ______| |__| | / \ | | | | (___ + | ___/ |__v3__| __ | / /\ \| | | |\___ \ + | | | | | | | |/ ____ \ |__| |____) | + |_| |_| |_| |_/_/ \_\____/|_____/ +${CL}" +} +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using Version ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using VM Name ${BGN}pi-haos${STABLE}${CL}" + VM_NAME=pi-haos${STABLE} + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" + START_VM="yes" + +} +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Latest for Version ${RELEASE}, or Press [ENTER] for Stable Version ${STABLE} " + read BRANCH + if [ -z $BRANCH ]; then BRANCH=$STABLE; + else + BRANCH=$RELEASE; fi; + echo -en "${DGN}Set Version To ${BL}$BRANCH${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read VMID + if [ -z $VMID ]; then VMID=$NEXTID; fi; + echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: pi-haos${BRANCH} " + read VMNAME + if [ -z $VMNAME ]; then + VM_NAME=pi-haos${BRANCH} + else + VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$VM_NAME${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}${CORE_COUNT}${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Valid MAC Address, or Press [ENTER] for Generated MAC: $GEN_MAC " + read MAC + if [ -z $MAC ]; then MAC=$GEN_MAC; fi; + echo -en "${DGN}Set MAC Address To ${BL}$MAC${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " + read START_VM + if [ -z $START_VM ]; then START_VM="yes"; + else + START_VM="no"; fi; + echo -en "${DGN}Starting VM when completed ${BL}$START_VM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" + echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" + echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + echo -e "'Disk image' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the Pi-HAOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_generic-aarch64-${BRANCH}.img.xz +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}haos_generic-aarch64-${BRANCH}.img.xz${CL}" +msg_info "Extracting Disk Image" +unxz $FILE +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + btrfs|nfs|dir) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +msg_ok "Extracted Disk Image" + +msg_info "Creating Pi-HAOS VM" +qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ + -scsi0 ${DISK1_REF},size=6G >/dev/null +qm set $VMID \ + -boot order=scsi0 >/dev/null +qm resize $VMID scsi0 +26G >/dev/null +qm set $VMID -description "# Home Assistant OS +### https://github.com/tteck/Proxmox" >/dev/null + +msg_ok "Created Pi-HAOS VM ${CL}${BL}${VM_NAME}" + +if [ "$START_VM" == "yes" ]; then +msg_info "Starting Home Assistant OS VM" +qm start $VMID +msg_ok "Started Home Assistant OS VM" +fi +msg_ok "Completed Successfully!\n" From f3976828287932aa158239d5f2e5a5fc793aa629 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Jul 2022 15:35:23 -0400 Subject: [PATCH 3199/6505] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5e3f51b2..ff422513 100644 --- a/README.md +++ b/README.md @@ -843,8 +843,7 @@ npm start Run in the LXC console ```yaml -cd /opt/zigbee2mqtt -bash update.sh +cd /opt/zigbee2mqtt && bash update.sh ``` ⚙️ **Copy Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** @@ -1541,8 +1540,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror- Run in the LXC Console ```yaml -cd /opt/magicmirror -git pull && npm install --only=prod --omit=dev +cd /opt/magicmirror && git pull && npm install --only=prod --omit=dev ``` From a5e7557870a027442b836c553df3da315300f8f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Jul 2022 12:38:19 -0400 Subject: [PATCH 3200/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index b4f264c5..30772996 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -88,9 +88,9 @@ function default_settings() { echo -e "${DGN}Using Disk Size ${BGN}6${CL}${DGN}GB${CL}" DISK_SIZE="6" echo -e "${DGN}Using ${BGN}4${CL}${DGN}vCPU${CL}" - CORE_COUNT="4" + CORE_COUNT="2" echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="4096" + RAM_SIZE="2048" echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" @@ -179,9 +179,9 @@ header_info echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 4 " + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="4"; fi; + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" echo -e " ${CM}${CL} \r" sleep 1 @@ -194,9 +194,9 @@ header_info echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" echo -e " ${CM}${CL} \n" sleep 1 From eea8c0701e6d07743d8cc9d859b8ce822da7dfa4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Jul 2022 12:42:16 -0400 Subject: [PATCH 3201/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ff422513..9d9fc2ad 100644 --- a/README.md +++ b/README.md @@ -1906,6 +1906,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden- The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. Expect 30+ minute install time. +

    ⚡ Build Settings: 2048Mib RAM - 6GB Storage - 2vCPU ⚡

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    **Vaultwarden Interface - IP:8000** From bdee71bc743a5eee9d0700dfd25c8376c754cfbc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Jul 2022 16:34:23 -0400 Subject: [PATCH 3202/6505] Fix Vaultwarden/Web-vault Update scripts (#355) * Update and rename vaultwarden-update.sh to web-vault-update.sh * Create vaultwarden-update.sh * Update web-vault-update.sh * Update web-vault-update.sh * Update web-vault-update.sh * Update web-vault-update.sh * Update web-vault-update.sh * Update vaultwarden-update.sh * Update README.md * Update CHANGELOG.MD * Update vaultwarden-update.sh * Update vaultwarden-update.sh * Update README.md * Update vaultwarden-update.sh * Update vaultwarden-update.sh --- CHANGELOG.MD | 8 ++++++ README.md | 12 ++++++--- misc/vaultwarden-update.sh | 31 ++++++++++++----------- misc/web-vault-update.sh | 50 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 misc/web-vault-update.sh diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1455042f..8c231e81 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,14 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-17 + +### Changed + +- **Vaultwarden LXC** + - NEW Vaultwarden Update (post 2022-05-29 only) Script + - NEW Web-vault Update (any) Script + ## 2022-07-14 ### Changed diff --git a/README.md b/README.md index 9d9fc2ad..cb04974f 100644 --- a/README.md +++ b/README.md @@ -1888,7 +1888,7 @@ ________________________________________________________________________________
    - Vaultwarden LXC + 🔸Vaultwarden LXC

    @@ -1909,19 +1909,25 @@ Expect 30+ minute install time.

    ⚡ Build Settings: 2048Mib RAM - 6GB Storage - 2vCPU ⚡

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    -**Vaultwarden Interface - IP:8000** +**Vaultwarden Interface: CTIP:8000** ⚙️ **Path to Vaultwarden .env file** (to enable `ADMIN_TOKEN`) ```yaml /opt/vaultwarden/.env ``` -⚙️ **To Update Vaultwarden** +⚙️ **To Update Vaultwarden (post 2022-05-29 only)** Run in the LXC console ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/vaultwarden-update.sh)" ``` +⚙️ **To Update Web-vault (any)** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/web-vault-update.sh)" +``` ____________________________________________________________________________________________ diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 1a5e7a7d..b645e810 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -1,5 +1,5 @@ -#!/bin/sh -VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ +#!/usr/bin/env bash +VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 2, length($2)-3) }') \ @@ -16,13 +16,13 @@ echo -e "${BL} \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| - UPDATE + ${VAULT} UPDATE ${CL}" } update_info while true; do - read -p "This will Update Vaultwarden to $VWRELEASE. Proceed(y/n)?" yn + read -p "This will Update Vaultwarden to $VAULT (set 2vCPU 2048MiB RAM Min.). Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -34,18 +34,17 @@ echo -e "${GN} Stopping Vaultwarden... ${CL}" systemctl stop vaultwarden.service sleep 1 -echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" -curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null -if [ -d "/var/lib/vaultwarden" ]; then -tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null -else -tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null -fi +echo -e "${GN} Updating (Building) to ${VAULT} (Patience)... ${CL}" +git clone https://github.com/dani-garcia/vaultwarden &>/dev/null +cd vaultwarden +cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null +cp target/release/vaultwarden /opt/vaultwarden/bin/ -echo -e "${GN} Cleaning up... ${CL}" -rm bw_web_$VWRELEASE.tar.gz - -echo -e "${GN} Starting Vaultwarden... ${CL}" +echo -e "${GN} Starting Vaultwarden ${VAULT}... ${CL}" systemctl start vaultwarden.service sleep 1 -echo -e "${GN} Finished Update ${CL}" + +echo -e "${GN} Cleaning up... ${CL}" +cd ~ && rm -rf vaultwarden + +echo -e "${GN} Finished Update (set resources back to normal settings)${CL}" diff --git a/misc/web-vault-update.sh b/misc/web-vault-update.sh new file mode 100644 index 00000000..d55b0aeb --- /dev/null +++ b/misc/web-vault-update.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ + +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +function update_info { +echo -e "${BL} + __ __ _ _ _ + \ \ / / | | | | | + \ \ /\ / /__| |__ ________ ____ _ _ _| | |_ + \ \/ \/ / _ \ _ \______\ \ / / _ | | | | | __| + \ /\ / __/ |_) | \ V / (_| | |_| | | |_ + \/ \/ \___|_.__/ \_/ \__,_|\__,_|_|\__| + ${VWRELEASE} UPDATE +${CL}" +} +update_info +while true; do + read -p "This will Update Web-Vault to $VWRELEASE. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +sleep 2 +echo -e "${GN} Stopping Vaultwarden... ${CL}" +systemctl stop vaultwarden.service +sleep 1 + +echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" +curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null +if [ -d "/var/lib/vaultwarden" ]; then +tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null +else +tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null +fi + +echo -e "${GN} Cleaning up... ${CL}" +rm bw_web_$VWRELEASE.tar.gz + +echo -e "${GN} Starting Vaultwarden... ${CL}" +systemctl start vaultwarden.service +sleep 1 +echo -e "${GN} Finished Update ${CL}" From 968a3543307ec21e03d57cd51e50611e14b3870d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Jul 2022 22:21:30 -0400 Subject: [PATCH 3203/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb04974f..5e999a51 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant OS VM + Home Assistant OS VM

    From e7f73fbd5ee4745a0319e284a884d32b186a2b64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Jul 2022 03:41:19 -0400 Subject: [PATCH 3204/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e999a51..85ce883c 100644 --- a/README.md +++ b/README.md @@ -1916,7 +1916,7 @@ Expect 30+ minute install time. /opt/vaultwarden/.env ``` -⚙️ **To Update Vaultwarden (post 2022-05-29 only)** +⚙️ **To Update Vaultwarden (post 2022-05-29 installs only)** Run in the LXC console ```yaml From 9d2ff2ca4efee77fb77e4852368699cc062e56f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Jul 2022 04:25:37 -0400 Subject: [PATCH 3205/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 8c231e81..1783da1d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Vaultwarden LXC** - - NEW Vaultwarden Update (post 2022-05-29 only) Script + - NEW Vaultwarden Update (post 2022-05-29 installs only) Script - NEW Web-vault Update (any) Script ## 2022-07-14 From 712daafc6a640818fb245de191b403b6691d9372 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Jul 2022 14:03:55 -0400 Subject: [PATCH 3206/6505] test script --- vm/pimox-haos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh index 13aaae0b..fa00b8cc 100644 --- a/vm/pimox-haos.sh +++ b/vm/pimox-haos.sh @@ -329,7 +329,7 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=6G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null -qm resize $VMID scsi0 +26G >/dev/null +#qm resize $VMID scsi0 +26G >/dev/null qm set $VMID -description "# Home Assistant OS ### https://github.com/tteck/Proxmox" >/dev/null From 0fe9d91d38a4c4f7735fa861e6bc4c1241b7a467 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Jul 2022 14:08:12 -0400 Subject: [PATCH 3207/6505] test script --- vm/pimox-haos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh index fa00b8cc..d62c3691 100644 --- a/vm/pimox-haos.sh +++ b/vm/pimox-haos.sh @@ -326,7 +326,7 @@ pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ - -scsi0 ${DISK1_REF},size=6G >/dev/null + -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null #qm resize $VMID scsi0 +26G >/dev/null From b6c6190600c0e42ea7b98f93dcf9b7f672aacbb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Jul 2022 14:31:11 -0400 Subject: [PATCH 3208/6505] test script --- vm/pimox-haos.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh index d62c3691..a2d29003 100644 --- a/vm/pimox-haos.sh +++ b/vm/pimox-haos.sh @@ -322,10 +322,10 @@ msg_ok "Extracted Disk Image" msg_info "Creating Pi-HAOS VM" qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 8M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ + -efidisk0 ${DISK0_REF},efitype=8m,size=8M \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From 6ff4f880ab0eccec44c9a71d3f04e93d1e7cd5bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Jul 2022 15:04:24 -0400 Subject: [PATCH 3209/6505] test script --- vm/pimox-haos.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh index a2d29003..41c15126 100644 --- a/vm/pimox-haos.sh +++ b/vm/pimox-haos.sh @@ -320,12 +320,12 @@ done msg_ok "Extracted Disk Image" msg_info "Creating Pi-HAOS VM" -qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 8M 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=8m,size=8M \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From 1285b2fb20e6de9131030fcad627d5e328dc1f9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Jul 2022 11:47:46 -0400 Subject: [PATCH 3210/6505] Update vaultwarden-v3.sh --- ct/vaultwarden-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index 30772996..bfa156f7 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -87,9 +87,9 @@ function default_settings() { HN=$NSAPP echo -e "${DGN}Using Disk Size ${BGN}6${CL}${DGN}GB${CL}" DISK_SIZE="6" - echo -e "${DGN}Using ${BGN}4${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" RAM_SIZE="2048" echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" BRG="vmbr0" From 84865b7f3a4b1ca7429cfd0e95d4ce72d2b1097c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Jul 2022 14:23:02 -0400 Subject: [PATCH 3211/6505] Update jellyfin-install.sh --- setup/jellyfin-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index bc116748..4574a10c 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -98,7 +98,7 @@ After = network.target Type = simple EnvironmentFile = /etc/default/jellyfin User = root -ExecStart = /usr/bin/jellyfin ${JELLYFIN_WEB_OPT} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELL> +ExecStart = /usr/bin/jellyfin Restart = on-failure TimeoutSec = 15 [Install] From f16fd89271a93ff6a88dbb4b964ef1fd707516a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Jul 2022 19:18:18 -0400 Subject: [PATCH 3212/6505] correct spelling --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index d0f8f49d..3e2bcd69 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -24,7 +24,7 @@ trap cleanup EXIT function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 From 73852c9113e4d9de6a27985e33eb5d762d93c760 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Jul 2022 19:19:14 -0400 Subject: [PATCH 3213/6505] correct spelling --- vm/pimox-haos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh index 41c15126..38b009ae 100644 --- a/vm/pimox-haos.sh +++ b/vm/pimox-haos.sh @@ -24,7 +24,7 @@ trap cleanup EXIT function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 From 5b9c37ce81334b2350c1e9eab82a2bcf2eb1a248 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Jul 2022 19:19:44 -0400 Subject: [PATCH 3214/6505] correct spelling --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index cad4c934..83652ed4 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -24,7 +24,7 @@ trap cleanup EXIT function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 From fca2fcf970b6b956d61a215756cbcd27ff04ea0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Jul 2022 06:10:39 -0400 Subject: [PATCH 3215/6505] Correct Spelling (#360) * Update adguard-install.sh * Update daemonsync-install.sh * Update dashy-install.sh * Update debian-install.sh * Update deconz-install.sh * Update docker-install.sh * Update esphome-install.sh * Update grafana-install.sh * Update heimdalldashboard-install.sh * Update homeassistant-install.sh * Update homebridge-install.sh * Update influxdb-install.sh * Update iobroker-install.sh * Update jellyfin-install.sh * Update keycloak-install.sh * Update magicmirror-install.sh * Update mariadb-install.sh * Update meshcentral-install.sh * Update motioneye-install.sh * Update mqtt-install.sh * Update nginx-proxy-manager-install.sh * Update nocodb-install.sh * Update node-red-install.sh * Update omada-install.sh * Update openhab-install.sh * Update photoprism-install.sh * Update pihole-install.sh * Update plex-install.sh * Update podman-homeassistant-install.sh * Update postgresql-install.sh * Update prometheus-install.sh * Update technitiumdns-install.sh * Update ubuntu-install.sh * Update unifi-install.sh * Update uptimekuma-install.sh * Update vaultwarden-install.sh * Update whoogle-install.sh * Update wireguard-install.sh * Update zigbee2mqtt-install.sh * Update zwavejs2mqtt-install.sh * Update adguard-v3.sh * Update create_lxc.sh * Update daemonsync-v3.sh * Update dashy-v3.sh * Update debian-v3.sh * Update deconz-v3.sh * Update docker-v3.sh * Update esphome-v3.sh * Update grafana-v3.sh * Update heimdalldashboard-v3.sh * Update homeassistant-v3.sh * Update homebridge-v3.sh * Update influxdb-v3.sh * Update iobroker-v3.sh * Update jellyfin-v3.sh * Update keycloak-v3.sh * Update magicmirror-v3.sh * Update mariadb-v3.sh * Update meshcentral-v3.sh * Update motioneye-v3.sh * Update mqtt-v3.sh * Update nginx-proxy-manager-v3.sh * Update nocodb-v3.sh * Update node-red-v3.sh * Update omada-v3.sh * Update openhab-v3.sh * Update photoprism-v3.sh * Update pihole-v3.sh * Update plex-v3.sh * Update podman-homeassistant-v3.sh * Update postgresql-v3.sh * Update prometheus-v3.sh * Update technitiumdns-v3.sh * Update ubuntu-v3.sh * Update unifi-v3.sh * Update uptimekuma-v3.sh * Update vaultwarden-v3.sh * Update whoogle-v3.sh * Update wireguard-v3.sh * Update zigbee2mqtt-v3.sh * Update zwavejs2mqtt-v3.sh --- ct/adguard-v3.sh | 2 +- ct/create_lxc.sh | 2 +- ct/daemonsync-v3.sh | 2 +- ct/dashy-v3.sh | 2 +- ct/debian-v3.sh | 2 +- ct/deconz-v3.sh | 2 +- ct/docker-v3.sh | 2 +- ct/esphome-v3.sh | 2 +- ct/grafana-v3.sh | 2 +- ct/heimdalldashboard-v3.sh | 2 +- ct/homeassistant-v3.sh | 2 +- ct/homebridge-v3.sh | 2 +- ct/influxdb-v3.sh | 2 +- ct/iobroker-v3.sh | 2 +- ct/jellyfin-v3.sh | 2 +- ct/keycloak-v3.sh | 2 +- ct/magicmirror-v3.sh | 2 +- ct/mariadb-v3.sh | 2 +- ct/meshcentral-v3.sh | 2 +- ct/motioneye-v3.sh | 2 +- ct/mqtt-v3.sh | 2 +- ct/nginx-proxy-manager-v3.sh | 2 +- ct/nocodb-v3.sh | 2 +- ct/node-red-v3.sh | 2 +- ct/omada-v3.sh | 2 +- ct/openhab-v3.sh | 2 +- ct/photoprism-v3.sh | 2 +- ct/pihole-v3.sh | 2 +- ct/plex-v3.sh | 2 +- ct/podman-homeassistant-v3.sh | 2 +- ct/postgresql-v3.sh | 2 +- ct/prometheus-v3.sh | 2 +- ct/technitiumdns-v3.sh | 2 +- ct/ubuntu-v3.sh | 2 +- ct/unifi-v3.sh | 2 +- ct/uptimekuma-v3.sh | 2 +- ct/vaultwarden-v3.sh | 2 +- ct/whoogle-v3.sh | 2 +- ct/wireguard-v3.sh | 2 +- ct/zigbee2mqtt-v3.sh | 2 +- ct/zwavejs2mqtt-v3.sh | 17 +++++++++++++++++ setup/adguard-install.sh | 2 +- setup/daemonsync-install.sh | 2 +- setup/dashy-install.sh | 2 +- setup/debian-install.sh | 2 +- setup/deconz-install.sh | 2 +- setup/docker-install.sh | 2 +- setup/esphome-install.sh | 2 +- setup/grafana-install.sh | 2 +- setup/heimdalldashboard-install.sh | 2 +- setup/homeassistant-install.sh | 2 +- setup/homebridge-install.sh | 2 +- setup/influxdb-install.sh | 2 +- setup/iobroker-install.sh | 2 +- setup/jellyfin-install.sh | 2 +- setup/keycloak-install.sh | 2 +- setup/magicmirror-install.sh | 2 +- setup/mariadb-install.sh | 2 +- setup/meshcentral-install.sh | 2 +- setup/motioneye-install.sh | 2 +- setup/mqtt-install.sh | 2 +- setup/nginx-proxy-manager-install.sh | 2 +- setup/nocodb-install.sh | 2 +- setup/node-red-install.sh | 2 +- setup/omada-install.sh | 2 +- setup/openhab-install.sh | 2 +- setup/photoprism-install.sh | 2 +- setup/pihole-install.sh | 2 +- setup/plex-install.sh | 2 +- setup/podman-homeassistant-install.sh | 2 +- setup/postgresql-install.sh | 2 +- setup/prometheus-install.sh | 2 +- setup/technitiumdns-install.sh | 2 +- setup/ubuntu-install.sh | 2 +- setup/unifi-install.sh | 2 +- setup/uptimekuma-install.sh | 2 +- setup/vaultwarden-install.sh | 2 +- setup/whoogle-install.sh | 2 +- setup/wireguard-install.sh | 2 +- setup/zigbee2mqtt-install.sh | 2 +- setup/zwavejs2mqtt-install.sh | 2 +- 81 files changed, 97 insertions(+), 80 deletions(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index 655fa9de..de7e7e8c 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -24,7 +24,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 5bcce863..4cb7864e 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -17,7 +17,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index 2930caaa..f4b50508 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index 3b2bf0d4..8d74bd5d 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 5c872b28..4003fd90 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -29,7 +29,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index 246c5616..6997e34c 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -29,7 +29,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index 4dde4984..bca99c7e 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 9f8b2456..8616eb25 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index 3175cdc2..d106ab55 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index 130e5587..c56ab9e1 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -24,7 +24,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 382de9a8..4bedfe63 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index bb6a1473..0bb4cd62 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index c8602b61..075c51d4 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 3382c5a1..55f98b00 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index df1784ff..2262277d 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -24,7 +24,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/keycloak-v3.sh b/ct/keycloak-v3.sh index 5794a434..ddfd12ae 100644 --- a/ct/keycloak-v3.sh +++ b/ct/keycloak-v3.sh @@ -29,7 +29,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/magicmirror-v3.sh b/ct/magicmirror-v3.sh index b97f981f..ab15832f 100644 --- a/ct/magicmirror-v3.sh +++ b/ct/magicmirror-v3.sh @@ -29,7 +29,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index da4485e8..3ec3fd17 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index ddefc38d..1b47dfc1 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index 10ade0fd..a837501c 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index 6da68624..d9e7f025 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 16eff8e0..3485393f 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index 18370502..34712d40 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index cb35cefb..f0331e4d 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index eb2e23e3..513d93f3 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/openhab-v3.sh b/ct/openhab-v3.sh index f3c0bcc6..35d512c4 100644 --- a/ct/openhab-v3.sh +++ b/ct/openhab-v3.sh @@ -29,7 +29,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index 6a74a0fe..bc2f2362 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -24,7 +24,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 9bae1e0f..88c5a57e 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 302b48df..8d3ea495 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -24,7 +24,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 1464ac6f..97d2048d 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -24,7 +24,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/postgresql-v3.sh b/ct/postgresql-v3.sh index 8b120b89..788fea92 100644 --- a/ct/postgresql-v3.sh +++ b/ct/postgresql-v3.sh @@ -29,7 +29,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/prometheus-v3.sh b/ct/prometheus-v3.sh index aab32e44..ad555450 100644 --- a/ct/prometheus-v3.sh +++ b/ct/prometheus-v3.sh @@ -29,7 +29,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 192e0ab1..107dfe7d 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index a1384182..586f4f82 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index 3b237b86..40d5a222 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index f2287af9..fc5eb477 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index bfa156f7..38a23d01 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/whoogle-v3.sh b/ct/whoogle-v3.sh index 8cc19d7e..c0529fb3 100644 --- a/ct/whoogle-v3.sh +++ b/ct/whoogle-v3.sh @@ -30,7 +30,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index 2bebc82a..b0bf0bac 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -23,7 +23,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 81c57807..3a48dd9c 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -24,7 +24,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 6b54e7c1..99afdd8d 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -14,6 +14,23 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" APP="Zwavejs2MQTT" NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + while true; do read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 9837589f..fd8ff882 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 60d6e1cf..2af9de0a 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index f172a1c2..02039294 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/debian-install.sh b/setup/debian-install.sh index e7c6af98..48e7eb1f 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index e367205f..d38b416a 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/docker-install.sh b/setup/docker-install.sh index fed664cf..aec07703 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 44fe61fa..e8c0c05a 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 12a96358..9eff5400 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 5ebef0e8..852068d8 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 77ab5de4..8ee274bb 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 70e455d3..8ba3327f 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 441f4070..216949e7 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index c9650bab..9db4f6d3 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 4574a10c..dccddafe 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index 53da44b8..b593459c 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index b3461fc7..3513f225 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index e5680925..18db68da 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 2155cf4a..485b352f 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 730a5266..4b96cc31 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index c84f645d..fd52f630 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 686a4b60..afa87e32 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 7b9c96c7..9e51d2e1 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 313da248..058fb297 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 0423e373..598dabde 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 25e9f9ab..c4e69e18 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 9ad97e85..51a62770 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -22,7 +22,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 0e9b413d..0a47cc07 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 08695424..c5030bc2 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 0ed099da..43fd53b9 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 8cbc6aa3..c9cc2a7b 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 87338f49..e83fa5a0 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 18d2eca6..1a9e5271 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index bc311688..7173f364 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 071ef075..f47cb3e3 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -22,7 +22,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 57c13fc2..948ab37f 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 78c22b10..ec4da4f3 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index ce4803f6..52d65c56 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 8109a2a0..4804a3c6 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 0e7f6ad6..8056c2b6 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 0d2c1ead..06aabdda 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -21,7 +21,7 @@ trap die ERR function error_exit() { trap - ERR - local reason="Unknown failure occured." + local reason="Unknown failure occurred." local msg="${1:-$reason}" local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" echo -e "$flag $msg" 1>&2 From 1c3ba6c2bc289523662570db0fbc0f2f8b375c95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Jul 2022 07:48:59 -0400 Subject: [PATCH 3216/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 85ce883c..01873670 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ ________________________________________________________________________________
    - 🔸Proxmox Edge Kernel Tool + Proxmox Edge Kernel Tool

    From e851a070bdd326be665ea8439917ae6c09a19887 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Jul 2022 12:20:27 -0400 Subject: [PATCH 3217/6505] add exiftool --- setup/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 51a62770..20fa12c9 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -70,6 +70,7 @@ apt-get install -y gnupg &>/dev/null apt-get install -y make &>/dev/null apt-get install -y zip &>/dev/null apt-get install -y unzip &>/dev/null +apt-get install -y exiftool &>/dev/null apt-get install -y ffmpeg &>/dev/null msg_ok "Installed Dependencies" From d8bb779b1f5b3f77c991a2f710f03d3feef3db28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Jul 2022 20:27:31 -0400 Subject: [PATCH 3218/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01873670..c8882b35 100644 --- a/README.md +++ b/README.md @@ -1514,7 +1514,7 @@ ________________________________________________________________________________
    - 🔸MagicMirror Server LXC + MagicMirror Server LXC

    From 43cc17f6d221b85672d92105a0b16ef171577c82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 07:00:47 -0400 Subject: [PATCH 3219/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 3e2bcd69..34459f59 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.3" +STABLE="8.2" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` From be3ba17993a3c27370adb3350e19d5aa337c3a7a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 07:50:42 -0400 Subject: [PATCH 3220/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 34459f59..8c6e2a2f 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -2,7 +2,7 @@ GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.2" +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -258,7 +258,7 @@ fi } function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + echo -e "${YW}Type Advanced (Latest ${RELEASE}), or Press [ENTER] for Default Settings (Stable ${STABLE}) " read SETTINGS if [ -z $SETTINGS ]; then default_settings; else From df91454ca6c2574fdf9f7ebe9849c33888c81183 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 08:47:16 -0400 Subject: [PATCH 3221/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 8c6e2a2f..105aad6d 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') @@ -50,6 +51,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null while true; do + clear read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; From ed377bd06d3a311d9c9d6f91c4a15a57b0ef4ef0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 10:22:33 -0400 Subject: [PATCH 3222/6505] Maintenance (#365) * Update debian-v3.sh * Update debian-v3.sh * Update adguard-v3.sh * Update daemonsync-v3.sh * Update dashy-v3.sh * Update deconz-v3.sh * Update docker-v3.sh * Update esphome-v3.sh * Update grafana-v3.sh * Update heimdalldashboard-v3.sh * Update homeassistant-v3.sh * Update homebridge-v3.sh * Update influxdb-v3.sh * Update iobroker-v3.sh * Update jellyfin-v3.sh * Update keycloak-v3.sh * Update magicmirror-v3.sh * Update mariadb-v3.sh * Update meshcentral-v3.sh * Update motioneye-v3.sh * Update mqtt-v3.sh * Update nginx-proxy-manager-v3.sh * Update nocodb-v3.sh * Update node-red-v3.sh * Update omada-v3.sh * Update openhab-v3.sh * Update photoprism-v3.sh * Update pihole-v3.sh * Update plex-v3.sh * Update podman-homeassistant-v3.sh * Update postgresql-v3.sh * Update prometheus-v3.sh * Update technitiumdns-v3.sh * Update ubuntu-v3.sh * Update unifi-v3.sh * Update uptimekuma-v3.sh * Update vaultwarden-v3.sh * Update whoogle-v3.sh * Update wireguard-v3.sh * Update zigbee2mqtt-v3.sh * Update zwavejs2mqtt-v3.sh * Update haos_vm.sh * Update haos_vm.sh --- ct/adguard-v3.sh | 3 ++- ct/daemonsync-v3.sh | 2 ++ ct/dashy-v3.sh | 2 ++ ct/debian-v3.sh | 2 ++ ct/deconz-v3.sh | 2 ++ ct/docker-v3.sh | 2 ++ ct/esphome-v3.sh | 2 ++ ct/grafana-v3.sh | 2 ++ ct/heimdalldashboard-v3.sh | 2 ++ ct/homeassistant-v3.sh | 2 ++ ct/homebridge-v3.sh | 2 ++ ct/influxdb-v3.sh | 2 ++ ct/iobroker-v3.sh | 2 ++ ct/jellyfin-v3.sh | 2 ++ ct/keycloak-v3.sh | 2 ++ ct/magicmirror-v3.sh | 2 ++ ct/mariadb-v3.sh | 2 ++ ct/meshcentral-v3.sh | 2 ++ ct/motioneye-v3.sh | 2 ++ ct/mqtt-v3.sh | 2 ++ ct/nginx-proxy-manager-v3.sh | 2 ++ ct/nocodb-v3.sh | 2 ++ ct/node-red-v3.sh | 2 ++ ct/omada-v3.sh | 2 ++ ct/openhab-v3.sh | 2 ++ ct/photoprism-v3.sh | 2 ++ ct/pihole-v3.sh | 2 ++ ct/plex-v3.sh | 2 ++ ct/podman-homeassistant-v3.sh | 2 ++ ct/postgresql-v3.sh | 2 ++ ct/prometheus-v3.sh | 2 ++ ct/technitiumdns-v3.sh | 2 ++ ct/ubuntu-v3.sh | 2 ++ ct/unifi-v3.sh | 2 ++ ct/uptimekuma-v3.sh | 2 ++ ct/vaultwarden-v3.sh | 2 ++ ct/whoogle-v3.sh | 2 ++ ct/wireguard-v3.sh | 2 ++ ct/zigbee2mqtt-v3.sh | 2 ++ ct/zwavejs2mqtt-v3.sh | 2 ++ vm/haos_vm.sh | 4 +++- 41 files changed, 83 insertions(+), 2 deletions(-) diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh index de7e7e8c..26955d34 100644 --- a/ct/adguard-v3.sh +++ b/ct/adguard-v3.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -32,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh index f4b50508..df44541e 100644 --- a/ct/daemonsync-v3.sh +++ b/ct/daemonsync-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh index 8d74bd5d..b7e795d2 100644 --- a/ct/dashy-v3.sh +++ b/ct/dashy-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh index 4003fd90..79c9bdd1 100644 --- a/ct/debian-v3.sh +++ b/ct/debian-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="Debian" var_disk="2" var_cpu="1" @@ -47,6 +48,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh index 6997e34c..3679fb6c 100644 --- a/ct/deconz-v3.sh +++ b/ct/deconz-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="deCONZ" var_disk="4" var_cpu="2" @@ -47,6 +48,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh index bca99c7e..3c2c71a4 100644 --- a/ct/docker-v3.sh +++ b/ct/docker-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh index 8616eb25..b39f4f07 100644 --- a/ct/esphome-v3.sh +++ b/ct/esphome-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh index d106ab55..cf708a67 100644 --- a/ct/grafana-v3.sh +++ b/ct/grafana-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh index c56ab9e1..1a1eb641 100644 --- a/ct/heimdalldashboard-v3.sh +++ b/ct/heimdalldashboard-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' PP=`echo "\e[1;35m"` @@ -32,6 +33,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh index 4bedfe63..ad4dc553 100644 --- a/ct/homeassistant-v3.sh +++ b/ct/homeassistant-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh index 0bb4cd62..629a9a19 100644 --- a/ct/homebridge-v3.sh +++ b/ct/homebridge-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh index 075c51d4..d4288d8b 100644 --- a/ct/influxdb-v3.sh +++ b/ct/influxdb-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh index 55f98b00..f6a52106 100644 --- a/ct/iobroker-v3.sh +++ b/ct/iobroker-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh index 2262277d..59b4cae9 100644 --- a/ct/jellyfin-v3.sh +++ b/ct/jellyfin-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -32,6 +33,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/keycloak-v3.sh b/ct/keycloak-v3.sh index ddfd12ae..f11080d3 100644 --- a/ct/keycloak-v3.sh +++ b/ct/keycloak-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="Keycloak" var_disk="4" var_cpu="2" @@ -47,6 +48,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/magicmirror-v3.sh b/ct/magicmirror-v3.sh index ab15832f..fc2fa201 100644 --- a/ct/magicmirror-v3.sh +++ b/ct/magicmirror-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="MagicMirror" var_disk="3" var_cpu="1" @@ -47,6 +48,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh index 3ec3fd17..74c52575 100644 --- a/ct/mariadb-v3.sh +++ b/ct/mariadb-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh index 1b47dfc1..ff411439 100644 --- a/ct/meshcentral-v3.sh +++ b/ct/meshcentral-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh index a837501c..1c3ca29e 100644 --- a/ct/motioneye-v3.sh +++ b/ct/motioneye-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh index d9e7f025..7d74a950 100644 --- a/ct/mqtt-v3.sh +++ b/ct/mqtt-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh index 3485393f..bfcf2225 100644 --- a/ct/nginx-proxy-manager-v3.sh +++ b/ct/nginx-proxy-manager-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh index 34712d40..9ede88a8 100644 --- a/ct/nocodb-v3.sh +++ b/ct/nocodb-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh index f0331e4d..58252e17 100644 --- a/ct/node-red-v3.sh +++ b/ct/node-red-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh index 513d93f3..7b97dace 100644 --- a/ct/omada-v3.sh +++ b/ct/omada-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/openhab-v3.sh b/ct/openhab-v3.sh index 35d512c4..a4726cb0 100644 --- a/ct/openhab-v3.sh +++ b/ct/openhab-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="openHAB" var_disk="8" var_cpu="2" @@ -47,6 +48,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh index bc2f2362..3f90236f 100644 --- a/ct/photoprism-v3.sh +++ b/ct/photoprism-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' PP=`echo "\e[1;35m"` @@ -32,6 +33,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh index 88c5a57e..03a5b577 100644 --- a/ct/pihole-v3.sh +++ b/ct/pihole-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh index 8d3ea495..da77b58e 100644 --- a/ct/plex-v3.sh +++ b/ct/plex-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -32,6 +33,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh index 97d2048d..30985849 100644 --- a/ct/podman-homeassistant-v3.sh +++ b/ct/podman-homeassistant-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -32,6 +33,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/postgresql-v3.sh b/ct/postgresql-v3.sh index 788fea92..d68d8102 100644 --- a/ct/postgresql-v3.sh +++ b/ct/postgresql-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="PostgreSQL" var_disk="4" var_cpu="1" @@ -47,6 +48,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/prometheus-v3.sh b/ct/prometheus-v3.sh index ad555450..a41f5125 100644 --- a/ct/prometheus-v3.sh +++ b/ct/prometheus-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="Prometheus" var_disk="4" var_cpu="1" @@ -47,6 +48,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh index 107dfe7d..201b6267 100644 --- a/ct/technitiumdns-v3.sh +++ b/ct/technitiumdns-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh index 586f4f82..5f5b38b1 100644 --- a/ct/ubuntu-v3.sh +++ b/ct/ubuntu-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh index 40d5a222..158758b1 100644 --- a/ct/unifi-v3.sh +++ b/ct/unifi-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh index fc5eb477..d9cb376b 100644 --- a/ct/uptimekuma-v3.sh +++ b/ct/uptimekuma-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh index 38a23d01..735160ff 100644 --- a/ct/vaultwarden-v3.sh +++ b/ct/vaultwarden-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/whoogle-v3.sh b/ct/whoogle-v3.sh index c0529fb3..59274f4e 100644 --- a/ct/whoogle-v3.sh +++ b/ct/whoogle-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." APP="Whoogle" var_disk="2" var_cpu="1" @@ -48,6 +49,7 @@ function msg_ok() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh index b0bf0bac..284f665c 100644 --- a/ct/wireguard-v3.sh +++ b/ct/wireguard-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -31,6 +32,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh index 3a48dd9c..46a61c82 100644 --- a/ct/zigbee2mqtt-v3.sh +++ b/ct/zigbee2mqtt-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -32,6 +33,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh index 99afdd8d..88b9c87c 100644 --- a/ct/zwavejs2mqtt-v3.sh +++ b/ct/zwavejs2mqtt-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +echo -e "Loading..." NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=`echo "\033[33m"` @@ -32,6 +33,7 @@ function error_exit() { } while true; do + clear read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 83652ed4..1153be37 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash +echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.2" +STABLE="8.1" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -50,6 +51,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null while true; do + clear read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; From 2cd95851e5c32cae709a77cbd1832623e36542cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 18:01:51 -0400 Subject: [PATCH 3223/6505] Create grocy-install.sh --- setup/grocy-install.sh | 117 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 setup/grocy-install.sh diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh new file mode 100644 index 00000000..1e5890d9 --- /dev/null +++ b/setup/grocy-install.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y apache2 &>/dev/null +apt-get install -y unzip &>/dev/null +apt-get install -y php &>/dev/null +apt-get install -y libapache2-mod-php &>/dev/null +apt-get install -y php-sqlite3 &>/dev/null +apt-get install -y php-gd &>/dev/null +apt-get install -y php-intl &>/dev/null +apt-get install -y php-mbstring &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing grocy" +wget https://releases.grocy.info/latest &>/dev/null +unzip latest -d /var/www/html &>/dev/null +chown -R www-data:www-data /var/www/html +cp /var/www/html/config-dist.php /var/www/html/data/config.php +chmod +x /var/www/html/update.sh + +cat < /etc/apache2/sites-available/grocy.conf + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html/public + +EOF + +sed -i '//,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf +a2dissite 000-default.conf &>/dev/null +a2ensite grocy.conf &>/dev/null +a2enmod rewrite &>/dev/null +systemctl reload apache2 +msg_ok "Installed grocy" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/latest +msg_ok "Cleaned" From 6ba7d6709adbbd3cb85a48668cf7cdbb5b7857fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 18:04:06 -0400 Subject: [PATCH 3224/6505] Create grocy-v3.sh --- ct/grocy-v3.sh | 359 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 ct/grocy-v3.sh diff --git a/ct/grocy-v3.sh b/ct/grocy-v3.sh new file mode 100644 index 00000000..38f6b555 --- /dev/null +++ b/ct/grocy-v3.sh @@ -0,0 +1,359 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="grocy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +while true; do + clear + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${YW} + __ _ _ __ ___ ___ _ _ + / _ | __/ _ \ / __| | | | + | (_| | | | (_) | (__| |_| | + \__, |_| \___/ \___|\__, | + __/ | v3 __/ | + |___/ |___/ +${CL}" +} + +header_info + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From ea3e3da4243ad28a8ccb143efe38d8226346d8c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 18:35:32 -0400 Subject: [PATCH 3225/6505] Update README.md --- README.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c8882b35..0518e291 100644 --- a/README.md +++ b/README.md @@ -1592,6 +1592,46 @@ ________________________________________________________________________________
    +
    + 🔸grocy LXC + +

    + +

    grocy LXC

    + +[grocy](https://grocy.info/) is a web-based self-hosted groceries & household management solution for your home. + +To create a new Proxmox grocy LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v3.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**grocy Interface: http:// IP** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` + +⚙️ **To Update grocy** + +Run in the LXC console + ```yaml +bash /var/www/html/update.sh +``` +____________________________________________________________________________________________ + +
    +
    Daemon Sync Server LXC @@ -1645,7 +1685,6 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye-v3 ``` - ⚙️ **To Update MotionEye** Run in the LXC console @@ -1793,6 +1832,7 @@ apt update && apt upgrade -y ____________________________________________________________________________________________
    +
    Tailscale From 178a2a52a759e47c478001af8bb995a2a005071d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 18:36:36 -0400 Subject: [PATCH 3226/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1783da1d..7c407340 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-21 + +### Changed + +- **grocy LXC** + - NEW Script + ## 2022-07-17 ### Changed From 481af56d723420508e98328beb09f15ed147593d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 18:54:13 -0400 Subject: [PATCH 3227/6505] Update grocy-install.sh --- setup/grocy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 1e5890d9..e12d9cc1 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -78,7 +78,7 @@ unzip latest -d /var/www/html &>/dev/null chown -R www-data:www-data /var/www/html cp /var/www/html/config-dist.php /var/www/html/data/config.php chmod +x /var/www/html/update.sh - +mkdir /var/log/apache2/ cat < /etc/apache2/sites-available/grocy.conf ServerAdmin webmaster@localhost From 2fa3057c18f14da0f8fbf1b5d7edadbdac2e0340 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 19:02:20 -0400 Subject: [PATCH 3228/6505] Update grocy-install.sh --- setup/grocy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index e12d9cc1..1e5890d9 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -78,7 +78,7 @@ unzip latest -d /var/www/html &>/dev/null chown -R www-data:www-data /var/www/html cp /var/www/html/config-dist.php /var/www/html/data/config.php chmod +x /var/www/html/update.sh -mkdir /var/log/apache2/ + cat < /etc/apache2/sites-available/grocy.conf ServerAdmin webmaster@localhost From 24973788d84f2fecbbd4399e634794170099bf26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 19:03:23 -0400 Subject: [PATCH 3229/6505] Update grocy-install.sh --- setup/grocy-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 1e5890d9..7801c8e2 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -83,6 +83,7 @@ cat < /etc/apache2/sites-available/grocy.conf ServerAdmin webmaster@localhost DocumentRoot /var/www/html/public + ErrorLog /var/log/apache2/error.log EOF From d49eb76efa612765b533e237fcdb43e6fe910daf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 19:12:48 -0400 Subject: [PATCH 3230/6505] Update grocy-install.sh --- setup/grocy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 7801c8e2..0dc26dff 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -114,5 +114,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/latest +rm -rf /root/latest msg_ok "Cleaned" From 35536242bdc745bda6994267a873de390cbc2151 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 19:49:02 -0400 Subject: [PATCH 3231/6505] Update README.md --- README.md | 80 +++++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 0518e291..652c75d8 100644 --- a/README.md +++ b/README.md @@ -1513,6 +1513,46 @@ ________________________________________________________________________________
    +
    + 🔸grocy LXC + +

    + +

    grocy LXC

    + +[grocy](https://grocy.info/) is a web-based self-hosted groceries & household management solution for your home. + +To create a new Proxmox grocy LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v3.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**grocy Interface: http:// IP** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` + +⚙️ **To Update grocy** + +Run in the LXC console + ```yaml +bash /var/www/html/update.sh +``` +____________________________________________________________________________________________ + +
    +
    MagicMirror Server LXC @@ -1592,46 +1632,6 @@ ________________________________________________________________________________
    -
    - 🔸grocy LXC - -

    - -

    grocy LXC

    - -[grocy](https://grocy.info/) is a web-based self-hosted groceries & household management solution for your home. - -To create a new Proxmox grocy LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v3.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**grocy Interface: http:// IP** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` - -⚙️ **To Update grocy** - -Run in the LXC console - ```yaml -bash /var/www/html/update.sh -``` -____________________________________________________________________________________________ - -
    -
    Daemon Sync Server LXC From 5569dfd040c7a88afc776c9f7c3448ca9d9e0310 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 21:40:40 -0400 Subject: [PATCH 3232/6505] Update grocy-install.sh --- setup/grocy-install.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 0dc26dff..b9f62174 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -84,10 +84,15 @@ cat < /etc/apache2/sites-available/grocy.conf ServerAdmin webmaster@localhost DocumentRoot /var/www/html/public ErrorLog /var/log/apache2/error.log + + Options Indexes FollowSymLinks MultiViews + AllowOverride All + Order allow,deny + allow from all + EOF -sed -i '//,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf a2dissite 000-default.conf &>/dev/null a2ensite grocy.conf &>/dev/null a2enmod rewrite &>/dev/null @@ -114,5 +119,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /root/latest +rm -rf /var/cache/* /var/lib/apt/lists/* /root/latest msg_ok "Cleaned" From 56b433b3663ee2ee94da3baa394acaf5e233b22a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 22:01:22 -0400 Subject: [PATCH 3233/6505] Update grocy-install.sh --- setup/grocy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index b9f62174..cffdefa3 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -119,5 +119,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/cache/* /var/lib/apt/lists/* /root/latest +rm -rf /var/cache/* /var/lib/apt/lists/* /var/log/!(apache2) /root/latest msg_ok "Cleaned" From eef478d0555901fbd3887b793778c695ae2bf114 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Jul 2022 22:14:24 -0400 Subject: [PATCH 3234/6505] Update grocy-install.sh --- setup/grocy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index cffdefa3..de7bc523 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -119,5 +119,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/cache/* /var/lib/apt/lists/* /var/log/!(apache2) /root/latest +rm -rf /var/cache/* /root/latest msg_ok "Cleaned" From 7d7c5d62aeca71576d1a64a367470c2468405130 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Jul 2022 12:38:04 -0400 Subject: [PATCH 3235/6505] Create n8n-v3.sh --- ct/n8n-v3.sh | 356 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 ct/n8n-v3.sh diff --git a/ct/n8n-v3.sh b/ct/n8n-v3.sh new file mode 100644 index 00000000..1347f25c --- /dev/null +++ b/ct/n8n-v3.sh @@ -0,0 +1,356 @@ +#!/usr/bin/env bash +echo -e "Loading..." +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="n8n" +NSAPP=$(echo ${APP,,} | tr -d ' ') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +while true; do + clear + read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${RD} + ___ + / _ \ + _ __ | (_) |_v3_ + | _ \ > _ <| _ \ + | | | | (_) | | | | + |_| |_|\___/|_| |_| +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" + PW=" " + echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size ${BGN}3${CL}${DGN}GB${CL}" + DISK_SIZE="3" + echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" + CORE_COUNT="2" + echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" + RAM_SIZE="2048" + echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" + GATE="" + echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" + VLAN="" +} + +function advanced_settings() { + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" + read CT_TYPE1 + if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; + echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" + else + CT_TYPE1="Privileged" + CT_TYPE="0" + echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " + read PW1 + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -en "${DGN}Set CT ${BL}$PW1${CL}" + else + PW="-password $PW1" + echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" + fi; +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " + read CT_ID + if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; + echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " + read CT_NAME + if [ -z $CT_NAME ]; then + HN=$NSAPP + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3 " + read DISK_SIZE + if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; + echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " + read CORE_COUNT + if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; + echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" +echo -e " ${CM}${CL} \r" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " + read RAM_SIZE + if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; + echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " + read BRG + if [ -z $BRG ]; then BRG="vmbr0"; fi; + echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " + read NET + if [ -z $NET ]; then NET="dhcp"; fi; + echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " + read GATE1 + if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " + read VLAN1 + if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" + fi; +echo -e " ${CM}${CL} \n" +sleep 1 +clear +header_info + echo -e "${RD}Using Advanced Settings${CL}" + echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" + echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" + echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" + echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" + echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" + echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" + echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" + echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" + echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" + echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" + echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" + +read -p "Are these settings correct(y/n)? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + advanced_settings +fi +} + +function start_script() { + echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + read SETTINGS + if [ -z $SETTINGS ]; then default_settings; + else + advanced_settings + fi; +} + +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=debian +export PCT_OSVERSION=11 +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/n8n-install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +pct set $CTID -description "# ${APP} LXC +### https://github.com/tteck/Proxmox" + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5678${CL} \n" From 3a6404f2d33c62f12b0c75de738825c9cef8e145 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Jul 2022 12:39:51 -0400 Subject: [PATCH 3236/6505] Create n8n-install.sh --- setup/n8n-install.sh | 116 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 setup/n8n-install.sh diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh new file mode 100644 index 00000000..09670422 --- /dev/null +++ b/setup/n8n-install.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +curl -sL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Installing n8n (Patience)" +npm install --global n8n &>/dev/null +msg_ok "Installed n8n" + +msg_info "Creating Service" +cat < /etc/systemd/system/n8n.service +[Unit] +Description=n8n + +[Service] +Type=simple +ExecStart=n8n start +[Install] +WantedBy=multi-user.target +EOF +sudo systemctl start n8n &>/dev/null +sudo systemctl enable n8n &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From d5090dc7071b11a7e328d1cd8a52d23ccd18451f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Jul 2022 12:47:55 -0400 Subject: [PATCH 3237/6505] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 652c75d8..868f2de5 100644 --- a/README.md +++ b/README.md @@ -583,6 +583,35 @@ ________________________________________________________________________________
    +
    + 🔸n8n LXC + +

    + +

    n8n LXC

    + +[n8n](https://n8n.io/) is a workflow automation platform that doesn't box you in, that you never outgrow + +To create a new Proxmox n8n LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/n8n-v3.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    + +**n8n Interface: IP:5678** + +⚙️ **To Update n8n** + +```yaml +npm update -g n8n +``` + +____________________________________________________________________________________________ + +
    +
    Mariadb LXC From 1bc6c0c4e9b4813fdebe1125e4108ddd7491ea31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Jul 2022 12:50:26 -0400 Subject: [PATCH 3238/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7c407340..e6005cd1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-22 + +### Changed + +- **n8n LXC** (thanks to @cyakimov) + - NEW Script + ## 2022-07-21 ### Changed From 193c4d799409884cc029362e276a02acdb1d0334 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Jul 2022 16:47:28 -0400 Subject: [PATCH 3239/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 868f2de5..c8bb5d36 100644 --- a/README.md +++ b/README.md @@ -590,7 +590,7 @@ ________________________________________________________________________________

    n8n LXC

    -[n8n](https://n8n.io/) is a workflow automation platform that doesn't box you in, that you never outgrow +[n8n](https://n8n.io/) is an extendable workflow automation tool which enables you to connect anything to everything. To create a new Proxmox n8n LXC, run the following in the Proxmox Shell. From b28f966c2c2782a4dae6e6cd4c2fe1805547eb47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Jul 2022 19:33:29 -0400 Subject: [PATCH 3240/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c8bb5d36..b0fdf495 100644 --- a/README.md +++ b/README.md @@ -586,7 +586,7 @@ ________________________________________________________________________________
    🔸n8n LXC -

    +

    n8n LXC

    From ebea0be21de42b9c8828368638e672d2e1f12694 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Jul 2022 08:42:45 -0400 Subject: [PATCH 3241/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0fdf495..469afdb3 100644 --- a/README.md +++ b/README.md @@ -1957,7 +1957,7 @@ ________________________________________________________________________________
    - 🔸Vaultwarden LXC + Vaultwarden LXC

    From ba2e96b7baa5f9be6096edf1e25539b0b3a91157 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Jul 2022 09:31:40 -0400 Subject: [PATCH 3242/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 105aad6d..7e666b1b 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -336,7 +336,7 @@ pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ - -scsi0 ${DISK1_REF},size=32G >/dev/null + -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS From f6bfbf03fa22944298024f8fcdc862467937dc03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Jul 2022 09:57:25 -0400 Subject: [PATCH 3243/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e6005cd1..dbc9ee06 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,15 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-24 + +### Changed + +- **Home Assistant OS VM** + - Present the drive to the guest as a solid-state drive rather than a rotational hard disk. There is no requirement that the underlying storage actually be backed by SSD's. + - When the VM’s filesystem marks blocks as unused after deleting files, the SCSI controller will relay this information to the storage, which will then shrink the disk image accordingly. + + ## 2022-07-22 ### Changed From e89b63b06c40db0ccd42ed37c49b2378357616cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Jul 2022 09:57:56 -0400 Subject: [PATCH 3244/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 469afdb3..6a4d031b 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ ________________________________________________________________________________
    - Home Assistant OS VM + 🔸Home Assistant OS VM

    From 76837433f98fbf8d3fd01f76e5f63a9b1fe2c01b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Jul 2022 21:35:21 -0400 Subject: [PATCH 3245/6505] Update magicmirror-install.sh --- setup/magicmirror-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index 3513f225..880f959a 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -66,7 +66,7 @@ apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 5c6c92136753ed607826744a44e2e04cf10c9db7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Jul 2022 18:10:50 -0400 Subject: [PATCH 3246/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index dbc9ee06..7874d87f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,9 +7,10 @@ All notable changes to this project will be documented in this file. ### Changed -- **Home Assistant OS VM** +- **Home Assistant OS VM** - Present the drive to the guest as a solid-state drive rather than a rotational hard disk. There is no requirement that the underlying storage actually be backed by SSD's. - When the VM’s filesystem marks blocks as unused after deleting files, the SCSI controller will relay this information to the storage, which will then shrink the disk image accordingly. + - 👉 [more info](https://github.com/tteck/Proxmox/discussions/378) ## 2022-07-22 From 1738b956be749f042f86990d1e60ebce7e98aebd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Jul 2022 17:08:44 -0400 Subject: [PATCH 3247/6505] Update haos-vm-v3.sh --- vm/haos-vm-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 7e666b1b..6e92ae82 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -330,7 +330,7 @@ done msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null From 687b0ba2946755d97393624e04cc93a7d9452bd8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Jul 2022 17:31:03 -0400 Subject: [PATCH 3248/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7874d87f..6956b22e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,14 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-07-26 + +### Changed + +- **Home Assistant OS VM** + - Set the real time clock (RTC) to local time. + - Disable the USB tablet device (save resources / not needed). + ## 2022-07-24 ### Changed @@ -12,7 +20,6 @@ All notable changes to this project will be documented in this file. - When the VM’s filesystem marks blocks as unused after deleting files, the SCSI controller will relay this information to the storage, which will then shrink the disk image accordingly. - 👉 [more info](https://github.com/tteck/Proxmox/discussions/378) - ## 2022-07-22 ### Changed From fa8ff8d2171ae5ed0220c350cd4a28d1260fd469 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Jul 2022 01:47:51 -0400 Subject: [PATCH 3249/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a4d031b..5b6ee203 100644 --- a/README.md +++ b/README.md @@ -1543,7 +1543,7 @@ ________________________________________________________________________________
    - 🔸grocy LXC + grocy LXC

    From 3fb7dbd51cd5e97e84c2a3f0a904b48062d6be23 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Jul 2022 06:27:53 -0400 Subject: [PATCH 3250/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b6ee203..12ce908e 100644 --- a/README.md +++ b/README.md @@ -584,7 +584,7 @@ ________________________________________________________________________________
    - 🔸n8n LXC + n8n LXC

    From 3f84f9b2878833e06127e94281a6032e07bb0d87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Jul 2022 11:03:45 -0400 Subject: [PATCH 3251/6505] Update post-install-v3.sh --- misc/post-install-v3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-install-v3.sh b/misc/post-install-v3.sh index effa399d..747c2128 100644 --- a/misc/post-install-v3.sh +++ b/misc/post-install-v3.sh @@ -110,7 +110,7 @@ then msg_info "Updating Proxmox VE 7" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null -msg_ok "Updated Proxmox VE 7" +msg_ok "Updated Proxmox VE 7 (Reboot Recommended)" fi sleep 2 From abee6b784af62d8e9fd39b10e82bf8a9fa435a84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Jul 2022 17:51:48 -0400 Subject: [PATCH 3252/6505] test --- vm/haos_vm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 1153be37..42f3dd29 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -3,7 +3,7 @@ echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.1" +STABLE="8.2" YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -332,10 +332,10 @@ msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ + -efidisk0 ${DISK0_REF},size=128k \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From ab4ab4d8c5e04081e9d1d9a438559ebb0af06ac2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Jul 2022 18:04:22 -0400 Subject: [PATCH 3253/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 42f3dd29..dc81e84d 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -335,7 +335,7 @@ qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $ pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},size=128k \ + -efidisk0 ${DISK0_REF},size=128K \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From a4d6fee95fc169e43d36c2afc1f808abb517dd60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Jul 2022 22:08:13 -0400 Subject: [PATCH 3254/6505] add PVE check --- vm/haos-vm-v3.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh index 6e92ae82..4dbb9499 100644 --- a/vm/haos-vm-v3.sh +++ b/vm/haos-vm-v3.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash echo -e "Loading..." +PVE=$(pveversion | grep "pve-manager/7" | wc -l) GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') @@ -49,6 +50,13 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null + +if [[ "$PVE" != "1" ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi while true; do clear From fe47b3d90f6fa9cc77e5318f3d58e8b9f59d1f2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Jul 2022 00:54:02 -0400 Subject: [PATCH 3255/6505] Update haos_vm.sh works with PVE6 --- vm/haos_vm.sh | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index dc81e84d..89ec3614 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash echo -e "Loading..." +PVE=$(pveversion | grep "pve-manager/7" | wc -l) GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.2" +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -49,6 +50,12 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null + +if [[ "$PVE" == "1" ]]; then + echo -e "${YW}This script is for Proxmox Virtual Environment 6${CL}" + echo -e "Continuing..." + sleep 5 +fi while true; do clear @@ -260,7 +267,7 @@ fi } function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " + echo -e "${YW}Type Advanced (Latest ${RELEASE}), or Press [ENTER] for Default Settings (Stable ${STABLE}) " read SETTINGS if [ -z $SETTINGS ]; then default_settings; else @@ -312,15 +319,6 @@ case $STORAGE_TYPE in DISK_EXT=".qcow2" DISK_REF="$VMID/" DISK_IMPORT="-format qcow2" - ;; - - btrfs) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_FORMAT="subvol" - DISK_IMPORT="-format raw" - ;; - esac for i in {0,1}; do disk="DISK$i" @@ -341,7 +339,6 @@ qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS ### https://github.com/tteck/Proxmox" >/dev/null - msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" if [ "$START_VM" == "yes" ]; then From 5429e11bf54d1d0ea8273c7236f9e4e2a434c687 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 16:22:50 -0400 Subject: [PATCH 3256/6505] Create ubuntu-v4.sh an early look at the v4 script --- ct/ubuntu-v4.sh | 311 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 ct/ubuntu-v4.sh diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh new file mode 100644 index 00000000..dec5b882 --- /dev/null +++ b/ct/ubuntu-v4.sh @@ -0,0 +1,311 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Ubuntu" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="ubuntu" +var_version="22.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + __ ____ __ + / / / / /_v4__ ______ / /___ __ + / / / / __ \/ / / / __ \/ __/ / / / +/ /_/ / /_/ / /_/ / / / / /_/ /_/ / +\____/_.___/\__,_/_/ /_/\__/\__,_/ +${CL}" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + #var_version="22.04" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function advanced_settings() { +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +"18.04" "18.04" OFF \ +"20.04" "20.04" OFF \ +"21.10" "21.10" OFF \ +"22.04" "22.04" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi + +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi + +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi + +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + echo "Going Back to Advanced Settings" + advanced_settings +fi +} + +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script + +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" + +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit + +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') + +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/" + +msg_ok "Completed Successfully!\n" From d0090a8cd0bb00fe7860d6a622615689d111dd8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 17:35:14 -0400 Subject: [PATCH 3257/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index d179b866..369631f4 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -35,14 +35,7 @@ function update_container() { clear header_info echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" - pct config $container > temp - os=`awk '/^ostype/' temp | cut -d' ' -f2` - if [ "$os" == "alpine" ] - then - pct exec $container -- ash -c "apk update && apk upgrade" - else - pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" - fi + pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" } read -p "Skip stopped containers? " -n 1 -r echo @@ -76,5 +69,4 @@ do fi done; wait -rm temp echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From 78fa9a70f74b8c2d94c3fd9f0c2aec835445270c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 20:13:34 -0400 Subject: [PATCH 3258/6505] Update ubuntu-v4.sh --- ct/ubuntu-v4.sh | 68 ++++++++----------------------------------------- 1 file changed, 10 insertions(+), 58 deletions(-) diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index dec5b882..4337d157 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -27,7 +27,6 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR - function error_exit() { trap - ERR local reason="Unknown failure occurred." @@ -36,7 +35,6 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then echo "User selected Yes" else @@ -53,28 +51,23 @@ echo -e "${YW} \____/_.___/\__,_/_/ /_/\__/\__,_/ ${CL}" } - function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } - function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } - function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi } - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" #var_version="22.04" @@ -104,23 +97,19 @@ function default_settings() { VLAN="" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } - function advanced_settings() { var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ -"18.04" "18.04" OFF \ -"20.04" "20.04" OFF \ -"21.10" "21.10" OFF \ -"22.04" "22.04" ON \ +"18.04" "Bionic" OFF \ +"20.04" "Focal" OFF \ +"21.10" "Impish" OFF \ +"22.04" "Jammy" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -129,11 +118,8 @@ exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -144,78 +130,56 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi - CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' ') echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" else - clear - echo -e "⚠ User exited script \n" exit fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -226,7 +190,6 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -237,7 +200,6 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -248,7 +210,6 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -257,7 +218,6 @@ else advanced_settings fi } - function start_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then header_info @@ -271,16 +231,13 @@ fi } clear start_script - if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else FEATURES="nesting=1" fi - TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version @@ -296,16 +253,11 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" - lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/" - msg_ok "Completed Successfully!\n" From 90cbdb05efb6ec8bbf59bea03254fed0e9943689 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 20:16:41 -0400 Subject: [PATCH 3259/6505] Create debian-v4.sh --- ct/debian-v4.sh | 261 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 ct/debian-v4.sh diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh new file mode 100644 index 00000000..7fe07b7b --- /dev/null +++ b/ct/debian-v4.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Debian" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + _____ _ _ + | __ \ | | (_) + | | | | ___| |__ _ __ _ _ __ + | | | |/ _ \ _ \| |/ _ | _ \ + | |__| | __/ |_) | | (_| | | | | + |_${YW}v4${RD}__/ \___|_.__/|_|\__,_|_| |_| +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + echo "Going Back to Advanced Settings" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" From e07ae08b0e18ab2017016075d8bf5ff399fb9841 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 20:17:26 -0400 Subject: [PATCH 3260/6505] Update ubuntu-v4.sh --- ct/ubuntu-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 4337d157..e7d0178d 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -70,7 +70,7 @@ fi } function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - #var_version="22.04" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" From 5b0f8710ee60eb3a95e1ab1e412f773955b8658e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 20:23:52 -0400 Subject: [PATCH 3261/6505] Create wireguard-v4.sh --- ct/wireguard-v4.sh | 264 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 ct/wireguard-v4.sh diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh new file mode 100644 index 00000000..fddf43bf --- /dev/null +++ b/ct/wireguard-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Wireguaed" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + __ ___ _____ _ + \ \ / (_) / ____| | | + \ \ /\ / / _ _ __ ___| | __ _ _ __ _ _ __ __| | + \ \/ \/ / | | __/ _ \ | |_ | | | |/ _ | __/ _ | + \ /\ / | | | | __/ |__| | |_| | (_| | | | (_| | + \/ \/ v4|_|_| \___|\_____|\__,_|\__,_|_| \__,_| + ${YW}With WGDashboard +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + echo "Going Back to Advanced Settings" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "WGDashboard should be reachable by going to the following URL. + ${BL}http://${IP}:10086${CL} \n" From 36c1dc455eb4e063611ef3324deac38d6ba357d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 21:30:19 -0400 Subject: [PATCH 3262/6505] Update debian-v4.sh --- ct/debian-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 7fe07b7b..5f99592f 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -128,7 +128,7 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" From e40781bb857be06e487f2cb26cd76b9abfba81f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 22:57:00 -0400 Subject: [PATCH 3263/6505] Create haos-vm-v4.sh --- vm/haos-vm-v4.sh | 292 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 vm/haos-vm-v4.sh diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh new file mode 100644 index 00000000..1fa3e5eb --- /dev/null +++ b/vm/haos-vm-v4.sh @@ -0,0 +1,292 @@ +#!/usr/bin/env bash +echo -e "Loading..." +PVE=$(pveversion | grep "pve-manager/7" | wc -l) +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +NEXTID=$(pvesh get /cluster/nextid) +RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} + +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +if [[ "$PVE" != "1" ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi + +if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + _ _ ____ _____ + | | | | /\ / __ \ / ____| + | |__| | / \ | | | | (___ + | __ | / /\ \| | | |\___ \ + | | | |/ ____ \ |__| |____) | + |_| |_/_/ ${CL}${YW}v4${CL}${BL} \_\____/|_____/ +${CL}" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function default_settings() { + echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" + VM_NAME=haos${STABLE} + echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}NONE${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" + START_VM="yes" + +} +function advanced_settings() { +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 2 \ +"$STABLE" "Stable" ON \ +"$RELEASE" "Latest" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" +else + exit +fi + +VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" +else + exit +fi + +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${STABLE} --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi + +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi + +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi + +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi + +MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + exit +fi + +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi + +if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Starting VM when completed${CL}" + START_VM="yes" +else + echo -e "${DGN}Do not start VM when completed${CL}" + START_VM="no" +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then + echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" +else + clear + echo "Going Back to Advanced Settings" + advanced_settings +fi +} + +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} + +start_script + +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + echo -e "'Disk image' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the HAOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" +msg_info "Extracting KVM Disk Image" +unxz $FILE +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; + + btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_FORMAT="subvol" + DISK_IMPORT="-format raw" + ;; + +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +msg_ok "Extracted KVM Disk Image" + +msg_info "Creating HAOS VM" +qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ + -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null +qm set $VMID \ + -boot order=scsi0 >/dev/null +qm set $VMID -description "# Home Assistant OS +### https://github.com/tteck/Proxmox" >/dev/null +msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" + +if [ "$START_VM" == "yes" ]; then +msg_info "Starting Home Assistant OS VM" +qm start $VMID +msg_ok "Started Home Assistant OS VM" +fi +msg_ok "Completed Successfully!\n" From 2b41ad24ea9be31e4f23521f131b9633926b5728 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 23:06:21 -0400 Subject: [PATCH 3264/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 1fa3e5eb..c2ff7a40 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -23,7 +23,6 @@ shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR trap cleanup EXIT - function error_exit() { trap - ERR local reason="Unknown failure occurred." @@ -33,7 +32,6 @@ function error_exit() { [ ! -z ${VMID-} ] && cleanup_vmid exit $EXIT } - function cleanup_vmid() { if $(qm status $VMID &>/dev/null); then if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then @@ -42,22 +40,18 @@ function cleanup_vmid() { qm destroy $VMID fi } - function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } - TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - if [[ "$PVE" != "1" ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit fi - if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then echo "User selected Yes" else @@ -75,12 +69,10 @@ echo -e "${BL} |_| |_/_/ ${CL}${YW}v4${CL}${BL} \_\____/|_____/ ${CL}" } - function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } - function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" @@ -91,7 +83,7 @@ function default_settings() { echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" VMID=$NEXTID echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" - VM_NAME=haos${STABLE} + HN=haos${STABLE} echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" CORE_COUNT="2" echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" @@ -104,7 +96,7 @@ function default_settings() { VLAN="" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" START_VM="yes" - + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 2 \ @@ -117,7 +109,6 @@ if [ $exitstatus = 0 ]; then else exit fi - VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -125,7 +116,6 @@ if [ $exitstatus = 0 ]; then else exit fi - VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${STABLE} --title "HOSTNAME" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -134,7 +124,6 @@ if [ $exitstatus = 0 ]; then else exit fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -142,7 +131,6 @@ if [ $exitstatus = 0 ]; then else exit fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -150,7 +138,6 @@ if [ $exitstatus = 0 ]; then else exit fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -158,7 +145,6 @@ if [ $exitstatus = 0 ]; then else exit fi - MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -167,7 +153,6 @@ if [ $exitstatus = 0 ]; then else exit fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -178,7 +163,6 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi - if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Starting VM when completed${CL}" START_VM="yes" @@ -194,7 +178,6 @@ else advanced_settings fi } - function start_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then clear @@ -208,9 +191,7 @@ else advanced_settings fi } - start_script - while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -254,14 +235,12 @@ case $STORAGE_TYPE in DISK_REF="$VMID/" DISK_IMPORT="-format qcow2" ;; - btrfs) DISK_EXT=".raw" DISK_REF="$VMID/" DISK_FORMAT="subvol" DISK_IMPORT="-format raw" ;; - esac for i in {0,1}; do disk="DISK$i" @@ -269,7 +248,6 @@ for i in {0,1}; do eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done msg_ok "Extracted KVM Disk Image" - msg_info "Creating HAOS VM" qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci @@ -283,7 +261,6 @@ qm set $VMID \ qm set $VMID -description "# Home Assistant OS ### https://github.com/tteck/Proxmox" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" - if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID From 40fdd09c47adc767c93c6ec23b8186b7f4575db8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 23:12:29 -0400 Subject: [PATCH 3265/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index c2ff7a40..693400e9 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -260,7 +260,7 @@ qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS ### https://github.com/tteck/Proxmox" >/dev/null -msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" +msg_ok "Created HAOS VM ${CL}${BL}${HN}" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID From f9a0540decea04913380ec0b3ee1c8dfbd087740 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Jul 2022 23:48:50 -0400 Subject: [PATCH 3266/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 693400e9..5739f28a 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -173,9 +173,10 @@ fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" else - clear - echo "Going Back to Advanced Settings" - advanced_settings + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings fi } function start_script() { @@ -260,7 +261,7 @@ qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS ### https://github.com/tteck/Proxmox" >/dev/null -msg_ok "Created HAOS VM ${CL}${BL}${HN}" +msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID From 1189beb7ae60bbb3774515e62c36d47adf3c8cbd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 05:46:27 -0400 Subject: [PATCH 3267/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 5739f28a..3b6641f1 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -3,7 +3,7 @@ echo -e "Loading..." PVE=$(pveversion | grep "pve-manager/7" | wc -l) GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) -RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` @@ -101,7 +101,7 @@ function default_settings() { function advanced_settings() { BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 2 \ "$STABLE" "Stable" ON \ -"$RELEASE" "Latest" OFF \ +"$LATEST" "Latest" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then From 271e8422b9ff6709b9059a1b89fbefbf844bf513 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 06:10:41 -0400 Subject: [PATCH 3268/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 3b6641f1..c2980aeb 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -7,6 +7,7 @@ LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-sys STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` +HA=`echo "\033[1;34m"` RD=`echo "\033[01;31m"` BGN=`echo "\033[4;92m"` GN=`echo "\033[1;92m"` @@ -60,13 +61,13 @@ else exit fi function header_info { -echo -e "${BL} - _ _ ____ _____ - | | | | /\ / __ \ / ____| - | |__| | / \ | | | | (___ - | __ | / /\ \| | | |\___ \ - | | | |/ ____ \ |__| |____) | - |_| |_/_/ ${CL}${YW}v4${CL}${BL} \_\____/|_____/ +echo -e "${HA} + __ _____ ____ _____ + / / / / | / __ \/ ___/ + / /_/ / /| |/ / / /\__ \ + / __ / ___ / /_/ /___/ / +/_/ /_/_/v4|_\____//____/ + Home Assistant OS ${CL}" } function msg_info() { From c357e1f7d011c262f3ffeccf7469614aa90044a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 07:21:35 -0400 Subject: [PATCH 3269/6505] Delete pimox-haos.sh --- vm/pimox-haos.sh | 343 ----------------------------------------------- 1 file changed, 343 deletions(-) delete mode 100644 vm/pimox-haos.sh diff --git a/vm/pimox-haos.sh b/vm/pimox-haos.sh deleted file mode 100644 index 38b009ae..00000000 --- a/vm/pimox-haos.sh +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env bash -GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') -NEXTID=$(pvesh get /cluster/nextid) -RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE="8.2" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} - -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} - -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -while true; do - read -p "This will create a New PiMox Home Assistant OS VM. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear - -function header_info { -echo -e "${YW} - - _____ _ _ _ ____ _____ - | __ (_) | | | | /\ / __ \ / ____| - | |__) | ______| |__| | / \ | | | | (___ - | ___/ |__v3__| __ | / /\ \| | | |\___ \ - | | | | | | | |/ ____ \ |__| |____) | - |_| |_| |_| |_/_/ \_\____/|_____/ -${CL}" -} -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using Version ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using VM Name ${BGN}pi-haos${STABLE}${CL}" - VM_NAME=pi-haos${STABLE} - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" - echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" - START_VM="yes" - -} -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Latest for Version ${RELEASE}, or Press [ENTER] for Stable Version ${STABLE} " - read BRANCH - if [ -z $BRANCH ]; then BRANCH=$STABLE; - else - BRANCH=$RELEASE; fi; - echo -en "${DGN}Set Version To ${BL}$BRANCH${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read VMID - if [ -z $VMID ]; then VMID=$NEXTID; fi; - echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: pi-haos${BRANCH} " - read VMNAME - if [ -z $VMNAME ]; then - VM_NAME=pi-haos${BRANCH} - else - VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$VM_NAME${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}${CORE_COUNT}${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Valid MAC Address, or Press [ENTER] for Generated MAC: $GEN_MAC " - read MAC - if [ -z $MAC ]; then MAC=$GEN_MAC; fi; - echo -en "${DGN}Set MAC Address To ${BL}$MAC${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " - read START_VM - if [ -z $START_VM ]; then START_VM="yes"; - else - START_VM="no"; fi; - echo -en "${DGN}Starting VM when completed ${BL}$START_VM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content images | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - echo -e "'Disk image' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the Pi-HAOS VM?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" -URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_generic-aarch64-${BRANCH}.img.xz -sleep 2 -msg_ok "${CL}${BL}${URL}${CL}" -wget -q --show-progress $URL -echo -en "\e[1A\e[0K" -FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}haos_generic-aarch64-${BRANCH}.img.xz${CL}" -msg_info "Extracting Disk Image" -unxz $FILE -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - btrfs|nfs|dir) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_IMPORT="-format raw" -esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done -msg_ok "Extracted Disk Image" - -msg_info "Creating Pi-HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ - -scsi0 ${DISK1_REF},size=32G >/dev/null -qm set $VMID \ - -boot order=scsi0 >/dev/null -#qm resize $VMID scsi0 +26G >/dev/null -qm set $VMID -description "# Home Assistant OS -### https://github.com/tteck/Proxmox" >/dev/null - -msg_ok "Created Pi-HAOS VM ${CL}${BL}${VM_NAME}" - -if [ "$START_VM" == "yes" ]; then -msg_info "Starting Home Assistant OS VM" -qm start $VMID -msg_ok "Started Home Assistant OS VM" -fi -msg_ok "Completed Successfully!\n" From e6b4af33ef663103852c9d81100d18fef0946901 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 07:27:26 -0400 Subject: [PATCH 3270/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index c2980aeb..59549df7 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -93,7 +93,7 @@ function default_settings() { BRG="vmbr0" echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}NONE${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" VLAN="" echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" START_VM="yes" From d7eafbed46084a73d09bf18da09c69e78f60b32e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 07:30:48 -0400 Subject: [PATCH 3271/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 59549df7..18ca623d 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -95,7 +95,7 @@ function default_settings() { MAC=$GEN_MAC echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } @@ -165,10 +165,10 @@ else fi fi if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then - echo -e "${DGN}Starting VM when completed${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" else - echo -e "${DGN}Do not start VM when completed${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then From a8f176742358c1cc6ac91f9a5e54d792b1565d67 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 07:37:55 -0400 Subject: [PATCH 3272/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12ce908e..13f6a5db 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ The script automates the manual process of finding, downloading and extracting t To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v4.sh)" ```

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    From 4df37263d69972dff95573e06e701f4237285d02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 07:40:14 -0400 Subject: [PATCH 3273/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6956b22e..1f55fa41 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-01 + +### Changed + +- **Home Assistant OS VM** + - v4 Script - Whiptail menus + ## 2022-07-26 ### Changed From a9999766b81b05ae5eb02dfd18fc9228302a3e34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 12:12:28 -0400 Subject: [PATCH 3274/6505] Update debian-v4.sh --- ct/debian-v4.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 5f99592f..fae80a9f 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -44,12 +44,11 @@ else fi function header_info { echo -e "${RD} - _____ _ _ - | __ \ | | (_) - | | | | ___| |__ _ __ _ _ __ - | | | |/ _ \ _ \| |/ _ | _ \ - | |__| | __/ |_) | | (_| | | | | - |_${YW}v4${RD}__/ \___|_.__/|_|\__,_|_| |_| + ____ __________ _______ _ __ + / __ \/ ____/ __ )/ _/ | / | / / + / / / / __/ / __ |/ // /| | / |/ / + / /_/ / /_v4/ /_/ // // ___ |/ /| / +/_____/_____/_____/___/_/ |_/_/ |_/ ${CL}" } function msg_info() { @@ -72,7 +71,7 @@ fi function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" From 2fd2aa151bd9a8fcc6137db18e569f984c937f6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 12:19:27 -0400 Subject: [PATCH 3275/6505] Update README.md --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 13f6a5db..6982c1b7 100644 --- a/README.md +++ b/README.md @@ -1127,21 +1127,22 @@ ________________________________________________________________________________
    - Debian 11 LXC + Debian LXC

    Debian

    -

    Debian 11 LXC

    +

    Debian LXC

    +

    Option to define version 10 or 11

    -To create a new Proxmox Debian 11 (curl. sudo) LXC, run the following in the Proxmox Shell. +To create a new Proxmox Debian (curl & sudo) LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -⚙️ **To Update Debian 11** +⚙️ **To Update Debian** Run in the LXC console ```yaml @@ -1161,10 +1162,10 @@ ________________________________________________________________________________

    Ubuntu LXC

    Option to define version 18.04, 20.04, 21.10 or 22.04

    -To create a new Proxmox Ubuntu (curl. sudo) LXC, run the following in the Proxmox Shell. +To create a new Proxmox Ubuntu (curl & sudo) LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04 ⚡

    From 4847f335c8dddbe3c5303fa093eb5c34b63e3586 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 12:20:47 -0400 Subject: [PATCH 3276/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6982c1b7..4cc27aef 100644 --- a/README.md +++ b/README.md @@ -1132,7 +1132,7 @@ ________________________________________________________________________________

    Debian

    Debian LXC

    -

    Option to define version 10 or 11

    +

    Option to select version 10 or 11

    To create a new Proxmox Debian (curl & sudo) LXC, run the following in the Proxmox Shell. @@ -1160,7 +1160,7 @@ ________________________________________________________________________________

    Ubuntu

    Ubuntu LXC

    -

    Option to define version 18.04, 20.04, 21.10 or 22.04

    +

    Option to select version 18.04, 20.04, 21.10 or 22.04

    To create a new Proxmox Ubuntu (curl & sudo) LXC, run the following in the Proxmox Shell. From 30d8ca1dcb90ff514669803e82bab5f37378a60d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 12:29:49 -0400 Subject: [PATCH 3277/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cc27aef..89f7b3e1 100644 --- a/README.md +++ b/README.md @@ -1823,7 +1823,7 @@ ________________________________________________________________________________ To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    From e00a57266cf1b4ed24dc37a10e44c2df85af7e4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 12:36:11 -0400 Subject: [PATCH 3278/6505] Update debian-v4.sh --- ct/debian-v4.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index fae80a9f..8e2cbcab 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -210,9 +210,10 @@ fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else - clear - echo "Going Back to Advanced Settings" - advanced_settings + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings fi } function start_script() { From e08d777900fd533906ac803902b0116978bdb7a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 12:36:49 -0400 Subject: [PATCH 3279/6505] Update ubuntu-v4.sh --- ct/ubuntu-v4.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index e7d0178d..fd4c3077 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -213,9 +213,10 @@ fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else - clear - echo "Going Back to Advanced Settings" - advanced_settings + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings fi } function start_script() { From bd0ab64b87366f764356ef341c82e2943e08bff6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 12:37:40 -0400 Subject: [PATCH 3280/6505] Update wireguard-v4.sh --- ct/wireguard-v4.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index fddf43bf..0574c2b3 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -212,9 +212,10 @@ fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else - clear - echo "Going Back to Advanced Settings" - advanced_settings + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings fi } function start_script() { From 156c1cf4fde2150ce118a082f9c54afdd945e846 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 14:05:33 -0400 Subject: [PATCH 3281/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 20fa12c9..a27e4973 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -129,6 +129,7 @@ msg_ok "Built PhotoPrism" env_path="/var/lib/photoprism/.env" echo " +PHOTOPRISM_AUTH_MODE='password' PHOTOPRISM_ADMIN_PASSWORD='admin' PHOTOPRISM_HTTP_HOST='0.0.0.0' PHOTOPRISM_HTTP_PORT=2342 From 1cd30fb5e9500501c5e8e5c323a87fd975895814 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 14:13:30 -0400 Subject: [PATCH 3282/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index a27e4973..dbbf1db5 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -130,7 +130,7 @@ msg_ok "Built PhotoPrism" env_path="/var/lib/photoprism/.env" echo " PHOTOPRISM_AUTH_MODE='password' -PHOTOPRISM_ADMIN_PASSWORD='admin' +PHOTOPRISM_ADMIN_PASSWORD='changeme' PHOTOPRISM_HTTP_HOST='0.0.0.0' PHOTOPRISM_HTTP_PORT=2342 PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' From 61c13b78d2aa1c401e555ef189d74e2729bdbc4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 14:14:28 -0400 Subject: [PATCH 3283/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89f7b3e1..56d1118e 100644 --- a/README.md +++ b/README.md @@ -1646,7 +1646,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v ``` **password** ```yaml - admin + changeme ``` [PhotoSync](https://www.photosync-app.com/home.html) From f9186adde51741b6c05a0059883d7ccc49027309 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 17:20:33 -0400 Subject: [PATCH 3284/6505] Create docker-v4.sh --- ct/docker-v4.sh | 266 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 ct/docker-v4.sh diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh new file mode 100644 index 00000000..50deaa4d --- /dev/null +++ b/ct/docker-v4.sh @@ -0,0 +1,266 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Docker" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + ____ __ + / __ \____ _____/ /_v4__ _____ + / / / / __ \/ ___/ //_/ _ \/ ___/ + / /_/ / /_/ / /__/ ,< / __/ / +/_____/\____/\___/_/|_|\___/_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" From 1b1f7c7b25290fd7e8d0a3dd3e9b3cb22c2ea03f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 17:22:30 -0400 Subject: [PATCH 3285/6505] Create zigbee2mqtt-v4.sh --- ct/zigbee2mqtt-v4.sh | 272 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 ct/zigbee2mqtt-v4.sh diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh new file mode 100644 index 00000000..25a20cab --- /dev/null +++ b/ct/zigbee2mqtt-v4.sh @@ -0,0 +1,272 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Zigbee2MQTT" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + _____ _ __ ___ __ _______ ____________ +/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ + / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / + / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / +/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ + /____/ 🐝 v4 +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" From 6aab893485aeda7d35e4c7d841f2bdf209512453 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 17:43:11 -0400 Subject: [PATCH 3286/6505] Create plex-v4.sh --- ct/plex-v4.sh | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 ct/plex-v4.sh diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh new file mode 100644 index 00000000..cde23da8 --- /dev/null +++ b/ct/plex-v4.sh @@ -0,0 +1,275 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Plex" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + ____ __ + / __ \/ /__ _ __ + / /_/ / / _ \| |/_/ + / ____/ / __/> < +/_/v4 /_/\___/_/|_| +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +"18.04" "Bionic" OFF \ +"20.04" "Focal" ON \ +"21.10" "Impish" OFF \ +"22.04" "Jammy" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:32400/web${CL}\n" From 6f2c9f6ab039e757a6c0941683b324f3cd96c872 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 17:47:47 -0400 Subject: [PATCH 3287/6505] Update omada-install.sh Update to v5.4.6 --- setup/omada-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 598dabde..ae50a452 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -70,8 +70,8 @@ sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller" -wget -qL https://static.tp-link.com/upload/software/2022/202205/20220507/Omada_SDN_Controller_v5.3.1_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.3.1_Linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202207/20220729/Omada_SDN_Controller_v5.4.6_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.4.6_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From bc7017726415a4f35d1735652c0ccb2e16c355e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Aug 2022 18:19:00 -0400 Subject: [PATCH 3288/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 56d1118e..ae63ae1b 100644 --- a/README.md +++ b/README.md @@ -816,7 +816,7 @@ ________________________________________________________________________________ To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -1106,7 +1106,7 @@ ________________________________________________________________________________ To create a new Proxmox Docker LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -1284,7 +1284,7 @@ ________________________________________________________________________________ To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    From d1e11e04b473850774f9d7e6eed1fecf53298b7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Aug 2022 04:30:37 -0400 Subject: [PATCH 3289/6505] Update wireguard-v4.sh --- ct/wireguard-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 0574c2b3..f63f5202 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash echo -e "Loading..." -APP="Wireguaed" +APP="Wireguard" var_disk="2" var_cpu="1" var_ram="512" From 83185e903d23181c7ebbaca37ee03f7913d9eb93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Aug 2022 08:34:00 -0400 Subject: [PATCH 3290/6505] V4 (#397) * Create adguard-v4.sh * Create homeassistant-v4.sh * Create daemonsync-v4.sh * Update wireguard-v4.sh * Create dashy-v4.sh * Create deconz-v4.sh * Create esphome-v4.sh * Create grafana-v4.sh * Create grocy-v4.sh * Create heimdalldashboard-v4.sh * Create homebridge-v4.sh * Create influxdb-v4.sh * Create iobroker-v4.sh * Create jellyfin-v4.sh * Create keycloak-v4.sh * Create magicmirror-v4.sh * Create mariadb-v4.sh * Create meshcentral-v4.sh * Create motioneye-v4.sh * Create mqtt-v4.sh * Create n8n-v4.sh * Create nginx-proxy-manager-v4.sh * Create nocodb-v4.sh * Create node-red-v4.sh * Create omada-v4.sh * Create openhab-v4.sh * Create pihole-v4.sh * Create podman-homeassistant-v4.sh * Create postgresql-v4.sh * Create prometheus-v4.sh * Create technitiumdns-v4.sh * Create unifi-v4.sh * Create uptimekuma-v4.sh * Create vaultwarden-v4.sh * Create whoogle-v4.sh * Create zwavejs2mqtt-v4.sh * Update README.md * Update node-red-v4.sh * Create photoprism-v4.sh * Update CHANGELOG.MD * Update README.md --- CHANGELOG.MD | 4 +- README.md | 74 ++++----- ct/adguard-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/daemonsync-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/dashy-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/deconz-v4.sh | 277 ++++++++++++++++++++++++++++++++++ ct/esphome-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/grafana-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/grocy-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/heimdalldashboard-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/homeassistant-v4.sh | 270 +++++++++++++++++++++++++++++++++ ct/homebridge-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/influxdb-v4.sh | 261 ++++++++++++++++++++++++++++++++ ct/iobroker-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/jellyfin-v4.sh | 275 +++++++++++++++++++++++++++++++++ ct/keycloak-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/magicmirror-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/mariadb-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/meshcentral-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/motioneye-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/mqtt-v4.sh | 261 ++++++++++++++++++++++++++++++++ ct/n8n-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/nginx-proxy-manager-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/nocodb-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/node-red-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/omada-v4.sh | 266 ++++++++++++++++++++++++++++++++ ct/openhab-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/photoprism-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/pihole-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/podman-homeassistant-v4.sh | 274 +++++++++++++++++++++++++++++++++ ct/postgresql-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/prometheus-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/technitiumdns-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/unifi-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/uptimekuma-v4.sh | 264 ++++++++++++++++++++++++++++++++ ct/vaultwarden-v4.sh | 267 ++++++++++++++++++++++++++++++++ ct/whoogle-v4.sh | 263 ++++++++++++++++++++++++++++++++ ct/zwavejs2mqtt-v4.sh | 275 +++++++++++++++++++++++++++++++++ 38 files changed, 9576 insertions(+), 39 deletions(-) create mode 100644 ct/adguard-v4.sh create mode 100644 ct/daemonsync-v4.sh create mode 100644 ct/dashy-v4.sh create mode 100644 ct/deconz-v4.sh create mode 100644 ct/esphome-v4.sh create mode 100644 ct/grafana-v4.sh create mode 100644 ct/grocy-v4.sh create mode 100644 ct/heimdalldashboard-v4.sh create mode 100644 ct/homeassistant-v4.sh create mode 100644 ct/homebridge-v4.sh create mode 100644 ct/influxdb-v4.sh create mode 100644 ct/iobroker-v4.sh create mode 100644 ct/jellyfin-v4.sh create mode 100644 ct/keycloak-v4.sh create mode 100644 ct/magicmirror-v4.sh create mode 100644 ct/mariadb-v4.sh create mode 100644 ct/meshcentral-v4.sh create mode 100644 ct/motioneye-v4.sh create mode 100644 ct/mqtt-v4.sh create mode 100644 ct/n8n-v4.sh create mode 100644 ct/nginx-proxy-manager-v4.sh create mode 100644 ct/nocodb-v4.sh create mode 100644 ct/node-red-v4.sh create mode 100644 ct/omada-v4.sh create mode 100644 ct/openhab-v4.sh create mode 100644 ct/photoprism-v4.sh create mode 100644 ct/pihole-v4.sh create mode 100644 ct/podman-homeassistant-v4.sh create mode 100644 ct/postgresql-v4.sh create mode 100644 ct/prometheus-v4.sh create mode 100644 ct/technitiumdns-v4.sh create mode 100644 ct/unifi-v4.sh create mode 100644 ct/uptimekuma-v4.sh create mode 100644 ct/vaultwarden-v4.sh create mode 100644 ct/whoogle-v4.sh create mode 100644 ct/zwavejs2mqtt-v4.sh diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1f55fa41..5531b83b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,11 +3,11 @@ # Change Log All notable changes to this project will be documented in this file. -## 2022-08-01 +## 2022-08-02 ### Changed -- **Home Assistant OS VM** +- **All LXC/VM** - v4 Script - Whiptail menus ## 2022-07-26 diff --git a/README.md b/README.md index ae63ae1b..51fbb20e 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant OS VM + Home Assistant OS VM

    @@ -160,7 +160,7 @@ A standalone container-based installation of Home Assistant Core To create a new Proxmox Home Assistant Container LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    @@ -230,7 +230,7 @@ A standalone container-based installation of Home Assistant Core To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    @@ -300,7 +300,7 @@ ________________________________________________________________________________ To create a new Proxmox ioBroker LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/iobroker-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/iobroker-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -329,7 +329,7 @@ ________________________________________________________________________________ To create a new Proxmox openHAB LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/openhab-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/openhab-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -358,7 +358,7 @@ ________________________________________________________________________________ To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -415,7 +415,7 @@ Update from the Homebridge UI To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -448,7 +448,7 @@ ________________________________________________________________________________ To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. ```yaml - bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager-v3.sh)" + bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

    @@ -499,7 +499,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -551,7 +551,7 @@ ________________________________________________________________________________ To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -595,7 +595,7 @@ ________________________________________________________________________________ To create a new Proxmox n8n LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/n8n-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/n8n-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    @@ -624,7 +624,7 @@ ________________________________________________________________________________ To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -741,7 +741,7 @@ ________________________________________________________________________________ To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -897,7 +897,7 @@ ________________________________________________________________________________ To create a new Proxmox deCONZ LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/deconz-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/deconz-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -926,7 +926,7 @@ ________________________________________________________________________________ To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwavejs2mqtt-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwavejs2mqtt-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    @@ -961,7 +961,7 @@ ________________________________________________________________________________ To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -991,7 +991,7 @@ ________________________________________________________________________________ To create a new Proxmox Prometheus LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/prometheus-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/prometheus-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 1vCPU ⚡

    @@ -1022,7 +1022,7 @@ ________________________________________________________________________________ To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1064,7 +1064,7 @@ ________________________________________________________________________________ To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1195,7 +1195,7 @@ An application designed to optimize UniFi home and business networks with ease. To create a new Proxmox UniFi Network Application LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1224,7 +1224,7 @@ Omada Controller is software which is used to manage the EAP To create a new Proxmox Omada Controller LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1258,7 +1258,7 @@ MeshCentral is a full computer management web site. With MeshCentral, you can ru To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1317,7 +1317,7 @@ ________________________________________________________________________________ To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1347,7 +1347,7 @@ ________________________________________________________________________________ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1379,7 +1379,7 @@ An open source authoritative as well as recursive DNS server To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1406,7 +1406,7 @@ ________________________________________________________________________________ To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1436,7 +1436,7 @@ Uptime Kuma is a self-hosted, open source, fancy uptime monitoring and alerting To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1465,7 +1465,7 @@ Get Google search results, but without any ads, javascript, AMP links, cookies, To create a new Proxmox Whoogle LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/whoogle-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/whoogle-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1494,7 +1494,7 @@ ________________________________________________________________________________ To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1524,7 +1524,7 @@ Dashy helps you organize your self-hosted services by making them accessible fro To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    @@ -1555,7 +1555,7 @@ ________________________________________________________________________________ To create a new Proxmox grocy LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    @@ -1595,7 +1595,7 @@ ________________________________________________________________________________ To create a new MagicMirror Server LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 3GB Storage - 1vCPU ⚡

    @@ -1631,7 +1631,7 @@ PhotoPrism® is an AI-powered app for browsing, organizing & sharing your photo To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1674,7 +1674,7 @@ Sync files from app to server, share photos & videos, back up your data and stay To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    @@ -1697,7 +1697,7 @@ ________________________________________________________________________________ To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    @@ -1923,7 +1923,7 @@ ________________________________________________________________________________ To create a new Proxmox Keycloak LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/keycloak-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/keycloak-v4.sh)" ``` [Keycloak](https://www.keycloak.org/) is an Open Source Identity and Access Management solution for modern Applications and Services. @@ -1969,7 +1969,7 @@ Alternative implementation of the Bitwarden server API written in Rust and compa To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden-v4.sh)" ``` ⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh new file mode 100644 index 00000000..ad961086 --- /dev/null +++ b/ct/adguard-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Adguard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${GN} + ___ __ __ + / | ____/ /___ ___ ______ __________/ / + / /| |/ __ / __ / / / / __ / ___/ __ / + / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / +/_/v4|_\__,_/\__, /\__,_/\__,_/_/ \__,_/ + /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh new file mode 100644 index 00000000..81a1548d --- /dev/null +++ b/ct/daemonsync-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Daemon Sync" +var_disk="8" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + ____ _____ + / __ \____ ____ ____ ___ ____ ____ / ___/__ ______ _____ + / / / / __ / _ \/ __ __ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/ + / /_/ / /_/ / __/ / / / / / /_/ / / / / ___/ / /_/ / / / / /__ +/_____/\__,_/\___/_/ /_/ /_/\____/_/ /_/ v4/____/\__, /_/ /_/\___/ + /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh new file mode 100644 index 00000000..903b605b --- /dev/null +++ b/ct/dashy-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Dashy" +var_disk="3" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + ____ __ + / __ \____ ______/ /_ __ __ + / / / / __ / ___/ __ \/ / / / + / /_/ / /_/ (__ ) / / / /_/ / +/_____/\__,_/____/_/ /_/\__, / + v4 /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh new file mode 100644 index 00000000..388083aa --- /dev/null +++ b/ct/deconz-v4.sh @@ -0,0 +1,277 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="deCONZ" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + __ __________ _ _______ + ____/ /v4 / ____/ __ \/ | / /__ / + / __ / _ \/ / / / / / |/ / / / +/ /_/ / __/ /___/ /_/ / /| / / /__ +\__,_/\___/\____/\____/_/ |_/ /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +"18.04" "Bionic" OFF \ +"20.04" "Focal" ON \ +"21.10" "Impish" OFF \ +"22.04" "Jammy" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL}\n" diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh new file mode 100644 index 00000000..be9d9c6f --- /dev/null +++ b/ct/esphome-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="ESPHome" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${CL} + ___________ ____ __ ______ __ _________ + / ____/ ___// __ \/ / / / __ \/ |/ / ____/ + / __/ \__ \/ /_/ / /_/ / / / / /|_/ / __/ + / /___ ___/ / ____/ __ / /_/ / / / / /_v4 +/_____//____/_/ /_/ /_/\____/_/ /_/_____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh new file mode 100644 index 00000000..0b6a008b --- /dev/null +++ b/ct/grafana-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Grafana" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + ______ ____ + / ____/________ _/ __/___ _____ ____ _ + / / __/ ___/ __ / /_/ __ / __ \/ __ / +/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / +\____/_/ v4\__,_/_/ \__,_/_/ /_/\__,_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh new file mode 100644 index 00000000..d07e87fc --- /dev/null +++ b/ct/grocy-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="grocy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + ____ __________ _______ __ + / __ / ___/ __ \/ ___/ / / / + / /_/ / / / /_/ / /__/ /_/ / + \__, /_/ \____/\___/\__, / +/____/ v4 /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh new file mode 100644 index 00000000..8ff8a16f --- /dev/null +++ b/ct/heimdalldashboard-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Heimdall Dashboard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + __ __ _ __ ____ ____ __ __ __ + / / / /__ (_)___ ___ ____/ /_v4 _/ / / / __ \____ ______/ /_ / /_ ____ ____ __________/ / + / /_/ / _ \/ / __ __ \/ __ / __ / / / / / / / __ / ___/ __ \/ __ \/ __ \/ __ / ___/ __ / + / __ / __/ / / / / / / /_/ / /_/ / / / / /_/ / /_/ (__ ) / / / /_/ / /_/ / /_/ / / / /_/ / +/_/ /_/\___/_/_/ /_/ /_/\__,_/\__,_/_/_/ /_____/\__,_/____/_/ /_/_.___/\____/\__,_/_/ \__,_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh new file mode 100644 index 00000000..9af2f420 --- /dev/null +++ b/ct/homeassistant-v4.sh @@ -0,0 +1,270 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Home Assistant" +var_disk="16" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + __ __ ___ _ __ __ + / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} +Portainer should be reachable by going to the following URL. + ${BL}http://${IP}:9000${CL}\n" diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh new file mode 100644 index 00000000..21a66736 --- /dev/null +++ b/ct/homebridge-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Homebridge" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + __ ______ __ _____________ ____ ________ ____________ + / / / / __ \/ |/ / ____/ __ )/ __ \/ _/ __ \/ ____/ ____/ + / /_/ / / / / /|_/ / __/ / __ / /_/ // // / / / / __/ __/ + / __ / /_/ / / / / /___/ /_/ / _, _// // /_/ / /_/ / /___ +/_/ /_/\____/_/v4/_/_____/_____/_/ |_/___/_____/\____/_____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh new file mode 100644 index 00000000..865c93cc --- /dev/null +++ b/ct/influxdb-v4.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="InfluxDB" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + ____ ______ ____ ____ + / _/_v4 / __/ /_ ___ __/ __ \/ __ ) + / // __ \/ /_/ / / / / |/_/ / / / __ | + _/ // / / / __/ / /_/ /> &1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh new file mode 100644 index 00000000..92e0fca5 --- /dev/null +++ b/ct/iobroker-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="ioBroker" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + _ ____ __ + (_)___ / __ )_________ / /_____ _____ + / / __ \/ __ / ___/ __ \/ //_/ _ \/ ___/ + / / /_/ / /_/ / / / /_/ / ,< / __/ / +/_/\____/_____/_/ v4\____/_/|_|\___/_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8081${CL} \n" diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh new file mode 100644 index 00000000..bf6c0d7f --- /dev/null +++ b/ct/jellyfin-v4.sh @@ -0,0 +1,275 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Jellyfin" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${DGN} + __________ ____ _____________ __ + / / ____/ / / /\ \/ / ____/ _/ | / / + __ / / __/ / / / / \ / /_ / // |/ / +/ /_/ / /___/ /___/ /_v4/ / __/ _/ // /| / +\____/_____/_____/_____/_/_/ /___/_/ |_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +"18.04" "Bionic" OFF \ +"20.04" "Focal" ON \ +"21.10" "Impish" OFF \ +"22.04" "Jammy" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh new file mode 100644 index 00000000..ac0c7f90 --- /dev/null +++ b/ct/keycloak-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Keycloak" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + __ __ __ __ + / //_/__ __ _______/ /___ ____ _/ /__ + / ,< / _ \/ / / / ___/ / __ \/ __ / //_/ + / /| / __/ /_/ / /__/ / /_/ / /_/ / ,< +/_/ |_\___/\__, /\___/_/\____/\__,_/_/|_| + v4 /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh new file mode 100644 index 00000000..ed2d9ca4 --- /dev/null +++ b/ct/magicmirror-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="MagicMirror" +var_disk="3" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + __ ___ _ __ ____ + / |/ /___ _____ _(_)____/ |/ (_)_____________ _____ + / /|_/ / __ / __ / / ___/ /|_/ / / ___/ ___/ __ \/ ___/ + / / / / /_/ / /_/ / / /__/ / / / / / / / / /_/ / / +/_/ /_/\__,_/\__, /_/\___/_/ /_/_/_/ /_/ \____/_/ + /____/ v4 +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh new file mode 100644 index 00000000..ceabd448 --- /dev/null +++ b/ct/mariadb-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="MariaDB" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + __ ___ _ ____ ____ + / |/ /___ ______(_)___ _/ __ \/ __ ) + / /|_/ / __ / ___/ / __ / / / / __ | + / / / / /_/ / / / / /_/ / /_/ / /_/ / +/_/ /_/\__,_/_/v4/_/\__,_/_____/_____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "Adminer should be reachable by going to the following URL. + ${BL}http://${IP}/adminer/${CL} \n" diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh new file mode 100644 index 00000000..38a28870 --- /dev/null +++ b/ct/meshcentral-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="MeshCentral" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + __ ___ __ ______ __ __ + / |/ /__ _____/ /_ / ____/__ ____ / /__________ _/ / + / /|_/ / _ \/ ___/ __ \/ / / _ \/ __ \/ __/ ___/ __ / / + / / / / __(__ ) / / / /___/ __/ / / / /_/ / / /_/ / / +/_/ /_/\___/____/_/ /_/\____/\___/_/ /_/\__/_/ v4\__,_/_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh new file mode 100644 index 00000000..eb3b3735 --- /dev/null +++ b/ct/motioneye-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Motioneye" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + __ ___ __ _ ________ ________ + / |/ /___ / /_(_)___ ____ / ____/\ \/ / ____/ + / /|_/ / __ \/ __/ / __ \/ __ \/ __/ \ / __/ + / / / / /_/ / /_/ / /_/ / / / / /___v4 / / /___ +/_/ /_/\____/\__/_/\____/_/ /_/_____/ /_/_____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh new file mode 100644 index 00000000..624297b3 --- /dev/null +++ b/ct/mqtt-v4.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="MQTT" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${GN} + __ _______ ____________ + / |/ / __ \/_ __/_ __/ + / /|_/ / / / / / / / / + / / / / /_/ / / / / / +/_/ /_/\___\_\/_/ v4/_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh new file mode 100644 index 00000000..3be8d9a8 --- /dev/null +++ b/ct/n8n-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="n8n" +var_disk="3" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + ___ + / _ \ + _ __ | (_) |_v4_ + | _ \ > _ <| _ \ + | | | | (_) | | | | + |_| |_|\___/|_| |_| +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:5678${CL} \n" diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh new file mode 100644 index 00000000..7e134842 --- /dev/null +++ b/ct/nginx-proxy-manager-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Nginx Proxy Manager" +var_disk="3" +var_cpu="1" +var_ram="1048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + _ __ _ ____ __ ___ + / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____ + / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ + / /| / /_/ / / / / /> < / ____/ / / /_/ /> &1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh new file mode 100644 index 00000000..8cd33a28 --- /dev/null +++ b/ct/nocodb-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="NocoDB" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + _ __ ____ ____ + / | / /___ ____v4___ / __ \/ __ ) + / |/ / __ \/ ___/ __ \/ / / / __ | + / /| / /_/ / /__/ /_/ / /_/ / /_/ / +/_/ |_/\____/\___/\____/_____/_____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8080/dashboard${CL} \n" diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh new file mode 100644 index 00000000..9d4ed931 --- /dev/null +++ b/ct/node-red-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Node-Red" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + _ __ __ ____ __ + / | / /___ ____/ /__ v4 / __ \___ ____/ / + / |/ / __ \/ __ / _ \ / /_/ / _ \/ __ / + / /| / /_/ / /_/ / __/ / _, _/ __/ /_/ / +/_/ |_/\____/\__,_/\___/ /_/ |_|\___/\__,_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh new file mode 100644 index 00000000..9c121060 --- /dev/null +++ b/ct/omada-v4.sh @@ -0,0 +1,266 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Omada" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + ____ __ + / __ \____ ___v4____ _____/ /___ _ + / / / / __ __ \/ __ / __ / __ / +/ /_/ / / / / / / /_/ / /_/ / /_/ / +\____/_/ /_/ /_/\__,_/\__,_/\__,_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +"18.04" "Bionic" OFF \ +"20.04" "Focal" ON \ +"21.10" "Impish" OFF \ +"22.04" "Jammy" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:8043${CL} \n" diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh new file mode 100644 index 00000000..d3301be6 --- /dev/null +++ b/ct/openhab-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="openHAB" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${YW} + __ _____ ____ + ____v4____ ___ ____ / / / / | / __ ) + / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __ | +/ /_/ / /_/ / __/ / / / __ / ___ |/ /_/ / +\____/ .___/\___/_/ /_/_/ /_/_/ |_/_____/ + /_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh new file mode 100644 index 00000000..c8e2dc43 --- /dev/null +++ b/ct/photoprism-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="PhotoPrism" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + ____ __ ______ __________ ____ ____ _________ __ ___ + / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / + / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / + / ____/ __ / /_/ / / / / /_/ / ____/ _, _// / v4_/ / / / / +/_/ /_/ /_/\____/ /_/ \____/_/ /_/ |_/___//____/_/ /_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh new file mode 100644 index 00000000..ed11c16e --- /dev/null +++ b/ct/pihole-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Pihole" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + ____ ____ __ ______ __ ______ + / __ \/ _/ / / / / __ \/ / / ____/ + / /_/ // /___/ /_/ / / / / / / __/ + / ____// /___/ __ / /_/ / /v4_/ /___ +/_/ /___/ /_/ /_/\____/_____/_____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}/admin${CL} \n" diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh new file mode 100644 index 00000000..79f851a6 --- /dev/null +++ b/ct/podman-homeassistant-v4.sh @@ -0,0 +1,274 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Podman-Home Assistant" +var_disk="16" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + ____ __ + / __ \____ ____/ /___ ___ ____ _____ + v4 / /_/ / __ \/ __ / __ __ \/ __ / __ \ + / ____/ /_/ / /_/ / / / / / / /_/ / / / / + __ __ /_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/__ __ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} +Yacht should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL}\n" diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh new file mode 100644 index 00000000..33f06931 --- /dev/null +++ b/ct/postgresql-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="PostgreSQL" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + ____ __ _____ ____ __ + / __ \____ _____/ /_____ _________ / ___// __ \ / / + / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / + / ____/ /_/ (__ ) /_/ /_/ / / / __/__/ / /_/ / / /___ +/_/ \____/____/\__/\__, /_/v4 \___/____/\___\_\/_____/ + /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "Adminer should be reachable by going to the following URL. + ${BL}http://${IP}/adminer/${CL} \n" diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh new file mode 100644 index 00000000..6f172c69 --- /dev/null +++ b/ct/prometheus-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Prometheus" +var_disk="4" +var_cpu="1" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + ____ __ __ + / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ + / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ + / ____/ / / /_/ / / / / / / __/ /_/ / / / __/ /_/ (__ ) +/_/ v4/_/ \____/_/ /_/ /_/\___/\__/_/ /_/\___/\__,_/____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:9090${CL} \n" diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh new file mode 100644 index 00000000..a0cf9276 --- /dev/null +++ b/ct/technitiumdns-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Technitium DNS" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + ______ __ _ __ _ ____ _ _______ + /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ v4 / __ \/ | / / ___/ + / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ + / / / __/ /__/ / / / / / / / /_/ / /_/ / / / / / / / /_/ / /| /___/ / +/_/ \___/\___/_/ /_/_/ /_/_/\__/_/\__,_/_/ /_/ /_/ /_____/_/ |_//____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh new file mode 100644 index 00000000..f7cea5c7 --- /dev/null +++ b/ct/unifi-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Unifi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + __ __ _ _____ + / / / /_v4 (_) __(_) + / / / / __ \/ / /_/ / +/ /_/ / / / / / __/ / +\____/_/ /_/_/_/ /_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP}${CL} should be reachable by going to the following URL. + ${BL}https://${IP}:8443${CL} \n" diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh new file mode 100644 index 00000000..c545e1c6 --- /dev/null +++ b/ct/uptimekuma-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Uptime Kuma" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${DGN} + __ __ __ _ __ __ + / / / /___ / /_(_)___ ___ ___ v4 / //_/_ ______ ___ ____ _ + / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / +/ /_/ / /_/ / /_/ / / / / / / __/ / /| / /_/ / / / / / / /_/ / +\____/ .___/\__/_/_/ /_/ /_/\___/ /_/ |_\__,_/_/ /_/ /_/\__,_/ + /_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3001${CL} \n" diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh new file mode 100644 index 00000000..7f6799bc --- /dev/null +++ b/ct/vaultwarden-v4.sh @@ -0,0 +1,267 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Vaultwarden" +var_disk="6" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${CL} + _ _____ __ ____ _______ _____ ____ ____ _______ __ +| | / / | / / / / / /_ __/ | / / | / __ \/ __ \/ ____/ | / / +| | / / /| |/ / / / / / / | | /| / / /| | / /_/ / / / / __/ / |/ / +| |/ / ___ / /_/ / /___/ / | |/ |/ / ___ |/ _, _/ /_/ / /___/ /| / +|___/_/ |_\____/_____/_/ v4 |__/|__/_/ |_/_/ |_/_____/_____/_/ |_/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 512 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" +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/whoogle-v4.sh b/ct/whoogle-v4.sh new file mode 100644 index 00000000..d2c463cd --- /dev/null +++ b/ct/whoogle-v4.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Whoogle" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${GN} + _ ____ ______ ____ ________ ______ +| | v4 / / / / / __ \/ __ \/ ____/ / / ____/ +| | /| / / /_/ / / / / / / / / __/ / / __/ +| |/ |/ / __ / /_/ / /_/ / /_/ / /___/ /___ +|__/|__/_/ /_/\____/\____/\____/_____/_____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/zwavejs2mqtt-v4.sh b/ct/zwavejs2mqtt-v4.sh new file mode 100644 index 00000000..5e52fc2b --- /dev/null +++ b/ct/zwavejs2mqtt-v4.sh @@ -0,0 +1,275 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Zwavejs2MQTT" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + _____ _ ___ __ _______ ____________ +/__ /_ ______ __ _____ (_)___|__ \ / |/ / __ \/_ __/_ __/ + / /| | /| / / __ / | / / _ \ / / ___/_/ // /|_/ / / / / / / / / + / /_| |/ |/ / /_/ /| |/ / __/ / (__ ) __// / / / /_/ / / / / / +/____/__/|__/\__,_/ |___/\___/_/ /____/____/_/ /_/\___\_\/_/ v4/_/ + /___/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8091${CL} \n" From ce9129475d35b90efa9dba28ab20a8b58807474c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Aug 2022 09:17:18 -0400 Subject: [PATCH 3291/6505] Update omada-install.sh --- setup/omada-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index ae50a452..c52bc085 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -69,7 +69,7 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing Omada Controller" +msg_info "Installing Omada Controller v5.4.6" wget -qL https://static.tp-link.com/upload/software/2022/202207/20220729/Omada_SDN_Controller_v5.4.6_Linux_x64.deb sudo dpkg -i Omada_SDN_Controller_v5.4.6_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" From afd7f1affc3d2133523a7c8d74291e311d14bd44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Aug 2022 11:36:33 -0400 Subject: [PATCH 3292/6505] Update README.md --- README.md | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/README.md b/README.md index 51fbb20e..10979c58 100644 --- a/README.md +++ b/README.md @@ -1614,50 +1614,6 @@ cd /opt/magicmirror && git pull && npm install --only=prod --omit=dev ``` -____________________________________________________________________________________________ - -
    - - -
    - PhotoPrism LXC - -

    - -

    PhotoPrism LXC

    - -PhotoPrism® is an AI-powered app for browsing, organizing & sharing your photo collection. - -To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**PhotoPrism Interface - IP:2342** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - changeme - ``` -[PhotoSync](https://www.photosync-app.com/home.html) - -⚙️ **To Update PhotoPrism** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/photoprism-update.sh)" -``` - - ____________________________________________________________________________________________
    From 05f7d144920c3a30d1102805aa3b15fe58ead75f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Aug 2022 21:04:31 -0400 Subject: [PATCH 3293/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 5531b83b..74eb4deb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **All LXC/VM** - - v4 Script - Whiptail menus + - v4 Script - Whiptail menu's ## 2022-07-26 From d0a56ffc44e69bbcdccb8d6ebf2a9033b71253e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Aug 2022 15:51:03 -0400 Subject: [PATCH 3294/6505] Update nginx-proxy-manager-v4.sh --- ct/nginx-proxy-manager-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 7e134842..ae4e9b7e 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -255,7 +255,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nginx-proxy-manager-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" From c24dec5b011a8f616b78fc739a312bef44643320 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 06:24:49 -0400 Subject: [PATCH 3295/6505] Update filebrowser-v3.sh don't show Docker IP --- misc/filebrowser-v3.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/filebrowser-v3.sh b/misc/filebrowser-v3.sh index 78cf8ab2..e5cdfcf8 100644 --- a/misc/filebrowser-v3.sh +++ b/misc/filebrowser-v3.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +IP=$(hostname -I | awk '{print $1}') YW=`echo "\033[33m"` BL=`echo "\033[36m"` RD=`echo "\033[01;31m"` @@ -86,4 +87,4 @@ msg_ok "Created Service" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://$(hostname -I):8080${CL} \n" + ${BL}http://$IP:8080${CL} \n" From 4542b2dd881fcda48330f1bcd3a8c65ac5640268 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 08:25:12 -0400 Subject: [PATCH 3296/6505] Update unifi-install.sh --- setup/unifi-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index f47cb3e3..fa9277e3 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -96,7 +96,7 @@ msg_ok "Customized Container" fi msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null +#apt-get autoremove >/dev/null +#apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" From d3ef2acb8c6fdff6aec5d532a41657b481bb7c4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 09:39:42 -0400 Subject: [PATCH 3297/6505] Update unifi-install.sh --- setup/unifi-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index fa9277e3..f47cb3e3 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -96,7 +96,7 @@ msg_ok "Customized Container" fi msg_info "Cleaning up" -#apt-get autoremove >/dev/null -#apt-get autoclean >/dev/null +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" From 69eeaaee2a9efd50741e60c987eb2f5281b1b603 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 13:14:04 -0400 Subject: [PATCH 3298/6505] maintenance (#403) --- ct/daemonsync-v4.sh | 2 +- ct/dashy-v4.sh | 2 +- ct/esphome-v4.sh | 2 +- ct/grafana-v4.sh | 2 +- ct/grocy-v4.sh | 2 +- ct/heimdalldashboard-v4.sh | 2 +- ct/homebridge-v4.sh | 2 +- ct/iobroker-v4.sh | 2 +- ct/keycloak-v4.sh | 2 +- ct/magicmirror-v4.sh | 2 +- ct/meshcentral-v4.sh | 2 +- ct/motioneye-v4.sh | 2 +- ct/n8n-v4.sh | 2 +- ct/nginx-proxy-manager-v4.sh | 2 +- ct/nocodb-v4.sh | 2 +- ct/node-red-v4.sh | 2 +- ct/openhab-v4.sh | 2 +- ct/photoprism-v4.sh | 2 +- ct/pihole-v4.sh | 2 +- ct/prometheus-v4.sh | 2 +- ct/technitiumdns-v4.sh | 2 +- ct/uptimekuma-v4.sh | 2 +- ct/vaultwarden-v4.sh | 2 +- ct/whoogle-v4.sh | 2 +- ct/zwavejs2mqtt-v4.sh | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index 81a1548d..f805e6ac 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 903b605b..ab5bac02 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index be9d9c6f..a3409634 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 0b6a008b..9ec1d569 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index d07e87fc..172f92c0 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}${CL} \n" diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 8ff8a16f..6fecd9d9 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 21a66736..fc197eb6 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 92e0fca5..2cf95f20 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8081${CL} \n" diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index ac0c7f90..739dc010 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index ed2d9ca4..237ff677 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 38a28870..fc66509e 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}${CL} \n" diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index eb3b3735..64d25618 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index 3be8d9a8..22863a44 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5678${CL} \n" diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index ae4e9b7e..73ab124d 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 8cd33a28..6b3566f1 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080/dashboard${CL} \n" diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 9d4ed931..f79341df 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index d3301be6..ae186e7d 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index c8e2dc43..41ed38cb 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index ed11c16e..6fbfa78a 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}/admin${CL} \n" diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 6f172c69..13ae0854 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:9090${CL} \n" diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index a0cf9276..061ef6b2 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index c545e1c6..8569b392 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -260,5 +260,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3001${CL} \n" diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index 7f6799bc..f82d066f 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -263,5 +263,5 @@ pct set $CTID -memory 512 pct set $CTID -cores 1 msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index d2c463cd..bf0f9b9e 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -259,5 +259,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/zwavejs2mqtt-v4.sh b/ct/zwavejs2mqtt-v4.sh index 5e52fc2b..9c732818 100644 --- a/ct/zwavejs2mqtt-v4.sh +++ b/ct/zwavejs2mqtt-v4.sh @@ -271,5 +271,5 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8091${CL} \n" From f7b3b1e8939e796067760461400d850db4edb682 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 16:20:52 -0400 Subject: [PATCH 3299/6505] Update filebrowser-v3.sh --- misc/filebrowser-v3.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/filebrowser-v3.sh b/misc/filebrowser-v3.sh index e5cdfcf8..81b6c515 100644 --- a/misc/filebrowser-v3.sh +++ b/misc/filebrowser-v3.sh @@ -11,6 +11,7 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" APP="FileBrowser" +hostname="$(hostname)" set -o errexit set -o errtrace set -o nounset @@ -29,7 +30,7 @@ function error_exit() { } while true; do - read -p "This will Install ${APP}. Proceed(y/n)?" yn + read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -66,7 +67,7 @@ curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bas filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null -msg_ok "Installed ${APP}" +msg_ok "Installed ${APP} on $hostname" msg_info "Creating Service" service_path="/etc/systemd/system/filebrowser.service" From 231cad52d7f5e31ce784dc08f341704ff3033060 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 16:25:53 -0400 Subject: [PATCH 3300/6505] Update and rename filebrowser-v3.sh to filebrowser.sh --- misc/{filebrowser-v3.sh => filebrowser.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename misc/{filebrowser-v3.sh => filebrowser.sh} (97%) diff --git a/misc/filebrowser-v3.sh b/misc/filebrowser.sh similarity index 97% rename from misc/filebrowser-v3.sh rename to misc/filebrowser.sh index 81b6c515..6a11c514 100644 --- a/misc/filebrowser-v3.sh +++ b/misc/filebrowser.sh @@ -43,7 +43,7 @@ echo -e "${DGN} ______ _ _ ____ | ____(_) | | _ \ - | |__ _| | ___| |_) |_ __ _____ v3 _____ ___ _ __ + | |__ _| | ___| |_) |_ __ _____ _____ ___ _ __ | __| | | |/ _ \ _ <| __/ _ \ \ /\ / / __|/ _ \ __| | | | | | __/ |_) | | | (_) \ V V /\__ \ __/ | |_| |_|_|\___|____/|_| \___/ \_/\_/ |___/\___|_| From fd66a153c667a846ce73f5a0778c739931746859 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 16:28:23 -0400 Subject: [PATCH 3301/6505] Update and rename crowdsec-v3.sh to crowdsec.sh --- misc/{crowdsec-v3.sh => crowdsec.sh} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename misc/{crowdsec-v3.sh => crowdsec.sh} (90%) diff --git a/misc/crowdsec-v3.sh b/misc/crowdsec.sh similarity index 90% rename from misc/crowdsec-v3.sh rename to misc/crowdsec.sh index 0ab6d5c3..b250e765 100644 --- a/misc/crowdsec-v3.sh +++ b/misc/crowdsec.sh @@ -10,6 +10,7 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" APP="CrowdSec" +hostname="$(hostname)" set -o errexit set -o errtrace set -o nounset @@ -28,7 +29,7 @@ function error_exit() { } while true; do - read -p "This will Install ${APP}. Proceed(y/n)?" yn + read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -41,7 +42,7 @@ echo -e "${BL} _____ _ _____ / ____| | |/ ____| | | _ __ _____ ____| | (___ ___ ___ - | | v3 | __/ _ \ \ /\ / / _ |\___ \ / _ \/ __| + | | | __/ _ \ \ /\ / / _ |\___ \ / _ \/ __| | |____| | | (_) \ V V / (_| |____) | __/ (__ \_____|_| \___/ \_/\_/ \__ _|_____/ \___|\___| ${CL}" @@ -68,7 +69,7 @@ msg_ok "Setup ${APP} Repository" msg_info "Installing ${APP}" apt-get update &>/dev/null apt-get install -y crowdsec &>/dev/null -msg_ok "Installed ${APP}" +msg_ok "Installed ${APP} on $hostname" msg_info "Installing ${APP} Common Bouncer" apt-get install -y crowdsec-firewall-bouncer-iptables &>/dev/null From 4e7496546176952ca4cdfbbcedfb280dfb5c210e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 16:30:51 -0400 Subject: [PATCH 3302/6505] Delete kernel-clean.sh --- misc/kernel-clean.sh | 100 ------------------------------------------- 1 file changed, 100 deletions(-) delete mode 100644 misc/kernel-clean.sh diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh deleted file mode 100644 index 9a883003..00000000 --- a/misc/kernel-clean.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -RD=$(tput setaf 1) -GN=$(tput setaf 2) -LYW=$(tput setaf 190) -WH=$(tput setaf 7) -BRT=$(tput bold) -CL=$(tput sgr0) -UL=$(tput smul) -current_kernel=$(uname -r) -pve=$(pveversion) - -while true; do - read -p "${WH}This will Clean unused Kernel images. Proceed(y/n)?${CL}" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo -e "${RD}Please answer y/n${CL}";; - esac -done -clear - -function check_root { - if [[ $EUID -ne 0 ]]; then - echo -e "${RD}Error: This script must be ran as the root user.\n${CL}" - exit 1 - fi -} - -function header_info { -echo -e "${RD} - _ __ _ _____ _ - | |/ / | | / ____| | - | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ - | < / _ \ __| _ \ / _ \ | | | | |/ _ \/ _ | _ \ - | \ __/ | | | | | __/ | | |____| | __/ (_| | | | | - |_|\_\___|_| |_| |_|\___|_| \_____|_|\___|\__,_|_| |_| - -${CL}" -} - -function kernel_info() { - latest_kernel=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) - echo -e "${LYW}PVE Version: ${UL}${WH}$pve\n${CL}" - if [[ "$current_kernel" == *"pve"* ]]; then - if [[ "$latest_kernel" != *"$current_kernel"* ]]; then - echo -e "${GN}Latest Kernel: $latest_kernel\n${CL}" - fi - else - echo -e "\n${RD}ERROR: No PVE Kernel Found\n${CL}" - exit 1 - fi -} - -function kernel_clean() { - kernels=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | sort -V) - remove_kernels="" - for kernel in $kernels - do - if [ "$(echo $kernel | grep $current_kernel)" ]; then - break - else - echo -e "${RD}'$kernel' ${CL}${LYW}has been added to the remove Kernel list\n${CL}" - remove_kernels+=" $kernel" - fi - done -echo -e "${LYW}Kernel Search Complete!\n${CL}" - if [[ "$remove_kernels" != *"pve"* ]]; then - echo -e "${BRT}${GN}It appears there are no old Kernels on your system. \n${CL}" - else - read -p "${LYW}Would you like to remove the${RD} $(echo $remove_kernels | awk '{print NF}') ${CL}${LYW}selected Kernels listed above? [y/n]: ${CL}" -n 1 -r - fi - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo -e "${LYW}\nRemoving ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${LYW}old Kernels...${CL}" - /usr/bin/apt purge -y $remove_kernels > /dev/null 2>&1 - echo -e "${LYW}Finished!\n${CL}" - echo -e "${LYW}Updating GRUB... \n${CL}" - /usr/sbin/update-grub > /dev/null 2>&1 - echo -e "${LYW}Finished!\n${CL}" - else - echo -e "${LYW}Exiting...\n${CL}" - sleep 2 - fi -} - -function main() { - check_root - header_info - kernel_info -} - -while true; do - case "$1" in - * ) - main - kernel_clean - exit 1 - ;; - esac - shift -done From 9b990503398fc523ad4fc411051e0f6adf36639b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 16:31:04 -0400 Subject: [PATCH 3303/6505] Update and rename kernel-clean-v3.sh to kernel-clean.sh --- misc/{kernel-clean-v3.sh => kernel-clean.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename misc/{kernel-clean-v3.sh => kernel-clean.sh} (98%) diff --git a/misc/kernel-clean-v3.sh b/misc/kernel-clean.sh similarity index 98% rename from misc/kernel-clean-v3.sh rename to misc/kernel-clean.sh index c079d7ea..c804741a 100644 --- a/misc/kernel-clean-v3.sh +++ b/misc/kernel-clean.sh @@ -33,7 +33,7 @@ echo -e "${RD} | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ | < / _ \ __| _ \ / _ \ | | | | |/ _ \/ _ | _ \ | \ __/ | | | | | __/ | | |____| | __/ (_| | | | | - |_|\_\___|_| |_| |_|\___|_|v3\_____|_|\___|\__,_|_| |_| + |_|\_\___|_| |_| |_|\___|_| \_____|_|\___|\__,_|_| |_| ${CL}" } From ba94d2ee8c19c1495992ff19e21f1c2c4bc0ef95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 16:33:04 -0400 Subject: [PATCH 3304/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 10979c58..653fd82d 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Cleaning unused kernel images is not only good because of a reduced grub menu, b Run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean.sh)" ``` ____________________________________________________________________________________________ @@ -1692,7 +1692,7 @@ ________________________________________________________________________________ To Install File Browser, ⚠️ run the following in the LXC console. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/filebrowser-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/filebrowser.sh)" ``` [File Browser](https://filebrowser.org/features) is a create-your-own-cloud-kind of software where you can install it on a server, direct it to a path and then access your files through a nice web interface. Many available features! @@ -1858,7 +1858,7 @@ ________________________________________________________________________________ To Install CrowdSec, ⚠️ run the following in the LXC console. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec.sh)" ``` [CrowdSec](https://crowdsec.net/) is a free, open-source and collaborative IPS. Analyze behaviors, respond to attacks & share signals across the community. From c929b48ac4cb61a5d2e58d10b6a64fac9df8c788 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 16:34:40 -0400 Subject: [PATCH 3305/6505] Create code-server.sh --- misc/code-server.sh | 89 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 misc/code-server.sh diff --git a/misc/code-server.sh b/misc/code-server.sh new file mode 100644 index 00000000..2fcade90 --- /dev/null +++ b/misc/code-server.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +IP=$(hostname -I | awk '{print $1}') +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Code Server" +hostname="$(hostname)" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +while true; do + read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +echo -e "${BL} + ______ __ _____ + / ____/___ ____/ /__ / ___/___ ______ _____ _____ + / / / __ \/ __ / _ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ +/ /___/ /_/ / /_/ / __/ ___/ / __/ / | |/ / __/ / +\____/\____/\__,_/\___/ /____/\___/_/ |___/\___/_/ +${CL}" +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +msg_ok "Installed Dependencies" + +VERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') \ + +msg_info "Installing Code-Server v${VERSION}" +curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_amd64.deb &>/dev/null +sudo dpkg -i code-server_${VERSION}_amd64.deb &>/dev/null +rm -rf code-server_${VERSION}_amd64.deb +mkdir -p ~/.config/code-server/ +sudo systemctl enable --now code-server@$USER &>/dev/null +cat < ~/.config/code-server/config.yaml +bind-addr: 0.0.0.0:8680 +auth: none +password: +cert: false +EOF +sudo systemctl restart code-server@$USER +msg_ok "Installed Code-Server v${VERSION} on $hostname" + +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://$IP:8680${CL} \n" From 744d99bc6ef6bb656990a865e9def6e40a8f3876 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:02:56 -0400 Subject: [PATCH 3306/6505] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 653fd82d..6165e4ca 100644 --- a/README.md +++ b/README.md @@ -1721,6 +1721,29 @@ ________________________________________________________________________________
    +
    + 🔸Code Server + +

    + +

    Code Server

    + +To Install Code Server, ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/code-server.sh)" +``` + +[Code Server](https://code.visualstudio.com/docs/remote/vscode-server) is a service you can run on a remote development machine, like your desktop PC or a virtual machine (VM). It allows you to securely connect to that remote machine from anywhere through a vscode.dev URL, without the requirement of SSH. + + + +**Code Server Interface - http:// IP:8680** + +___________________________________________________________________________________________ + +
    +
    Webmin System Administration From 2693a5c5ae01495497efe4465a17b1bb247b13f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:04:32 -0400 Subject: [PATCH 3307/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 74eb4deb..0cd09df0 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-04 + +### Changed + +- **Code Server** + - NEW Script + ## 2022-08-02 ### Changed From a87cb3533112b2ead20b76ef137ca05fd3de957c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:08:57 -0400 Subject: [PATCH 3308/6505] Delete post_install.sh --- misc/post_install.sh | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 misc/post_install.sh diff --git a/misc/post_install.sh b/misc/post_install.sh deleted file mode 100644 index d529fb3c..00000000 --- a/misc/post_install.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -echo -e "\e[1;33m This script will Setup Repositories and attempt the No-Nag fix. PVE7 ONLY \e[0m" -while true; do - read -p "Start the PVE7 Post Install Script (y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo -e "This script requires Proxmox Virtual Environment 7.0 or greater" - echo -e "Exiting..." - sleep 2 - exit -fi -clear -echo -e "\e[1;33m Disable Enterprise Repository... \e[0m" -sleep 1 -sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list -echo -e "\e[1;33m Setup Repositories... \e[0m" -sleep 1 -cat < /etc/apt/sources.list -deb http://ftp.debian.org/debian bullseye main contrib -deb http://ftp.debian.org/debian bullseye-updates main contrib -deb http://security.debian.org/debian-security bullseye-security main contrib -deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription -# deb http://download.proxmox.com/debian/pve bullseye pvetest -EOF -echo -e "\e[1;33m Disable Subscription Nag... \e[0m" -echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script -apt --reinstall install proxmox-widget-toolkit &>/dev/null -echo -e "\e[1;33m Finished....Please Update Proxmox \e[0m" - -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/post_install.sh)" From c8741fdc1980b165500da8a8ff01e37f6d057e28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:11:24 -0400 Subject: [PATCH 3309/6505] Rename post-install-v3.sh to post-install.sh --- misc/{post-install-v3.sh => post-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename misc/{post-install-v3.sh => post-install.sh} (100%) diff --git a/misc/post-install-v3.sh b/misc/post-install.sh similarity index 100% rename from misc/post-install-v3.sh rename to misc/post-install.sh From 98a7e71aca86c4a19dde10f9001e1c30b343fce3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:11:40 -0400 Subject: [PATCH 3310/6505] Update post-install.sh --- misc/post-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-install.sh b/misc/post-install.sh index 747c2128..543f36c6 100644 --- a/misc/post-install.sh +++ b/misc/post-install.sh @@ -33,7 +33,7 @@ echo -e "${RD} _______ ________ ______ _____ _ _____ _ _ _ | __ \ \ / / ____|____ | | __ \ | | |_ _| | | | | | | |__) \ \ / /| |__ / / | |__) |__ ___| |_ | | _ __ ___| |_ __ _| | | - | ___/ \ \/ / | __| v3 / / | ___/ _ \/ __| __| | | | _ \/ __| __/ _ | | | + | ___/ \ \/ / | __| / / | ___/ _ \/ __| __| | | | _ \/ __| __/ _ | | | | | \ / | |____ / / | | | (_) \__ \ |_ _| |_| | | \__ \ || (_| | | | |_| \/ |______|/_/ |_| \___/|___/\__| |_____|_| |_|___/\__\__,_|_|_| ${CL}" From c3d2e486ef0858303460d0d6f6b8654c05002da6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:12:42 -0400 Subject: [PATCH 3311/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6165e4ca..c85d3ee1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 So Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-install-v3.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-install.sh)" ``` It's recommended to answer `y` to all options. From 0b7fd7ed8aa2d29619c5fcfc28ac78276af629a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:18:29 -0400 Subject: [PATCH 3312/6505] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c85d3ee1..2dcdee2e 100644 --- a/README.md +++ b/README.md @@ -1722,23 +1722,23 @@ ________________________________________________________________________________
    - 🔸Code Server + 🔸VS Code Server

    -

    Code Server

    +

    VS Code Server

    -To Install Code Server, ⚠️ run the following in the LXC console. +To Install VS Code Server, ⚠️ run the following in the LXC console. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/code-server.sh)" ``` -[Code Server](https://code.visualstudio.com/docs/remote/vscode-server) is a service you can run on a remote development machine, like your desktop PC or a virtual machine (VM). It allows you to securely connect to that remote machine from anywhere through a vscode.dev URL, without the requirement of SSH. +[VS Code Server](https://code.visualstudio.com/docs/remote/vscode-server) is a service you can run on a remote development machine, like your desktop PC or a virtual machine (VM). It allows you to securely connect to that remote machine from anywhere through a vscode.dev URL, without the requirement of SSH. -**Code Server Interface - http:// IP:8680** +**VS Code Server Interface - http:// IP:8680** ___________________________________________________________________________________________ From 79eb153c5af39fa644547b0a20a67467ee02f162 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Aug 2022 18:18:50 -0400 Subject: [PATCH 3313/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0cd09df0..a66d0b91 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **Code Server** +- **VS Code Server** - NEW Script ## 2022-08-02 From 47a76e6977541e25a08e4421553a20ddb4113ded Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Aug 2022 11:18:16 -0400 Subject: [PATCH 3314/6505] Update post-install.sh --- misc/post-install.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/misc/post-install.sh b/misc/post-install.sh index 543f36c6..55100fb7 100644 --- a/misc/post-install.sh +++ b/misc/post-install.sh @@ -30,12 +30,11 @@ if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then fi function header_info { echo -e "${RD} - _______ ________ ______ _____ _ _____ _ _ _ - | __ \ \ / / ____|____ | | __ \ | | |_ _| | | | | | - | |__) \ \ / /| |__ / / | |__) |__ ___| |_ | | _ __ ___| |_ __ _| | | - | ___/ \ \/ / | __| / / | ___/ _ \/ __| __| | | | _ \/ __| __/ _ | | | - | | \ / | |____ / / | | | (_) \__ \ |_ _| |_| | | \__ \ || (_| | | | - |_| \/ |______|/_/ |_| \___/|___/\__| |_____|_| |_|___/\__\__,_|_|_| + ____ _ _____________ ____ __ ____ __ ____ + / __ \ | / / ____/__ / / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / + / ____/| |/ / /___ / / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/ /_/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ ${CL}" } From 978af4df27b446cf1c74ba9e2f5cea3a1862cf30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Aug 2022 12:55:38 -0400 Subject: [PATCH 3315/6505] Update nginx-proxy-manager-v4.sh --- ct/nginx-proxy-manager-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 73ab124d..1dd6b6a7 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -3,7 +3,7 @@ echo -e "Loading..." APP="Nginx Proxy Manager" var_disk="3" var_cpu="1" -var_ram="1048" +var_ram="1024" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') From 0d8ece655393834ed2c08ad80bf29e57d0829d44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Aug 2022 20:13:56 -0400 Subject: [PATCH 3316/6505] Update zigbee2mqtt-v4.sh --- ct/zigbee2mqtt-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 25a20cab..0a8e837e 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -49,7 +49,7 @@ echo -e "${YW} / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / /____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ - /____/ 🐝 v4 + v4 /____/ 🐝 ${CL}" } function msg_info() { From 1b8e9814997a704e7f20368b5294e1736321e721 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 Aug 2022 15:23:25 -0400 Subject: [PATCH 3317/6505] Create pimox-haos-vm-v4.sh --- vm/pimox-haos-vm-v4.sh | 256 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 vm/pimox-haos-vm-v4.sh diff --git a/vm/pimox-haos-vm-v4.sh b/vm/pimox-haos-vm-v4.sh new file mode 100644 index 00000000..624fcc62 --- /dev/null +++ b/vm/pimox-haos-vm-v4.sh @@ -0,0 +1,256 @@ +#!/usr/bin/env bash +echo -e "Loading..." +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +NEXTID=$(pvesh get /cluster/nextid) +LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +HA=`echo "\033[1;34m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + ____ _ __ ___ __ _____ ____ _____ + / __ \(_) / |/ /___ _ __ / / / / | / __ \/ ___/ + / /_/ / /v4_/ /|_/ / __ \| |/_/ / /_/ / /| |/ / / /\__ \ + / ____/ /___/ / / / /_/ /> < / __ / ___ / /_/ /___/ / +/_/ /_/ /_/ /_/\____/_/|_| /_/ /_/_/ |_\____//____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function default_settings() { + echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" + HN=haos${STABLE} + echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" +} +function advanced_settings() { +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 2 \ +"$STABLE" "Stable" ON \ +"$LATEST" "Latest" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" +else + exit +fi +VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" +else + exit +fi +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${STABLE} --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + exit +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" +else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then + echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +start_script +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then + echo -e "'Disk image' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the HAOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_generic-aarch64-${BRANCH}.qcow2.xz +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}haos_generic-aarch64-${BRANCH}.qcow2.xz${CL}" +msg_info "Extracting Disk Image" +unxz $FILE +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +msg_ok "Extracted Disk Image" +msg_info "Creating HAOS VM" +qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},size=128K \ + -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null +qm set $VMID \ + -boot order=scsi0 >/dev/null +qm set $VMID -description "# Home Assistant OS +### https://github.com/tteck/Proxmox" >/dev/null +msg_ok "Created HAOS VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then +msg_info "Starting Home Assistant OS VM" +qm start $VMID +msg_ok "Started Home Assistant OS VM" +fi +msg_ok "Completed Successfully!\n" From 8113f8b18a47aa1037393db1bd8e155343efcdf3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 Aug 2022 15:51:17 -0400 Subject: [PATCH 3318/6505] Update pimox-haos-vm-v4.sh --- vm/pimox-haos-vm-v4.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vm/pimox-haos-vm-v4.sh b/vm/pimox-haos-vm-v4.sh index 624fcc62..717300da 100644 --- a/vm/pimox-haos-vm-v4.sh +++ b/vm/pimox-haos-vm-v4.sh @@ -236,13 +236,13 @@ for i in {0,1}; do done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null +pvesm alloc $STORAGE $VMID $DISK0 64M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null + -efidisk0 ${DISK0_REF},efitype=4m,size=64M \ + -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS From d0aee3ceced5a1c3c1ad5d5d3b50f60de7cff76b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 Aug 2022 21:57:31 -0400 Subject: [PATCH 3319/6505] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2dcdee2e..65f280b0 100644 --- a/README.md +++ b/README.md @@ -1239,9 +1239,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v4.sh) ⚙️ **To Update Omada** -```yaml -Working On -``` +https://github.com/tteck/Proxmox/issues/402#issue-1328460983 + ____________________________________________________________________________________________
    From 430bd65f3332fccedce15dce78ae2f396d2e518b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Aug 2022 17:46:57 -0400 Subject: [PATCH 3320/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index dbbf1db5..af7b1ae3 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -127,17 +127,26 @@ NODE_OPTIONS=--max_old_space_size=2048 make all &>/dev/null cp -a assets/ /opt/photoprism/assets/ &>/dev/null msg_ok "Built PhotoPrism" -env_path="/var/lib/photoprism/.env" -echo " -PHOTOPRISM_AUTH_MODE='password' -PHOTOPRISM_ADMIN_PASSWORD='changeme' -PHOTOPRISM_HTTP_HOST='0.0.0.0' -PHOTOPRISM_HTTP_PORT=2342 -PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' -PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' -PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -" > $env_path +#env_path="/var/lib/photoprism/.env" +#echo " +#PHOTOPRISM_AUTH_MODE='password' +#PHOTOPRISM_ADMIN_PASSWORD='changeme' +#PHOTOPRISM_HTTP_HOST='0.0.0.0' +#PHOTOPRISM_HTTP_PORT=2342 +#PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' +#PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' +#PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' +#" > $env_path +cat < /var/lib/photoprism/.env +PHOTOPRISM_AUTH_MODE="password" +PHOTOPRISM_ADMIN_PASSWORD="changeme" +PHOTOPRISM_HTTP_HOST="0.0.0.0" +PHOTOPRISM_HTTP_PORT="2342" +PHOTOPRISM_STORAGE_PATH="/var/lib/photoprism/storage" +PHOTOPRISM_ORIGINALS_PATH="/var/lib/photoprism/photos/Originals" +PHOTOPRISM_IMPORT_PATH="/var/lib/photoprism/photos/Import" +EOF msg_info "Creating Service" service_path="/etc/systemd/system/photoprism.service" From eebaf645f173eaf080e258c1aea5f0056520b25c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Aug 2022 20:04:09 -0400 Subject: [PATCH 3321/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65f280b0..a05e006d 100644 --- a/README.md +++ b/README.md @@ -1721,7 +1721,7 @@ ________________________________________________________________________________
    - 🔸VS Code Server + VS Code Server

    From ef9e363498f32226dd6d4311b2a5fda85778d4ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Aug 2022 10:01:51 -0400 Subject: [PATCH 3322/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 18ca623d..390abae4 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash echo -e "Loading..." -PVE=$(pveversion | grep "pve-manager/7" | wc -l) GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') @@ -47,11 +46,12 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [[ "$PVE" != "1" ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: 7.XX" + echo "Exiting..." + sleep 3 + exit fi if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then echo "User selected Yes" From 35c83337680bde52340488eaee51ea6cb395899b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Aug 2022 10:04:39 -0400 Subject: [PATCH 3323/6505] Update post-install.sh --- misc/post-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/misc/post-install.sh b/misc/post-install.sh index 55100fb7..b88fe3b2 100644 --- a/misc/post-install.sh +++ b/misc/post-install.sh @@ -23,10 +23,11 @@ while true; do esac done if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo -e "This script requires Proxmox Virtual Environment 7.0 or greater" - echo -e "Exiting..." - sleep 2 - exit + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: 7.XX" + echo "Exiting..." + sleep 3 + exit fi function header_info { echo -e "${RD} From 1cdc6b9687ce85e0be5d8cacb8cab8c97af47ec6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Aug 2022 13:43:47 -0400 Subject: [PATCH 3324/6505] Update haos-vm-v4.sh Validate Storage --- vm/haos-vm-v4.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 390abae4..81141b62 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -194,6 +194,7 @@ else fi } start_script +msg_info "Validating Storage" while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -203,11 +204,13 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - echo -e "'Disk image' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + echo -e "${RD}⚠ Unable to detect a valid storage location.${CL}" + echo -e "Exiting..." + exit elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else From 3ffee0b695d79d524008b25d1ecab18914a2327d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Aug 2022 13:45:14 -0400 Subject: [PATCH 3325/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a05e006d..50b0ddfb 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ ________________________________________________________________________________
    - Home Assistant OS VM + 🔸Home Assistant OS VM

    From cf8c77b7c4529ee6c0307c31d16216468fcc299a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Aug 2022 13:46:44 -0400 Subject: [PATCH 3326/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a66d0b91..c145dfc5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-11 + +### Changed + +- **Home Assistant OS VM** + - Validate Storage + ## 2022-08-04 ### Changed From 54bf1dffb7c897bc1133074502e7c91e6e5e8f73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Aug 2022 05:25:50 -0400 Subject: [PATCH 3327/6505] maintenance (#420) --- ct/adguard-v4.sh | 1 + ct/daemonsync-v4.sh | 1 + ct/dashy-v4.sh | 1 + ct/debian-v4.sh | 1 + ct/deconz-v4.sh | 1 + ct/docker-v4.sh | 1 + ct/esphome-v4.sh | 1 + ct/grafana-v4.sh | 1 + ct/grocy-v4.sh | 1 + ct/heimdalldashboard-v4.sh | 1 + ct/homeassistant-v4.sh | 1 + ct/homebridge-v4.sh | 1 + ct/influxdb-v4.sh | 1 + ct/iobroker-v4.sh | 1 + ct/jellyfin-v4.sh | 1 + ct/keycloak-v4.sh | 1 + ct/magicmirror-v4.sh | 1 + ct/mariadb-v4.sh | 1 + ct/meshcentral-v4.sh | 1 + ct/motioneye-v4.sh | 1 + ct/mqtt-v4.sh | 1 + ct/n8n-v4.sh | 1 + ct/nginx-proxy-manager-v4.sh | 1 + ct/nocodb-v4.sh | 1 + ct/node-red-v4.sh | 1 + ct/omada-v4.sh | 1 + ct/openhab-v4.sh | 1 + ct/photoprism-v4.sh | 1 + ct/pihole-v4.sh | 1 + ct/plex-v4.sh | 1 + ct/podman-homeassistant-v4.sh | 1 + ct/postgresql-v4.sh | 1 + ct/prometheus-v4.sh | 1 + ct/technitiumdns-v4.sh | 1 + ct/ubuntu-v4.sh | 1 + ct/unifi-v4.sh | 1 + ct/uptimekuma-v4.sh | 1 + ct/vaultwarden-v4.sh | 1 + ct/whoogle-v4.sh | 1 + ct/wireguard-v4.sh | 1 + ct/zigbee2mqtt-v4.sh | 1 + ct/zwavejs2mqtt-v4.sh | 1 + 42 files changed, 42 insertions(+) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index ad961086..bb40f982 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index f805e6ac..3fee2a6e 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index ab5bac02..5383cf97 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 8e2cbcab..fb470b8a 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 388083aa..28db39a2 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -149,6 +149,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index 50deaa4d..d83382b7 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index a3409634..e6488c95 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 9ec1d569..7ed70c2c 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 172f92c0..680bcc4a 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 6fecd9d9..3b5c52bd 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 9af2f420..17ff5cdc 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index fc197eb6..87b60dcb 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 865c93cc..f7b0fa7a 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 2cf95f20..7b56f873 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index bf6c0d7f..210bfdf9 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -149,6 +149,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 739dc010..61954dae 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 237ff677..9f81130a 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index ceabd448..effb77bf 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index fc66509e..35ef4971 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 64d25618..0ce01077 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index 624297b3..01638788 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index 22863a44..5cdcc286 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 1dd6b6a7..39ffe521 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 6b3566f1..08e6fd4b 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index f79341df..04aba883 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 9c121060..6236796c 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -149,6 +149,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index ae186e7d..128a0223 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index 41ed38cb..9ffc9399 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 6fbfa78a..60dd7c25 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index cde23da8..9c43b82c 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -149,6 +149,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 79f851a6..6c97d5d8 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -150,6 +150,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index 33f06931..7d8c4d13 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 13ae0854..554e531f 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index 061ef6b2..fa20dafc 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index fd4c3077..8df0e0f4 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -149,6 +149,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index f7cea5c7..71f3ac51 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index 8569b392..3a806bff 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index f82d066f..fa33cb7b 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index bf0f9b9e..f5dabd3e 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -146,6 +146,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index f63f5202..6e2e9282 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -148,6 +148,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 0a8e837e..2c5662e2 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi diff --git a/ct/zwavejs2mqtt-v4.sh b/ct/zwavejs2mqtt-v4.sh index 9c732818..9854db8e 100644 --- a/ct/zwavejs2mqtt-v4.sh +++ b/ct/zwavejs2mqtt-v4.sh @@ -147,6 +147,7 @@ DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DI exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; else exit fi From 0df983699d0de9e3944a714c20250c1d8db6d834 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Aug 2022 13:24:37 -0400 Subject: [PATCH 3328/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 81141b62..6ae0ef59 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -208,7 +208,7 @@ STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') VALID=$(pvesm status -content images | awk 'NR>1') if [ -z "$VALID" ]; then - echo -e "${RD}⚠ Unable to detect a valid storage location.${CL}" + echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" echo -e "Exiting..." exit elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then From 1b3f2b0a752df742cff405c68fa76af92a07da7a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Aug 2022 15:08:00 -0400 Subject: [PATCH 3329/6505] Update haos-vm-v4.sh add Dev branch option --- vm/haos-vm-v4.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 6ae0ef59..7adda760 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -2,8 +2,9 @@ echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) -LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` HA=`echo "\033[1;34m"` @@ -100,9 +101,10 @@ function default_settings() { echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 2 \ +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 3 \ "$STABLE" "Stable" ON \ "$LATEST" "Latest" OFF \ +"$DEV" "Dev" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -117,7 +119,7 @@ if [ $exitstatus = 0 ]; then else exit fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${STABLE} --title "HOSTNAME" 3>&1 1>&2 2>&3) +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' ') @@ -224,7 +226,11 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +if [ "$BRANCH" == "$DEV" ]; then +URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +else URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +fi sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From f215f21d885464366b457ef4368f3ace79ac38b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Aug 2022 15:08:45 -0400 Subject: [PATCH 3330/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50b0ddfb..a1093d3e 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ ________________________________________________________________________________

    Home Assistant OS VM

    -

    Option to create VM using the Latest or Stable Image

    +

    Option to create VM using Stable, Latest or Dev Image

    The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip, ect...) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. From 35826c04e1d519927c258b3d41d31f3213657170 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Aug 2022 15:10:28 -0400 Subject: [PATCH 3331/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c145dfc5..864950b4 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-13 + +### Changed + +- **Home Assistant OS VM** + - Option to create VM using Stable, Latest or Dev Image + ## 2022-08-11 ### Changed From e2bea6da89228860dcac150790378e80190c89f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 Aug 2022 08:02:21 -0400 Subject: [PATCH 3332/6505] Change Latest to Beta (#425) * Update haos-vm-v4.sh * Update README.md * Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- README.md | 2 +- vm/haos-vm-v4.sh | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 864950b4..c7cea0e3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Home Assistant OS VM** - - Option to create VM using Stable, Latest or Dev Image + - Option to create VM using Stable, Beta or Dev Image ## 2022-08-11 diff --git a/README.md b/README.md index a1093d3e..9dcc539b 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ ________________________________________________________________________________

    Home Assistant OS VM

    -

    Option to create VM using Stable, Latest or Dev Image

    +

    Option to create VM using Stable, Beta or Dev Image

    The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip, ect...) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 7adda760..1f9fa7cd 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -3,7 +3,7 @@ echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` @@ -103,7 +103,7 @@ function default_settings() { function advanced_settings() { BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 3 \ "$STABLE" "Stable" ON \ -"$LATEST" "Latest" OFF \ +"$BETA" "Beta" OFF \ "$DEV" "Dev" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? From 4a1eb2e3e136dcb006410db58c958774bf57cdb5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Aug 2022 07:38:56 -0400 Subject: [PATCH 3333/6505] Update haos_vm.sh --- vm/haos_vm.sh | 360 ++++++++++++++++++++------------------------------ 1 file changed, 141 insertions(+), 219 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 89ec3614..9acaeb70 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -1,12 +1,13 @@ #!/usr/bin/env bash echo -e "Loading..." -PVE=$(pveversion | grep "pve-manager/7" | wc -l) GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) -RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +BETA=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') +DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` +HA=`echo "\033[1;34m"` RD=`echo "\033[01;31m"` BGN=`echo "\033[4;92m"` GN=`echo "\033[1;92m"` @@ -23,7 +24,6 @@ shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR trap cleanup EXIT - function error_exit() { trap - ERR local reason="Unknown failure occurred." @@ -33,7 +33,6 @@ function error_exit() { [ ! -z ${VMID-} ] && cleanup_vmid exit $EXIT } - function cleanup_vmid() { if $(qm status $VMID &>/dev/null); then if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then @@ -42,241 +41,160 @@ function cleanup_vmid() { qm destroy $VMID fi } - function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } - TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - -if [[ "$PVE" == "1" ]]; then - echo -e "${YW}This script is for Proxmox Virtual Environment 6${CL}" +if [ `pveversion | grep "pve-manager/7" | wc -l` -eq 1 ]; then + echo -e "${YW}This script is for Proxmox Virtual Environment 6.xx${CL}" echo -e "Continuing..." - sleep 5 + sleep 3 fi - -while true; do +if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then + echo "User selected Yes" +else clear - read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear - + echo -e "⚠ User exited script \n" + exit +fi function header_info { -echo -e "${BL} - _ _ ____ _____ - | | | | /\ / __ \ / ____| - | |__| | / \ | | | | (___ - | __ | / /\ \| | | |\___ \ - | | | |/ ____ \ |__| |____) | - |_| |_/_/ ${CL}${YW}v3${CL}${BL} \_\____/|_____/ +echo -e "${HA} + __ _____ ____ _____ + / / / / | / __ \/ ___/ + / /_/ / /| |/ / / /\__ \ + / __ / ___ / /_/ /___/ / +/_/ /_/_/v4|_\____//____/ + Home Assistant OS ${CL}" } -header_info - function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } - function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using Version ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" - VM_NAME=haos${STABLE} - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" - echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" - START_VM="yes" - + echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" + HN=haos${STABLE} + echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Latest for Version ${RELEASE}, or Press [ENTER] for Stable Version ${STABLE} " - read BRANCH - if [ -z $BRANCH ]; then BRANCH=$STABLE; - else - BRANCH=$RELEASE; fi; - echo -en "${DGN}Set Version To ${BL}$BRANCH${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read VMID - if [ -z $VMID ]; then VMID=$NEXTID; fi; - echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${BRANCH} " - read VMNAME - if [ -z $VMNAME ]; then - VM_NAME=haos${BRANCH} - else - VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$VM_NAME${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}${CORE_COUNT}${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Valid MAC Address, or Press [ENTER] for Generated MAC: $GEN_MAC " - read MAC - if [ -z $MAC ]; then MAC=$GEN_MAC; fi; - echo -en "${DGN}Set MAC Address To ${BL}$MAC${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " - read START_VM - if [ -z $START_VM ]; then START_VM="yes"; - else - START_VM="no"; fi; - echo -en "${DGN}Starting VM when completed ${BL}$START_VM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 3 \ +"$STABLE" "Stable" ON \ +"$BETA" "Beta" OFF \ +"$DEV" "Dev" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" +else + exit +fi +VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" +else + exit +fi +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + exit +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" +else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then + echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings fi } - function start_script() { - echo -e "${YW}Type Advanced (Latest ${RELEASE}), or Press [ENTER] for Default Settings (Stable ${STABLE}) " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi } - start_script - +msg_info "Validating Storage" while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -286,11 +204,13 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - echo -e "'Disk image' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" + echo -e "Exiting..." + exit elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else @@ -304,7 +224,11 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +if [ "$BRANCH" == "$DEV" ]; then +URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +else URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +fi sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL @@ -326,9 +250,8 @@ for i in {0,1}; do eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done msg_ok "Extracted KVM Disk Image" - msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null @@ -339,8 +262,7 @@ qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS ### https://github.com/tteck/Proxmox" >/dev/null -msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" - +msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID From ee43d67571deedf5b66232fbec991d4d9801036e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Aug 2022 09:03:34 -0400 Subject: [PATCH 3334/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9dcc539b..4aae6cb2 100644 --- a/README.md +++ b/README.md @@ -972,7 +972,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v4.sh Run in the LXC console ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/nocodb-update.sh)" +cd /opt/nocodb && npm run upgrade ``` ____________________________________________________________________________________________ From 249c751efbd7f1a525e2a2c2d21b1696eb80a593 Mon Sep 17 00:00:00 2001 From: cklam2 Date: Fri, 19 Aug 2022 12:40:45 +0200 Subject: [PATCH 3335/6505] Update photoprism-install.sh (#442) --- setup/photoprism-install.sh | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index af7b1ae3..72190169 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -97,6 +97,7 @@ cp /usr/local/go/bin/richgo /usr/local/bin/richgo cp /usr/local/go/bin/gosu /usr/local/sbin/gosu chown root:root /usr/local/sbin/gosu chmod 755 /usr/local/sbin/gosu +rm go1.18.3.linux-amd64.tar.gz msg_ok "Installed Golang" msg_info "Installing Tensorflow" @@ -111,6 +112,7 @@ if [[ "$AVX" =~ avx2 ]]; then tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null fi ldconfig &>/dev/null +rm libtensorflow-linux-avx2-1.15.2.tar.gz msg_ok "Installed Tensorflow" msg_info "Cloning PhotoPrism" @@ -127,25 +129,17 @@ NODE_OPTIONS=--max_old_space_size=2048 make all &>/dev/null cp -a assets/ /opt/photoprism/assets/ &>/dev/null msg_ok "Built PhotoPrism" -#env_path="/var/lib/photoprism/.env" -#echo " -#PHOTOPRISM_AUTH_MODE='password' -#PHOTOPRISM_ADMIN_PASSWORD='changeme' -#PHOTOPRISM_HTTP_HOST='0.0.0.0' -#PHOTOPRISM_HTTP_PORT=2342 -#PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' -#PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' -#PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -#" > $env_path - -cat < /var/lib/photoprism/.env -PHOTOPRISM_AUTH_MODE="password" -PHOTOPRISM_ADMIN_PASSWORD="changeme" -PHOTOPRISM_HTTP_HOST="0.0.0.0" -PHOTOPRISM_HTTP_PORT="2342" -PHOTOPRISM_STORAGE_PATH="/var/lib/photoprism/storage" -PHOTOPRISM_ORIGINALS_PATH="/var/lib/photoprism/photos/Originals" -PHOTOPRISM_IMPORT_PATH="/var/lib/photoprism/photos/Import" +cat < /var/lib/photoprism/options.yml +# Authentication +AuthMode: password +AdminPassword: changeme +# Listening address/port +HttpPort: 2342 +HttpHost: 0.0.0.0 +# Paths +StoragePath: /var/lib/photoprism/storage +OriginalsPath: /var/lib/photoprism/photos/Originals +ImportPath: /var/lib/photoprism/photos/Import EOF msg_info "Creating Service" service_path="/etc/systemd/system/photoprism.service" @@ -158,8 +152,7 @@ After=network.target Type=forking User=root WorkingDirectory=/opt/photoprism -EnvironmentFile=/var/lib/photoprism/.env -ExecStart=/opt/photoprism/bin/photoprism up -d +ExecStart=/opt/photoprism/bin/photoprism --config-path /var/lib/photoprism/ up -d ExecStop=/opt/photoprism/bin/photoprism down [Install] From ee6b092866529e366e132bce1e8583ea5b9f5767 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 07:10:31 -0400 Subject: [PATCH 3336/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 72190169..39664570 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -83,8 +83,8 @@ apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Golang" -wget https://golang.org/dl/go1.18.3.linux-amd64.tar.gz &>/dev/null -tar -xzf go1.18.3.linux-amd64.tar.gz -C /usr/local &>/dev/null +wget https://golang.org/dl/go1.18.4.linux-amd64.tar.gz &>/dev/null +tar -xzf go1.18.4.linux-amd64.tar.gz -C /usr/local &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null go install github.com/tianon/gosu@latest &>/dev/null go install golang.org/x/tools/cmd/goimports@latest &>/dev/null @@ -97,7 +97,6 @@ cp /usr/local/go/bin/richgo /usr/local/bin/richgo cp /usr/local/go/bin/gosu /usr/local/sbin/gosu chown root:root /usr/local/sbin/gosu chmod 755 /usr/local/sbin/gosu -rm go1.18.3.linux-amd64.tar.gz msg_ok "Installed Golang" msg_info "Installing Tensorflow" @@ -112,7 +111,6 @@ if [[ "$AVX" =~ avx2 ]]; then tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null fi ldconfig &>/dev/null -rm libtensorflow-linux-avx2-1.15.2.tar.gz msg_ok "Installed Tensorflow" msg_info "Cloning PhotoPrism" @@ -123,7 +121,7 @@ cd photoprism git checkout release &>/dev/null msg_ok "Cloned PhotoPrism" -msg_info "Building PhotoPrism" +msg_info "Building PhotoPrism (Patience)" NODE_OPTIONS=--max_old_space_size=2048 make all &>/dev/null ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null cp -a assets/ /opt/photoprism/assets/ &>/dev/null @@ -141,6 +139,7 @@ StoragePath: /var/lib/photoprism/storage OriginalsPath: /var/lib/photoprism/photos/Originals ImportPath: /var/lib/photoprism/photos/Import EOF + msg_info "Creating Service" service_path="/etc/systemd/system/photoprism.service" @@ -157,7 +156,6 @@ ExecStop=/opt/photoprism/bin/photoprism down [Install] WantedBy=multi-user.target" > $service_path -systemctl enable --now photoprism &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -181,5 +179,6 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +rm -rf /var/{cache,log}/* /root/go1.18.4.linux-amd64.tar.gz /root/libtensorflow-linux-avx2-1.15.2.tar.gz /root/libtensorflow-linux-avx-1.15.2.tar.gz /root/libtensorflow-linux-cpu-1.15.2.tar.gz +systemctl enable --now photoprism &>/dev/null msg_ok "Cleaned" From 0ba075e9236c0ffe4ed3fe52cec343f0c2fd7ec7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 11:59:03 -0400 Subject: [PATCH 3337/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 39664570..758d1db8 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -60,7 +60,7 @@ apt update &>/dev/null apt-get -qqy upgrade &>/dev/null msg_ok "Updated Container OS" -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y gcc &>/dev/null @@ -82,7 +82,7 @@ msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" -msg_info "Installing Golang" +msg_info "Installing Golang (Patience)" wget https://golang.org/dl/go1.18.4.linux-amd64.tar.gz &>/dev/null tar -xzf go1.18.4.linux-amd64.tar.gz -C /usr/local &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null @@ -179,6 +179,10 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /root/go1.18.4.linux-amd64.tar.gz /root/libtensorflow-linux-avx2-1.15.2.tar.gz /root/libtensorflow-linux-avx-1.15.2.tar.gz /root/libtensorflow-linux-cpu-1.15.2.tar.gz +rm -rf /var/{cache,log}/* \ +/go1.18.4.linux-amd64.tar.gz \ +/libtensorflow-linux-avx2-1.15.2.tar.gz \ +/libtensorflow-linux-avx-1.15.2.tar.gz \ +/libtensorflow-linux-cpu-1.15.2.tar.gz systemctl enable --now photoprism &>/dev/null msg_ok "Cleaned" From 84528b901564a24360155d8bbc38d99667c93f1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 12:40:47 -0400 Subject: [PATCH 3338/6505] Update README.md --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README.md b/README.md index 4aae6cb2..1f6b159c 100644 --- a/README.md +++ b/README.md @@ -1641,7 +1641,48 @@ Search: `DAEMON Sync` in your favorite app store __________________________________________________________________________________________
    + +
    + 🔸PhotoPrism LXC +

    + +

    PhotoPrism LXC

    + +[PhotoPrism](https://photoprism.app/) is an AI-powered app for browsing, organizing & sharing your photo collection. + +To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**PhotoPrism Interface - IP:2342** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + changeme + ``` +[PhotoSync](https://www.photosync-app.com/home.html) + +⚙️ **To Update PhotoPrism** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/photoprism-update.sh)" +``` +____________________________________________________________________________________________ + +
    +
    MotionEye VMS LXC From 2246589610405ba02ca92e36337c273728e5836a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 12:45:30 -0400 Subject: [PATCH 3339/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c7cea0e3..a50fdf58 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-19 + +### Changed + +- **PhotoPrism LXC** + - Fixed .env bug Thanks @cklam2 + ## 2022-08-13 ### Changed From 9884852326bb17fd08fc0cd3d61f1837df88382d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 12:54:52 -0400 Subject: [PATCH 3340/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a50fdf58..79846468 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **PhotoPrism LXC** - - Fixed .env bug Thanks @cklam2 + - Fixed .env bug (Thanks @cklam2) ## 2022-08-13 From cb0576e67e1e6a1bdecaa62ddb1edcd0844f1ea3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 15:13:03 -0400 Subject: [PATCH 3341/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 758d1db8..da489df7 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -56,8 +56,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies (Patience)" @@ -75,7 +75,7 @@ apt-get install -y ffmpeg &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null +curl -sL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" @@ -127,18 +127,16 @@ NODE_OPTIONS=--max_old_space_size=2048 make all &>/dev/null cp -a assets/ /opt/photoprism/assets/ &>/dev/null msg_ok "Built PhotoPrism" -cat < /var/lib/photoprism/options.yml -# Authentication -AuthMode: password -AdminPassword: changeme -# Listening address/port -HttpPort: 2342 -HttpHost: 0.0.0.0 -# Paths -StoragePath: /var/lib/photoprism/storage -OriginalsPath: /var/lib/photoprism/photos/Originals -ImportPath: /var/lib/photoprism/photos/Import -EOF +env_path="/var/lib/photoprism/.env" +echo " +PHOTOPRISM_AUTH_MODE='password' +PHOTOPRISM_ADMIN_PASSWORD='changeme' +PHOTOPRISM_HTTP_HOST='0.0.0.0' +PHOTOPRISM_HTTP_PORT='2342' +PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' +PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' +PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' +" > $env_path msg_info "Creating Service" service_path="/etc/systemd/system/photoprism.service" @@ -151,7 +149,8 @@ After=network.target Type=forking User=root WorkingDirectory=/opt/photoprism -ExecStart=/opt/photoprism/bin/photoprism --config-path /var/lib/photoprism/ up -d +EnvironmentFile=/var/lib/photoprism/.env +ExecStart=/opt/photoprism/bin/photoprism up -d ExecStop=/opt/photoprism/bin/photoprism down [Install] From e4ddc8fc0c37f0067f1fef3f76374f69a22867f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 16:08:49 -0400 Subject: [PATCH 3342/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index da489df7..883be3a3 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -179,9 +179,13 @@ msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* \ +/photoprism \ /go1.18.4.linux-amd64.tar.gz \ /libtensorflow-linux-avx2-1.15.2.tar.gz \ /libtensorflow-linux-avx-1.15.2.tar.gz \ /libtensorflow-linux-cpu-1.15.2.tar.gz -systemctl enable --now photoprism &>/dev/null msg_ok "Cleaned" + +msg_info "Starting PhotoPrism" +systemctl enable --now photoprism &>/dev/null +msg_info "Started PhotoPrism" From f50d5890a29ecc60b03fbf403169411f5793a4da Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 16:23:42 -0400 Subject: [PATCH 3343/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 883be3a3..73f42e95 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -133,6 +133,7 @@ PHOTOPRISM_AUTH_MODE='password' PHOTOPRISM_ADMIN_PASSWORD='changeme' PHOTOPRISM_HTTP_HOST='0.0.0.0' PHOTOPRISM_HTTP_PORT='2342' +PHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/' PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' From 75a78e38cd3fcd3c4dabfb17fb0fd8e304952060 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 16:42:14 -0400 Subject: [PATCH 3344/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f6b159c..275d6551 100644 --- a/README.md +++ b/README.md @@ -1673,7 +1673,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v ``` [PhotoSync](https://www.photosync-app.com/home.html) -⚙️ **To Update PhotoPrism** +⚙️ **To Update or Change Branch** Run in the LXC Console ```yaml From 742d903ad1fe8c9790d8b9fddf7d3eff0369dadb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 16:59:59 -0400 Subject: [PATCH 3345/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 73f42e95..9cebf0d8 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -189,4 +189,4 @@ msg_ok "Cleaned" msg_info "Starting PhotoPrism" systemctl enable --now photoprism &>/dev/null -msg_info "Started PhotoPrism" +msg_ok "Started PhotoPrism" From f0b995e4ee1f0868338dc2e5e95af6463b718f01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 17:03:19 -0400 Subject: [PATCH 3346/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 9cebf0d8..b703e80a 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -189,4 +189,3 @@ msg_ok "Cleaned" msg_info "Starting PhotoPrism" systemctl enable --now photoprism &>/dev/null -msg_ok "Started PhotoPrism" From 79ce387391c746b065d5cc0e031fdf2ed921b20b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Aug 2022 17:09:38 -0400 Subject: [PATCH 3347/6505] Create mikrotik-routeros-v4.sh --- vm/mikrotik-routeros-v4.sh | 261 +++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 vm/mikrotik-routeros-v4.sh diff --git a/vm/mikrotik-routeros-v4.sh b/vm/mikrotik-routeros-v4.sh new file mode 100644 index 00000000..848a505c --- /dev/null +++ b/vm/mikrotik-routeros-v4.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env bash +echo -e "Loading..." +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +NEXTID=$(pvesh get /cluster/nextid) +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +HA=`echo "\033[1;34m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: 7.XX" + echo "Exiting..." + sleep 3 + exit +fi +if (whiptail --title "Mikrotik RouterOS VM" --yesno "This will create a New Mikrotik RouterOS VM. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${RD} + __ ____ __ __ _ __ ____ __ ____ _____ + / |/ (_) /___________ / /_(_) /__ / __ \____ __ __/ /____ _____/ __ \/ ___/ + / /|_/ / / //_/ ___/ __ \/ __/ / //_/ / /_/ / __ \/ / / / __/ _ \/ ___/ / / /\__ \ + / / / / / < / / / /_/ / /_/ / < v4 / _ _/ /_/ / /_/ / /_/ __/ / / /_/ /___/ / +/_/ /_/_/_/|_/_/ \____/\__/_/_/|_| /_/ |_|\____/\__,_/\__/\___/_/ \____//____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function default_settings() { + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}mikrotik-routeros${CL}" + HN=mikrotik-routeros + echo -e "${DGN}Allocated Cores: ${BGN}1${CL}" + CORE_COUNT="1" + echo -e "${DGN}Allocated RAM: ${BGN}1024${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + echo -e "${BL}Creating a Mikrotik RouterOS VM using the above default settings${CL}" +} +function advanced_settings() { +VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" +else + exit +fi +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 Mikrotik-RouterOS --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + exit +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS VM when completed?" 10 58); then + echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}yes${CL}" + START_VM="yes" +else + echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}no${CL}" + START_VM="no" +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create Mikrotik RouterOS VM?" 10 58); then + echo -e "${RD}Creating Mikrotik RouterOS VM using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +start_script +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi +STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" + echo -e "Exiting..." + exit +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the Mikrotik RouterOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Getting URL for Mikrotik RouterOS Disk Image" + +URL=https://download.mikrotik.com/routeros/7.4.1/install-image-7.4.1.zip + +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}$FILE${CL}" +msg_info "Extracting Mikrotik RouterOS Disk Image" +gunzip -f -S .zip $FILE +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; + btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_FORMAT="subvol" + DISK_IMPORT="-format raw" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +msg_ok "Extracted Mikrotik RouterOS Disk Image" +msg_info "Creating Mikrotik RouterOS VM" +qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ + -scsi0 ${DISK1_REF},size=2G >/dev/null +qm set $VMID \ + -boot order=scsi0 >/dev/null +qm set $VMID -description "# Mikrotik RouterOS +### https://github.com/tteck/Proxmox" >/dev/null +msg_ok "Mikrotik RouterOS VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then +msg_info "Starting Mikrotik RouterOS VM" +qm start $VMID +msg_ok "Started Mikrotik RouterOS VM" +fi +msg_ok "Completed Successfully!\n" From 0604f6feeb8171045fb0e098b9dd3ab050de73a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Aug 2022 07:36:35 -0400 Subject: [PATCH 3348/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 275d6551..49c0425d 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant OS VM + Home Assistant OS VM

    From 531dede13ae26e22b97e08c50e8d9f7ffa250a86 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Aug 2022 12:46:48 -0400 Subject: [PATCH 3349/6505] Update post-install.sh --- misc/post-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/post-install.sh b/misc/post-install.sh index b88fe3b2..14c0dcc2 100644 --- a/misc/post-install.sh +++ b/misc/post-install.sh @@ -107,11 +107,11 @@ fi read -r -p "Update Proxmox VE 7 now? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then -msg_info "Updating Proxmox VE 7" +msg_info "Updating Proxmox VE 7 (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null -msg_ok "Updated Proxmox VE 7 (Reboot Recommended)" +msg_ok "Updated Proxmox VE 7 (⚠ Reboot Recommended)" fi sleep 2 -msg_ok "Finished Post Install Routines" +msg_ok "Completed Post Install Routines" From dbd238cd64a3cc922bd83c57bd43fda621ceba82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Aug 2022 14:53:51 -0400 Subject: [PATCH 3350/6505] Update keycloak-install.sh --- setup/keycloak-install.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index b593459c..7d155d9f 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -55,21 +55,25 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y openjdk-11-jdk &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing Keycloak" +RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 2, length($2)-3) }') \ + +msg_info "Installing Keycloak v$RELEASE" cd /opt -wget https://github.com/keycloak/keycloak/releases/download/18.0.0/keycloak-18.0.0.tar.gz &>/dev/null -tar -xvf keycloak-18.0.0.tar.gz &>/dev/null -mv keycloak-18.0.0 keycloak +wget https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz &>/dev/null +tar -xvf keycloak-$RELEASE.tar.gz &>/dev/null +mv keycloak-$RELEASE keycloak msg_ok "Installed Keycloak" msg_info "Creating Service" From def4a71f47cb30f82cb7b5f7b8019c30c375fe20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Aug 2022 17:16:40 -0400 Subject: [PATCH 3351/6505] Update README.md --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 49c0425d..8651a8c0 100644 --- a/README.md +++ b/README.md @@ -1976,6 +1976,28 @@ ________________________________________________________________________________
    +
    + 🔸Mikrotik RouterOS VM + +

    + +

    Mikrotik RouterOS VM

    + +[Mikrotik RouterOS](https://wiki.mikrotik.com/wiki/Manual:TOC) can be installed on a PC and will turn it into a router with all the necessary features - routing, firewall, bandwidth management, wireless access point, backhaul link, hotspot gateway, VPN server and more. + +To create a new Proxmox Mikrotik RouterOS VM, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mikrotik-routeros-v4.sh.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1CPU ⚡

    + + +____________________________________________________________________________________________ + +
    +
    Vaultwarden LXC From f957994ddd141b0b8b679cce344f8a9e7b902b79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Aug 2022 17:18:11 -0400 Subject: [PATCH 3352/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 79846468..acec539e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-20 + +### Changed + +- **Mikrotik RouterOS VM** + - NEW Script + ## 2022-08-19 ### Changed From aa428ffcab32f6cd718ba249c1d008cff7199e13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Aug 2022 06:42:56 -0400 Subject: [PATCH 3353/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8651a8c0..c5be8c19 100644 --- a/README.md +++ b/README.md @@ -1990,6 +1990,7 @@ To create a new Proxmox Mikrotik RouterOS VM, run the following in the Proxmox S ``` bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mikrotik-routeros-v4.sh.sh)" ``` +Setup is done via VM console.

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1CPU ⚡

    From 0849ab2330792f5cdc58791fd2b6555b691394f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 08:49:58 -0400 Subject: [PATCH 3354/6505] Create wikijs-v4.sh --- ct/wikijs-v4.sh | 265 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 ct/wikijs-v4.sh diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh new file mode 100644 index 00000000..99f794fd --- /dev/null +++ b/ct/wikijs-v4.sh @@ -0,0 +1,265 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Wikijs" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${BL} + _ ___ __ _ _ +| | / (_) /__(_) (_)____ +| | /| / / / //_/ / / / ___/ +| |/ |/ / / ,< / / / (__ ) +|__/|__/_/_/|_/_(_)_/ /____/ + /___/ v4 +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 41b4c1f56e21048b99f9fc698358107e99284f7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 08:51:00 -0400 Subject: [PATCH 3355/6505] Create wikijs-install.sh --- setup/wikijs-install.sh | 138 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 setup/wikijs-install.sh diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh new file mode 100644 index 00000000..baa71eb0 --- /dev/null +++ b/setup/wikijs-install.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +curl -sL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Installing Wiki.js" +mkdir -p /opt/wikijs +cd /opt/wikijs +wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz &>/dev/null +tar xzf wiki-js.tar.gz +rm wiki-js.tar.gz + +cat < /opt/wikijs/config.yml +bindIP: 0.0.0.0 +port: 3000 +db: + type: sqlite + storage: /opt/wikijs/db.sqlite +logLevel: info +logFormat: default +dataPath: /opt/wikijs/data +bodyParserLimit: 5mb +EOF +npm rebuild sqlite3 &>/dev/null +msg_ok "Installed Wiki.js" + +msg_info "Creating Service" +service_path="/etc/systemd/system/wikijs.service" + +echo "[Unit] +Description=Wiki.js +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/node server +Restart=always +User=root +Environment=NODE_ENV=production +WorkingDirectory=/opt/wikijs + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now wikijs &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 3ee91ed75b083f2ce0dcccd6c4427cf03a8c341d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 08:52:00 -0400 Subject: [PATCH 3356/6505] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index c5be8c19..cee0e5fd 100644 --- a/README.md +++ b/README.md @@ -1481,6 +1481,29 @@ ________________________________________________________________________________
    +
    + 🔸Wiki.js LXC + +

    + +

    Wiki.js LXC

    + +[Wiki.js](https://js.wiki/) is a modern, lightweight and powerful wiki app built on NodeJS. + +To create a new Proxmox Wiki.js LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wikijs-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Wiki.js Interface - IP:3000** + +____________________________________________________________________________________________ + +
    +
    Heimdall Dashboard LXC From af9af711db852d8378af55e0833bb13005fee06b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 09:03:47 -0400 Subject: [PATCH 3357/6505] Update wikijs-v4.sh --- ct/wikijs-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index 99f794fd..32df8a0d 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -258,7 +258,7 @@ pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} ${var_version} LXC +pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. From 18dece6f2d26744e1d87ea47e61ee1e4e4149b67 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 09:08:03 -0400 Subject: [PATCH 3358/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index acec539e..78fdd7cd 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-22 + +### Changed + +- **Wiki.js LXC** + - NEW Script + ## 2022-08-20 ### Changed From b68d7ba3df34bfe14a6457f0bf50a6ce771f63be Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 15:41:16 -0400 Subject: [PATCH 3359/6505] Create emby-install.sh --- setup/emby-install.sh | 105 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 setup/emby-install.sh diff --git a/setup/emby-install.sh b/setup/emby-install.sh new file mode 100644 index 00000000..ff07541f --- /dev/null +++ b/setup/emby-install.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +msg_info "Updating Container OS" +apt update &>/dev/null +apt-get -qqy upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting Up Hardware Acceleration" +apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd &>/dev/null + +/bin/chgrp video /dev/dri +/bin/chmod 755 /dev/dri +/bin/chmod 660 /dev/dri/* +msg_ok "Set Up Hardware Acceleration" + +msg_info "Installing Emby" +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.7.6.0/emby-server-deb_4.7.6.0_amd64.deb &>/dev/null +dpkg -i emby-server-deb_4.7.6.0_amd64.deb &>/dev/null +apt-get install -y ffmpeg &>/dev/null +msg_ok "Installed Emby" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 38e502aaa8f701598a532cad762999be37741925 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 15:43:38 -0400 Subject: [PATCH 3360/6505] Create emby-v4.sh --- ct/emby-v4.sh | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 ct/emby-v4.sh diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh new file mode 100644 index 00000000..ed9c62b4 --- /dev/null +++ b/ct/emby-v4.sh @@ -0,0 +1,277 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Emby" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +echo -e "${DGN} + ______ __ + / ____/___ v4_ / /_ __ __ + / __/ / __ __ \/ __ \/ / / / + / /___/ / / / / / /_/ / /_/ / +/_____/_/ /_/ /_/_.___/\__, / + /____/ +${CL}" +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +"18.04" "Bionic" OFF \ +"20.04" "Focal" ON \ +"21.10" "Impish" OFF \ +"22.04" "Jammy" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8096${CL}\n" From 2c0f36b42465b5c094c1d9ec0b49b2b8764cd36f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 15:44:16 -0400 Subject: [PATCH 3361/6505] Update README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index cee0e5fd..3b6169f1 100644 --- a/README.md +++ b/README.md @@ -1306,6 +1306,30 @@ ________________________________________________________________________________
    +
    + 🔸Emby Media Server LXC +

    +

    Emby Media Server LXC

    + +To create a new Proxmox Emby Media Server LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**Emby Media Server Interface - IP:8096** + +⚙️ **To Update Emby Media Server** + +Run in the LXC console +```yaml + +``` +____________________________________________________________________________________________ + +
    +
    Jellyfin Media Server LXC

    From d99fbb45611fed17356ad4be9bc63bc604337a4b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 15:46:23 -0400 Subject: [PATCH 3362/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 78fdd7cd..83a0040f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **Wiki.js LXC** - NEW Script +- **Emby Media Server LXC** + - NEW Script ## 2022-08-20 From 3437c136a9bb23dc966049ba237afa753b62e60c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 15:55:34 -0400 Subject: [PATCH 3363/6505] Update README.md --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 3b6169f1..6cbdc313 100644 --- a/README.md +++ b/README.md @@ -1320,12 +1320,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" **Emby Media Server Interface - IP:8096** -⚙️ **To Update Emby Media Server** +⚙️ **Emby Media Server Uses Automatic Updates** -Run in the LXC console -```yaml - -``` ____________________________________________________________________________________________
    From ef0180298d28002ea8768426ffbc34ab4dbdf2db Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Aug 2022 15:57:22 -0400 Subject: [PATCH 3364/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6cbdc313..480c9c22 100644 --- a/README.md +++ b/README.md @@ -1320,7 +1320,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" **Emby Media Server Interface - IP:8096** -⚙️ **Emby Media Server Uses Automatic Updates** +⚙️ **Emby Media Server Utilizes Automatic Updates** ____________________________________________________________________________________________ From ac18ede76b95aa402d905268ba9aa679d754cdcc Mon Sep 17 00:00:00 2001 From: chpego <38792705+chpego@users.noreply.github.com> Date: Mon, 22 Aug 2022 22:11:05 +0200 Subject: [PATCH 3365/6505] generate a new token admin (#446) --- setup/vaultwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index ec4da4f3..5b994967 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -106,7 +106,7 @@ msg_ok "Downloaded Web-Vault ${WEBVAULT}" cat < /opt/vaultwarden/.env ## https://github.com/dani-garcia/vaultwarden/blob/main/.env.template -# ADMIN_TOKEN=Vy2VyYTTsKPv8W5aEOWUbB/Bt3DEKePbHmI4m9VcemUMS2rEviDowNAFqYi1xjmp +# ADMIN_TOKEN=$(openssl rand -base64 48) ROCKET_ADDRESS=0.0.0.0 DATA_FOLDER=/opt/vaultwarden/data DATABASE_MAX_CONNS=10 From d93c146b87e4fde47d86b11d32984817cfada295 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 08:36:08 -0400 Subject: [PATCH 3366/6505] v5.5.6 --- setup/omada-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index c52bc085..6a7c930f 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -69,9 +69,9 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing Omada Controller v5.4.6" -wget -qL https://static.tp-link.com/upload/software/2022/202207/20220729/Omada_SDN_Controller_v5.4.6_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.4.6_Linux_x64.deb &>/dev/null +msg_info "Installing Omada Controller v5.5.6" +wget -qL https://static.tp-link.com/upload/software/2022/202208/20220822/Omada_SDN_Controller_v5.5.6_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.5.6_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6); From f15190ebd4ab734bd6f8d15b14f69ebeb7b92139 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 08:59:43 -0400 Subject: [PATCH 3367/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 5b994967..897f7ca5 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -74,11 +74,11 @@ msg_ok "Installed Dependencies" WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ | grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ +| awk '{print substr($2, 2, length($2)-3) }') VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest \ | grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ +| awk '{print substr($2, 2, length($2)-3) }') msg_info "Installing Rust" curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal &>/dev/null From bedb9f650c01d572b291df4270d93c796f2912d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 09:04:51 -0400 Subject: [PATCH 3368/6505] Update vaultwarden-update.sh --- misc/vaultwarden-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index b645e810..91159e1b 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest \ | grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ +| awk '{print substr($2, 2, length($2)-3) }') RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 0a8ec7f066ad1f846c2c8c8b1c2f7eab51f638f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 09:05:18 -0400 Subject: [PATCH 3369/6505] Update web-vault-update.sh --- misc/web-vault-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/web-vault-update.sh b/misc/web-vault-update.sh index d55b0aeb..a6b5eaf8 100644 --- a/misc/web-vault-update.sh +++ b/misc/web-vault-update.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ | grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ +| awk '{print substr($2, 2, length($2)-3) }') RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` From 36cfc3043b6159bc489516fc7fbf1c3a36deab0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 10:46:07 -0400 Subject: [PATCH 3370/6505] Update vaultwarden-install.sh --- setup/vaultwarden-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 897f7ca5..81ca2b28 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -105,8 +105,7 @@ tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ &>/dev/null msg_ok "Downloaded Web-Vault ${WEBVAULT}" cat < /opt/vaultwarden/.env -## https://github.com/dani-garcia/vaultwarden/blob/main/.env.template -# ADMIN_TOKEN=$(openssl rand -base64 48) +ADMIN_TOKEN=$(openssl rand -base64 48) ROCKET_ADDRESS=0.0.0.0 DATA_FOLDER=/opt/vaultwarden/data DATABASE_MAX_CONNS=10 From 3caf5fb5bde5bb4c9e1d2d7d675ce93016f5f8f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 10:47:17 -0400 Subject: [PATCH 3371/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 480c9c22..31685268 100644 --- a/README.md +++ b/README.md @@ -2066,7 +2066,7 @@ Expect 30+ minute install time. **Vaultwarden Interface: CTIP:8000** -⚙️ **Path to Vaultwarden .env file** (to enable `ADMIN_TOKEN`) +⚙️ **Path to Vaultwarden .env file** (to find the `ADMIN_TOKEN`) ```yaml /opt/vaultwarden/.env ``` From b11d161c30f7a051966c7c878386afcb7cba076f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 13:28:14 -0400 Subject: [PATCH 3372/6505] Update docker-install.sh --- setup/docker-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index aec07703..3ee63673 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -83,7 +83,7 @@ EOF sh <(curl -sSL https://get.docker.com) &>/dev/null msg_ok "Installed Docker $DOCKER_LATEST_VERSION" -read -r -p "Would you like to add Portainer? " prompt +read -r -p "Would you like to add Portainer? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then PORTAINER="Y" @@ -105,7 +105,7 @@ docker run -d \ msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" fi -read -r -p "Would you like to add Docker Compose? " prompt +read -r -p "Would you like to add Docker Compose? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then DOCKER_COMPOSE="Y" From 3cce666e4c2d1a4cd9012bd61bff64d79139d209 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 13:57:59 -0400 Subject: [PATCH 3373/6505] Update docker-install.sh --- setup/docker-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 3ee63673..f5ccbb05 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -83,7 +83,7 @@ EOF sh <(curl -sSL https://get.docker.com) &>/dev/null msg_ok "Installed Docker $DOCKER_LATEST_VERSION" -read -r -p "Would you like to add Portainer? " prompt +read -r -p "Would you like to add Portainer? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then PORTAINER="Y" @@ -105,7 +105,7 @@ docker run -d \ msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" fi -read -r -p "Would you like to add Docker Compose? " prompt +read -r -p "Would you like to add Docker Compose? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then DOCKER_COMPOSE="Y" From 08b41260228853fdd783af865851e4f2b0af00f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 20:53:10 -0400 Subject: [PATCH 3374/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 31685268..118331c3 100644 --- a/README.md +++ b/README.md @@ -1311,6 +1311,8 @@ ________________________________________________________________________________

    Emby Media Server LXC

    +[Emby](https://emby.media/) brings together your personal videos, music, photos, and live television. + To create a new Proxmox Emby Media Server LXC, run the following in the Proxmox Shell. ```yaml From 4a5a609e26237e42826fa6fada88278a7c9d6412 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Aug 2022 21:37:12 -0400 Subject: [PATCH 3375/6505] Update post-install.sh --- misc/post-install.sh | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/misc/post-install.sh b/misc/post-install.sh index 14c0dcc2..73c32268 100644 --- a/misc/post-install.sh +++ b/misc/post-install.sh @@ -12,8 +12,8 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" - -echo -e "\e[1;33m This script will Perform Post Install Routines. PVE7 ONLY \e[0m" +clear +echo -e "${BL}This script will Perform Post Install Routines.${CL}" while true; do read -p "Start the PVE7 Post Install Script (y/n)?" yn case $yn in @@ -23,11 +23,11 @@ while true; do esac done if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: 7.XX" - echo "Exiting..." - sleep 3 - exit + echo -e "\n${RD}⚠ This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version: 7.XX${CL}" + echo -e "\nExiting..." + sleep 3 + exit fi function header_info { echo -e "${RD} @@ -51,7 +51,7 @@ function msg_ok() { clear header_info -read -r -p "Disable Enterprise Repository? " prompt +read -r -p "Disable Enterprise Repository? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Disabling Enterprise Repository" @@ -60,7 +60,7 @@ sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list msg_ok "Disabled Enterprise Repository" fi -read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt +read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Adding or Correcting PVE7 Sources" @@ -73,7 +73,7 @@ sleep 2 msg_ok "Added or Corrected PVE7 Sources" fi -read -r -p "Enable No-Subscription Repository? " prompt +read -r -p "Enable No-Subscription Repository? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Enabling No-Subscription Repository" @@ -84,7 +84,7 @@ sleep 2 msg_ok "Enabled No-Subscription Repository" fi -read -r -p "Add (Disabled) Beta/Test Repository? " prompt +read -r -p "Add (Disabled) Beta/Test Repository? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Adding Beta/Test Repository and set disabled" @@ -95,7 +95,7 @@ sleep 2 msg_ok "Added Beta/Test Repository" fi -read -r -p "Disable Subscription Nag? " prompt +read -r -p "Disable Subscription Nag? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Disabling Subscription Nag" @@ -104,7 +104,7 @@ apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag" fi -read -r -p "Update Proxmox VE 7 now? " prompt +read -r -p "Update Proxmox VE 7 now? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] then msg_info "Updating Proxmox VE 7 (Patience)" @@ -113,5 +113,14 @@ apt-get -y dist-upgrade &>/dev/null msg_ok "Updated Proxmox VE 7 (⚠ Reboot Recommended)" fi +read -r -p "Reboot Proxmox VE 7 now? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Rebooting Proxmox VE 7" +sleep 2 +msg_ok "Completed Post Install Routines" +reboot +fi + sleep 2 msg_ok "Completed Post Install Routines" From dd4c9f2f1f21a0bb1944a3cdb3ead5bce1b96d18 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Aug 2022 17:53:53 -0400 Subject: [PATCH 3376/6505] Update emby-install.sh --- setup/emby-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/emby-install.sh b/setup/emby-install.sh index ff07541f..d8c52828 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -75,10 +75,11 @@ apt-get -y install \ /bin/chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" +LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) + msg_info "Installing Emby" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.7.6.0/emby-server-deb_4.7.6.0_amd64.deb &>/dev/null -dpkg -i emby-server-deb_4.7.6.0_amd64.deb &>/dev/null -apt-get install -y ffmpeg &>/dev/null +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null +dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null msg_ok "Installed Emby" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 31df60631d9b8398f60ccd080707e1b2981cc0ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Aug 2022 14:55:31 -0400 Subject: [PATCH 3377/6505] Update haos_vm.sh --- vm/haos_vm.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 9acaeb70..40a34f64 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -49,8 +49,9 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if [ `pveversion | grep "pve-manager/7" | wc -l` -eq 1 ]; then echo -e "${YW}This script is for Proxmox Virtual Environment 6.xx${CL}" - echo -e "Continuing..." - sleep 3 + echo "Exiting..." + sleep 3 + exit fi if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then echo "User selected Yes" From 71c0880e0da8670404e98426d63667e400288d14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Aug 2022 14:59:47 -0400 Subject: [PATCH 3378/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 40a34f64..3c7abfbf 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -48,7 +48,7 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if [ `pveversion | grep "pve-manager/7" | wc -l` -eq 1 ]; then - echo -e "${YW}This script is for Proxmox Virtual Environment 6.xx${CL}" + echo -e "\n🚨 ${RD}This script is for Proxmox Virtual Environment 6.xx${CL}\n" echo "Exiting..." sleep 3 exit From 0a6820f6c269207533d5a0f18d78ca7a2e103d4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Aug 2022 15:02:28 -0400 Subject: [PATCH 3379/6505] Update haos_vm.sh --- vm/haos_vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh index 3c7abfbf..5f204f69 100644 --- a/vm/haos_vm.sh +++ b/vm/haos_vm.sh @@ -48,7 +48,7 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if [ `pveversion | grep "pve-manager/7" | wc -l` -eq 1 ]; then - echo -e "\n🚨 ${RD}This script is for Proxmox Virtual Environment 6.xx${CL}\n" + echo -e "\n🚨 ${RD} This script is for Proxmox Virtual Environment 6.xx${CL}\n" echo "Exiting..." sleep 3 exit From 6ab155763cbdfa792acdf289b7c171c0cd76b1a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Aug 2022 23:10:45 -0400 Subject: [PATCH 3380/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 118331c3..1cbffbdb 100644 --- a/README.md +++ b/README.md @@ -1688,7 +1688,7 @@ ________________________________________________________________________________
    - 🔸PhotoPrism LXC + PhotoPrism LXC

    From 5b869e1ae7d8c25e2c67e0f6169062e7f68e09f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Aug 2022 09:56:01 -0400 Subject: [PATCH 3381/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cbffbdb..d2aa49b2 100644 --- a/README.md +++ b/README.md @@ -2033,7 +2033,7 @@ ________________________________________________________________________________ To create a new Proxmox Mikrotik RouterOS VM, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mikrotik-routeros-v4.sh.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mikrotik-routeros-v4.sh)" ``` Setup is done via VM console. From 4c44097d9811e210d082c6d6e9aedf4229c71602 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Aug 2022 10:58:47 -0400 Subject: [PATCH 3382/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d2aa49b2..a9f295e4 100644 --- a/README.md +++ b/README.md @@ -2033,7 +2033,7 @@ ________________________________________________________________________________ To create a new Proxmox Mikrotik RouterOS VM, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mikrotik-routeros-v4.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/mikrotik-routeros-v4.sh)" ``` Setup is done via VM console. From 02c4dc5d282c044a69287acebc5893d5f7fcceb5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Aug 2022 01:58:17 -0400 Subject: [PATCH 3383/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9f295e4..7032171b 100644 --- a/README.md +++ b/README.md @@ -2022,7 +2022,7 @@ ________________________________________________________________________________
    - 🔸Mikrotik RouterOS VM + Mikrotik RouterOS VM

    From 38295ed54dddeac46e5cea5d31617432455c0261 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Aug 2022 16:25:22 -0400 Subject: [PATCH 3384/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7032171b..6eeda68b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@

    Proxmox VE 7 Post Install

    -The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag and Update Proxmox VE. +The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox VE and Reboot PVE. Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** From 258f48003bdd03f165edab7450883685549d813e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Aug 2022 00:28:31 -0400 Subject: [PATCH 3385/6505] Update create_lxc.sh --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 4cb7864e..82269485 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -33,7 +33,7 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } - +msg_info "Validating Storage" function select_storage() { local CLASS=$1 local CONTENT From 12271b69d757db0f36c6102083eaed954ab9b937 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Aug 2022 08:28:22 -0400 Subject: [PATCH 3386/6505] Update edge-kernel.sh --- misc/edge-kernel.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index e4c37235..69d58d40 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -25,7 +25,7 @@ show_menu(){ proxmox-boot-tool kernel list echo -e "\nCurrent Kernel: ${menu}${KERNEL_ON}${normal}" printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Install Proxmox 5.18 Edge Kernel & Reboot\n" + printf "${menu}**${number} 1)${normal} Install Proxmox Edge Kernel & Reboot\n" printf "${menu}**${number} 2)${normal} Switch to Proxmox VE 7 ${menu}${PVE_KERNEL}${normal} Kernel & Reboot\n" printf "${menu}**${number} 3)${normal} Switch to Proxmox Edge ${menu}${EDGE_KERNEL}${normal} Kernel & Reboot\n" printf "${menu}**${number} 4)${normal} Unpin Current Kernel\n" @@ -49,7 +49,7 @@ while [ $opt != '' ] else case $opt in 1) while true; do - read -p "Are you sure you want to Install Proxmox 5.18 Edge Kernel & Reboot? Proceed(y/n)?" yn + read -p "Are you sure you want to Install Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -57,12 +57,12 @@ while [ $opt != '' ] esac done clear; - option_picked "Installing Proxmox 5.18 Edge Kernel & Rebooting"; + option_picked "Installing Proxmox Edge Kernel & Rebooting"; apt-get install -y gnupg curl -1sLf 'https://dl.cloudsmith.io/public/pve-edge/kernel/gpg.8EC01CCF309B98E7.key' | apt-key add - echo "deb https://dl.cloudsmith.io/public/pve-edge/kernel/deb/debian bullseye main" > /etc/apt/sources.list.d/pve-edge-kernel.list apt-get -y update - apt-get -y install pve-kernel-5.18-edge + apt-get -y install pve-kernel-5.19-edge reboot break; ;; From 12222e2bc50f61faf11f5e820488f83cfa04f10a Mon Sep 17 00:00:00 2001 From: Dustin <56093730+Dustin36@users.noreply.github.com> Date: Mon, 29 Aug 2022 01:34:07 +0200 Subject: [PATCH 3387/6505] Correct Spelling (#462) --- setup/homebridge-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 8ba3327f..0ff43cd8 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -72,9 +72,9 @@ msg_info "Installing Node.js" sudo apt-get install -y nodejs gcc g++ make python net-tools &>/dev/null msg_ok "Installed Node.js" -msg_info "nstalling Homebridge" +msg_info "Installing Homebridge" sudo npm install -g --unsafe-perm homebridge homebridge-config-ui-x &>/dev/null -msg_info "nstalled Homebridge" +msg_info "Installed Homebridge" msg_info "Creating Service" sudo hb-service install --user homebridge &>/dev/null From 4fda1984034f3dd83ca26c1a1578c099eefa07a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Aug 2022 22:14:46 -0400 Subject: [PATCH 3388/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6eeda68b..8c5ac4ce 100644 --- a/README.md +++ b/README.md @@ -1371,7 +1371,9 @@ To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v4.sh)" ```

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - + +⚠️ **Reboot Pi-hole LXC after install** + ⚙️ **To set your password:** Run in the LXC console From 88c9db5b6bd5e1fc03026593e47c0e4763d35612 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Aug 2022 08:35:37 -0400 Subject: [PATCH 3389/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c5ac4ce..ff28afc3 100644 --- a/README.md +++ b/README.md @@ -1307,7 +1307,7 @@ ________________________________________________________________________________
    - 🔸Emby Media Server LXC + Emby Media Server LXC

    Emby Media Server LXC

    @@ -1506,7 +1506,7 @@ ________________________________________________________________________________
    - 🔸Wiki.js LXC + Wiki.js LXC

    From 40897f22c56b11192b041e8402e030e109bf39d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Aug 2022 18:43:55 -0400 Subject: [PATCH 3390/6505] maintenance (#466) --- setup/adguard-install.sh | 4 ++-- setup/daemonsync-install.sh | 4 ++-- setup/dashy-install.sh | 4 ++-- setup/debian-install.sh | 4 ++-- setup/deconz-install.sh | 4 ++-- setup/docker-install.sh | 4 ++-- setup/emby-install.sh | 4 ++-- setup/esphome-install.sh | 4 ++-- setup/grafana-install.sh | 4 ++-- setup/grocy-install.sh | 4 ++-- setup/heimdalldashboard-install.sh | 4 ++-- setup/homeassistant-install.sh | 4 ++-- setup/homebridge-install.sh | 4 ++-- setup/influxdb-install.sh | 4 ++-- setup/iobroker-install.sh | 4 ++-- setup/jellyfin-install.sh | 4 ++-- setup/magicmirror-install.sh | 4 ++-- setup/mariadb-install.sh | 4 ++-- setup/meshcentral-install.sh | 4 ++-- setup/motioneye-install.sh | 4 ++-- setup/mqtt-install.sh | 4 ++-- setup/n8n-install.sh | 4 ++-- setup/nginx-proxy-manager-install.sh | 4 ++-- setup/nocodb-install.sh | 4 ++-- setup/node-red-install.sh | 4 ++-- setup/omada-install.sh | 4 ++-- setup/openhab-install.sh | 4 ++-- setup/pihole-install.sh | 2 +- setup/plex-install.sh | 4 ++-- setup/podman-homeassistant-install.sh | 4 ++-- setup/postgresql-install.sh | 2 +- setup/prometheus-install.sh | 4 ++-- setup/technitiumdns-install.sh | 4 ++-- setup/ubuntu-install.sh | 4 ++-- setup/unifi-install.sh | 4 ++-- setup/uptimekuma-install.sh | 4 ++-- setup/vaultwarden-install.sh | 4 ++-- setup/whoogle-install.sh | 4 ++-- setup/wikijs-install.sh | 4 ++-- setup/wireguard-install.sh | 4 ++-- setup/zigbee2mqtt-install.sh | 4 ++-- setup/zwavejs2mqtt-install.sh | 4 ++-- 42 files changed, 82 insertions(+), 82 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index fd8ff882..ba2c520b 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 2af9de0a..cd41862b 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 02039294..3a5746e9 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 48e7eb1f..299f9728 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index d38b416a..643e818e 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/docker-install.sh b/setup/docker-install.sh index f5ccbb05..8c65c7f5 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/emby-install.sh b/setup/emby-install.sh index d8c52828..63305ab4 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index e8c0c05a..ffb1ff5b 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 9eff5400..b1dbe1c8 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index de7bc523..7910ce7c 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 852068d8..1420ca67 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 8ee274bb..fe4c60fd 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 0ff43cd8..eae42a0e 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 216949e7..5f4fd34e 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 9db4f6d3..05bbfd36 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index dccddafe..d61151a5 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index 880f959a..0e80fb54 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 18db68da..a8e6b69b 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 485b352f..bdeb64b2 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 4b96cc31..a47c3841 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index fd52f630..6bfc4f04 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 09670422..282f6c6e 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index afa87e32..b2d01b5c 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 9e51d2e1..ee32e987 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 058fb297..f09cbc92 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 6a7c930f..c65a4104 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS (216 packages)" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index c4e69e18..3fa1e64b 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 0a47cc07..6ac189ad 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -56,7 +56,7 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" apt-get update &>/dev/null -apt-get -y dist-upgrade &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/plex-install.sh b/setup/plex-install.sh index c5030bc2..1b2d091c 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 43fd53b9..9f23fc47 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index c9cc2a7b..a37609b2 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -56,7 +56,7 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index e83fa5a0..5c0cfc1e 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 1a9e5271..9755d9e3 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 7173f364..c26130b6 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index f47cb3e3..0d1cecc3 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -56,8 +56,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 948ab37f..2e90fb3c 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 81ca2b28..699cdd4a 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -55,8 +55,8 @@ msg_ok "Setup Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index 52d65c56..dd79d68d 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index baa71eb0..a1bb4882 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 4804a3c6..1a0476e3 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -72,8 +72,8 @@ UNATTUPG=1 EOF msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 8056c2b6..2b109303 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index 06aabdda..c1fa407c 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -55,8 +55,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" msg_info "Updating Container OS" -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" msg_info "Installing Dependencies" From b21ce7b82eea091d8ec5e54b2e5e06fe6d743838 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Aug 2022 19:34:29 -0400 Subject: [PATCH 3391/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 59 ++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 1f9fa7cd..358b707b 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -16,6 +16,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -48,11 +49,11 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: 7.XX" - echo "Exiting..." - sleep 3 - exit + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: 7.XX" + echo "Exiting..." + sleep 3 + exit fi if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then echo "User selected Yes" @@ -79,26 +80,31 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + function default_settings() { - echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" - HN=haos${STABLE} - echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" - CORE_COUNT="2" - echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" - echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" + echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" + HN=haos${STABLE} + echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 3 \ @@ -210,9 +216,8 @@ STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content images | awk 'NR>1') VALID=$(pvesm status -content images | awk 'NR>1') if [ -z "$VALID" ]; then - echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" - echo -e "Exiting..." - exit +msg_error "Unable to detect a valid storage location." + exit elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else From 77f299cb0568c09c1192318d9599c9e94c3d1c54 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Aug 2022 20:22:03 -0400 Subject: [PATCH 3392/6505] Add network tools (#467) --- setup/debian-install.sh | 8 ++++++++ setup/ubuntu-install.sh | 13 +++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 299f9728..d738a621 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -37,6 +37,10 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen @@ -54,6 +58,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; fi; +RESOLVEDIP=$(nslookup "google.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index c26130b6..55469d7a 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; fi; +RESOLVEDIP=$(nslookup "google.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null From 1f30030268bd9773c4f8918675f293f8b1e81a13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Aug 2022 21:26:55 -0400 Subject: [PATCH 3393/6505] Update debian-install.sh --- setup/debian-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index d738a621..48b5b4c8 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -59,8 +59,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; fi; -RESOLVEDIP=$(nslookup "google.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved to $RESOLVEDIP"; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; msg_info "Updating Container OS" apt-get update &>/dev/null From e6fa32fc34afdd86425177753d996a3a546355eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Aug 2022 21:28:05 -0400 Subject: [PATCH 3394/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 55469d7a..d3c93401 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -60,8 +60,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; fi; -RESOLVEDIP=$(nslookup "google.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved to $RESOLVEDIP"; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; msg_info "Updating Container OS" apt-get update &>/dev/null From 1779aab46096a1134903ed4eaf65f8679b106cf6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Aug 2022 15:37:13 -0400 Subject: [PATCH 3395/6505] Update debian-install.sh --- setup/debian-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 48b5b4c8..90b25b47 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -58,9 +58,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; fi; -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; IC="YES"; else msg_error "Internet NOT Connected"; IC="NO"; fi; +if [[ ${IC} == "YES" ]]; then RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) + if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +fi msg_info "Updating Container OS" apt-get update &>/dev/null From 1e5d1381602ddb3d1261d095b03eb7162143b67e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Aug 2022 15:38:08 -0400 Subject: [PATCH 3396/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index d3c93401..1cf8f254 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -59,9 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; fi; -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; IC="YES"; else msg_error "Internet NOT Connected"; IC="NO"; fi; +if [[ ${IC} == "YES" ]]; then RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) + if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +fi msg_info "Updating Container OS" apt-get update &>/dev/null From c6ef397bc9b5de19431330d494d428cff3bc2026 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Aug 2022 17:10:14 -0400 Subject: [PATCH 3397/6505] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..8ecf7b04 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +ko_fi: proxmoxhelperscripts From 35baa41feb11d2ab93383891c5b8f48eeb9fed81 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Aug 2022 17:37:10 -0400 Subject: [PATCH 3398/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ff28afc3..13f0a434 100644 --- a/README.md +++ b/README.md @@ -2091,3 +2091,5 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/web-vault- ____________________________________________________________________________________________
    + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF) From 56615fbe793af35dd498ccce7bd75f33faba6030 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Aug 2022 19:59:07 -0400 Subject: [PATCH 3399/6505] Update create_lxc.sh --- ct/create_lxc.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 82269485..f82768a5 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -5,6 +5,7 @@ RD=`echo "\033[01;31m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" set -o errexit @@ -33,7 +34,15 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Validating Storage" +VALID=$(pvesm status -content rootdir | awk 'NR>1') +if [ -z "$VALID" ]; then msg_error "Unable to detect a valid storage location."; exit 1; fi; + function select_storage() { local CLASS=$1 local CONTENT @@ -57,10 +66,7 @@ function select_storage() { MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content $CONTENT | awk 'NR>1') - if [ $((${#MENU[@]}/3)) -eq 0 ]; then - echo -e "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then + if [ $((${#MENU[@]}/3)) -eq 1 ]; then printf ${MENU[0]} else local STORAGE @@ -117,4 +123,3 @@ msg_info "Creating LXC Container" pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created." - From 6eff2a95b4949c701830d43ffad1d30f0665ca57 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Aug 2022 20:01:03 -0400 Subject: [PATCH 3400/6505] Update debian-install.sh --- setup/debian-install.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 90b25b47..84f28bfa 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -58,10 +58,9 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; IC="YES"; else msg_error "Internet NOT Connected"; IC="NO"; fi; -if [[ ${IC} == "YES" ]]; then RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) - if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; -fi +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; msg_info "Updating Container OS" apt-get update &>/dev/null From 14a88737622715854e01e7fc49a7fdca2b128843 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Aug 2022 20:01:32 -0400 Subject: [PATCH 3401/6505] Update ubuntu-install.sh --- setup/ubuntu-install.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 1cf8f254..5514c920 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -59,10 +59,9 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; IC="YES"; else msg_error "Internet NOT Connected"; IC="NO"; fi; -if [[ ${IC} == "YES" ]]; then RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) - if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; -fi +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; msg_info "Updating Container OS" apt-get update &>/dev/null From fe206d8483ab67eed4cb1ec5b47a9a1b6c8ed883 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 31 Aug 2022 05:18:35 -0400 Subject: [PATCH 3402/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 358b707b..8eb97bbc 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -275,7 +275,8 @@ qm set $VMID \ qm set $VMID \ -boot order=scsi0 >/dev/null qm set $VMID -description "# Home Assistant OS -### https://github.com/tteck/Proxmox" >/dev/null +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" From 5a5afad573d651140cfcbd73757b886312208843 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 31 Aug 2022 05:20:58 -0400 Subject: [PATCH 3403/6505] Add Internet & DNS Check (#471) --- setup/adguard-install.sh | 13 +++++++++++-- setup/daemonsync-install.sh | 13 +++++++++++-- setup/dashy-install.sh | 13 +++++++++++-- setup/deconz-install.sh | 9 +++++++++ setup/docker-install.sh | 13 +++++++++++-- setup/emby-install.sh | 13 +++++++++++-- setup/esphome-install.sh | 13 +++++++++++-- setup/grafana-install.sh | 13 +++++++++++-- setup/grocy-install.sh | 9 +++++++++ setup/heimdalldashboard-install.sh | 13 +++++++++++-- setup/homeassistant-install.sh | 13 +++++++++++-- setup/homebridge-install.sh | 13 +++++++++++-- setup/influxdb-install.sh | 13 +++++++++++-- setup/iobroker-install.sh | 13 +++++++++++-- setup/jellyfin-install.sh | 13 +++++++++++-- setup/keycloak-install.sh | 9 +++++++++ setup/magicmirror-install.sh | 9 +++++++++ setup/mariadb-install.sh | 13 +++++++++++-- setup/meshcentral-install.sh | 13 +++++++++++-- setup/motioneye-install.sh | 13 +++++++++++-- setup/mqtt-install.sh | 13 +++++++++++-- setup/n8n-install.sh | 13 +++++++++++-- setup/nginx-proxy-manager-install.sh | 13 +++++++++++-- setup/nocodb-install.sh | 13 +++++++++++-- setup/node-red-install.sh | 13 +++++++++++-- setup/omada-install.sh | 15 ++++++++++++--- setup/openhab-install.sh | 9 +++++++++ setup/photoprism-install.sh | 9 +++++++++ setup/pihole-install.sh | 13 +++++++++++-- setup/plex-install.sh | 13 +++++++++++-- setup/podman-homeassistant-install.sh | 13 +++++++++++-- setup/postgresql-install.sh | 9 +++++++++ setup/prometheus-install.sh | 9 +++++++++ setup/technitiumdns-install.sh | 13 +++++++++++-- setup/unifi-install.sh | 13 +++++++++++-- setup/uptimekuma-install.sh | 13 +++++++++++-- setup/vaultwarden-install.sh | 13 +++++++++++-- setup/whoogle-install.sh | 9 +++++++++ setup/wikijs-install.sh | 9 +++++++++ setup/wireguard-install.sh | 13 +++++++++++-- setup/zigbee2mqtt-install.sh | 13 +++++++++++-- setup/zwavejs2mqtt-install.sh | 13 +++++++++++-- 42 files changed, 443 insertions(+), 65 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index ba2c520b..61be5518 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index cd41862b..35957afc 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 3a5746e9..8267f380 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index 643e818e..1cb64ebb 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 8c65c7f5..1780dcfd 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 63305ab4..0ba9b200 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index ffb1ff5b..1f4323be 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index b1dbe1c8..9803f66a 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 7910ce7c..66317825 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 1420ca67..c70347a4 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index fe4c60fd..80e53aba 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index eae42a0e..8678c607 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 5f4fd34e..6495809f 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 05bbfd36..7ba4a65f 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index d61151a5..d0a32cd4 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index 7d155d9f..06c679f6 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index 0e80fb54..0c903cd2 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index a8e6b69b..c9025669 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index bdeb64b2..0221f817 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index a47c3841..2229ac30 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 6bfc4f04..ade1c168 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 282f6c6e..9adffc10 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index b2d01b5c..2f9b21b0 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index ee32e987..ae27d97c 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index f09cbc92..180daf92 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/omada-install.sh b/setup/omada-install.sh index c65a4104..4260e995 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -38,23 +38,32 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -msg_info "Updating Container OS (216 packages)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 3fa1e64b..4ec66d79 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index b703e80a..aa692945 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -39,6 +39,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -55,6 +60,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 6ac189ad..c27e7ea4 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 1b2d091c..be02e9a4 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 9f23fc47..c5d9b23f 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index a37609b2..175011f8 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 5c0cfc1e..2da05e62 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 9755d9e3..48650070 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 0d1cecc3..8e899809 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -39,22 +39,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 2e90fb3c..b29954f1 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 699cdd4a..3f18807a 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -47,13 +52,17 @@ while [ "$(hostname -I)" = "" ]; do ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done -msg_ok "Setup Container OS" +msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index dd79d68d..e7854c82 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index a1bb4882..8866f812 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -38,6 +38,11 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null @@ -54,6 +59,10 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 1a0476e3..d295d4db 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + OPTIONS_PATH='/options.conf' cat >$OPTIONS_PATH <<'EOF' IPv4dev=eth0 diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 2b109303..910da0fe 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwavejs2mqtt-install.sh index c1fa407c..c439b9c8 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwavejs2mqtt-install.sh @@ -38,22 +38,31 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + 1>&2 echo -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) if [ $NUM -eq 0 ] then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + msg_info "Updating Container OS" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null From 5fc225a957ca9023d566075a12d1d1502b89b343 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 31 Aug 2022 05:23:25 -0400 Subject: [PATCH 3404/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 83a0040f..bb61be63 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-08-31 + +### Changed + +- **All LXC's** + - Add Internet & DNS Check + ## 2022-08-22 ### Changed From 6ff58734d3f2ac78cbf4422eda95eef90b0c9896 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 31 Aug 2022 06:46:22 -0400 Subject: [PATCH 3405/6505] Delete haos-vm-v3.sh --- vm/haos-vm-v3.sh | 359 ----------------------------------------------- 1 file changed, 359 deletions(-) delete mode 100644 vm/haos-vm-v3.sh diff --git a/vm/haos-vm-v3.sh b/vm/haos-vm-v3.sh deleted file mode 100644 index 4dbb9499..00000000 --- a/vm/haos-vm-v3.sh +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -PVE=$(pveversion | grep "pve-manager/7" | wc -l) -GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') -NEXTID=$(pvesh get /cluster/nextid) -RELEASE=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} - -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} - -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -if [[ "$PVE" != "1" ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi - -while true; do - clear - read -p "This will create a New Home Assistant OS VM. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear - -function header_info { -echo -e "${BL} - _ _ ____ _____ - | | | | /\ / __ \ / ____| - | |__| | / \ | | | | (___ - | __ | / /\ \| | | |\___ \ - | | | |/ ____ \ |__| |____) | - |_| |_/_/ ${CL}${YW}v3${CL}${BL} \_\____/|_____/ -${CL}" -} -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using Version ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using VM ID ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using VM Name ${BGN}haos${STABLE}${CL}" - VM_NAME=haos${STABLE} - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}4096${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" - echo -e "${DGN}Start VM when completed ${BGN}yes${CL}" - START_VM="yes" - -} -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Latest for Version ${RELEASE}, or Press [ENTER] for Stable Version ${STABLE} " - read BRANCH - if [ -z $BRANCH ]; then BRANCH=$STABLE; - else - BRANCH=$RELEASE; fi; - echo -en "${DGN}Set Version To ${BL}$BRANCH${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${YW}Enter the VM ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read VMID - if [ -z $VMID ]; then VMID=$NEXTID; fi; - echo -en "${DGN}Set VM ID To ${BL}$VMID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${YW}Enter VM Name (no-spaces), or Press [ENTER] for Default: haos${BRANCH} " - read VMNAME - if [ -z $VMNAME ]; then - VM_NAME=haos${BRANCH} - else - VM_NAME=$(echo ${VMNAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$VM_NAME${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}${CORE_COUNT}${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 4096 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Valid MAC Address, or Press [ENTER] for Generated MAC: $GEN_MAC " - read MAC - if [ -z $MAC ]; then MAC=$GEN_MAC; fi; - echo -en "${DGN}Set MAC Address To ${BL}$MAC${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - echo -e "${YW}Start VM when completed, or Press [ENTER] for Default: yes " - read START_VM - if [ -z $START_VM ]; then START_VM="yes"; - else - START_VM="no"; fi; - echo -en "${DGN}Starting VM when completed ${BL}$START_VM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$BRANCH${CL}" - echo -e "${DGN}Using VM ID ${BGN}$VMID${CL}" - echo -e "${DGN}Using VM Name ${BGN}$VM_NAME${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address ${BGN}$MAC${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - echo -e "${DGN}Start VM when completed ${BGN}$START_VM${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced (Latest ${RELEASE}), or Press [ENTER] for Default Settings (Stable ${STABLE}) " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content images | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - echo -e "'Disk image' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the HAOS VM?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" -URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -sleep 2 -msg_ok "${CL}${BL}${URL}${CL}" -wget -q --show-progress $URL -echo -en "\e[1A\e[0K" -FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" -msg_info "Extracting KVM Disk Image" -unxz $FILE -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DISK_IMPORT="-format qcow2" - ;; - - btrfs) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_FORMAT="subvol" - DISK_IMPORT="-format raw" - ;; - -esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done -msg_ok "Extracted KVM Disk Image" - -msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $VM_NAME -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ - -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null -qm set $VMID \ - -boot order=scsi0 >/dev/null -qm set $VMID -description "# Home Assistant OS -### https://github.com/tteck/Proxmox" >/dev/null -msg_ok "Created HAOS VM ${CL}${BL}${VM_NAME}" - -if [ "$START_VM" == "yes" ]; then -msg_info "Starting Home Assistant OS VM" -qm start $VMID -msg_ok "Started Home Assistant OS VM" -fi -msg_ok "Completed Successfully!\n" From 538f355dedb9a36c192342f53cbe9c4e326819e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 1 Sep 2022 05:59:20 -0400 Subject: [PATCH 3406/6505] Add files via upload --- misc/images/add_integration.png | Bin 0 -> 2749 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/add_integration.png diff --git a/misc/images/add_integration.png b/misc/images/add_integration.png new file mode 100644 index 0000000000000000000000000000000000000000..64d19fd2a24fb2838def65c1fd723513bad01ed5 GIT binary patch literal 2749 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 Dr(IED literal 0 HcmV?d00001 From 9a510418421221a16c3a059858d850d6fef6373f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 1 Sep 2022 19:20:46 -0400 Subject: [PATCH 3407/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index aa692945..38e53a3e 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -84,7 +84,7 @@ apt-get install -y ffmpeg &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -curl -sL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +curl -sL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" @@ -92,8 +92,8 @@ apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Golang (Patience)" -wget https://golang.org/dl/go1.18.4.linux-amd64.tar.gz &>/dev/null -tar -xzf go1.18.4.linux-amd64.tar.gz -C /usr/local &>/dev/null +wget https://golang.org/dl/go1.19.linux-amd64.tar.gz &>/dev/null +tar -xzf go1.19.linux-amd64.tar.gz -C /usr/local &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null go install github.com/tianon/gosu@latest &>/dev/null go install golang.org/x/tools/cmd/goimports@latest &>/dev/null @@ -190,7 +190,7 @@ apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* \ /photoprism \ -/go1.18.4.linux-amd64.tar.gz \ +/go1.19.linux-amd64.tar.gz \ /libtensorflow-linux-avx2-1.15.2.tar.gz \ /libtensorflow-linux-avx-1.15.2.tar.gz \ /libtensorflow-linux-cpu-1.15.2.tar.gz From cdf9a6ba351cc1ad3b016f727bc4e021bac22895 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Sep 2022 12:47:11 -0400 Subject: [PATCH 3408/6505] Update frigate-support.sh --- misc/frigate-support.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/frigate-support.sh b/misc/frigate-support.sh index 3a26a3b9..18c80d18 100644 --- a/misc/frigate-support.sh +++ b/misc/frigate-support.sh @@ -73,5 +73,5 @@ EOF echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" # In the Proxmox web shell run (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/frigate-support.sh)" -s 106 +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/frigate-support.sh)" -s 106 # Reboot the LXC to apply the changes From b7d557a0594aef4ec3cea0700dc28e6bb79c790c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 15:13:49 -0400 Subject: [PATCH 3409/6505] Create navidrome-v4.sh --- ct/navidrome-v4.sh | 264 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 ct/navidrome-v4.sh diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh new file mode 100644 index 00000000..1c674333 --- /dev/null +++ b/ct/navidrome-v4.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Navidrome" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + _ __ _ __ + / | / /___ __ v4__(_)___/ /________ ____ ___ ___ + / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ + / /| / /_/ /| |/ / / /_/ / / / /_/ / / / / / / __/ +/_/ |_/\__,_/ |___/_/\__,_/_/ \____/_/ /_/ /_/\___/ +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:4533${CL} \n" From b4d4e48922fd632d29bc007c65a9d4424a303d72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 15:14:52 -0400 Subject: [PATCH 3410/6505] Create navidrome-install.sh --- setup/navidrome-install.sh | 147 +++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 setup/navidrome-install.sh diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh new file mode 100644 index 00000000..22619e02 --- /dev/null +++ b/setup/navidrome-install.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y ffmpeg &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Navidrome" +sudo install -d -o root -g root /opt/navidrome +sudo install -d -o root -g root /var/lib/navidrome +wget https://github.com/navidrome/navidrome/releases/download/v0.47.5/navidrome_0.47.5_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null +sudo tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null +sudo chown -R root:root /opt/navidrome +mkdir -p /music +cat < /var/lib/navidrome/navidrome.toml +MusicFolder = '/music' +EOF +msg_ok "Installed Navidrome" + +msg_info "Creating Service" +service_path="/etc/systemd/system/navidrome.service" + +echo "[Unit] +Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic +After=remote-fs.target network.target +AssertPathExists=/var/lib/navidrome + +[Service] +User=root +Group=root +Type=simple +ExecStart=/opt/navidrome/navidrome --configfile '/var/lib/navidrome/navidrome.toml' +WorkingDirectory=/var/lib/navidrome +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +DevicePolicy=closed +NoNewPrivileges=yes +PrivateTmp=yes +PrivateUsers=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +RestrictNamespaces=yes +RestrictRealtime=yes +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap +ReadWritePaths=/var/lib/navidrome +ProtectSystem=full + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl daemon-reload +systemctl enable --now navidrome.service &>/dev/null + +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/Navidrome.tar.gz +msg_ok "Cleaned" From e97e83930665353e44239a4be889f6da091f23e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 15:22:24 -0400 Subject: [PATCH 3411/6505] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 13f0a434..2c0a5ab7 100644 --- a/README.md +++ b/README.md @@ -1689,6 +1689,29 @@ ________________________________________________________________________________
    +
    + 🔸Navidrome LXC + +

    + +

    Navidrome LXC

    + +[Navidrome](https://www.navidrome.org/) allows you to enjoy your music collection from anywhere, by making it available through a modern Web UI and through a wide range of third-party compatible mobile apps, for both iOS and Android devices. + +To create a new Proxmox Navidrome LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/navidrome-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +**Navidrome Interface - IP:4533** + +____________________________________________________________________________________________ + +
    +
    PhotoPrism LXC From 5cb30cc61398f5f0bb063580b67c56f2085d1b0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 15:24:10 -0400 Subject: [PATCH 3412/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bb61be63..80a8a9da 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-08 + +### Changed + +- **Navidrome LXC** + - NEW Script + ## 2022-08-31 ### Changed From 3846a041234582b5010b84f71ab1a7c6328cd4bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 15:31:58 -0400 Subject: [PATCH 3413/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2c0a5ab7..0faa460c 100644 --- a/README.md +++ b/README.md @@ -1706,6 +1706,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/navidrome-v4

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    +To change Navidrome music folder path, edit: `/var/lib/photoprism/navidrome.toml` + **Navidrome Interface - IP:4533** ____________________________________________________________________________________________ From 0ed58641bcd5a751c6dfb34cba796d6db1c1e4ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 15:38:45 -0400 Subject: [PATCH 3414/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0faa460c..eb0acb5f 100644 --- a/README.md +++ b/README.md @@ -1706,7 +1706,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/navidrome-v4

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    -To change Navidrome music folder path, edit: `/var/lib/photoprism/navidrome.toml` +To change Navidrome music folder path, edit: `/var/lib/navidrome/navidrome.toml` **Navidrome Interface - IP:4533** From 3c9479c241e943d3284fb5eb8132eadaa9025ba7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 18:39:48 -0400 Subject: [PATCH 3415/6505] Create homepage-install.sh --- setup/homepage-install.sh | 131 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 setup/homepage-install.sh diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh new file mode 100644 index 00000000..9ec584b8 --- /dev/null +++ b/setup/homepage-install.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Installing Homepage" +git clone https://github.com/benphelps/homepage.git /opt/homepage &>/dev/null +cd /opt/homepage +npm install &>/dev/null +npm run build &>/dev/null +mkdir -p config +msg_ok "Installed Homepage" + +msg_info "Creating Service" +service_path="/etc/systemd/system/homepage.service" +echo "[Unit] +Description=Homepage +After=network.target +StartLimitIntervalSec=0 +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +WorkingDirectory=/opt/homepage/ +ExecStart=npm start +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now homepage &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From 85d836e120536709e338627e1d5c5f407a4f6cc4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 18:54:54 -0400 Subject: [PATCH 3416/6505] Create homepage-v4.sh --- ct/homepage-v4.sh | 265 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 ct/homepage-v4.sh diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh new file mode 100644 index 00000000..dc41118d --- /dev/null +++ b/ct/homepage-v4.sh @@ -0,0 +1,265 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Homepage" +var_disk="3" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + __ __ + / / / /___ ____ ___ ___ ____ ____ _____ ____ + / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ + / __ / /_/ / / / / / / __/ /_/ / /_/ / /_/ / __/ +/_/ /_/\____/_/ /_/ /_/\___/ .___/\__,_/\__, /\___/ + /_/ v4 /____/ +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 62e82c770ddacf02e883db0fbc0c07e4dacf60ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 19:04:37 -0400 Subject: [PATCH 3417/6505] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index eb0acb5f..2eec0b3b 100644 --- a/README.md +++ b/README.md @@ -1557,6 +1557,29 @@ ________________________________________________________________________________
    +
    + 🔸Homepage LXC + + +

    Homepage LXC

    + +[Homepage](https://github.com/benphelps/homepage) is a self-hosted dashboard. + +To create a new Proxmox Homepage LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homepage-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 2vCPU ⚡

    + +[Configuration](https://github.com/benphelps/homepage/wiki) file path: `/opt/homepage/config/` + +**Homepage Interface - IP:3000** + +____________________________________________________________________________________________ + +
    Dashy LXC From 04286fa868c29ce5108474773f44f34fb15401e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 19:05:43 -0400 Subject: [PATCH 3418/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 80a8a9da..09f7c45a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **Navidrome LXC** - NEW Script +- **Homepage LXC** + - NEW Script ## 2022-08-31 From a76ff528493c955575f1757ce4e4adde822d847a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Sep 2022 19:10:43 -0400 Subject: [PATCH 3419/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2eec0b3b..83d738fb 100644 --- a/README.md +++ b/README.md @@ -1573,7 +1573,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homepage-v4.

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 2vCPU ⚡

    -[Configuration](https://github.com/benphelps/homepage/wiki) file path: `/opt/homepage/config/` +[Configuration](https://github.com/benphelps/homepage/wiki) (bookmarks.yaml, services.yaml, widgets.yaml) path: `/opt/homepage/config/` **Homepage Interface - IP:3000** From 376490dcd5518339277265686b47a2063be44556 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Sep 2022 10:41:23 -0400 Subject: [PATCH 3420/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 09f7c45a..7d88d1e3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-09 + +### Changed + +- **CasaOS LXC** + - NEW Script + ## 2022-09-08 ### Changed From 50b12c44dd7aa8608b7df9f483a427d3fbd1c0b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Sep 2022 10:45:13 -0400 Subject: [PATCH 3421/6505] Create CassOS (#490) * Create casaos-v4.sh * Create casaos-install.sh * Update README.md * Update casaos-v4.sh --- README.md | 24 ++++ ct/casaos-v4.sh | 270 ++++++++++++++++++++++++++++++++++++++++ setup/casaos-install.sh | 111 +++++++++++++++++ 3 files changed, 405 insertions(+) create mode 100644 ct/casaos-v4.sh create mode 100644 setup/casaos-install.sh diff --git a/README.md b/README.md index 83d738fb..0e5c956b 100644 --- a/README.md +++ b/README.md @@ -1126,6 +1126,30 @@ ________________________________________________________________________________
    +
    + 🔸CasaOS LXC + +

    + +

    CasaOS LXC

    + +[CasaOS](https://www.casaos.io/) is a community-based open source software focused on delivering simple home cloud experience around Docker ecosystem. + + +To create a new Proxmox CasaOS LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/CasaOS-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**CasaOS Interface - IP** + +____________________________________________________________________________________________ + +
    +
    Debian LXC diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh new file mode 100644 index 00000000..4f6509a5 --- /dev/null +++ b/ct/casaos-v4.sh @@ -0,0 +1,270 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="CasaOS" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + ______ ____ _____ + / ____/___ __v4______ _/ __ \/ ___/ + / / / __ `/ ___/ __ `/ / / /\__ \ +/ /___/ /_/ (__ ) /_/ / /_/ /___/ / +\____/\__,_/____/\__,_/\____//____/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ +"10" "Buster" OFF \ +"11" "Bullseye" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" +else + exit +fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP} ${CL} \n" diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh new file mode 100644 index 00000000..634a00e7 --- /dev/null +++ b/setup/casaos-install.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y unzip &>/dev/null +msg_ok "Installed Dependencies" + +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +msg_info "Installing CasaOS (Patience)" +wget -qO- https://get.casaos.io | bash &>/dev/null +msg_ok "Installed CasaOS" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From eb57929e56f32458f2be5f6a835947851b1fa238 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Sep 2022 21:03:20 -0400 Subject: [PATCH 3422/6505] Update Kernel Clean to work with PBS --- misc/kernel-clean.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index c804741a..212ad8e0 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -14,7 +14,6 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" PARTY="🎉" current_kernel=$(uname -r) -pve=$(pveversion) while true; do read -p "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed(y/n)?" yn @@ -70,7 +69,9 @@ function edge_kernel() { function kernel_info() { latest_kernel=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) - echo -e "${YW}PVE Version: ${BL}$pve\n${CL}" + if [[ "$MODE" != "PBS" ]]; then + echo -e "${YW}PVE Version: ${BL}$(pveversion)\n${CL}" + fi if [[ "$current_kernel" == *"pve"* ]]; then if [[ "$latest_kernel" != *"$current_kernel"* ]]; then echo -e "${GN}Latest Kernel: $latest_kernel\n${CL}" @@ -120,4 +121,12 @@ msg_ok "Kernel Search Completed\n" fi } +if ! command -v pveversion >/dev/null 2>&1; then + echo -e " Switching to PBS mode" + MODE="PBS" + sleep 2 + else + MODE="PVE" +fi + check_root From 543a6e7bfce10610511e453bb1fabb7cae41093d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Sep 2022 21:06:32 -0400 Subject: [PATCH 3423/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7d88d1e3..fec654f4 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **CasaOS LXC** - NEW Script +- **Proxmox Kernel Clean** + - Now works with Proxmox Backup Server ## 2022-09-08 From 90ebd56c102c71f741f4fa56c49fc0411418db89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Sep 2022 06:27:49 -0400 Subject: [PATCH 3424/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e5c956b..7552b528 100644 --- a/README.md +++ b/README.md @@ -1139,7 +1139,7 @@ ________________________________________________________________________________ To create a new Proxmox CasaOS LXC, run the following in the Proxmox Shell. ``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/CasaOS-v4.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/casaos-v4.sh)" ```

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    From de9ce16082e64cef51275690edcc1538f31e1476 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Sep 2022 12:10:30 -0400 Subject: [PATCH 3425/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index ade1c168..31ddf860 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -60,8 +60,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +#RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +#if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; msg_info "Updating Container OS" apt-get update &>/dev/null From 4132e882b37fcb14b1c5819493663455c91c1f4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Sep 2022 12:22:59 -0400 Subject: [PATCH 3426/6505] Update mqtt-install.sh --- setup/mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 31ddf860..ade1c168 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -60,8 +60,8 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; -#RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -#if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; msg_info "Updating Container OS" apt-get update &>/dev/null From e1cd05db1e588c299d865388931aa16a5a79abcc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Sep 2022 21:34:18 -0400 Subject: [PATCH 3427/6505] Create syncthing-v4.sh --- ct/syncthing-v4.sh | 255 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 ct/syncthing-v4.sh diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh new file mode 100644 index 00000000..d151d1d4 --- /dev/null +++ b/ct/syncthing-v4.sh @@ -0,0 +1,255 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Syncthing" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + _____ __ __ _ + / ___/__ ______v4_____/ /_/ /_ (_)___ ____ _ + \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ + ___/ / /_/ / / / / /__/ /_/ / / / / / / / /_/ / +/____/\__, /_/ /_/\___/\__/_/ /_/_/_/ /_/\__, / + /____/ /____/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8384 ${CL} (after initial start) \n" From 3656bc560235e53f5c6ea8f865cf4457da180b3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Sep 2022 21:35:27 -0400 Subject: [PATCH 3428/6505] Create syncthing-install.sh --- setup/syncthing-install.sh | 105 +++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 setup/syncthing-install.sh diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh new file mode 100644 index 00000000..2b09475a --- /dev/null +++ b/setup/syncthing-install.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Syncthing" +curl -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg &>/dev/null +echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list &>/dev/null +apt-get update &>/dev/null +apt-get install -y syncthing &>/dev/null +systemctl enable syncthing@root.service &>/dev/null +msg_ok "Installed Syncthing" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* +msg_ok "Cleaned" From d37a619554dba88543591185c080392318ab2bca Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Sep 2022 21:39:02 -0400 Subject: [PATCH 3429/6505] Update README.md --- README.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7552b528..b88273be 100644 --- a/README.md +++ b/README.md @@ -1948,11 +1948,42 @@ bash /etc/webmin/uninstall.sh ``` ___________________________________________________________________________________________ +
    + +
    + 🔸Syncthing LXC + +

    + +

    Syncthing LXC

    + +[Syncthing](https://syncthing.net/) is a continuous file synchronization program. It synchronizes files between two or more computers. + +To create a new Proxmox Syncthing LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/syncthing-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +⚙️ For the initial start, run `syncthing --gui-address=0.0.0.0:8384` in the LXC console, then go to the LXC IP:8384 In settings set the LXC IP address under the GUI (also set the GUI Authentication User and GUI Authentication Password) and Connections tab's and save. Reboot the LXC. + +**Syncthing Interface - IP:8384** + +⚙️ **To Update Syncthing** + +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ +
    WireGuard LXC - +

    WireGuard LXC

    From 80d2305a0f386ba7179d38f5571fddf46dce0e9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Sep 2022 21:41:04 -0400 Subject: [PATCH 3430/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index fec654f4..7b747e4c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-10 + +### Changed + +- **Syncthing LXC** + - NEW Script + ## 2022-09-09 ### Changed From b803b562ca6b6d0f906c632caf6165cf8c792a34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 02:17:44 -0400 Subject: [PATCH 3431/6505] Update homepage-install.sh --- setup/homepage-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 9ec584b8..661898df 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -74,7 +74,7 @@ apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" @@ -84,9 +84,9 @@ msg_ok "Installed Node.js" msg_info "Installing Homepage" git clone https://github.com/benphelps/homepage.git /opt/homepage &>/dev/null cd /opt/homepage +mkdir -p config npm install &>/dev/null npm run build &>/dev/null -mkdir -p config msg_ok "Installed Homepage" msg_info "Creating Service" From 1515ce2ab72ca367123c5fc79e908563cd2b20f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 04:12:24 -0400 Subject: [PATCH 3432/6505] Update homepage-install.sh --- setup/homepage-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 661898df..2ee58a14 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -79,14 +79,15 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null +npm install -g pnpm &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Homepage" git clone https://github.com/benphelps/homepage.git /opt/homepage &>/dev/null cd /opt/homepage mkdir -p config -npm install &>/dev/null -npm run build &>/dev/null +pnpm install &>/dev/null +pnpm build &>/dev/null msg_ok "Installed Homepage" msg_info "Creating Service" From 7fe2b50c1f604b4a72f93b5cd4d7d91a87c4745b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 04:26:19 -0400 Subject: [PATCH 3433/6505] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index b88273be..33f1ed61 100644 --- a/README.md +++ b/README.md @@ -1601,6 +1601,13 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homepage-v4. **Homepage Interface - IP:3000** +⚙️ **To Update Homepage** + +Run in the LXC console +```yaml +cd /opt/homepage && systemctl stop homepage && git pull --force && pnpm install && pnpm build && systemctl start homepage +``` + ____________________________________________________________________________________________
    From 8e77bfaf3d5595ba512352e888d6210ca2ab95ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 04:44:16 -0400 Subject: [PATCH 3434/6505] Create homepage-update.sh --- misc/homepage-update.sh | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 misc/homepage-update.sh diff --git a/misc/homepage-update.sh b/misc/homepage-update.sh new file mode 100644 index 00000000..239bd879 --- /dev/null +++ b/misc/homepage-update.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="NocoDB" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +while true; do + read -p "This will Update ${APP}. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +cat << "EOF" + __ __ + / / / /___ ____ ___ ___ ____ ____ _____ ____ + / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ + / __ / /_/ / / / / / / __/ /_/ / /_/ / /_/ / __/ +/_/ /_/\____/_/ /_/ /_/\___/ .___/\__,_/\__, /\___/ + /_/ UPDATE /____/ +EOF +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Updating ${APP}" +if ! command -v pnpm >/dev/null 2>&1; then + npm install -g pnpm &>/dev/null +fi +cd /opt/homepage +systemctl stop homepage +git pull --force &>/dev/null +pnpm install &>/dev/null +pnpm build &>/dev/null +systemctl start homepage +msg_ok "Updated ${APP}" From f4f30bbc4036a3b15e0cf3c30800b02e1bcb3b63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 04:47:46 -0400 Subject: [PATCH 3435/6505] Update homepage-update.sh --- misc/homepage-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/homepage-update.sh b/misc/homepage-update.sh index 239bd879..7b8ac4c6 100644 --- a/misc/homepage-update.sh +++ b/misc/homepage-update.sh @@ -9,7 +9,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -APP="NocoDB" +APP="Homepage" set -o errexit set -o errtrace set -o nounset From 0be6894a45bd15be524618bac7b51c437d816cf8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 04:50:12 -0400 Subject: [PATCH 3436/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33f1ed61..5f1d27a2 100644 --- a/README.md +++ b/README.md @@ -1605,7 +1605,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homepage-v4. Run in the LXC console ```yaml -cd /opt/homepage && systemctl stop homepage && git pull --force && pnpm install && pnpm build && systemctl start homepage +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/homepage-update.sh)" ``` ____________________________________________________________________________________________ From 4661d073cd0e74ae28bc030fcf866262404957f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 10:58:04 -0400 Subject: [PATCH 3437/6505] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5f1d27a2..c28cd71b 100644 --- a/README.md +++ b/README.md @@ -1146,6 +1146,12 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/casaos-v4.sh **CasaOS Interface - IP** +⚙️ **To Update CasaOS** + +```yaml +update from the CasaOS UI +``` + ____________________________________________________________________________________________
    From b5331838296a10b4981d7bb8ae468d1a2522066a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 14:51:09 -0400 Subject: [PATCH 3438/6505] Create trilium-v4.sh --- ct/trilium-v4.sh | 254 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 ct/trilium-v4.sh diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh new file mode 100644 index 00000000..0cdd70e8 --- /dev/null +++ b/ct/trilium-v4.sh @@ -0,0 +1,254 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Trilium" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + ______ _ ___ + /_ __/_v4_(_) (_)_ ______ ___ + / / / ___/ / / / / / / __ `__ \ + / / / / / / / / /_/ / / / / / / +/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" From 7c9f3752c7510de58963457ecfb18d9c7a8a5546 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 14:52:16 -0400 Subject: [PATCH 3439/6505] Create trilium-install.sh --- setup/trilium-install.sh | 122 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 setup/trilium-install.sh diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh new file mode 100644 index 00000000..00a32428 --- /dev/null +++ b/setup/trilium-install.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Trilium" +wget -q https://github.com/zadam/trilium/releases/download/v0.54.3/trilium-linux-x64-server-0.54.3.tar.xz +tar -xvf trilium-linux-x64-server-0.54.3.tar.xz &>/dev/null +mv trilium-linux-x64-server /opt/trilium +msg_ok "Installed Trilium" + +msg_info "Creating Service" +service_path="/etc/systemd/system/trilium.service" + +echo "[Unit] +Description=Trilium Daemon +After=syslog.target network.target + +[Service] +User=root +Type=simple +ExecStart=/opt/trilium/trilium.sh +WorkingDirectory=/opt/trilium/ +TimeoutStopSec=20 +Restart=always + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now -q trilium +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/trilium-linux-x64-server-0.54.3.tar.xz +msg_ok "Cleaned" From 5dd18e581c6caaa6629ecde7d6620a16ff8202a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 15:06:39 -0400 Subject: [PATCH 3440/6505] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index c28cd71b..c18a3bfc 100644 --- a/README.md +++ b/README.md @@ -1535,6 +1535,29 @@ ________________________________________________________________________________
    +
    + 🔸Trilium LXC + +

    + +

    Trilium LXC

    + +[Trilium](https://github.com/zadam/trilium#trilium-notes) is a hierarchical note taking application with focus on building large personal knowledge bases. + +To create a new Proxmox Trilium LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/trilium-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Trilium Interface - IP:8080** + +____________________________________________________________________________________________ + +
    +
    Wiki.js LXC From 9d57ca692a4be59dd2231a1bfa7348f60ecab39d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 15:07:47 -0400 Subject: [PATCH 3441/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7b747e4c..0bab3311 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-11 + +### Changed + +- **Trilium LXC** + - NEW Script + ## 2022-09-10 ### Changed From 85d72e8225daded4ba4de7f136d5dcc3dac72828 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 15:48:35 -0400 Subject: [PATCH 3442/6505] Create trilium-update.sh --- misc/trilium-update.sh | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 misc/trilium-update.sh diff --git a/misc/trilium-update.sh b/misc/trilium-update.sh new file mode 100644 index 00000000..108f75ce --- /dev/null +++ b/misc/trilium-update.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +VWRELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') + +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +function update_info { +cat << "EOF" + ______ _ ___ + /_ __/____(_) (_)_ ______ ___ + / / / ___/ / / / / / / __ `__ \ + / / / / / / / / /_/ / / / / / / +/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ + UPDATE + +EOF +} +update_info +while true; do + read -p "This will Update Trilium to v$VWRELEASE. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +sleep 2 +echo -e "${GN} Stopping Trilium... ${CL}" +systemctl stop trilium.service +sleep 1 + +echo -e "${GN} Updating to v${VWRELEASE}... ${CL}" +wget -q https://github.com/zadam/trilium/releases/download/v$VWRELEASE/trilium-linux-x64-server-$VWRELEASE.tar.xz + +tar -xzf trilium-linux-x64-server-$VWRELEASE.tar.xz -C /opt/trilium &>/dev/null + +echo -e "${GN} Cleaning up... ${CL}" +rm trilium-linux-x64-server-$VWRELEASE.tar.xz + +echo -e "${GN} Starting Trilium... ${CL}" +systemctl start trilium.service +sleep 1 +echo -e "${GN} Finished Update ${CL}" From 06e0a1208ad24001b83790aa03f1aa4129821d38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 16:02:41 -0400 Subject: [PATCH 3443/6505] Create navidrome-update.sh --- misc/navidrome-update.sh | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 misc/navidrome-update.sh diff --git a/misc/navidrome-update.sh b/misc/navidrome-update.sh new file mode 100644 index 00000000..fb9a95ff --- /dev/null +++ b/misc/navidrome-update.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +VWRELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') + +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +function update_info { +cat << "EOF" + _ __ _ __ + / | / /___ __ __(_)___/ /________ ____ ___ ___ + / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ + / /| / /_/ /| |/ / / /_/ / / / /_/ / / / / / / __/ +/_/ |_/\__,_/ |___/_/\__,_/_/ \____/_/ /_/ /_/\___/ + UPDATE + +EOF +} +update_info +while true; do + read -p "This will Update Navidrome to v$VWRELEASE. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +sleep 2 +echo -e "${GN} Stopping Navidrome... ${CL}" +systemctl stop navidrome.service +sleep 1 + +echo -e "${GN} Updating to v${VWRELEASE}... ${CL}" +wget https://github.com/navidrome/navidrome/releases/download/v$VWRELEASE/navidrome_$VWRELEASE_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null +tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null + +echo -e "${GN} Cleaning up... ${CL}" +rm Navidrome.tar.gz + +echo -e "${GN} Starting Navidrome... ${CL}" +systemctl start navidrome.service +sleep 1 +echo -e "${GN} Finished Update ${CL}" From 37d393a1a5bd197f07b68a8e89c589091bb3165c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 16:06:46 -0400 Subject: [PATCH 3444/6505] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index c18a3bfc..ba6f5f6a 100644 --- a/README.md +++ b/README.md @@ -1554,6 +1554,13 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/trilium-v4.s **Trilium Interface - IP:8080** +⚙️ **To Update Trilium** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/trilium-update.sh)" +``` + ____________________________________________________________________________________________
    @@ -1793,6 +1800,13 @@ To change Navidrome music folder path, edit: `/var/lib/navidrome/navidrome.toml` **Navidrome Interface - IP:4533** +⚙️ **To Update Navidrome** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/navidrome-update.sh)" +``` + ____________________________________________________________________________________________
    From 930af6e1de298e6916d2deb67ad236761c61ef72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 20:50:52 -0400 Subject: [PATCH 3445/6505] Update navidrome-install.sh --- setup/navidrome-install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index 22619e02..21d44e78 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -67,16 +67,20 @@ apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (patience)" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y ffmpeg &>/dev/null msg_ok "Installed Dependencies" +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') + msg_info "Installing Navidrome" sudo install -d -o root -g root /opt/navidrome sudo install -d -o root -g root /var/lib/navidrome -wget https://github.com/navidrome/navidrome/releases/download/v0.47.5/navidrome_0.47.5_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null +wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null sudo tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null sudo chown -R root:root /opt/navidrome mkdir -p /music From be3bbcc509398ef8dcf2437e02d00cecc6241a95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 20:52:26 -0400 Subject: [PATCH 3446/6505] Update trilium-install.sh --- setup/trilium-install.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index 00a32428..36524370 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -72,9 +72,13 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest \ +| grep "tag_name" \ +| awk '{print substr($2, 3, length($2)-4) }') + msg_info "Installing Trilium" -wget -q https://github.com/zadam/trilium/releases/download/v0.54.3/trilium-linux-x64-server-0.54.3.tar.xz -tar -xvf trilium-linux-x64-server-0.54.3.tar.xz &>/dev/null +wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz +tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null mv trilium-linux-x64-server /opt/trilium msg_ok "Installed Trilium" @@ -118,5 +122,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/trilium-linux-x64-server-0.54.3.tar.xz +rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/trilium-linux-x64-server-$RELEASE.tar.xz msg_ok "Cleaned" From dbe0e4909d5e20fabdc6e049c9e4a4f656af984a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 20:53:52 -0400 Subject: [PATCH 3447/6505] Update navidrome-update.sh --- misc/navidrome-update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/navidrome-update.sh b/misc/navidrome-update.sh index fb9a95ff..c3ecded7 100644 --- a/misc/navidrome-update.sh +++ b/misc/navidrome-update.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -VWRELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest \ +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') @@ -21,7 +21,7 @@ EOF } update_info while true; do - read -p "This will Update Navidrome to v$VWRELEASE. Proceed(y/n)?" yn + read -p "This will Update Navidrome to v$RELEASE. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -33,8 +33,8 @@ echo -e "${GN} Stopping Navidrome... ${CL}" systemctl stop navidrome.service sleep 1 -echo -e "${GN} Updating to v${VWRELEASE}... ${CL}" -wget https://github.com/navidrome/navidrome/releases/download/v$VWRELEASE/navidrome_$VWRELEASE_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null +echo -e "${GN} Updating to v${RELEASE}... ${CL}" +wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null echo -e "${GN} Cleaning up... ${CL}" From 99d81287e54ce4d4a9f32cbcbf93edfeb94deefc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Sep 2022 20:56:31 -0400 Subject: [PATCH 3448/6505] Update trilium-update.sh --- misc/trilium-update.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/misc/trilium-update.sh b/misc/trilium-update.sh index 108f75ce..9220c2d7 100644 --- a/misc/trilium-update.sh +++ b/misc/trilium-update.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -VWRELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest \ +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest \ | grep "tag_name" \ | awk '{print substr($2, 3, length($2)-4) }') @@ -21,7 +21,7 @@ EOF } update_info while true; do - read -p "This will Update Trilium to v$VWRELEASE. Proceed(y/n)?" yn + read -p "This will Update Trilium to v$RELEASE. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -33,13 +33,13 @@ echo -e "${GN} Stopping Trilium... ${CL}" systemctl stop trilium.service sleep 1 -echo -e "${GN} Updating to v${VWRELEASE}... ${CL}" -wget -q https://github.com/zadam/trilium/releases/download/v$VWRELEASE/trilium-linux-x64-server-$VWRELEASE.tar.xz +echo -e "${GN} Updating to v${RELEASE}... ${CL}" +wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz -tar -xzf trilium-linux-x64-server-$VWRELEASE.tar.xz -C /opt/trilium &>/dev/null +tar -xzf trilium-linux-x64-server-$RELEASE.tar.xz -C /opt/trilium &>/dev/null echo -e "${GN} Cleaning up... ${CL}" -rm trilium-linux-x64-server-$VWRELEASE.tar.xz +rm trilium-linux-x64-server-$RELEASE.tar.xz echo -e "${GN} Starting Trilium... ${CL}" systemctl start trilium.service From d9689afab542e0912b7b2198ec1d5cbae461a8c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Sep 2022 11:25:48 -0400 Subject: [PATCH 3449/6505] Update README.md --- README.md | 57 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index ba6f5f6a..c1528a6a 100644 --- a/README.md +++ b/README.md @@ -1275,34 +1275,6 @@ ________________________________________________________________________________
    -
    - MeshCentral LXC - -

    - -

    MeshCentral LXC

    - -MeshCentral is a full computer management web site. With MeshCentral, you can run your own web server to remotely manage and control computers on a local network or anywhere on the internet. - -To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**MeshCentral Interface - http:// IP** - -⚙️ **To Update MeshCentral** - -```yaml -Update from the MeshCentral UI -``` -____________________________________________________________________________________________ - -
    -
    Plex Media Server LXC @@ -2082,6 +2054,35 @@ ________________________________________________________________________________
    + +
    + MeshCentral LXC + +

    + +

    MeshCentral LXC

    + +[MeshCentral](https://meshcentral.com/info/) is a full computer management web site. With MeshCentral, you can run your own web server to remotely manage and control computers on a local network or anywhere on the internet. + +To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**MeshCentral Interface - http:// IP** + +⚙️ **To Update MeshCentral** + +```yaml +Update from the MeshCentral UI +``` +____________________________________________________________________________________________ + +
    +
    Tailscale From d006211d01801d29f17b1f8da8637faa3dcdfada Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Sep 2022 17:35:37 -0400 Subject: [PATCH 3450/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1528a6a..5bdebc67 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    -
    🔸 +
    Proxmox VE 7 Post Install From f0188f79f58417ad236e365b943be412775712cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Sep 2022 17:40:47 -0400 Subject: [PATCH 3451/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bdebc67..9e590b91 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    - +
    Proxmox VE 7 Post Install From d91326f95deb10978ad94cfe090e120cad6986a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Sep 2022 17:50:00 -0400 Subject: [PATCH 3452/6505] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9e590b91..313a1819 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    - +
    Proxmox VE 7 Post Install @@ -2245,5 +2246,3 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/web-vault- ____________________________________________________________________________________________
    - -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF) From 12ca8e5493aeb468e7a727719c51f600d29bc235 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Sep 2022 18:24:32 -0400 Subject: [PATCH 3453/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 313a1819..5bc5d171 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    -
    From d9caa28a4331435ad8b48652ec79ade7aedf37f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Sep 2022 21:48:08 -0400 Subject: [PATCH 3454/6505] maintenance (#506) * maintenance * maintenance * maintenance * Update debian-v4.sh * Update debian-v4.sh --- ct/adguard-v4.sh | 14 ++------------ ct/casaos-v4.sh | 18 ++++-------------- ct/daemonsync-v4.sh | 14 ++------------ ct/dashy-v4.sh | 14 ++------------ ct/debian-v4.sh | 14 ++------------ ct/deconz-v4.sh | 6 +++--- ct/docker-v4.sh | 18 ++++-------------- ct/emby-v4.sh | 6 +++--- ct/esphome-v4.sh | 14 ++------------ ct/grafana-v4.sh | 14 ++------------ ct/grocy-v4.sh | 14 ++------------ ct/heimdalldashboard-v4.sh | 14 ++------------ ct/homeassistant-v4.sh | 14 ++------------ ct/homebridge-v4.sh | 14 ++------------ ct/homepage-v4.sh | 14 ++------------ ct/influxdb-v4.sh | 14 ++------------ ct/iobroker-v4.sh | 14 ++------------ ct/jellyfin-v4.sh | 3 ++- ct/keycloak-v4.sh | 14 ++------------ ct/magicmirror-v4.sh | 14 ++------------ ct/mariadb-v4.sh | 14 ++------------ ct/meshcentral-v4.sh | 14 ++------------ ct/motioneye-v4.sh | 14 ++------------ ct/mqtt-v4.sh | 14 ++------------ ct/n8n-v4.sh | 14 ++------------ ct/navidrome-v4.sh | 14 ++------------ ct/nginx-proxy-manager-v4.sh | 14 ++------------ ct/nocodb-v4.sh | 14 ++------------ ct/node-red-v4.sh | 14 ++------------ ct/omada-v4.sh | 12 ++++++------ ct/openhab-v4.sh | 14 ++------------ ct/photoprism-v4.sh | 14 ++------------ ct/pihole-v4.sh | 14 ++------------ ct/plex-v4.sh | 3 ++- ct/podman-homeassistant-v4.sh | 14 ++------------ ct/postgresql-v4.sh | 14 ++------------ ct/prometheus-v4.sh | 14 ++------------ ct/syncthing-v4.sh | 3 ++- ct/technitiumdns-v4.sh | 14 ++------------ ct/trilium-v4.sh | 3 ++- ct/ubuntu-v4.sh | 8 ++++---- ct/unifi-v4.sh | 14 ++------------ ct/uptimekuma-v4.sh | 14 ++------------ ct/vaultwarden-v4.sh | 14 ++------------ ct/whoogle-v4.sh | 14 ++------------ ct/wikijs-v4.sh | 14 ++------------ ct/wireguard-v4.sh | 22 ++++++---------------- ct/zigbee2mqtt-v4.sh | 22 ++++++---------------- ct/zwavejs2mqtt-v4.sh | 14 ++------------ 49 files changed, 118 insertions(+), 524 deletions(-) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index bb40f982..e54d84aa 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} Setup should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 4f6509a5..a4a95bf7 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -70,9 +70,8 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -264,7 +253,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} Setup should be reachable by going to the following URL. ${BL}http://${IP} ${CL} \n" diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index 3fee2a6e..07334f6a 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 5383cf97..07232766 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index fb470b8a..ddc48a91 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,5 +247,6 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 28db39a2..c7a671bf 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -70,8 +70,7 @@ fi } function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" @@ -272,7 +271,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}${CL}\n" diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index d83382b7..5534f38a 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -69,9 +69,8 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -263,5 +252,6 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index ed9c62b4..6ea1bcec 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -71,8 +71,7 @@ fi } function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" @@ -271,7 +270,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index e6488c95..9172c085 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 7ed70c2c..d2622f59 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 680bcc4a..54755899 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}${CL} \n" diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 3b5c52bd..4c534619 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 17ff5cdc..3b2083ad 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -263,7 +252,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL} diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 87b60dcb..abbee6a9 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index dc41118d..97df3d81 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} Setup should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index f7b0fa7a..7f9f991e 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,5 +247,6 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 7b56f873..364cf6e1 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8081${CL} \n" diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 210bfdf9..bee0357b 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -270,7 +270,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 61954dae..2c5db5a9 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 9f81130a..06aee016 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index effb77bf..771db328 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "Adminer should be reachable by going to the following URL. ${BL}http://${IP}/adminer/${CL} \n" diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 35ef4971..602a6db5 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}${CL} \n" diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 0ce01077..7a53e637 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index 01638788..899552a9 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,5 +247,6 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index 5cdcc286..d683c6fd 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5678${CL} \n" diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 1c674333..4cb19868 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:4533${CL} \n" diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 39ffe521..bea15edf 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nginx-proxy-manager-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 08e6fd4b..050e5ff9 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080/dashboard${CL} \n" diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 04aba883..9230148b 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 6236796c..f4f1a9af 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -70,9 +70,8 @@ fi } function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -93,8 +92,8 @@ function default_settings() { GATE="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -261,7 +260,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}https://${IP}:8043${CL} \n" diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index 128a0223..e724c8e3 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index 9ffc9399..cbfa9b92 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 60dd7c25..d917e1f5 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}/admin${CL} \n" diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index 9c43b82c..cad50e02 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -270,7 +270,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:32400/web${CL}\n" diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 6c97d5d8..55efec47 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -73,7 +73,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -101,16 +100,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ @@ -267,7 +256,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL} diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index 7d8c4d13..230fa91f 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "Adminer should be reachable by going to the following URL. ${BL}http://${IP}/adminer/${CL} \n" diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 554e531f..587412e9 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:9090${CL} \n" diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index d151d1d4..27d73050 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -249,7 +249,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8384 ${CL} (after initial start) \n" diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index fa20dafc..e7f78fd4 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index 0cdd70e8..8dc66c67 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -248,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 8df0e0f4..f485ca4e 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -70,9 +70,8 @@ fi } function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -261,5 +260,6 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index 71f3ac51..d6f7b954 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP}${CL} should be reachable by going to the following URL. ${BL}https://${IP}:8443${CL} \n" diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index 3a806bff..4f7f4e3b 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3001${CL} \n" diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index fa33cb7b..02b0f684 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_info "Setting Container to Normal Resources" pct set $CTID -memory 512 pct set $CTID -cores 1 diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index f5dabd3e..21a1ecdf 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -69,7 +69,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -97,16 +96,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -258,7 +247,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index 32df8a0d..b41e5a4a 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -259,7 +248,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 6e2e9282..564dd218 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -71,9 +71,8 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -94,21 +93,11 @@ function default_settings() { GATE="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -260,7 +249,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "WGDashboard should be reachable by going to the following URL. ${BL}http://${IP}:10086${CL} \n" diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 2c5662e2..48fcc97f 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -70,9 +70,8 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -93,21 +92,11 @@ function default_settings() { GATE="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ @@ -269,5 +258,6 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" diff --git a/ct/zwavejs2mqtt-v4.sh b/ct/zwavejs2mqtt-v4.sh index 9854db8e..56fe0f5c 100644 --- a/ct/zwavejs2mqtt-v4.sh +++ b/ct/zwavejs2mqtt-v4.sh @@ -70,7 +70,6 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -98,16 +97,6 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ -"10" "Buster" OFF \ -"11" "Bullseye" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Debian Version: ${BGN}$var_version${CL}" -else - exit -fi CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ @@ -270,7 +259,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/" +### https://tteck.github.io/Proxmox/ +" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8091${CL} \n" From a83c5e8b972f607bf094e1bfc651461be2719ad8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Sep 2022 22:53:25 -0400 Subject: [PATCH 3455/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 5bc5d171..f911c2f3 100644 --- a/README.md +++ b/README.md @@ -866,8 +866,7 @@ advanced: Run in the LXC console ```yaml -cd /opt/zigbee2mqtt -npm start +cd /opt/zigbee2mqtt && npm start ``` ⚙️ **To update Zigbee2MQTT** From 7aaf479d33b22e38589c02e81534b53f2c130d52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Sep 2022 06:03:31 -0400 Subject: [PATCH 3456/6505] Update casaos-v4.sh --- ct/casaos-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index a4a95bf7..344b3534 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -254,7 +254,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ -" +" msg_ok "Completed Successfully!\n" echo -e "${APP} Setup should be reachable by going to the following URL. ${BL}http://${IP} ${CL} \n" From fd1ce4a327bc2e97ee5736820701d8fe3de371fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Sep 2022 18:03:30 -0400 Subject: [PATCH 3457/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f911c2f3..a2dc7774 100644 --- a/README.md +++ b/README.md @@ -1590,7 +1590,7 @@ ________________________________________________________________________________
    - 🔸Homepage LXC + Homepage LXC

    Homepage LXC

    @@ -1752,7 +1752,7 @@ ________________________________________________________________________________
    - 🔸Navidrome LXC + Navidrome LXC

    From 22a7800fb58c3c8ddc6bd46eb037157637a4c9df Mon Sep 17 00:00:00 2001 From: Donkeykong307 Date: Fri, 16 Sep 2022 03:59:38 +0100 Subject: [PATCH 3458/6505] Made Paperless-ngx Script (#508) Downloads and installs Paperless-ngx including JBIG2. Makes a paperless.creds file in root home directory that contains the usernames and passwords for Postgres Database and the WebUI. --- setup/paperless-ngx-install.sh | 260 +++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 setup/paperless-ngx-install.sh diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh new file mode 100644 index 00000000..993a49ec --- /dev/null +++ b/setup/paperless-ngx-install.sh @@ -0,0 +1,260 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Paperless Dependencies" +apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + python3-dev \ + imagemagick \ + fonts-liberation \ + optipng \ + gnupg \ + libpq-dev \ + libmagic-dev \ + mime-support \ + libzbar0 \ + poppler-utils \ + sudo &>/dev/null +msg_ok "Installed Paperless Dependencies" + +msg_info "Installing OCR Dependencies" +apt-get install -y --no-install-recommends \ + unpaper \ + ghostscript \ + icc-profiles-free \ + qpdf \ + liblept5 \ + libxml2 \ + pngquant \ + zlib1g \ + tesseract-ocr \ + tesseract-ocr-eng &>/dev/null +msg_ok "Installed OCR Dependencies" + +msg_info "Installing Extra Dependencies" +apt-get install -y --no-install-recommends \ + redis \ + postgresql \ + build-essential \ + python3-setuptools \ + python3-wheel &>/dev/null +msg_ok "Installed Extra Dependencies" + +msg_info "Installing JBIG2" +apt-get install -y --no-install-recommends \ + build-essential \ + automake \ + libtool \ + pkg-config \ + git \ + curl \ + libtiff-dev \ + libpng-dev \ + libleptonica-dev &>/dev/null + +git clone https://github.com/agl/jbig2enc /opt/jbig2enc &>/dev/null +cd /opt/jbig2enc +/bin/bash -c "./autogen.sh" &>/dev/null && \ +/bin/bash -c "./configure && make" &>/dev/null && \ +/bin/bash -c "make install" &>/dev/null +rm -rf /opt/jbig2enc +msg_ok "Installed JBIG2" + +msg_info "Downloading Paperless-NGx" +cd /opt && \ +wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz &>/dev/null && \ +tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ &>/dev/null && \ +mv paperless-ngx paperless && \ +rm paperless-ngx-$Paperlessngx.tar.xz +cd /opt/paperless + +## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file +sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt + +/usr/bin/python3 -m pip install --upgrade pip &>/dev/null +/usr/bin/python3 -m pip install -r requirements.txt &>/dev/null +msg_ok "Downloaded Paperless-NGx" + +msg_info "Setting up database" +DB_USER=paperless +DB_PASS="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" +DB_NAME=paperlessdb + +sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" &>/dev/null +sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" &>/dev/null + +echo "Paperless-NGx Database User" >> ~/paperless.creds +echo $DB_USER >> ~/paperless.creds +echo "Paperless-NGx Database Password" >> ~/paperless.creds +echo $DB_PASS >> ~/paperless.creds +echo "Paperless-NGx Database Name" >> ~/paperless.creds +echo $DB_NAME >> ~/paperless.creds + +/bin/bash -c "mkdir -p {consume,media}" + +sed -i -e 's|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=paperlessdb|' /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" /opt/paperless/paperless.conf +SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" +sed -i -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" /opt/paperless/paperless.conf + +cd /opt/paperless/src +/usr/bin/python3 manage.py migrate &>/dev/null +msg_ok "Set up database" + +msg_info "Setting up admin Paperless-NGx User & Password" +## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations +cat << EOF | python3 /opt/paperless/src/manage.py shell +from django.contrib.auth import get_user_model +UserModel = get_user_model() +if len(UserModel.objects.all()) == 1: + user = UserModel.objects.create_user('admin', password='$DB_PASS') + user.is_superuser = True + user.is_staff = True + user.save() +EOF +echo "" >> ~/paperless.creds +echo "Paperless-NGx WebUI User" >> ~/paperless.creds +echo admin >> ~/paperless.creds +echo "Paperless-NGx WebUI Password" >> ~/paperless.creds +echo $DB_PASS >> ~/paperless.creds +msg_ok "Set up admin Paperless-NGx User & Password" + +cat << EOF > /etc/systemd/system/paperless-scheduler.service +[Unit] +Description=Paperless consumer +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=python3 manage.py qcluster + +[Install] +WantedBy=multi-user.target +EOF + +cat << EOF > /etc/systemd/system/paperless-consumer.service +[Unit] +Description=Paperless consumer +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=python3 manage.py document_consumer + +[Install] +WantedBy=multi-user.target +EOF + +cat << EOF > /etc/systemd/system/paperless-webserver.service +[Unit] +Description=Paperless webserver +After=network.target +Wants=network.target +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=/usr/local/bin/gunicorn -c /opt/paperless/gunicorn.conf.py paperless.asgi:application + +[Install] +WantedBy=multi-user.target +EOF + +sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml + +systemctl daemon-reload +systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler &>/dev/null + +msg_ok "Finished installing Paperless-NGx" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From b2575522ffb33f2b78b5137008ddc22487092c56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Sep 2022 23:19:24 -0400 Subject: [PATCH 3459/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2dc7774..7494601f 100644 --- a/README.md +++ b/README.md @@ -1127,7 +1127,7 @@ ________________________________________________________________________________
    - 🔸CasaOS LXC + CasaOS LXC

    From 7d18b44a052269955c428273412111b1bf291a9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 00:11:08 -0400 Subject: [PATCH 3460/6505] Create paperless-ngx-v4.sh --- ct/paperless-ngx-v4.sh | 255 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 ct/paperless-ngx-v4.sh diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh new file mode 100644 index 00000000..69f151d4 --- /dev/null +++ b/ct/paperless-ngx-v4.sh @@ -0,0 +1,255 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Paperless-ngx" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + ____ __ + / __ \____ _____ ___ _____/ /__v4__________ ____ ____ __ __ + / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ + / ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> < +/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| + /_/ /____/ +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From 92c5a572d164e873a46ca8ae6ea4f10e9d88357c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 00:12:35 -0400 Subject: [PATCH 3461/6505] Update paperless-ngx-install.sh --- setup/paperless-ngx-install.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index 993a49ec..d1872eb5 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -18,7 +18,6 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) function error_exit() { trap - ERR @@ -69,7 +68,7 @@ apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" -msg_info "Installing Paperless Dependencies" +msg_info "Installing Paperless-ngx Dependencies" apt-get install -y --no-install-recommends \ python3 \ python3-pip \ @@ -84,7 +83,7 @@ apt-get install -y --no-install-recommends \ libzbar0 \ poppler-utils \ sudo &>/dev/null -msg_ok "Installed Paperless Dependencies" +msg_ok "Installed Paperless-ngx Dependencies" msg_info "Installing OCR Dependencies" apt-get install -y --no-install-recommends \ @@ -129,7 +128,8 @@ cd /opt/jbig2enc rm -rf /opt/jbig2enc msg_ok "Installed JBIG2" -msg_info "Downloading Paperless-NGx" +msg_info "Downloading Paperless-ngx" +Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) cd /opt && \ wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz &>/dev/null && \ tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ &>/dev/null && \ @@ -142,7 +142,7 @@ sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://gi /usr/bin/python3 -m pip install --upgrade pip &>/dev/null /usr/bin/python3 -m pip install -r requirements.txt &>/dev/null -msg_ok "Downloaded Paperless-NGx" +msg_ok "Downloaded Paperless-ngx" msg_info "Setting up database" DB_USER=paperless @@ -152,11 +152,11 @@ DB_NAME=paperlessdb sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" &>/dev/null sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" &>/dev/null -echo "Paperless-NGx Database User" >> ~/paperless.creds +echo "Paperless-ngx Database User" >> ~/paperless.creds echo $DB_USER >> ~/paperless.creds -echo "Paperless-NGx Database Password" >> ~/paperless.creds +echo "Paperless-ngx Database Password" >> ~/paperless.creds echo $DB_PASS >> ~/paperless.creds -echo "Paperless-NGx Database Name" >> ~/paperless.creds +echo "Paperless-ngx Database Name" >> ~/paperless.creds echo $DB_NAME >> ~/paperless.creds /bin/bash -c "mkdir -p {consume,media}" @@ -170,7 +170,7 @@ cd /opt/paperless/src /usr/bin/python3 manage.py migrate &>/dev/null msg_ok "Set up database" -msg_info "Setting up admin Paperless-NGx User & Password" +msg_info "Setting up admin Paperless-ngx User & Password" ## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations cat << EOF | python3 /opt/paperless/src/manage.py shell from django.contrib.auth import get_user_model @@ -182,11 +182,11 @@ if len(UserModel.objects.all()) == 1: user.save() EOF echo "" >> ~/paperless.creds -echo "Paperless-NGx WebUI User" >> ~/paperless.creds +echo "Paperless-ngx WebUI User" >> ~/paperless.creds echo admin >> ~/paperless.creds -echo "Paperless-NGx WebUI Password" >> ~/paperless.creds +echo "Paperless-ngx WebUI Password" >> ~/paperless.creds echo $DB_PASS >> ~/paperless.creds -msg_ok "Set up admin Paperless-NGx User & Password" +msg_ok "Set up admin Paperless-ngx User & Password" cat << EOF > /etc/systemd/system/paperless-scheduler.service [Unit] @@ -234,7 +234,7 @@ sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /et systemctl daemon-reload systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler &>/dev/null -msg_ok "Finished installing Paperless-NGx" +msg_ok "Finished installing Paperless-ngx" PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From d80b6ede5daeec66dc0665c33e6b62c9991ae060 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 00:13:16 -0400 Subject: [PATCH 3462/6505] Update paperless-ngx-install.sh --- setup/paperless-ngx-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index d1872eb5..2f424f81 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -110,7 +110,6 @@ msg_ok "Installed Extra Dependencies" msg_info "Installing JBIG2" apt-get install -y --no-install-recommends \ - build-essential \ automake \ libtool \ pkg-config \ From 8fefb7f4c5279d6e4ef2ad3810043297b292e424 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 00:15:31 -0400 Subject: [PATCH 3463/6505] Update README.md --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 7494601f..f3c73ab9 100644 --- a/README.md +++ b/README.md @@ -1507,6 +1507,36 @@ ________________________________________________________________________________
    + +
    + 🔸Paperless-ngx LXC + +

    + +

    Paperless-ngx LXC

    + +[Paperless-ngx](https://paperless-ngx.readthedocs.io/en/latest/#) is a document management system that transforms your physical documents into a searchable online archive so you can keep, well, less paper. + +To create a new Proxmox Paperless-ngx LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/paperless-ngx-v4.sh)" +``` + +

    ⚡ Default Settings: 2048MiB RAM - 4GB Storage - 2vCPU ⚡

    + +**Paperless-ngx Interface - IP:8080** + +🛈 A paperless.creds file is in root home directory that contains the usernames and passwords. + +Run in the LXC Console +```yaml +cat paperless.creds +``` +____________________________________________________________________________________________ + +
    +
    🔸Trilium LXC From 705b7f44c41889f82a19cd86a536a506cff19e0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 00:18:13 -0400 Subject: [PATCH 3464/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0bab3311..5691e8f1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-16 + +### Changed + +- **Paperless-ngx LXC** + - NEW Script + ## 2022-09-11 ### Changed From 41f9cf3077b88c99009f9bc464b6e3b90def3db5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 00:20:14 -0400 Subject: [PATCH 3465/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 5691e8f1..33c2b4fd 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Paperless-ngx LXC** - - NEW Script + - NEW Script (Thanks @Donkeykong307) ## 2022-09-11 From 3752fc9b948fd9e42620e02ef89781892d7ba006 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 06:04:06 -0400 Subject: [PATCH 3466/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3c73ab9..776a1ed6 100644 --- a/README.md +++ b/README.md @@ -1525,7 +1525,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/paperless-ng

    ⚡ Default Settings: 2048MiB RAM - 4GB Storage - 2vCPU ⚡

    -**Paperless-ngx Interface - IP:8080** +**Paperless-ngx Interface - IP:8000** 🛈 A paperless.creds file is in root home directory that contains the usernames and passwords. From 415f743863ccfdfc1e92c6c88121c8e3673bd536 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 07:56:29 -0400 Subject: [PATCH 3467/6505] Create paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 misc/paperless-ngx-update.sh diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh new file mode 100644 index 00000000..b6e162f8 --- /dev/null +++ b/misc/paperless-ngx-update.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +clear +RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -e + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +cat << "EOF" + ____ __ + / __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __ + / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ + / ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> < +/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| + /_/ UPDATE /____/ +EOF + +while true; do + read -p "This will Update Paperless-ngx to $RELEASE. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +sleep 2 +msg_info "Stopping Paperless-ngx" +systemctl stop paperless-consumer paperless-webserver paperless-scheduler +sleep 1 +msg_ok "Stopped Paperless-ngx" + +msg_info "Updating to ${RELEASE}" +wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null +tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null +cp -r paperless-ngx/* /opt/paperless/ +cd /opt/paperless +pip install -r requirements.txt &>/dev/null +cd src +python3 manage.py migrate &>/dev/null +msg_ok "Updated to ${RELEASE}" + +msg_info "Cleaning up" +cd ~ +rm paperless-ngx-$RELEASE.tar.xz +rm -rf paperless-ngx +msg_ok "Cleaned" + +msg_info "Starting Paperless-ngx" +systemctl start paperless-consumer paperless-webserver paperless-scheduler +sleep 1 +msg_ok "Finished Update" From 049cb371243e452dc748c74b6ed447d2d9a7126d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 08:35:11 -0400 Subject: [PATCH 3468/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index b6e162f8..5c4f39b6 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -73,3 +73,4 @@ msg_info "Starting Paperless-ngx" systemctl start paperless-consumer paperless-webserver paperless-scheduler sleep 1 msg_ok "Finished Update" +echo -e "\n${BL}It may take a minute or so for Paperless-ngx to become available.${CL}\n" From e75acf208c38a3e2e9fbef7fb306cf96f7858cbf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 14:07:50 -0400 Subject: [PATCH 3469/6505] Update homepage-install.sh --- setup/homepage-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 2ee58a14..e3e49589 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -74,7 +74,7 @@ apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 46f0337d066c2991fc022b9c2e60049de8d1c3d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 14:40:15 -0400 Subject: [PATCH 3470/6505] Switch from pnpm to npm --- setup/homepage-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index e3e49589..127ea407 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -79,15 +79,15 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null -npm install -g pnpm &>/dev/null +# npm install -g pnpm &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Homepage" git clone https://github.com/benphelps/homepage.git /opt/homepage &>/dev/null cd /opt/homepage mkdir -p config -pnpm install &>/dev/null -pnpm build &>/dev/null +npm install &>/dev/null +npm run build &>/dev/null msg_ok "Installed Homepage" msg_info "Creating Service" From d6bea05d9de3e2db823ae3b64bfe3a6b2eba49e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:05:41 -0400 Subject: [PATCH 3471/6505] Create CONTRIBUTING.md --- .github/CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/CONTRIBUTING.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..2f938e25 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,5 @@ +# Contributing to Proxmox Helper Scripts + +Everybody is invited and welcome to contribute to Proxmox Helper Scripts. + +- Pull requests are always created against the [**pull-requests**](https://github.com/tteck/Proxmox/tree/pull-requests) branch. From 53ab4ea2c2490d8f332cd4aca446cbac2782b3b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:10:39 -0400 Subject: [PATCH 3472/6505] Create CODE_OF_CONDUCT.md --- .github/CODE_OF_CONDUCT.md | 132 +++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..4cf8cff5 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations From ea44c02315d56b86807a953ff75fd4efb4e451ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:21:29 -0400 Subject: [PATCH 3473/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. From e6938f8b3f2328d2c7e729194d8330002e573f61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:26:14 -0400 Subject: [PATCH 3474/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..69da9eac --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: Feature Request +labels: Feature Request +assignees: tteck + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 8c614be4984995f145e758a2520f573dda869a7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:29:21 -0400 Subject: [PATCH 3475/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea78..ccb3b3f9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,9 +1,9 @@ --- name: Bug report about: Create a report to help us improve -title: '' -labels: '' -assignees: '' +title: BUG +labels: bug +assignees: tteck --- @@ -12,10 +12,6 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error **Expected behavior** A clear and concise description of what you expected to happen. @@ -23,16 +19,5 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] - **Additional context** Add any other context about the problem here. From 3d57ef88c96a1b4dff2abaae6891ce53e16c0015 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:36:06 -0400 Subject: [PATCH 3476/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ccb3b3f9..d029a230 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,7 @@ --- name: Bug report about: Create a report to help us improve -title: BUG +title: '' labels: bug assignees: tteck @@ -10,12 +10,6 @@ assignees: tteck **Describe the bug** A clear and concise description of what the bug is. -**To Reproduce** -Steps to reproduce the behavior: - -**Expected behavior** -A clear and concise description of what you expected to happen. - **Screenshots** If applicable, add screenshots to help explain your problem. From 2bdef16284e948153ad3e87bca729c76076c339b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:37:41 -0400 Subject: [PATCH 3477/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 69da9eac..ea28cca8 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: Feature Request +title: '' labels: Feature Request assignees: tteck From a490ca5aacd42fd7ae1f01e6a9fafe3cd78111c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:44:27 -0400 Subject: [PATCH 3478/6505] Create pull_request_template.md --- .github/pull_request_template.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1 @@ + From 9af7ce69f375708b124adfadf92db708b96ca4cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Sep 2022 23:52:52 -0400 Subject: [PATCH 3479/6505] Update pull_request_template.md --- .github/pull_request_template.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8b137891..ef2d9b8f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1 +1,16 @@ +# Pull Request Template +## Description + +Please include a summary of the change and/or which issue is fixed. + +Fixes # (issue) + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug fix +- [ ] New feature +- [ ] New Script +- [ ] This change requires a documentation update From a65a27ad89628a782dd86396370ffcc3af7fdbe8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:01:08 -0400 Subject: [PATCH 3480/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature_request.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index ea28cca8..66a63d73 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,14 +7,4 @@ assignees: tteck --- -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. +**Please submit feature request to the [discussions](https://github.com/tteck/Proxmox/discussions)area.** From 2d451515c2316dff4117b8eea20a4954c01ba7af Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:03:35 -0400 Subject: [PATCH 3481/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 66a63d73..aaae8874 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,4 +7,4 @@ assignees: tteck --- -**Please submit feature request to the [discussions](https://github.com/tteck/Proxmox/discussions)area.** +**Please submit feature request to [discussions](https://github.com/tteck/Proxmox/discussions)** From a6d4c68753a6539cab1433c4a7c8d2fc22f39c0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:09:05 -0400 Subject: [PATCH 3482/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index aaae8874..f129ea0e 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: '' +title: "**Please submit feature request to [discussions](https://github.com/tteck/Proxmox/discussions)**" labels: Feature Request assignees: tteck From 23a1ab5789ebb6a2932ce7193cfc1e7967bf34a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:15:26 -0400 Subject: [PATCH 3483/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature-script-request.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature-script-request.md diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.md b/.github/ISSUE_TEMPLATE/feature-script-request.md new file mode 100644 index 00000000..45cb200f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-script-request.md @@ -0,0 +1,11 @@ +--- +name: Feature/Script Request +about: Suggest an idea for this project +title: Please submit feature/script requests to Discussions +labels: Feature Request +assignees: tteck + +--- + +Please submit feature request to Discussions +https://github.com/tteck/Proxmox/discussions From 37d4df6beab09f4729c495e1aa8a8557c9e5ff6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:17:48 -0400 Subject: [PATCH 3484/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature-script-request.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.md b/.github/ISSUE_TEMPLATE/feature-script-request.md index 45cb200f..22265d7c 100644 --- a/.github/ISSUE_TEMPLATE/feature-script-request.md +++ b/.github/ISSUE_TEMPLATE/feature-script-request.md @@ -7,5 +7,5 @@ assignees: tteck --- -Please submit feature request to Discussions +Please submit feature/script requests to Discussions https://github.com/tteck/Proxmox/discussions diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index f129ea0e..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "**Please submit feature request to [discussions](https://github.com/tteck/Proxmox/discussions)**" -labels: Feature Request -assignees: tteck - ---- - -**Please submit feature request to [discussions](https://github.com/tteck/Proxmox/discussions)** From 057b26539df687261fe47586ea44a6cbd1644555 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:23:43 -0400 Subject: [PATCH 3485/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d029a230..5ed782af 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -15,3 +15,5 @@ If applicable, add screenshots to help explain your problem. **Additional context** Add any other context about the problem here. + +**Bug reports will be closed after 12 hours of NO communication.** From 09df541b3997058b3ecdd784340aaa044326fa93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:29:04 -0400 Subject: [PATCH 3486/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 5ed782af..942ae955 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -17,3 +17,8 @@ If applicable, add screenshots to help explain your problem. Add any other context about the problem here. **Bug reports will be closed after 12 hours of NO communication.** + +As the saying goes... +It’s not DNS +There’s no way it’s DNS +It was DNS From 1b0f173ffc3077f7e8e2f5569a7e9d1a6fa94a95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:42:34 -0400 Subject: [PATCH 3487/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 942ae955..5731f240 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Create a report to help us improve +about: Create a report to help us improve (script related) title: '' labels: bug assignees: tteck From 20b2c069c8198914c0db841f6391209bdc96427a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 00:49:02 -0400 Subject: [PATCH 3488/6505] Update issue templates --- .github/ISSUE_TEMPLATE/feature-script-request.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.md b/.github/ISSUE_TEMPLATE/feature-script-request.md index 22265d7c..ddcfa3a4 100644 --- a/.github/ISSUE_TEMPLATE/feature-script-request.md +++ b/.github/ISSUE_TEMPLATE/feature-script-request.md @@ -1,11 +1,11 @@ --- name: Feature/Script Request -about: Suggest an idea for this project -title: Please submit feature/script requests to Discussions +about: Suggest an idea for this project in Discussions +title: Please submit feature/script requests in Discussions labels: Feature Request assignees: tteck --- -Please submit feature/script requests to Discussions +Please submit feature/script requests in Discussions https://github.com/tteck/Proxmox/discussions From 9d41a71a2c81026d01acff6856659171d018bdc6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 01:03:38 -0400 Subject: [PATCH 3489/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 776a1ed6..d7715b60 100644 --- a/README.md +++ b/README.md @@ -2003,7 +2003,7 @@ ________________________________________________________________________________
    - 🔸Syncthing LXC + Syncthing LXC

    From 0f5f9273dfe075fab3b65fdbb99f8e0fc74dceca Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 06:57:25 -0400 Subject: [PATCH 3490/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 5731f240..09e6995c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -16,7 +16,7 @@ If applicable, add screenshots to help explain your problem. **Additional context** Add any other context about the problem here. -**Bug reports will be closed after 12 hours of NO communication.** +**Bug reports will be closed after 12 hours of NO activity.** As the saying goes... It’s not DNS From 7ba8391cca61e57e8e4f0de8bbd9c9d6590c7fe6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 09:30:42 -0400 Subject: [PATCH 3491/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 09e6995c..1b3a752e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,18 +7,10 @@ assignees: tteck --- -**Describe the bug** +**Describe the issue** A clear and concise description of what the bug is. **Screenshots** If applicable, add screenshots to help explain your problem. -**Additional context** -Add any other context about the problem here. - **Bug reports will be closed after 12 hours of NO activity.** - -As the saying goes... -It’s not DNS -There’s no way it’s DNS -It was DNS From 58d56ef28c8f794c1b8ccf30c10ce0e11da2e1a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 12:05:13 -0400 Subject: [PATCH 3492/6505] Update homepage-install.sh --- setup/homepage-install.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 127ea407..833d35a6 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -74,20 +74,20 @@ apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null +curl -fsSL https://deb.nodesource.com/setup_14.x | bash - &>/dev/null msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null -# npm install -g pnpm &>/dev/null +npm install -g pnpm &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Homepage" git clone https://github.com/benphelps/homepage.git /opt/homepage &>/dev/null cd /opt/homepage mkdir -p config -npm install &>/dev/null -npm run build &>/dev/null +pnpm install &>/dev/null +pnpm build &>/dev/null msg_ok "Installed Homepage" msg_info "Creating Service" @@ -102,7 +102,7 @@ Restart=always RestartSec=1 User=root WorkingDirectory=/opt/homepage/ -ExecStart=npm start +ExecStart=pnpm start [Install] WantedBy=multi-user.target" > $service_path systemctl enable --now homepage &>/dev/null From c06f7afce96c1652852485daff16c0af4ef88956 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 12:16:27 -0400 Subject: [PATCH 3493/6505] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1b3a752e..dae485c8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,8 +2,8 @@ name: Bug report about: Create a report to help us improve (script related) title: '' -labels: bug -assignees: tteck +labels: '' +assignees: '' --- From fbab8319539eb074008ab0d4620cc87565acbfae Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 21:18:04 -0400 Subject: [PATCH 3494/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 5c4f39b6..9d515ac3 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -56,6 +56,7 @@ msg_ok "Stopped Paperless-ngx" msg_info "Updating to ${RELEASE}" wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null +cp -r /opt/paperless/paperless.conf paperless-ngx/ cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless pip install -r requirements.txt &>/dev/null From e9e10555dd251410f4e2c2a39219679f52588c87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 21:40:44 -0400 Subject: [PATCH 3495/6505] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index d7715b60..94f286ce 100644 --- a/README.md +++ b/README.md @@ -1533,6 +1533,13 @@ Run in the LXC Console ```yaml cat paperless.creds ``` + +⚙️ **To Update Paperless-ngx** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/paperless-ngx-update.sh)" +``` ____________________________________________________________________________________________
    From cd10962216f73ce732d645b593ae9dbe1451dcdf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Sep 2022 22:36:28 -0400 Subject: [PATCH 3496/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 94f286ce..8521283c 100644 --- a/README.md +++ b/README.md @@ -1545,7 +1545,7 @@ ________________________________________________________________________________
    - 🔸Trilium LXC + Trilium LXC

    From fe7754808385adeff8912450c1d9c4530f6f2c47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 09:31:49 -0400 Subject: [PATCH 3497/6505] Create omv-v4.sh --- ct/omv-v4.sh | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 ct/omv-v4.sh diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh new file mode 100644 index 00000000..c03834b1 --- /dev/null +++ b/ct/omv-v4.sh @@ -0,0 +1,265 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="OMV" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + ____ __ ___ ___ _ __ ____ + / __ \____v4___ ____ / |/ /__ ____/ (_)___ | | / /___ ___ __/ / /_ + / / / / __ \/ _ \/ __ \/ /|_/ / _ \/ __ / / __ `/ | / / __ `/ / / / / __/ +/ /_/ / /_/ / __/ / / / / / / __/ /_/ / / /_/ /| |/ / /_/ / /_/ / / /_ +\____/ .___/\___/_/ /_/_/ /_/\___/\__,_/_/\__,_/ |___/\__,_/\__,_/_/\__/ + /_/ +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From af6454abd044d287ccc574d71bea3f2dac1cfdec Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 09:33:12 -0400 Subject: [PATCH 3498/6505] Create omv-install.sh --- setup/omv-install.sh | 118 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 setup/omv-install.sh diff --git a/setup/omv-install.sh b/setup/omv-install.sh new file mode 100644 index 00000000..0f553a62 --- /dev/null +++ b/setup/omv-install.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +export DEBIAN_FRONTEND=noninteractive +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing OpenMediaVault (Patience)" +wget -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key &>/dev/null +apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" &>/dev/null + +cat <> /etc/apt/sources.list.d/openmediavault.list +deb https://packages.openmediavault.org/public shaitan main +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main +## Uncomment the following line to add software from the proposed repository. +# deb https://packages.openmediavault.org/public shaitan-proposed main +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan-proposed main +## This software is not part of OpenMediaVault, but is offered by third-party +## developers as a service to OpenMediaVault users. +# deb https://packages.openmediavault.org/public shaitan partner +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner +EOF +apt-get update &>/dev/null +apt-get -y install openmediavault-keyring &>/dev/null +apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends install openmediavault &>/dev/null +omv-confdbadm populate +msg_ok "Installed OpenMediaVault" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 65c99088c9d97bba0683285573f8c5b01d2c2a94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 09:44:51 -0400 Subject: [PATCH 3499/6505] Add files via upload --- misc/images/omv.png | Bin 0 -> 2795 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/omv.png diff --git a/misc/images/omv.png b/misc/images/omv.png new file mode 100644 index 0000000000000000000000000000000000000000..b8de99c57387f34f2dcaa52fdf4cf9753d08b70f GIT binary patch literal 2795 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 GM)GfN<%gdD literal 0 HcmV?d00001 From 30a89363a3d5274efc40f6a4d0a5a9abbc135a95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 09:52:46 -0400 Subject: [PATCH 3500/6505] Update README.md --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index 8521283c..9fe01cc4 100644 --- a/README.md +++ b/README.md @@ -1788,6 +1788,40 @@ ________________________________________________________________________________
    +
    + 🔸OpenMediaVault LXC + +

    + +

    OpenMediaVault LXC

    + +[OpenMediaVault](https://www.openmediavault.org/) is the next generation network attached storage (NAS) solution based on Debian Linux. + +To create a new Proxmox OpenMediaVault LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omv-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +**OpenMediaVault Interface - IP** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + openmediavault + ``` + +____________________________________________________________________________________________ + +
    +
    Navidrome LXC From 4bcec067e19e40d5105971154552a10913ed68e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 09:53:51 -0400 Subject: [PATCH 3501/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 33c2b4fd..2bf2047e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-20 + +### Changed + +- **OpenMediaVault LXC** + - NEW Script + ## 2022-09-16 ### Changed From 3d1c964d204b0a08d4afb94622b1f98d46e82905 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 12:37:36 -0400 Subject: [PATCH 3502/6505] Update pihole-install.sh Code refactoring --- setup/pihole-install.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index c27e7ea4..3d6a0e4d 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +export DEBIAN_FRONTEND=noninteractive YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` @@ -76,8 +77,24 @@ apt-get install -y ntp &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Pi-hole" -wget -O tteck-install.sh https://install.pi-hole.net &>/dev/null -bash tteck-install.sh +mkdir -p /etc/pihole/ +cat < /etc/pihole/setupVars.conf +PIHOLE_INTERFACE=eth0 +PIHOLE_DNS_1=8.8.8.8 +PIHOLE_DNS_2=8.8.4.4 +QUERY_LOGGING=true +INSTALL_WEB_SERVER=true +INSTALL_WEB_INTERFACE=true +LIGHTTPD_ENABLED=true +CACHE_SIZE=10000 +DNS_FQDN_REQUIRED=true +DNS_BOGUS_PRIV=true +DNSMASQ_LISTENING=local +WEBPASSWORD=$(openssl rand -base64 48) +BLOCKING_ENABLED=true +EOF + +curl -sSL https://install.pi-hole.net | bash /dev/stdin --unattended &>/dev/null msg_ok "Installed Pi-hole" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -101,5 +118,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/tteck-install.sh msg_ok "Cleaned" From 94b7ef3ebb7c7dd13b9201cad35e98b254efc2e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 12:48:55 -0400 Subject: [PATCH 3503/6505] Update README.md --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9fe01cc4..4e410be7 100644 --- a/README.md +++ b/README.md @@ -1376,6 +1376,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v4.sh ⚠️ **Reboot Pi-hole LXC after install** +**Pi-hole Interface - http:// IP/admin** + ⚙️ **To set your password:** Run in the LXC console @@ -1383,12 +1385,6 @@ Run in the LXC console ```yaml pihole -a -p ``` -⚙️ **To Update Pi-hole:** - -```yaml -Update from the Pi-hole UI -``` - ____________________________________________________________________________________________
    From 46d83226f8b1f9f0e2023e455bf21f55d3017a2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 13:03:29 -0400 Subject: [PATCH 3504/6505] Update mariadb-install.sh Make installing Adminer an option --- setup/mariadb-install.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index c9025669..15acb821 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -79,11 +79,21 @@ apt-get update >/dev/null apt-get install -y mariadb-server &>/dev/null msg_ok "Installed MariaDB" +read -r -p "Would you like to add Adminer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +ADMINER="Y" +else +ADMINER="N" +fi + +if [[ $ADMINER == "Y" ]]; then msg_info "Installing Adminer" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null msg_ok "Installed Adminer" +fi PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then @@ -106,7 +116,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -mkdir /var/log/apache2 -chmod 750 /var/log/apache2 msg_ok "Cleaned" From 9b5749b5da5ae5fc3703d60cb619c363ed6508cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 13:11:45 -0400 Subject: [PATCH 3505/6505] Update postgresql-install.sh Make installing Adminer an option --- setup/postgresql-install.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 175011f8..7d68b81d 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -971,11 +971,21 @@ EOF sudo systemctl restart postgresql msg_ok "Installed PostgreSQL" +read -r -p "Would you like to add Adminer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +ADMINER="Y" +else +ADMINER="N" +fi + +if [[ $ADMINER == "Y" ]]; then msg_info "Installing Adminer" sudo apt install adminer -y &>/dev/null sudo a2enconf adminer &>/dev/null sudo systemctl reload apache2 &>/dev/null msg_ok "Installed Adminer" +fi PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then @@ -997,7 +1007,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* -mkdir /var/log/apache2 -chmod 750 /var/log/apache2 msg_ok "Cleaned" From 04a27156302f10f55a80170fdd66442c197d5ed4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 13:14:21 -0400 Subject: [PATCH 3506/6505] Update mariadb-v4.sh --- ct/mariadb-v4.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index 771db328..3187a6d1 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -250,5 +250,3 @@ pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" -echo -e "Adminer should be reachable by going to the following URL. - ${BL}http://${IP}/adminer/${CL} \n" From 90131ef6138c0d9bd9335c09a38972d64ad08d39 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 13:15:03 -0400 Subject: [PATCH 3507/6505] Update postgresql-v4.sh --- ct/postgresql-v4.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index 230fa91f..ef9302e0 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -251,5 +251,3 @@ pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" -echo -e "Adminer should be reachable by going to the following URL. - ${BL}http://${IP}/adminer/${CL} \n" From eb3d31193f49d64e49aea94275dc42942f53e820 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Sep 2022 13:21:27 -0400 Subject: [PATCH 3508/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4e410be7..fc113c8e 100644 --- a/README.md +++ b/README.md @@ -619,6 +619,7 @@ ________________________________________________________________________________

    MariaDB

    Mariadb LXC

    +

    Option to Install Adminer

    [MariaDB](https://mariadb.org/) is a community-developed, commercially supported fork of the MySQL relational database management system. @@ -736,6 +737,7 @@ ________________________________________________________________________________

    PostgreSQL LXC

    +

    Option to Install Adminer

    [PostgreSQL](https://www.postgresql.org/), also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance. From a1d426d81d3111b58e2ce082576ec578aebd560b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 02:35:37 -0400 Subject: [PATCH 3509/6505] Update jellyfin-v4.sh remove 22.04 as an option for now --- ct/jellyfin-v4.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index bee0357b..88334668 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -98,11 +98,10 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "21.10" "Impish" OFF \ -"22.04" "Jammy" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then From e643fb6332cf07c8de1b5f4d9041d25e2e85875c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 02:38:51 -0400 Subject: [PATCH 3510/6505] Update emby-v4.sh remove 22.04 as an option for now --- ct/emby-v4.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 6ea1bcec..db03bdfa 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -98,11 +98,10 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "21.10" "Impish" OFF \ -"22.04" "Jammy" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then From cf4685077320c29812908dd1a6e27a5b7fc70bf7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 02:39:36 -0400 Subject: [PATCH 3511/6505] Update plex-v4.sh remove 22.04 as an option for now --- ct/plex-v4.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index cad50e02..0cbeeb10 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -98,11 +98,10 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "21.10" "Impish" OFF \ -"22.04" "Jammy" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then From 47e5cea8e51bb65ce7b109bb1a3d38cfdbb05508 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 08:00:55 -0400 Subject: [PATCH 3512/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index c5d9b23f..239ccee9 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -71,11 +71,11 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -apt-get install -y runc &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Podman" apt-get -y install podman &>/dev/null +systemctl enable --now podman.socket &>/dev/null msg_ok "Installed Podman" msg_info "Pulling Yacht Image" @@ -145,5 +145,4 @@ systemctl enable yacht &>/dev/null msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" From 95537511399b2179af48e93f5ac610dac7cc5485 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 08:23:35 -0400 Subject: [PATCH 3513/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 239ccee9..9a2ca71f 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -78,6 +78,15 @@ apt-get -y install podman &>/dev/null systemctl enable --now podman.socket &>/dev/null msg_ok "Installed Podman" +read -r -p "Would you like to add Yacht (Semifunctional)? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +YACHT="Y" +else +YACHT="N" +fi + +if [[ $YACHT == "Y" ]]; then msg_info "Pulling Yacht Image" podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null msg_ok "Pulled Yacht Image" @@ -94,8 +103,12 @@ podman run -d \ -v /etc/timezone:/etc/timezone:ro \ -p 8000:8000 \ selfhostedpro/yacht:latest &>/dev/null +podman generate systemd \ + --new --name yacht \ + > /etc/systemd/system/yacht.service +systemctl enable yacht &>/dev/null msg_ok "Installed Yacht" - +fi msg_info "Pulling Home Assistant Image" podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null msg_ok "Pulled Home Assistant Image" @@ -137,11 +150,6 @@ podman generate systemd \ > /etc/systemd/system/homeassistant.service systemctl enable homeassistant &>/dev/null -podman generate systemd \ - --new --name yacht \ - > /etc/systemd/system/yacht.service -systemctl enable yacht &>/dev/null - msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null From e9658f3e3afa319d801accfee94f8514bd885cfc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 08:39:26 -0400 Subject: [PATCH 3514/6505] Update podman-homeassistant-install.sh --- setup/podman-homeassistant-install.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 9a2ca71f..9a885507 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -125,6 +125,10 @@ podman run -d \ -v /etc/timezone:/etc/timezone:ro \ --net=host \ homeassistant/home-assistant:stable &>/dev/null +podman generate systemd \ + --new --name homeassistant \ + > /etc/systemd/system/homeassistant.service +systemctl enable homeassistant &>/dev/null msg_ok "Installed Home Assistant" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -144,12 +148,7 @@ systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi - -podman generate systemd \ - --new --name homeassistant \ - > /etc/systemd/system/homeassistant.service -systemctl enable homeassistant &>/dev/null - + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null From ac878833a922ae3a60f6f828e9676dae36d3ccc1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 12:22:29 -0400 Subject: [PATCH 3515/6505] Update post-install.sh --- misc/post-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/misc/post-install.sh b/misc/post-install.sh index 73c32268..21654ffd 100644 --- a/misc/post-install.sh +++ b/misc/post-install.sh @@ -22,6 +22,12 @@ while true; do * ) echo "Please answer yes or no.";; esac done + +if ! command -v pveversion >/dev/null 2>&1; then + echo -e "\n🛑 No PVE Detected, Wrong Script!\n" + exit 1 +fi + if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then echo -e "\n${RD}⚠ This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version: 7.XX${CL}" From 67f23a220b0847a3f95b5366f5edc6eabc2387fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 12:25:28 -0400 Subject: [PATCH 3516/6505] Create post-pbs-install.sh --- misc/post-pbs-install.sh | 126 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 misc/post-pbs-install.sh diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh new file mode 100644 index 00000000..c73c1cfb --- /dev/null +++ b/misc/post-pbs-install.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash -ex +set -euo pipefail +shopt -s inherit_errexit nullglob +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +clear +echo -e "${BL}This script will Perform Post Install Routines.${CL}" +while true; do + read -p "Start the PBS Post Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +if command -v pveversion >/dev/null 2>&1; then + echo -e "\n🛑 PVE Detected, Wrong Script!\n" + exit 1 +fi + +function header_info { +cat << "EOF" + ____ ____ _____ ____ __ ____ __ ____ + / __ \/ __ ) ___/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / __ \__ \ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / + / ____/ /_/ /__/ / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ /_____/____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + +EOF +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +clear +header_info +read -r -p "Disable Enterprise Repository? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Disabling Enterprise Repository" +sleep 2 +sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pbs-enterprise.list +msg_ok "Disabled Enterprise Repository" +fi + +read -r -p "Add/Correct PBS Sources (sources.list)? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Adding or Correcting PBS Sources" +cat < /etc/apt/sources.list +deb http://ftp.debian.org/debian bullseye main contrib +deb http://ftp.debian.org/debian bullseye-updates main contrib +deb http://security.debian.org/debian-security bullseye-security main contrib +EOF +sleep 2 +msg_ok "Added or Corrected PBS Sources" +fi + +read -r -p "Enable No-Subscription Repository? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Enabling No-Subscription Repository" +cat <> /etc/apt/sources.list +deb http://download.proxmox.com/debian/pbs bullseye pbs-no-subscription +EOF +sleep 2 +msg_ok "Enabled No-Subscription Repository" +fi + +read -r -p "Add (Disabled) Beta/Test Repository? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Adding Beta/Test Repository and set disabled" +cat <> /etc/apt/sources.list +# deb http://download.proxmox.com/debian/pbs bullseye pbstest +EOF +sleep 2 +msg_ok "Added Beta/Test Repository" +fi + +read -r -p "Disable Subscription Nag? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Disabling Subscription Nag" +echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script +apt --reinstall install proxmox-widget-toolkit &>/dev/null +msg_ok "Disabled Subscription Nag" +fi + +read -r -p "Update Proxmox Backup Server now? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Updating Proxmox Backup Server (Patience)" +apt-get update &>/dev/null +apt-get -y dist-upgrade &>/dev/null +msg_ok "Updated Proxmox Backup Server (⚠ Reboot Recommended)" +fi + +read -r -p "Reboot Proxmox Backup Server now? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +msg_info "Rebooting Proxmox Backup Server" +sleep 2 +msg_ok "Completed Post Install Routines" +reboot +fi + +sleep 2 +msg_ok "Completed Post Install Routines" From 3fa9f13f7074f0d39342e844dad05e3f662353fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 12:45:14 -0400 Subject: [PATCH 3517/6505] Rename post-install.sh to post-pve-install.sh --- misc/{post-install.sh => post-pve-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename misc/{post-install.sh => post-pve-install.sh} (100%) diff --git a/misc/post-install.sh b/misc/post-pve-install.sh similarity index 100% rename from misc/post-install.sh rename to misc/post-pve-install.sh From 53dadc68739b002d0f2f8c6f84cf77cd63ddb60b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 12:46:02 -0400 Subject: [PATCH 3518/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc113c8e..c915ba57 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 So Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-install.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pve-install.sh)" ``` It's recommended to answer `y` to all options. From 934614619b3f410d41bcafbae272709fca74a67b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 13:20:08 -0400 Subject: [PATCH 3519/6505] Update README.md --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index c915ba57..c019be3f 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,26 @@ ________________________________________________________________________________
    +
    + 🔸Proxmox Backup Server Post Install + +

    + +

    Proxmox Backup Server Post Install

    + +The script will give options to Disable the Enterprise Repo, Add/Correct PBS Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox Backup Server and Reboot PBS. + +Run the following in the Proxmox Shell. ⚠️ **Proxmox Backup Server ONLY** + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pbs-install.sh)" +``` + +It's recommended to answer `y` to all options. + +____________________________________________________________________________________________ + +
    Home Assistant OS VM From 14aaaa47e4afa44f0e7f497f70b3b7ec07eb5c89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 13:55:26 -0400 Subject: [PATCH 3520/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2bf2047e..5e25d802 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-21 + +### Changed + +- **Proxmox Backup Server Post Install** + - NEW Script + ## 2022-09-20 ### Changed From 52364ed5d02150523c205e4f50cd2d470bf7a044 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 17:43:10 -0400 Subject: [PATCH 3521/6505] Update zwave-copy-data.sh --- misc/zwave-copy-data.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/misc/zwave-copy-data.sh b/misc/zwave-copy-data.sh index 728fbaf7..4b6de0d1 100644 --- a/misc/zwave-copy-data.sh +++ b/misc/zwave-copy-data.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Use to copy all data from one Zwavejs2MQTT LXC to another +# Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwave-copy-data.sh)" while true; do - read -p "Use to copy all data from one Zwavejs2MQTT LXC to another. Proceed(y/n)?" yn + read -p "Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; @@ -51,7 +51,7 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -TITLE="Zigbee2MQTT LXC Data Copy" +TITLE="Zigbee2MQTT to Z-wave JS UI Data Copy" while read -r line; do TAG=$(echo "$line" | awk '{print $1}') ITEM=$(echo "$line" | awk '{print substr($0,36)}') @@ -69,7 +69,7 @@ while [ -z "${CTID_FROM:+x}" ]; do done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Zwavejs2MQTT LXC would you like to copy TO?\n" \ + "\nWhich Z-wave JS UI LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done @@ -82,7 +82,7 @@ done whiptail --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) -Version: 2022.03.06" 13 50 || exit +Version: 2022.09.21" 13 50 || exit info "Zwavejs2MQTT Data from '$CTID_FROM' to '$CTID_TO'" if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then msg "Stopping '$CTID_TO'..." @@ -90,13 +90,14 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then fi msg "Mounting Container Disks..." DATA_PATH=/opt/zwavejs2mqtt/store/ +DATA_PATH_NEW=/opt/zwave-js-ui/store/ CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ die "Zwavejs2MQTT directories in '$CTID_FROM' not found." CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${DATA_PATH_NEW}" ] || \ die "Zwavejs2MQTT directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} @@ -111,8 +112,8 @@ RSYNC_OPTIONS=( --no-inc-recursive --info=progress2 ) -msg "<======== Zwavejs2MQTT Data ========>" -rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH} +msg "<======== Zwavejs Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH_NEW} echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." From 7d85d7de4570bf18fa28181496a984af38100641 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 17:48:01 -0400 Subject: [PATCH 3522/6505] Update and rename zwavejs2mqtt-update.sh to zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 39 ++++++++++++++++++++++++++ misc/zwavejs2mqtt-update.sh | 56 ------------------------------------- 2 files changed, 39 insertions(+), 56 deletions(-) create mode 100644 misc/zwave-js-ui-update.sh delete mode 100644 misc/zwavejs2mqtt-update.sh diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh new file mode 100644 index 00000000..f0948ee1 --- /dev/null +++ b/misc/zwave-js-ui-update.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -e +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +CM='\xE2\x9C\x94\033' +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +echo -en "${GN} Updating Z-wave JS UI... " +systemctl stop zwave-js-ui.service +cd /opt/zwavejs2mqtt +curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null +unzip zwave-js-ui-v*.zip zwave-js-ui &>/dev/null +echo -e "${CM}${CL} \r" + +echo -en "${GN} Cleanup... " +rm zwave-js-ui-v*.zip +systemctl --system daemon-reload +systemctl start zwave-js-ui.service +echo -e "${CM}${CL} \n" + +echo -e "${GN} Finished ${CL}" + diff --git a/misc/zwavejs2mqtt-update.sh b/misc/zwavejs2mqtt-update.sh deleted file mode 100644 index cf02af01..00000000 --- a/misc/zwavejs2mqtt-update.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -set -e -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -echo -en "${GN} Updating Zwavejs2MQTT... " -systemctl stop zwavejs2mqtt.service -cd /opt/zwavejs2mqtt -curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null -unzip -o zwavejs2mqtt-v*.zip zwavejs2mqtt &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Checking Service... " -SERVICE=/etc/systemd/system/zwavejs2mqtt.service -cat < $SERVICE -[Unit] -Description=ZWavejs2MQTT -Wants=network-online.target -After=network-online.target -[Service] -User=root -WorkingDirectory=/opt/zwavejs2mqtt -ExecStart=/opt/zwavejs2mqtt/zwavejs2mqtt -[Install] -WantedBy=multi-user.target -EOF -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm zwavejs2mqtt-v*.zip -systemctl --system daemon-reload -systemctl start zwavejs2mqtt.service -systemctl enable zwavejs2mqtt.service &>/dev/null -echo -e "${CM}${CL} \n" - -echo -e "${GN} Finished ${CL}" - From 855d5e3a9a7aeeb2a896aa6be0adc47e7cadb6e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 17:54:27 -0400 Subject: [PATCH 3523/6505] Update and rename zwavejs2mqtt-v4.sh to zwave-js-ui-v4.sh --- ct/{zwavejs2mqtt-v4.sh => zwave-js-ui-v4.sh} | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) rename ct/{zwavejs2mqtt-v4.sh => zwave-js-ui-v4.sh} (94%) diff --git a/ct/zwavejs2mqtt-v4.sh b/ct/zwave-js-ui-v4.sh similarity index 94% rename from ct/zwavejs2mqtt-v4.sh rename to ct/zwave-js-ui-v4.sh index 56fe0f5c..ab9fc567 100644 --- a/ct/zwavejs2mqtt-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash echo -e "Loading..." -APP="Zwavejs2MQTT" +APP="Zwave-JS-UI" var_disk="4" var_cpu="2" var_ram="1024" @@ -43,14 +43,14 @@ else exit fi function header_info { -echo -e "${BL} - _____ _ ___ __ _______ ____________ -/__ /_ ______ __ _____ (_)___|__ \ / |/ / __ \/_ __/_ __/ - / /| | /| / / __ / | / / _ \ / / ___/_/ // /|_/ / / / / / / / / - / /_| |/ |/ / /_/ /| |/ / __/ / (__ ) __// / / / /_/ / / / / / -/____/__/|__/\__,_/ |___/\___/_/ /____/____/_/ /_/\___\_\/_/ v4/_/ - /___/ -${CL}" +cat << "EOF" + _____ _______ __ ______ +/__ /_ ______ __v4 _____ / / ___/ / / / / _/ + / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / + / /_| |/ |/ / /_/ /| |/ / __/ / /_/ /___/ / / /_/ // / +/____/__/|__/\__,_/ |___/\___/ \____//____/ \____/___/ + +EOF } function msg_info() { local msg="$1" From 2531e299daa30142c36ba1768681ec0071246903 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 17:55:58 -0400 Subject: [PATCH 3524/6505] Update and rename zwavejs2mqtt-install.sh to zwave-js-ui-install.sh --- ...mqtt-install.sh => zwave-js-ui-install.sh} | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) rename setup/{zwavejs2mqtt-install.sh => zwave-js-ui-install.sh} (81%) diff --git a/setup/zwavejs2mqtt-install.sh b/setup/zwave-js-ui-install.sh similarity index 81% rename from setup/zwavejs2mqtt-install.sh rename to setup/zwave-js-ui-install.sh index c439b9c8..8948e19b 100644 --- a/setup/zwavejs2mqtt-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -74,28 +74,28 @@ apt-get install -y sudo &>/dev/null apt-get install -y unzip &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing Zwavejs2MQTT" -mkdir /opt/zwavejs2mqtt -cd /opt/zwavejs2mqtt +msg_info "Installing Z-Wave JS UI" +mkdir /opt/zwave-js-ui +cd /opt/zwave-js-ui mkdir store -curl -s https://api.github.com/repos/zwave-js/zwavejs2mqtt/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null -unzip zwavejs2mqtt-v*.zip zwavejs2mqtt &>/dev/null -msg_ok "Installed Zwavejs2MQTT" +curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null +unzip zwave-js-ui-v*.zip zwave-js-ui &>/dev/null +msg_ok "Installed Z-Wave JS UI" msg_info "Creating Service" -service_path="/etc/systemd/system/zwavejs2mqtt.service" +service_path="/etc/systemd/system/zwave-js-ui.service" echo "[Unit] -Description=ZWavejs2MQTT +Description=zwave-js-ui Wants=network-online.target After=network-online.target [Service] User=root -WorkingDirectory=/opt/zwavejs2mqtt -ExecStart=/opt/zwavejs2mqtt/zwavejs2mqtt +WorkingDirectory=/opt/zwave-js-ui +ExecStart=/opt/zwave-js-ui/zwave-js-ui [Install] WantedBy=multi-user.target" > $service_path -systemctl start zwavejs2mqtt -systemctl enable zwavejs2mqtt &>/dev/null +systemctl start zwave-js-ui +systemctl enable zwave-js-ui &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -117,8 +117,7 @@ msg_ok "Customized Container" fi msg_info "Cleaning up" -rm zwavejs2mqtt-v*.zip +rm zwave-js-ui-v*.zip apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" From e5581a5f3fdec1def850914b69051d096ca89298 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 17:59:02 -0400 Subject: [PATCH 3525/6505] Update README.md --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c019be3f..e7aea991 100644 --- a/README.md +++ b/README.md @@ -937,38 +937,37 @@ ________________________________________________________________________________
    - Zwavejs2MQTT LXC + 🔸Z-Wave JS UI LXC -

    +

    Zwavejs2MQTT LXC

    -[Zwavejs2MQTT](https://zwave-js.github.io/zwavejs2mqtt/#/) is a fully configurable Z-Wave to MQTT Gateway and Control Panel. +[Z-Wave JS UI](https://github.com/zwave-js/zwave-js-ui#) is a fully configurable Z-Wave to MQTT Gateway and Control Panel. -To create a new Proxmox Zwavejs2MQTT LXC, run the following in the Proxmox Shell. +To create a new Proxmox Z-Wave JS UI LXC, run the following in the Proxmox Shell. ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwavejs2mqtt-v4.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwave-js-ui-v4.sh)" ```

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    -**Zwavejs2MQTT Interface - IP:8091** +**Z-Wave JS UI Interface - IP:8091** -⚙️ **Copy Data From a Existing Zwavejs2MQTT LXC to another Zwavejs2MQTT LXC** +⚙️ **Copy Data From a Existing Zwavejs2MQTT LXC to a Z-Wave JS UI LXC** Run in the Proxmox Shell ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-copy-data.sh)" ``` -⚙️ **To Update Zwavejs2MQTT** +⚙️ **To Update Z-Wave JS UI** Run in the LXC Console ```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwavejs2mqtt-update.sh)" +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-js-ui-update.sh)" ``` ____________________________________________________________________________________________ -
    From 6f2c2fddd10ab152144968eba49369667d208ba6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Sep 2022 18:06:16 -0400 Subject: [PATCH 3526/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 5e25d802..572a8e51 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,10 @@ All notable changes to this project will be documented in this file. - **Proxmox Backup Server Post Install** - NEW Script +- **Z-wave JS UI LXC** + - NEW Script (and all sub scripts 🤞) +- **Zwave2MQTT LXC** + - Bye Bye Script ## 2022-09-20 From 8c60ea7a952dfd5b8b3b8c90b5f722403c73a22a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 06:13:02 -0400 Subject: [PATCH 3527/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7aea991..b311d0c7 100644 --- a/README.md +++ b/README.md @@ -941,7 +941,7 @@ ________________________________________________________________________________

    -

    Zwavejs2MQTT LXC

    +

    Z-Wave JS UI LXC

    [Z-Wave JS UI](https://github.com/zwave-js/zwave-js-ui#) is a fully configurable Z-Wave to MQTT Gateway and Control Panel. From e6e6e44e8a5c3f267c1ed5f04162d79adf791cf3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 06:20:26 -0400 Subject: [PATCH 3528/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b311d0c7..8e9978d2 100644 --- a/README.md +++ b/README.md @@ -939,7 +939,7 @@ ________________________________________________________________________________
    🔸Z-Wave JS UI LXC -

    +

    Z-Wave JS UI LXC

    From 487998c3eb3790945eecc1af13ad7e41fca9ff50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 12:14:59 -0400 Subject: [PATCH 3529/6505] Update trilium-update.sh --- misc/trilium-update.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/trilium-update.sh b/misc/trilium-update.sh index 9220c2d7..eb9a1d88 100644 --- a/misc/trilium-update.sh +++ b/misc/trilium-update.sh @@ -36,10 +36,10 @@ sleep 1 echo -e "${GN} Updating to v${RELEASE}... ${CL}" wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz -tar -xzf trilium-linux-x64-server-$RELEASE.tar.xz -C /opt/trilium &>/dev/null - +tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null +cp -r trilium-linux-x64-server/* /opt/trilium/ echo -e "${GN} Cleaning up... ${CL}" -rm trilium-linux-x64-server-$RELEASE.tar.xz +rm -rf trilium-linux-x64-server-$RELEASE.tar.xz trilium-linux-x64-server echo -e "${GN} Starting Trilium... ${CL}" systemctl start trilium.service From 24bb0654812b685203ce72ea03867b82255d6c30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 20:26:23 -0400 Subject: [PATCH 3530/6505] Create nextcloudpi-v4.sh --- ct/nextcloudpi-v4.sh | 255 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 ct/nextcloudpi-v4.sh diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh new file mode 100644 index 00000000..0985a708 --- /dev/null +++ b/ct/nextcloudpi-v4.sh @@ -0,0 +1,255 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="NextCloudPi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + _ __ __ ________ ______ _ + / | / /__ _ __/ /_/ ____/ /___ __v4______/ / __ \(_) + / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / /_/ / / + / /| / __/> &1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}https://${IP}/${CL} \n" From a00a9c532e327959adb7a016f8eaca28af868b6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 20:27:27 -0400 Subject: [PATCH 3531/6505] Create nextcloudpi-install.sh --- setup/nextcloudpi-install.sh | 99 ++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 setup/nextcloudpi-install.sh diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh new file mode 100644 index 00000000..5d8d1555 --- /dev/null +++ b/setup/nextcloudpi-install.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing NextCloudPi (Patience)" +curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null +msg_ok "Installed NextCloudPi" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 873e91fab2bf76a5f0d374d8474665455f33ec7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 20:42:06 -0400 Subject: [PATCH 3532/6505] Update README.md --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index 8e9978d2..22fe7a3c 100644 --- a/README.md +++ b/README.md @@ -1805,6 +1805,37 @@ ________________________________________________________________________________
    +
    + 🔸NextCloudPi LXC + +

    + +

    NextCloudPi LXC

    + +[NextCloudPi LXC](https://github.com/nextcloud/nextcloudpi#features) is the most popular self-hosted collaboration solution. + +To create a new Proxmox NextCloudPi LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nextcloudpi-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +❗1️. Set nc trusted domains + +Run in the LXC console +``` +sudo ncp-config +``` +Go to config ➡ nc-trusted-domains, add 0.0.0.0 or a static NextCloudPi IP + +Get back to the command prompt, and restart Apache2 `sudo service apache2 restart` + +❗2. **NextCloudPi Interface - https:// IP/** +____________________________________________________________________________________________ + +
    +
    🔸OpenMediaVault LXC From 89de8fd7dce81a75de08329f2234c9ca57dcbd3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 20:43:19 -0400 Subject: [PATCH 3533/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 572a8e51..e9209399 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-22 + +### Changed + +- **NextCloudPi LXC** + - NEW Script + ## 2022-09-21 ### Changed From 24b736dcb9dedb6b8c22edb97b80722de1bc9a6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 20:44:36 -0400 Subject: [PATCH 3534/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22fe7a3c..f0f1c399 100644 --- a/README.md +++ b/README.md @@ -1526,7 +1526,7 @@ ________________________________________________________________________________
    - 🔸Paperless-ngx LXC + Paperless-ngx LXC

    From 933841040a7cb9fbca91ecc2d7b9ec3b444c6b76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 20:57:30 -0400 Subject: [PATCH 3535/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0f1c399..d5f483c6 100644 --- a/README.md +++ b/README.md @@ -1827,7 +1827,7 @@ Run in the LXC console ``` sudo ncp-config ``` -Go to config ➡ nc-trusted-domains, add 0.0.0.0 or a static NextCloudPi IP +Go to config ➡ nc-trusted-domains, add `0.0.0.0` or a static NextCloudPi IP Get back to the command prompt, and restart Apache2 `sudo service apache2 restart` From d3d5418a1b3ccf3f7083ada6b58c7e533cbe472f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Sep 2022 21:17:54 -0400 Subject: [PATCH 3536/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d5f483c6..7165704b 100644 --- a/README.md +++ b/README.md @@ -1832,6 +1832,7 @@ Go to config ➡ nc-trusted-domains, add `0.0.0.0` or a static NextCloudPi IP Get back to the command prompt, and restart Apache2 `sudo service apache2 restart` ❗2. **NextCloudPi Interface - https:// IP/** + ____________________________________________________________________________________________
    From 7b736bce6d8740f38ed03863c03508381d1e4e63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 09:18:20 -0400 Subject: [PATCH 3537/6505] Update omv-v4.sh --- ct/omv-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index c03834b1..bff9e4db 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -70,7 +70,7 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" From 9cca4a56ce1d645fe4a4f966eb1a3ae1e5f53680 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 09:19:59 -0400 Subject: [PATCH 3538/6505] Update nextcloudpi-v4.sh --- ct/nextcloudpi-v4.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index 0985a708..22fed957 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -70,8 +70,8 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -98,8 +98,8 @@ function default_settings() { } function advanced_settings() { CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ +"1" "Unprivileged" OFF \ +"0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then From 5ce5d916658330bc7e271f59757167dac414cd3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 12:12:58 -0400 Subject: [PATCH 3539/6505] maintenance (#543) --- setup/adguard-install.sh | 1 - setup/casaos-install.sh | 1 - setup/daemonsync-install.sh | 1 - setup/dashy-install.sh | 1 - setup/debian-install.sh | 1 - setup/deconz-install.sh | 1 - setup/docker-install.sh | 1 - setup/emby-install.sh | 1 - setup/esphome-install.sh | 1 - setup/grafana-install.sh | 1 - setup/grocy-install.sh | 2 +- setup/heimdalldashboard-install.sh | 1 - setup/homeassistant-install.sh | 1 - setup/homebridge-install.sh | 1 - setup/homepage-install.sh | 1 - setup/influxdb-install.sh | 1 - setup/iobroker-install.sh | 1 - setup/jellyfin-install.sh | 1 - setup/keycloak-install.sh | 1 - setup/magicmirror-install.sh | 1 - setup/meshcentral-install.sh | 1 - setup/motioneye-install.sh | 1 - setup/mqtt-install.sh | 1 - setup/n8n-install.sh | 1 - setup/navidrome-install.sh | 2 +- setup/nginx-proxy-manager-install.sh | 1 - setup/nocodb-install.sh | 1 - setup/node-red-install.sh | 1 - setup/omada-install.sh | 1 - setup/openhab-install.sh | 1 - setup/plex-install.sh | 1 - setup/prometheus-install.sh | 2 +- setup/syncthing-install.sh | 1 - setup/technitiumdns-install.sh | 1 - setup/trilium-install.sh | 2 +- setup/ubuntu-install.sh | 1 - setup/unifi-install.sh | 1 - setup/uptimekuma-install.sh | 1 - setup/vaultwarden-install.sh | 1 - setup/whoogle-install.sh | 1 - setup/wikijs-install.sh | 1 - setup/wireguard-install.sh | 1 - setup/zigbee2mqtt-install.sh | 1 - 43 files changed, 4 insertions(+), 43 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 61be5518..080e2cff 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -98,5 +98,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index 634a00e7..8ee90a70 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -107,5 +107,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 35957afc..e3bd458d 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -100,5 +100,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 8267f380..7485178e 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -131,5 +131,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 84f28bfa..bc9f39cb 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -92,5 +92,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index 1cb64ebb..bc6f0c0c 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -124,5 +124,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 1780dcfd..c4234aed 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -152,5 +152,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 0ba9b200..5a448e55 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -111,5 +111,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 1f4323be..8d0aab4e 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -120,5 +120,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 9803f66a..6503d3f1 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -109,5 +109,4 @@ systemctl enable grafana-server.service &>/dev/null msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 66317825..32ca846b 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -128,5 +128,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/cache/* /root/latest +rm -rf /root/latest msg_ok "Cleaned" diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index c70347a4..d4b509f7 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -131,5 +131,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 80e53aba..35617ab0 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -334,5 +334,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 8678c607..033a52b5 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -110,5 +110,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 833d35a6..8adb85c9 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -128,5 +128,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 6495809f..0dc32e13 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -111,5 +111,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 7ba4a65f..ab65830e 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -98,5 +98,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index d0a32cd4..f7f3576e 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -136,5 +136,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index 06c679f6..0c86f4fa 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -119,5 +119,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index 0c903cd2..64dce914 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -221,5 +221,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 0221f817..eb2e219f 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -109,5 +109,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 2229ac30..ff8afa47 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -128,5 +128,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index ade1c168..db9331d9 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -105,5 +105,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 9adffc10..322064c0 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -121,5 +121,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index 21d44e78..6a50e363 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -147,5 +147,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/Navidrome.tar.gz +rm -rf /root/Navidrome.tar.gz msg_ok "Cleaned" diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 2f9b21b0..4861405e 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -259,5 +259,4 @@ msg_ok "Started Services" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index ae27d97c..57083bb8 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -127,5 +127,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 180daf92..f9d90389 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -100,5 +100,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 4260e995..6c2dde53 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -103,5 +103,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 4ec66d79..1dec802f 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -115,5 +115,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/plex-install.sh b/setup/plex-install.sh index be02e9a4..90e21271 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -115,6 +115,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 2da05e62..378a8ab5 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -127,5 +127,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/prometheus-2.36.2.linux-amd64 /root/prometheus-2.36.2.linux-amd64.tar.gz +rm -rf /root/prometheus-2.36.2.linux-amd64 /root/prometheus-2.36.2.linux-amd64.tar.gz msg_ok "Cleaned" diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh index 2b09475a..a9d942bc 100644 --- a/setup/syncthing-install.sh +++ b/setup/syncthing-install.sh @@ -101,5 +101,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 48650070..907c7e2f 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -98,5 +98,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index 36524370..8b259725 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -122,5 +122,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* /root/trilium-linux-x64-server-$RELEASE.tar.xz +rm -rf /root/trilium-linux-x64-server-$RELEASE.tar.xz msg_ok "Cleaned" diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 5514c920..4abacf6d 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -93,5 +93,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 8e899809..49ebf87d 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -107,5 +107,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index b29954f1..f8663bfc 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -127,5 +127,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 3f18807a..2f9e90c7 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -183,5 +183,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index e7854c82..0a653770 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -114,5 +114,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index 8866f812..db684221 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -143,5 +143,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index d295d4db..f9af0201 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -157,5 +157,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 910da0fe..944e2981 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -132,5 +132,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* /var/lib/apt/lists/* msg_ok "Cleaned" From 3ce3c22681c9b29d7a901e45e1b997f0a4ccf937 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 17:29:04 -0400 Subject: [PATCH 3540/6505] Create emqx-v4.sh --- ct/emqx-v4.sh | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 ct/emqx-v4.sh diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh new file mode 100644 index 00000000..4cf17014 --- /dev/null +++ b/ct/emqx-v4.sh @@ -0,0 +1,255 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="EMQX" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + ________ _______v4 _ __ + / ____/ |/ / __ \ | |/ / + / __/ / /|_/ / / / / | / + / /___/ / / / /_/ / / | +/_____/_/ /_/\___\_\/_/|_| + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +else + exit +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +else + exit +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +else + exit +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +else + exit +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +else + exit +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +else + exit +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:18083${CL} \n" From 74ae3b9036da3e80bf83bd24acfb318bcdcb9a78 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 17:30:06 -0400 Subject: [PATCH 3541/6505] Create emqx-install.sh --- setup/emqx-install.sh | 102 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 setup/emqx-install.sh diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh new file mode 100644 index 00000000..b7bce533 --- /dev/null +++ b/setup/emqx-install.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y gnupg &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing EMQX" +wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null +apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +msg_ok "Installed EMQX" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" +systemctl start emqx From 7b38267b3420ab4ce783d8f0fd7b5290d8d01a0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 17:40:41 -0400 Subject: [PATCH 3542/6505] Update README.md --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index 7165704b..20012f39 100644 --- a/README.md +++ b/README.md @@ -560,6 +560,41 @@ ________________________________________________________________________________
    +
    + 🔸EMQX LXC + +

    hero

    + + +

    EMQX LXC

    + +[EMQX](https://www.emqx.io/) is an Open-source MQTT broker with a high-performance real-time message processing engine, powering event streaming for IoT devices at massive scale. + +To create a new Proxmox EMQX LXC Container, run the following in the Proxmox Shell. + +```yaml + bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emqx-v4.sh)" +``` +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + + +**EMQX Interface - IP:18083** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + public + ``` +***More info to come when someone figures it out*** ッ + ____________________________________________________________________________________________ + +
    +
    Node-Red LXC From 25f1cde0170cd46c1885a984fdba51d522d4bf3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 17:41:35 -0400 Subject: [PATCH 3543/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e9209399..72be5984 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-23 + +### Changed + +- **EMQX LXC** + - NEW Script + ## 2022-09-22 ### Changed From 9324a97796fb022a9f7b83eedd0a747fd681272f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 17:47:25 -0400 Subject: [PATCH 3544/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20012f39..6e4627e8 100644 --- a/README.md +++ b/README.md @@ -563,7 +563,7 @@ ________________________________________________________________________________
    🔸EMQX LXC -

    hero

    +

    EMQX LXC

    From 5bc0ab338222f060ecef08c57c1c1e6a87f97018 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 17:49:43 -0400 Subject: [PATCH 3545/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6e4627e8..c730bc19 100644 --- a/README.md +++ b/README.md @@ -591,6 +591,7 @@ To create a new Proxmox EMQX LXC Container, run the following in the Proxmox She public ``` ***More info to come when someone figures it out*** ッ + ____________________________________________________________________________________________
    From 07a8a57c5cf4ac072611e7593ea070fc4a903d8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 17:57:56 -0400 Subject: [PATCH 3546/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c730bc19..d33cc60d 100644 --- a/README.md +++ b/README.md @@ -570,7 +570,7 @@ ________________________________________________________________________________ [EMQX](https://www.emqx.io/) is an Open-source MQTT broker with a high-performance real-time message processing engine, powering event streaming for IoT devices at massive scale. -To create a new Proxmox EMQX LXC Container, run the following in the Proxmox Shell. +To create a new Proxmox EMQX LXC, run the following in the Proxmox Shell. ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emqx-v4.sh)" From 87560b475f52b632d07e1e5e97a4c6ac699610c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 18:10:37 -0400 Subject: [PATCH 3547/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d33cc60d..ea6e6373 100644 --- a/README.md +++ b/README.md @@ -578,7 +578,7 @@ To create a new Proxmox EMQX LXC, run the following in the Proxmox Shell.

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    -**EMQX Interface - IP:18083** +**EMQX Interface - IP:18083** (If the web UI doesn't load, reboot the LXC) ⚙️ **Initial Login** From 24601051775b2b01614a36abd6d8f9f2bb1695be Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 23:40:07 -0400 Subject: [PATCH 3548/6505] Update emqx-install.sh --- setup/emqx-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index b7bce533..5c6b42ab 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,8 +74,9 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null -apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash +sudo apt-get install -y emqx +sudo emqx start msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -99,4 +100,3 @@ msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null msg_ok "Cleaned" -systemctl start emqx From fb649c3899450373f63f5e6b9050f70c8e6d2c8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Sep 2022 23:50:25 -0400 Subject: [PATCH 3549/6505] Update emqx-install.sh --- setup/emqx-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 5c6b42ab..4a6ed62a 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,9 +74,9 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash -sudo apt-get install -y emqx -sudo emqx start +curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null +sudo apt-get install -y emqx &>/dev/null +sudo emqx start &>/dev/null msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 4c547cf1bdd8fe9321c26c7f42dc4ef7ca6270cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Sep 2022 00:04:34 -0400 Subject: [PATCH 3550/6505] Update emqx-install.sh --- setup/emqx-install.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 4a6ed62a..69ee6b25 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,9 +74,12 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null -sudo apt-get install -y emqx &>/dev/null -sudo emqx start &>/dev/null +#curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null +#sudo apt-get install -y emqx &>/dev/null +#sudo emqx start &>/dev/null +wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null +apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +systemctl start emqx msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 104d35e999ab5bcbceaabb339a6811b79303fbb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Sep 2022 00:30:23 -0400 Subject: [PATCH 3551/6505] Update README.md --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea6e6373..24efdac7 100644 --- a/README.md +++ b/README.md @@ -578,7 +578,7 @@ To create a new Proxmox EMQX LXC, run the following in the Proxmox Shell.

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    -**EMQX Interface - IP:18083** (If the web UI doesn't load, reboot the LXC) +**EMQX Interface - IP:18083** ⚙️ **Initial Login** @@ -590,7 +590,16 @@ To create a new Proxmox EMQX LXC, run the following in the Proxmox Shell. ```yaml public ``` -***More info to come when someone figures it out*** ッ +⚙️ **Setup** + +Access Control ➡ Authentication ➡ Create ➡ Next ➡ Next ➡ Create ➡ Users ➡ Add ➡ Username / Password (to authenicate with MQTT) ➡ Save. You're now ready to enjoy a high-performance MQTT Broker. + +⚙️ **To Update EMQX** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` ____________________________________________________________________________________________ From 4078e67dad608d74dcd1dc02ecf522e64a2c991b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Sep 2022 00:39:40 -0400 Subject: [PATCH 3552/6505] Update emqx-install.sh --- setup/emqx-install.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 69ee6b25..4947a0cc 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,12 +74,12 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -#curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null -#sudo apt-get install -y emqx &>/dev/null -#sudo emqx start &>/dev/null -wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null -apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null -systemctl start emqx +curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null +sudo apt-get install -y emqx &>/dev/null +sudo emqx start &>/dev/null +#wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null +#apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +#systemctl start emqx msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -102,4 +102,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null +rm -rf emqx-5.0.8-debian11-amd64.deb msg_ok "Cleaned" From 0060499d74050742bb341109452a199d71425072 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Sep 2022 04:13:18 -0400 Subject: [PATCH 3553/6505] Update emqx-install.sh --- setup/emqx-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 4947a0cc..5d7c25ae 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,12 +74,12 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null -sudo apt-get install -y emqx &>/dev/null -sudo emqx start &>/dev/null -#wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null -#apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null -#systemctl start emqx +#curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null +#sudo apt-get install -y emqx &>/dev/null +#sudo emqx start &>/dev/null +wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null +apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +systemctl start emqx msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6); From af5172beaf6d8092fb72ca98fdde81a3cb554fa7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Sep 2022 12:15:15 -0400 Subject: [PATCH 3554/6505] Update emqx-install.sh --- setup/emqx-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 5d7c25ae..c2894145 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,11 +74,11 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -#curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash &>/dev/null -#sudo apt-get install -y emqx &>/dev/null +curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | bash &>/dev/null +apt-get install -y emqx &>/dev/null #sudo emqx start &>/dev/null -wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null -apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +#wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null +#apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null systemctl start emqx msg_ok "Installed EMQX" From 050268ad7aaf2d9aed5e0416b973a57b88cf75e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Sep 2022 12:19:12 -0400 Subject: [PATCH 3555/6505] Update emqx-install.sh --- setup/emqx-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index c2894145..aef1b4c7 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,11 +74,11 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | bash &>/dev/null -apt-get install -y emqx &>/dev/null +#curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | bash &>/dev/null +#apt-get install -y emqx &>/dev/null #sudo emqx start &>/dev/null -#wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null -#apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null +apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null systemctl start emqx msg_ok "Installed EMQX" From cb33d1b2043f8d5103ff1b17462fa5700898ac24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Sep 2022 14:38:42 -0400 Subject: [PATCH 3556/6505] Update emqx-install.sh --- setup/emqx-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index aef1b4c7..3dc6c6c0 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -74,11 +74,11 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" -#curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | bash &>/dev/null -#apt-get install -y emqx &>/dev/null +curl -s https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh | bash &>/dev/null +sudo apt-get install -y emqx=5.0.8 &>/dev/null #sudo emqx start &>/dev/null -wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null -apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null +#wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null +#apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null systemctl start emqx msg_ok "Installed EMQX" From 0011c04cd3ef6f2279ce15918726dfcdd1de6677 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Sep 2022 14:45:28 -0400 Subject: [PATCH 3557/6505] Update emqx-install.sh --- setup/emqx-install.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 3dc6c6c0..0694ad1f 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -70,15 +70,11 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing EMQX" curl -s https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh | bash &>/dev/null sudo apt-get install -y emqx=5.0.8 &>/dev/null -#sudo emqx start &>/dev/null -#wget https://www.emqx.com/en/downloads/broker/5.0.8/emqx-5.0.8-debian11-amd64.deb &>/dev/null -#apt install ./emqx-5.0.8-debian11-amd64.deb &>/dev/null systemctl start emqx msg_ok "Installed EMQX" From 7f4efd1d8ef9237770e27c957dddf8ae04aa4db8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Sep 2022 14:51:45 -0400 Subject: [PATCH 3558/6505] Update emqx-install.sh --- setup/emqx-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 0694ad1f..dc3e224b 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -98,5 +98,4 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf emqx-5.0.8-debian11-amd64.deb msg_ok "Cleaned" From 2de6ed9d48a9d2fcf183ea05f2b500220d0906f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Sep 2022 17:58:46 -0400 Subject: [PATCH 3559/6505] Update paperless-ngx-install.sh fix install issue with 1.9.0 --- setup/paperless-ngx-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index 2f424f81..c1c2640b 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -82,6 +82,7 @@ apt-get install -y --no-install-recommends \ mime-support \ libzbar0 \ poppler-utils \ + default-libmysqlclient-dev \ sudo &>/dev/null msg_ok "Installed Paperless-ngx Dependencies" From 8a64b5728a4f6dc17fd6bc28d66c3b7063175495 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Sep 2022 20:28:39 -0400 Subject: [PATCH 3560/6505] Update paperless-ngx-update.sh Change migrate to long path --- misc/paperless-ngx-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 9d515ac3..daaecda5 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -60,8 +60,8 @@ cp -r /opt/paperless/paperless.conf paperless-ngx/ cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless pip install -r requirements.txt &>/dev/null -cd src -python3 manage.py migrate &>/dev/null +cd /opt/paperless/src +/usr/bin/python3 manage.py migrate &>/dev/null msg_ok "Updated to ${RELEASE}" msg_info "Cleaning up" From 2252e28a6af6f4ca5fa1d2e354d41c7cbae44368 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Sep 2022 11:46:53 -0400 Subject: [PATCH 3561/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index f0948ee1..e479fc5f 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -24,7 +24,7 @@ function error_exit() { echo -en "${GN} Updating Z-wave JS UI... " systemctl stop zwave-js-ui.service -cd /opt/zwavejs2mqtt +cd /opt/zwave-js-ui curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null unzip zwave-js-ui-v*.zip zwave-js-ui &>/dev/null echo -e "${CM}${CL} \r" From 46566025aec9fab72f980f82f864117d2ebd79c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Sep 2022 12:14:20 -0400 Subject: [PATCH 3562/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 24efdac7..fce222bf 100644 --- a/README.md +++ b/README.md @@ -1883,7 +1883,7 @@ ________________________________________________________________________________
    - 🔸OpenMediaVault LXC + OpenMediaVault LXC

    From f7a65716046972984452cfabc2c87cfdd3cae9ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Sep 2022 02:25:48 -0400 Subject: [PATCH 3563/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fce222bf..2a9ae449 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ ________________________________________________________________________________
    - 🔸Proxmox Backup Server Post Install + Proxmox Backup Server Post Install

    @@ -982,7 +982,7 @@ ________________________________________________________________________________
    - 🔸Z-Wave JS UI LXC + Z-Wave JS UI LXC

    From 1e8ac7e63e4eed34fe7faefd6f10ae73ede9e3a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Sep 2022 08:16:38 -0400 Subject: [PATCH 3564/6505] maintenance (#569) update whiptail menu --- ct/adguard-v4.sh | 68 ++++++++++++---------------- ct/casaos-v4.sh | 68 ++++++++++++---------------- ct/daemonsync-v4.sh | 68 ++++++++++++---------------- ct/dashy-v4.sh | 68 ++++++++++++---------------- ct/debian-v4.sh | 68 ++++++++++++---------------- ct/deconz-v4.sh | 84 +++++++++++++---------------------- ct/docker-v4.sh | 68 ++++++++++++---------------- ct/emby-v4.sh | 74 +++++++++++++----------------- ct/emqx-v4.sh | 68 ++++++++++++---------------- ct/esphome-v4.sh | 68 ++++++++++++---------------- ct/grafana-v4.sh | 68 ++++++++++++---------------- ct/grocy-v4.sh | 68 ++++++++++++---------------- ct/heimdalldashboard-v4.sh | 68 ++++++++++++---------------- ct/homeassistant-v4.sh | 68 ++++++++++++---------------- ct/homebridge-v4.sh | 68 ++++++++++++---------------- ct/homepage-v4.sh | 68 ++++++++++++---------------- ct/influxdb-v4.sh | 68 ++++++++++++---------------- ct/iobroker-v4.sh | 68 ++++++++++++---------------- ct/jellyfin-v4.sh | 74 +++++++++++++----------------- ct/keycloak-v4.sh | 68 ++++++++++++---------------- ct/magicmirror-v4.sh | 68 ++++++++++++---------------- ct/mariadb-v4.sh | 68 ++++++++++++---------------- ct/meshcentral-v4.sh | 68 ++++++++++++---------------- ct/motioneye-v4.sh | 68 ++++++++++++---------------- ct/mqtt-v4.sh | 68 ++++++++++++---------------- ct/n8n-v4.sh | 68 ++++++++++++---------------- ct/navidrome-v4.sh | 68 ++++++++++++---------------- ct/nextcloudpi-v4.sh | 72 +++++++++++++----------------- ct/nginx-proxy-manager-v4.sh | 68 ++++++++++++---------------- ct/nocodb-v4.sh | 68 ++++++++++++---------------- ct/node-red-v4.sh | 68 ++++++++++++---------------- ct/omada-v4.sh | 74 +++++++++++++----------------- ct/omv-v4.sh | 72 +++++++++++++----------------- ct/openhab-v4.sh | 68 ++++++++++++---------------- ct/paperless-ngx-v4.sh | 68 ++++++++++++---------------- ct/photoprism-v4.sh | 68 ++++++++++++---------------- ct/pihole-v4.sh | 72 +++++++++++++----------------- ct/plex-v4.sh | 74 +++++++++++++----------------- ct/podman-homeassistant-v4.sh | 72 +++++++++++++----------------- ct/postgresql-v4.sh | 68 ++++++++++++---------------- ct/prometheus-v4.sh | 68 ++++++++++++---------------- ct/syncthing-v4.sh | 68 ++++++++++++---------------- ct/technitiumdns-v4.sh | 68 ++++++++++++---------------- ct/trilium-v4.sh | 68 ++++++++++++---------------- ct/ubuntu-v4.sh | 74 +++++++++++++----------------- ct/unifi-v4.sh | 68 ++++++++++++---------------- ct/uptimekuma-v4.sh | 68 ++++++++++++---------------- ct/vaultwarden-v4.sh | 68 ++++++++++++---------------- ct/whoogle-v4.sh | 68 ++++++++++++---------------- ct/wikijs-v4.sh | 68 ++++++++++++---------------- ct/wireguard-v4.sh | 68 ++++++++++++---------------- ct/zigbee2mqtt-v4.sh | 68 ++++++++++++---------------- ct/zwave-js-ui-v4.sh | 68 ++++++++++++---------------- 53 files changed, 1552 insertions(+), 2114 deletions(-) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index e54d84aa..d0f3d6a9 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 344b3534..4458f5c5 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index 07334f6a..a22b3961 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 07232766..4e95a911 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index ddc48a91..c440df07 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index c7a671bf..06cc25ad 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -97,29 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ -"18.04" "Bionic" OFF \ -"20.04" "Focal" ON \ -"21.10" "Impish" OFF \ -"22.04" "Jammy" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit -fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -129,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -190,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -200,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -210,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -220,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index 5534f38a..a7357282 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index db03bdfa..e90725f1 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -104,22 +104,16 @@ var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 "21.10" "Impish" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit -fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -129,58 +123,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -190,7 +176,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -200,7 +186,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -210,7 +196,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -220,7 +206,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index 4cf17014..5e7f2885 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index 9172c085..e3174370 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index d2622f59..58ce46cf 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 54755899..09972d1a 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 4c534619..4a3ce6e5 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 3b2083ad..2a521357 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index abbee6a9..7b3e7ddf 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index 97df3d81..3b2d63de 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 7f9f991e..3ab809b5 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 364cf6e1..71bfa4ae 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 88334668..76421a3c 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -104,22 +104,16 @@ var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 "21.10" "Impish" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit -fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -129,58 +123,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -190,7 +176,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -200,7 +186,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -210,7 +196,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -220,7 +206,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 2c5db5a9..966edbe8 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 06aee016..cfc67cfc 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index 3187a6d1..2b4820ae 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 602a6db5..325b2b68 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 7a53e637..8069c1b0 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index 899552a9..7210af65 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index d683c6fd..496e626d 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 4cb19868..446f1b22 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index 22fed957..f39b2a59 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index bea15edf..f99bb2e4 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 050e5ff9..4cdfe3f5 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 9230148b..33400099 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index f4f1a9af..3a2c7abc 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -104,22 +104,16 @@ var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 "22.04" "Jammy" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit -fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -129,58 +123,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -190,7 +176,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -200,7 +186,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -210,7 +196,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -220,7 +206,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index bff9e4db..0e84cfb6 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index e724c8e3..8e16f806 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index 69f151d4..58e2a0b5 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index cbfa9b92..0b1825cf 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index d917e1f5..70252cbb 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index 0cbeeb10..eeed0cca 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -104,22 +104,16 @@ var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 "21.10" "Impish" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit -fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -129,58 +123,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -190,7 +176,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -200,7 +186,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -210,7 +196,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -220,7 +206,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 55efec47..2557a709 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -100,17 +100,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -120,58 +118,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -181,7 +171,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -191,7 +181,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -201,7 +191,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -211,7 +201,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index ef9302e0..dd29509b 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 587412e9..e8765aad 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index 27d73050..10c55f42 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -98,17 +98,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -118,58 +116,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -179,7 +169,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -189,7 +179,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -199,7 +189,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -209,7 +199,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index e7f78fd4..d23f72c2 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index 8dc66c67..c9b9baba 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index f485ca4e..fca16b27 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -104,22 +104,16 @@ var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 "22.04" "Jammy" ON \ 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit -fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -129,58 +123,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -190,7 +176,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -200,7 +186,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -210,7 +196,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -220,7 +206,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index d6f7b954..2f204933 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index 4f7f4e3b..4c4a2761 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index 02b0f684..cac70cf7 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 21a1ecdf..6adc5170 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -96,17 +96,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -116,58 +114,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -177,7 +167,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -187,7 +177,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -197,7 +187,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -207,7 +197,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index b41e5a4a..38c99f5a 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 564dd218..98c074ac 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -98,17 +98,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -118,58 +116,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -179,7 +169,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -189,7 +179,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -199,7 +189,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -209,7 +199,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 48fcc97f..14057e7a 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID?" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index ab9fc567..a56a065c 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -97,17 +97,15 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -117,58 +115,50 @@ else echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3) +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3) +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3) +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -else - exit fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $GATE1 ]; then GATE1="Default" GATE=""; @@ -178,7 +168,7 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MAC1 ]; then MAC1="Default" MAC=""; @@ -188,7 +178,7 @@ else echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -198,7 +188,7 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -208,7 +198,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings From 9fce615c4b260bf1e4c20505e32259abf59f0727 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Sep 2022 16:28:22 -0400 Subject: [PATCH 3565/6505] Update webmin.sh update starting version --- misc/webmin.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 080b5611..d5dca0de 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -22,19 +22,19 @@ apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip sh echo -e "${CM}${CL} \r" echo -en "${GN} Downloading Webmin... " -wget http://prdownloads.sourceforge.net/webadmin/webmin_1.996_all.deb &>/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_2.000_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Webmin... " -dpkg --install webmin_1.996_all.deb &>/dev/null +dpkg --install webmin_2.000_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Setting Default Webmin usermame & password to root... " /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /root/webmin_1.996_all.deb +rm -rf /root/webmin_2.000_all.deb echo -e "${CM}${CL} \r" IP=$(hostname -I | cut -f1 -d ' ') -echo -e "${BL} Successfully Installed Webmin, Now Go To https://${IP}:10000 ${CL}" +echo -e "Successfully Installed!! Webmin should be reachable by going to https://${IP}:10000" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" From 0890cfffe48642ffa9e9f17de7137f7887825cea Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Sep 2022 21:26:54 -0400 Subject: [PATCH 3566/6505] Update haos-vm-v4.sh update whiptail menu --- vm/haos-vm-v4.sh | 70 ++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 8eb97bbc..c164c30c 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -64,12 +64,12 @@ else fi function header_info { echo -e "${HA} - __ _____ ____ _____ - / / / / | / __ \/ ___/ - / /_/ / /| |/ / / /\__ \ - / __ / ___ / /_/ /___/ / -/_/ /_/_/v4|_\____//____/ - Home Assistant OS + __ __ ___ ____ _____ + / / / // |v4/ __ \/ ___/ + / /_/ // /| | / / / /\__ \ + / __ // ___ |/ /_/ /___/ / +/_/ /_//_/ |_|\____//____/ + Home Assistant OS ${CL}" } function msg_info() { @@ -107,62 +107,50 @@ function default_settings() { echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 3 \ +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ "$STABLE" "Stable" ON \ "$BETA" "Beta" OFF \ "$DEV" "Dev" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" -else - exit -fi -VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi +VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" +if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" 3>&1 1>&2 2>&3) +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${VM_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $VM_NAME ]; then HN="haos${BRANCH}"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - MAC="$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +if [ -z $MAC1 ]; then MAC="$GEN_MAC"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}"; else - exit + if [ $exitstatus = 0 ]; then MAC="$MAC1"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"; fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -179,7 +167,7 @@ else echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" else clear @@ -189,7 +177,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then clear header_info echo -e "${BL}Using Default Settings${CL}" From f12c5a7923b38d4d10db41a6cbff0da816a920cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Sep 2022 21:53:17 -0400 Subject: [PATCH 3567/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a9ae449..a5966eda 100644 --- a/README.md +++ b/README.md @@ -1851,7 +1851,7 @@ ________________________________________________________________________________
    - 🔸NextCloudPi LXC + NextCloudPi LXC

    From 787862645e7432a126139e61142e05f9c6dec7d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 06:33:08 -0400 Subject: [PATCH 3568/6505] Update homeassistant-v4.sh --- ct/homeassistant-v4.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 2a521357..18d1c534 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -232,10 +232,22 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +if [ "$CT_TYPE" == "0" ]; then cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF +else +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From d900355fb0ef7b31abcc8ce0c7a62d6f0cf9c364 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 06:38:20 -0400 Subject: [PATCH 3569/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 72be5984..b6c6e341 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-09-29 + +### Changed + +- **Home Assistant Container LXC** + - If the LXC is created Privileged, the script will automatically set up USB passthrough. + ## 2022-09-23 ### Changed From 98ea1161985f0a235526633c79677cfdfbeb92c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 06:41:39 -0400 Subject: [PATCH 3570/6505] Update homeassistant-v4.sh --- ct/homeassistant-v4.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 18d1c534..e17e476e 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -247,6 +247,7 @@ else cat <> $LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: +EOF fi msg_info "Starting LXC Container" pct start $CTID From a4fea97ace7f38b9d7def2e45e24f4d4e7bebdc2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 06:57:07 -0400 Subject: [PATCH 3571/6505] Update README.md --- README.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a5966eda..8c1276cc 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,8 @@ ________________________________________________________________________________ A standalone container-based installation of Home Assistant Core +🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* + To create a new Proxmox Home Assistant Container LXC, run the following in the Proxmox Shell. ```yaml @@ -209,16 +211,6 @@ Run in the Proxmox Shell bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data.sh)" ``` -⚙️ **To Allow USB Device Passthrough:** - -Run in the Proxmox Shell. (**replace `106` with your LXC ID**) -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 -``` - -Reboot the LXC to apply the changes - - ⚙️ **To Install HACS:** Run in the LXC console From 0d1970977a9580fc1b0f61e4d1f1cfeb965436e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 11:00:34 -0400 Subject: [PATCH 3572/6505] Create hacs-core.sh --- misc/hacs-core.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 misc/hacs-core.sh diff --git a/misc/hacs-core.sh b/misc/hacs-core.sh new file mode 100644 index 00000000..b6374539 --- /dev/null +++ b/misc/hacs-core.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" + +while true; do + read -p "Start the HACS Install Script (y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done + +apt update &>/dev/null +apt install unzip &>/dev/null +cd .homeassistant +wget -O - https://get.hacs.xyz | bash - + +# To install HACS run the following from the container (LXC) console +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs-core.sh)" +# Then add the integration in HA From a05231aeae1ecfbf2b238aeb2f81364ea30d895a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 11:08:00 -0400 Subject: [PATCH 3573/6505] Create homeassistant-core-v4.sh --- ct/homeassistant-core-v4.sh | 258 ++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 ct/homeassistant-core-v4.sh diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh new file mode 100644 index 00000000..e8759185 --- /dev/null +++ b/ct/homeassistant-core-v4.sh @@ -0,0 +1,258 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Home Assistant-Core" +var_disk="8" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + __ __ ___ _ __ __ ______ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / ____/___v4________ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / __ \/ ___/ _ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /___/ /_/ / / / __/ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____/\____/_/ \___/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; +else + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable (after it's initialized) by going to the following URL. + ${BL}http://${IP}:8123${CL}" From ece1588e0e3283b6208e8267ad69436213b0aed3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 11:09:06 -0400 Subject: [PATCH 3574/6505] Create homeassistant-core-install.sh --- setup/homeassistant-core-install.sh | 137 ++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 setup/homeassistant-core-install.sh diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh new file mode 100644 index 00000000..a7b441ce --- /dev/null +++ b/setup/homeassistant-core-install.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y \ + python3 \ + python3-dev \ + python3-venv \ + python3-pip \ + bluez \ + libffi-dev \ + libssl-dev \ + libjpeg-dev \ + zlib1g-dev \ + autoconf \ + build-essential \ + libopenjp2-7 \ + libtiff5 \ + libturbojpeg0-dev \ + tzdata \ + curl \ + sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Home Assistant-Core" +mkdir /srv/homeassistant +cd /srv/homeassistant +python3 -m venv . +source bin/activate +python3 -m pip install wheel &>/dev/null +pip3 install homeassistant &>/dev/null +msg_ok "Installed Home Assistant-Core" + +msg_info "Creating Service" +cat << EOF > /etc/systemd/system/homeassistant.service + +[Unit] +Description=Home Assistant +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/root/.homeassistant +ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable homeassistant &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From f3ebf54ba53ee3f40dafc1c8e84f435c654daa65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 11:29:04 -0400 Subject: [PATCH 3575/6505] Update README.md --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/README.md b/README.md index 8c1276cc..0f16ed59 100644 --- a/README.md +++ b/README.md @@ -229,6 +229,53 @@ Run in the LXC console ____________________________________________________________________________________________
    +
    + Home Assistant Core LXC + +

    + +

    Home Assistant Core LXC

    + +A standalone installation of Home Assistant Core + +To create a new Proxmox Home Assistant Core LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-core-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 8GB Storage - 2vCPU ⚡

    + +⚠️ Initialize Home Assistant-Core (Only required once)
    +Run in the LXC console +```yaml +cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass +``` + +***Home Assistant Interface - IP:8123*** + +⚙️ **Edit the HA configuration.yaml**
    +Run in the LXC console +```yaml +nano .homeassistant/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + +⚙️ **Install HACS:**
    +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs-core.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + +⚙️ **Update Home Assistant**
    +Run in the LXC console +```yaml +systemctl stop homeassistant.service && source /srv/homeassistant/bin/activate && pip3 install --upgrade homeassistant && systemctl start homeassistant.service && exit +``` +____________________________________________________________________________________________ +
    +
    Podman Home Assistant Container LXC From 869e7e29f86a7883f7b0718a2d4a24dfec713bf4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 11:30:16 -0400 Subject: [PATCH 3576/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f16ed59..f70bc7d4 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,7 @@ ________________________________________________________________________________
    - Home Assistant Core LXC + 🔸Home Assistant Core LXC

    From a2d92cffb839b1aaab2755dbd8e5e3ba8b488cf1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 11:32:25 -0400 Subject: [PATCH 3577/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b6c6e341..3fa037e3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **Home Assistant Container LXC** - If the LXC is created Privileged, the script will automatically set up USB passthrough. +- **Home Assistant Core LXC** + - NEW Script ## 2022-09-23 From 9f2119886a5feee3076a3eddd8376c6fe0c4ccf5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 12:11:55 -0400 Subject: [PATCH 3578/6505] Update pimox-haos-vm-v4.sh --- vm/pimox-haos-vm-v4.sh | 117 ++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/vm/pimox-haos-vm-v4.sh b/vm/pimox-haos-vm-v4.sh index 717300da..97dc8369 100644 --- a/vm/pimox-haos-vm-v4.sh +++ b/vm/pimox-haos-vm-v4.sh @@ -2,8 +2,9 @@ echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) -LATEST=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` HA=`echo "\033[1;34m"` @@ -15,6 +16,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -46,7 +48,7 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then +if (whiptail --title "PiMox HAOS VM" --yesno "This will create a New PiMox HAOS VM. Proceed?" 10 58); then echo "User selected Yes" else clear @@ -70,83 +72,77 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + function default_settings() { - echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" - HN=haos${STABLE} - echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" - CORE_COUNT="2" - echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" - echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" + echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" + HN=haos${STABLE} + echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 2 \ +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ "$STABLE" "Stable" ON \ -"$LATEST" "Latest" OFF \ +"$BETA" "Beta" OFF \ +"$DEV" "Dev" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" -else - exit -fi -VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi +VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" +if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${STABLE} --title "HOSTNAME" 3>&1 1>&2 2>&3) +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${VM_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +if [ -z $VM_NAME ]; then HN="haos${BRANCH}"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; else - exit + if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" +if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" 3>&1 1>&2 2>&3) +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" +if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else - exit + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; fi -MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) +MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? -if [ $exitstatus = 0 ]; then - MAC="$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +if [ -z $MAC1 ]; then MAC="$GEN_MAC"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}"; else - exit + if [ $exitstatus = 0 ]; then MAC="$MAC1"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"; fi fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; @@ -163,7 +159,7 @@ else echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" else clear @@ -173,7 +169,7 @@ else fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then clear header_info echo -e "${BL}Using Default Settings${CL}" @@ -236,7 +232,7 @@ for i in {0,1}; do done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 64M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null @@ -245,8 +241,9 @@ qm set $VMID \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null -qm set $VMID -description "# Home Assistant OS -### https://github.com/tteck/Proxmox" >/dev/null +qm set $VMID -description "# PiMox HAOS +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" From 0a31fd03f1f7046b8cd2bb0cb639f5d0b176bcd1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 12:33:10 -0400 Subject: [PATCH 3579/6505] Add files via upload --- misc/images/pimox.png | Bin 0 -> 23460 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/pimox.png diff --git a/misc/images/pimox.png b/misc/images/pimox.png new file mode 100644 index 0000000000000000000000000000000000000000..a6a8baed26745f0954bc3625fdeef795d3df958a GIT binary patch literal 23460 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 X(HY04u5`KO00000NkvXXu0mjfCXXUp literal 0 HcmV?d00001 From c3e7f17b6b2ef10f5fe1287b3b415d402b5bdd99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 12:38:00 -0400 Subject: [PATCH 3580/6505] Update README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index f70bc7d4..cf431786 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,30 @@ ________________________________________________________________________________

    +
    + PiMox HAOS VM + +

    + +

    PiMox HAOS VM

    +

    Option to create VM using Stable, Beta or Dev Image

    + +The script automates the manual process of finding, downloading and extracting the aarch64 (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. + +To create a new PiMox HAOS VM, run the following in the Proxmox Shell + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/pimox-haos-vm-v4.sh)" +``` +

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    + +After the script completes, click on the VM Console to find the Home Assistant IP. + +**Home Assistant Interface - IP:8123** + +____________________________________________________________________________________________ + +
    Home Assistant Container LXC From 04f4f542c6ec611bd44e1e386fcdcdc6e75c016d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 12:38:47 -0400 Subject: [PATCH 3581/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf431786..3b50be5b 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ ________________________________________________________________________________

    -

    PiMox HAOS VM

    +

    🔸PiMox HAOS VM

    Option to create VM using Stable, Beta or Dev Image

    The script automates the manual process of finding, downloading and extracting the aarch64 (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. From 97a6651ba3ab6861f2089a1e8eebab68ec882a09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 12:40:00 -0400 Subject: [PATCH 3582/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3fa037e3..39972f0c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - If the LXC is created Privileged, the script will automatically set up USB passthrough. - **Home Assistant Core LXC** - NEW Script +- **PiMox HAOS VM** + - NEW Script ## 2022-09-23 From 69c11f784420fbede93ba2a5f4f0721abe86c8fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 12:46:01 -0400 Subject: [PATCH 3583/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3b50be5b..c5951407 100644 --- a/README.md +++ b/README.md @@ -168,11 +168,11 @@ ________________________________________________________________________________
    - PiMox HAOS VM + 🔸PiMox HAOS VM

    -

    🔸PiMox HAOS VM

    +

    PiMox HAOS VM

    Option to create VM using Stable, Beta or Dev Image

    The script automates the manual process of finding, downloading and extracting the aarch64 (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. From 903904d0c3626f2dace6063c07c8fb2ae1720616 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 13:06:01 -0400 Subject: [PATCH 3584/6505] Update README.md --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c5951407..26f2dda7 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistan

    ⚡ Default Settings: 1GB RAM - 8GB Storage - 2vCPU ⚡

    -⚠️ Initialize Home Assistant-Core (Only required once)
    +⚠️ Initialize Home Assistant-Core (Only required once) + Run in the LXC console ```yaml cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass @@ -278,21 +279,24 @@ cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass ***Home Assistant Interface - IP:8123*** -⚙️ **Edit the HA configuration.yaml**
    +⚙️ **Edit the HA configuration.yaml** + Run in the LXC console ```yaml nano .homeassistant/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **Install HACS:**
    +⚙️ **Install HACS:** + Run in the LXC console ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs-core.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **Update Home Assistant**
    +⚙️ **Update Home Assistant** + Run in the LXC console ```yaml systemctl stop homeassistant.service && source /srv/homeassistant/bin/activate && pip3 install --upgrade homeassistant && systemctl start homeassistant.service && exit From c3a70f55c00cf4f0201f4bbe3912422eb6b07b7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 13:14:32 -0400 Subject: [PATCH 3585/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26f2dda7..a2d54fd8 100644 --- a/README.md +++ b/README.md @@ -256,7 +256,7 @@ ________________________________________________________________________________
    🔸Home Assistant Core LXC -

    +

    Home Assistant Core LXC

    From 6519b05150a1813a961d2d7042ab381843390e8a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 17:19:46 -0400 Subject: [PATCH 3586/6505] Update homeassistant-core-install.sh add psycopg2-binary --- setup/homeassistant-core-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index a7b441ce..a8783e1b 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -95,6 +95,7 @@ python3 -m venv . source bin/activate python3 -m pip install wheel &>/dev/null pip3 install homeassistant &>/dev/null +pip3 install psycopg2-binary &>/dev/null msg_ok "Installed Home Assistant-Core" msg_info "Creating Service" From c9e6edb2c45ec7318dc4b4329890c0c39f31ba30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 17:31:02 -0400 Subject: [PATCH 3587/6505] Update README.md --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a2d54fd8..06c84a25 100644 --- a/README.md +++ b/README.md @@ -260,7 +260,8 @@ ________________________________________________________________________________

    Home Assistant Core LXC

    -A standalone installation of Home Assistant Core +A standalone installation of Home Assistant Core
    +🛈 If the LXC is created Privileged, the script will automatically set up USB passthrough. To create a new Proxmox Home Assistant Core LXC, run the following in the Proxmox Shell. @@ -270,8 +271,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistan

    ⚡ Default Settings: 1GB RAM - 8GB Storage - 2vCPU ⚡

    -⚠️ Initialize Home Assistant-Core (Only required once) - +⚠️ Initialize Home Assistant-Core (Only required once)
    Run in the LXC console ```yaml cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass @@ -279,24 +279,21 @@ cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass ***Home Assistant Interface - IP:8123*** -⚙️ **Edit the HA configuration.yaml** - +⚙️ **Edit the HA configuration.yaml**
    Run in the LXC console ```yaml nano .homeassistant/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **Install HACS:** - +⚙️ **Install HACS:**
    Run in the LXC console ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs-core.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **Update Home Assistant** - +⚙️ **Update Home Assistant**
    Run in the LXC console ```yaml systemctl stop homeassistant.service && source /srv/homeassistant/bin/activate && pip3 install --upgrade homeassistant && systemctl start homeassistant.service && exit From 570d9e1ca694c73454ef6edc275273e0e8b3f209 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 17:35:05 -0400 Subject: [PATCH 3588/6505] Update README.md --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 06c84a25..7795ac68 100644 --- a/README.md +++ b/README.md @@ -260,8 +260,9 @@ ________________________________________________________________________________

    Home Assistant Core LXC

    -A standalone installation of Home Assistant Core
    -🛈 If the LXC is created Privileged, the script will automatically set up USB passthrough. +A standalone installation of Home Assistant Core + +🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* To create a new Proxmox Home Assistant Core LXC, run the following in the Proxmox Shell. @@ -271,7 +272,8 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistan

    ⚡ Default Settings: 1GB RAM - 8GB Storage - 2vCPU ⚡

    -⚠️ Initialize Home Assistant-Core (Only required once)
    +⚠️ Initialize Home Assistant-Core (Only required once) + Run in the LXC console ```yaml cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass @@ -279,21 +281,24 @@ cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass ***Home Assistant Interface - IP:8123*** -⚙️ **Edit the HA configuration.yaml**
    +⚙️ **Edit the HA configuration.yaml** + Run in the LXC console ```yaml nano .homeassistant/configuration.yaml ``` Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” -⚙️ **Install HACS:**
    +⚙️ **Install HACS:** + Run in the LXC console ```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs-core.sh)" ``` After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. -⚙️ **Update Home Assistant**
    +⚙️ **Update Home Assistant** + Run in the LXC console ```yaml systemctl stop homeassistant.service && source /srv/homeassistant/bin/activate && pip3 install --upgrade homeassistant && systemctl start homeassistant.service && exit From cce7033d8ffafaee3fcd955bdf7de4b96fc450a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Sep 2022 22:40:02 -0400 Subject: [PATCH 3589/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7795ac68..a20790fa 100644 --- a/README.md +++ b/README.md @@ -630,7 +630,7 @@ ________________________________________________________________________________
    - 🔸EMQX LXC + EMQX LXC

    From a8c195d9b453b9e05c4209bd3cda33f026c5b317 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Sep 2022 09:53:32 -0400 Subject: [PATCH 3590/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index e479fc5f..f45da0f8 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -26,7 +26,7 @@ echo -en "${GN} Updating Z-wave JS UI... " systemctl stop zwave-js-ui.service cd /opt/zwave-js-ui curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null -unzip zwave-js-ui-v*.zip zwave-js-ui &>/dev/null +unzip -o zwave-js-ui-v*.zip zwave-js-ui &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " From 25133371dc50e4ada6a955063d41b9b5e6b001a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Sep 2022 10:01:35 -0400 Subject: [PATCH 3591/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index f45da0f8..70108b55 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -21,6 +21,16 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } +clear +while true; do + read -p "This will update ZWave JS UI. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear echo -en "${GN} Updating Z-wave JS UI... " systemctl stop zwave-js-ui.service From 9e7e6ecbc2a58f4b6f2ae0634b5ef76c7ffd92bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Sep 2022 18:49:57 -0400 Subject: [PATCH 3592/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a20790fa..44d7d327 100644 --- a/README.md +++ b/README.md @@ -1760,6 +1760,7 @@ ________________________________________________________________________________
    Homepage LXC +

    Homepage LXC

    From 06260e9bc118218f81de38c65392600162f1188d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Sep 2022 21:10:05 -0400 Subject: [PATCH 3593/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 44d7d327..b5ae53c7 100644 --- a/README.md +++ b/README.md @@ -1404,7 +1404,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v4.sh) ⚙️ **To Update Omada** -https://github.com/tteck/Proxmox/issues/402#issue-1328460983 +[#403](https://github.com/tteck/Proxmox/issues/402#issue-1328460983) ____________________________________________________________________________________________ From 5f75108ff3cdab459688c756c49a0fea21a8c0ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Sep 2022 21:52:08 -0400 Subject: [PATCH 3594/6505] Update emby-install.sh --- setup/emby-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 5a448e55..28c762ab 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -87,8 +87,8 @@ msg_ok "Set Up Hardware Acceleration" LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Installing Emby" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null -dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.7.6.0/emby-server-deb_4.7.6.0_amd64.deb &>/dev/null +dpkg -i emby-server-deb_4.7.6.0_amd64.deb &>/dev/null msg_ok "Installed Emby" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 3d0207fbb1e0fc0ab2a2648962b3e0f10327c281 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 06:49:11 -0400 Subject: [PATCH 3595/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index daaecda5..fc737ee0 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -59,6 +59,7 @@ tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null cp -r /opt/paperless/paperless.conf paperless-ngx/ cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless +sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt pip install -r requirements.txt &>/dev/null cd /opt/paperless/src /usr/bin/python3 manage.py migrate &>/dev/null From 9299ca4736902df19fa6d65847374bdd30405a88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 07:45:27 -0400 Subject: [PATCH 3596/6505] Update influxdb-install.sh optional install Telegraf --- setup/influxdb-install.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 0dc32e13..3faa99b9 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -86,9 +86,19 @@ apt-get update &>/dev/null apt-get install -y influxdb &>/dev/null msg_ok "Installed InfluxDB" +read -r -p "Would you like to add Telegraf? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] +then +TELEGRAF="Y" +else +TELEGRAF="N" +fi + +if [[ $TELEGRAF == "Y" ]]; then msg_info "Installing Telegraf" apt-get install -y telegraf &>/dev/null msg_ok "Installed Telegraf" +fi PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then From 04da1046bd1c1e2ba5e893263e2935aa26e4d0a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 07:49:40 -0400 Subject: [PATCH 3597/6505] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b5ae53c7..ee956ea4 100644 --- a/README.md +++ b/README.md @@ -1144,11 +1144,13 @@ ________________________________________________________________________________
    - InfluxDB/Telegraf LXC + InfluxDB LXC

    -

    InfluxDB/Telegraf LXC

    +

    InfluxDB LXC

    + +

    Option to Install Telegraf

    [InfluxDB](https://www.influxdata.com/) is an open-source time series database developed by the company InfluxData. From 642346d366a2ae2c40270b8a05fa64b657afd890 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 11:02:23 -0400 Subject: [PATCH 3598/6505] Create hacore2hacontainer-data.sh --- misc/hacore2hacontainer-data.sh | 116 ++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 misc/hacore2hacontainer-data.sh diff --git a/misc/hacore2hacontainer-data.sh b/misc/hacore2hacontainer-data.sh new file mode 100644 index 00000000..0d0c0417 --- /dev/null +++ b/misc/hacore2hacontainer-data.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +while true; do + read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Home Assistant LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Container LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Core LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.10.02" 13 50 || exit +info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi +msg "Mounting Container Disks..." +DOCKER_PATH=/var/lib/docker/volumes/hass_config/_data +CORE_PATH=/root/.homeassistant +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${CORE_PATH}" ] || \ + die "Home Assistant directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_TO' not found." + +msg "Copying Data..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Docker Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacore2hacontainer-data.sh)" From 6d9f3940383e021fc81b32e04f63c1a7ac315bbb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 11:11:43 -0400 Subject: [PATCH 3599/6505] Update hacore2hacontainer-data.sh --- misc/hacore2hacontainer-data.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/hacore2hacontainer-data.sh b/misc/hacore2hacontainer-data.sh index 0d0c0417..98fe7684 100644 --- a/misc/hacore2hacontainer-data.sh +++ b/misc/hacore2hacontainer-data.sh @@ -59,13 +59,13 @@ while read -r line; do done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Container LXC would you like to copy FROM?\n" \ + "\nWhich HA Core LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Core LXC would you like to copy TO?\n" \ + "\nWhich HA Container LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done From c6c047288a6b910a28df917b5ba5b4fe26820343 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 11:32:20 -0400 Subject: [PATCH 3600/6505] Update hacore2hacontainer-data.sh --- misc/hacore2hacontainer-data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/hacore2hacontainer-data.sh b/misc/hacore2hacontainer-data.sh index 98fe7684..8edf5b74 100644 --- a/misc/hacore2hacontainer-data.sh +++ b/misc/hacore2hacontainer-data.sh @@ -106,7 +106,7 @@ RSYNC_OPTIONS=( --info=progress2 ) msg "<======== Docker Data ========>" -rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH} +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${CORE_PATH} ${CTID_TO_PATH}${DOCKER_PATH} echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." From 9c56a846da3e48a868e86bfe6a07c037525d6125 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 11:33:50 -0400 Subject: [PATCH 3601/6505] Create hacontainer2hacore-data.sh --- misc/hacontainer2hacore-data.sh | 116 ++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 misc/hacontainer2hacore-data.sh diff --git a/misc/hacontainer2hacore-data.sh b/misc/hacontainer2hacore-data.sh new file mode 100644 index 00000000..94476e09 --- /dev/null +++ b/misc/hacontainer2hacore-data.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +while true; do + read -p "Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Home Assistant LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Container LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Core LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.10.02" 13 50 || exit +info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi +msg "Mounting Container Disks..." +DOCKER_PATH=/var/lib/docker/volumes/hass_config/_data +CORE_PATH=/root/.homeassistant +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ + die "Home Assistant directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${CORE_PATH}" ] || \ + die "Home Assistant directories in '$CTID_TO' not found." + +msg "Copying Data..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Docker Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${CORE_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacontainer2hacore-data.sh)" From c2886904440f74c825e04005ffcf65ef35f250a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 16:16:55 -0400 Subject: [PATCH 3602/6505] Create README_NEW.md --- README_NEW.md | 2575 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2575 insertions(+) create mode 100644 README_NEW.md diff --git a/README_NEW.md b/README_NEW.md new file mode 100644 index 00000000..ac97b90b --- /dev/null +++ b/README_NEW.md @@ -0,0 +1,2575 @@ +

    Select a Proxmox Helper

    + +

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    + + +
    + Proxmox Tools +⬇____________________________________________________________________________________________ +
    + Proxmox VE 7 Post Install + +

    + +

    Proxmox VE 7 Post Install

    + +The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox VE and Reboot PVE. + +Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pve-install.sh)" +``` + +It's recommended to answer `y` to all options. + +____________________________________________________________________________________________ + +
    + +
    + Proxmox Kernel Clean + +

    + +

    Proxmox Kernel Clean

    + +Cleaning unused kernel images is not only good because of a reduced grub menu, but also gains some disk space. + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + Proxmox Edge Kernel Tool + +

    + +

    Proxmox Edge Kernel Tool

    + +Proxmox [Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7. Keeping up with new Kernel releases instead of LTS + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + Proxmox CPU Scaling Governor + +

    + +

    Proxmox CPU Scaling Governor

    + +CPU Scaling Governor enables the operating system to scale the CPU frequency up or down in order to save power or improve performance. + +[Generic Scaling Governors](https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html?#generic-scaling-governors) + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/scaling-governor.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + Proxmox LXC Updater + +

    + +

    Proxmox LXC Updater

    + +Update All LXC's Fast & Easy + +Run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + Proxmox Dark Theme + +

    + +

    Proxmox Discord Dark Theme

    + +A dark theme for the Proxmox Web UI by [Weilbyte](https://github.com/Weilbyte/PVEDiscordDark) + +Run the following in the Proxmox Shell. + +```yaml +bash <(curl -s https://raw.githubusercontent.com/Weilbyte/PVEDiscordDark/master/PVEDiscordDark.sh ) install +``` + +To uninstall the theme, simply run the script with the `uninstall` command. + +____________________________________________________________________________________________ + +
    + +
    + Proxmox Backup Server Post Install + +

    + +

    Proxmox Backup Server Post Install

    + +The script will give options to Disable the Enterprise Repo, Add/Correct PBS Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox Backup Server and Reboot PBS. + +Run the following in the Proxmox Shell. ⚠️ **Proxmox Backup Server ONLY** + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pbs-install.sh)" +``` + +It's recommended to answer `y` to all options. + +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Home Assistant +⬇____________________________________________________________________________________________ + +
    + Home Assistant OS VM + +

    + +

    Home Assistant OS VM

    +

    Option to create VM using Stable, Beta or Dev Image

    + +The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip, ect...) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. + +To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v4.sh)" +``` +

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    + +After the script completes, click on the VM, then on the **_Summary_** tab to find the VM IP. + +**Home Assistant Interface - IP:8123** + +____________________________________________________________________________________________ + +
    + +
    + 🔸PiMox HAOS VM + +

    + +

    PiMox HAOS VM

    +

    Option to create VM using Stable, Beta or Dev Image

    + +The script automates the manual process of finding, downloading and extracting the aarch64 (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. + +To create a new PiMox HAOS VM, run the following in the Proxmox Shell + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/pimox-haos-vm-v4.sh)" +``` +

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    + +After the script completes, click on the VM Console to find the Home Assistant IP. + +**Home Assistant Interface - IP:8123** + +____________________________________________________________________________________________ + +
    + +
    + Home Assistant Container LXC + +

    Docker Logos | Docker +@home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    + +

    Home Assistant Container LXC

    + +A standalone container-based installation of Home Assistant Core + +🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* + +To create a new Proxmox Home Assistant Container LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    + +**Home Assistant Interface - IP:8123** + +**Portainer Interface - IP:9000** + +⚙️ **Path to HA /config** +```yaml +/var/lib/docker/volumes/hass_config/_data + ``` +⚙️ **To Edit the HA configuration.yaml** (Recommend Using File Browser) + +Run in the LXC console +```yaml +nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + +⚙️ **Copy Data From a Existing Home Assistant LXC to another Home Assistant LXC** + +Run in the Proxmox Shell +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data.sh)" + ``` + +⚙️ **To Install HACS:** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + + +⚙️ [**Update Menu**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) + +Run in the LXC console +```yaml +./update +``` +____________________________________________________________________________________________ +
    + +
    + 🔸Home Assistant Core LXC + +

    + +

    Home Assistant Core LXC

    + +A standalone installation of Home Assistant Core + +🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* + +To create a new Proxmox Home Assistant Core LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-core-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 8GB Storage - 2vCPU ⚡

    + +⚠️ Initialize Home Assistant-Core (Only required once) + +Run in the LXC console +```yaml +cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass +``` + +***Home Assistant Interface - IP:8123*** + +⚙️ **Edit the HA configuration.yaml** + +Run in the LXC console +```yaml +nano .homeassistant/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + +⚙️ **Install HACS:** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs-core.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + +⚙️ **Update Home Assistant** + +Run in the LXC console +```yaml +systemctl stop homeassistant.service && source /srv/homeassistant/bin/activate && pip3 install --upgrade homeassistant && systemctl start homeassistant.service && exit +``` +____________________________________________________________________________________________ +
    + +
    + Podman Home Assistant Container LXC + +

    +@home-assistant

    + +

    Podman Home Assistant Container LXC

    +A standalone container-based installation of Home Assistant Core + +⚠️ Podman seems to need a privileged LXC + +To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    + +**Home Assistant Interface - IP:8123** + +**Yacht Interface - IP:8000** + +⚙️ **Path to HA /config** +```yaml +/var/lib/containers/storage/volumes/hass_config/_data + ``` +⚙️ **To edit the HA configuration.yaml** + +Run in the LXC console +```yaml +nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml +``` +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + +⚙️ **Copy Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** + +Run in the Proxmox Shell +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data-podman.sh)" + ``` + +⚙️ **To allow USB device passthrough:** + +Run in the Proxmox Shell. (**replace `106` with your LXC ID**) +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 +``` + +Reboot the LXC to apply the changes + +⚙️ **To Install HACS:** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/podman_hacs.sh)" +``` +After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. + +⚙️ **Initial Yacht Login** + +**username** + ```yaml + admin@yacht.local + ``` + **password** + ```yaml + pass + ``` + +____________________________________________________________________________________________ +
    +⬆____________________________________________________________________________________________ +
    + +
    + Automation +⬇____________________________________________________________________________________________ + +
    + ioBroker LXC + +

    + +

    ioBroker LXC

    + +[ioBroker](https://www.iobroker.net/#en/intro) is an open source automation platform. + +To create a new Proxmox ioBroker LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/iobroker-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**ioBroker Interface - IP:8081** + +⚙️ **To Update ioBroker** + +```yaml +update from the ioBroker UI +``` + +____________________________________________________________________________________________ + +
    + +
    + openHAB LXC + +

    + +

    openHAB LXC

    + +[openHAB](https://www.openhab.org/), a vendor and technology agnostic open source automation software for your home. + +To create a new Proxmox openHAB LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/openhab-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**openHAB Interface - IP:8080** + +⚙️ **To Update openHAB** + +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    + +
    + Homebridge LXC + +

    + +

    Homebridge LXC

    + +[Homebridge](https://homebridge.io/) allows you to integrate with smart home devices that do not natively support HomeKit + +To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +**Homebridge Interface - IP:8581** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` +Config File Path `/var/lib/homebridge/config.json` + +Storage Path `/var/lib/homebridge` + +Restart Command `sudo hb-service restart` + +Stop Command `sudo hb-service stop` + +Start Command `sudo hb-service start` + +View Logs Command `sudo hb-service logs` + +Systemd Service File `/etc/systemd/system/homebridge.service` + +Systemd Env File `/etc/default/homebridge` + +⚙️ **To Update Homebridge** + +```yaml +Update from the Homebridge UI +``` + + ___________________________________________________________________________________________ + +
    + + + +
    + ESPHome LXC + +

    + +

    ESPHome LXC

    + +[ESPHome](https://esphome.io/) is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems. + +To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +**ESPHome Interface - IP:6052** + +⚙️ **To Update ESPHome** + +Run in the LXC console +```yaml +pip3 install esphome --upgrade +``` + +____________________________________________________________________________________________ + +
    + +
    + Node-Red LXC + +

    + +

    Node-Red LXC

    + +[Node-RED](https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. + +To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +**Node-Red Interface - IP:1880** + +⚙️ **To Restart Node-Red:** + +Run in the LXC console +```yaml +node-red-restart +``` + +⚙️ **To Update Node-Red:** + +Run in the LXC console (Restart after update) +```yaml +npm install -g --unsafe-perm node-red +``` + +⚙️ **To Install Node-Red Themes** ⚠️ **Backup your flows before running this script!!** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/node-red-themes.sh)" +``` + +____________________________________________________________________________________________ + +
    + +
    + n8n LXC + +

    + +

    n8n LXC

    + +[n8n](https://n8n.io/) is an extendable workflow automation tool which enables you to connect anything to everything. + +To create a new Proxmox n8n LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/n8n-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    + +**n8n Interface: IP:5678** + +⚙️ **To Update n8n** + +```yaml +npm update -g n8n +``` + +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + MQTT +⬇____________________________________________________________________________________________ + +
    + MQTT LXC + +

    + +

    MQTT LXC

    + +[Eclipse Mosquitto](https://mosquitto.org/) is an open source message broker that implements the MQTT protocol + +To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +Mosquitto comes with a password file generating utility called mosquitto_passwd. +```yaml +sudo mosquitto_passwd -c /etc/mosquitto/passwd +``` +Password: < password > + +Create a configuration file for Mosquitto pointing to the password file we have just created. +```yaml +sudo nano /etc/mosquitto/conf.d/default.conf +``` +This will open an empty file. Paste the following into it. +```yaml +allow_anonymous false +persistence true +password_file /etc/mosquitto/passwd +listener 1883 +``` +Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X". + +Now restart Mosquitto server. +```yaml +sudo systemctl restart mosquitto +``` + +⚙️ **To Update MQTT:** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    + +
    + EMQX LXC + +

    + + +

    EMQX LXC

    + +[EMQX](https://www.emqx.io/) is an Open-source MQTT broker with a high-performance real-time message processing engine, powering event streaming for IoT devices at massive scale. + +To create a new Proxmox EMQX LXC, run the following in the Proxmox Shell. + +```yaml + bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emqx-v4.sh)" +``` +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + + +**EMQX Interface - IP:18083** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + public + ``` +⚙️ **Setup** + +Access Control ➡ Authentication ➡ Create ➡ Next ➡ Next ➡ Create ➡ Users ➡ Add ➡ Username / Password (to authenicate with MQTT) ➡ Save. You're now ready to enjoy a high-performance MQTT Broker. + +⚙️ **To Update EMQX** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + + ____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + + +
    + Database +⬇____________________________________________________________________________________________ + +
    + Mariadb LXC + +

    MariaDB

    + +

    Mariadb LXC

    +

    Option to Install Adminer

    + +[MariaDB](https://mariadb.org/) is a community-developed, commercially supported fork of the MySQL relational database management system. + +To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: +```yaml +nano /etc/mysql/my.cnf +``` +Un-comment `port =3306` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". + +```yaml +nano /etc/mysql/mariadb.conf.d/50-server.cnf +``` +Comment `bind-address = 127.0.0.1` +Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". + +For new MariaDB installations, the next step is to run the included security script. This script changes some of the less secure default options. We will use it to block remote root logins and to remove unused database users. + +Run the security script: +```yaml +sudo mysql_secure_installation +``` +Enter current password for root (enter for none): `enter` + +Switch to unix_socket authentication [Y/n] `y` + +Change the root password? [Y/n] `n` + +Remove anonymous users? [Y/n] `y` + +Disallow root login remotely? [Y/n] `y` + +Remove test database and access to it? [Y/n] `y` + +Reload privilege tables now? [Y/n] `y` + +We will create a new account called admin with the same capabilities as the root account, but configured for password authentication. +```yaml +sudo mysql +``` +Prompt will change to ```MariaDB [(none)]>``` + +Create a new local admin (Change the username and password to match your preferences) +```yaml +CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password'; +``` +Give local admin root privileges (Change the username and password to match above) +```yaml +GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; +``` + +Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on your local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the **_username_**, **_password_** and **_subnet_** to match your preferences: +```yaml +GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; +``` +Flush the privileges to ensure that they are saved and available in the current session: +```yaml +FLUSH PRIVILEGES; +``` +Following this, exit the MariaDB shell: +```yaml +exit +``` +Log in as the new database user you just created: +```yaml +mysql -u admin -p +``` +Create a new database: +```yaml +CREATE DATABASE homeassistant; +``` +Following this, exit the MariaDB shell: +```yaml +exit +``` +⚠️ Reboot the lxc + +Checking status. +```yaml +sudo systemctl status mariadb +``` +Change the recorder: `db_url:` in your HA configuration.yaml + +Example: +```yaml +recorder: + db_url: mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4 +``` + +⚙️ **To Update Mariadb:** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` +⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool + + `http://your-mariadb-lxc-ip/adminer/` + +____________________________________________________________________________________________ + +
    + +
    + PostgreSQL LXC + +

    + +

    PostgreSQL LXC

    +

    Option to Install Adminer

    + +[PostgreSQL](https://www.postgresql.org/), also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance. + +To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +To make sure our PostgreSQL is secured with a strong password, set a password for its system user and then change the default database admin user account + +Change user password +```yaml +passwd postgres +``` +Login using Postgres system account + +```yaml +su - postgres +``` +Now, change the Admin database password +```yaml +psql -c "ALTER USER postgres WITH PASSWORD 'your-password';" +``` +Create a new user. +```yaml +psql +``` +```yaml +CREATE USER admin WITH PASSWORD 'your-password'; +``` +Create a new database: +```yaml +CREATE DATABASE homeassistant; +``` +Grant all rights or privileges on created database to the user +```yaml +GRANT ALL ON DATABASE homeassistant TO admin; +``` +To exit psql +```yaml +\q +``` +Then type exit to get back to root + +Change the recorder: `db_url:` in your HA configuration.yaml + +Example: +```yaml +recorder: + db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8 +``` +⚙️ **To Update PostgreSQL** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` +⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool + + `http://your-PostgreSQL-lxc-ip/adminer/` + +____________________________________________________________________________________________ + +
    + +
    + InfluxDB LXC + +

    + +

    InfluxDB LXC

    + +

    Option to Install Telegraf

    + +[InfluxDB](https://www.influxdata.com/) is an open-source time series database developed by the company InfluxData. + +[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) is an open source plugin-driven server agent for collecting and reporting metrics. + +To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +⚙️ **InfluxDB Configuration** + +Run in the LXC console +```yaml +nano /etc/influxdb/influxdb.conf +``` + +⚙️ **Telegraf Configuration** + +Run in the LXC console +```yaml +nano /etc/telegraf/telegraf.conf +``` + +⚙️ **To Update InfluxDB/Telegraf** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Zigbee - Zwave +⬇____________________________________________________________________________________________ + +
    + Zigbee2MQTT LXC + +

    + + +

    Zigbee2MQTT LXC

    + +[Zigbee2MQTT](https://www.zigbee2mqtt.io/) is a standalone nodejs application that connects a zigbee network to MQTT + +To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt-v4.sh)" +``` +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + + +⚙️ **Determine the location of your adapter** + +Run in the LXC console +```yaml +ls -l /dev/serial/by-id +``` +Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` + + +⚙️ ⚠️ **Before you start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** + +Run in the LXC console +```yaml +nano /opt/zigbee2mqtt/data/configuration.yaml +``` + +Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” + +Example: +```yaml +frontend: + port: 9442 +homeassistant: true +permit_join: false +mqtt: + base_topic: zigbee2mqtt + server: 'mqtt://192.168.86.224:1883' + user: usr + password: pwd + keepalive: 60 + reject_unauthorized: true + version: 4 +serial: + port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 + #adapter: deconz #(uncomment for ConBee II) +advanced: + pan_id: GENERATE + network_key: GENERATE + channel: 20 +``` +⚙️ **Zigbee2MQTT can be started after completing the configuration** + +Run in the LXC console +```yaml +cd /opt/zigbee2mqtt && npm start +``` +⚙️ **To update Zigbee2MQTT** + +Run in the LXC console + ```yaml +cd /opt/zigbee2mqtt && bash update.sh + ``` +⚙️ **Copy Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** + +Run in the Proxmox Shell +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/z2m-copy-data.sh)" + ``` + +____________________________________________________________________________________________ + +
    + +
    + deCONZ LXC + +

    + +

    deCONZ LXC

    + +[deCONZ](https://www.phoscon.de/en/conbee2/software#deconz) is used to configure, control and display Zigbee networks. + +To create a new Proxmox deCONZ LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/deconz-v4.sh)" +``` +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +**deCONZ Interface - IP:80** + +⚙️ **To Update deCONZ** + +Run in the LXC Console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    + +
    + Z-Wave JS UI LXC + +

    + +

    Z-Wave JS UI LXC

    + +[Z-Wave JS UI](https://github.com/zwave-js/zwave-js-ui#) is a fully configurable Z-Wave to MQTT Gateway and Control Panel. + +To create a new Proxmox Z-Wave JS UI LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwave-js-ui-v4.sh)" +``` +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +**Z-Wave JS UI Interface - IP:8091** + +⚙️ **Copy Data From a Existing Zwavejs2MQTT LXC to a Z-Wave JS UI LXC** + +Run in the Proxmox Shell +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-copy-data.sh)" + ``` +⚙️ **To Update Z-Wave JS UI** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-js-ui-update.sh)" +``` + +____________________________________________________________________________________________ +
    +⬆____________________________________________________________________________________________ +
    + +
    + Monitoring - Analytics +⬇____________________________________________________________________________________________ + +
    + Uptime Kuma LXC + +

    + +

    Uptime Kuma LXC

    + +Uptime Kuma is a self-hosted, open source, fancy uptime monitoring and alerting system. It can monitor HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server. + +To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1vCPU ⚡

    + +**Uptime Kuma Interface - IP:3001** + +⚙️ **To Update Uptime Kuma** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/uptimekuma-update.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + Prometheus LXC + +

    + +

    Prometheus LXC

    + +[Prometheus](https://prometheus.io/) is an open-source systems monitoring and alerting toolkit + +To create a new Proxmox Prometheus LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/prometheus-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 1vCPU ⚡

    + +**Prometheus Interface - IP:9090** + +⚙️ **To Update Prometheus** + +```yaml +Working On +``` + +____________________________________________________________________________________________ + +
    + + +
    + Grafana LXC + +

    + +

    Grafana LXC

    + +[Grafana](https://grafana.com/) is a multi-platform open source analytics and interactive visualization web application. + +To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Grafana Interface - IP:3000** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` + +⚙️ **To Update Grafana** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Docker +⬇____________________________________________________________________________________________ + +
    + Docker LXC + +

    + +

    Docker LXC

    +

    Options to Install Portainer and/or Docker Compose V2

    + +[Docker](https://www.docker.com/) is an open-source project for automating the deployment of applications as portable, self-sufficient containers. + +To create a new Proxmox Docker LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    + +**⚠ Run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** + +**Portainer Interface - IP:9000** + +⚙️ **To Update** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    + +
    + CasaOS LXC + +

    + +

    CasaOS LXC

    + +[CasaOS](https://www.casaos.io/) is a community-based open source software focused on delivering simple home cloud experience around Docker ecosystem. + + +To create a new Proxmox CasaOS LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/casaos-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**CasaOS Interface - IP** + +⚙️ **To Update CasaOS** + +```yaml +update from the CasaOS UI +``` + +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + OS +⬇____________________________________________________________________________________________ + +
    + Debian LXC + +

    Debian

    + +

    Debian LXC

    +

    Option to select version 10 or 11

    + +To create a new Proxmox Debian (curl & sudo) LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +⚙️ **To Update Debian** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    + + +
    + Ubuntu LXC + +

    Ubuntu

    + +

    Ubuntu LXC

    +

    Option to select version 18.04, 20.04, 21.10 or 22.04

    + +To create a new Proxmox Ubuntu (curl & sudo) LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04 ⚡

    + +⚙️ **To Update Ubuntu** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Server - Networklng +⬇____________________________________________________________________________________________ + +
    + Nginx Proxy Manager LXC + +

    hero

    + + +

    Nginx Proxy Manager LXC

    + +[Nginx Proxy Manager](https://nginxproxymanager.com/) Expose your services easily and securely + +To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. + +```yaml + bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager-v4.sh)" +``` +

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

    + +____________________________________________________________________________________ + +Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. + +Add the following to your `configuration.yaml` in Home Assistant. +```yaml + http: + use_x_forwarded_for: true + trusted_proxies: + - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### +``` + +**Nginx Proxy Manager Interface - IP:81** + +⚙️ **Initial Login** + +**username** + ```yaml + admin@example.com + ``` + **password** + ```yaml + changeme + ``` +⚙️ **To Update Nginx Proxy Manager** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update.sh)" +``` + +____________________________________________________________________________________________ + +
    + +
    + UniFi Network Application LXC + +

    + +

    UniFi Network Application LXC

    + +

    With Local Controller Option

    + +An application designed to optimize UniFi home and business networks with ease. + +To create a new Proxmox UniFi Network Application LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**UniFi Interface - https:// IP:8443** + +⚙️ **To Update UniFi** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/unifi-update.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + Omada Controller LXC + +

    + +

    Omada Controller LXC

    + +Omada Controller is software which is used to manage the EAP + +To create a new Proxmox Omada Controller LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**Omada Interface - https:// IP:8043** + +`tpeap status` show status of Omada Controller + +`tpeap start` start Omada Controller + +`tpeap stop` stop Omada Controller + +⚙️ **To Update Omada** + +[#403](https://github.com/tteck/Proxmox/issues/402#issue-1328460983) + +____________________________________________________________________________________________ + +
    + +
    + WireGuard LXC + +

    + +

    WireGuard LXC

    +

    With WGDashboard

    + +To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**WGDashboard Interface - http:// IP:10086** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` + +⚙️ **Host Configuration** + +Run in the LXC console + ```yaml + nano /etc/pivpn/wireguard/setupVars.conf + ``` + ⚙️**Add Clients** + + Run in the LXC console + ```yaml + pivpn add + ``` +⚙️ **To Update WireGuard** + +Run in the LXC console + ```yaml +apt update && apt upgrade -y +``` +____________________________________________________________________________________________ + +
    + + +
    + MeshCentral LXC + +

    + +

    MeshCentral LXC

    + +[MeshCentral](https://meshcentral.com/info/) is a full computer management web site. With MeshCentral, you can run your own web server to remotely manage and control computers on a local network or anywhere on the internet. + +To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**MeshCentral Interface - http:// IP** + +⚙️ **To Update MeshCentral** + +```yaml +Update from the MeshCentral UI +``` +____________________________________________________________________________________________ + +
    + +
    + Tailscale + +

    + +

    Tailscale

    + +[Tailscale](https://tailscale.com/) Creates a secure network between your servers, computers, and cloud instances. Even when separated by firewalls or subnets, Tailscale just works. + +To Install Talescale on an existing LXC, run the following in the Proxmox Shell (replace `106` with your LXC ID). + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/add-tailscale-lxc.sh)" -s 106 +``` +After the script finishes, reboot the LXC then run `tailscale up` in the LXC console + +[**Tailscale Login**](https://login.tailscale.com/start) + +⚙️ **To Update Tailscale** + +Run in the LXC console + ```yaml +apt update && apt upgrade -y +``` + +___________________________________________________________________________________________ + +
    + +
    + CrowdSec + +

    + +

    CrowdSec

    + +To Install CrowdSec, ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec.sh)" +``` + +[CrowdSec](https://crowdsec.net/) is a free, open-source and collaborative IPS. Analyze behaviors, respond to attacks & share signals across the community. + +[**Control center for your CrowdSec machines.**](https://app.crowdsec.net/product-tour) + +___________________________________________________________________________________________ + +
    + +
    + Keycloak LXC + +

    + +

    Keycloak LXC

    + +To create a new Proxmox Keycloak LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/keycloak-v4.sh)" +``` + +[Keycloak](https://www.keycloak.org/) is an Open Source Identity and Access Management solution for modern Applications and Services. + +**Keycloak Interface - http:// IP:8080** (First start can take a few minutes) + +⚙️ **Initial Login** + +The initial admin user can be added manually using the web frontend when accessed from localhost or automatically using environment variables. + +To add the initial admin user using environment variables, set `KEYCLOAK_ADMIN` for the initial admin username and `KEYCLOAK_ADMIN_PASSWORD` for the initial admin password. + +First, stop Keycloak +```yaml +systemctl stop keycloak.service +``` +then start Keycloak by coping & pasting the following (only needed once) +```yaml +cd /opt/keycloak +export KEYCLOAK_ADMIN=admin +export KEYCLOAK_ADMIN_PASSWORD=changeme + +bin/kc.sh start-dev +``` +⚙️ **To Update Keycloak** + +```yaml +working On +``` +___________________________________________________________________________________________ + +
    + +
    + Mikrotik RouterOS VM + +

    + +

    Mikrotik RouterOS VM

    + +[Mikrotik RouterOS](https://wiki.mikrotik.com/wiki/Manual:TOC) can be installed on a PC and will turn it into a router with all the necessary features - routing, firewall, bandwidth management, wireless access point, backhaul link, hotspot gateway, VPN server and more. + +To create a new Proxmox Mikrotik RouterOS VM, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/mikrotik-routeros-v4.sh)" +``` +Setup is done via VM console. + +

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1CPU ⚡

    + + +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Media - Photo +⬇____________________________________________________________________________________________ + +
    + Plex Media Server LXC + +

    + +

    Plex Media Server LXC

    +

    With Hardware Acceleration Support

    +To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**Plex Media Server Interface - IP:32400/web** + +⚙️ **To Update Plex Media Server:** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` +⚙️ **Copy Data From a Existing Plex Media Server LXC to another Plex Media Server LXC** + +Run in the Proxmox Shell +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/pms-copy-data.sh)" + ``` + +____________________________________________________________________________________________ + +
    + +
    + Emby Media Server LXC +

    +

    Emby Media Server LXC

    + +[Emby](https://emby.media/) brings together your personal videos, music, photos, and live television. + +To create a new Proxmox Emby Media Server LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**Emby Media Server Interface - IP:8096** + +⚙️ **Emby Media Server Utilizes Automatic Updates** + +____________________________________________________________________________________________ + +
    + +
    + Jellyfin Media Server LXC +

    +

    Jellyfin Media Server LXC

    + +[TurnKey has a LXC CT for Jellyfin](https://www.turnkeylinux.org/mediaserver) + +To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**Jellyfin Media Server Interface - IP:8096** + +FFmpeg path: `/usr/lib/jellyfin-ffmpeg/ffmpeg` + +⚙️ **To Update Jellyfin Media Server** + +Run in the LXC console +```yaml +apt update && apt upgrade -y +``` +____________________________________________________________________________________________ + +
    + +
    + NextCloudPi LXC + +

    + +

    NextCloudPi LXC

    + +[NextCloudPi LXC](https://github.com/nextcloud/nextcloudpi#features) is the most popular self-hosted collaboration solution. + +To create a new Proxmox NextCloudPi LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nextcloudpi-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +❗1️. Set nc trusted domains + +Run in the LXC console +``` +sudo ncp-config +``` +Go to config ➡ nc-trusted-domains, add `0.0.0.0` or a static NextCloudPi IP + +Get back to the command prompt, and restart Apache2 `sudo service apache2 restart` + +❗2. **NextCloudPi Interface - https:// IP/** + +____________________________________________________________________________________________ + +
    + +
    + OpenMediaVault LXC + +

    + +

    OpenMediaVault LXC

    + +[OpenMediaVault](https://www.openmediavault.org/) is the next generation network attached storage (NAS) solution based on Debian Linux. + +To create a new Proxmox OpenMediaVault LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omv-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +**OpenMediaVault Interface - IP** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + openmediavault + ``` + +____________________________________________________________________________________________ + +
    + +
    + Navidrome LXC + +

    + +

    Navidrome LXC

    + +[Navidrome](https://www.navidrome.org/) allows you to enjoy your music collection from anywhere, by making it available through a modern Web UI and through a wide range of third-party compatible mobile apps, for both iOS and Android devices. + +To create a new Proxmox Navidrome LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/navidrome-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    + +To change Navidrome music folder path, edit: `/var/lib/navidrome/navidrome.toml` + +**Navidrome Interface - IP:4533** + +⚙️ **To Update Navidrome** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/navidrome-update.sh)" +``` + +____________________________________________________________________________________________ + +
    + +
    + PhotoPrism LXC + +

    + +

    PhotoPrism LXC

    + +[PhotoPrism](https://photoprism.app/) is an AI-powered app for browsing, organizing & sharing your photo collection. + +To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**PhotoPrism Interface - IP:2342** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + changeme + ``` +[PhotoSync](https://www.photosync-app.com/home.html) + +⚙️ **To Update or Change Branch** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/photoprism-update.sh)" +``` +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Ad Blocker +⬇____________________________________________________________________________________________ + +
    + Pi-hole LXC + +

    + +

    Pi-hole LXC

    + +[Pi-hole](https://pi-hole.net/) is a Linux network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole and optionally a DHCP server. + +To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v4.sh)" +``` +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +⚠️ **Reboot Pi-hole LXC after install** + +**Pi-hole Interface - http:// IP/admin** + +⚙️ **To set your password:** + +Run in the LXC console + +```yaml +pihole -a -p +``` +____________________________________________________________________________________________ + +
    + +
    + Technitium DNS LXC + +

    + +

    Technitium DNS LXC

    +An open source authoritative as well as recursive DNS server + +To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Technitium DNS Interface - IP:5380** + +⚙️ **To Update Technitium DNS** + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/technitiumdns-update.sh)" +``` +__________________________________________________________________________________________ + +
    + + +
    + AdGuard Home LXC + +

    + +

    AdGuard Home LXC

    + +To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**AdGuard Home Setup Interface - IP:3000 (After Setup use only IP)** + + (For the Home Assistant Integration, use port `80` not `3000`) + +⚙️ **To Update Adguard** + +```yaml +Update from the Adguard UI +``` +__________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Document - Notes +⬇____________________________________________________________________________________________ + +
    + Paperless-ngx LXC + +

    + +

    Paperless-ngx LXC

    + +[Paperless-ngx](https://paperless-ngx.readthedocs.io/en/latest/#) is a document management system that transforms your physical documents into a searchable online archive so you can keep, well, less paper. + +To create a new Proxmox Paperless-ngx LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/paperless-ngx-v4.sh)" +``` + +

    ⚡ Default Settings: 2048MiB RAM - 4GB Storage - 2vCPU ⚡

    + +**Paperless-ngx Interface - IP:8000** + +🛈 A paperless.creds file is in root home directory that contains the usernames and passwords. + +Run in the LXC Console +```yaml +cat paperless.creds +``` + +⚙️ **To Update Paperless-ngx** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/paperless-ngx-update.sh)" +``` +____________________________________________________________________________________________ + +
    + +
    + Trilium LXC + +

    + +

    Trilium LXC

    + +[Trilium](https://github.com/zadam/trilium#trilium-notes) is a hierarchical note taking application with focus on building large personal knowledge bases. + +To create a new Proxmox Trilium LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/trilium-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Trilium Interface - IP:8080** + +⚙️ **To Update Trilium** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/trilium-update.sh)" +``` + +____________________________________________________________________________________________ + +
    + +
    + Wiki.js LXC + +

    + +

    Wiki.js LXC

    + +[Wiki.js](https://js.wiki/) is a modern, lightweight and powerful wiki app built on NodeJS. + +To create a new Proxmox Wiki.js LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wikijs-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Wiki.js Interface - IP:3000** + +____________________________________________________________________________________________ + +
    + +
    + NocoDB LXC + +

    + +

    NocoDB LXC

    + +[NocoDB](https://www.nocodb.com/) is an open source #NoCode platform that turns any database into a smart spreadsheet. Airtable Alternative. + +To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    + +**NocoDB Interface - IP:8080/dashboard** + +⚙️ **To Update NocoDB** + +Run in the LXC console +```yaml +cd /opt/nocodb && npm run upgrade +``` + +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + +
    + Dashboards +⬇____________________________________________________________________________________________ + +
    + Heimdall Dashboard LXC + +

    + +

    Heimdall Dashboard LXC

    + +[Heimdall Application Dashboard](https://camo.githubusercontent.com/bcfd4f74c93b25bea7b14eacbafd649206bf754a3d4b596329968f0ee569cf3c/68747470733a2f2f692e696d6775722e636f6d2f4d72433451704e2e676966) is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like. + +To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard-v4.sh)" +``` +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Heimdall Dashboard Interface - IP:7990** + +⚙️ **To Update Heimdall Dashboard** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard-all-update.sh)" +``` + +__________________________________________________________________________________________ + +
    + +
    + Homepage LXC + +

    + +

    Homepage LXC

    + +[Homepage](https://github.com/benphelps/homepage) is a self-hosted dashboard. + +To create a new Proxmox Homepage LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homepage-v4.sh)" +``` + +

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 2vCPU ⚡

    + +[Configuration](https://github.com/benphelps/homepage/wiki) (bookmarks.yaml, services.yaml, widgets.yaml) path: `/opt/homepage/config/` + +**Homepage Interface - IP:3000** + +⚙️ **To Update Homepage** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/homepage-update.sh)" +``` + +____________________________________________________________________________________________ + +
    + +
    + Dashy LXC + +

    + +

    Dashy LXC

    + +Dashy helps you organize your self-hosted services by making them accessible from a single place + +To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy-v4.sh)" +``` +

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    + +**Dashy Interface - IP:4000** + +After getting everything setup the way you want in interactive mode and saved to disk, you have to go into update configuration and rebuild application. + +⚙️ **To Update Dashy** + +Run in the LXC Console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/dashy-update.sh)" +``` + +__________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ +
    + + +
    + File Working +⬇____________________________________________________________________________________________ +
    + File Browser + +

    + +

    File Browser

    + +To Install File Browser, ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/filebrowser.sh)" +``` + +[File Browser](https://filebrowser.org/features) is a create-your-own-cloud-kind of software where you can install it on a server, direct it to a path and then access your files through a nice web interface. Many available features! + + + +**File Browser Interface - http:// IP:8080** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + changeme + ``` + +⚙️ **To Update File Browser** + +```yaml +curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash +``` +___________________________________________________________________________________________ + +
    + +
    + VS Code Server + +

    + +

    VS Code Server

    + +To Install VS Code Server, ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/code-server.sh)" +``` + +[VS Code Server](https://code.visualstudio.com/docs/remote/vscode-server) is a service you can run on a remote development machine, like your desktop PC or a virtual machine (VM). It allows you to securely connect to that remote machine from anywhere through a vscode.dev URL, without the requirement of SSH. + + + +**VS Code Server Interface - http:// IP:8680** + +___________________________________________________________________________________________ + +
    + +
    + Webmin System Administration + +

    + +

    Webmin System Administration

    + +To Install Webmin System Administration [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png), ⚠️ run the following in the LXC console. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/webmin.sh)" +``` + +If you prefer to manage all aspects of your Proxmox LXC from a graphical interface instead of the command line interface, Webmin might be right for you. + +Benefits include automatic daily security updates, backup and restore, file manager with editor, web control panel, and preconfigured system monitoring with optional email alerts. + + + +**Webmin Interface - https:// IP:10000 (https)** + +⚙️ **Initial Login** + +**username** + ```yaml + root + ``` + **password** + ```yaml + root + ``` + +⚙️ **To Update Webmin** + +```yaml +Update from the Webmin UI +``` +⚙️ **To Uninstall Webmin** + +Run in the LXC console +```yaml +bash /etc/webmin/uninstall.sh +``` +___________________________________________________________________________________________ + +
    + +
    + Syncthing LXC + +

    + +

    Syncthing LXC

    + +[Syncthing](https://syncthing.net/) is a continuous file synchronization program. It synchronizes files between two or more computers. + +To create a new Proxmox Syncthing LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/syncthing-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +⚙️ For the initial start, run `syncthing --gui-address=0.0.0.0:8384` in the LXC console, then go to the LXC IP:8384 In settings set the LXC IP address under the GUI (also set the GUI Authentication User and GUI Authentication Password) and Connections tab's and save. Reboot the LXC. + +**Syncthing Interface - IP:8384** + +⚙️ **To Update Syncthing** + +```yaml +apt update && apt upgrade -y +``` + +____________________________________________________________________________________________ + +
    + +
    + Daemon Sync Server LXC + +

    + +

    Daemon Sync Server LXC

    + +Sync files from app to server, share photos & videos, back up your data and stay secure inside local network. + +To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    + +**Daemon Sync Server Interface - IP:8084** + +Search: `DAEMON Sync` in your favorite app store + +__________________________________________________________________________________________ + +
    +⬆__________________________________________________________________________________________ + +
    + +
    + Misc. +⬇__________________________________________________________________________________________ + +
    + Vaultwarden LXC + +

    + +

    Vaultwarden LXC

    + +Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream [Bitwarden clients](https://bitwarden.com/download/), perfect for self-hosted deployment where running the official resource-heavy service might not be ideal. + +To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden-v4.sh)" +``` +⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. + +The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. + +Expect 30+ minute install time. +

    ⚡ Build Settings: 2048Mib RAM - 6GB Storage - 2vCPU ⚡

    +

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    + +**Vaultwarden Interface: CTIP:8000** + +⚙️ **Path to Vaultwarden .env file** (to find the `ADMIN_TOKEN`) +```yaml +/opt/vaultwarden/.env +``` + +⚙️ **To Update Vaultwarden (post 2022-05-29 installs only)** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/vaultwarden-update.sh)" +``` +⚙️ **To Update Web-vault (any)** + +Run in the LXC console +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/web-vault-update.sh)" +``` + +____________________________________________________________________________________________ + +
    + +
    + grocy LXC + +

    + +

    grocy LXC

    + +[grocy](https://grocy.info/) is a web-based self-hosted groceries & household management solution for your home. + +To create a new Proxmox grocy LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**grocy Interface: http:// IP** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + admin + ``` + +⚙️ **To Update grocy** + +Run in the LXC console + ```yaml +bash /var/www/html/update.sh +``` +____________________________________________________________________________________________ + +
    + +
    + MagicMirror Server LXC + +

    + +

    MagicMirror Server LXC

    + +[MagicMirror²](https://docs.magicmirror.builders/) is an open source modular smart mirror platform. + +To create a new MagicMirror Server LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 3GB Storage - 1vCPU ⚡

    + +**MagicMirror Interface - IP:8080** + +⚙️ **[Configuration](https://docs.magicmirror.builders/configuration/introduction.html#configuring-your-magicmirror)** +```yaml +/opt/magicmirror/config/config.js +``` +⚙️ **[Update MagicMirror](https://docs.magicmirror.builders/getting-started/upgrade-guide.html#upgrade-guide)** + +Run in the LXC Console +```yaml +cd /opt/magicmirror && git pull && npm install --only=prod --omit=dev +``` +____________________________________________________________________________________________ + +
    + +
    + Whoogle LXC + +

    + +

    Whoogle LXC

    + +Get Google search results, but without any ads, javascript, AMP links, cookies, or IP address tracking. + +To create a new Proxmox Whoogle LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/whoogle-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + +**Whoogle Interface - IP:5000** + +⚙️ **To Update Whoogle** + +Run in the LXC console +```yaml +pip3 install whoogle-search --upgrade +``` +____________________________________________________________________________________________ + +
    + +
    + MotionEye VMS LXC + +

    + +

    MotionEye VMS LXC

    + +To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**MotionEye Interface - IP:8765** + +⚙️ **Initial Login** + +**username** + ```yaml + admin + ``` + **password** + ```yaml + + ``` + +⚙️ **To Update MotionEye** + +Run in the LXC console + ```yaml +pip install motioneye --upgrade +``` +____________________________________________________________________________________________ + +
    +⬆____________________________________________________________________________________________ + +
    From e2b17148938735619d9e25b064b7788f1768ab48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 16:28:23 -0400 Subject: [PATCH 3603/6505] Rename README.md to README_OLD.md --- README.md => README_OLD.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.md => README_OLD.md (100%) diff --git a/README.md b/README_OLD.md similarity index 100% rename from README.md rename to README_OLD.md From 87461ec0669250e6ead68f04098930e380c9fd50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 16:28:51 -0400 Subject: [PATCH 3604/6505] Rename README_NEW.md to README.md --- README_NEW.md => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README_NEW.md => README.md (100%) diff --git a/README_NEW.md b/README.md similarity index 100% rename from README_NEW.md rename to README.md From 9c64633731c8ed486e51fde0d9e3e90b6f9a3d12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 16:42:20 -0400 Subject: [PATCH 3605/6505] Update README.md --- README.md | 64 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index ac97b90b..b0c56e7a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ href="https://ko-fi.com/D1D7EP4GF">
    Proxmox Tools -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Proxmox VE 7 Post Install @@ -143,12 +143,12 @@ It's recommended to answer `y` to all options. ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Home Assistant -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Home Assistant OS VM @@ -385,12 +385,12 @@ After install, reboot Home Assistant and **clear browser cache** then Add HACS i ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Automation -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    ioBroker LXC @@ -609,12 +609,12 @@ npm update -g n8n ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    MQTT -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    MQTT LXC @@ -712,13 +712,13 @@ apt update && apt upgrade -y ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Database -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Mariadb LXC @@ -958,12 +958,12 @@ apt update && apt upgrade -y ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Zigbee - Zwave -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Zigbee2MQTT LXC @@ -1108,12 +1108,12 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-js-u ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Monitoring - Analytics -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Uptime Kuma LXC @@ -1213,12 +1213,12 @@ apt update && apt upgrade -y ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Docker -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Docker LXC @@ -1282,12 +1282,12 @@ update from the CasaOS UI ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    OS -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Debian LXC @@ -1343,12 +1343,12 @@ apt update && apt upgrade -y ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Server - Networklng -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Nginx Proxy Manager LXC @@ -1662,12 +1662,12 @@ Setup is done via VM console. ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Media - Photo -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Plex Media Server LXC @@ -1890,12 +1890,12 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/photoprism ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Ad Blocker -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Pi-hole LXC @@ -1983,12 +1983,12 @@ Update from the Adguard UI __________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Document - Notes -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Paperless-ngx LXC @@ -2108,12 +2108,12 @@ cd /opt/nocodb && npm run upgrade ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    Dashboards -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    Heimdall Dashboard LXC @@ -2206,13 +2206,13 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/dashy-upda __________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    File Working -⬇____________________________________________________________________________________________ +⬇__________________________________________________________________________________________
    File Browser @@ -2377,13 +2377,13 @@ Search: `DAEMON Sync` in your favorite app store __________________________________________________________________________________________
    -⬆__________________________________________________________________________________________ +⬆________________________________________________________________________________________
    Misc. -⬇__________________________________________________________________________________________ +⬇________________________________________________________________________________________
    Vaultwarden LXC @@ -2570,6 +2570,6 @@ pip install motioneye --upgrade ____________________________________________________________________________________________
    -⬆____________________________________________________________________________________________ +⬆__________________________________________________________________________________________
    From d46ce6a1146de477b35facc42b2552b8b9dd8bcf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 17:49:27 -0400 Subject: [PATCH 3606/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0c56e7a..c91421b4 100644 --- a/README.md +++ b/README.md @@ -1347,7 +1347,7 @@ ________________________________________________________________________________
    - Server - Networklng + Server - Networking ⬇__________________________________________________________________________________________
    From 84a4c26b2d27cf68fc97778ef9487bd948f6dc32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 20:19:43 -0400 Subject: [PATCH 3607/6505] Update homeassistant-core-install.sh --- setup/homeassistant-core-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index a8783e1b..3749faa2 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -108,7 +108,7 @@ After=network-online.target Type=simple WorkingDirectory=/root/.homeassistant ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" - +RestartForceExitStatus=100 [Install] WantedBy=multi-user.target EOF From abec4b0fa7dbd3d385ad6fdfa154130b09b8edf0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 20:46:25 -0400 Subject: [PATCH 3608/6505] Update influxdb-install.sh --- setup/influxdb-install.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 3faa99b9..ec96f9d1 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -81,9 +81,21 @@ wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add - &>/dev/ echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list &>/dev/null msg_ok "Set up InfluxDB Repository" +read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt +if [[ $prompt == "2" ]] +then +INFLUX="2" +else +INFLUX="1" +fi + msg_info "Installing InfluxDB" apt-get update &>/dev/null +if [[ $INFLUX == "2" ]]; then +apt-get install -y influxdb2 &>/dev/null +else apt-get install -y influxdb &>/dev/null +fi msg_ok "Installed InfluxDB" read -r -p "Would you like to add Telegraf? " prompt From dfc40d04ab67cf378ac1b9e1a221e1e20499c8e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Oct 2022 20:49:09 -0400 Subject: [PATCH 3609/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c91421b4..807fa149 100644 --- a/README.md +++ b/README.md @@ -920,7 +920,7 @@ ________________________________________________________________________________

    InfluxDB LXC

    -

    Option to Install Telegraf

    +

    Options to Install InfluxDB v1 or v2 and Telegraf

    [InfluxDB](https://www.influxdata.com/) is an open-source time series database developed by the company InfluxData. From 26566524a88f0d183b38f2f4aa221f7ffe366a38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 3 Oct 2022 03:09:08 -0400 Subject: [PATCH 3610/6505] Create hacore2hacore-data.sh --- misc/hacore2hacore-data.sh | 112 +++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 misc/hacore2hacore-data.sh diff --git a/misc/hacore2hacore-data.sh b/misc/hacore2hacore-data.sh new file mode 100644 index 00000000..44c67f6f --- /dev/null +++ b/misc/hacore2hacore-data.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +clear +while true; do + read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" + exit $EXIT +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup() { + [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM + [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null + +TITLE="Home Assistant LXC Data Copy" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) +done < <(pct list | awk 'NR>1') +while [ -z "${CTID_FROM:+x}" ]; do + CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Core LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +while [ -z "${CTID_TO:+x}" ]; do + CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + "\nWhich HA Core LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done +for i in ${!CTID_MENU[@]}; do + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) +done +whiptail --defaultno --title "$TITLE" --yesno \ +"Are you sure you want to copy data between the following LXCs? +$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) +Version: 2022.10.03" 13 50 || exit +info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_TO'..." + pct stop $CTID_TO +fi +msg "Mounting Container Disks..." +DOCKER_PATH=/var/lib/docker/volumes/hass_config/_data +CORE_PATH=/root/.homeassistant +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." +[ -d "${CTID_FROM_PATH}${CORE_PATH}" ] || \ + die "Home Assistant directories in '$CTID_FROM' not found." +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ + die "There was a problem mounting the root disk of LXC '${CTID_TO}'." +[ -d "${CTID_TO_PATH}${CORE_PATH}" ] || \ + die "Home Assistant directories in '$CTID_TO' not found." + +msg "Copying Data..." +RSYNC_OPTIONS=( + --archive + --hard-links + --sparse + --xattrs + --no-inc-recursive + --info=progress2 +) +msg "<======== Docker Data ========>" +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${CORE_PATH} ${CTID_TO_PATH}${CORE_PATH} +echo -en "\e[1A\e[0K\e[1A\e[0K" + +info "Successfully Transferred Data." + +# Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacore2hacore-data.sh)" From 8b6561d6b46f546d25987a55581f97e2fcd66e6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 3 Oct 2022 06:08:14 -0400 Subject: [PATCH 3611/6505] Update homeassistant-core-install.sh --- setup/homeassistant-core-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 3749faa2..783ac845 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -77,6 +77,7 @@ apt-get install -y \ libffi-dev \ libssl-dev \ libjpeg-dev \ + libpcap-dev \ zlib1g-dev \ autoconf \ build-essential \ @@ -95,6 +96,8 @@ python3 -m venv . source bin/activate python3 -m pip install wheel &>/dev/null pip3 install homeassistant &>/dev/null +pip3 install Cython &>/dev/null +pip3 install python-libpcap &>/dev/null pip3 install psycopg2-binary &>/dev/null msg_ok "Installed Home Assistant-Core" From 5d47b17d407174e5c7093e158d20fb9f7d89a602 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 3 Oct 2022 12:29:01 -0400 Subject: [PATCH 3612/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 807fa149..6b0a3868 100644 --- a/README.md +++ b/README.md @@ -2211,7 +2211,7 @@ ________________________________________________________________________________
    - File Working + File - Code ⬇__________________________________________________________________________________________
    File Browser From 8c619bcf7f1b4cba7ca7ef53dc89735fbaeb3cd0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Oct 2022 13:38:23 -0400 Subject: [PATCH 3613/6505] Update zigbee2mqtt-install.sh --- setup/zigbee2mqtt-install.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 944e2981..a7fe1668 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -86,11 +86,22 @@ apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Setting up Zigbee2MQTT Repository" -sudo git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null +git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null msg_ok "Set up Zigbee2MQTT Repository" +read -r -p "Switch to Edge/dev branch? (y/N) " prompt +if [[ $prompt == "y" ]] +then +DEV="y" +else +DEV="n" +fi + msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt &>/dev/null +if [[ $DEV == "y" ]]; then +git checkout dev &>/dev/null +fi npm ci &>/dev/null msg_ok "Installed Zigbee2MQTT" From 65a0024c9b0a228e971539615adc8777146895a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Oct 2022 13:44:36 -0400 Subject: [PATCH 3614/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6b0a3868..4590b39d 100644 --- a/README.md +++ b/README.md @@ -973,6 +973,8 @@ ________________________________________________________________________________

    Zigbee2MQTT LXC

    +

    Option to switch to Edge/dev branch

    + [Zigbee2MQTT](https://www.zigbee2mqtt.io/) is a standalone nodejs application that connects a zigbee network to MQTT To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. From 3309c8465b8a181d2eaee88ac2055eca93c6470e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Oct 2022 19:03:47 -0400 Subject: [PATCH 3615/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4590b39d..8add1099 100644 --- a/README.md +++ b/README.md @@ -1896,7 +1896,7 @@ ________________________________________________________________________________
    - Ad Blocker + Ad Blocker - DNS ⬇__________________________________________________________________________________________
    From 287e1b7047d29cf615a248a7eac7bf78c312aca9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 06:56:41 -0400 Subject: [PATCH 3616/6505] Create umbrel-v4.sh --- ct/umbrel-v4.sh | 250 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 ct/umbrel-v4.sh diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh new file mode 100644 index 00000000..5935bc2e --- /dev/null +++ b/ct/umbrel-v4.sh @@ -0,0 +1,250 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Umbrel" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + __ __ __ __ + / / / /___ ___v4/ /_ ________ / / + / / / / __ `__ \/ __ \/ ___/ _ \/ / +/ /_/ / / / / / / /_/ / / / __/ / +\____/_/ /_/ /_/_.___/_/ \___/_/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; +else + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <> $LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP} ${CL} \n" From bc80b2d9f2047c2658132f2f6e8fccdddf3a4f6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 06:57:39 -0400 Subject: [PATCH 3617/6505] Create umbrel-install.sh --- setup/umbrel-install.sh | 109 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 setup/umbrel-install.sh diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh new file mode 100644 index 00000000..bd6c5a7b --- /dev/null +++ b/setup/umbrel-install.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +msg_info "Installing Umbrel (Patience)" +curl -sL https://umbrel.sh | bash &>/dev/null +msg_ok "Installed Umbrel" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +rm /etc/motd +rm /etc/update-motd.d/10-uname +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 778f76b7efc839b8c9bbe3c46062323b12366607 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 07:04:49 -0400 Subject: [PATCH 3618/6505] Update README.md --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 8add1099..f6b0cdaf 100644 --- a/README.md +++ b/README.md @@ -1255,6 +1255,36 @@ ________________________________________________________________________________
    +
    + Umbrel LXC + +

    + +

    Umbrel LXC

    + +[Umbrel](https://umbrel.com/) is a beautiful personal server OS for self-hosting. + + +To create a new Proxmox Umbrel LXC, run the following in the Proxmox Shell. + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/umbrel-v4.sh)" +``` + +

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    + +**Umbrel Interface - IP** + +⚙️ **To Update Umbrel** + +```yaml +update from the Umbrel UI +``` + +____________________________________________________________________________________________ + +
    +
    CasaOS LXC From 4e57cde91ea91f71c49add913866be0177b254dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 07:08:38 -0400 Subject: [PATCH 3619/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6b0cdaf..e6a79a2f 100644 --- a/README.md +++ b/README.md @@ -1256,7 +1256,7 @@ ________________________________________________________________________________
    - Umbrel LXC + 🔸Umbrel LXC

    From 50c0c77a6d3b9e9665b7965754f644e5edabb8cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 07:09:50 -0400 Subject: [PATCH 3620/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 39972f0c..2ed7b887 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-10-05 + +### Changed + +- **Umbrel LXC** + - NEW Script + ## 2022-09-29 ### Changed From 77e813ab64a75a19a802884460b12f67836144d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 07:11:22 -0400 Subject: [PATCH 3621/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2ed7b887..d8647143 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **Umbrel LXC** +- **Umbrel LXC** (Docker) - NEW Script ## 2022-09-29 From a962aaaab2e7ba39fed8d2297af02fcf19e56280 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 07:29:16 -0400 Subject: [PATCH 3622/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d8647143..0a0eee2b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,8 +7,8 @@ All notable changes to this project will be documented in this file. ### Changed -- **Umbrel LXC** (Docker) - - NEW Script +- **Umbrel LXC** + - NEW Script (Docker) ## 2022-09-29 From 23da0e4655ea2b3b506e2d926c4ea52e5c004f3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 11:24:46 -0400 Subject: [PATCH 3623/6505] Create blocky-v4.sh --- ct/blocky-v4.sh | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 ct/blocky-v4.sh diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh new file mode 100644 index 00000000..dd6e1821 --- /dev/null +++ b/ct/blocky-v4.sh @@ -0,0 +1,243 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Blocky" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat << "EOF" + ____ __ __ + / __ )/ /___v4_____/ /____ __ + / __ / / __ \/ ___/ //_/ / / / + / /_/ / / /_/ / /__/ ,< / /_/ / +/_____/_/\____/\___/_/|_|\__, / + /____/ +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) +if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"1" "Unprivileged" ON \ +"0" "Privileged" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +fi +PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi +fi +CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; +fi +CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; +else + if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; +fi +DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; + if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; +fi +NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; +fi +GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then GATE1="Default" GATE=""; + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi +fi +MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then MAC1="Default" MAC=""; + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" +else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From b658f5fcde0cc7ac99a09589d3e59c8322931531 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 11:25:50 -0400 Subject: [PATCH 3624/6505] Create blocky-install.sh --- setup/blocky-install.sh | 355 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 setup/blocky-install.sh diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh new file mode 100644 index 00000000..33330ff0 --- /dev/null +++ b/setup/blocky-install.sh @@ -0,0 +1,355 @@ +#!/usr/bin/env bash +YW=`echo "\033[33m"` +RD=`echo "\033[01;31m"` +BL=`echo "\033[36m"` +GN=`echo "\033[1;92m"` +CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + 1>&2 echo -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ] + then + 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Blocky" +RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz &>/dev/null +mkdir -p /opt/blocky +tar -xf blocky_0.19_Linux_x86_64.tar.gz -C /opt/blocky +rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz +cat << EOF > /opt/blocky/config.yml +upstream: + # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query + # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) + # this configuration is mandatory, please define at least one external DNS resolver + default: + # example for tcp+udp IPv4 server (https://digitalcourage.de/) + #- 5.9.164.112 + # Cloudflare + - 1.1.1.1 + # example for DNS-over-TLS server (DoT) + #- tcp-tls:fdns1.dismail.de:853 + # example for DNS-over-HTTPS (DoH) + #- https://dns.digitale-gesellschaft.ch/dns-query + # optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range) + # or single ip address / client subnet as CIDR notation + #laptop*: + #- 123.123.123.123 + +# optional: timeout to query the upstream resolver. Default: 2s +#upstreamTimeout: 2s + +# optional: If true, blocky will fail to start unless at least one upstream server per group is reachable. Default: false +#startVerifyUpstream: true + +# optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists. +# accepted: dual, v4, v6 +# default: dual +#connectIPVersion: dual + +# optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma +# example: query "printer.lan" or "my.printer.lan" will return 192.168.178.3 +#customDNS: + #customTTL: 1h + # optional: if true (default), return empty result for unmapped query types (for example TXT, MX or AAAA if only IPv4 address is defined). + # if false, queries with unmapped types will be forwarded to the upstream resolver + #filterUnmappedTypes: true + # optional: replace domain in the query with other domain before resolver lookup in the mapping + #rewrite: + #example.com: printer.lan + #mapping: + #printer.lan: 192.168.178.3,2001:0db8:85a3:08d3:1319:8a2e:0370:7344 + +# optional: definition, which DNS resolver(s) should be used for queries to the domain (with all sub-domains). Multiple resolvers must be separated by a comma +# Example: Query client.fritz.box will ask DNS server 192.168.178.1. This is necessary for local network, to resolve clients by host name +#conditional: + # optional: if false (default), return empty result if after rewrite, the mapped resolver returned an empty answer. If true, the original query will be sent to the upstream resolver + # Example: The query "blog.example.com" will be rewritten to "blog.fritz.box" and also redirected to the resolver at 192.168.178.1. If not found and if was set to , the original query "blog.example.com" will be sent upstream. + # Usage: One usecase when having split DNS for internal and external (internet facing) users, but not all subdomains are listed in the internal domain. + #fallbackUpstream: false + # optional: replace domain in the query with other domain before resolver lookup in the mapping + #rewrite: + #example.com: fritz.box + #mapping: + #fritz.box: 192.168.178.1 + #lan.net: 192.168.178.1,192.168.178.2 + +# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.) +blocking: + # definition of blacklist groups. Can be external link (http/https) or local file + blackLists: + ads: + - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt + - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts + - http://sysctl.org/cameleon/hosts + - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt + - | + # inline definition with YAML literal block scalar style + # hosts format + someadsdomain.com + special: + - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts + # definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked + whiteLists: + ads: + - whitelist.txt + - | + # inline definition with YAML literal block scalar style + # hosts format + whitelistdomain.com + # this is a regex + /^banners?[_.-]/ + # definition: which groups should be applied for which client + clientGroupsBlock: + # default will be used, if no special definition for a client name exists + default: + - ads + - special + # use client name (with wildcard support: * - sequence of any characters, [0-9] - range) + # or single ip address / client subnet as CIDR notation + #laptop*: + #- ads + #192.168.178.1/24: + #- special + # which response will be sent, if query is blocked: + # zeroIp: 0.0.0.0 will be returned (default) + # nxDomain: return NXDOMAIN as return code + # comma separated list of destination IP addresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. + blockType: zeroIp + # optional: TTL for answers to blocked domains + # default: 6h + blockTTL: 1m + # optional: automatically list refresh period (in duration format). Default: 4h. + # Negative value -> deactivate automatically refresh. + # 0 value -> use default + refreshPeriod: 4h + # optional: timeout for list download (each url). Default: 60s. Use large values for big lists or slow internet connections + downloadTimeout: 4m + # optional: Download attempt timeout. Default: 60s + downloadAttempts: 5 + # optional: Time between the download attempts. Default: 1s + downloadCooldown: 10s + # optional: if failOnError, application startup will fail if at least one list can't be downloaded / opened. Default: blocking + #startStrategy: failOnError + +# optional: configuration for caching of DNS responses +caching: + # duration how long a response must be cached (min value). + # If <=0, use response's TTL, if >0 use this value, if TTL is smaller + # Default: 0 + minTime: 5m + # duration how long a response must be cached (max value). + # If <0, do not cache responses + # If 0, use TTL + # If > 0, use this value, if TTL is greater + # Default: 0 + maxTime: 30m + # Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + maxItemsCount: 0 + # if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2-hour time window) + # this improves the response time for often used queries, but significantly increases external traffic + # default: false + prefetching: true + # prefetch track time window (in duration format) + # default: 120 + prefetchExpires: 2h + # name queries threshold for prefetch + # default: 5 + prefetchThreshold: 5 + # Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + #prefetchMaxItemsCount: 0 + +# optional: configuration of client name resolution +clientLookup: + # optional: this DNS resolver will be used to perform reverse DNS lookup (typically local router) + #upstream: 192.168.178.1 + # optional: some routers return multiple names for client (host name and user defined name). Define which single name should be used. + # Example: take second name if present, if not take first name + #singleNameOrder: + #- 2 + #- 1 + # optional: custom mapping of client name to IP addresses. Useful if reverse DNS does not work properly or just to have custom client names. + #clients: + #laptop: + #- 192.168.178.29 +# optional: configuration for prometheus metrics endpoint +prometheus: + # enabled if true + #enable: true + # url path, optional (default '/metrics') + #path: /metrics + +# optional: write query information (question, answer, client, duration etc.) to daily csv file +queryLog: + # optional one of: mysql, postgresql, csv, csv-client. If empty, log to console + #type: mysql + # directory (should be mounted as volume in docker) for csv, db connection string for mysql/postgresql + #target: db_user:db_password@tcp(db_host_or_ip:3306)/db_name?charset=utf8mb4&parseTime=True&loc=Local + #postgresql target: postgres://user:password@db_host_or_ip:5432/db_name + # if > 0, deletes log files which are older than ... days + #logRetentionDays: 7 + # optional: Max attempts to create specific query log writer, default: 3 + #creationAttempts: 1 + # optional: Time between the creation attempts, default: 2s + #creationCooldown: 2s + +# optional: Blocky can synchronize its cache and blocking state between multiple instances through redis. +redis: + # Server address and port + #address: redis:6379 + # Password if necessary + #password: passwd + # Database, default: 0 + #database: 2 + # Connection is required for blocky to start. Default: false + #required: true + # Max connection attempts, default: 3 + #connectionAttempts: 10 + # Time between the connection attempts, default: 1s + #connectionCooldown: 3s + +# optional: DNS listener port(s) and bind ip address(es), default 53 (UDP and TCP). Example: 53, :53, "127.0.0.1:5353,[::1]:5353" +port: 553 +# optional: Port(s) and bind ip address(es) for DoT (DNS-over-TLS) listener. Example: 853, 127.0.0.1:853 +#tlsPort: 853 +# optional: HTTPS listener port(s) and bind ip address(es), default empty = no http listener. If > 0, will be used for prometheus metrics, pprof, REST API, DoH... Example: 443, :443, 127.0.0.1:443 +#httpPort: 4000 +#httpsPort: 443 +# optional: Mininal TLS version that the DoH and DoT server will use +#minTlsServeVersion: 1.3 +# if https port > 0: path to cert and key file for SSL encryption. if not set, self-signed certificate will be generated +#certFile: server.crt +#keyFile: server.key +# optional: use this DNS server to resolve blacklist urls and upstream DNS servers. Useful if no DNS resolver is configured and blocky needs to resolve a host name. Format net:IP:port, net must be udp or tcp +#bootstrapDns: tcp+udp:1.1.1.1 + +filtering: +# optional: drop all queries with following query types. Default: empty + #queryTypes: + #- AAAA + +# optional: if path defined, use this file for query resolution (A, AAAA and rDNS). Default: empty +hostsFile: + # optional: Path to hosts file (e.g. /etc/hosts on Linux) + #filePath: /etc/hosts + # optional: TTL, default: 1h + #hostsTTL: 60m + # optional: Time between hosts file refresh, default: 1h + #refreshPeriod: 30m + # optional: Whether loopback hosts addresses (127.0.0.0/8 and ::1) should be filtered or not, default: false + #filterLoopback: true +# optional: Log level (one from debug, info, warn, error). Default: info +#logLevel: info +# optional: Log format (text or json). Default: text +#logFormat: text +# optional: log timestamps. Default: true +#logTimestamp: true +# optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false +#logPrivacy: false + +# optional: add EDE error codes to dns response +#ede: + # enabled if true, Default: false + #enable: true +EOF +msg_ok "Installed Blocky" + +msg_info "Creating Service" +cat << EOF > /etc/systemd/system/blocky.service +[Unit] +Description=Blocky +After=network.target +[Service] +User=root +WorkingDirectory=/opt/blocky +ExecStart=/opt/blocky/./blocky --config config.yml +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now blocky +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6); + if [[ $PASS != $ ]]; then +msg_info "Customizing Container" +chmod -x /etc/update-motd.d/* +touch ~/.hushlogin +GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" +mkdir -p $(dirname $GETTY_OVERRIDE) +cat << EOF > $GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF +systemctl daemon-reload +systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') +msg_ok "Customized Container" + fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From db23eec00c81710dfc7ede7ae4c2c10120083488 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 11:38:18 -0400 Subject: [PATCH 3625/6505] Update README.md --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index e6a79a2f..c502db0a 100644 --- a/README.md +++ b/README.md @@ -2015,6 +2015,34 @@ Update from the Adguard UI __________________________________________________________________________________________
    + +
    + 🔸Blocky LXC + +

    + +

    Blocky LXC

    + +[Blocky](https://0xerr0r.github.io/blocky/) is a DNS proxy and ad-blocker for the local network written in Go. + +To create a new Proxmox Blocky LXC, run the following in the Proxmox Shell. + +```yaml +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/blocky-v4.sh)" +``` + +

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    + + +⚙️ **To Update Blocky** + +```yaml +Working On +``` +__________________________________________________________________________________________ + +
    + ⬆__________________________________________________________________________________________
    From e4c9b4e30228a6c747e45e6983e2f7787339426f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 11:39:29 -0400 Subject: [PATCH 3626/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0a0eee2b..09ad5b90 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **Umbrel LXC** - NEW Script (Docker) +- **Blocky LXC** + - NEW Script (Adblocker - DNS) ## 2022-09-29 From e0b32a8c0d43266ac0a1bb1913f23b50465bcfad Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 12:06:50 -0400 Subject: [PATCH 3627/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c502db0a..8df1118b 100644 --- a/README.md +++ b/README.md @@ -2019,7 +2019,7 @@ ________________________________________________________________________________
    🔸Blocky LXC -

    +

    Blocky LXC

    From 21cb6734a4f9c2029c0cab22daf574bfe80e91b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 13:24:05 -0400 Subject: [PATCH 3628/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8df1118b..46cd880b 100644 --- a/README.md +++ b/README.md @@ -2034,10 +2034,10 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/blocky-v4.sh

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    -⚙️ **To Update Blocky** +⚙️ **Blocky Config Path** ```yaml -Working On +/opt/blocky/config.yml ``` __________________________________________________________________________________________ From 4da3ea90b173d2ad1791a428153b775d4a77f33a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 13:30:40 -0400 Subject: [PATCH 3629/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 46cd880b..1c87629d 100644 --- a/README.md +++ b/README.md @@ -2023,7 +2023,7 @@ ________________________________________________________________________________

    Blocky LXC

    -[Blocky](https://0xerr0r.github.io/blocky/) is a DNS proxy and ad-blocker for the local network written in Go. +[Blocky](https://0xerr0r.github.io/blocky/) is a DNS proxy and ad-blocker for the local network written in Go. 🚨 For Advanced Users. No UI. To create a new Proxmox Blocky LXC, run the following in the Proxmox Shell. From a025cf15514405cddc506d86c484aa34ce24f7c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 18:19:39 -0400 Subject: [PATCH 3630/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c87629d..b0db91c1 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ ________________________________________________________________________________
    - 🔸PiMox HAOS VM + PiMox HAOS VM

    @@ -262,7 +262,7 @@ ________________________________________________________________________________
    - 🔸Home Assistant Core LXC + Home Assistant Core LXC

    From d90b2fbac3df2cc48e5ff13c17ec3573f671d952 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 20:31:09 -0400 Subject: [PATCH 3631/6505] Update zwave-js-ui-install.sh --- setup/zwave-js-ui-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index 8948e19b..e30bfdd7 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -78,8 +78,9 @@ msg_info "Installing Z-Wave JS UI" mkdir /opt/zwave-js-ui cd /opt/zwave-js-ui mkdir store -curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null -unzip zwave-js-ui-v*.zip zwave-js-ui &>/dev/null +RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null +unzip zwave-js-ui-${RELEASE}.zip zwave-js-ui &>/dev/null msg_ok "Installed Z-Wave JS UI" msg_info "Creating Service" From 89c85f829017ea1d1a237243785b1e4e2851c716 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 20:37:33 -0400 Subject: [PATCH 3632/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 70108b55..53168069 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -35,8 +35,9 @@ clear echo -en "${GN} Updating Z-wave JS UI... " systemctl stop zwave-js-ui.service cd /opt/zwave-js-ui -curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -i - &>/dev/null -unzip -o zwave-js-ui-v*.zip zwave-js-ui &>/dev/null +RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null +unzip zwave-js-ui-${RELEASE}.zip zwave-js-ui &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " From 4ed405ee60400ec6e89baf41e16c7286107c08ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 20:46:41 -0400 Subject: [PATCH 3633/6505] Update zwave-js-ui-install.sh --- setup/zwave-js-ui-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index e30bfdd7..613a10ad 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -80,7 +80,7 @@ cd /opt/zwave-js-ui mkdir store RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}.zip zwave-js-ui &>/dev/null +unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui &>/dev/null msg_ok "Installed Z-Wave JS UI" msg_info "Creating Service" From e74ec49a55801f5897a2c66d68c80d8b53a91cbc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 20:47:49 -0400 Subject: [PATCH 3634/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 53168069..645145d3 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -37,11 +37,11 @@ systemctl stop zwave-js-ui.service cd /opt/zwave-js-ui RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}.zip zwave-js-ui &>/dev/null +unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " -rm zwave-js-ui-v*.zip +rm zwave-js-ui-${RELEASE}-linux.zip systemctl --system daemon-reload systemctl start zwave-js-ui.service echo -e "${CM}${CL} \n" From 5d5809c78c0f402756b375dac3841217e2182a09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 20:48:44 -0400 Subject: [PATCH 3635/6505] Update zwave-js-ui-install.sh --- setup/zwave-js-ui-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index 613a10ad..71025daf 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -118,7 +118,7 @@ msg_ok "Customized Container" fi msg_info "Cleaning up" -rm zwave-js-ui-v*.zip +rm zwave-js-ui-${RELEASE}-linux.zip apt-get autoremove >/dev/null apt-get autoclean >/dev/null msg_ok "Cleaned" From 342ce1229042ebd3cc62bb73095046b73ac2fe69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 20:54:32 -0400 Subject: [PATCH 3636/6505] Update zwave-js-ui-install.sh --- setup/zwave-js-ui-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index 71025daf..fd41363e 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -80,7 +80,7 @@ cd /opt/zwave-js-ui mkdir store RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui &>/dev/null +unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux &>/dev/null msg_ok "Installed Z-Wave JS UI" msg_info "Creating Service" @@ -92,7 +92,7 @@ After=network-online.target [Service] User=root WorkingDirectory=/opt/zwave-js-ui -ExecStart=/opt/zwave-js-ui/zwave-js-ui +ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux [Install] WantedBy=multi-user.target" > $service_path systemctl start zwave-js-ui From a28f172757e0c6f69737b672abb2c2c5659d6b0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 21:01:16 -0400 Subject: [PATCH 3637/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 645145d3..0a1d48c3 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -37,7 +37,7 @@ systemctl stop zwave-js-ui.service cd /opt/zwave-js-ui RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui &>/dev/null +unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " From cf49c462a7dd4c368e8bb6090803db33f36e3bda Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 21:09:02 -0400 Subject: [PATCH 3638/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 0a1d48c3..9276e3ff 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -38,12 +38,25 @@ cd /opt/zwave-js-ui RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux &>/dev/null + +cat << EOF > /etc/systemd/system/zwave-js-ui.service +[Unit] +Description=zwave-js-ui +Wants=network-online.target +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/zwave-js-ui +ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux +[Install] +WantedBy=multi-user.target +EOF echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " -rm zwave-js-ui-${RELEASE}-linux.zip -systemctl --system daemon-reload -systemctl start zwave-js-ui.service +rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui +systemctl daemon-reload +systemctl enable --now zwave-js-ui.service echo -e "${CM}${CL} \n" echo -e "${GN} Finished ${CL}" From 5419f8fa229f1951b5cd0210c7b4698d7cf85f05 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 21:29:02 -0400 Subject: [PATCH 3639/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 9276e3ff..f80c638b 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -34,10 +34,10 @@ clear echo -en "${GN} Updating Z-wave JS UI... " systemctl stop zwave-js-ui.service -cd /opt/zwave-js-ui RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux &>/dev/null +cp -R zwave-js-ui-linux /opt/zwave-js-ui cat << EOF > /etc/systemd/system/zwave-js-ui.service [Unit] @@ -54,7 +54,7 @@ EOF echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " -rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui +rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux systemctl daemon-reload systemctl enable --now zwave-js-ui.service echo -e "${CM}${CL} \n" From bf259b4b9d5350062fd736c9d4a44b6cc34b56b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 21:39:18 -0400 Subject: [PATCH 3640/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index f80c638b..75ed1a9a 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -37,7 +37,7 @@ systemctl stop zwave-js-ui.service RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux &>/dev/null -cp -R zwave-js-ui-linux /opt/zwave-js-ui +\cp -R zwave-js-ui-linux /opt/zwave-js-ui cat << EOF > /etc/systemd/system/zwave-js-ui.service [Unit] @@ -54,7 +54,7 @@ EOF echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " -rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux +rm -rf zwave-js-ui-${RELEASE}-linux.zip store systemctl daemon-reload systemctl enable --now zwave-js-ui.service echo -e "${CM}${CL} \n" From 658954654db14bcdb7911edea1580c128987b6e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 21:42:11 -0400 Subject: [PATCH 3641/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 75ed1a9a..f7ef7e67 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -54,7 +54,7 @@ EOF echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " -rm -rf zwave-js-ui-${RELEASE}-linux.zip store +rm -rf zwave-js-ui-${RELEASE}-linux.zip store zwave-js-ui-linux systemctl daemon-reload systemctl enable --now zwave-js-ui.service echo -e "${CM}${CL} \n" From a2d8aa3cd2421e998d1e8f73f152f69066673ca1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 21:52:35 -0400 Subject: [PATCH 3642/6505] Update zwave-js-ui-update.sh --- misc/zwave-js-ui-update.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index f7ef7e67..514b5664 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -36,7 +36,7 @@ echo -en "${GN} Updating Z-wave JS UI... " systemctl stop zwave-js-ui.service RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux &>/dev/null +unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null \cp -R zwave-js-ui-linux /opt/zwave-js-ui cat << EOF > /etc/systemd/system/zwave-js-ui.service @@ -54,10 +54,9 @@ EOF echo -e "${CM}${CL} \r" echo -en "${GN} Cleanup... " -rm -rf zwave-js-ui-${RELEASE}-linux.zip store zwave-js-ui-linux +rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store systemctl daemon-reload systemctl enable --now zwave-js-ui.service echo -e "${CM}${CL} \n" echo -e "${GN} Finished ${CL}" - From 97579693943877f2312f84856e71b517f963b3dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Oct 2022 21:58:52 -0400 Subject: [PATCH 3643/6505] Update zwave-js-ui-install.sh --- setup/zwave-js-ui-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index fd41363e..15da4574 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -77,10 +77,9 @@ msg_ok "Installed Dependencies" msg_info "Installing Z-Wave JS UI" mkdir /opt/zwave-js-ui cd /opt/zwave-js-ui -mkdir store RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux &>/dev/null +unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null msg_ok "Installed Z-Wave JS UI" msg_info "Creating Service" From 16307254d4318344efdaee18f7d80001afc41684 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Oct 2022 06:46:15 -0400 Subject: [PATCH 3644/6505] Update zwave-js-ui-v4.sh --- ct/zwave-js-ui-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index a56a065c..0890a2f0 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else From a67a9138f69011f96d28c2e668f3a2fd35da5ac7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Oct 2022 07:05:29 -0400 Subject: [PATCH 3645/6505] maintenance (#606) --- ct/adguard-v4.sh | 2 +- ct/blocky-v4.sh | 2 +- ct/casaos-v4.sh | 2 +- ct/daemonsync-v4.sh | 2 +- ct/dashy-v4.sh | 2 +- ct/debian-v4.sh | 2 +- ct/deconz-v4.sh | 2 +- ct/docker-v4.sh | 2 +- ct/emby-v4.sh | 2 +- ct/emqx-v4.sh | 2 +- ct/esphome-v4.sh | 2 +- ct/grafana-v4.sh | 2 +- ct/grocy-v4.sh | 2 +- ct/heimdalldashboard-v4.sh | 2 +- ct/homeassistant-core-v4.sh | 2 +- ct/homeassistant-v4.sh | 2 +- ct/homebridge-v4.sh | 2 +- ct/homepage-v4.sh | 2 +- ct/influxdb-v4.sh | 2 +- ct/iobroker-v4.sh | 2 +- ct/jellyfin-v4.sh | 2 +- ct/keycloak-v4.sh | 2 +- ct/magicmirror-v4.sh | 2 +- ct/mariadb-v4.sh | 2 +- ct/meshcentral-v4.sh | 2 +- ct/motioneye-v4.sh | 2 +- ct/mqtt-v4.sh | 2 +- ct/n8n-v4.sh | 2 +- ct/navidrome-v4.sh | 2 +- ct/nextcloudpi-v4.sh | 2 +- ct/nginx-proxy-manager-v4.sh | 2 +- ct/nocodb-v4.sh | 2 +- ct/node-red-v4.sh | 2 +- ct/omada-v4.sh | 2 +- ct/omv-v4.sh | 2 +- ct/openhab-v4.sh | 2 +- ct/paperless-ngx-v4.sh | 2 +- ct/photoprism-v4.sh | 2 +- ct/pihole-v4.sh | 2 +- ct/plex-v4.sh | 2 +- ct/podman-homeassistant-v4.sh | 2 +- ct/postgresql-v4.sh | 2 +- ct/prometheus-v4.sh | 2 +- ct/syncthing-v4.sh | 2 +- ct/technitiumdns-v4.sh | 2 +- ct/trilium-v4.sh | 2 +- ct/ubuntu-v4.sh | 2 +- ct/umbrel-v4.sh | 2 +- ct/unifi-v4.sh | 2 +- ct/uptimekuma-v4.sh | 2 +- ct/vaultwarden-v4.sh | 2 +- ct/whoogle-v4.sh | 2 +- ct/wikijs-v4.sh | 2 +- ct/wireguard-v4.sh | 2 +- ct/zigbee2mqtt-v4.sh | 2 +- 55 files changed, 55 insertions(+), 55 deletions(-) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index d0f3d6a9..1a8fe6cc 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index dd6e1821..a2e79c5f 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 4458f5c5..73d38b3c 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index a22b3961..1eacbab4 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 4e95a911..8eaaf93d 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index c440df07..3a7f61ae 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 06cc25ad..8225b32d 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index a7357282..a5e4b72a 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index e90725f1..66ddb644 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -154,7 +154,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index 5e7f2885..f43d6508 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index e3174370..d3cc16e3 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 58ce46cf..fc40f4ff 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 09972d1a..21f73bb1 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 4a3ce6e5..de568b9b 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index e8759185..c6b1ba10 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index e17e476e..767a5bb8 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 7b3e7ddf..508bc15d 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index 3b2d63de..4d28a5f2 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 3ab809b5..b931f6b5 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 71bfa4ae..d2d8c6b0 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 76421a3c..bf006c52 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -154,7 +154,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 966edbe8..f8172987 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index cfc67cfc..12fc6bee 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index 2b4820ae..bb162f47 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 325b2b68..20b01de8 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 8069c1b0..ca5ba0e2 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index 7210af65..c9b3cfe6 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index 496e626d..b12a26ac 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 446f1b22..52940afc 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index f39b2a59..feb45833 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index f99bb2e4..68dbbf6e 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 4cdfe3f5..a4eccffb 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 33400099..0c356ee0 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 3a2c7abc..51b2f592 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -154,7 +154,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index 0e84cfb6..322e0373 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index 8e16f806..28aa3454 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index 58e2a0b5..7092b27b 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index 0b1825cf..d7f06465 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 70252cbb..3fced599 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index eeed0cca..b4ca8385 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -154,7 +154,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 2557a709..9bbac839 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -149,7 +149,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index dd29509b..6f89483a 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index e8765aad..db1ce80e 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index 10c55f42..50ef405c 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -147,7 +147,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index d23f72c2..3c1fe3a9 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index c9b9baba..bd121dd9 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index fca16b27..40997d2b 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -154,7 +154,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 5935bc2e..1a7c38b1 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index 2f204933..cdbb1a9d 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index 4c4a2761..fcd9fc30 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index cac70cf7..8e08604e 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 6adc5170..644b5a3f 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -145,7 +145,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index 38c99f5a..7f6965ee 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 98c074ac..c594abc2 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -147,7 +147,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 14057e7a..84b4b06e 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -146,7 +146,7 @@ if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${B else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE"--cancel-button Exit-Script 3>&1 1>&2 2>&3) +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; else From b90315fac1348754ec26a2698088fc70e1ad56ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Oct 2022 12:29:34 -0400 Subject: [PATCH 3646/6505] Update zwave-js-ui-update.sh clean up --- misc/zwave-js-ui-update.sh | 63 ++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 514b5664..7b749018 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -1,10 +1,18 @@ #!/usr/bin/env bash +RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') set -e +YW=`echo "\033[33m"` RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' GN=`echo "\033[1;92m"` CL=`echo "\033[m"` +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" set -o errexit set -o errtrace set -o nounset @@ -21,24 +29,52 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} clear +cat << "EOF" + _____ _______ __ ______ +/__ /_ ______ __ _____ / / ___/ / / / / _/ + / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / + / /_| |/ |/ / /_/ /| |/ / __/ / /_/ /___/ / / /_/ // / +/____/__/|__/\__,_/ |___/\___/ \____//____/ \____/___/ + UPDATE + +EOF + while true; do - read -p "This will update ZWave JS UI. Proceed(y/n)?" yn + read -p "This will update ZWave JS UI to $RELEASE. Proceed(y/n)?" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done -clear +if [ ! -d /opt/zwave-js-ui ]; then msg_error "No Zwave JS UI Install Detected!"; exit; fi -echo -en "${GN} Updating Z-wave JS UI... " +msg_info "Stopping Z-wave JS UI" systemctl stop zwave-js-ui.service -RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +msg_ok "Stopped Z-wave JS UI" + +msg_info "Updating Z-wave JS UI" wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null \cp -R zwave-js-ui-linux /opt/zwave-js-ui +msg_ok "Updated Z-wave JS UI" +msg_info "Updating Z-wave JS UI service file" cat << EOF > /etc/systemd/system/zwave-js-ui.service [Unit] Description=zwave-js-ui @@ -51,12 +87,15 @@ ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux [Install] WantedBy=multi-user.target EOF -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store systemctl daemon-reload -systemctl enable --now zwave-js-ui.service -echo -e "${CM}${CL} \n" +msg_ok "Updated Z-wave JS UI service file" -echo -e "${GN} Finished ${CL}" +msg_info "Cleanup" +rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store +msg_ok "Cleaned" + +msg_info "Starting Z-wave JS UI" +systemctl enable --now zwave-js-ui.service +msg_info "Started Z-wave JS UI" + +msg_ok "Completed Successfully!\n" From d9bb820ae95b6050e1bb948abb943ad9b3579fb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Oct 2022 08:19:45 -0400 Subject: [PATCH 3647/6505] Update haos-vm-v4.sh add "Latest" --- vm/haos-vm-v4.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index c164c30c..36ee3afa 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -5,6 +5,7 @@ NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +LATEST=$(curl -s https://api.github.com/repos/home-assistant/operating-system/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') YW=`echo "\033[33m"` BL=`echo "\033[36m"` HA=`echo "\033[1;34m"` @@ -107,10 +108,11 @@ function default_settings() { echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 4 \ "$STABLE" "Stable" ON \ "$BETA" "Beta" OFF \ "$DEV" "Dev" OFF \ +"$LATEST" "Latest" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi From 2690a6f2489c5c53ad5b5e283e892a15c72eefe5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Oct 2022 08:21:08 -0400 Subject: [PATCH 3648/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0db91c1..a324dc59 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ ________________________________________________________________________________

    Home Assistant OS VM

    -

    Option to create VM using Stable, Beta or Dev Image

    +

    Option to create VM using Stable, Beta, Dev or Latest Image

    The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip, ect...) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. From 256b71703121373df51756e7b2b0379489c8df9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Oct 2022 08:23:21 -0400 Subject: [PATCH 3649/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 09ad5b90..209bfa8f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-10-07 + +### Changed + +- **Home Assistant OS VM** + - Add "Latest" Image + ## 2022-10-05 ### Changed From 48e8952168ee727ee12f7b830880a16fdea6d51e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Oct 2022 15:17:49 -0400 Subject: [PATCH 3650/6505] Update zwave-js-ui-v4.sh add dev/ttyUSB1 --- ct/zwave-js-ui-v4.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 0890a2f0..646773a0 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -240,6 +240,7 @@ lxc.cgroup2.devices.allow: c 188:* rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF From ed758e9d8d725b2899f46ee025757987faac6128 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Oct 2022 15:20:20 -0400 Subject: [PATCH 3651/6505] Update zigbee2mqtt-v4.sh add /dev/ttyUSB1 & /dev/ttyACM1 --- ct/zigbee2mqtt-v4.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 84b4b06e..703b7fde 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -240,7 +240,9 @@ lxc.cgroup2.devices.allow: c 188:* rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF msg_info "Starting LXC Container" pct start $CTID From 606d825c5761ccab3207ee6b13e7bbb6776a968f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Oct 2022 15:26:16 -0400 Subject: [PATCH 3652/6505] Update crowdsec.sh add curl install --- misc/crowdsec.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/crowdsec.sh b/misc/crowdsec.sh index b250e765..e7981523 100644 --- a/misc/crowdsec.sh +++ b/misc/crowdsec.sh @@ -62,6 +62,7 @@ function msg_ok() { msg_info "Setting up ${APP} Repository" apt-get update &>/dev/null +apt-get install -y curl &>/dev/null apt-get install -y gnupg &>/dev/null curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash &>/dev/null msg_ok "Setup ${APP} Repository" From 9adfd34f3a58f5ff4fb127381028811d23bf7db8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Oct 2022 15:42:10 -0400 Subject: [PATCH 3653/6505] Update crowdsec.sh remove sudo command --- misc/crowdsec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/crowdsec.sh b/misc/crowdsec.sh index e7981523..c4cf3d2d 100644 --- a/misc/crowdsec.sh +++ b/misc/crowdsec.sh @@ -64,7 +64,7 @@ msg_info "Setting up ${APP} Repository" apt-get update &>/dev/null apt-get install -y curl &>/dev/null apt-get install -y gnupg &>/dev/null -curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash &>/dev/null +curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | bash &>/dev/null msg_ok "Setup ${APP} Repository" msg_info "Installing ${APP}" From bb3ace78f4ac0cfe66e3e1b9d39c03622470fb38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Oct 2022 07:22:09 -0400 Subject: [PATCH 3654/6505] Update uptimekuma-update.sh --- misc/uptimekuma-update.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index 70e77dcb..bee3f2de 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -53,13 +53,14 @@ msg_ok "Stopped ${APP}" cd /opt/uptime-kuma msg_info "Pulling ${APP} ${LATEST}" -git fetch &>/dev/null -git checkout $LATEST &>/dev/null +git fetch --all &>/dev/null +git checkout $LATEST --force &>/dev/null git pull &>/dev/null msg_ok "Pulled ${APP} ${LATEST}" -msg_info "Updating ${APP} to ${LATEST} (Patience)" -npm ci &>/dev/null +msg_info "Updating ${APP} to ${LATEST}" +npm install --production &>/dev/null +npm run download-dist &>/dev/null msg_ok "Updated ${APP}" msg_info "Starting ${APP}" From 56e1f905ce5174f2f3ac0e1e1a046fa77bfbb12a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Oct 2022 10:24:44 -0400 Subject: [PATCH 3655/6505] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a324dc59..daf45a42 100644 --- a/README.md +++ b/README.md @@ -1256,7 +1256,7 @@ ________________________________________________________________________________
    - 🔸Umbrel LXC + Umbrel LXC

    @@ -2017,7 +2017,7 @@ ________________________________________________________________________________
    - 🔸Blocky LXC + Blocky LXC

    From 6b1e4466988d301ab0ad79e8deee2b74533fc877 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Oct 2022 15:03:36 -0400 Subject: [PATCH 3656/6505] Update photoprism-install.sh up go version --- setup/photoprism-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 38e53a3e..c709699e 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -92,8 +92,8 @@ apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Golang (Patience)" -wget https://golang.org/dl/go1.19.linux-amd64.tar.gz &>/dev/null -tar -xzf go1.19.linux-amd64.tar.gz -C /usr/local &>/dev/null +wget https://golang.org/dl/go1.19.2.linux-amd64.tar.gz &>/dev/null +tar -xzf go1.19.2.linux-amd64.tar.gz -C /usr/local &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null go install github.com/tianon/gosu@latest &>/dev/null go install golang.org/x/tools/cmd/goimports@latest &>/dev/null From b0481d605f621c52c1fc44bd28287c3a323c65a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Oct 2022 13:41:14 -0400 Subject: [PATCH 3657/6505] Update zwave-js-ui-update.sh clean up --- misc/zwave-js-ui-update.sh | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 7b749018..1d669dcf 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -6,29 +6,10 @@ RD=`echo "\033[01;31m"` BL=`echo "\033[36m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." From 21b62610b5bbaa180349059ac5b3bf028654f1cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Oct 2022 09:24:33 -0400 Subject: [PATCH 3658/6505] Update kernel-clean.sh --- misc/kernel-clean.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 212ad8e0..8a337672 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -68,14 +68,11 @@ function edge_kernel() { } function kernel_info() { - latest_kernel=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | tac | head -n 1) if [[ "$MODE" != "PBS" ]]; then echo -e "${YW}PVE Version: ${BL}$(pveversion)\n${CL}" fi if [[ "$current_kernel" == *"pve"* ]]; then - if [[ "$latest_kernel" != *"$current_kernel"* ]]; then - echo -e "${GN}Latest Kernel: $latest_kernel\n${CL}" - fi + echo -e "${YW}Current Kernel: ${BL}$current_kernel\n${CL}" else echo -e "\n${CROSS} ${RD}ERROR: No PVE Kernel Found\n${CL}" exit 1 From 452938f975f895e0b1e6d1e819681e9b74d51ff6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Oct 2022 11:20:54 -0400 Subject: [PATCH 3659/6505] Update photoprism-install.sh --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index c709699e..e75d91b0 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -190,7 +190,7 @@ apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* \ /photoprism \ -/go1.19.linux-amd64.tar.gz \ +/go1.19.2.linux-amd64.tar.gz \ /libtensorflow-linux-avx2-1.15.2.tar.gz \ /libtensorflow-linux-avx-1.15.2.tar.gz \ /libtensorflow-linux-cpu-1.15.2.tar.gz From c97a5d57258fe320d5b2903adbec29d3e892d091 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Oct 2022 11:51:45 -0400 Subject: [PATCH 3660/6505] Update post-pve-install.sh mention to delete browser cache --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 21654ffd..efd4945d 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -107,7 +107,7 @@ then msg_info "Disabling Subscription Nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null -msg_ok "Disabled Subscription Nag" +msg_ok "Disabled Subscription Nag (Delete browser cache)" fi read -r -p "Update Proxmox VE 7 now? " prompt From da5e0dbd40b923928c4ab05b9a35ba323e4c7fa8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Oct 2022 12:36:31 -0400 Subject: [PATCH 3661/6505] Update blocky-install.sh disable systemd-resolved --- setup/blocky-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index 33330ff0..f632bc54 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -73,6 +73,8 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Blocky" +systemctl stop systemd-resolved &>/dev/null +systemctl disable systemd-resolved.service &>/dev/null RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz &>/dev/null mkdir -p /opt/blocky From bfeb4105e91b82027820e7931d515596359ed570 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Oct 2022 09:28:21 -0400 Subject: [PATCH 3662/6505] Update postgresql-install.sh update .conf files for version 15 --- setup/postgresql-install.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 7d68b81d..d97f9e0e 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -84,7 +84,7 @@ msg_info "Installing PostgreSQL" apt-get update &>/dev/null apt-get install -y postgresql &>/dev/null -cat < /etc/postgresql/14/main/pg_hba.conf +cat < /etc/postgresql/15/main/pg_hba.conf # PostgreSQL Client Authentication Configuration File # =================================================== # @@ -186,7 +186,7 @@ host all all ::1/128 scram-sha-256 host all all 0.0.0.0/0 md5 EOF -cat < /etc/postgresql/14/main/postgresql.conf +cat < /etc/postgresql/15/main/postgresql.conf # ----------------------------- # PostgreSQL configuration file # ----------------------------- @@ -228,15 +228,15 @@ cat < /etc/postgresql/14/main/postgresql.conf # The default values of these variables are driven from the -D command-line # option or PGDATA environment variable, represented here as ConfigDir. -data_directory = '/var/lib/postgresql/14/main' # use data in another directory +data_directory = '/var/lib/postgresql/15/main' # use data in another directory # (change requires restart) -hba_file = '/etc/postgresql/14/main/pg_hba.conf' # host-based authentication file +hba_file = '/etc/postgresql/15/main/pg_hba.conf' # host-based authentication file # (change requires restart) -ident_file = '/etc/postgresql/14/main/pg_ident.conf' # ident configuration file +ident_file = '/etc/postgresql/15/main/pg_ident.conf' # ident configuration file # (change requires restart) # If external_pid_file is not explicitly set, no extra PID file is written. -external_pid_file = '/var/run/postgresql/14-main.pid' # write an extra PID file +external_pid_file = '/var/run/postgresql/15-main.pid' # write an extra PID file # (change requires restart) @@ -755,7 +755,7 @@ log_timezone = 'Etc/UTC' # PROCESS TITLE #------------------------------------------------------------------------------ -cluster_name = '14/main' # added to process titles if nonempty +cluster_name = '15/main' # added to process titles if nonempty # (change requires restart) #update_process_title = on @@ -771,7 +771,7 @@ cluster_name = '14/main' # added to process titles if non #track_io_timing = off #track_functions = none # none, pl, all #track_activity_query_size = 1024 # (change requires restart) -stats_temp_directory = '/var/run/postgresql/14-main.pg_stat_tmp' +stats_temp_directory = '/var/run/postgresql/15-main.pg_stat_tmp' # - Monitoring - From a291719a709db4ce56c0dafe42dbc17997fb7f72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Oct 2022 11:03:11 -0400 Subject: [PATCH 3663/6505] Update postgresql-install.sh revert installing version 15 until all commands are known --- setup/postgresql-install.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index d97f9e0e..7d1582f4 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -82,9 +82,9 @@ msg_ok "Setup PostgreSQL Repository" msg_info "Installing PostgreSQL" apt-get update &>/dev/null -apt-get install -y postgresql &>/dev/null +apt-get install -y postgresql-14 &>/dev/null -cat < /etc/postgresql/15/main/pg_hba.conf +cat < /etc/postgresql/14/main/pg_hba.conf # PostgreSQL Client Authentication Configuration File # =================================================== # @@ -186,7 +186,7 @@ host all all ::1/128 scram-sha-256 host all all 0.0.0.0/0 md5 EOF -cat < /etc/postgresql/15/main/postgresql.conf +cat < /etc/postgresql/14/main/postgresql.conf # ----------------------------- # PostgreSQL configuration file # ----------------------------- @@ -228,15 +228,15 @@ cat < /etc/postgresql/15/main/postgresql.conf # The default values of these variables are driven from the -D command-line # option or PGDATA environment variable, represented here as ConfigDir. -data_directory = '/var/lib/postgresql/15/main' # use data in another directory +data_directory = '/var/lib/postgresql/14/main' # use data in another directory # (change requires restart) -hba_file = '/etc/postgresql/15/main/pg_hba.conf' # host-based authentication file +hba_file = '/etc/postgresql/14/main/pg_hba.conf' # host-based authentication file # (change requires restart) -ident_file = '/etc/postgresql/15/main/pg_ident.conf' # ident configuration file +ident_file = '/etc/postgresql/14/main/pg_ident.conf' # ident configuration file # (change requires restart) # If external_pid_file is not explicitly set, no extra PID file is written. -external_pid_file = '/var/run/postgresql/15-main.pid' # write an extra PID file +external_pid_file = '/var/run/postgresql/14-main.pid' # write an extra PID file # (change requires restart) @@ -755,7 +755,7 @@ log_timezone = 'Etc/UTC' # PROCESS TITLE #------------------------------------------------------------------------------ -cluster_name = '15/main' # added to process titles if nonempty +cluster_name = '14/main' # added to process titles if nonempty # (change requires restart) #update_process_title = on @@ -771,7 +771,7 @@ cluster_name = '15/main' # added to process titles if non #track_io_timing = off #track_functions = none # none, pl, all #track_activity_query_size = 1024 # (change requires restart) -stats_temp_directory = '/var/run/postgresql/15-main.pg_stat_tmp' +stats_temp_directory = '/var/run/postgresql/14-main.pg_stat_tmp' # - Monitoring - From 77ae43b07cb76cf6674e8b5b74937aea517a36ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Oct 2022 13:16:57 -0400 Subject: [PATCH 3664/6505] Update postgresql-install.sh update to version 15 --- setup/postgresql-install.sh | 844 ++---------------------------------- 1 file changed, 30 insertions(+), 814 deletions(-) diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 7d1582f4..1468ce34 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -82,163 +82,40 @@ msg_ok "Setup PostgreSQL Repository" msg_info "Installing PostgreSQL" apt-get update &>/dev/null -apt-get install -y postgresql-14 &>/dev/null +apt-get install -y postgresql &>/dev/null -cat < /etc/postgresql/14/main/pg_hba.conf +cat < /etc/postgresql/15/main/pg_hba.conf # PostgreSQL Client Authentication Configuration File -# =================================================== -# -# Refer to the "Client Authentication" section in the PostgreSQL -# documentation for a complete description of this file. A short -# synopsis follows. -# -# This file controls: which hosts are allowed to connect, how clients -# are authenticated, which PostgreSQL user names they can use, which -# databases they can access. Records take one of these forms: -# -# local DATABASE USER METHOD [OPTIONS] -# host DATABASE USER ADDRESS METHOD [OPTIONS] -# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] -# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] -# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] -# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] -# -# (The uppercase items must be replaced by actual values.) -# -# The first field is the connection type: "local" is a Unix-domain -# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, -# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a -# non-SSL TCP/IP socket. Similarly, "hostgssenc" uses a -# GSSAPI-encrypted TCP/IP socket, while "hostnogssenc" uses a -# non-GSSAPI socket. -# -# DATABASE can be "all", "sameuser", "samerole", "replication", a -# database name, or a comma-separated list thereof. The "all" -# keyword does not match "replication". Access to replication -# must be enabled in a separate record (see example below). -# -# USER can be "all", a user name, a group name prefixed with "+", or a -# comma-separated list thereof. In both the DATABASE and USER fields -# you can also write a file name prefixed with "@" to include names -# from a separate file. -# -# ADDRESS specifies the set of hosts the record matches. It can be a -# host name, or it is made up of an IP address and a CIDR mask that is -# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that -# specifies the number of significant bits in the mask. A host name -# that starts with a dot (.) matches a suffix of the actual host name. -# Alternatively, you can write an IP address and netmask in separate -# columns to specify the set of hosts. Instead of a CIDR-address, you -# can write "samehost" to match any of the server's own IP addresses, -# or "samenet" to match any address in any subnet that the server is -# directly connected to. -# -# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", -# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". -# Note that "password" sends passwords in clear text; "md5" or -# "scram-sha-256" are preferred since they send encrypted passwords. -# -# OPTIONS are a set of options for the authentication in the format -# NAME=VALUE. The available options depend on the different -# authentication methods -- refer to the "Client Authentication" -# section in the documentation for a list of which options are -# available for which authentication methods. -# -# Database and user names containing spaces, commas, quotes and other -# special characters must be quoted. Quoting one of the keywords -# "all", "sameuser", "samerole" or "replication" makes the name lose -# its special character, and just match a database or username with -# that name. -# -# This file is read on server startup and when the server receives a -# SIGHUP signal. If you edit the file on a running system, you have to -# SIGHUP the server for the changes to take effect, run "pg_ctl reload", -# or execute "SELECT pg_reload_conf()". -# -# Put your actual configuration here -# ---------------------------------- -# -# If you want to allow non-local connections, you need to add more -# "host" records. In that case you will also need to make PostgreSQL -# listen on a non-local interface via the listen_addresses -# configuration parameter, or via the -i or -h command line switches. - - - - -# DO NOT DISABLE! -# If you change this first entry you will need to make sure that the -# database superuser can access the database using some other method. -# Noninteractive access to all databases is required during automatic -# maintenance (custom daily cronjobs, replication, and similar tasks). -# -# Database administrative login by Unix domain socket -local all postgres trust +local all postgres peer # TYPE DATABASE USER ADDRESS METHOD - # "local" is for Unix domain socket connections only -local all all trust +local all all peer # IPv4 local connections: host all all 127.0.0.1/32 scram-sha-256 host all all 0.0.0.0/24 md5 # IPv6 local connections: host all all ::1/128 scram-sha-256 host all all 0.0.0.0/0 md5 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 scram-sha-256 +host replication all ::1/128 scram-sha-256 EOF -cat < /etc/postgresql/14/main/postgresql.conf +cat < /etc/postgresql/15/main/postgresql.conf # ----------------------------- # PostgreSQL configuration file # ----------------------------- -# -# This file consists of lines of the form: -# -# name = value -# -# (The "=" is optional.) Whitespace may be used. Comments are introduced with -# "#" anywhere on a line. The complete list of parameter names and allowed -# values can be found in the PostgreSQL documentation. -# -# The commented-out settings shown in this file represent the default values. -# Re-commenting a setting is NOT sufficient to revert it to the default value; -# you need to reload the server. -# -# This file is read on server startup and when the server receives a SIGHUP -# signal. If you edit the file on a running system, you have to SIGHUP the -# server for the changes to take effect, run "pg_ctl reload", or execute -# "SELECT pg_reload_conf()". Some parameters, which are marked below, -# require a server shutdown and restart to take effect. -# -# Any parameter can also be given as a command-line option to the server, e.g., -# "postgres -c log_connections=on". Some parameters can be changed at run time -# with the "SET" SQL command. -# -# Memory units: B = bytes Time units: us = microseconds -# kB = kilobytes ms = milliseconds -# MB = megabytes s = seconds -# GB = gigabytes min = minutes -# TB = terabytes h = hours -# d = days - #------------------------------------------------------------------------------ # FILE LOCATIONS #------------------------------------------------------------------------------ -# The default values of these variables are driven from the -D command-line -# option or PGDATA environment variable, represented here as ConfigDir. - -data_directory = '/var/lib/postgresql/14/main' # use data in another directory - # (change requires restart) -hba_file = '/etc/postgresql/14/main/pg_hba.conf' # host-based authentication file - # (change requires restart) -ident_file = '/etc/postgresql/14/main/pg_ident.conf' # ident configuration file - # (change requires restart) - -# If external_pid_file is not explicitly set, no extra PID file is written. -external_pid_file = '/var/run/postgresql/14-main.pid' # write an extra PID file - # (change requires restart) - +data_directory = '/var/lib/postgresql/15/main' +hba_file = '/etc/postgresql/15/main/pg_hba.conf' +ident_file = '/etc/postgresql/15/main/pg_ident.conf' +external_pid_file = '/var/run/postgresql/15-main.pid' #------------------------------------------------------------------------------ # CONNECTIONS AND AUTHENTICATION @@ -246,726 +123,65 @@ external_pid_file = '/var/run/postgresql/14-main.pid' # write # - Connection Settings - -listen_addresses = '*' # what IP address(es) to listen on; - # comma-separated list of addresses; - # defaults to 'localhost'; use '*' for all - # (change requires restart) -port = 5432 # (change requires restart) -max_connections = 100 # (change requires restart) -#superuser_reserved_connections = 3 # (change requires restart) -unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories - # (change requires restart) -#unix_socket_group = '' # (change requires restart) -#unix_socket_permissions = 0777 # begin with 0 to use octal notation - # (change requires restart) -#bonjour = off # advertise server via Bonjour - # (change requires restart) -#bonjour_name = '' # defaults to the computer name - # (change requires restart) - -# - TCP settings - -# see "man tcp" for details - -#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; - # 0 selects the system default -#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; - # 0 selects the system default -#tcp_keepalives_count = 0 # TCP_KEEPCNT; - # 0 selects the system default -#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; - # 0 selects the system default - -# - Authentication - - -#authentication_timeout = 1min # 1s-600s -#password_encryption = md5 # md5 or scram-sha-256 -#db_user_namespace = off - -# GSSAPI using Kerberos -#krb_caseins_users = off +listen_addresses = '*' +port = 5432 +max_connections = 100 +unix_socket_directories = '/var/run/postgresql' # - SSL - -#ssl = on -#ssl_ca_file = '' -#ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' -#ssl_crl_file = '' -#ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' -#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers -#ssl_prefer_server_ciphers = on -#ssl_ecdh_curve = 'prime256v1' -#ssl_min_protocol_version = 'TLSv1.2' -#ssl_max_protocol_version = '' -#ssl_dh_params_file = '' -#ssl_passphrase_command = '' -#ssl_passphrase_command_supports_reload = off - +ssl = on +ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' +ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' #------------------------------------------------------------------------------ # RESOURCE USAGE (except WAL) #------------------------------------------------------------------------------ -# - Memory - - -shared_buffers = 128MB # min 128kB - # (change requires restart) -#huge_pages = try # on, off, or try - # (change requires restart) -#temp_buffers = 8MB # min 800kB -#max_prepared_transactions = 0 # zero disables the feature - # (change requires restart) -# Caution: it is not advisable to set max_prepared_transactions nonzero unless -# you actively intend to use prepared transactions. -#work_mem = 4MB # min 64kB -#hash_mem_multiplier = 1.0 # 1-1000.0 multiplier on hash table work_mem -#maintenance_work_mem = 64MB # min 1MB -#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem -#logical_decoding_work_mem = 64MB # min 64kB -#max_stack_depth = 2MB # min 100kB -#shared_memory_type = mmap # the default is the first option - # supported by the operating system: - # mmap - # sysv - # windows - # (change requires restart) -dynamic_shared_memory_type = posix # the default is the first option - # supported by the operating system: - # posix - # sysv - # windows - # mmap - # (change requires restart) - -# - Disk - - -#temp_file_limit = -1 # limits per-process temp file space - # in kilobytes, or -1 for no limit - -# - Kernel Resources - - -#max_files_per_process = 1000 # min 64 - # (change requires restart) - -# - Cost-Based Vacuum Delay - - -#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) -#vacuum_cost_page_hit = 1 # 0-10000 credits -#vacuum_cost_page_miss = 10 # 0-10000 credits -#vacuum_cost_page_dirty = 20 # 0-10000 credits -#vacuum_cost_limit = 200 # 1-10000 credits - -# - Background Writer - - -#bgwriter_delay = 200ms # 10-10000ms between rounds -#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables -#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round -#bgwriter_flush_after = 512kB # measured in pages, 0 disables - -# - Asynchronous Behavior - - -#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching -#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching -#max_worker_processes = 8 # (change requires restart) -#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers -#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers -#parallel_leader_participation = on -#max_parallel_workers = 8 # maximum number of max_worker_processes that - # can be used in parallel operations -#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate - # (change requires restart) -#backend_flush_after = 0 # measured in pages, 0 disables - +shared_buffers = 128MB +dynamic_shared_memory_type = posix #------------------------------------------------------------------------------ # WRITE-AHEAD LOG #------------------------------------------------------------------------------ -# - Settings - - -#wal_level = replica # minimal, replica, or logical - # (change requires restart) -#fsync = on # flush data to disk for crash safety - # (turning this off can cause - # unrecoverable data corruption) -#synchronous_commit = on # synchronization level; - # off, local, remote_write, remote_apply, or on -#wal_sync_method = fsync # the default is the first option - # supported by the operating system: - # open_datasync - # fdatasync (default on Linux and FreeBSD) - # fsync - # fsync_writethrough - # open_sync -#full_page_writes = on # recover from partial page writes -#wal_compression = off # enable compression of full-page writes -#wal_log_hints = off # also do full page writes of non-critical updates - # (change requires restart) -#wal_init_zero = on # zero-fill new WAL files -#wal_recycle = on # recycle WAL files -#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers - # (change requires restart) -#wal_writer_delay = 200ms # 1-10000 milliseconds -#wal_writer_flush_after = 1MB # measured in pages, 0 disables -#wal_skip_threshold = 2MB - -#commit_delay = 0 # range 0-100000, in microseconds -#commit_siblings = 5 # range 1-1000 - -# - Checkpoints - - -#checkpoint_timeout = 5min # range 30s-1d max_wal_size = 1GB min_wal_size = 80MB -#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 -#checkpoint_flush_after = 256kB # measured in pages, 0 disables -#checkpoint_warning = 30s # 0 disables - -# - Archiving - - -#archive_mode = off # enables archiving; off, on, or always - # (change requires restart) -#archive_command = '' # command to use to archive a logfile segment - # placeholders: %p = path of file to archive - # %f = file name only - # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' -#archive_timeout = 0 # force a logfile segment switch after this - # number of seconds; 0 disables - -# - Archive Recovery - - -# These are only used in recovery mode. - -#restore_command = '' # command to use to restore an archived logfile segment - # placeholders: %p = path of file to restore - # %f = file name only - # e.g. 'cp /mnt/server/archivedir/%f %p' - # (change requires restart) -#archive_cleanup_command = '' # command to execute at every restartpoint -#recovery_end_command = '' # command to execute at completion of recovery - -# - Recovery Target - - -# Set these only when performing a targeted recovery. - -#recovery_target = '' # 'immediate' to end recovery as soon as a - # consistent state is reached - # (change requires restart) -#recovery_target_name = '' # the named restore point to which recovery will proceed - # (change requires restart) -#recovery_target_time = '' # the time stamp up to which recovery will proceed - # (change requires restart) -#recovery_target_xid = '' # the transaction ID up to which recovery will proceed - # (change requires restart) -#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed - # (change requires restart) -#recovery_target_inclusive = on # Specifies whether to stop: - # just after the specified recovery target (on) - # just before the recovery target (off) - # (change requires restart) -#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID - # (change requires restart) -#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' - # (change requires restart) - - -#------------------------------------------------------------------------------ -# REPLICATION -#------------------------------------------------------------------------------ - -# - Sending Servers - - -# Set these on the master and on any standby that will send replication data. - -#max_wal_senders = 10 # max number of walsender processes - # (change requires restart) -#wal_keep_size = 0 # in megabytes; 0 disables -#max_slot_wal_keep_size = -1 # in megabytes; -1 disables -#wal_sender_timeout = 60s # in milliseconds; 0 disables - -#max_replication_slots = 10 # max number of replication slots - # (change requires restart) -#track_commit_timestamp = off # collect timestamp of transaction commit - # (change requires restart) - -# - Master Server - - -# These settings are ignored on a standby server. - -#synchronous_standby_names = '' # standby servers that provide sync rep - # method to choose sync standbys, number of sync standbys, - # and comma-separated list of application_name - # from standby(s); '*' = all -#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed - -# - Standby Servers - - -# These settings are ignored on a master server. - -#primary_conninfo = '' # connection string to sending server -#primary_slot_name = '' # replication slot on sending server -#promote_trigger_file = '' # file name whose presence ends recovery -#hot_standby = on # "off" disallows queries during recovery - # (change requires restart) -#max_standby_archive_delay = 30s # max delay before canceling queries - # when reading WAL from archive; - # -1 allows indefinite delay -#max_standby_streaming_delay = 30s # max delay before canceling queries - # when reading streaming WAL; - # -1 allows indefinite delay -#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name - # is not set -#wal_receiver_status_interval = 10s # send replies at least this often - # 0 disables -#hot_standby_feedback = off # send info from standby to prevent - # query conflicts -#wal_receiver_timeout = 60s # time that receiver waits for - # communication from master - # in milliseconds; 0 disables -#wal_retrieve_retry_interval = 5s # time to wait before retrying to - # retrieve WAL after a failed attempt -#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery - -# - Subscribers - - -# These settings are ignored on a publisher. - -#max_logical_replication_workers = 4 # taken from max_worker_processes - # (change requires restart) -#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers - - -#------------------------------------------------------------------------------ -# QUERY TUNING -#------------------------------------------------------------------------------ - -# - Planner Method Configuration - - -#enable_bitmapscan = on -#enable_hashagg = on -#enable_hashjoin = on -#enable_indexscan = on -#enable_indexonlyscan = on -#enable_material = on -#enable_mergejoin = on -#enable_nestloop = on -#enable_parallel_append = on -#enable_seqscan = on -#enable_sort = on -#enable_incremental_sort = on -#enable_tidscan = on -#enable_partitionwise_join = off -#enable_partitionwise_aggregate = off -#enable_parallel_hash = on -#enable_partition_pruning = on - -# - Planner Cost Constants - - -#seq_page_cost = 1.0 # measured on an arbitrary scale -#random_page_cost = 4.0 # same scale as above -#cpu_tuple_cost = 0.01 # same scale as above -#cpu_index_tuple_cost = 0.005 # same scale as above -#cpu_operator_cost = 0.0025 # same scale as above -#parallel_tuple_cost = 0.1 # same scale as above -#parallel_setup_cost = 1000.0 # same scale as above - -#jit_above_cost = 100000 # perform JIT compilation if available - # and query more expensive than this; - # -1 disables -#jit_inline_above_cost = 500000 # inline small functions if query is - # more expensive than this; -1 disables -#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if - # query is more expensive than this; - # -1 disables - -#min_parallel_table_scan_size = 8MB -#min_parallel_index_scan_size = 512kB -#effective_cache_size = 4GB - -# - Genetic Query Optimizer - - -#geqo = on -#geqo_threshold = 12 -#geqo_effort = 5 # range 1-10 -#geqo_pool_size = 0 # selects default based on effort -#geqo_generations = 0 # selects default based on effort -#geqo_selection_bias = 2.0 # range 1.5-2.0 -#geqo_seed = 0.0 # range 0.0-1.0 - -# - Other Planner Options - - -#default_statistics_target = 100 # range 1-10000 -#constraint_exclusion = partition # on, off, or partition -#cursor_tuple_fraction = 0.1 # range 0.0-1.0 -#from_collapse_limit = 8 -#join_collapse_limit = 8 # 1 disables collapsing of explicit - # JOIN clauses -#force_parallel_mode = off -#jit = on # allow JIT compilation -#plan_cache_mode = auto # auto, force_generic_plan or - # force_custom_plan - #------------------------------------------------------------------------------ # REPORTING AND LOGGING #------------------------------------------------------------------------------ -# - Where to Log - - -#log_destination = 'stderr' # Valid values are combinations of - # stderr, csvlog, syslog, and eventlog, - # depending on platform. csvlog - # requires logging_collector to be on. - -# This is used when logging to stderr: -#logging_collector = off # Enable capturing of stderr and csvlog - # into log files. Required to be on for - # csvlogs. - # (change requires restart) - -# These are only used if logging_collector is on: -#log_directory = 'log' # directory where log files are written, - # can be absolute or relative to PGDATA -#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, - # can include strftime() escapes -#log_file_mode = 0600 # creation mode for log files, - # begin with 0 to use octal notation -#log_truncate_on_rotation = off # If on, an existing log file with the - # same name as the new log file will be - # truncated rather than appended to. - # But such truncation only occurs on - # time-driven rotation, not on restarts - # or size-driven rotation. Default is - # off, meaning append to existing files - # in all cases. -#log_rotation_age = 1d # Automatic rotation of logfiles will - # happen after that time. 0 disables. -#log_rotation_size = 10MB # Automatic rotation of logfiles will - # happen after that much log output. - # 0 disables. - -# These are relevant when logging to syslog: -#syslog_facility = 'LOCAL0' -#syslog_ident = 'postgres' -#syslog_sequence_numbers = on -#syslog_split_messages = on - -# This is only relevant when logging to eventlog (win32): -# (change requires restart) -#event_source = 'PostgreSQL' - -# - When to Log - - -#log_min_messages = warning # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic - -#log_min_error_statement = error # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic (effectively off) - -#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements - # and their durations, > 0 logs only - # statements running at least this number - # of milliseconds - -#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements - # and their durations, > 0 logs only a sample of - # statements running at least this number - # of milliseconds; - # sample fraction is determined by log_statement_sample_rate - -#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding - # log_min_duration_sample to be logged; - # 1.0 logs all such statements, 0.0 never logs - - -#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements - # are logged regardless of their duration; 1.0 logs all - # statements from all transactions, 0.0 never logs - # - What to Log - -#debug_print_parse = off -#debug_print_rewritten = off -#debug_print_plan = off -#debug_pretty_print = on -#log_checkpoints = off -#log_connections = off -#log_disconnections = off -#log_duration = off -#log_error_verbosity = default # terse, default, or verbose messages -#log_hostname = off -log_line_prefix = '%m [%p] %q%u@%d ' # special values: - # %a = application name - # %u = user name - # %d = database name - # %r = remote host and port - # %h = remote host - # %b = backend type - # %p = process ID - # %t = timestamp without milliseconds - # %m = timestamp with milliseconds - # %n = timestamp with milliseconds (as a Unix epoch) - # %i = command tag - # %e = SQL state - # %c = session ID - # %l = session line number - # %s = session start timestamp - # %v = virtual transaction ID - # %x = transaction ID (0 if none) - # %q = stop here in non-session - # processes - # %% = '%' - # e.g. '<%u%%%d> ' -#log_lock_waits = off # log lock waits >= deadlock_timeout -#log_parameter_max_length = -1 # when logging statements, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -#log_parameter_max_length_on_error = 0 # when logging an error, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -#log_statement = 'none' # none, ddl, mod, all -#log_replication_commands = off -#log_temp_files = -1 # log temporary files equal or larger - # than the specified size in kilobytes; - # -1 disables, 0 logs all temp files +log_line_prefix = '%m [%p] %q%u@%d ' log_timezone = 'Etc/UTC' #------------------------------------------------------------------------------ # PROCESS TITLE #------------------------------------------------------------------------------ -cluster_name = '14/main' # added to process titles if nonempty - # (change requires restart) -#update_process_title = on - - -#------------------------------------------------------------------------------ -# STATISTICS -#------------------------------------------------------------------------------ - -# - Query and Index Statistics Collector - - -#track_activities = on -#track_counts = on -#track_io_timing = off -#track_functions = none # none, pl, all -#track_activity_query_size = 1024 # (change requires restart) -stats_temp_directory = '/var/run/postgresql/14-main.pg_stat_tmp' - - -# - Monitoring - - -#log_parser_stats = off -#log_planner_stats = off -#log_executor_stats = off -#log_statement_stats = off - - -#------------------------------------------------------------------------------ -# AUTOVACUUM -#------------------------------------------------------------------------------ - -#autovacuum = on # Enable autovacuum subprocess? 'on' - # requires track_counts to also be on. -#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and - # their durations, > 0 logs only - # actions running at least this number - # of milliseconds. -#autovacuum_max_workers = 3 # max number of autovacuum subprocesses - # (change requires restart) -#autovacuum_naptime = 1min # time between autovacuum runs -#autovacuum_vacuum_threshold = 50 # min number of row updates before - # vacuum -#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts - # before vacuum; -1 disables insert - # vacuums -#autovacuum_analyze_threshold = 50 # min number of row updates before - # analyze -#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum -#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table - # size before insert vacuum -#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze -#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum - # (change requires restart) -#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age - # before forced vacuum - # (change requires restart) -#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for - # autovacuum, in milliseconds; - # -1 means use vacuum_cost_delay -#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for - # autovacuum, -1 means use - # vacuum_cost_limit - +cluster_name = '15/main' #------------------------------------------------------------------------------ # CLIENT CONNECTION DEFAULTS #------------------------------------------------------------------------------ -# - Statement Behavior - - -#client_min_messages = notice # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # log - # notice - # warning - # error -#row_security = on -#default_tablespace = '' # a tablespace name, '' uses the default -#temp_tablespaces = '' # a list of tablespace names, '' uses - # only default tablespace -#default_table_access_method = 'heap' -#check_function_bodies = on -#default_transaction_isolation = 'read committed' -#default_transaction_read_only = off -#default_transaction_deferrable = off -#session_replication_role = 'origin' -#statement_timeout = 0 # in milliseconds, 0 is disabled -#lock_timeout = 0 # in milliseconds, 0 is disabled -#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled -#vacuum_freeze_min_age = 50000000 -#vacuum_freeze_table_age = 150000000 -#vacuum_multixact_freeze_min_age = 5000000 -#vacuum_multixact_freeze_table_age = 150000000 -#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples - # before index cleanup, 0 always performs - # index cleanup -#bytea_output = 'hex' # hex, escape -#xmlbinary = 'base64' -#xmloption = 'content' -#gin_fuzzy_search_limit = 0 -#gin_pending_list_limit = 4MB - # - Locale and Formatting - datestyle = 'iso, mdy' -#intervalstyle = 'postgres' timezone = 'Etc/UTC' -#timezone_abbreviations = 'Default' # Select the set of available time zone - # abbreviations. Currently, there are - # Default - # Australia (historical usage) - # India - # You can create your own file in - # share/timezonesets/. -#extra_float_digits = 1 # min -15, max 3; any value >0 actually - # selects precise output mode -#client_encoding = sql_ascii # actually, defaults to database - # encoding - -# These settings are initialized by initdb, but they can be changed. -lc_messages = 'C' # locale for system error message - # strings -lc_monetary = 'C' # locale for monetary formatting -lc_numeric = 'C' # locale for number formatting -lc_time = 'C' # locale for time formatting - -# default configuration for text search +lc_messages = 'C' +lc_monetary = 'C' +lc_numeric = 'C' +lc_time = 'C' default_text_search_config = 'pg_catalog.english' -# - Shared Library Preloading - - -#shared_preload_libraries = '' # (change requires restart) -#local_preload_libraries = '' -#session_preload_libraries = '' -#jit_provider = 'llvmjit' # JIT library to use - -# - Other Defaults - - -#extension_destdir = '' # prepend path when loading extensions - # and shared objects (added by Debian) - - -#------------------------------------------------------------------------------ -# LOCK MANAGEMENT -#------------------------------------------------------------------------------ - -#deadlock_timeout = 1s -#max_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_relation = -2 # negative values mean - # (max_pred_locks_per_transaction - # / -max_pred_locks_per_relation) - 1 -#max_pred_locks_per_page = 2 # min 0 - - -#------------------------------------------------------------------------------ -# VERSION AND PLATFORM COMPATIBILITY -#------------------------------------------------------------------------------ - -# - Previous PostgreSQL Versions - - -#array_nulls = on -#backslash_quote = safe_encoding # on, off, or safe_encoding -#escape_string_warning = on -#lo_compat_privileges = off -#operator_precedence_warning = off -#quote_all_identifiers = off -#standard_conforming_strings = on -#synchronize_seqscans = on - -# - Other Platforms and Clients - - -#transform_null_equals = off - - -#------------------------------------------------------------------------------ -# ERROR HANDLING -#------------------------------------------------------------------------------ - -#exit_on_error = off # terminate session on any error? -#restart_after_crash = on # reinitialize after backend crash? -#data_sync_retry = off # retry or panic on failure to fsync - # data? - # (change requires restart) - - #------------------------------------------------------------------------------ # CONFIG FILE INCLUDES #------------------------------------------------------------------------------ -# These options allow settings to be loaded from files other than the -# default postgresql.conf. Note that these are directives, not variable -# assignments, so they can usefully be given more than once. - -include_dir = 'conf.d' # include files ending in '.conf' from - # a directory, e.g., 'conf.d' -#include_if_exists = '...' # include file only if it exists -#include = '...' # include file - - -#------------------------------------------------------------------------------ -# CUSTOMIZED OPTIONS -#------------------------------------------------------------------------------ - -# Add settings for extensions here +include_dir = 'conf.d' EOF sudo systemctl restart postgresql From 40724f6434c25bbf0af79f0ed467c6c3a773e907 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Oct 2022 15:18:27 -0400 Subject: [PATCH 3665/6505] Update pull_request_template.md --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ef2d9b8f..ad7ef3fc 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ -# Pull Request Template +# All Pull Requests should be made to the `pull-requests` branch ## Description From e6d2cbc8122c34306129ed6b665c779ccd8eaf30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Oct 2022 16:23:11 -0400 Subject: [PATCH 3666/6505] Update plex-install.sh hardware acceleration - check for privileged/unprivileged --- setup/plex-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 90e21271..3d8a1cb0 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -74,6 +74,7 @@ apt-get install -y sudo &>/dev/null apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then msg_info "Setting Up Hardware Acceleration" apt-get -y install \ va-driver-all \ @@ -84,6 +85,7 @@ apt-get -y install \ /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" +fi msg_info "Setting Up Plex Media Server Repository" wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null From 6d0ba55c8393e04be2cdf79c1ae26ad7d43d52d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Oct 2022 16:40:04 -0400 Subject: [PATCH 3667/6505] Update emby-install.sh hardware acceleration - check for privileged/unprivileged --- setup/emby-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 28c762ab..39919c87 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -73,6 +73,7 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then msg_info "Setting Up Hardware Acceleration" apt-get -y install \ va-driver-all \ @@ -83,6 +84,7 @@ apt-get -y install \ /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" +fi LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) From 28ac44926ceb0a39f5431fce0cdc91a06ea62ffc Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Oct 2022 16:41:03 -0400 Subject: [PATCH 3668/6505] Update jellyfin-install.sh hardware acceleration - check for privileged/unprivileged --- setup/jellyfin-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index f7f3576e..c8d0e63d 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -75,6 +75,7 @@ apt-get install -y apt-transport-https &>/dev/null apt-get install -y software-properties-common &>/dev/null msg_ok "Installed Dependencies" +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then msg_info "Setting Up Hardware Acceleration" apt-get -y install \ va-driver-all \ @@ -85,6 +86,7 @@ apt-get -y install \ /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" +fi msg_info "Setting Up Jellyfin Repository" sudo add-apt-repository universe -y &>/dev/null From 0beaa20971301c255a7a4ba2661afcb1af49c6c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Oct 2022 05:52:33 -0400 Subject: [PATCH 3669/6505] Maintenance (#662) --- README.md | 2 +- ct/vaultwarden-v4.sh | 2 +- setup/adguard-install.sh | 4 ++++ setup/blocky-install.sh | 4 ++++ setup/casaos-install.sh | 4 ++++ setup/daemonsync-install.sh | 4 ++++ setup/dashy-install.sh | 4 ++++ setup/debian-install.sh | 4 ++++ setup/deconz-install.sh | 4 ++++ setup/docker-install.sh | 4 ++++ setup/emby-install.sh | 4 ++++ setup/emqx-install.sh | 4 ++++ setup/esphome-install.sh | 4 ++++ setup/grafana-install.sh | 4 ++++ setup/grocy-install.sh | 4 ++++ setup/heimdalldashboard-install.sh | 4 ++++ setup/homeassistant-core-install.sh | 4 ++++ setup/homeassistant-install.sh | 4 ++++ setup/homebridge-install.sh | 4 ++++ setup/homepage-install.sh | 4 ++++ setup/influxdb-install.sh | 4 ++++ setup/iobroker-install.sh | 4 ++++ setup/jellyfin-install.sh | 4 ++++ setup/keycloak-install.sh | 4 ++++ setup/magicmirror-install.sh | 4 ++++ setup/mariadb-install.sh | 4 ++++ setup/meshcentral-install.sh | 4 ++++ setup/motioneye-install.sh | 4 ++++ setup/mqtt-install.sh | 4 ++++ setup/n8n-install.sh | 4 ++++ setup/navidrome-install.sh | 4 ++++ setup/nextcloudpi-install.sh | 4 ++++ setup/nginx-proxy-manager-install.sh | 4 ++++ setup/nocodb-install.sh | 4 ++++ setup/node-red-install.sh | 4 ++++ setup/omada-install.sh | 4 ++++ setup/omv-install.sh | 4 ++++ setup/openhab-install.sh | 4 ++++ setup/paperless-ngx-install.sh | 4 ++++ setup/photoprism-install.sh | 4 ++++ setup/pihole-install.sh | 4 ++++ setup/plex-install.sh | 4 ++++ setup/podman-homeassistant-install.sh | 4 ++++ setup/postgresql-install.sh | 4 ++++ setup/prometheus-install.sh | 4 ++++ setup/syncthing-install.sh | 4 ++++ setup/technitiumdns-install.sh | 4 ++++ setup/trilium-install.sh | 4 ++++ setup/ubuntu-install.sh | 4 ++++ setup/umbrel-install.sh | 4 ++++ setup/unifi-install.sh | 4 ++++ setup/uptimekuma-install.sh | 4 ++++ setup/vaultwarden-install.sh | 4 ++++ setup/whoogle-install.sh | 4 ++++ setup/wikijs-install.sh | 4 ++++ setup/wireguard-install.sh | 4 ++++ setup/zigbee2mqtt-install.sh | 4 ++++ setup/zwave-js-ui-install.sh | 4 ++++ 58 files changed, 226 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index daf45a42..35db7d24 100644 --- a/README.md +++ b/README.md @@ -2464,7 +2464,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden- The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. Expect 30+ minute install time. -

    ⚡ Build Settings: 2048Mib RAM - 6GB Storage - 2vCPU ⚡

    +

    ⚡ Build Settings: 3072Mib RAM - 6GB Storage - 2vCPU ⚡

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    **Vaultwarden Interface: CTIP:8000** diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index 8e08604e..1e403439 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -3,7 +3,7 @@ echo -e "Loading..." APP="Vaultwarden" var_disk="6" var_cpu="2" -var_ram="2048" +var_ram="3072" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 080e2cff..8b34a502 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index f632bc54..e66fbd27 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index 8ee90a70..4e582f0e 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index e3bd458d..bd9e8b13 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 7485178e..0029e8a7 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/debian-install.sh b/setup/debian-install.sh index bc9f39cb..db18f9b2 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index bc6f0c0c..ee6d8795 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/docker-install.sh b/setup/docker-install.sh index c4234aed..e70dd50c 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 39919c87..42373035 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index dc3e224b..6303f7b7 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 8d0aab4e..625ea8b2 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 6503d3f1..4b270cf6 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 32ca846b..6342b1a2 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index d4b509f7..02c3a90a 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 783ac845..6602f5ad 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 35617ab0..0d0d8952 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 033a52b5..4fad6168 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 8adb85c9..31ff0c7a 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index ec96f9d1..e2a082fe 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index ab65830e..2cbe7067 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index c8d0e63d..82acbffa 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index 0c86f4fa..9397fa7a 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index 64dce914..4d3cd89f 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 15acb821..53b8c955 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index eb2e219f..6c6b0149 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index ff8afa47..08d80adc 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index db9331d9..f39c7fcc 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 322064c0..21fd5f49 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index 6a50e363..b04cdda9 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index 5d8d1555..c38cef27 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 4861405e..37cd3c92 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 57083bb8..37e2fb97 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index f9d90389..6e0843f2 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 6c2dde53..9a3705aa 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/omv-install.sh b/setup/omv-install.sh index 0f553a62..073653af 100644 --- a/setup/omv-install.sh +++ b/setup/omv-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 1dec802f..65a811d4 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index c1c2640b..db0a2ff6 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index e75d91b0..a2027d0e 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -60,9 +60,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 3d6a0e4d..572f70b5 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -60,9 +60,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 3d8a1cb0..a1ea5f33 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 9a885507..e192c86e 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 1468ce34..e4cd0a20 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 378a8ab5..f9b176d0 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh index a9d942bc..ced965d4 100644 --- a/setup/syncthing-install.sh +++ b/setup/syncthing-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 907c7e2f..887ad747 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index 8b259725..9478d2f4 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -58,9 +58,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 4abacf6d..4ee2e1ea 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index bd6c5a7b..5c8138f6 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 49ebf87d..2c0a32c4 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -60,9 +60,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index f8663bfc..7777f05a 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 2f9e90c7..d3afc43f 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index 0a653770..ef22a09a 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index db684221..0b54cd7f 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index f9af0201..ed1aab09 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e OPTIONS_PATH='/options.conf' cat >$OPTIONS_PATH <<'EOF' diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index a7fe1668..538e109f 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index 15da4574..c0137e07 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -59,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null From 79c8e8d5d042757f5b948931f9cf611859537082 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Oct 2022 07:15:58 -0400 Subject: [PATCH 3670/6505] Update photoprism-v4.sh increase ram for building binary --- ct/photoprism-v4.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index d7f06465..b0ffd76c 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -3,7 +3,7 @@ echo -e "Loading..." APP="PhotoPrism" var_disk="8" var_cpu="2" -var_ram="2048" +var_ram="3072" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') @@ -239,6 +239,9 @@ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2 pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 2048 +msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:2342${CL} \n" From fd7c812ffe254e073423420dd9c14e936b39438d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Oct 2022 07:21:45 -0400 Subject: [PATCH 3671/6505] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 35db7d24..00df7159 100644 --- a/README.md +++ b/README.md @@ -1896,8 +1896,9 @@ To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. ``` bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v4.sh)" ``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    +The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. +

    ⚡ Build Settings: 3GB RAM - 8GB Storage - 2vCPU ⚡

    +

    ⚡ Normal Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    **PhotoPrism Interface - IP:2342** From bb469a2b3e1bb39a2f73df9730dc764cf8c09d71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Oct 2022 11:26:07 -0400 Subject: [PATCH 3672/6505] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 00df7159..69332856 100644 --- a/README.md +++ b/README.md @@ -2468,11 +2468,13 @@ Expect 30+ minute install time.

    ⚡ Build Settings: 3072Mib RAM - 6GB Storage - 2vCPU ⚡

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    -**Vaultwarden Interface: CTIP:8000** +**Vaultwarden Interface: IP:8000** -⚙️ **Path to Vaultwarden .env file** (to find the `ADMIN_TOKEN`) +**Vaultwarden Admin Interface: IP:8000/admin** + +⚙️ **Vaultwarden .env file** (to find the `ADMIN_TOKEN`) ```yaml -/opt/vaultwarden/.env +cat /opt/vaultwarden/.env ``` ⚙️ **To Update Vaultwarden (post 2022-05-29 installs only)** From 94a29252301d583cb24606097a6b37c338a90580 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Oct 2022 10:50:26 -0400 Subject: [PATCH 3673/6505] Update node-red-install.sh fix install --- setup/node-red-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 6e0843f2..2193abd3 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -78,9 +78,8 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Node-Red" -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/nul -sudo systemctl enable nodered.service &>/dev/null -sudo systemctl start nodered.service &>/dev/null +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi --node18 --no-init &>/dev/nul +systemctl enable --now nodered.service &>/dev/null msg_ok "Installed Node-Red" PASS=$(grep -w "root" /etc/shadow | cut -b6); From 7b92d8ddb0f0647c180206f30df2a2ee53d78eda Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Oct 2022 11:27:07 -0400 Subject: [PATCH 3674/6505] Update node-red-install.sh --- setup/node-red-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 2193abd3..a9b742da 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -75,6 +75,8 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +apt-get install -y build-essential &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Node-Red" From f99b7649b54bc7439e4c3853a48d178173a1767a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Oct 2022 12:14:12 -0400 Subject: [PATCH 3675/6505] Update node-red-install.sh --- setup/node-red-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index a9b742da..babd4099 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -80,7 +80,7 @@ apt-get install -y build-essential &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Node-Red" -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi --node18 --no-init &>/dev/nul +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi --node18 --no-init &>/dev/null systemctl enable --now nodered.service &>/dev/null msg_ok "Installed Node-Red" From bfb6c36b330478ae654eba31e36481b17d69480a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Oct 2022 14:45:07 -0400 Subject: [PATCH 3676/6505] Update node-red-install.sh --- setup/node-red-install.sh | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index babd4099..69c9a1b4 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -11,22 +11,6 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} function msg_info() { local msg="$1" @@ -59,13 +43,9 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" -set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e msg_info "Updating Container OS" apt-get update &>/dev/null @@ -75,12 +55,10 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -apt-get install -y build-essential &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Node-Red" -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi --node18 --no-init &>/dev/null +bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi --no-init &>/dev/null systemctl enable --now nodered.service &>/dev/null msg_ok "Installed Node-Red" From 283c328917e4ca80841b654e4df99aa1b436b690 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Oct 2022 15:35:17 -0400 Subject: [PATCH 3677/6505] Update node-red-install.sh move away from node-red github install script --- setup/node-red-install.sh | 54 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 69c9a1b4..ea9a4998 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -11,6 +11,22 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function msg_info() { local msg="$1" @@ -43,9 +59,13 @@ done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" +set +e +alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e msg_info "Updating Container OS" apt-get update &>/dev/null @@ -57,11 +77,41 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + msg_info "Installing Node-Red" -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi --no-init &>/dev/null -systemctl enable --now nodered.service &>/dev/null +npm install -g --unsafe-perm node-red &>/dev/null msg_ok "Installed Node-Red" +msg_info "Creating Service" +service_path="/etc/systemd/system/nodered.service" +echo "[Unit] +Description=Node-RED +After=syslog.target network.target + +[Service] +ExecStart=/usr/bin/node-red --max-old-space-size=128 -v +Restart=on-failure +KillSignal=SIGINT + +SyslogIdentifier=node-red +StandardOutput=syslog + +WorkingDirectory=/root/ +User=root +Group=root + +[Install] +WantedBy=multi-user.target" > $service_path +systemctl enable --now nodered.service &>/dev/null +msg_ok "Created Service" + PASS=$(grep -w "root" /etc/shadow | cut -b6); if [[ $PASS != $ ]]; then msg_info "Customizing Container" From fc807bed6a5f8a2805d3cc20860d51b5ebbb0fae Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Oct 2022 15:36:16 -0400 Subject: [PATCH 3678/6505] Update node-red-themes.sh --- misc/node-red-themes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh index 5f8738b1..7795f8cb 100644 --- a/misc/node-red-themes.sh +++ b/misc/node-red-themes.sh @@ -132,6 +132,6 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Restarting Node-Red... " echo -e "${CM}${CL} \r" -node-red-restart +systemctl restart nodered echo -en "${GN} Finished... ${CL} \n" exit From 1af219c48b0a7d6de0ec89011899dc65bd3fd20c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Oct 2022 15:37:44 -0400 Subject: [PATCH 3679/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69332856..0944a4a3 100644 --- a/README.md +++ b/README.md @@ -560,7 +560,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red-v4. Run in the LXC console ```yaml -node-red-restart +systemctl restart nodered ``` ⚙️ **To Update Node-Red:** From e0c380b54b332823744f98cecf91342ca0fe5fda Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Oct 2022 05:30:11 -0400 Subject: [PATCH 3680/6505] Update emqx-install.sh 5.0.9 --- setup/emqx-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 6303f7b7..6a613a80 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -78,7 +78,7 @@ msg_ok "Installed Dependencies" msg_info "Installing EMQX" curl -s https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh | bash &>/dev/null -sudo apt-get install -y emqx=5.0.8 &>/dev/null +sudo apt-get install -y emqx=5.0.9 &>/dev/null systemctl start emqx msg_ok "Installed EMQX" From 35ea3211078016a347083109ab883a4038832aad Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Oct 2022 17:24:31 -0400 Subject: [PATCH 3681/6505] Create emby-update.sh --- misc/emby-update.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 misc/emby-update.sh diff --git a/misc/emby-update.sh b/misc/emby-update.sh new file mode 100644 index 00000000..fd947d03 --- /dev/null +++ b/misc/emby-update.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Emby" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +while true; do + read -p "This will Update ${APP} to ${LATEST}. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +cat << "EOF" + ______ __ + / ____/___ ___ / /_ __ __ + / __/ / __ __ \/ __ \/ / / / + / /___/ / / / / / /_/ / /_/ / +/_____/_/ /_/ /_/_.___/\__, / + UPDATE /____/ +EOF +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Updating ${APP}" +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null +systemctl stop emby-server +dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null +systemctl start emby-server +rm emby-server-deb_${LATEST}_amd64.deb +msg_ok "Updated ${APP}" From 02f32c59535e51ae74e2dd5fa70976850c74be83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Oct 2022 17:35:59 -0400 Subject: [PATCH 3682/6505] Update emby-update.sh --- misc/emby-update.sh | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/misc/emby-update.sh b/misc/emby-update.sh index fd947d03..86a67a9e 100644 --- a/misc/emby-update.sh +++ b/misc/emby-update.sh @@ -11,23 +11,6 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" APP="Emby" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - while true; do read -p "This will Update ${APP} to ${LATEST}. Proceed(y/n)?" yn case $yn in From 54a273f579888b2d8a0f7ef0be516dddc7175321 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Oct 2022 17:47:32 -0400 Subject: [PATCH 3683/6505] Update emby-install.sh 4.7.8.0 --- setup/emby-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 42373035..59cb2d64 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -93,8 +93,8 @@ fi LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Installing Emby" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.7.6.0/emby-server-deb_4.7.6.0_amd64.deb &>/dev/null -dpkg -i emby-server-deb_4.7.6.0_amd64.deb &>/dev/null +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.7.6.0/emby-server-deb_4.7.8.0_amd64.deb &>/dev/null +dpkg -i emby-server-deb_4.7.8.0_amd64.deb &>/dev/null msg_ok "Installed Emby" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -117,4 +117,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null +rm emby-server-deb_4.7.8.0_amd64.deb msg_ok "Cleaned" From beab1ba98de380f49bb6e0d04b4d794e18aeff93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Oct 2022 17:56:37 -0400 Subject: [PATCH 3684/6505] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0944a4a3..1f89bf5c 100644 --- a/README.md +++ b/README.md @@ -1750,7 +1750,11 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" **Emby Media Server Interface - IP:8096** -⚙️ **Emby Media Server Utilizes Automatic Updates** +⚙️ **To Update Emby** + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/emby-update.sh)" +``` ____________________________________________________________________________________________ @@ -2208,7 +2212,7 @@ ________________________________________________________________________________
    Homepage LXC -

    +

    Homepage LXC

    From d57251ac1668dbae726f63b326286ec293e0ae23 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Oct 2022 17:59:24 -0400 Subject: [PATCH 3685/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f89bf5c..b3b0da86 100644 --- a/README.md +++ b/README.md @@ -1752,7 +1752,7 @@ bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" ⚙️ **To Update Emby** -``` +```yaml bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/emby-update.sh)" ``` From 4e82e8ae613a8e407de438e504cf952068f0d97d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Oct 2022 03:26:17 -0400 Subject: [PATCH 3686/6505] Update create_lxc.sh --- ct/create_lxc.sh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index f82768a5..48a7d513 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -5,7 +5,6 @@ RD=`echo "\033[01;31m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" set -o errexit @@ -34,14 +33,6 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Validating Storage" -VALID=$(pvesm status -content rootdir | awk 'NR>1') -if [ -z "$VALID" ]; then msg_error "Unable to detect a valid storage location."; exit 1; fi; function select_storage() { local CLASS=$1 @@ -66,7 +57,10 @@ function select_storage() { MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content $CONTENT | awk 'NR>1') - if [ $((${#MENU[@]}/3)) -eq 1 ]; then + if [ $((${#MENU[@]}/3)) -eq 0 ]; then + echo -e "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then printf ${MENU[0]} else local STORAGE From 3c89ba2b56f5fdaac3a5da007fcc31ccd1fdfcd2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Oct 2022 03:43:46 -0400 Subject: [PATCH 3687/6505] Update create_lxc.sh --- ct/create_lxc.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 48a7d513..f82768a5 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -5,6 +5,7 @@ RD=`echo "\033[01;31m"` GN=`echo "\033[1;92m"` CL=`echo "\033[m"` CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" set -o errexit @@ -33,6 +34,14 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Validating Storage" +VALID=$(pvesm status -content rootdir | awk 'NR>1') +if [ -z "$VALID" ]; then msg_error "Unable to detect a valid storage location."; exit 1; fi; function select_storage() { local CLASS=$1 @@ -57,10 +66,7 @@ function select_storage() { MENU+=( "$TAG" "$ITEM" "OFF" ) done < <(pvesm status -content $CONTENT | awk 'NR>1') - if [ $((${#MENU[@]}/3)) -eq 0 ]; then - echo -e "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then + if [ $((${#MENU[@]}/3)) -eq 1 ]; then printf ${MENU[0]} else local STORAGE From f1b76b3949af6ec16ac3f625e50f4b7410faf5b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Oct 2022 04:43:15 -0400 Subject: [PATCH 3688/6505] Update create_lxc.sh update validate storage check --- ct/create_lxc.sh | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index f82768a5..1ac3ae44 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -8,22 +8,6 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} function msg_info() { local msg="$1" @@ -40,8 +24,27 @@ function msg_error() { } msg_info "Validating Storage" -VALID=$(pvesm status -content rootdir | awk 'NR>1') -if [ -z "$VALID" ]; then msg_error "Unable to detect a valid storage location."; exit 1; fi; +VALIDCT=$(pvesm status -content rootdir | awk 'NR>1') +if [ -z "$VALIDCT" ]; then msg_error "Unable to detect a valid Container Storage location."; exit 1; fi; +VALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1') +if [ -z "$VALIDTMP" ]; then msg_error "Unable to detect a valid Template Storage location."; exit 1; fi; + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} function select_storage() { local CLASS=$1 From 4044d501b057d35f5851ad032a9bb21d41e4c537 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Oct 2022 05:31:49 -0400 Subject: [PATCH 3689/6505] Update emqx-install.sh --- setup/emqx-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 6a613a80..543648a8 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -78,7 +78,7 @@ msg_ok "Installed Dependencies" msg_info "Installing EMQX" curl -s https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh | bash &>/dev/null -sudo apt-get install -y emqx=5.0.9 &>/dev/null +sudo apt-get install -y emqx >/dev/null systemctl start emqx msg_ok "Installed EMQX" From 672b97dc523b47947f747db6a65d8656ed6c19e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Oct 2022 10:51:39 -0400 Subject: [PATCH 3690/6505] Create core-restore-from-backup.sh --- misc/core-restore-from-backup.sh | 75 ++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 misc/core-restore-from-backup.sh diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh new file mode 100644 index 00000000..fe5b1738 --- /dev/null +++ b/misc/core-restore-from-backup.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +clear +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="Home Assistant Core" +while true; do + read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +cat << "EOF" + __ __ ___ _ __ __ ______ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / ____/___ ________ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / __ \/ ___/ _ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /___/ /_/ / / / __/ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____/\____/_/ \___/ + RESTORE FROM BACKUP +EOF +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +DIR=/root/.restore +if [ -d "$DIR" ]; +then + msg_ok "Restore Directory Exists." +else + mkdir -p /root/.restore + msg_ok "Created Restore Directory." +fi + +cd /root/.homeassistant/backups/ +PS3="Please enter your choice: " +files="$(ls -A .)" +select filename in ${files}; do msg_ok "You selected ${filename}"; break; done +msg_info "Stopping Home Assistant" +sudo service homeassistant stop +msg_ok "Stopped Home Assistant" + +msg_info "Restoring Home Assistant using ${filename}" +tar xvf ${filename} -C /root/.restore &>/dev/null +cd /root/.restore +tar -xvf homeassistant.tar.gz &>/dev/null +if ! command -v rsync >/dev/null 2>&1; then + apt-get install -y rsync &>/dev/null +fi +rsync -a /root/.restore/data/ /root/.homeassistant + +rm -rf /root/.restore/* +msg_ok "Restore Complete" +msg_ok "Starting Home Assistant" +sudo service homeassistant start From aa18221a45f9b7bfc8e73318897ff889f15034d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Oct 2022 12:07:03 -0400 Subject: [PATCH 3691/6505] Update core-restore-from-backup.sh --- misc/core-restore-from-backup.sh | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh index fe5b1738..40b40425 100644 --- a/misc/core-restore-from-backup.sh +++ b/misc/core-restore-from-backup.sh @@ -37,39 +37,33 @@ function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } - function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } - -DIR=/root/.restore +DIR=/root/.homeassistant/restore if [ -d "$DIR" ]; then msg_ok "Restore Directory Exists." else - mkdir -p /root/.restore - msg_ok "Created Restore Directory." + mkdir -p /root/.homeassistant/restore + msg_ok "Created Restore Directory." fi - +if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then echo -e "${RD}No backups found!${CL} \n"; exit 1; fi cd /root/.homeassistant/backups/ PS3="Please enter your choice: " files="$(ls -A .)" -select filename in ${files}; do msg_ok "You selected ${filename}"; break; done +select filename in ${files}; do msg_ok "You selected ${BL}${filename}${CL}"; break; done msg_info "Stopping Home Assistant" sudo service homeassistant stop msg_ok "Stopped Home Assistant" - msg_info "Restoring Home Assistant using ${filename}" -tar xvf ${filename} -C /root/.restore &>/dev/null -cd /root/.restore +tar xvf ${filename} -C /root/.homeassistant/restore &>/dev/null +cd /root/.homeassistant/restore tar -xvf homeassistant.tar.gz &>/dev/null -if ! command -v rsync >/dev/null 2>&1; then - apt-get install -y rsync &>/dev/null -fi -rsync -a /root/.restore/data/ /root/.homeassistant - -rm -rf /root/.restore/* +if ! command -v rsync >/dev/null 2>&1; then apt-get install -y rsync &>/dev/null; fi +rsync -a /root/.homeassistant/restore/data/ /root/.homeassistant +rm -rf /root/.homeassistant/restore/* msg_ok "Restore Complete" -msg_ok "Starting Home Assistant" +msg_ok "Starting Home Assistant \n" sudo service homeassistant start From b029f3ef3ad99c1fd077740edeb430043a303b52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Oct 2022 12:21:53 -0400 Subject: [PATCH 3692/6505] Update core-restore-from-backup.sh --- misc/core-restore-from-backup.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh index 40b40425..ece2d0bf 100644 --- a/misc/core-restore-from-backup.sh +++ b/misc/core-restore-from-backup.sh @@ -10,6 +10,7 @@ CL=`echo "\033[m"` BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" APP="Home Assistant Core" while true; do read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn @@ -41,6 +42,10 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} DIR=/root/.homeassistant/restore if [ -d "$DIR" ]; then @@ -49,7 +54,7 @@ else mkdir -p /root/.homeassistant/restore msg_ok "Created Restore Directory." fi -if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then echo -e "${RD}No backups found!${CL} \n"; exit 1; fi +if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then msg_error "No backups found! \n"; exit 1; fi cd /root/.homeassistant/backups/ PS3="Please enter your choice: " files="$(ls -A .)" From 76a9d00a640258d8259d605f5420cd64015a75f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Oct 2022 12:33:50 -0400 Subject: [PATCH 3693/6505] Create container-restore-from-backup.sh --- misc/container-restore-from-backup.sh | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 misc/container-restore-from-backup.sh diff --git a/misc/container-restore-from-backup.sh b/misc/container-restore-from-backup.sh new file mode 100644 index 00000000..d85478d5 --- /dev/null +++ b/misc/container-restore-from-backup.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +clear +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +APP="Home Assistant Container" +while true; do + read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +clear +function header_info { +cat << "EOF" + __ __ ___ _ __ __ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ + RESTORE FROM BACKUP +EOF +} + +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} +if [ -z "$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)" ]; then msg_error "No backups found! \n"; exit 1; fi +DIR=/var/lib/docker/volumes/hass_config/_data/restore +if [ -d "$DIR" ]; +then + msg_ok "Restore Directory Exists." +else + mkdir -p /var/lib/docker/volumes/hass_config/_data/restore + msg_ok "Created Restore Directory." +fi +cd /var/lib/docker/volumes/hass_config/_data/backups/ +PS3="Please enter your choice: " +files="$(ls -A .)" +select filename in ${files}; do msg_ok "You selected ${BL}${filename}${CL}"; break; done +msg_info "Stopping Home Assistant" +docker stop homeassistant +msg_ok "Stopped Home Assistant" +msg_info "Restoring Home Assistant using ${filename}" +tar xvf ${filename} -C /var/lib/docker/volumes/hass_config/_data/restore &>/dev/null +cd /var/lib/docker/volumes/hass_config/_data/restore +tar -xvf homeassistant.tar.gz &>/dev/null +if ! command -v rsync >/dev/null 2>&1; then apt-get install -y rsync &>/dev/null; fi +rsync -a /var/lib/docker/volumes/hass_config/_data/restore/data/ /var/lib/docker/volumes/hass_config/_data +rm -rf /var/lib/docker/volumes/hass_config/_data/restore/* +msg_ok "Restore Complete" +msg_ok "Starting Home Assistant \n" +docker start homeassistant From ca08e20253af1858b027ee577f62609fb05aeef3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Oct 2022 12:34:51 -0400 Subject: [PATCH 3694/6505] Update core-restore-from-backup.sh --- misc/core-restore-from-backup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh index ece2d0bf..e603cc6d 100644 --- a/misc/core-restore-from-backup.sh +++ b/misc/core-restore-from-backup.sh @@ -46,6 +46,7 @@ function msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then msg_error "No backups found! \n"; exit 1; fi DIR=/root/.homeassistant/restore if [ -d "$DIR" ]; then @@ -54,7 +55,6 @@ else mkdir -p /root/.homeassistant/restore msg_ok "Created Restore Directory." fi -if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then msg_error "No backups found! \n"; exit 1; fi cd /root/.homeassistant/backups/ PS3="Please enter your choice: " files="$(ls -A .)" From ba31094dbc0f18cec8a5d92fc297f2ca6ba96001 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Oct 2022 15:05:30 -0400 Subject: [PATCH 3695/6505] Update emby-install.sh --- setup/emby-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 59cb2d64..a673c2c9 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -93,8 +93,8 @@ fi LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Installing Emby" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.7.6.0/emby-server-deb_4.7.8.0_amd64.deb &>/dev/null -dpkg -i emby-server-deb_4.7.8.0_amd64.deb &>/dev/null +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null +dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null msg_ok "Installed Emby" PASS=$(grep -w "root" /etc/shadow | cut -b6); @@ -117,5 +117,5 @@ msg_ok "Customized Container" msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm emby-server-deb_4.7.8.0_amd64.deb +rm emby-server-deb_${LATEST}_amd64.deb msg_ok "Cleaned" From b3939463589c2ff261505428989badc1dfdc7ddd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Oct 2022 07:07:54 -0400 Subject: [PATCH 3696/6505] Update container-restore-from-backup.sh --- misc/container-restore-from-backup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/container-restore-from-backup.sh b/misc/container-restore-from-backup.sh index d85478d5..a70370ea 100644 --- a/misc/container-restore-from-backup.sh +++ b/misc/container-restore-from-backup.sh @@ -60,7 +60,7 @@ PS3="Please enter your choice: " files="$(ls -A .)" select filename in ${files}; do msg_ok "You selected ${BL}${filename}${CL}"; break; done msg_info "Stopping Home Assistant" -docker stop homeassistant +docker stop homeassistant &>/dev/null msg_ok "Stopped Home Assistant" msg_info "Restoring Home Assistant using ${filename}" tar xvf ${filename} -C /var/lib/docker/volumes/hass_config/_data/restore &>/dev/null From 54abd811797c86a130b22f028f3aa8a7e058b83f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Oct 2022 07:50:39 -0400 Subject: [PATCH 3697/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 209bfa8f..c94872fd 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-10-27 + +### Changed + +- **Container & Core Restore from Backup** + - NEW Scripts https://github.com/tteck/Proxmox/discussions/674 + ## 2022-10-07 ### Changed From 4e025f460b3af9ed5a15a7240359be858bf93a2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Oct 2022 14:53:01 -0400 Subject: [PATCH 3698/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3b0da86..d5c4254d 100644 --- a/README.md +++ b/README.md @@ -916,7 +916,7 @@ ________________________________________________________________________________
    InfluxDB LXC -

    +

    InfluxDB LXC

    From e36b17de130d07bcd5003fbc29b85bf17b6a7e58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Oct 2022 15:20:49 -0400 Subject: [PATCH 3699/6505] Update uptimekuma-update.sh add directory check --- misc/uptimekuma-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index bee3f2de..acccf4b2 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -45,6 +45,7 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +if [ ! -d "/opt/uptime-kuma" ]; then echo -e "No Uptime Kuma Directory Found."; exit; fi msg_info "Stopping ${APP}" sudo systemctl stop uptime-kuma &>/dev/null From 56228b67ee569da88dd7253bb18850bf87186ab8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Oct 2022 20:09:41 -0400 Subject: [PATCH 3700/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5c4254d..c6cff4fe 100644 --- a/README.md +++ b/README.md @@ -916,7 +916,7 @@ ________________________________________________________________________________
    InfluxDB LXC -

    +

    InfluxDB LXC

    From 32cbe55b374c5bdf8bf1f48cd4d588dc7181a72d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Oct 2022 10:47:31 -0400 Subject: [PATCH 3701/6505] Update emqx-install.sh add systemctl enable --now emqx --- setup/emqx-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 543648a8..601fd5d2 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -79,7 +79,7 @@ msg_ok "Installed Dependencies" msg_info "Installing EMQX" curl -s https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh | bash &>/dev/null sudo apt-get install -y emqx >/dev/null -systemctl start emqx +systemctl enable --now emqx msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6); From e7ec3d02757960b61702a91026468481ce79ee36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Oct 2022 20:08:41 -0400 Subject: [PATCH 3702/6505] Maintenance (#680) --- ct/create_lxc.sh | 64 +++++---- ct/debian-v4.sh | 336 +++++++++++++++++++++++++---------------------- 2 files changed, 218 insertions(+), 182 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 1ac3ae44..43aea538 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -1,33 +1,39 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Validating Storage" VALIDCT=$(pvesm status -content rootdir | awk 'NR>1') -if [ -z "$VALIDCT" ]; then msg_error "Unable to detect a valid Container Storage location."; exit 1; fi; +if [ -z "$VALIDCT" ]; then + msg_error "Unable to detect a valid Container Storage location." + exit 1 +fi VALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1') -if [ -z "$VALIDTMP" ]; then msg_error "Unable to detect a valid Template Storage location."; exit 1; fi; +if [ -z "$VALIDTMP" ]; then + msg_error "Unable to detect a valid Template Storage location." + exit 1 +fi set -o errexit set -o errtrace @@ -51,9 +57,15 @@ function select_storage() { local CONTENT local CONTENT_LABEL case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; + container) + CONTENT='rootdir' + CONTENT_LABEL='Container' + ;; + template) + CONTENT='vztmpl' + CONTENT_LABEL='Container template' + ;; + *) false || die "Invalid storage class." ;; esac local -a MENU @@ -66,18 +78,18 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') - if [ $((${#MENU[@]}/3)) -eq 1 ]; then + if [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -118,9 +130,9 @@ fi DEFAULT_PCT_OPTIONS=( -arch $(dpkg --print-architecture)) - -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) msg_info "Creating LXC Container" pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 3a7f61ae..443d577a 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ____ __________ _______ _ __ / __ \/ ____/ __ )/ _/ | / | / / / / / / __/ / __ |/ // /| | / |/ / @@ -52,168 +52,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID From 8e331fcbff94c660cc906bfa95704290e76a196f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Oct 2022 21:04:45 -0400 Subject: [PATCH 3703/6505] Maintenance (#681) * Maintenance --- ct/adguard-v4.sh | 336 +++++++++++++----------- ct/blocky-v4.sh | 336 +++++++++++++----------- ct/casaos-v4.sh | 338 ++++++++++++------------ ct/daemonsync-v4.sh | 336 +++++++++++++----------- ct/dashy-v4.sh | 336 +++++++++++++----------- ct/deconz-v4.sh | 340 ++++++++++++------------ ct/docker-v4.sh | 338 ++++++++++++------------ ct/emby-v4.sh | 354 +++++++++++++------------ ct/emqx-v4.sh | 336 +++++++++++++----------- ct/esphome-v4.sh | 336 +++++++++++++----------- ct/grafana-v4.sh | 336 +++++++++++++----------- ct/grocy-v4.sh | 336 +++++++++++++----------- ct/heimdalldashboard-v4.sh | 336 +++++++++++++----------- ct/homeassistant-core-v4.sh | 340 ++++++++++++------------ ct/homeassistant-v4.sh | 340 ++++++++++++------------ ct/homebridge-v4.sh | 336 +++++++++++++----------- ct/homepage-v4.sh | 336 +++++++++++++----------- ct/influxdb-v4.sh | 336 +++++++++++++----------- ct/iobroker-v4.sh | 336 +++++++++++++----------- ct/jellyfin-v4.sh | 356 ++++++++++++++------------ ct/keycloak-v4.sh | 336 +++++++++++++----------- ct/magicmirror-v4.sh | 336 +++++++++++++----------- ct/mariadb-v4.sh | 336 +++++++++++++----------- ct/meshcentral-v4.sh | 336 +++++++++++++----------- ct/motioneye-v4.sh | 336 +++++++++++++----------- ct/n8n-v4.sh | 336 +++++++++++++----------- ct/navidrome-v4.sh | 336 +++++++++++++----------- ct/nextcloudpi-v4.sh | 336 +++++++++++++----------- ct/nginx-proxy-manager-v4.sh | 336 +++++++++++++----------- ct/nocodb-v4.sh | 336 +++++++++++++----------- ct/node-red-v4.sh | 336 +++++++++++++----------- ct/omada-v4.sh | 354 +++++++++++++------------ ct/omv-v4.sh | 338 ++++++++++++------------ ct/openhab-v4.sh | 336 +++++++++++++----------- ct/paperless-ngx-v4.sh | 336 +++++++++++++----------- ct/photoprism-v4.sh | 336 +++++++++++++----------- ct/pihole-v4.sh | 336 +++++++++++++----------- ct/plex-v4.sh | 356 ++++++++++++++------------ ct/podman-homeassistant-v4.sh | 338 ++++++++++++------------ ct/postgresql-v4.sh | 336 +++++++++++++----------- ct/prometheus-v4.sh | 336 +++++++++++++----------- ct/syncthing-v4.sh | 336 +++++++++++++----------- ct/technitiumdns-v4.sh | 336 +++++++++++++----------- ct/trilium-v4.sh | 336 +++++++++++++----------- ct/ubuntu-v4.sh | 354 +++++++++++++------------ ct/umbrel-v4.sh | 338 ++++++++++++------------ ct/unifi-v4.sh | 336 +++++++++++++----------- ct/uptimekuma-v4.sh | 336 +++++++++++++----------- ct/vaultwarden-v4.sh | 336 +++++++++++++----------- ct/whoogle-v4.sh | 336 +++++++++++++----------- ct/wikijs-v4.sh | 336 +++++++++++++----------- ct/wireguard-v4.sh | 336 +++++++++++++----------- ct/zigbee2mqtt-v4.sh | 338 ++++++++++++------------ ct/zwave-js-ui-v4.sh | 338 ++++++++++++------------ misc/add-tailscale-lxc.sh | 14 +- misc/code-server.sh | 42 +-- misc/container-restore-from-backup.sh | 35 +-- misc/core-restore-from-backup.sh | 35 +-- misc/crowdsec.sh | 34 +-- misc/dashy-update.sh | 18 +- misc/edge-kernel.sh | 189 +++++++------- misc/emby-update.sh | 22 +- misc/filebrowser.sh | 36 +-- misc/frigate-support.sh | 16 +- misc/ha-copy-data-podman.sh | 44 ++-- misc/ha-copy-data.sh | 44 ++-- misc/hacontainer2hacore-data.sh | 44 ++-- misc/hacore2hacontainer-data.sh | 44 ++-- misc/hacore2hacore-data.sh | 44 ++-- misc/hacs-core.sh | 6 +- misc/hacs.sh | 6 +- misc/heimdalldashboard-all-update.sh | 47 ++-- misc/homepage-update.sh | 40 +-- misc/kernel-clean.sh | 103 ++++---- misc/latest-update-menu.sh | 22 +- misc/navidrome-update.sh | 22 +- misc/nocodb-update.sh | 47 ++-- misc/node-red-themes.sh | 137 +++++----- misc/npm_update.sh | 100 ++++---- misc/paperless-ngx-update.sh | 18 +- misc/photoprism-update.sh | 76 +++--- misc/pms-copy-data.sh | 44 ++-- misc/podman-copy-data-docker.sh | 44 ++-- misc/podman_hacs.sh | 6 +- misc/post-pbs-install.sh | 103 ++++---- misc/post-pve-install.sh | 115 ++++----- misc/scaling-governor.sh | 84 +++--- misc/technitiumdns-update.sh | 67 +++-- misc/trilium-update.sh | 22 +- misc/unifi-update.sh | 19 +- misc/update-lxcs.sh | 71 +++-- misc/uptimekuma-update.sh | 27 +- misc/usb-passthrough.sh | 16 +- misc/vaultwarden-update.sh | 22 +- misc/web-vault-update.sh | 28 +- misc/webmin.sh | 19 +- misc/z2m-copy-data.sh | 44 ++-- misc/zwave-copy-data.sh | 45 ++-- misc/zwave-js-ui-update.sh | 27 +- setup/adguard-install.sh | 64 ++--- setup/blocky-install.sh | 66 ++--- setup/casaos-install.sh | 64 ++--- setup/daemonsync-install.sh | 64 ++--- setup/dashy-install.sh | 68 ++--- setup/debian-install.sh | 62 ++--- setup/deconz-install.sh | 64 ++--- setup/docker-install.sh | 108 ++++---- setup/emby-install.sh | 76 +++--- setup/emqx-install.sh | 62 ++--- setup/esphome-install.sh | 64 ++--- setup/grafana-install.sh | 64 ++--- setup/grocy-install.sh | 64 ++--- setup/heimdalldashboard-install.sh | 72 +++--- setup/homeassistant-core-install.sh | 104 ++++---- setup/homeassistant-install.sh | 64 ++--- setup/homebridge-install.sh | 64 ++--- setup/homepage-install.sh | 64 ++--- setup/influxdb-install.sh | 88 +++---- setup/iobroker-install.sh | 64 ++--- setup/jellyfin-install.sh | 80 +++--- setup/keycloak-install.sh | 70 ++--- setup/magicmirror-install.sh | 86 ++++--- setup/mariadb-install.sh | 79 +++--- setup/meshcentral-install.sh | 64 ++--- setup/motioneye-install.sh | 108 ++++---- setup/mqtt-install.sh | 64 ++--- setup/n8n-install.sh | 64 ++--- setup/navidrome-install.sh | 74 +++--- setup/nextcloudpi-install.sh | 62 ++--- setup/nginx-proxy-manager-install.sh | 150 +++++------ setup/nocodb-install.sh | 66 ++--- setup/node-red-install.sh | 66 ++--- setup/omada-install.sh | 62 ++--- setup/omv-install.sh | 64 ++--- setup/openhab-install.sh | 68 ++--- setup/paperless-ngx-install.sh | 130 +++++----- setup/photoprism-install.sh | 82 +++--- setup/pihole-install.sh | 66 ++--- setup/plex-install.sh | 79 +++--- setup/podman-homeassistant-install.sh | 113 ++++---- setup/postgresql-install.sh | 83 +++--- setup/prometheus-install.sh | 66 ++--- setup/syncthing-install.sh | 62 ++--- setup/technitiumdns-install.sh | 64 ++--- setup/trilium-install.sh | 70 ++--- setup/ubuntu-install.sh | 62 ++--- setup/umbrel-install.sh | 64 ++--- setup/unifi-install.sh | 71 ++--- setup/uptimekuma-install.sh | 66 ++--- setup/vaultwarden-install.sh | 98 +++---- setup/whoogle-install.sh | 64 ++--- setup/wikijs-install.sh | 70 ++--- setup/wireguard-install.sh | 74 +++--- setup/zigbee2mqtt-install.sh | 75 +++--- setup/zwave-js-ui-install.sh | 66 ++--- 155 files changed, 12962 insertions(+), 11552 deletions(-) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index 1a8fe6cc..60b4e089 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${GN} + echo -e "${GN} ___ __ __ / | ____/ /___ ___ ______ __________/ / / /| |/ __ / __ / / / / __ / ___/ __ / @@ -53,168 +53,192 @@ echo -e "${GN} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index a2e79c5f..ff4f3475 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" ____ __ __ / __ )/ /___v4_____/ /____ __ / __ / / __ \/ ___/ //_/ / / / @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 73d38b3c..e1e701f6 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" ______ ____ _____ / ____/___ __v4______ _/ __ \/ ___/ / / / __ `/ ___/ __ `/ / / /\__ \ @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,7 +257,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index 1eacbab4..820267f4 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} ____ _____ / __ \____ ____ ____ ___ ____ ____ / ___/__ ______ _____ / / / / __ / _ \/ __ __ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/ @@ -53,168 +53,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 8eaaf93d..fa6e0ad6 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ____ __ / __ \____ ______/ /_ __ __ / / / / __ / ___/ __ \/ / / / @@ -53,168 +53,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 8225b32d..ab9a868b 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} __ __________ _ _______ ____/ /v4 / ____/ __ \/ | / /__ / / __ / _ \/ / / / / / |/ / / / @@ -52,169 +52,193 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,7 +257,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index a5e4b72a..1e598396 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} ____ __ / __ \____ _____/ /_v4__ _____ / / / / __ \/ ___/ //_/ _ \/ ___/ @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -232,7 +256,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 66ddb644..3a3096f4 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${DGN} + echo -e "${DGN} ______ __ / ____/___ v4_ / /_ __ __ / __/ / __ __ \/ __ \/ / / / @@ -53,176 +53,200 @@ echo -e "${DGN} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ -"18.04" "Bionic" OFF \ -"20.04" "Focal" ON \ -"21.10" "Impish" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "21.10" "Impish" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -241,7 +265,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index f43d6508..0a79efcf 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" ________ _______v4 _ __ / ____/ |/ / __ \ | |/ / / __/ / /|_/ / / / / | / @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index d3cc16e3..95c5b25e 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${CL} + echo -e "${CL} ___________ ____ __ ______ __ _________ / ____/ ___// __ \/ / / / __ \/ |/ / ____/ / __/ \__ \/ /_/ / /_/ / / / / /|_/ / __/ @@ -52,168 +52,192 @@ echo -e "${CL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index fc40f4ff..6762da87 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} ______ ____ / ____/________ _/ __/___ _____ ____ _ / / __/ ___/ __ / /_/ __ / __ \/ __ / @@ -52,168 +52,192 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 21f73bb1..f1ed2e1d 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} ____ __________ _______ __ / __ / ___/ __ \/ ___/ / / / / /_/ / / / /_/ / /__/ /_/ / @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index de568b9b..7912b71b 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} __ __ _ __ ____ ____ __ __ __ / / / /__ (_)___ ___ ____/ /_v4 _/ / / / __ \____ ______/ /_ / /_ ____ ____ __________/ / / /_/ / _ \/ / __ __ \/ __ / __ / / / / / / / __ / ___/ __ \/ __ \/ __ \/ __ / ___/ __ / @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index c6b1ba10..11373448 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" __ __ ___ _ __ __ ______ / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / ____/___v4________ / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / __ \/ ___/ _ \ @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,8 +257,8 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit if [ "$CT_TYPE" == "0" ]; then -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 767a5bb8..8d8b9464 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} __ __ ___ _ __ __ / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,7 +257,7 @@ export PCT_OPTIONS=" bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf if [ "$CT_TYPE" == "0" ]; then -cat <> $LXC_CONFIG + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm @@ -244,7 +268,7 @@ lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create= lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF else -cat <> $LXC_CONFIG + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 508bc15d..861bc448 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} __ ______ __ _____________ ____ ________ ____________ / / / / __ \/ |/ / ____/ __ )/ __ \/ _/ __ \/ ____/ ____/ / /_/ / / / / /|_/ / __/ / __ / /_/ // // / / / / __/ __/ @@ -52,168 +52,192 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index 4d28a5f2..9c92edc8 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" __ __ / / / /___ ____ ___ ___ ____ ____ _____ ____ / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index b931f6b5..74121380 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} ____ ______ ____ ____ / _/_v4 / __/ /_ ___ __/ __ \/ __ ) / // __ \/ /_/ / / / / |/_/ / / / __ | @@ -52,168 +52,192 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index d2d8c6b0..43436724 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} _ ____ __ (_)___ / __ )_________ / /_____ _____ / / __ \/ __ / ___/ __ \/ //_/ _ \/ ___/ @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index bf006c52..3f49d1e7 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${DGN} + echo -e "${DGN} __________ ____ _____________ __ / / ____/ / / /\ \/ / ____/ _/ | / / __ / / __/ / / / / \ / /_ / // |/ / @@ -52,177 +52,201 @@ echo -e "${DGN} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ -"18.04" "Bionic" OFF \ -"20.04" "Focal" ON \ -"21.10" "Impish" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "21.10" "Impish" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -241,7 +265,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index f8172987..63d553f5 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} __ __ __ __ / //_/__ __ _______/ /___ ____ _/ /__ / ,< / _ \/ / / / ___/ / __ \/ __ / //_/ @@ -53,168 +53,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 12fc6bee..5a52a4de 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} __ ___ _ __ ____ / |/ /___ _____ _(_)____/ |/ (_)_____________ _____ / /|_/ / __ / __ / / ___/ /|_/ / / ___/ ___/ __ \/ ___/ @@ -53,168 +53,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index bb162f47..b2db3d31 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} __ ___ _ ____ ____ / |/ /___ ______(_)___ _/ __ \/ __ ) / /|_/ / __ / ___/ / __ / / / / __ | @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 20b01de8..a7b6767c 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} __ ___ __ ______ __ __ / |/ /__ _____/ /_ / ____/__ ____ / /__________ _/ / / /|_/ / _ \/ ___/ __ \/ / / _ \/ __ \/ __/ ___/ __ / / @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index ca5ba0e2..4834b42e 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} __ ___ __ _ ________ ________ / |/ /___ / /_(_)___ ____ / ____/\ \/ / ____/ / /|_/ / __ \/ __/ / __ \/ __ \/ __/ \ / __/ @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index b12a26ac..c1f88353 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ___ / _ \ _ __ | (_) |_v4_ @@ -53,168 +53,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 52940afc..57bfe2a0 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" _ __ _ __ / | / /___ __ v4__(_)___/ /________ ____ ___ ___ / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ @@ -52,168 +52,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index feb45833..68e5aed5 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" _ __ __ ________ ______ _ / | / /__ _ __/ /_/ ____/ /___ __v4______/ / __ \(_) / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / /_/ / / @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 68dbbf6e..326d353c 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} _ __ _ ____ __ ___ / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____ / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ @@ -53,168 +53,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index a4eccffb..8c58f846 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} _ __ ____ ____ / | / /___ ____v4___ / __ \/ __ ) / |/ / __ \/ ___/ __ \/ / / / __ | @@ -52,168 +52,192 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 0c356ee0..434bd642 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} _ __ __ ____ __ / | / /___ ____/ /__ v4 / __ \___ ____/ / / |/ / __ \/ __ / _ \ / /_/ / _ \/ __ / @@ -52,168 +52,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 51b2f592..6cea6f85 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} ____ __ / __ \____ ___v4____ _____/ /___ _ / / / / __ __ \/ __ / __ / __ / @@ -52,177 +52,201 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ -"18.04" "Bionic" OFF \ -"20.04" "Focal" ON \ -"21.10" "Impish" OFF \ -"22.04" "Jammy" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "21.10" "Impish" OFF \ + "22.04" "Jammy" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index 322e0373..2d58a0ad 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" ____ __ ___ ___ _ __ ____ / __ \____v4___ ____ / |/ /__ ____/ (_)___ | | / /___ ___ __/ / /_ / / / / __ \/ _ \/ __ \/ /|_/ / _ \/ __ / / __ `/ | / / __ `/ / / / / __/ @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,7 +257,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index 28aa3454..fb07b1fd 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} __ _____ ____ ____v4____ ___ ____ / / / / | / __ ) / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __ | @@ -53,168 +53,192 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index 7092b27b..f735b822 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" ____ __ / __ \____ _____ ___ _____/ /__v4__________ ____ ____ __ __ / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index b0ffd76c..69b2fd5e 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ____ __ ______ __________ ____ ____ _________ __ ___ / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / @@ -52,168 +52,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 3fced599..65b1df79 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ____ ____ __ ______ __ ______ / __ \/ _/ / / / / __ \/ / / ____/ / /_/ // /___/ /_/ / / / / / / __/ @@ -52,168 +52,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index b4ca8385..d9c4b619 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} ____ __ / __ \/ /__ _ __ / /_/ / / _ \| |/_/ @@ -52,177 +52,201 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ -"18.04" "Bionic" OFF \ -"20.04" "Focal" ON \ -"21.10" "Impish" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "21.10" "Impish" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -241,7 +265,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 9bbac839..df926cb6 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} ____ __ / __ \____ ____/ /___ ___ ____ _____ v4 / /_/ / __ \/ __ / __ __ \/ __ / __ \ @@ -56,168 +56,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -236,7 +260,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index 6f89483a..9fc542d3 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} ____ __ _____ ____ __ / __ \____ _____/ /_____ _________ / ___// __ \ / / / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / @@ -53,168 +53,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index db1ce80e..f17864ae 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ____ __ __ / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ @@ -52,168 +52,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index 50ef405c..e20ee8df 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" _____ __ __ _ / ___/__ ______v4_____/ /_/ /_ (_)___ ____ _ \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ @@ -54,168 +54,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index 3c1fe3a9..7d36387e 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ______ __ _ __ _ ____ _ _______ /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ v4 / __ \/ | / / ___/ / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ @@ -52,168 +52,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index bd121dd9..b64d1333 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" ______ _ ___ /_ __/_v4_(_) (_)_ ______ ___ / / / ___/ / / / / / / __ `__ \ @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 40997d2b..ce011c0a 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} __ ____ __ / / / / /_v4__ ______ / /___ __ / / / / __ \/ / / / __ \/ __/ / / / @@ -52,177 +52,201 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ -"18.04" "Bionic" OFF \ -"20.04" "Focal" OFF \ -"21.10" "Impish" OFF \ -"22.04" "Jammy" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" OFF \ + "21.10" "Impish" OFF \ + "22.04" "Jammy" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 1a7c38b1..8d02a0a6 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" __ __ __ __ / / / /___ ___v4/ /_ ________ / / / / / / __ `__ \/ __ \/ ___/ _ \/ / @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,7 +257,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index cdbb1a9d..0051f6a5 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} __ __ _ _____ / / / /_v4 (_) __(_) / / / / __ \/ / /_/ / @@ -52,168 +52,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index fcd9fc30..f1779f12 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${DGN} + echo -e "${DGN} __ __ __ _ __ __ / / / /___ / /_(_)___ ___ ___ v4 / //_/_ ______ ___ ____ _ / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / @@ -53,168 +53,192 @@ echo -e "${DGN} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index 1e403439..1de5fc5d 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${CL} + echo -e "${CL} _ _____ __ ____ _______ _____ ____ ____ _______ __ | | / / | / / / / / /_ __/ | / / | / __ \/ __ \/ ____/ | / / | | / / /| |/ / / / / / / | | /| / / /| | / /_/ / / / / __/ / |/ / @@ -52,168 +52,192 @@ echo -e "${CL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 644b5a3f..9527d486 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${GN} + echo -e "${GN} _ ____ ______ ____ ________ ______ | | v4 / / / / / __ \/ __ \/ ____/ / / ____/ | | /| / / /_/ / / / / / / / / __/ / / __/ @@ -52,168 +52,192 @@ echo -e "${GN} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index 7f6965ee..b4b50eff 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${BL} + echo -e "${BL} _ ___ __ _ _ | | / (_) /__(_) (_)____ | | /| / / / //_/ / / / ___/ @@ -53,168 +53,192 @@ echo -e "${BL} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index c594abc2..38e82951 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} __ ___ _____ _ \ \ / (_) / ____| | | \ \ /\ / / _ _ __ ___| | __ _ _ __ _ _ __ __| | @@ -54,168 +54,192 @@ echo -e "${RD} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 703b7fde..2c1881a5 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -echo -e "${YW} + echo -e "${YW} _____ _ __ ___ __ _______ ____________ /__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / @@ -53,168 +53,192 @@ echo -e "${YW} ${CL}" } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,7 +257,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 646773a0..45dd790c 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -10,13 +10,13 @@ NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -36,14 +36,14 @@ function error_exit() { exit $EXIT } if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function header_info { -cat << "EOF" + cat <<"EOF" _____ _______ __ ______ /__ /_ ______ __v4 _____ / / ___/ / / / / _/ / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / @@ -53,168 +53,192 @@ cat << "EOF" EOF } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ -"1" "Unprivileged" OFF \ -"0" "Privileged" ON \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi fi -fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export CTID=$CT_ID @@ -233,7 +257,7 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index ba0e37a2..e9a54a2d 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash echo -e "\e[1;33mThis script will add Tailscale to an existing LXC Container ONLY\e[0m" while true; do - read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit @@ -32,7 +32,7 @@ function msg() { CTID=$1 CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf -cat <> $CTID_CONFIG_PATH +cat <>$CTID_CONFIG_PATH lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF diff --git a/misc/code-server.sh b/misc/code-server.sh index 2fcade90..dfadd067 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash IP=$(hostname -I | awk '{print $1}') -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -21,25 +21,25 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${BL} + echo -e "${BL} ______ __ _____ / ____/___ ____/ /__ / ___/___ ______ _____ _____ / / / __ \/ __ / _ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ @@ -66,9 +66,9 @@ apt-get install -y sudo &>/dev/null apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" -VERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') \ +VERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') msg_info "Installing Code-Server v${VERSION}" curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_amd64.deb &>/dev/null @@ -76,7 +76,7 @@ sudo dpkg -i code-server_${VERSION}_amd64.deb &>/dev/null rm -rf code-server_${VERSION}_amd64.deb mkdir -p ~/.config/code-server/ sudo systemctl enable --now code-server@$USER &>/dev/null -cat < ~/.config/code-server/config.yaml +cat <~/.config/code-server/config.yaml bind-addr: 0.0.0.0:8680 auth: none password: diff --git a/misc/container-restore-from-backup.sh b/misc/container-restore-from-backup.sh index a70370ea..f1526ec5 100644 --- a/misc/container-restore-from-backup.sh +++ b/misc/container-restore-from-backup.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash clear -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -15,14 +15,14 @@ APP="Home Assistant Container" while true; do read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -cat << "EOF" + cat <<"EOF" __ __ ___ _ __ __ / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ @@ -46,10 +46,12 @@ function msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } -if [ -z "$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)" ]; then msg_error "No backups found! \n"; exit 1; fi +if [ -z "$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)" ]; then + msg_error "No backups found! \n" + exit 1 +fi DIR=/var/lib/docker/volumes/hass_config/_data/restore -if [ -d "$DIR" ]; -then +if [ -d "$DIR" ]; then msg_ok "Restore Directory Exists." else mkdir -p /var/lib/docker/volumes/hass_config/_data/restore @@ -58,7 +60,10 @@ fi cd /var/lib/docker/volumes/hass_config/_data/backups/ PS3="Please enter your choice: " files="$(ls -A .)" -select filename in ${files}; do msg_ok "You selected ${BL}${filename}${CL}"; break; done +select filename in ${files}; do + msg_ok "You selected ${BL}${filename}${CL}" + break +done msg_info "Stopping Home Assistant" docker stop homeassistant &>/dev/null msg_ok "Stopped Home Assistant" diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh index e603cc6d..afa664ee 100644 --- a/misc/core-restore-from-backup.sh +++ b/misc/core-restore-from-backup.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash clear -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -15,14 +15,14 @@ APP="Home Assistant Core" while true; do read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -cat << "EOF" + cat <<"EOF" __ __ ___ _ __ __ ______ / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / ____/___ ________ / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / __ \/ ___/ _ \ @@ -46,10 +46,12 @@ function msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } -if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then msg_error "No backups found! \n"; exit 1; fi +if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then + msg_error "No backups found! \n" + exit 1 +fi DIR=/root/.homeassistant/restore -if [ -d "$DIR" ]; -then +if [ -d "$DIR" ]; then msg_ok "Restore Directory Exists." else mkdir -p /root/.homeassistant/restore @@ -58,7 +60,10 @@ fi cd /root/.homeassistant/backups/ PS3="Please enter your choice: " files="$(ls -A .)" -select filename in ${files}; do msg_ok "You selected ${BL}${filename}${CL}"; break; done +select filename in ${files}; do + msg_ok "You selected ${BL}${filename}${CL}" + break +done msg_info "Stopping Home Assistant" sudo service homeassistant stop msg_ok "Stopped Home Assistant" diff --git a/misc/crowdsec.sh b/misc/crowdsec.sh index c4cf3d2d..63d3645e 100644 --- a/misc/crowdsec.sh +++ b/misc/crowdsec.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -20,25 +20,25 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${BL} + echo -e "${BL} _____ _ _____ / ____| | |/ ____| | | _ __ _____ ____| | (___ ___ ___ diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh index 6e7151de..d9c3826f 100644 --- a/misc/dashy-update.sh +++ b/misc/dashy-update.sh @@ -1,23 +1,23 @@ #!/usr/bin/env bash set -e clear -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") while true; do read -p "This will Update Dashy LXC. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${RD} + echo -e "${RD} _____ _ | __ \ | | | | | | __ _ ___| |__ _ _ diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 69d58d40..74867e89 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -2,26 +2,26 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" set -e KERNEL_ON=$(uname -r) -PVE_KERNEL=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) -EDGE_KERNEL=$(dpkg --list| grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) +PVE_KERNEL=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) +EDGE_KERNEL=$(dpkg --list | grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) clear while true; do read -p "This is a Proxmox Edge Kernel Tool, USE AT YOUR OWN RISK. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear -show_menu(){ - normal=`echo "\033[m"` - safe=`echo "\033[32m"` - menu=`echo "\033[36m"` - number=`echo "\033[33m"` - bgred=`echo "\033[41m"` - fgred=`echo "\033[31m"` +show_menu() { + normal=$(echo "\033[m") + safe=$(echo "\033[32m") + menu=$(echo "\033[36m") + number=$(echo "\033[33m") + bgred=$(echo "\033[41m") + fgred=$(echo "\033[31m") proxmox-boot-tool kernel list echo -e "\nCurrent Kernel: ${menu}${KERNEL_ON}${normal}" printf "\n${menu}*********************************************${normal}\n" @@ -34,106 +34,113 @@ show_menu(){ printf "Please choose an option from the menu and enter or ${fgred}x${normal} to exit." read opt } -option_picked(){ - msgcolor=`echo "\033[01;31m"` - normal=`echo "\033[00;00m"` +option_picked() { + msgcolor=$(echo "\033[01;31m") + normal=$(echo "\033[00;00m") message=${@:-"${normal}Error: No message passed"} printf "${msgcolor}${message}${normal}\n" } clear show_menu -while [ $opt != '' ] - do +while [ $opt != '' ]; do if [ $opt = '' ]; then - exit; + exit else - case $opt in - 1) while true; do - read -p "Are you sure you want to Install Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Installing Proxmox Edge Kernel & Rebooting"; + case $opt in + 1) + while true; do + read -p "Are you sure you want to Install Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + clear + option_picked "Installing Proxmox Edge Kernel & Rebooting" apt-get install -y gnupg curl -1sLf 'https://dl.cloudsmith.io/public/pve-edge/kernel/gpg.8EC01CCF309B98E7.key' | apt-key add - - echo "deb https://dl.cloudsmith.io/public/pve-edge/kernel/deb/debian bullseye main" > /etc/apt/sources.list.d/pve-edge-kernel.list + echo "deb https://dl.cloudsmith.io/public/pve-edge/kernel/deb/debian bullseye main" >/etc/apt/sources.list.d/pve-edge-kernel.list apt-get -y update apt-get -y install pve-kernel-5.19-edge reboot - break; - ;; - 2) while true; do - read -p "Are you sure you want to Switch to Proxmox VE 7 ${PVE_KERNEL} Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Switching to Proxmox VE 7 Kernel & Rebooting"; + break + ;; + 2) + while true; do + read -p "Are you sure you want to Switch to Proxmox VE 7 ${PVE_KERNEL} Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + clear + option_picked "Switching to Proxmox VE 7 Kernel & Rebooting" proxmox-boot-tool kernel pin ${PVE_KERNEL} reboot - break; - ;; - 3) while true; do - read -p "Are you sure you want to Switch to Proxmox ${EDGE_KERNEL} Edge Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Switching to Proxmox Edge Kernel & Rebooting"; + break + ;; + 3) + while true; do + read -p "Are you sure you want to Switch to Proxmox ${EDGE_KERNEL} Edge Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + clear + option_picked "Switching to Proxmox Edge Kernel & Rebooting" proxmox-boot-tool kernel pin ${EDGE_KERNEL} reboot - break; - ;; - 4) while true; do - read -p "Are you sure you want to Unpin the Current Kernel? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Unpinning Current Kernel"; + break + ;; + 4) + while true; do + read -p "Are you sure you want to Unpin the Current Kernel? Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + clear + option_picked "Unpinning Current Kernel" proxmox-boot-tool kernel unpin - clear; - break; - ;; - 5) while true; do - read -p "Are you sure you want to Remove Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Removing Proxmox Edge Kernel & Rebooting"; + clear + break + ;; + 5) + while true; do + read -p "Are you sure you want to Remove Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + clear + option_picked "Removing Proxmox Edge Kernel & Rebooting" apt-get purge -y ${EDGE_KERNEL} rm -rf /etc/apt/sources.list.d/pve-edge-kernel.list proxmox-boot-tool kernel unpin reboot - break; - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose an option from the menu"; - show_menu; - ;; - esac + break + ;; + x) + exit + ;; + \n) + exit + ;; + *) + clear + option_picked "Please choose an option from the menu" + show_menu + ;; + esac fi - done +done show_menu diff --git a/misc/emby-update.sh b/misc/emby-update.sh index 86a67a9e..85f7bc83 100644 --- a/misc/emby-update.sh +++ b/misc/emby-update.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -14,14 +14,14 @@ APP="Emby" while true; do read -p "This will Update ${APP} to ${LATEST}. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -cat << "EOF" + cat <<"EOF" ______ __ / ____/___ ___ / /_ __ __ / __/ / __ __ \/ __ \/ / / / diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index 6a11c514..dc322299 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash IP=$(hostname -I | awk '{print $1}') -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -21,25 +21,25 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${DGN} + echo -e "${DGN} ______ _ _ ____ | ____(_) | | _ \ @@ -81,7 +81,7 @@ WorkingDirectory=/root/ ExecStart=/usr/local/bin/filebrowser -r / [Install] -WantedBy=default.target" > $service_path +WantedBy=default.target" >$service_path systemctl enable --now filebrowser.service &>/dev/null msg_ok "Created Service" diff --git a/misc/frigate-support.sh b/misc/frigate-support.sh index 18c80d18..0341c2cd 100644 --- a/misc/frigate-support.sh +++ b/misc/frigate-support.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash echo -e "\e[1;33m This script will Prepare a LXC Container for Frigate \e[0m" while true; do - read -p "Did you replace 106 with your LXC ID? Proceed (y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Did you replace 106 with your LXC ID? Proceed (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -48,7 +48,7 @@ for char_dev in ${CHAR_DEVS[@]}; do CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" done -read -r -d '' HOOK_SCRIPT <<- EOF || true +read -r -d '' HOOK_SCRIPT <<-EOF || true for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); @@ -66,7 +66,7 @@ CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH -cat <> $CTID_CONFIG_PATH +cat <>$CTID_CONFIG_PATH lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF diff --git a/misc/ha-copy-data-podman.sh b/misc/ha-copy-data-podman.sh index a37c9779..7296519c 100644 --- a/misc/ha-copy-data-podman.sh +++ b/misc/ha-copy-data-podman.sh @@ -3,12 +3,12 @@ # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" while true; do - read -p "Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -58,28 +58,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Podman LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Podman LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.02.12" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" @@ -90,13 +90,13 @@ fi msg "Mounting Container Disks..." DOCKER_PATH=/var/lib/docker/volumes/hass_config/ PODMAN_PATH=/var/lib/containers/storage/volumes/hass_config/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || die "Home Assistant directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${PODMAN_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${PODMAN_PATH}" ] || die "Home Assistant directories in '$CTID_TO' not found." rm -rf ${CTID_TO_PATH}${PODMAN_PATH} diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index dfc67d12..83f26a19 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -3,12 +3,12 @@ # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" while true; do - read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -58,28 +58,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.23" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" @@ -89,13 +89,13 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then fi msg "Mounting Container Disks..." DOCKER_PATH=/var/lib/docker/volumes/hass_config/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || die "Home Assistant directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || die "Home Assistant directories in '$CTID_TO' not found." rm -rf ${CTID_TO_PATH}${DOCKER_PATH} diff --git a/misc/hacontainer2hacore-data.sh b/misc/hacontainer2hacore-data.sh index 94476e09..e6563275 100644 --- a/misc/hacontainer2hacore-data.sh +++ b/misc/hacontainer2hacore-data.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash while true; do - read -p "Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -55,28 +55,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Container LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Container LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Core LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Core LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.10.02" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" @@ -87,13 +87,13 @@ fi msg "Mounting Container Disks..." DOCKER_PATH=/var/lib/docker/volumes/hass_config/_data CORE_PATH=/root/.homeassistant -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || die "Home Assistant directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${CORE_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${CORE_PATH}" ] || die "Home Assistant directories in '$CTID_TO' not found." msg "Copying Data..." diff --git a/misc/hacore2hacontainer-data.sh b/misc/hacore2hacontainer-data.sh index 8edf5b74..ec40b43c 100644 --- a/misc/hacore2hacontainer-data.sh +++ b/misc/hacore2hacontainer-data.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash while true; do - read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -55,28 +55,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Core LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Core LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Container LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Container LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.10.02" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" @@ -87,13 +87,13 @@ fi msg "Mounting Container Disks..." DOCKER_PATH=/var/lib/docker/volumes/hass_config/_data CORE_PATH=/root/.homeassistant -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${CORE_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${CORE_PATH}" ] || die "Home Assistant directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || die "Home Assistant directories in '$CTID_TO' not found." msg "Copying Data..." diff --git a/misc/hacore2hacore-data.sh b/misc/hacore2hacore-data.sh index 44c67f6f..1faff32c 100644 --- a/misc/hacore2hacore-data.sh +++ b/misc/hacore2hacore-data.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash clear while true; do - read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -51,28 +51,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Core LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Core LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Core LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Core LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.10.03" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" @@ -83,13 +83,13 @@ fi msg "Mounting Container Disks..." DOCKER_PATH=/var/lib/docker/volumes/hass_config/_data CORE_PATH=/root/.homeassistant -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${CORE_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${CORE_PATH}" ] || die "Home Assistant directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${CORE_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${CORE_PATH}" ] || die "Home Assistant directories in '$CTID_TO' not found." msg "Copying Data..." diff --git a/misc/hacs-core.sh b/misc/hacs-core.sh index b6374539..71a9524f 100644 --- a/misc/hacs-core.sh +++ b/misc/hacs-core.sh @@ -4,9 +4,9 @@ echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) while true; do read -p "Start the HACS Install Script (y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done diff --git a/misc/hacs.sh b/misc/hacs.sh index ed476b0d..0c3cd2ad 100644 --- a/misc/hacs.sh +++ b/misc/hacs.sh @@ -4,9 +4,9 @@ echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) while true; do read -p "Start the HACS Install Script (y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done diff --git a/misc/heimdalldashboard-all-update.sh b/misc/heimdalldashboard-all-update.sh index 66539ed6..e7b1de62 100644 --- a/misc/heimdalldashboard-all-update.sh +++ b/misc/heimdalldashboard-all-update.sh @@ -1,22 +1,22 @@ #!/usr/bin/env bash set -e -PP=`echo "\e[1;35m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` +PP=$(echo "\e[1;35m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") while true; do - read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done clear function header_info { -echo -e "${PP} + echo -e "${PP} _ _ _ _ _ _ _____ _ _ _ | | | | (_) | | | | | | __ \ | | | | | | | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | @@ -39,13 +39,13 @@ echo -en "${GN} Backing up Data... " if [ -d "/opt/Heimdall-2.4.6" ]; then cp -R /opt/Heimdall-2.4.6/database database-backup cp -R /opt/Heimdall-2.4.6/public public-backup - elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then +elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then cp -R /opt/Heimdall-2.4.7b/database database-backup cp -R /opt/Heimdall-2.4.7b/public public-backup - elif [[ -d "/opt/Heimdall-2.4.8" ]]; then +elif [[ -d "/opt/Heimdall-2.4.8" ]]; then cp -R /opt/Heimdall-2.4.8/database database-backup cp -R /opt/Heimdall-2.4.8/public public-backup - else +else cp -R /opt/Heimdall/database database-backup cp -R /opt/Heimdall/public public-backup fi @@ -56,13 +56,13 @@ RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releas echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') if [ ! -d "/opt/Heimdall" ]; then - mv Heimdall-${VER} /opt/Heimdall - else + mv Heimdall-${VER} /opt/Heimdall +else cp -R Heimdall-${VER}/* /opt/Heimdall fi echo -e "${CM}${CL} \r" @@ -82,7 +82,7 @@ ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 TimeoutStopSec=30 [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path echo -en "${GN} Restoring Data... " cp -R database-backup/* /opt/Heimdall/database @@ -94,10 +94,10 @@ echo -en "${GN} Cleanup... " if [ -d "/opt/Heimdall-2.4.6" ]; then rm -rf /opt/Heimdall-2.4.6 rm -rf /opt/v2.4.6.tar.gz - elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then +elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then rm -rf /opt/Heimdall-2.4.7b rm -rf /opt/v2.4.7b.tar.gz - elif [[ -d "/opt/Heimdall-2.4.8" ]]; then +elif [[ -d "/opt/Heimdall-2.4.8" ]]; then rm -rf /opt/Heimdall-2.4.8 rm -rf /opt/v2.4.8.tar.gz fi @@ -116,4 +116,3 @@ sleep 2 echo -e "${CM}${CL} \r" echo -en "${GN} Finished! ${CL}\n" - diff --git a/misc/homepage-update.sh b/misc/homepage-update.sh index 7b8ac4c6..49a65168 100644 --- a/misc/homepage-update.sh +++ b/misc/homepage-update.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -19,25 +19,25 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } while true; do read -p "This will Update ${APP}. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -cat << "EOF" + cat <<"EOF" __ __ / / / /___ ____ ___ ___ ____ ____ _____ ____ / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ @@ -61,10 +61,10 @@ function msg_ok() { msg_info "Updating ${APP}" if ! command -v pnpm >/dev/null 2>&1; then - npm install -g pnpm &>/dev/null + npm install -g pnpm &>/dev/null fi -cd /opt/homepage -systemctl stop homepage +cd /opt/homepage +systemctl stop homepage git pull --force &>/dev/null pnpm install &>/dev/null pnpm build &>/dev/null diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 8a337672..a7b6319d 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash -ex set -euo pipefail shopt -s inherit_errexit nullglob -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -18,15 +18,15 @@ current_kernel=$(uname -r) while true; do read -p "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo -e "${RD}Please answer y/n${CL}";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo -e "${RD}Please answer y/n${CL}" ;; esac done clear function header_info { -echo -e "${RD} + echo -e "${RD} _ __ _ _____ _ | |/ / | | / ____| | | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ @@ -48,29 +48,29 @@ function msg_ok() { } function check_root() { - if [[ $EUID -ne 0 ]]; then - echo -e "${CROSS}${RD}Error: This script must be ran as the root user.\n${CL}" - exit 1 - else - header_info - edge_kernel - kernel_info - kernel_clean - fi + if [[ $EUID -ne 0 ]]; then + echo -e "${CROSS}${RD}Error: This script must be ran as the root user.\n${CL}" + exit 1 + else + header_info + edge_kernel + kernel_info + kernel_clean + fi } function edge_kernel() { if [[ "$current_kernel" == *"edge"* ]]; then - echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" - echo -e "\nAn Active PVE Kernel is required to use Kernel Clean\n" - exit 1 + echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" + echo -e "\nAn Active PVE Kernel is required to use Kernel Clean\n" + exit 1 fi } function kernel_info() { - if [[ "$MODE" != "PBS" ]]; then - echo -e "${YW}PVE Version: ${BL}$(pveversion)\n${CL}" - fi + if [[ "$MODE" != "PBS" ]]; then + echo -e "${YW}PVE Version: ${BL}$(pveversion)\n${CL}" + fi if [[ "$current_kernel" == *"pve"* ]]; then echo -e "${YW}Current Kernel: ${BL}$current_kernel\n${CL}" else @@ -80,50 +80,49 @@ function kernel_info() { } function kernel_clean() { - kernels=$(dpkg --list| grep 'kernel-.*-pve' | awk '{print $2}' | sort -V) + kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | sort -V) remove_kernels="" - for kernel in $kernels - do + for kernel in $kernels; do if [ "$(echo $kernel | grep $current_kernel)" ]; then break else echo -e "${BL}'$kernel' ${CL}${YW}has been added to the remove Kernel list\n${CL}" - remove_kernels+=" $kernel" + remove_kernels+=" $kernel" fi done -msg_ok "Kernel Search Completed\n" + msg_ok "Kernel Search Completed\n" if [[ "$remove_kernels" != *"pve"* ]]; then echo -e "${PARTY} ${GN}It appears there are no old Kernels on your system. \n${CL}" msg_info "Exiting" sleep 2 msg_ok "Done" else - read -p "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') selected Kernels listed above? [y/n]: " -n 1 -r + read -p "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') selected Kernels listed above? [y/n]: " -n 1 -r echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" - /usr/bin/apt purge -y $remove_kernels > /dev/null 2>&1 - msg_ok "Successfully Removed Kernels" - msg_info "Updating GRUB" - /usr/sbin/update-grub > /dev/null 2>&1 - msg_ok "Successfully Updated GRUB" - msg_info "Exiting" - sleep 2 - msg_ok "Done" - else - msg_info "Exiting" - sleep 2 - msg_ok "Done" - fi + if [[ $REPLY =~ ^[Yy]$ ]]; then + msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" + /usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 + msg_ok "Successfully Removed Kernels" + msg_info "Updating GRUB" + /usr/sbin/update-grub >/dev/null 2>&1 + msg_ok "Successfully Updated GRUB" + msg_info "Exiting" + sleep 2 + msg_ok "Done" + else + msg_info "Exiting" + sleep 2 + msg_ok "Done" + fi fi } if ! command -v pveversion >/dev/null 2>&1; then - echo -e " Switching to PBS mode" - MODE="PBS" - sleep 2 - else - MODE="PVE" + echo -e " Switching to PBS mode" + MODE="PBS" + sleep 2 +else + MODE="PVE" fi check_root diff --git a/misc/latest-update-menu.sh b/misc/latest-update-menu.sh index 2d23b5f7..90d6f25b 100644 --- a/misc/latest-update-menu.sh +++ b/misc/latest-update-menu.sh @@ -3,9 +3,9 @@ while true; do read -p "This will create a New Update Menu for Home Assistant Container LXC. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear @@ -13,19 +13,19 @@ set -o errexit rm -rf /root/update.sh update update-containers.sh echo -e "\e[1;92m Creating New Update Menu Script... \e[0m" if [ -f /usr/local/lib/python3.9/dist-packages/runlike/runlike.py ]; then -echo -e "\e[1;92m pip3/runlike Already Installed! \e[0m" + echo -e "\e[1;92m pip3/runlike Already Installed! \e[0m" else -apt-get update &>/dev/null -echo -e "\e[1;92m Installing pip3... \e[0m" -apt-get install -y python3-pip &>/dev/null -echo -e "\e[1;92m Installing runlike... \e[0m" -pip3 install runlike &>/dev/null + apt-get update &>/dev/null + echo -e "\e[1;92m Installing pip3... \e[0m" + apt-get install -y python3-pip &>/dev/null + echo -e "\e[1;92m Installing runlike... \e[0m" + pip3 install runlike &>/dev/null fi echo -e "\e[1;92m Creating Update Script... \e[0m" if [ -d /root/hass_config ]; then -echo -e "\e[1;92m There's Already (hass_config) Folder! \e[0m" + echo -e "\e[1;92m There's Already (hass_config) Folder! \e[0m" else -mkdir /root/hass_config + mkdir /root/hass_config fi UPDATE_PATH='/root/update' UPDATE_CONTAINERS_PATH='/root/update-containers.sh' diff --git a/misc/navidrome-update.sh b/misc/navidrome-update.sh index c3ecded7..333632cc 100644 --- a/misc/navidrome-update.sh +++ b/misc/navidrome-update.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") function update_info { -cat << "EOF" + cat <<"EOF" _ __ _ __ / | / /___ __ __(_)___/ /________ ____ ___ ___ / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ @@ -23,9 +23,9 @@ update_info while true; do read -p "This will Update Navidrome to v$RELEASE. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done sleep 2 diff --git a/misc/nocodb-update.sh b/misc/nocodb-update.sh index 9a4e0399..3cc7494c 100644 --- a/misc/nocodb-update.sh +++ b/misc/nocodb-update.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -19,25 +19,25 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT + trap - ERR + local reason="Unknown failure occured." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } while true; do read -p "This will Update ${APP}. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${YW} + echo -e "${YW} _ _ _____ ____ | \ | | | __ \| _ \ | \| | ___ v3___ ___ | | | | |_) | @@ -68,18 +68,17 @@ msg_ok "Updated ${APP}" read -p "${APP} LXC needs to reboot to apply the update. Reboot now? " -n 1 -r echo -if [[ $REPLY =~ ^[Yy]$ ]] -then +if [[ $REPLY =~ ^[Yy]$ ]]; then reboot=yes else reboot=no fi -if [ "$reboot" == "yes" ]; then -msg_info "Rebooting ${APP} LXC" -reboot +if [ "$reboot" == "yes" ]; then + msg_info "Rebooting ${APP} LXC" + reboot fi -if [ "$reboot" == "no" ]; then -msg_ok "Finished Updating ${APP}. Reboot to apply the update." +if [ "$reboot" == "no" ]; then + msg_ok "Finished Updating ${APP}. Reboot to apply the update." fi diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh index 7795f8cb..1a813bc1 100644 --- a/misc/node-red-themes.sh +++ b/misc/node-red-themes.sh @@ -1,24 +1,24 @@ #!/usr/bin/env bash # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-themes.sh)" set -o errexit -show_menu(){ - YW=`echo "\033[33m"` - RD=`echo "\033[01;31m"` - BL=`echo "\033[36m"` +show_menu() { + YW=$(echo "\033[33m") + RD=$(echo "\033[01;31m") + BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' - GN=`echo "\033[1;92m"` - CL=`echo "\033[m"` -echo -e "${RD} Backup your Node-Red flows before running this script!!${CL} \n " -while true; do - read -p "This will Install Node-Red Themes. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -echo -e "${RD} Backup your Node-Red flows before installing any theme!!${CL} \n " + GN=$(echo "\033[1;92m") + CL=$(echo "\033[m") + echo -e "${RD} Backup your Node-Red flows before running this script!!${CL} \n " + while true; do + read -p "This will Install Node-Red Themes. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + clear + echo -e "${RD} Backup your Node-Red flows before installing any theme!!${CL} \n " printf "\n${BL}*********************************************${CL}\n" printf "${BL}**${YW} 1)${GN} Default Theme ${CL}\n" printf "${BL}**${YW} 2)${GN} Dark Theme ${CL}\n" @@ -32,75 +32,84 @@ echo -e "${RD} Backup your Node-Red flows before installing any theme!!${CL} \n read opt } -option_picked(){ - msgcolor=`echo "\033[01;31m"` - normal=`echo "\033[00;00m"` +option_picked() { + msgcolor=$(echo "\033[01;31m") + normal=$(echo "\033[00;00m") message=${@:-"${CL}Error: No message passed"} printf "${RD}${message}${CL}\n" } clear show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - option_picked "Installing Default Theme"; - THEME= - JS=// - break; +while [ "$opt" != " " ]; do + case $opt in + 1) + clear + option_picked "Installing Default Theme" + THEME= + JS=// + break ;; - 2) clear; - option_picked "Installing Dark Theme"; - THEME=dark - break; + 2) + clear + option_picked "Installing Dark Theme" + THEME=dark + break ;; - 3) clear; - option_picked "Installing Dracula Theme"; - THEME=dracula - break; + 3) + clear + option_picked "Installing Dracula Theme" + THEME=dracula + break ;; - 4) clear; - option_picked "Installing Midnight-Red Theme"; - THEME=midnight-red - break; + 4) + clear + option_picked "Installing Midnight-Red Theme" + THEME=midnight-red + break ;; - 5) clear; - option_picked "Installing Oled Theme"; - THEME=oled - break; + 5) + clear + option_picked "Installing Oled Theme" + THEME=oled + break ;; - 6) clear; - option_picked "Installing Solarized-Dark Theme"; - THEME=solarized-dark - break; + 6) + clear + option_picked "Installing Solarized-Dark Theme" + THEME=solarized-dark + break ;; - 7) clear; - option_picked "Installing Solarized-Light Theme"; - THEME=solarized-light - break; + 7) + clear + option_picked "Installing Solarized-Light Theme" + THEME=solarized-light + break ;; - x)exit; + x) + exit ;; - \n)exit; + \n) + exit ;; - *)clear; - option_picked "Please choose a theme from the menu"; - show_menu; + *) + clear + option_picked "Please choose a theme from the menu" + show_menu ;; - esac - done + esac +done echo -en "${GN} Installing ${THEME} Theme... " cd /root/.node-red if [ "${THEME}" = "" ]; then - echo -e "${CM}${CL} \r" - else -npm install @node-red-contrib-themes/${THEME} &>/dev/null -echo -e "${CM}${CL} \r" + echo -e "${CM}${CL} \r" +else + npm install @node-red-contrib-themes/${THEME} &>/dev/null + echo -e "${CM}${CL} \r" fi echo -en "${GN} Writing Settings... " -cat < /root/.node-red/settings.js +cat </root/.node-red/settings.js module.exports = { uiPort: process.env.PORT || 1880, mqttReconnectTime: 15000, serialReconnectTime: 15000, diff --git a/misc/npm_update.sh b/misc/npm_update.sh index 4289e892..ca817b59 100644 --- a/misc/npm_update.sh +++ b/misc/npm_update.sh @@ -1,16 +1,16 @@ #!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') \ +RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") function update_info { -echo -e "${RD} + echo -e "${RD} _ _ _____ __ __ | \ | | | __ \ | \/ | | \| | | |__) | | \ / | @@ -24,19 +24,19 @@ ${CL}" update_info while true; do - read -p "This will update Nginx Proxy Manager to v${RELEASE}. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "This will update Nginx Proxy Manager to v${RELEASE}. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done clear update_info -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -57,23 +57,23 @@ function msg() { T="$(date +%M)" if [ -f /lib/systemd/system/npm.service ]; then -echo -en "${GN} Prep For Update... " -sleep 2 -echo -e "${CM}${CL} \r" -echo -en "${GN} Stopping Services... " + echo -en "${GN} Prep For Update... " + sleep 2 + echo -e "${CM}${CL} \r" + echo -en "${GN} Stopping Services... " systemctl stop openresty systemctl stop npm -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleaning Old Files... " - rm -rf /app \ - /var/www/html \ - /etc/nginx \ - /var/log/nginx \ - /var/lib/nginx \ - /var/cache/nginx &>/dev/null echo -e "${CM}${CL} \r" - else + + echo -en "${GN} Cleaning Old Files... " + rm -rf /app \ + /var/www/html \ + /etc/nginx \ + /var/log/nginx \ + /var/lib/nginx \ + /var/cache/nginx &>/dev/null + echo -e "${CM}${CL} \r" +else echo -en "${RD} No NPM to Update! ${CL}" exit fi @@ -103,24 +103,24 @@ cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-prox ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf rm -f /etc/nginx/conf.d/dev.conf mkdir -p /tmp/nginx/body \ -/run/nginx \ -/data/nginx \ -/data/custom_ssl \ -/data/logs \ -/data/access \ -/data/nginx/default_host \ -/data/nginx/default_www \ -/data/nginx/proxy_host \ -/data/nginx/redirection_host \ -/data/nginx/stream \ -/data/nginx/dead_host \ -/data/nginx/temp \ -/var/lib/nginx/cache/public \ -/var/lib/nginx/cache/private \ -/var/cache/nginx/proxy_temp + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp chmod -R 777 /var/cache/nginx chown root /tmp/nginx -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf echo -e "${CM}${CL} \r" if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then @@ -144,7 +144,7 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Initializing Backend... " rm -rf /app/config/default.json &>/dev/null if [ ! -f /app/config/production.json ]; then -cat << 'EOF' > /app/config/production.json + cat <<'EOF' >/app/config/production.json { "database": { "engine": "knex-native", @@ -168,7 +168,7 @@ systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm echo -e "${CM}${CL} \r" -TS="$(($(date +%M)-T))" +TS="$(($(date +%M) - T))" IP=$(hostname -I | cut -f1 -d ' ') echo -e "${GN}Successfully Updated Nginx Proxy Manager to ${RD}${RELEASE}${CL} and it took ${RD}${TS} minutes.${CL} diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index fc737ee0..87cbf03f 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash clear RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -30,7 +30,7 @@ function msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } -cat << "EOF" +cat <<"EOF" ____ __ / __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __ / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ @@ -42,9 +42,9 @@ EOF while true; do read -p "This will Update Paperless-ngx to $RELEASE. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done sleep 2 diff --git a/misc/photoprism-update.sh b/misc/photoprism-update.sh index 7ab7f8f6..f6e99980 100644 --- a/misc/photoprism-update.sh +++ b/misc/photoprism-update.sh @@ -1,28 +1,28 @@ #!/usr/bin/env bash set -e -RELEASE=$(curl -s https://api.github.com/repos/photoprism/photoprism/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-4) }') \ +RELEASE=$(curl -s https://api.github.com/repos/photoprism/photoprism/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-4) }') -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -PP=`echo "\e[1;35m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +PP=$(echo "\e[1;35m") while true; do read -p "Update PhotoPrism LXC. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${PP} + echo -e "${PP} _____ _ _ _____ _ | __ \| | | | | __ \ (_) | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ @@ -34,7 +34,7 @@ ${CL}" } header_info -show_menu(){ +show_menu() { printf " ${YW} 1)${GN} Release Branch ${CL}\n" printf " ${YW} 2)${YW} Develop Branch ${CL}\n" @@ -42,37 +42,41 @@ show_menu(){ read opt } -option_picked(){ +option_picked() { message1=${@:-"${CL}Error: No message passed"} printf " ${YW}${message1}${CL}\n" } show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Release Branch"; - BR="release" - break; +while [ "$opt" != " " ]; do + case $opt in + 1) + clear + header_info + option_picked "Using Release Branch" + BR="release" + break ;; - 2) clear; - header_info; - option_picked "Using Develop Branch"; - BR="develop" - break; + 2) + clear + header_info + option_picked "Using Develop Branch" + BR="develop" + break ;; - x)exit; + x) + exit ;; - \n)exit; + \n) + exit ;; - *)clear; - option_picked "Please choose a Install Branch from the menu"; - show_menu; + *) + clear + option_picked "Please choose a Install Branch from the menu" + show_menu ;; - esac - done + esac +done echo -en "${GN} Stopping PhotoPrism... " sudo systemctl stop photoprism @@ -100,5 +104,3 @@ sudo systemctl start photoprism echo -e "${CM}${CL} \n" echo -e "${GN} Finished ${CL} \n " - - diff --git a/misc/pms-copy-data.sh b/misc/pms-copy-data.sh index ffa2340f..60812f67 100644 --- a/misc/pms-copy-data.sh +++ b/misc/pms-copy-data.sh @@ -3,12 +3,12 @@ # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" while true; do - read -p "Use to copy all data from one Plex Media Server LXC to another. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from one Plex Media Server LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -58,28 +58,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Plex Media Server LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich Plex Media Server LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Plex Media Server LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich Plex Media Server LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.24" 13 50 || exit info "Plex Media Server Data from '$CTID_FROM' to '$CTID_TO'" @@ -89,13 +89,13 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then fi msg "Mounting Container Disks..." DATA_PATH=/var/lib/plexmediaserver/Library/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || die "Plex Media Server directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || die "Plex Media Server directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} diff --git a/misc/podman-copy-data-docker.sh b/misc/podman-copy-data-docker.sh index de5e0b1a..5b5bea9e 100644 --- a/misc/podman-copy-data-docker.sh +++ b/misc/podman-copy-data-docker.sh @@ -3,12 +3,12 @@ # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman-copy-data-docker.sh)" while true; do - read -p "Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -58,28 +58,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA Podman LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA Podman LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich HA LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich HA LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.03.31" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" @@ -90,13 +90,13 @@ fi msg "Mounting Container Disks..." DOCKER_PATH=/var/lib/docker/volumes/hass_config/ PODMAN_PATH=/var/lib/containers/storage/volumes/hass_config/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${PODMAN_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${PODMAN_PATH}" ] || die "Home Assistant directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || die "Home Assistant directories in '$CTID_TO' not found." rm -rf ${CTID_TO_PATH}${DOCKER_PATH} diff --git a/misc/podman_hacs.sh b/misc/podman_hacs.sh index d85ad7da..6936b066 100644 --- a/misc/podman_hacs.sh +++ b/misc/podman_hacs.sh @@ -4,9 +4,9 @@ echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) while true; do read -p "Start the HACS Install Script (y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index c73c1cfb..b96dbb93 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash -ex set -euo pipefail shopt -s inherit_errexit nullglob -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -17,19 +17,19 @@ echo -e "${BL}This script will Perform Post Install Routines.${CL}" while true; do read -p "Start the PBS Post Install Script (y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done if command -v pveversion >/dev/null 2>&1; then - echo -e "\n🛑 PVE Detected, Wrong Script!\n" - exit 1 + echo -e "\n🛑 PVE Detected, Wrong Script!\n" + exit 1 fi function header_info { -cat << "EOF" + cat <<"EOF" ____ ____ _____ ____ __ ____ __ ____ / __ \/ __ ) ___/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / / /_/ / __ \__ \ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / @@ -52,74 +52,67 @@ function msg_ok() { clear header_info read -r -p "Disable Enterprise Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Disabling Enterprise Repository" -sleep 2 -sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pbs-enterprise.list -msg_ok "Disabled Enterprise Repository" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Disabling Enterprise Repository" + sleep 2 + sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pbs-enterprise.list + msg_ok "Disabled Enterprise Repository" fi read -r -p "Add/Correct PBS Sources (sources.list)? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Adding or Correcting PBS Sources" -cat < /etc/apt/sources.list +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Adding or Correcting PBS Sources" + cat </etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib deb http://ftp.debian.org/debian bullseye-updates main contrib deb http://security.debian.org/debian-security bullseye-security main contrib EOF -sleep 2 -msg_ok "Added or Corrected PBS Sources" + sleep 2 + msg_ok "Added or Corrected PBS Sources" fi read -r -p "Enable No-Subscription Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Enabling No-Subscription Repository" -cat <> /etc/apt/sources.list +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Enabling No-Subscription Repository" + cat <>/etc/apt/sources.list deb http://download.proxmox.com/debian/pbs bullseye pbs-no-subscription EOF -sleep 2 -msg_ok "Enabled No-Subscription Repository" + sleep 2 + msg_ok "Enabled No-Subscription Repository" fi read -r -p "Add (Disabled) Beta/Test Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Adding Beta/Test Repository and set disabled" -cat <> /etc/apt/sources.list +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Adding Beta/Test Repository and set disabled" + cat <>/etc/apt/sources.list # deb http://download.proxmox.com/debian/pbs bullseye pbstest EOF -sleep 2 -msg_ok "Added Beta/Test Repository" + sleep 2 + msg_ok "Added Beta/Test Repository" fi read -r -p "Disable Subscription Nag? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Disabling Subscription Nag" -echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script -apt --reinstall install proxmox-widget-toolkit &>/dev/null -msg_ok "Disabled Subscription Nag" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Disabling Subscription Nag" + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + apt --reinstall install proxmox-widget-toolkit &>/dev/null + msg_ok "Disabled Subscription Nag" fi read -r -p "Update Proxmox Backup Server now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Updating Proxmox Backup Server (Patience)" -apt-get update &>/dev/null -apt-get -y dist-upgrade &>/dev/null -msg_ok "Updated Proxmox Backup Server (⚠ Reboot Recommended)" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Updating Proxmox Backup Server (Patience)" + apt-get update &>/dev/null + apt-get -y dist-upgrade &>/dev/null + msg_ok "Updated Proxmox Backup Server (⚠ Reboot Recommended)" fi read -r -p "Reboot Proxmox Backup Server now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Rebooting Proxmox Backup Server" -sleep 2 -msg_ok "Completed Post Install Routines" -reboot +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Rebooting Proxmox Backup Server" + sleep 2 + msg_ok "Completed Post Install Routines" + reboot fi sleep 2 diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index efd4945d..7fb7bd7b 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash -ex set -euo pipefail shopt -s inherit_errexit nullglob -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -17,26 +17,26 @@ echo -e "${BL}This script will Perform Post Install Routines.${CL}" while true; do read -p "Start the PVE7 Post Install Script (y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done if ! command -v pveversion >/dev/null 2>&1; then - echo -e "\n🛑 No PVE Detected, Wrong Script!\n" - exit 1 + echo -e "\n🛑 No PVE Detected, Wrong Script!\n" + exit 1 fi -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo -e "\n${RD}⚠ This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version: 7.XX${CL}" - echo -e "\nExiting..." - sleep 3 - exit +if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then + echo -e "\n${RD}⚠ This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version: 7.XX${CL}" + echo -e "\nExiting..." + sleep 3 + exit fi function header_info { -echo -e "${RD} + echo -e "${RD} ____ _ _____________ ____ __ ____ __ ____ / __ \ | / / ____/__ / / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / @@ -58,74 +58,67 @@ function msg_ok() { clear header_info read -r -p "Disable Enterprise Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Disabling Enterprise Repository" -sleep 2 -sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list -msg_ok "Disabled Enterprise Repository" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Disabling Enterprise Repository" + sleep 2 + sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list + msg_ok "Disabled Enterprise Repository" fi read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Adding or Correcting PVE7 Sources" -cat < /etc/apt/sources.list +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Adding or Correcting PVE7 Sources" + cat </etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib deb http://ftp.debian.org/debian bullseye-updates main contrib deb http://security.debian.org/debian-security bullseye-security main contrib EOF -sleep 2 -msg_ok "Added or Corrected PVE7 Sources" + sleep 2 + msg_ok "Added or Corrected PVE7 Sources" fi read -r -p "Enable No-Subscription Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Enabling No-Subscription Repository" -cat <> /etc/apt/sources.list +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Enabling No-Subscription Repository" + cat <>/etc/apt/sources.list deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription EOF -sleep 2 -msg_ok "Enabled No-Subscription Repository" + sleep 2 + msg_ok "Enabled No-Subscription Repository" fi read -r -p "Add (Disabled) Beta/Test Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Adding Beta/Test Repository and set disabled" -cat <> /etc/apt/sources.list +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Adding Beta/Test Repository and set disabled" + cat <>/etc/apt/sources.list # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF -sleep 2 -msg_ok "Added Beta/Test Repository" + sleep 2 + msg_ok "Added Beta/Test Repository" fi read -r -p "Disable Subscription Nag? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Disabling Subscription Nag" -echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/no-nag-script -apt --reinstall install proxmox-widget-toolkit &>/dev/null -msg_ok "Disabled Subscription Nag (Delete browser cache)" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Disabling Subscription Nag" + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + apt --reinstall install proxmox-widget-toolkit &>/dev/null + msg_ok "Disabled Subscription Nag (Delete browser cache)" fi read -r -p "Update Proxmox VE 7 now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Updating Proxmox VE 7 (Patience)" -apt-get update &>/dev/null -apt-get -y dist-upgrade &>/dev/null -msg_ok "Updated Proxmox VE 7 (⚠ Reboot Recommended)" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Updating Proxmox VE 7 (Patience)" + apt-get update &>/dev/null + apt-get -y dist-upgrade &>/dev/null + msg_ok "Updated Proxmox VE 7 (⚠ Reboot Recommended)" fi read -r -p "Reboot Proxmox VE 7 now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -msg_info "Rebooting Proxmox VE 7" -sleep 2 -msg_ok "Completed Post Install Routines" -reboot +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + msg_info "Rebooting Proxmox VE 7" + sleep 2 + msg_ok "Completed Post Install Routines" + reboot fi sleep 2 diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 8eace5bd..4a5821b2 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -4,14 +4,14 @@ set -e while true; do read -p "View CPU Scaling Governors. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e " + echo -e " _____ _____ _ _ / ____| __ \| | | | | | | |__) | | | | @@ -21,16 +21,16 @@ echo -e " Scaling Governors " } -show_menu(){ - CL=`echo "\033[m"` - GN=`echo "\033[32m"` - BL=`echo "\033[36m"` - YW=`echo "\033[33m"` - fgred=`echo "\033[31m"` -header_info +show_menu() { + CL=$(echo "\033[m") + GN=$(echo "\033[32m") + BL=$(echo "\033[36m") + YW=$(echo "\033[33m") + fgred=$(echo "\033[31m") + header_info CK=$(uname -r) IP=$(hostname -I) -# MAC=$(cat /sys/class/net/eno1/address) + # MAC=$(cat /sys/class/net/eno1/address) ACSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors) CCSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) echo -e "${YW}Proxmox IP ${BL}${IP}${CL}" @@ -41,7 +41,7 @@ header_info echo -e "\n${YW}Available CPU Scaling Governors ${BL}${ACSG}${CL}" - + echo -e "\n${YW}Current CPU Scaling Governor ${BL}${CCSG}${CL}" printf "\n ${fgred}Only Select Available CPU Scaling Governors From Above${CL}\n \n" @@ -57,43 +57,51 @@ header_info } clear show_menu -while [ $opt != '' ] - do +while [ $opt != '' ]; do if [ $opt = '' ]; then - exit; + exit else - case $opt in - 1) echo "conservative" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + case $opt in + 1) + echo "conservative" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 2) echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 2) + echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 3) echo "userspace" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 3) + echo "userspace" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 4) echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 4) + echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 5) echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 5) + echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 6) echo "schedutil" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 6) + echo "schedutil" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - show_menu; - ;; - esac + ;; + x) + exit + ;; + \n) + exit + ;; + *) + clear + show_menu + ;; + esac fi - done +done diff --git a/misc/technitiumdns-update.sh b/misc/technitiumdns-update.sh index 3cb30e42..0cfbd7f8 100644 --- a/misc/technitiumdns-update.sh +++ b/misc/technitiumdns-update.sh @@ -7,61 +7,52 @@ dnsUrl="https://download.technitium.com/dns/DnsServerPortable.tar.gz" mkdir -p $dnsDir installLog="$dnsDir/install.log" -echo "" > $installLog +echo "" >$installLog echo "" echo "===============================" echo "Technitium DNS Server Update" echo "===============================" -if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 6.0."; -then +if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 6.0."; then dotnetFound="yes" else dotnetFound="no" fi - if [ -d $dotnetDir ] - then - dotnetUpdate="yes" - echo "Updating .NET 6 Runtime..." +if [ -d $dotnetDir ]; then + dotnetUpdate="yes" + echo "Updating .NET 6 Runtime..." +fi + +curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 6.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >>$installLog 2>&1 + +if [ ! -f "/usr/bin/dotnet" ]; then + ln -s $dotnetDir/dotnet /usr/bin >>$installLog 2>&1 +fi + +if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 6.0."; then + if [ "$dotnetUpdate" = "yes" ]; then + echo ".NET 6 Runtime was updated successfully!" fi +else + echo "Failed to update .NET 6 Runtime. Please try again." + exit 1 +fi - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 6.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >> $installLog 2>&1 - - if [ ! -f "/usr/bin/dotnet" ] - then - ln -s $dotnetDir/dotnet /usr/bin >> $installLog 2>&1 - fi - - if dotnet --list-runtimes 2> /dev/null | grep -q "Microsoft.NETCore.App 6.0."; - then - if [ "$dotnetUpdate" = "yes" ] - then - echo ".NET 6 Runtime was updated successfully!" - fi - else - echo "Failed to update .NET 6 Runtime. Please try again." - exit 1 - fi - -if curl -o $dnsTar --fail $dnsUrl >> $installLog 2>&1 -then - if [ -d $dnsDir ] - then +if curl -o $dnsTar --fail $dnsUrl >>$installLog 2>&1; then + if [ -d $dnsDir ]; then echo "Updating Technitium DNS Server..." fi - - tar -zxf $dnsTar -C $dnsDir >> $installLog 2>&1 - - if [ "$(ps --no-headers -o comm 1 | tr -d '\n')" = "systemd" ] - then - if [ -f "/etc/systemd/system/dns.service" ] - then + + tar -zxf $dnsTar -C $dnsDir >>$installLog 2>&1 + + if [ "$(ps --no-headers -o comm 1 | tr -d '\n')" = "systemd" ]; then + if [ -f "/etc/systemd/system/dns.service" ]; then echo "Restarting systemd service..." - systemctl restart dns.service >> $installLog 2>&1 + systemctl restart dns.service >>$installLog 2>&1 fi - + echo "" echo "Technitium DNS Server was updated successfully!" else diff --git a/misc/trilium-update.sh b/misc/trilium-update.sh index eb9a1d88..5670c49e 100644 --- a/misc/trilium-update.sh +++ b/misc/trilium-update.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") function update_info { -cat << "EOF" + cat <<"EOF" ______ _ ___ /_ __/____(_) (_)_ ______ ___ / / / ___/ / / / / / / __ `__ \ @@ -23,9 +23,9 @@ update_info while true; do read -p "This will Update Trilium to v$RELEASE. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done sleep 2 diff --git a/misc/unifi-update.sh b/misc/unifi-update.sh index a7a19aae..6befdb24 100644 --- a/misc/unifi-update.sh +++ b/misc/unifi-update.sh @@ -1,22 +1,22 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") APP="UniFi Update" while true; do read -p "This will run ${APP}. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${RD} + echo -e "${RD} _ _ _ ______ _ | | | | (_) ____(_) | | | |_ __ _| |__ _ @@ -30,4 +30,3 @@ ${CL}" header_info sleep 3 wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh && bash unifi-update.sh - diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 369631f4..3c0a4f27 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -1,22 +1,22 @@ #!/bin/bash set -e -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") while true; do - read -p "This Will Update All LXC Containers. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "This Will Update All LXC Containers. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done clear function header_info { -echo -e "${BL} + echo -e "${BL} _ _ _____ _____ _______ ______ | | | | __ \| __ \ /\|__ __| ____| | | | | |__) | | | | / \ | | | |__ @@ -39,34 +39,33 @@ function update_container() { } read -p "Skip stopped containers? " -n 1 -r echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - skip=no +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + skip=no else - skip=yes + skip=yes fi -for container in $containers -do - status=`pct status $container` - if [ "$skip" == "no" ]; then - if [ "$status" == "status: stopped" ]; then - echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" - pct start $container - echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" - sleep 5 - update_container $container - echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" - pct shutdown $container & - elif [ "$status" == "status: running" ]; then - update_container $container +for container in $containers; do + status=$(pct status $container) + if [ "$skip" == "no" ]; then + if [ "$status" == "status: stopped" ]; then + echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" + pct start $container + echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" + sleep 5 + update_container $container + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + update_container $container + fi fi - fi - if [ "$skip" == "yes" ]; then - if [ "$status" == "status: running" ]; then - update_container $container + if [ "$skip" == "yes" ]; then + if [ "$status" == "status: running" ]; then + update_container $container + fi fi - fi -done; wait +done +wait echo -e "${GN} Finished, All Containers Updated. ${CL} \n" diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh index acccf4b2..be946ea7 100644 --- a/misc/uptimekuma-update.sh +++ b/misc/uptimekuma-update.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -ex LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -14,14 +14,14 @@ APP="Uptime Kuma" while true; do read -p "This will Update ${APP} to ${LATEST}. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e "${DGN} + echo -e "${DGN} _ _ _ _ _ __ | | | | | | (_) | |/ / | | | |_v3_ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ @@ -45,7 +45,10 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -if [ ! -d "/opt/uptime-kuma" ]; then echo -e "No Uptime Kuma Directory Found."; exit; fi +if [ ! -d "/opt/uptime-kuma" ]; then + echo -e "No Uptime Kuma Directory Found." + exit +fi msg_info "Stopping ${APP}" sudo systemctl stop uptime-kuma &>/dev/null diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index 8b75c792..b8623d3b 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash echo -e "\e[1;33m This script will allow USB passthrough to a PRIVILEGED LXC Container ONLY\e[0m" while true; do - read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit @@ -45,7 +45,7 @@ for char_dev in ${CHAR_DEVS[@]}; do CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" done -read -r -d '' HOOK_SCRIPT <<- EOF || true +read -r -d '' HOOK_SCRIPT <<-EOF || true for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; mkdir -p \$(dirname \${LXC_ROOTFS_MOUNT}\${dev}); @@ -63,7 +63,7 @@ CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH -cat <> $CTID_CONFIG_PATH +cat <>$CTID_CONFIG_PATH lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 91159e1b..43bfa368 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash -VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') +VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") function update_info { -echo -e "${BL} + echo -e "${BL} __ __ _ _ _ \ \ / / | | | | | \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ @@ -24,9 +24,9 @@ update_info while true; do read -p "This will Update Vaultwarden to $VAULT (set 2vCPU 2048MiB RAM Min.). Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done sleep 2 diff --git a/misc/web-vault-update.sh b/misc/web-vault-update.sh index a6b5eaf8..5b2e61b9 100644 --- a/misc/web-vault-update.sh +++ b/misc/web-vault-update.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash -VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') +VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") function update_info { -echo -e "${BL} + echo -e "${BL} __ __ _ _ _ \ \ / / | | | | | \ \ /\ / /__| |__ ________ ____ _ _ _| | |_ @@ -23,9 +23,9 @@ update_info while true; do read -p "This will Update Web-Vault to $VWRELEASE. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done sleep 2 @@ -36,9 +36,9 @@ sleep 1 echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null if [ -d "/var/lib/vaultwarden" ]; then -tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null -else -tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null + tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null +else + tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null fi echo -e "${GN} Cleaning up... ${CL}" diff --git a/misc/webmin.sh b/misc/webmin.sh index d5dca0de..b997df5f 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -1,17 +1,17 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") while true; do read -p "This will Install Webmin, Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear @@ -34,7 +34,6 @@ echo -en "${GN} Setting Default Webmin usermame & password to root... " rm -rf /root/webmin_2.000_all.deb echo -e "${CM}${CL} \r" IP=$(hostname -I | cut -f1 -d ' ') -echo -e "Successfully Installed!! Webmin should be reachable by going to https://${IP}:10000" - +echo -e "Successfully Installed!! Webmin should be reachable by going to https://${IP}:10000" # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" diff --git a/misc/z2m-copy-data.sh b/misc/z2m-copy-data.sh index a698ef35..ad29d1c2 100644 --- a/misc/z2m-copy-data.sh +++ b/misc/z2m-copy-data.sh @@ -3,12 +3,12 @@ # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" while true; do - read -p "Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done set -o errexit set -o errtrace @@ -58,28 +58,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Zigbee2MQTT LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich Zigbee2MQTT LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Zigbee2MQTT LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich Zigbee2MQTT LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.23" 13 50 || exit info "Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'" @@ -89,13 +89,13 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then fi msg "Mounting Container Disks..." DATA_PATH=/opt/zigbee2mqtt/data/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || die "Zigbee2igbee2MQTT directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || \ +[ -d "${CTID_TO_PATH}${DATA_PATH}" ] || die "Zigbee2MQTT directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} diff --git a/misc/zwave-copy-data.sh b/misc/zwave-copy-data.sh index 4b6de0d1..193a027e 100644 --- a/misc/zwave-copy-data.sh +++ b/misc/zwave-copy-data.sh @@ -3,12 +3,12 @@ # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwave-copy-data.sh)" while true; do - read -p "Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac + read -p "Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac done clear set -o errexit @@ -59,28 +59,28 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - CTID_MENU+=( "$TAG" "$ITEM " "OFF" ) + CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Zwavejs2MQTT LXC would you like to copy FROM?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich Zwavejs2MQTT LXC would you like to copy FROM?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do CTID_TO=$(whiptail --title "$TITLE" --radiolist \ - "\nWhich Z-wave JS UI LXC would you like to copy TO?\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nWhich Z-wave JS UI LXC would you like to copy TO?\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done for i in ${!CTID_MENU[@]}; do - [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && \ - CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) - [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && \ - CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i+1]}) + [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && + CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) + [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && + CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done whiptail --defaultno --title "$TITLE" --yesno \ -"Are you sure you want to copy data between the following LXCs? + "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.09.21" 13 50 || exit info "Zwavejs2MQTT Data from '$CTID_FROM' to '$CTID_TO'" @@ -91,13 +91,13 @@ fi msg "Mounting Container Disks..." DATA_PATH=/opt/zwavejs2mqtt/store/ DATA_PATH_NEW=/opt/zwave-js-ui/store/ -CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." -[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || \ +[ -d "${CTID_FROM_PATH}${DATA_PATH}" ] || die "Zwavejs2MQTT directories in '$CTID_FROM' not found." -CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || \ +CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${DATA_PATH_NEW}" ] || \ +[ -d "${CTID_TO_PATH}${DATA_PATH_NEW}" ] || die "Zwavejs2MQTT directories in '$CTID_TO' not found." #rm -rf ${CTID_TO_PATH}${DATA_PATH} @@ -117,4 +117,3 @@ rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PA echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." - diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh index 1d669dcf..e52fad51 100644 --- a/misc/zwave-js-ui-update.sh +++ b/misc/zwave-js-ui-update.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') set -e -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" @@ -25,7 +25,7 @@ function msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } clear -cat << "EOF" +cat <<"EOF" _____ _______ __ ______ /__ /_ ______ __ _____ / / ___/ / / / / _/ / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / @@ -38,12 +38,15 @@ EOF while true; do read -p "This will update ZWave JS UI to $RELEASE. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done -if [ ! -d /opt/zwave-js-ui ]; then msg_error "No Zwave JS UI Install Detected!"; exit; fi +if [ ! -d /opt/zwave-js-ui ]; then + msg_error "No Zwave JS UI Install Detected!" + exit +fi msg_info "Stopping Z-wave JS UI" systemctl stop zwave-js-ui.service @@ -56,7 +59,7 @@ unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null msg_ok "Updated Z-wave JS UI" msg_info "Updating Z-wave JS UI service file" -cat << EOF > /etc/systemd/system/zwave-js-ui.service +cat </etc/systemd/system/zwave-js-ui.service [Unit] Description=zwave-js-ui Wants=network-online.target diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index 8b34a502..e610ca68 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -81,24 +83,24 @@ msg_info "Installing AdGuard Home" curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null msg_ok "Installed AdGuard Home" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index e66fbd27..0f063c0b 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -84,7 +86,7 @@ wget https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELE mkdir -p /opt/blocky tar -xf blocky_0.19_Linux_x86_64.tar.gz -C /opt/blocky rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz -cat << EOF > /opt/blocky/config.yml +cat </opt/blocky/config.yml upstream: # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) @@ -324,7 +326,7 @@ EOF msg_ok "Installed Blocky" msg_info "Creating Service" -cat << EOF > /etc/systemd/system/blocky.service +cat </etc/systemd/system/blocky.service [Unit] Description=Blocky After=network.target @@ -338,23 +340,23 @@ EOF systemctl enable --now blocky msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index 4e582f0e..f5eaa998 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -90,24 +92,24 @@ msg_info "Installing CasaOS (Patience)" wget -qO- https://get.casaos.io | bash &>/dev/null msg_ok "Installed CasaOS" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index bd9e8b13..d635a284 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -83,24 +85,24 @@ wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_am sudo dpkg -i daemonsync_2.2.0.0059_amd64.deb &>/dev/null msg_ok "Installed Daemon Sync Server" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 0029e8a7..76f44974 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -85,7 +87,7 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" sudo apt-get install -y nodejs git make g++ gcc &>/dev/null msg_ok "Installed Node.js" - + msg_info "Installing Yarn" npm install --global yarn &>/dev/null msg_ok "Installed Yarn" @@ -99,7 +101,7 @@ yarn build &>/dev/null msg_ok "Installed Dashy" msg_info "Creating Service" -cat < /etc/systemd/system/dashy.service +cat </etc/systemd/system/dashy.service [Unit] Description=dashy @@ -114,24 +116,24 @@ sudo systemctl start dashy &>/dev/null sudo systemctl enable dashy &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/debian-install.sh b/setup/debian-install.sh index db18f9b2..1f8c6a20 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -76,23 +78,23 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index ee6d8795..9b16f561 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -103,28 +105,28 @@ RestartSec=30 AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl start deconz systemctl enable deconz &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/docker-install.sh b/setup/docker-install.sh index e70dd50c..d28872cb 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -78,7 +80,7 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 } DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") @@ -97,62 +99,60 @@ sh <(curl -sSL https://get.docker.com) &>/dev/null msg_ok "Installed Docker $DOCKER_LATEST_VERSION" read -r -p "Would you like to add Portainer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -PORTAINER="Y" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + PORTAINER="Y" else -PORTAINER="N" + PORTAINER="N" fi if [[ $PORTAINER == "Y" ]]; then -msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null -msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" + msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" + docker volume create portainer_data >/dev/null + docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest &>/dev/null + msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" fi read -r -p "Would you like to add Docker Compose? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -DOCKER_COMPOSE="Y" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + DOCKER_COMPOSE="Y" else -DOCKER_COMPOSE="N" + DOCKER_COMPOSE="N" fi if [[ $DOCKER_COMPOSE == "Y" ]]; then -msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins - curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose -msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/emby-install.sh b/setup/emby-install.sh index a673c2c9..9377cfb0 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -78,16 +80,16 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then -msg_info "Setting Up Hardware Acceleration" -apt-get -y install \ + msg_info "Setting Up Hardware Acceleration" + apt-get -y install \ va-driver-all \ ocl-icd-libopencl1 \ beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* -msg_ok "Set Up Hardware Acceleration" + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" fi LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) @@ -97,23 +99,23 @@ wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/e dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null msg_ok "Installed Emby" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 601fd5d2..33c85add 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -82,23 +84,23 @@ sudo apt-get install -y emqx >/dev/null systemctl enable --now emqx msg_ok "Installed EMQX" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 625ea8b2..7c73b3e3 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -98,28 +100,28 @@ ExecStart=/usr/local/bin/esphome /root/config/ dashboard Restart=always User=root [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable esphomeDashboard.service &>/dev/null systemctl start esphomeDashboard msg_ok "Installed ESPHome Dashboard" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 4b270cf6..fb212972 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -89,24 +91,24 @@ msg_info "Installing Grafana" apt-get update &>/dev/null apt-get install -y grafana &>/dev/null msg_ok "Installed Grafana" - -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi systemctl start grafana-server systemctl enable grafana-server.service &>/dev/null diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 6342b1a2..d01878f5 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -92,7 +94,7 @@ chown -R www-data:www-data /var/www/html cp /var/www/html/config-dist.php /var/www/html/data/config.php chmod +x /var/www/html/update.sh -cat < /etc/apache2/sites-available/grocy.conf +cat </etc/apache2/sites-available/grocy.conf ServerAdmin webmaster@localhost DocumentRoot /var/www/html/public @@ -112,23 +114,23 @@ a2enmod rewrite &>/dev/null systemctl reload apache2 msg_ok "Installed grocy" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 02c3a90a..3b63a1fb 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -87,9 +89,9 @@ RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releas msg_info "Installing Heimdall Dashboard ${RELEASE}" curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') rm -rf ${RELEASE}.tar.gz mv Heimdall-${VER} /opt/Heimdall msg_ok "Installed Heimdall Dashboard ${RELEASE}" @@ -110,28 +112,28 @@ ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 TimeoutStopSec=30 [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path sudo systemctl enable --now heimdall.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 6602f5ad..5f24cdc9 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -73,31 +75,31 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get install -y \ - python3 \ - python3-dev \ - python3-venv \ - python3-pip \ - bluez \ - libffi-dev \ - libssl-dev \ - libjpeg-dev \ - libpcap-dev \ - zlib1g-dev \ - autoconf \ - build-essential \ - libopenjp2-7 \ - libtiff5 \ - libturbojpeg0-dev \ - tzdata \ - curl \ - sudo &>/dev/null + python3 \ + python3-dev \ + python3-venv \ + python3-pip \ + bluez \ + libffi-dev \ + libssl-dev \ + libjpeg-dev \ + libpcap-dev \ + zlib1g-dev \ + autoconf \ + build-essential \ + libopenjp2-7 \ + libtiff5 \ + libturbojpeg0-dev \ + tzdata \ + curl \ + sudo &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Home Assistant-Core" -mkdir /srv/homeassistant +mkdir /srv/homeassistant cd /srv/homeassistant python3 -m venv . -source bin/activate +source bin/activate python3 -m pip install wheel &>/dev/null pip3 install homeassistant &>/dev/null pip3 install Cython &>/dev/null @@ -106,7 +108,7 @@ pip3 install psycopg2-binary &>/dev/null msg_ok "Installed Home Assistant-Core" msg_info "Creating Service" -cat << EOF > /etc/systemd/system/homeassistant.service +cat </etc/systemd/system/homeassistant.service [Unit] Description=Home Assistant @@ -122,23 +124,23 @@ EOF systemctl enable homeassistant &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 0d0d8952..ade97b6d 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -82,7 +84,7 @@ apt-get install -y python3-pip &>/dev/null msg_ok "Installed pip3" get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 } DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") @@ -317,23 +319,23 @@ EOF sudo chmod +x /root/update-containers.sh msg_ok "Created Update Menu Script" mkdir /root/hass_config -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 4fad6168..c363270c 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -93,24 +95,24 @@ msg_info "Creating Service" sudo hb-service install --user homebridge &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 31ff0c7a..294dccde 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -108,27 +110,27 @@ User=root WorkingDirectory=/opt/homepage/ ExecStart=pnpm start [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now homepage &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index e2a082fe..30a1d886 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -86,54 +88,52 @@ echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo msg_ok "Set up InfluxDB Repository" read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt -if [[ $prompt == "2" ]] -then -INFLUX="2" +if [[ $prompt == "2" ]]; then + INFLUX="2" else -INFLUX="1" + INFLUX="1" fi msg_info "Installing InfluxDB" apt-get update &>/dev/null if [[ $INFLUX == "2" ]]; then -apt-get install -y influxdb2 &>/dev/null + apt-get install -y influxdb2 &>/dev/null else -apt-get install -y influxdb &>/dev/null + apt-get install -y influxdb &>/dev/null fi msg_ok "Installed InfluxDB" read -r -p "Would you like to add Telegraf? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -TELEGRAF="Y" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + TELEGRAF="Y" else -TELEGRAF="N" + TELEGRAF="N" fi if [[ $TELEGRAF == "Y" ]]; then -msg_info "Installing Telegraf" -apt-get install -y telegraf &>/dev/null -msg_ok "Installed Telegraf" + msg_info "Installing Telegraf" + apt-get install -y telegraf &>/dev/null + msg_ok "Installed Telegraf" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 2cbe7067..46e2eae6 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -81,24 +83,24 @@ msg_info "Installing ioBroker (10 min)" curl -sLf https://iobroker.net/install.sh | bash - &>/dev/null msg_ok "Installed ioBroker" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 82acbffa..ba151b5d 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -80,22 +82,22 @@ apt-get install -y software-properties-common &>/dev/null msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then -msg_info "Setting Up Hardware Acceleration" -apt-get -y install \ + msg_info "Setting Up Hardware Acceleration" + apt-get -y install \ va-driver-all \ ocl-icd-libopencl1 \ beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* -msg_ok "Set Up Hardware Acceleration" + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" fi msg_info "Setting Up Jellyfin Repository" sudo add-apt-repository universe -y &>/dev/null wget -q -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null +echo "deb [arch=$(dpkg --print-architecture)] https://repo.jellyfin.org/ubuntu $(lsb_release -c -s) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null msg_ok "Set Up Jellyfin Repository" msg_info "Installing Jellyfin" @@ -105,7 +107,7 @@ apt install jellyfin-ffmpeg -y &>/dev/null msg_ok "Installed Jellyfin" msg_info "Creating Service" -cat << 'EOF' > /lib/systemd/system/jellyfin.service +cat <<'EOF' >/lib/systemd/system/jellyfin.service [Unit] Description = Jellyfin Media Server After = network.target @@ -122,23 +124,23 @@ EOF ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index 9397fa7a..d7fdb4c0 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -78,9 +80,9 @@ apt-get install -y sudo &>/dev/null apt-get install -y openjdk-11-jdk &>/dev/null msg_ok "Installed Dependencies" -RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ +RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') msg_info "Installing Keycloak v$RELEASE" cd /opt @@ -99,27 +101,27 @@ User=root WorkingDirectory=/opt/keycloak ExecStart=/opt/keycloak/bin/kc.sh start-dev [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now keycloak.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index 4d3cd89f..cf71719d 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -20,50 +20,52 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -94,7 +96,7 @@ msg_info "Installing MagicMirror" cd /opt/magicmirror &>/dev/null npm install --only=prod --omit=dev &>/dev/null -cat < /opt/magicmirror/config/config.js +cat </opt/magicmirror/config/config.js let config = { address: "0.0.0.0", port: 8080, @@ -201,27 +203,27 @@ WorkingDirectory=/opt/magicmirror/ ExecStart=/usr/bin/node serveronly [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now magicmirror &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 53b8c955..1aa22a35 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -84,38 +86,37 @@ apt-get install -y mariadb-server &>/dev/null msg_ok "Installed MariaDB" read -r -p "Would you like to add Adminer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -ADMINER="Y" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + ADMINER="Y" else -ADMINER="N" + ADMINER="N" fi if [[ $ADMINER == "Y" ]]; then -msg_info "Installing Adminer" -sudo apt install adminer -y &>/dev/null -sudo a2enconf adminer &>/dev/null -sudo systemctl reload apache2 &>/dev/null -msg_ok "Installed Adminer" + msg_info "Installing Adminer" + sudo apt install adminer -y &>/dev/null + sudo a2enconf adminer &>/dev/null + sudo systemctl reload apache2 &>/dev/null + msg_ok "Installed Adminer" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 6c6b0149..8f7a4095 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -92,24 +94,24 @@ npm install meshcentral &>/dev/null node node_modules/meshcentral --install &>/dev/null msg_ok "Installed MeshCentral" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 08d80adc..6fb9e71c 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -79,56 +81,56 @@ apt-get install -y cifs-utils &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Motion" - apt-get install motion -y &>/dev/null - systemctl stop motion &>/dev/null - systemctl disable motion &>/dev/null +apt-get install motion -y &>/dev/null +systemctl stop motion &>/dev/null +systemctl disable motion &>/dev/null msg_ok "Installed Motion" msg_info "Installing FFmpeg" - apt-get install ffmpeg v4l-utils -y &>/dev/null +apt-get install ffmpeg v4l-utils -y &>/dev/null msg_ok "Installed FFmpeg" msg_info "Installing Python" - apt-get update &>/dev/null - apt-get install python2 -y &>/dev/null - curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null - python2 get-pip.py &>/dev/null - apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null - apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null - msg_ok "Installed Python" - +apt-get update &>/dev/null +apt-get install python2 -y &>/dev/null +curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null +python2 get-pip.py &>/dev/null +apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null +apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null +msg_ok "Installed Python" + msg_info "Installing MotionEye" - apt-get update &>/dev/null - sudo pip install motioneye &>/dev/null - mkdir -p /etc/motioneye - cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf - mkdir -p /var/lib/motioneye +apt-get update &>/dev/null +sudo pip install motioneye &>/dev/null +mkdir -p /etc/motioneye +cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf +mkdir -p /var/lib/motioneye msg_ok "Installed MotionEye" -msg_info "Creating Service" - cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service &>/dev/null - systemctl enable motioneye &>/dev/null - systemctl start motioneye -msg_ok "Created Service" +msg_info "Creating Service" +cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service &>/dev/null +systemctl enable motioneye &>/dev/null +systemctl start motioneye +msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index f39c7fcc..225e6bd8 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -88,24 +90,24 @@ apt-get -y install mosquitto &>/dev/null apt-get -y install mosquitto-clients &>/dev/null msg_ok "Installed Mosquitto MQTT Broker" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 21fd5f49..00e48f8b 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -90,7 +92,7 @@ npm install --global n8n &>/dev/null msg_ok "Installed n8n" msg_info "Creating Service" -cat < /etc/systemd/system/n8n.service +cat </etc/systemd/system/n8n.service [Unit] Description=n8n @@ -104,23 +106,23 @@ sudo systemctl start n8n &>/dev/null sudo systemctl enable n8n &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index b04cdda9..dabdf703 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -77,18 +79,18 @@ apt-get install -y sudo &>/dev/null apt-get install -y ffmpeg &>/dev/null msg_ok "Installed Dependencies" -RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') msg_info "Installing Navidrome" sudo install -d -o root -g root /opt/navidrome sudo install -d -o root -g root /var/lib/navidrome wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null sudo tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null -sudo chown -R root:root /opt/navidrome +sudo chown -R root:root /opt/navidrome mkdir -p /music -cat < /var/lib/navidrome/navidrome.toml +cat </var/lib/navidrome/navidrome.toml MusicFolder = '/music' EOF msg_ok "Installed Navidrome" @@ -125,29 +127,29 @@ ReadWritePaths=/var/lib/navidrome ProtectSystem=full [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl daemon-reload systemctl enable --now navidrome.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index c38cef27..195dbc05 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -80,23 +82,23 @@ msg_info "Installing NextCloudPi (Patience)" curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null msg_ok "Installed NextCloudPi" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 37cd3c92..a790811d 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -75,35 +77,35 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get update &>/dev/null apt-get -y install \ - sudo \ - curl \ - gnupg \ - make \ - g++ \ - gcc \ - ca-certificates \ - apache2-utils \ - logrotate \ - build-essential \ - python3-dev \ - git \ - lsb-release &>/dev/null + sudo \ + curl \ + gnupg \ + make \ + g++ \ + gcc \ + ca-certificates \ + apache2-utils \ + logrotate \ + build-essential \ + python3-dev \ + git \ + lsb-release &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Python" - apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null - pip3 install --upgrade setuptools &>/dev/null - pip3 install --upgrade pip &>/dev/null - python3 -m venv /opt/certbot/ &>/dev/null - if [ "$(getconf LONG_BIT)" = "32" ]; then - python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null - fi - python3 -m pip install --no-cache-dir cffi certbot &>/dev/null +apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null +pip3 install --upgrade setuptools &>/dev/null +pip3 install --upgrade pip &>/dev/null +python3 -m venv /opt/certbot/ &>/dev/null +if [ "$(getconf LONG_BIT)" = "32" ]; then + python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null +fi +python3 -m pip install --no-cache-dir cffi certbot &>/dev/null msg_ok "Installed Python" msg_info "Installing Openresty" wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null -codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null +codename=$(grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release) &>/dev/null echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null apt-get -y update &>/dev/null apt-get -y install --no-install-recommends openresty &>/dev/null @@ -116,14 +118,14 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" - + msg_info "Installing Yarn" npm install --global yarn &>/dev/null msg_ok "Installed Yarn" -RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') \ +RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') msg_info "Downloading Nginx Proxy Manager v${RELEASE}" wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null @@ -154,26 +156,26 @@ ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf rm -f /etc/nginx/conf.d/dev.conf mkdir -p /tmp/nginx/body \ -/run/nginx \ -/data/nginx \ -/data/custom_ssl \ -/data/logs \ -/data/access \ -/data/nginx/default_host \ -/data/nginx/default_www \ -/data/nginx/proxy_host \ -/data/nginx/redirection_host \ -/data/nginx/stream \ -/data/nginx/dead_host \ -/data/nginx/temp \ -/var/lib/nginx/cache/public \ -/var/lib/nginx/cache/private \ -/var/cache/nginx/proxy_temp + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp chmod -R 777 /var/cache/nginx chown root /tmp/nginx -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then echo -en "${GN} Generating dummy SSL Certificate... " @@ -197,7 +199,7 @@ msg_ok "Built Frontend" msg_info "Initializing Backend" rm -rf /app/config/default.json &>/dev/null if [ ! -f /app/config/production.json ]; then -cat << 'EOF' > /app/config/production.json + cat <<'EOF' >/app/config/production.json { "database": { "engine": "knex-native", @@ -217,7 +219,7 @@ yarn install --network-timeout=30000 &>/dev/null msg_ok "Initialized Backend" msg_info "Creating Service" -cat << 'EOF' > /lib/systemd/system/npm.service +cat <<'EOF' >/lib/systemd/system/npm.service [Unit] Description=Nginx Proxy Manager After=network.target @@ -236,23 +238,23 @@ WantedBy=multi-user.target EOF msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Starting Services" systemctl enable npm &>/dev/null diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 37e2fb97..6d29b402 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -106,28 +108,28 @@ WorkingDirectory=/opt/nocodb ExecStart=/usr/bin/npm start [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now nocodb.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index ea9a4998..1b382cf1 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -108,28 +110,28 @@ User=root Group=root [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now nodered.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 9a3705aa..5cdb3b12 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -87,23 +89,23 @@ wget -qL https://static.tp-link.com/upload/software/2022/202208/20220822/Omada_S sudo dpkg -i Omada_SDN_Controller_v5.5.6_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/omv-install.sh b/setup/omv-install.sh index 073653af..e6b6b839 100644 --- a/setup/omv-install.sh +++ b/setup/omv-install.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -30,29 +30,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -82,7 +84,7 @@ msg_info "Installing OpenMediaVault (Patience)" wget -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key &>/dev/null apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" &>/dev/null -cat <> /etc/apt/sources.list.d/openmediavault.list +cat <>/etc/apt/sources.list.d/openmediavault.list deb https://packages.openmediavault.org/public shaitan main # deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main ## Uncomment the following line to add software from the proposed repository. @@ -99,23 +101,23 @@ apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-change-he omv-confdbadm populate msg_ok "Installed OpenMediaVault" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 65a811d4..02ef935f 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -88,9 +90,9 @@ apt-get -y install zulu11-jdk &>/dev/null msg_ok "Installed Azul Zulu" msg_info "Installing openHAB" -curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor > openhab.gpg -mv openhab.gpg /usr/share/keyrings -chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg +curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor >openhab.gpg +mv openhab.gpg /usr/share/keyrings +chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg echo 'deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main' | tee /etc/apt/sources.list.d/openhab.list &>/dev/null apt update &>/dev/null apt-get -y install openhab &>/dev/null @@ -99,23 +101,23 @@ systemctl enable openhab.service &>/dev/null systemctl start openhab.service msg_ok "Installed openHAB" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index db0a2ff6..01f85926 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -20,50 +20,52 @@ alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi done msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -126,19 +128,19 @@ apt-get install -y --no-install-recommends \ git clone https://github.com/agl/jbig2enc /opt/jbig2enc &>/dev/null cd /opt/jbig2enc -/bin/bash -c "./autogen.sh" &>/dev/null && \ -/bin/bash -c "./configure && make" &>/dev/null && \ -/bin/bash -c "make install" &>/dev/null -rm -rf /opt/jbig2enc +/bin/bash -c "./autogen.sh" &>/dev/null && + /bin/bash -c "./configure && make" &>/dev/null && + /bin/bash -c "make install" &>/dev/null +rm -rf /opt/jbig2enc msg_ok "Installed JBIG2" msg_info "Downloading Paperless-ngx" Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) -cd /opt && \ -wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz &>/dev/null && \ -tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ &>/dev/null && \ -mv paperless-ngx paperless && \ -rm paperless-ngx-$Paperlessngx.tar.xz +cd /opt && + wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz &>/dev/null && + tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ &>/dev/null && + mv paperless-ngx paperless && + rm paperless-ngx-$Paperlessngx.tar.xz cd /opt/paperless ## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file @@ -156,12 +158,12 @@ DB_NAME=paperlessdb sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" &>/dev/null sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" &>/dev/null -echo "Paperless-ngx Database User" >> ~/paperless.creds -echo $DB_USER >> ~/paperless.creds -echo "Paperless-ngx Database Password" >> ~/paperless.creds -echo $DB_PASS >> ~/paperless.creds -echo "Paperless-ngx Database Name" >> ~/paperless.creds -echo $DB_NAME >> ~/paperless.creds +echo "Paperless-ngx Database User" >>~/paperless.creds +echo $DB_USER >>~/paperless.creds +echo "Paperless-ngx Database Password" >>~/paperless.creds +echo $DB_PASS >>~/paperless.creds +echo "Paperless-ngx Database Name" >>~/paperless.creds +echo $DB_NAME >>~/paperless.creds /bin/bash -c "mkdir -p {consume,media}" @@ -176,7 +178,7 @@ msg_ok "Set up database" msg_info "Setting up admin Paperless-ngx User & Password" ## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations -cat << EOF | python3 /opt/paperless/src/manage.py shell +cat <> ~/paperless.creds -echo "Paperless-ngx WebUI User" >> ~/paperless.creds -echo admin >> ~/paperless.creds -echo "Paperless-ngx WebUI Password" >> ~/paperless.creds -echo $DB_PASS >> ~/paperless.creds +echo "" >>~/paperless.creds +echo "Paperless-ngx WebUI User" >>~/paperless.creds +echo admin >>~/paperless.creds +echo "Paperless-ngx WebUI Password" >>~/paperless.creds +echo $DB_PASS >>~/paperless.creds msg_ok "Set up admin Paperless-ngx User & Password" -cat << EOF > /etc/systemd/system/paperless-scheduler.service +cat </etc/systemd/system/paperless-scheduler.service [Unit] Description=Paperless consumer Requires=redis.service @@ -205,7 +207,7 @@ ExecStart=python3 manage.py qcluster WantedBy=multi-user.target EOF -cat << EOF > /etc/systemd/system/paperless-consumer.service +cat </etc/systemd/system/paperless-consumer.service [Unit] Description=Paperless consumer Requires=redis.service @@ -218,7 +220,7 @@ ExecStart=python3 manage.py document_consumer WantedBy=multi-user.target EOF -cat << EOF > /etc/systemd/system/paperless-webserver.service +cat </etc/systemd/system/paperless-webserver.service [Unit] Description=Paperless webserver After=network.target @@ -240,23 +242,23 @@ systemctl enable --now paperless-consumer paperless-webserver paperless-schedule msg_ok "Finished installing Paperless-ngx" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index a2027d0e..67015a34 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -30,30 +30,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -62,9 +61,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -116,10 +118,10 @@ msg_info "Installing Tensorflow" if [[ "$AVX" =~ avx2 ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - elif [[ "$AVX" =~ avx ]]; then +elif [[ "$AVX" =~ avx ]]; then wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - else +else wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null fi @@ -150,7 +152,7 @@ PHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/' PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -" > $env_path +" >$env_path msg_info "Creating Service" service_path="/etc/systemd/system/photoprism.service" @@ -168,36 +170,36 @@ ExecStart=/opt/photoprism/bin/photoprism up -d ExecStop=/opt/photoprism/bin/photoprism down [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* \ -/photoprism \ -/go1.19.2.linux-amd64.tar.gz \ -/libtensorflow-linux-avx2-1.15.2.tar.gz \ -/libtensorflow-linux-avx-1.15.2.tar.gz \ -/libtensorflow-linux-cpu-1.15.2.tar.gz + /photoprism \ + /go1.19.2.linux-amd64.tar.gz \ + /libtensorflow-linux-avx2-1.15.2.tar.gz \ + /libtensorflow-linux-avx-1.15.2.tar.gz \ + /libtensorflow-linux-cpu-1.15.2.tar.gz msg_ok "Cleaned" msg_info "Starting PhotoPrism" diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 572f70b5..c64f26db 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -30,30 +30,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -62,9 +61,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -82,7 +84,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Pi-hole" mkdir -p /etc/pihole/ -cat < /etc/pihole/setupVars.conf +cat </etc/pihole/setupVars.conf PIHOLE_INTERFACE=eth0 PIHOLE_DNS_1=8.8.8.8 PIHOLE_DNS_2=8.8.4.4 @@ -101,24 +103,24 @@ EOF curl -sSL https://install.pi-hole.net | bash /dev/stdin --unattended &>/dev/null msg_ok "Installed Pi-hole" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/plex-install.sh b/setup/plex-install.sh index a1ea5f33..3cef5ed5 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -79,21 +81,21 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then -msg_info "Setting Up Hardware Acceleration" -apt-get -y install \ + msg_info "Setting Up Hardware Acceleration" + apt-get -y install \ va-driver-all \ ocl-icd-libopencl1 \ beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* -msg_ok "Set Up Hardware Acceleration" + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" fi msg_info "Setting Up Plex Media Server Repository" wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://downloads.plex.tv/repo/deb/ public main" | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null +echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" @@ -101,25 +103,24 @@ apt-get update &>/dev/null apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver &>/dev/null msg_ok "Installed Plex Media Server" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null msg_ok "Cleaned" - diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index e192c86e..2900c446 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -83,35 +85,34 @@ systemctl enable --now podman.socket &>/dev/null msg_ok "Installed Podman" read -r -p "Would you like to add Yacht (Semifunctional)? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -YACHT="Y" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + YACHT="Y" else -YACHT="N" + YACHT="N" fi if [[ $YACHT == "Y" ]]; then -msg_info "Pulling Yacht Image" -podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null -msg_ok "Pulled Yacht Image" + msg_info "Pulling Yacht Image" + podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null + msg_ok "Pulled Yacht Image" -msg_info "Installing Yacht" -podman volume create yacht >/dev/null -podman run -d \ - --privileged \ - --name yacht \ - --restart always \ - -v /var/run/podman/podman.sock:/var/run/docker.sock \ - -v yacht:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - -p 8000:8000 \ - selfhostedpro/yacht:latest &>/dev/null -podman generate systemd \ + msg_info "Installing Yacht" + podman volume create yacht >/dev/null + podman run -d \ + --privileged \ + --name yacht \ + --restart always \ + -v /var/run/podman/podman.sock:/var/run/docker.sock \ + -v yacht:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + -p 8000:8000 \ + selfhostedpro/yacht:latest &>/dev/null + podman generate systemd \ --new --name yacht \ - > /etc/systemd/system/yacht.service -systemctl enable yacht &>/dev/null -msg_ok "Installed Yacht" + >/etc/systemd/system/yacht.service + systemctl enable yacht &>/dev/null + msg_ok "Installed Yacht" fi msg_info "Pulling Home Assistant Image" podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null @@ -130,29 +131,29 @@ podman run -d \ --net=host \ homeassistant/home-assistant:stable &>/dev/null podman generate systemd \ - --new --name homeassistant \ - > /etc/systemd/system/homeassistant.service + --new --name homeassistant \ + >/etc/systemd/system/homeassistant.service systemctl enable homeassistant &>/dev/null msg_ok "Installed Home Assistant" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index e4cd0a20..7fa9dc77 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -88,7 +90,7 @@ msg_info "Installing PostgreSQL" apt-get update &>/dev/null apt-get install -y postgresql &>/dev/null -cat < /etc/postgresql/15/main/pg_hba.conf +cat </etc/postgresql/15/main/pg_hba.conf # PostgreSQL Client Authentication Configuration File local all postgres peer # TYPE DATABASE USER ADDRESS METHOD @@ -107,7 +109,7 @@ host replication all 127.0.0.1/32 scram-sha-256 host replication all ::1/128 scram-sha-256 EOF -cat < /etc/postgresql/15/main/postgresql.conf +cat </etc/postgresql/15/main/postgresql.conf # ----------------------------- # PostgreSQL configuration file # ----------------------------- @@ -192,38 +194,37 @@ sudo systemctl restart postgresql msg_ok "Installed PostgreSQL" read -r -p "Would you like to add Adminer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -ADMINER="Y" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + ADMINER="Y" else -ADMINER="N" + ADMINER="N" fi if [[ $ADMINER == "Y" ]]; then -msg_info "Installing Adminer" -sudo apt install adminer -y &>/dev/null -sudo a2enconf adminer &>/dev/null -sudo systemctl reload apache2 &>/dev/null -msg_ok "Installed Adminer" + msg_info "Installing Adminer" + sudo apt install adminer -y &>/dev/null + sudo a2enconf adminer &>/dev/null + sudo systemctl reload apache2 &>/dev/null + msg_ok "Installed Adminer" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index f9b176d0..ba9b453e 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -107,29 +109,29 @@ ExecStart=/usr/local/bin/prometheus \ --web.listen-address=0.0.0.0:9090 [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path sudo systemctl enable --now prometheus &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null -rm -rf /root/prometheus-2.36.2.linux-amd64 /root/prometheus-2.36.2.linux-amd64.tar.gz +rm -rf /root/prometheus-2.36.2.linux-amd64 /root/prometheus-2.36.2.linux-amd64.tar.gz msg_ok "Cleaned" diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh index ced965d4..0a435c4d 100644 --- a/setup/syncthing-install.sh +++ b/setup/syncthing-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -85,23 +87,23 @@ apt-get install -y syncthing &>/dev/null systemctl enable syncthing@root.service &>/dev/null msg_ok "Installed Syncthing" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 887ad747..f97b40cd 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -81,24 +83,24 @@ msg_info "Installing Technitium DNS" curl -sSL https://download.technitium.com/dns/install.sh | sudo bash &>/dev/null msg_ok "Installed Technitium DNS" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index 9478d2f4..a6aab029 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,29 +29,28 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -60,9 +59,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -76,9 +78,9 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 3, length($2)-4) }') +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') msg_info "Installing Trilium" wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz @@ -102,27 +104,27 @@ TimeoutStopSec=20 Restart=always [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now -q trilium msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 4ee2e1ea..c7010188 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -77,23 +79,23 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index 5c8138f6..4da3411c 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -89,24 +91,24 @@ msg_info "Installing Umbrel (Patience)" curl -sL https://umbrel.sh | bash &>/dev/null msg_ok "Installed Umbrel" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 2c0a32c4..94100a0c 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -30,30 +30,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -62,9 +61,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -79,35 +81,34 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" read -r -p "Local Controller? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]] -then -LOCAL="--local-controller" +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + LOCAL="--local-controller" else -LOCAL="" + LOCAL="" fi msg_info "Installing UniFi Network Application (Patience)" wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip --add-repository $LOCAL &>/dev/null msg_ok "Installed UniFi Network Application" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 7777f05a..83c31b6c 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -106,28 +108,28 @@ WorkingDirectory=/opt/uptime-kuma ExecStart=/usr/bin/npm start [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now uptime-kuma.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index d3afc43f..c5736db9 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -75,27 +77,27 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" apt-get update &>/dev/null apt-get -qqy install \ - git \ - build-essential \ - pkgconf \ - libssl-dev \ - libmariadb-dev-compat \ - libpq-dev \ - curl \ - sudo &>/dev/null + git \ + build-essential \ + pkgconf \ + libssl-dev \ + libmariadb-dev-compat \ + libpq-dev \ + curl \ + sudo &>/dev/null msg_ok "Installed Dependencies" -WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') +WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') -VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') +VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') msg_info "Installing Rust" curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal &>/dev/null -echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null +echo 'export PATH=~/.cargo/bin:$PATH' >>~/.bashrc &>/dev/null export PATH=~/.cargo/bin:$PATH &>/dev/null which rustc &>/dev/null msg_ok "Installed Rust" @@ -117,7 +119,7 @@ curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBV tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ &>/dev/null msg_ok "Downloaded Web-Vault ${WEBVAULT}" -cat < /opt/vaultwarden/.env +cat </opt/vaultwarden/.env ADMIN_TOKEN=$(openssl rand -base64 48) ROCKET_ADDRESS=0.0.0.0 DATA_FOLDER=/opt/vaultwarden/data @@ -161,29 +163,29 @@ WorkingDirectory=/opt/vaultwarden ReadWriteDirectories=/opt/vaultwarden/data AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl daemon-reload systemctl enable --now vaultwarden.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index ef22a09a..3085e59b 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -93,28 +95,28 @@ ExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0 Restart=always User=root [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now whoogle.service &>/dev/null msg_ok "Installed Whoogle" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index 0b54cd7f..31f2ef9f 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -89,11 +91,11 @@ msg_ok "Installed Node.js" msg_info "Installing Wiki.js" mkdir -p /opt/wikijs cd /opt/wikijs -wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz &>/dev/null +wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz &>/dev/null tar xzf wiki-js.tar.gz rm wiki-js.tar.gz -cat < /opt/wikijs/config.yml +cat </opt/wikijs/config.yml bindIP: 0.0.0.0 port: 3000 db: @@ -104,7 +106,7 @@ logFormat: default dataPath: /opt/wikijs/data bodyParserLimit: 5mb EOF -npm rebuild sqlite3 &>/dev/null +npm rebuild sqlite3 &>/dev/null msg_ok "Installed Wiki.js" msg_info "Creating Service" @@ -123,27 +125,27 @@ Environment=NODE_ENV=production WorkingDirectory=/opt/wikijs [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable --now wikijs &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index ed1aab09..9dde9a1d 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -96,7 +98,7 @@ apt-get install -y gunicorn &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing WireGuard (using pivpn.io)" -curl -s -L https://install.pivpn.io > install.sh +curl -s -L https://install.pivpn.io >install.sh chmod +x install.sh ./install.sh --unattended options.conf &>/dev/null msg_ok "Installed WireGuard" @@ -110,9 +112,9 @@ pip install icmplib &>/dev/null msg_ok "Installed pip3" msg_info "Installing WGDashboard" -WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest \ -| grep "tag_name" \ -| awk '{print substr($2, 2, length($2)-3) }') \ +WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null cd /etc/wgdashboard/src @@ -133,31 +135,31 @@ Restart=always [Install] -WantedBy=default.target" > $service_path +WantedBy=default.target" >$service_path sudo chmod 664 /etc/systemd/system/wg-dashboard.service sudo systemctl daemon-reload sudo systemctl enable wg-dashboard.service &>/dev/null sudo systemctl start wg-dashboard.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi - + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 538e109f..8631ec2a 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -88,23 +90,22 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" - + msg_info "Setting up Zigbee2MQTT Repository" git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null msg_ok "Set up Zigbee2MQTT Repository" read -r -p "Switch to Edge/dev branch? (y/N) " prompt -if [[ $prompt == "y" ]] -then -DEV="y" +if [[ $prompt == "y" ]]; then + DEV="y" else -DEV="n" + DEV="n" fi msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt &>/dev/null if [[ $DEV == "y" ]]; then -git checkout dev &>/dev/null + git checkout dev &>/dev/null fi npm ci &>/dev/null msg_ok "Installed Zigbee2MQTT" @@ -122,27 +123,27 @@ StandardError=inherit Restart=always User=root [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl enable zigbee2mqtt.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index c0137e07..d8dbaead 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -YW=`echo "\033[33m"` -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 NUM=$RETRY_NUM @@ -29,30 +29,29 @@ function error_exit() { } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " + echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" exit 1 fi done @@ -61,9 +60,12 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -97,31 +99,31 @@ User=root WorkingDirectory=/opt/zwave-js-ui ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux [Install] -WantedBy=multi-user.target" > $service_path +WantedBy=multi-user.target" >$service_path systemctl start zwave-js-ui systemctl enable zwave-js-ui &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6); - if [[ $PASS != $ ]]; then -msg_info "Customizing Container" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -msg_ok "Customized Container" - fi + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi msg_info "Cleaning up" rm zwave-js-ui-${RELEASE}-linux.zip apt-get autoremove >/dev/null apt-get autoclean >/dev/null -msg_ok "Cleaned" +msg_ok "Cleaned" From f777a968ea6f782fc51d23cad82b17b8094d6d70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Oct 2022 23:21:13 -0400 Subject: [PATCH 3704/6505] Update scaling-governor.sh revert changes --- misc/scaling-governor.sh | 84 ++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 4a5821b2..8eace5bd 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -4,14 +4,14 @@ set -e while true; do read -p "View CPU Scaling Governors. Proceed(y/n)?" yn case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; esac done clear function header_info { - echo -e " +echo -e " _____ _____ _ _ / ____| __ \| | | | | | | |__) | | | | @@ -21,16 +21,16 @@ function header_info { Scaling Governors " } -show_menu() { - CL=$(echo "\033[m") - GN=$(echo "\033[32m") - BL=$(echo "\033[36m") - YW=$(echo "\033[33m") - fgred=$(echo "\033[31m") - header_info +show_menu(){ + CL=`echo "\033[m"` + GN=`echo "\033[32m"` + BL=`echo "\033[36m"` + YW=`echo "\033[33m"` + fgred=`echo "\033[31m"` +header_info CK=$(uname -r) IP=$(hostname -I) - # MAC=$(cat /sys/class/net/eno1/address) +# MAC=$(cat /sys/class/net/eno1/address) ACSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors) CCSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) echo -e "${YW}Proxmox IP ${BL}${IP}${CL}" @@ -41,7 +41,7 @@ show_menu() { echo -e "\n${YW}Available CPU Scaling Governors ${BL}${ACSG}${CL}" - + echo -e "\n${YW}Current CPU Scaling Governor ${BL}${CCSG}${CL}" printf "\n ${fgred}Only Select Available CPU Scaling Governors From Above${CL}\n \n" @@ -57,51 +57,43 @@ show_menu() { } clear show_menu -while [ $opt != '' ]; do +while [ $opt != '' ] + do if [ $opt = '' ]; then - exit + exit; else - case $opt in - 1) - echo "conservative" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + case $opt in + 1) echo "conservative" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 2) - echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 2) echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 3) - echo "userspace" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 3) echo "userspace" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 4) - echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 4) echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 5) - echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 5) echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 6) - echo "schedutil" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 6) echo "schedutil" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - x) - exit - ;; - \n) - exit - ;; - *) - clear - show_menu - ;; - esac + ;; + x)exit; + ;; + \n)exit; + ;; + *)clear; + show_menu; + ;; + esac fi -done + done From cf1f174174ffa4d3bc817bd00dd63965cbb6810b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Oct 2022 23:45:14 -0400 Subject: [PATCH 3705/6505] Update scaling-governor.sh revert the revert --- misc/scaling-governor.sh | 84 ++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 8eace5bd..4a5821b2 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -4,14 +4,14 @@ set -e while true; do read -p "View CPU Scaling Governors. Proceed(y/n)?" yn case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; esac done clear function header_info { -echo -e " + echo -e " _____ _____ _ _ / ____| __ \| | | | | | | |__) | | | | @@ -21,16 +21,16 @@ echo -e " Scaling Governors " } -show_menu(){ - CL=`echo "\033[m"` - GN=`echo "\033[32m"` - BL=`echo "\033[36m"` - YW=`echo "\033[33m"` - fgred=`echo "\033[31m"` -header_info +show_menu() { + CL=$(echo "\033[m") + GN=$(echo "\033[32m") + BL=$(echo "\033[36m") + YW=$(echo "\033[33m") + fgred=$(echo "\033[31m") + header_info CK=$(uname -r) IP=$(hostname -I) -# MAC=$(cat /sys/class/net/eno1/address) + # MAC=$(cat /sys/class/net/eno1/address) ACSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors) CCSG=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) echo -e "${YW}Proxmox IP ${BL}${IP}${CL}" @@ -41,7 +41,7 @@ header_info echo -e "\n${YW}Available CPU Scaling Governors ${BL}${ACSG}${CL}" - + echo -e "\n${YW}Current CPU Scaling Governor ${BL}${CCSG}${CL}" printf "\n ${fgred}Only Select Available CPU Scaling Governors From Above${CL}\n \n" @@ -57,43 +57,51 @@ header_info } clear show_menu -while [ $opt != '' ] - do +while [ $opt != '' ]; do if [ $opt = '' ]; then - exit; + exit else - case $opt in - 1) echo "conservative" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + case $opt in + 1) + echo "conservative" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 2) echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 2) + echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 3) echo "userspace" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 3) + echo "userspace" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 4) echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 4) + echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 5) echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 5) + echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - 6) echo "schedutil" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + ;; + 6) + echo "schedutil" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor clear show_menu - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - show_menu; - ;; - esac + ;; + x) + exit + ;; + \n) + exit + ;; + *) + clear + show_menu + ;; + esac fi - done +done From bfadcb1c090a189fe94c368c6b96d3792a11d1c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Oct 2022 00:19:48 -0400 Subject: [PATCH 3706/6505] Update scaling-governor.sh --- misc/scaling-governor.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 4a5821b2..1d0774c2 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -57,8 +57,8 @@ show_menu() { } clear show_menu -while [ $opt != '' ]; do - if [ $opt = '' ]; then +while [ "$opt" != "" ]; do + if [ "$opt" = "" ]; then exit else case $opt in From 1c685da6a5d2f2788935be296aedd458b6d6d494 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Oct 2022 08:56:13 -0400 Subject: [PATCH 3707/6505] Rename README.md to README_NEW.md --- README.md => README_NEW.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.md => README_NEW.md (100%) diff --git a/README.md b/README_NEW.md similarity index 100% rename from README.md rename to README_NEW.md From 4dc0ad8df76b255df0a897916c665fdbc7bf5491 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Oct 2022 08:57:09 -0400 Subject: [PATCH 3708/6505] Create README.md --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..fe325970 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +

    https://tteck.github.io/Proxmox/

    From bbd664af7c8a9e4a1e4bc7aee917692229947da4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Oct 2022 09:01:06 -0400 Subject: [PATCH 3709/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fe325970..716b1e65 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@

    https://tteck.github.io/Proxmox/

    +

    A big thank you to @mkaatman

    From 65bc3db7b4f7afffa6ec3d3d6b8f5674f4a772d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Oct 2022 16:41:08 -0400 Subject: [PATCH 3710/6505] Update omada-install.sh v5.6.3 --- setup/omada-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 5cdb3b12..2bdf2f1f 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -84,9 +84,9 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing Omada Controller v5.5.6" -wget -qL https://static.tp-link.com/upload/software/2022/202208/20220822/Omada_SDN_Controller_v5.5.6_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.5.6_Linux_x64.deb &>/dev/null +msg_info "Installing Omada Controller v5.6.3" +wget -qL https://static.tp-link.com/upload/software/2022/202210/20221024/Omada_SDN_Controller_v5.6.3_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.6.3_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6) From bca5ff7566c625dd4ed74b60f3097f9d6779df77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Oct 2022 17:11:36 -0400 Subject: [PATCH 3711/6505] Add files via upload --- misc/images/github-icon.png | Bin 0 -> 604 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/github-icon.png diff --git a/misc/images/github-icon.png b/misc/images/github-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cb9a01d02698d509569c02df327273f464ca8e8a GIT binary patch literal 604 zcmV-i0;BzjP)Px%7D+@wR9Hvtm%nbpFc8MSzycdcEU>Y*V=HC`W=s}XBf(?v4v2{fiIEMAgcuoE z+p&FvsslwZ@<-sx5k_Ea$AMJs(2U9X?ss>eFSdhUew<&9kI(@1dY$d}dpM4R^?L2| zClU!T#t@Ik(d~9a`Ls6nJdZ7xORIvV(`od2JuBaVMqvWWbT%MH073|}N;$xYQmT!k z{SZ}f!KQ;y0z@6$1aSpWtJRoLcNFD6_mNB{(eL*!VqO8Lvfu4?7>~!kuS%s7$Tb`e zPd2i>+=>eTUFpvq21b_*RKVvDe+Qt^Xt4Qwu1s*TSYS4rg-u@DvP>p(nwX~wn3NxN z3pkl*Lm)stpGT|Jx+#0H$fScnfP1q42Z*Es*=!b_PUq(};JPk591hAr_voNdC?J>1 zUHFZ~Vi*htzW)BsAmTJp&w_Hf44$q0Xh$)C2SUi3SRhI-_VH@9LbKUKsZ=s*qF5{< zl}agXD5Z}8-o;1b-;ir!G#V*Ks!A8r=@jjD+X!d;8y;8Y2q7QB%Vx8|WHLduTE%v| z^%IXfo%|u)4mlJ60000 Date: Mon, 31 Oct 2022 17:58:12 -0400 Subject: [PATCH 3712/6505] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 716b1e65..c770cf76 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@

    https://tteck.github.io/Proxmox/

    +
    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    A big thank you to @mkaatman

    From dc933dcb0912bf50a2dffe73ffa7bc3ccb7870fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 31 Oct 2022 22:22:59 -0400 Subject: [PATCH 3713/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c770cf76..0b72e4da 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@

    https://tteck.github.io/Proxmox/

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.
    -

    A big thank you to @mkaatman

    + From f8d100f852ba91f65fb0bf2ea124adfa3b8b7328 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Nov 2022 06:44:51 -0400 Subject: [PATCH 3714/6505] Create alpine-v4.sh --- ct/alpine-v4.sh | 266 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 ct/alpine-v4.sh diff --git a/ct/alpine-v4.sh b/ct/alpine-v4.sh new file mode 100644 index 00000000..07b4c79d --- /dev/null +++ b/ct/alpine-v4.sh @@ -0,0 +1,266 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Alpine" +var_disk="1" +var_cpu="1" +var_ram="512" +var_os="alpine" +var_version="3.16" +NSAPP=$(echo ${APP,,} | tr -d ' ') +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + cat <<"EOF" + ___ v4 __ _ + / | / /___ (_)___ ___ + / /| | / / __ \/ / __ \/ _ \ + / ___ |/ / /_/ / / / / / __/ +/_/ |_/_/ .___/_/_/ /_/\___/ + /_/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" + PW="-password alpine" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="alpine" PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 7f71be6dab077f9201899aaf7c7eb3a8276429f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Nov 2022 07:05:08 -0400 Subject: [PATCH 3715/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c94872fd..1a28f05f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-01 + +### Changed + +- **Alpine LXC** + - NEW Script + ## 2022-10-27 ### Changed From cb8df48b94499d21c2bb6d4c79ca1f380f2546c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Nov 2022 11:50:23 -0400 Subject: [PATCH 3716/6505] Create archlinux-v4.sh --- ct/archlinux-v4.sh | 265 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 ct/archlinux-v4.sh diff --git a/ct/archlinux-v4.sh b/ct/archlinux-v4.sh new file mode 100644 index 00000000..6d3243ca --- /dev/null +++ b/ct/archlinux-v4.sh @@ -0,0 +1,265 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Arch Linux" +var_disk="1" +var_cpu="1" +var_ram="512" +var_os="archlinux" +var_version="base" +NSAPP=$(echo ${APP,,} | tr -d ' ') +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + cat <<"EOF" + ___ __ __ _ + / | __________/ /_ v4 / / (_)___ __ ___ __ + / /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ + / ___ |/ / / /__/ / / / / /___/ / / / / /_/ /> < +/_/ |_/_/ \___/_/ /_/ /_____/_/_/ /_/\__,_/_/|_| + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}archlinux${CL}" + PW="-password archlinux" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="archlinux" PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From b3fbc18e6ca9a2cb0b87aa41355967c39ba07429 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Nov 2022 13:51:17 -0400 Subject: [PATCH 3717/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1a28f05f..c5cd9005 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **Alpine LXC** - NEW Script +- **Arch LXC** + - NEW Script ## 2022-10-27 From 6080629b25eef0a5ab1c98445ed936d2294c3139 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Nov 2022 09:51:11 -0400 Subject: [PATCH 3718/6505] Update nginx-proxy-manager-v4.sh increase disk --- ct/nginx-proxy-manager-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 326d353c..8e316769 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash echo -e "Loading..." APP="Nginx Proxy Manager" -var_disk="3" +var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" From b0e517ab74ca299d3dda83c82c86e97ac529e3a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Nov 2022 12:57:31 -0400 Subject: [PATCH 3719/6505] Update update-lxcs.sh added back alpine support --- misc/update-lxcs.sh | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 3c0a4f27..84a59274 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -16,15 +16,15 @@ while true; do done clear function header_info { - echo -e "${BL} - _ _ _____ _____ _______ ______ - | | | | __ \| __ \ /\|__ __| ____| - | | | | |__) | | | | / \ | | | |__ - | | | | ___/| | | |/ /\ \ | | | __| - | |__| | | | |__| / ____ \| | | |____ - \____/|_| |_____/_/ \_\_| |______| + cat <<"EOF" + __ __ __ __ __ _ ________ + / / / /___ ____/ /___ _/ /____ / / | |/ / ____/ + / / / / __ \/ __ / __ `/ __/ _ \ / / | / / +/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___ +\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/ + /_/ -${CL}" +EOF } header_info @@ -35,7 +35,14 @@ function update_container() { clear header_info echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" - pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" + pct config $container > temp + os=`awk '/^ostype/' temp | cut -d' ' -f2` + if [ "$os" == "alpine" ] + then + pct exec $container -- ash -c "apk update && apk upgrade" + else + pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" + fi } read -p "Skip stopped containers? " -n 1 -r echo @@ -67,5 +74,5 @@ for container in $containers; do fi done wait - +rm -rf temp echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From 3ed93239dc928942fccf1b4bfd91003118832450 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Nov 2022 20:17:37 -0400 Subject: [PATCH 3720/6505] Update homeassistant-core-v4.sh add dev/ttyUSB1 --- ct/homeassistant-core-v4.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index 11373448..4098d9c0 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -265,6 +265,7 @@ lxc.cgroup2.devices.allow: c 188:* rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF From 5daca675cf34ab56e6a9ab17a88cce4081261e73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Nov 2022 20:21:13 -0400 Subject: [PATCH 3721/6505] Update homeassistant-v4.sh add /dev/ttyUSB1 --- ct/homeassistant-v4.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 8d8b9464..77b128df 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -264,6 +264,7 @@ lxc.cgroup2.devices.allow: c 188:* rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF From 809af179fa3c03d475f710757aef9748100085a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Nov 2022 20:27:03 -0400 Subject: [PATCH 3722/6505] Update zwave-js-ui-v4.sh If the LXC is created Privileged, the script will automatically set up USB passthrough. --- ct/zwave-js-ui-v4.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 45dd790c..0f2af7ab 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -256,8 +256,9 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm @@ -268,6 +269,7 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From d6ef841b9b47d4798158007c6cc73fff2bc98671 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Nov 2022 20:29:04 -0400 Subject: [PATCH 3723/6505] Update zigbee2mqtt-v4.sh If the LXC is created Privileged, the script will automatically set up USB passthrough. --- ct/zigbee2mqtt-v4.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 2c1881a5..d19c5a03 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -256,10 +256,11 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a -lxc.cap.drop: +lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir @@ -268,6 +269,7 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From dc5728dced0db83318a0980ef40cc42adfba571b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Nov 2022 20:41:46 -0400 Subject: [PATCH 3724/6505] Update deconz-v4.sh If the LXC is created Privileged, the script will automatically set up USB passthrough. --- ct/deconz-v4.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index ab9a868b..2605ceae 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -256,17 +256,20 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From e21aa0fc3bbf4dc5be2b35c910615f9c28922bde Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Nov 2022 06:40:09 -0400 Subject: [PATCH 3725/6505] Update alpine-v4.sh set default disk 100 MiB --- ct/alpine-v4.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ct/alpine-v4.sh b/ct/alpine-v4.sh index 07b4c79d..11f8f2e7 100644 --- a/ct/alpine-v4.sh +++ b/ct/alpine-v4.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash echo -e "Loading..." APP="Alpine" -var_disk="1" +var_disk="0.1" var_cpu="1" var_ram="512" var_os="alpine" @@ -78,7 +78,7 @@ function default_settings() { CT_ID=$NEXTID echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" DISK_SIZE="$var_disk" echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" CORE_COUNT="$var_cpu" @@ -142,10 +142,6 @@ function advanced_settings() { echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" else if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi fi CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? From ade6c5a90528bfee343fb1da3ff5d0099a1aed64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Nov 2022 05:27:17 -0400 Subject: [PATCH 3726/6505] Update podman-homeassistant-v4.sh If the LXC is created Privileged, the script will automatically set up USB passthrough. --- ct/podman-homeassistant-v4.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index df926cb6..87bf6dea 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -259,11 +259,26 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +if [ "$CT_TYPE" == "0" ]; then LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +else + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From 789086b47c41aea8a793b1889bc4f3c34cb05dde Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Nov 2022 05:37:31 -0400 Subject: [PATCH 3727/6505] Delete README_OLD.md --- README_OLD.md | 2484 ------------------------------------------------- 1 file changed, 2484 deletions(-) delete mode 100644 README_OLD.md diff --git a/README_OLD.md b/README_OLD.md deleted file mode 100644 index ee956ea4..00000000 --- a/README_OLD.md +++ /dev/null @@ -1,2484 +0,0 @@ -

    Select a Proxmox Helper

    - -

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    - - - -
    - Proxmox VE 7 Post Install - -

    - -

    Proxmox VE 7 Post Install

    - -The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox VE and Reboot PVE. - -Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pve-install.sh)" -``` - -It's recommended to answer `y` to all options. - -____________________________________________________________________________________________ - -
    - -
    - Proxmox Kernel Clean - -

    - -

    Proxmox Kernel Clean

    - -Cleaning unused kernel images is not only good because of a reduced grub menu, but also gains some disk space. - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox Edge Kernel Tool - -

    - -

    Proxmox Edge Kernel Tool

    - -Proxmox [Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7. Keeping up with new Kernel releases instead of LTS - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox CPU Scaling Governor - -

    - -

    Proxmox CPU Scaling Governor

    - -CPU Scaling Governor enables the operating system to scale the CPU frequency up or down in order to save power or improve performance. - -[Generic Scaling Governors](https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html?#generic-scaling-governors) - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/scaling-governor.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox LXC Updater - -

    - -

    Proxmox LXC Updater

    - -Update All LXC's Fast & Easy - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox Dark Theme - -

    - -

    Proxmox Discord Dark Theme

    - -A dark theme for the Proxmox Web UI by [Weilbyte](https://github.com/Weilbyte/PVEDiscordDark) - -Run the following in the Proxmox Shell. - -```yaml -bash <(curl -s https://raw.githubusercontent.com/Weilbyte/PVEDiscordDark/master/PVEDiscordDark.sh ) install -``` - -To uninstall the theme, simply run the script with the `uninstall` command. - -____________________________________________________________________________________________ - -
    - -
    - Proxmox Backup Server Post Install - -

    - -

    Proxmox Backup Server Post Install

    - -The script will give options to Disable the Enterprise Repo, Add/Correct PBS Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox Backup Server and Reboot PBS. - -Run the following in the Proxmox Shell. ⚠️ **Proxmox Backup Server ONLY** - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pbs-install.sh)" -``` - -It's recommended to answer `y` to all options. - -____________________________________________________________________________________________ - -
    - -
    - Home Assistant OS VM - -

    - -

    Home Assistant OS VM

    -

    Option to create VM using Stable, Beta or Dev Image

    - -The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip, ect...) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. - -To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v4.sh)" -``` -

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    - -After the script completes, click on the VM, then on the **_Summary_** tab to find the VM IP. - -**Home Assistant Interface - IP:8123** - -____________________________________________________________________________________________ - -
    - -
    - 🔸PiMox HAOS VM - -

    - -

    PiMox HAOS VM

    -

    Option to create VM using Stable, Beta or Dev Image

    - -The script automates the manual process of finding, downloading and extracting the aarch64 (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. - -To create a new PiMox HAOS VM, run the following in the Proxmox Shell - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/pimox-haos-vm-v4.sh)" -``` -

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    - -After the script completes, click on the VM Console to find the Home Assistant IP. - -**Home Assistant Interface - IP:8123** - -____________________________________________________________________________________________ - -
    - -
    - Home Assistant Container LXC - -

    Docker Logos | Docker -@home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    - -

    Home Assistant Container LXC

    - -A standalone container-based installation of Home Assistant Core - -🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* - -To create a new Proxmox Home Assistant Container LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    - -**Home Assistant Interface - IP:8123** - -**Portainer Interface - IP:9000** - -⚙️ **Path to HA /config** -```yaml -/var/lib/docker/volumes/hass_config/_data - ``` -⚙️ **To Edit the HA configuration.yaml** (Recommend Using File Browser) - -Run in the LXC console -```yaml -nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -⚙️ **Copy Data From a Existing Home Assistant LXC to another Home Assistant LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data.sh)" - ``` - -⚙️ **To Install HACS:** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. - - -⚙️ [**Update Menu**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) - -Run in the LXC console -```yaml -./update -``` -____________________________________________________________________________________________ -
    - -
    - 🔸Home Assistant Core LXC - -

    - -

    Home Assistant Core LXC

    - -A standalone installation of Home Assistant Core - -🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* - -To create a new Proxmox Home Assistant Core LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-core-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 8GB Storage - 2vCPU ⚡

    - -⚠️ Initialize Home Assistant-Core (Only required once) - -Run in the LXC console -```yaml -cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass -``` - -***Home Assistant Interface - IP:8123*** - -⚙️ **Edit the HA configuration.yaml** - -Run in the LXC console -```yaml -nano .homeassistant/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -⚙️ **Install HACS:** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs-core.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. - -⚙️ **Update Home Assistant** - -Run in the LXC console -```yaml -systemctl stop homeassistant.service && source /srv/homeassistant/bin/activate && pip3 install --upgrade homeassistant && systemctl start homeassistant.service && exit -``` -____________________________________________________________________________________________ -
    - -
    - Podman Home Assistant Container LXC - -

    -@home-assistant

    - -

    Podman Home Assistant Container LXC

    -A standalone container-based installation of Home Assistant Core - -⚠️ Podman seems to need a privileged LXC - -To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    - -**Home Assistant Interface - IP:8123** - -**Yacht Interface - IP:8000** - -⚙️ **Path to HA /config** -```yaml -/var/lib/containers/storage/volumes/hass_config/_data - ``` -⚙️ **To edit the HA configuration.yaml** - -Run in the LXC console -```yaml -nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -⚙️ **Copy Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data-podman.sh)" - ``` - -⚙️ **To allow USB device passthrough:** - -Run in the Proxmox Shell. (**replace `106` with your LXC ID**) -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 -``` - -Reboot the LXC to apply the changes - -⚙️ **To Install HACS:** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/podman_hacs.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. - -⚙️ **Initial Yacht Login** - -**username** - ```yaml - admin@yacht.local - ``` - **password** - ```yaml - pass - ``` - -____________________________________________________________________________________________ -
    - -
    - ioBroker LXC - -

    - -

    ioBroker LXC

    - -[ioBroker](https://www.iobroker.net/#en/intro) is an open source automation platform. - -To create a new Proxmox ioBroker LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/iobroker-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**ioBroker Interface - IP:8081** - -⚙️ **To Update ioBroker** - -```yaml -update from the ioBroker UI -``` - -____________________________________________________________________________________________ - -
    - -
    - openHAB LXC - -

    - -

    openHAB LXC

    - -[openHAB](https://www.openhab.org/), a vendor and technology agnostic open source automation software for your home. - -To create a new Proxmox openHAB LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/openhab-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**openHAB Interface - IP:8080** - -⚙️ **To Update openHAB** - -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Homebridge LXC - -

    - -

    Homebridge LXC

    - -[Homebridge](https://homebridge.io/) allows you to integrate with smart home devices that do not natively support HomeKit - -To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -**Homebridge Interface - IP:8581** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` -Config File Path `/var/lib/homebridge/config.json` - -Storage Path `/var/lib/homebridge` - -Restart Command `sudo hb-service restart` - -Stop Command `sudo hb-service stop` - -Start Command `sudo hb-service start` - -View Logs Command `sudo hb-service logs` - -Systemd Service File `/etc/systemd/system/homebridge.service` - -Systemd Env File `/etc/default/homebridge` - -⚙️ **To Update Homebridge** - -```yaml -Update from the Homebridge UI -``` - - ___________________________________________________________________________________________ - -
    - - - -
    - ESPHome LXC - -

    - -

    ESPHome LXC

    - -[ESPHome](https://esphome.io/) is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems. - -To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**ESPHome Interface - IP:6052** - -⚙️ **To Update ESPHome** - -Run in the LXC console -```yaml -pip3 install esphome --upgrade -``` - -____________________________________________________________________________________________ - -
    - - - -
    - Nginx Proxy Manager LXC - -

    hero

    - - -

    Nginx Proxy Manager LXC

    - -[Nginx Proxy Manager](https://nginxproxymanager.com/) Expose your services easily and securely - -To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. - -```yaml - bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

    - -____________________________________________________________________________________ - -Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. - -Add the following to your `configuration.yaml` in Home Assistant. -```yaml - http: - use_x_forwarded_for: true - trusted_proxies: - - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### -``` - -**Nginx Proxy Manager Interface - IP:81** - -⚙️ **Initial Login** - -**username** - ```yaml - admin@example.com - ``` - **password** - ```yaml - changeme - ``` -⚙️ **To Update Nginx Proxy Manager** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update.sh)" -``` - - ____________________________________________________________________________________________ - -
    - -
    - MQTT LXC - -

    - -

    MQTT LXC

    - -[Eclipse Mosquitto](https://mosquitto.org/) is an open source message broker that implements the MQTT protocol - -To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -Mosquitto comes with a password file generating utility called mosquitto_passwd. -```yaml -sudo mosquitto_passwd -c /etc/mosquitto/passwd -``` -Password: < password > - -Create a configuration file for Mosquitto pointing to the password file we have just created. -```yaml -sudo nano /etc/mosquitto/conf.d/default.conf -``` -This will open an empty file. Paste the following into it. -```yaml -allow_anonymous false -persistence true -password_file /etc/mosquitto/passwd -listener 1883 -``` -Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X". - -Now restart Mosquitto server. -```yaml -sudo systemctl restart mosquitto -``` - -⚙️ **To Update MQTT:** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - EMQX LXC - -

    - - -

    EMQX LXC

    - -[EMQX](https://www.emqx.io/) is an Open-source MQTT broker with a high-performance real-time message processing engine, powering event streaming for IoT devices at massive scale. - -To create a new Proxmox EMQX LXC, run the following in the Proxmox Shell. - -```yaml - bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emqx-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - - -**EMQX Interface - IP:18083** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - public - ``` -⚙️ **Setup** - -Access Control ➡ Authentication ➡ Create ➡ Next ➡ Next ➡ Create ➡ Users ➡ Add ➡ Username / Password (to authenicate with MQTT) ➡ Save. You're now ready to enjoy a high-performance MQTT Broker. - -⚙️ **To Update EMQX** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - - ____________________________________________________________________________________________ - -
    - -
    - Node-Red LXC - -

    - -

    Node-Red LXC

    - -[Node-RED](https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. - -To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -**Node-Red Interface - IP:1880** - -⚙️ **To Restart Node-Red:** - -Run in the LXC console -```yaml -node-red-restart -``` - -⚙️ **To Update Node-Red:** - -Run in the LXC console (Restart after update) -```yaml -npm install -g --unsafe-perm node-red -``` - -⚙️ **To Install Node-Red Themes** ⚠️ **Backup your flows before running this script!!** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/node-red-themes.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - n8n LXC - -

    - -

    n8n LXC

    - -[n8n](https://n8n.io/) is an extendable workflow automation tool which enables you to connect anything to everything. - -To create a new Proxmox n8n LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/n8n-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    - -**n8n Interface: IP:5678** - -⚙️ **To Update n8n** - -```yaml -npm update -g n8n -``` - -____________________________________________________________________________________________ - -
    - -
    - Mariadb LXC - -

    MariaDB

    - -

    Mariadb LXC

    -

    Option to Install Adminer

    - -[MariaDB](https://mariadb.org/) is a community-developed, commercially supported fork of the MySQL relational database management system. - -To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: -```yaml -nano /etc/mysql/my.cnf -``` -Un-comment `port =3306` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". - -```yaml -nano /etc/mysql/mariadb.conf.d/50-server.cnf -``` -Comment `bind-address = 127.0.0.1` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". - -For new MariaDB installations, the next step is to run the included security script. This script changes some of the less secure default options. We will use it to block remote root logins and to remove unused database users. - -Run the security script: -```yaml -sudo mysql_secure_installation -``` -Enter current password for root (enter for none): `enter` - -Switch to unix_socket authentication [Y/n] `y` - -Change the root password? [Y/n] `n` - -Remove anonymous users? [Y/n] `y` - -Disallow root login remotely? [Y/n] `y` - -Remove test database and access to it? [Y/n] `y` - -Reload privilege tables now? [Y/n] `y` - -We will create a new account called admin with the same capabilities as the root account, but configured for password authentication. -```yaml -sudo mysql -``` -Prompt will change to ```MariaDB [(none)]>``` - -Create a new local admin (Change the username and password to match your preferences) -```yaml -CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password'; -``` -Give local admin root privileges (Change the username and password to match above) -```yaml -GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; -``` - -Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on your local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the **_username_**, **_password_** and **_subnet_** to match your preferences: -```yaml -GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; -``` -Flush the privileges to ensure that they are saved and available in the current session: -```yaml -FLUSH PRIVILEGES; -``` -Following this, exit the MariaDB shell: -```yaml -exit -``` -Log in as the new database user you just created: -```yaml -mysql -u admin -p -``` -Create a new database: -```yaml -CREATE DATABASE homeassistant; -``` -Following this, exit the MariaDB shell: -```yaml -exit -``` -⚠️ Reboot the lxc - -Checking status. -```yaml -sudo systemctl status mariadb -``` -Change the recorder: `db_url:` in your HA configuration.yaml - -Example: -```yaml -recorder: - db_url: mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4 -``` - -⚙️ **To Update Mariadb:** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool - - `http://your-mariadb-lxc-ip/adminer/` - -____________________________________________________________________________________________ - -
    - -
    - PostgreSQL LXC - -

    - -

    PostgreSQL LXC

    -

    Option to Install Adminer

    - -[PostgreSQL](https://www.postgresql.org/), also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance. - -To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -To make sure our PostgreSQL is secured with a strong password, set a password for its system user and then change the default database admin user account - -Change user password -```yaml -passwd postgres -``` -Login using Postgres system account - -```yaml -su - postgres -``` -Now, change the Admin database password -```yaml -psql -c "ALTER USER postgres WITH PASSWORD 'your-password';" -``` -Create a new user. -```yaml -psql -``` -```yaml -CREATE USER admin WITH PASSWORD 'your-password'; -``` -Create a new database: -```yaml -CREATE DATABASE homeassistant; -``` -Grant all rights or privileges on created database to the user -```yaml -GRANT ALL ON DATABASE homeassistant TO admin; -``` -To exit psql -```yaml -\q -``` -Then type exit to get back to root - -Change the recorder: `db_url:` in your HA configuration.yaml - -Example: -```yaml -recorder: - db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8 -``` -⚙️ **To Update PostgreSQL** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool - - `http://your-PostgreSQL-lxc-ip/adminer/` - -____________________________________________________________________________________________ - -
    - -
    - Zigbee2MQTT LXC - -

    - - -

    Zigbee2MQTT LXC

    - -[Zigbee2MQTT](https://www.zigbee2mqtt.io/) is a standalone nodejs application that connects a zigbee network to MQTT - -To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - - -⚙️ **Determine the location of your adapter** - -Run in the LXC console -```yaml -ls -l /dev/serial/by-id -``` -Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` - - -⚙️ ⚠️ **Before you start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** - -Run in the LXC console -```yaml -nano /opt/zigbee2mqtt/data/configuration.yaml -``` - -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -Example: -```yaml -frontend: - port: 9442 -homeassistant: true -permit_join: false -mqtt: - base_topic: zigbee2mqtt - server: 'mqtt://192.168.86.224:1883' - user: usr - password: pwd - keepalive: 60 - reject_unauthorized: true - version: 4 -serial: - port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 - #adapter: deconz #(uncomment for ConBee II) -advanced: - pan_id: GENERATE - network_key: GENERATE - channel: 20 -``` -⚙️ **Zigbee2MQTT can be started after completing the configuration** - -Run in the LXC console -```yaml -cd /opt/zigbee2mqtt && npm start -``` -⚙️ **To update Zigbee2MQTT** - -Run in the LXC console - ```yaml -cd /opt/zigbee2mqtt && bash update.sh - ``` -⚙️ **Copy Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/z2m-copy-data.sh)" - ``` - -____________________________________________________________________________________________ - -
    - -
    - deCONZ LXC - -

    - -

    deCONZ LXC

    - -[deCONZ](https://www.phoscon.de/en/conbee2/software#deconz) is used to configure, control and display Zigbee networks. - -To create a new Proxmox deCONZ LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/deconz-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**deCONZ Interface - IP:80** - -⚙️ **To Update deCONZ** - -Run in the LXC Console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Z-Wave JS UI LXC - -

    - -

    Z-Wave JS UI LXC

    - -[Z-Wave JS UI](https://github.com/zwave-js/zwave-js-ui#) is a fully configurable Z-Wave to MQTT Gateway and Control Panel. - -To create a new Proxmox Z-Wave JS UI LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwave-js-ui-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**Z-Wave JS UI Interface - IP:8091** - -⚙️ **Copy Data From a Existing Zwavejs2MQTT LXC to a Z-Wave JS UI LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-copy-data.sh)" - ``` -⚙️ **To Update Z-Wave JS UI** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-js-ui-update.sh)" -``` - -____________________________________________________________________________________________ -
    - -
    - NocoDB LXC - -

    - -

    NocoDB LXC

    - -[NocoDB](https://www.nocodb.com/) is an open source #NoCode platform that turns any database into a smart spreadsheet. Airtable Alternative. - -To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -**NocoDB Interface - IP:8080/dashboard** - -⚙️ **To Update NocoDB** - -Run in the LXC console -```yaml -cd /opt/nocodb && npm run upgrade -``` - -____________________________________________________________________________________________ - -
    - -
    - Prometheus LXC - -

    - -

    Prometheus LXC

    - -[Prometheus](https://prometheus.io/) is an open-source systems monitoring and alerting toolkit - -To create a new Proxmox Prometheus LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/prometheus-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 1vCPU ⚡

    - -**Prometheus Interface - IP:9090** - -⚙️ **To Update Prometheus** - -```yaml -Working On -``` - -____________________________________________________________________________________________ - -
    - -
    - InfluxDB LXC - -

    - -

    InfluxDB LXC

    - -

    Option to Install Telegraf

    - -[InfluxDB](https://www.influxdata.com/) is an open-source time series database developed by the company InfluxData. - -[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) is an open source plugin-driven server agent for collecting and reporting metrics. - -To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -⚙️ **InfluxDB Configuration** - -Run in the LXC console -```yaml -nano /etc/influxdb/influxdb.conf -``` - -⚙️ **Telegraf Configuration** - -Run in the LXC console -```yaml -nano /etc/telegraf/telegraf.conf -``` - -⚙️ **To Update InfluxDB/Telegraf** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Grafana LXC - -

    - -

    Grafana LXC

    - -[Grafana](https://grafana.com/) is a multi-platform open source analytics and interactive visualization web application. - -To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Grafana Interface - IP:3000** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` - -⚙️ **To Update Grafana** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Docker LXC - -

    - -

    Docker LXC

    -

    Options to Install Portainer and/or Docker Compose V2

    - -[Docker](https://www.docker.com/) is an open-source project for automating the deployment of applications as portable, self-sufficient containers. - -To create a new Proxmox Docker LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    - -**⚠ Run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** - -**Portainer Interface - IP:9000** - -⚙️ **To Update** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - CasaOS LXC - -

    - -

    CasaOS LXC

    - -[CasaOS](https://www.casaos.io/) is a community-based open source software focused on delivering simple home cloud experience around Docker ecosystem. - - -To create a new Proxmox CasaOS LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/casaos-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**CasaOS Interface - IP** - -⚙️ **To Update CasaOS** - -```yaml -update from the CasaOS UI -``` - -____________________________________________________________________________________________ - -
    - -
    - Debian LXC - -

    Debian

    - -

    Debian LXC

    -

    Option to select version 10 or 11

    - -To create a new Proxmox Debian (curl & sudo) LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -⚙️ **To Update Debian** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - - -
    - Ubuntu LXC - -

    Ubuntu

    - -

    Ubuntu LXC

    -

    Option to select version 18.04, 20.04, 21.10 or 22.04

    - -To create a new Proxmox Ubuntu (curl & sudo) LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04 ⚡

    - -⚙️ **To Update Ubuntu** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - UniFi Network Application LXC - -

    - -

    UniFi Network Application LXC

    - -

    With Local Controller Option

    - -An application designed to optimize UniFi home and business networks with ease. - -To create a new Proxmox UniFi Network Application LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**UniFi Interface - https:// IP:8443** - -⚙️ **To Update UniFi** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/unifi-update.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Omada Controller LXC - -

    - -

    Omada Controller LXC

    - -Omada Controller is software which is used to manage the EAP - -To create a new Proxmox Omada Controller LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Omada Interface - https:// IP:8043** - -`tpeap status` show status of Omada Controller - -`tpeap start` start Omada Controller - -`tpeap stop` stop Omada Controller - -⚙️ **To Update Omada** - -[#403](https://github.com/tteck/Proxmox/issues/402#issue-1328460983) - -____________________________________________________________________________________________ - -
    - -
    - Plex Media Server LXC - -

    - -

    Plex Media Server LXC

    -

    With Hardware Acceleration Support

    -To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Plex Media Server Interface - IP:32400/web** - -⚙️ **To Update Plex Media Server:** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -⚙️ **Copy Data From a Existing Plex Media Server LXC to another Plex Media Server LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/pms-copy-data.sh)" - ``` - -____________________________________________________________________________________________ - -
    - -
    - Emby Media Server LXC -

    -

    Emby Media Server LXC

    - -[Emby](https://emby.media/) brings together your personal videos, music, photos, and live television. - -To create a new Proxmox Emby Media Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Emby Media Server Interface - IP:8096** - -⚙️ **Emby Media Server Utilizes Automatic Updates** - -____________________________________________________________________________________________ - -
    - -
    - Jellyfin Media Server LXC -

    -

    Jellyfin Media Server LXC

    - -[TurnKey has a LXC CT for Jellyfin](https://www.turnkeylinux.org/mediaserver) - -To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Jellyfin Media Server Interface - IP:8096** - -FFmpeg path: `/usr/lib/jellyfin-ffmpeg/ffmpeg` - -⚙️ **To Update Jellyfin Media Server** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -____________________________________________________________________________________________ - -
    - -
    - Pi-hole LXC - -

    - -

    Pi-hole LXC

    - -[Pi-hole](https://pi-hole.net/) is a Linux network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole and optionally a DHCP server. - -To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v4.sh)" -``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -⚠️ **Reboot Pi-hole LXC after install** - -**Pi-hole Interface - http:// IP/admin** - -⚙️ **To set your password:** - -Run in the LXC console - -```yaml -pihole -a -p -``` -____________________________________________________________________________________________ - -
    - -
    - Technitium DNS LXC - -

    - -

    Technitium DNS LXC

    -An open source authoritative as well as recursive DNS server - -To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Technitium DNS Interface - IP:5380** - -⚙️ **To Update Technitium DNS** - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/technitiumdns-update.sh)" -``` -__________________________________________________________________________________________ - -
    - - -
    - AdGuard Home LXC - -

    - -

    AdGuard Home LXC

    - -To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**AdGuard Home Setup Interface - IP:3000 (After Setup use only IP)** - - (For the Home Assistant Integration, use port `80` not `3000`) - -⚙️ **To Update Adguard** - -```yaml -Update from the Adguard UI -``` -__________________________________________________________________________________________ - -
    - -
    - Uptime Kuma LXC - -

    - -

    Uptime Kuma LXC

    - -Uptime Kuma is a self-hosted, open source, fancy uptime monitoring and alerting system. It can monitor HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server. - -To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1vCPU ⚡

    - -**Uptime Kuma Interface - IP:3001** - -⚙️ **To Update Uptime Kuma** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/uptimekuma-update.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Whoogle LXC - -

    - -

    Whoogle LXC

    - -Get Google search results, but without any ads, javascript, AMP links, cookies, or IP address tracking. - -To create a new Proxmox Whoogle LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/whoogle-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Whoogle Interface - IP:5000** - -⚙️ **To Update Whoogle** - -Run in the LXC console -```yaml -pip3 install whoogle-search --upgrade -``` -____________________________________________________________________________________________ - -
    - - -
    - Paperless-ngx LXC - -

    - -

    Paperless-ngx LXC

    - -[Paperless-ngx](https://paperless-ngx.readthedocs.io/en/latest/#) is a document management system that transforms your physical documents into a searchable online archive so you can keep, well, less paper. - -To create a new Proxmox Paperless-ngx LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/paperless-ngx-v4.sh)" -``` - -

    ⚡ Default Settings: 2048MiB RAM - 4GB Storage - 2vCPU ⚡

    - -**Paperless-ngx Interface - IP:8000** - -🛈 A paperless.creds file is in root home directory that contains the usernames and passwords. - -Run in the LXC Console -```yaml -cat paperless.creds -``` - -⚙️ **To Update Paperless-ngx** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/paperless-ngx-update.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Trilium LXC - -

    - -

    Trilium LXC

    - -[Trilium](https://github.com/zadam/trilium#trilium-notes) is a hierarchical note taking application with focus on building large personal knowledge bases. - -To create a new Proxmox Trilium LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/trilium-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Trilium Interface - IP:8080** - -⚙️ **To Update Trilium** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/trilium-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - Wiki.js LXC - -

    - -

    Wiki.js LXC

    - -[Wiki.js](https://js.wiki/) is a modern, lightweight and powerful wiki app built on NodeJS. - -To create a new Proxmox Wiki.js LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wikijs-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Wiki.js Interface - IP:3000** - -____________________________________________________________________________________________ - -
    - -
    - Heimdall Dashboard LXC - -

    - -

    Heimdall Dashboard LXC

    - -[Heimdall Application Dashboard](https://camo.githubusercontent.com/bcfd4f74c93b25bea7b14eacbafd649206bf754a3d4b596329968f0ee569cf3c/68747470733a2f2f692e696d6775722e636f6d2f4d72433451704e2e676966) is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like. - -To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard-v4.sh)" -``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Heimdall Dashboard Interface - IP:7990** - -⚙️ **To Update Heimdall Dashboard** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard-all-update.sh)" -``` - -__________________________________________________________________________________________ - -
    - -
    - Homepage LXC - -

    - -

    Homepage LXC

    - -[Homepage](https://github.com/benphelps/homepage) is a self-hosted dashboard. - -To create a new Proxmox Homepage LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homepage-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 2vCPU ⚡

    - -[Configuration](https://github.com/benphelps/homepage/wiki) (bookmarks.yaml, services.yaml, widgets.yaml) path: `/opt/homepage/config/` - -**Homepage Interface - IP:3000** - -⚙️ **To Update Homepage** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/homepage-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - Dashy LXC - -

    - -

    Dashy LXC

    - -Dashy helps you organize your self-hosted services by making them accessible from a single place - -To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    - -**Dashy Interface - IP:4000** - -After getting everything setup the way you want in interactive mode and saved to disk, you have to go into update configuration and rebuild application. - -⚙️ **To Update Dashy** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/dashy-update.sh)" -``` - -__________________________________________________________________________________________ - -
    - -
    - grocy LXC - -

    - -

    grocy LXC

    - -[grocy](https://grocy.info/) is a web-based self-hosted groceries & household management solution for your home. - -To create a new Proxmox grocy LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**grocy Interface: http:// IP** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` - -⚙️ **To Update grocy** - -Run in the LXC console - ```yaml -bash /var/www/html/update.sh -``` -____________________________________________________________________________________________ - -
    - -
    - MagicMirror Server LXC - -

    - -

    MagicMirror Server LXC

    - -[MagicMirror²](https://docs.magicmirror.builders/) is an open source modular smart mirror platform. - -To create a new MagicMirror Server LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 3GB Storage - 1vCPU ⚡

    - -**MagicMirror Interface - IP:8080** - -⚙️ **[Configuration](https://docs.magicmirror.builders/configuration/introduction.html#configuring-your-magicmirror)** -```yaml -/opt/magicmirror/config/config.js -``` -⚙️ **[Update MagicMirror](https://docs.magicmirror.builders/getting-started/upgrade-guide.html#upgrade-guide)** - -Run in the LXC Console -```yaml -cd /opt/magicmirror && git pull && npm install --only=prod --omit=dev -``` - - -____________________________________________________________________________________________ - -
    - -
    - Daemon Sync Server LXC - -

    - -

    Daemon Sync Server LXC

    - -Sync files from app to server, share photos & videos, back up your data and stay secure inside local network. - -To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    - -**Daemon Sync Server Interface - IP:8084** - -Search: `DAEMON Sync` in your favorite app store - -__________________________________________________________________________________________ - -
    - -
    - NextCloudPi LXC - -

    - -

    NextCloudPi LXC

    - -[NextCloudPi LXC](https://github.com/nextcloud/nextcloudpi#features) is the most popular self-hosted collaboration solution. - -To create a new Proxmox NextCloudPi LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nextcloudpi-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -❗1️. Set nc trusted domains - -Run in the LXC console -``` -sudo ncp-config -``` -Go to config ➡ nc-trusted-domains, add `0.0.0.0` or a static NextCloudPi IP - -Get back to the command prompt, and restart Apache2 `sudo service apache2 restart` - -❗2. **NextCloudPi Interface - https:// IP/** - -____________________________________________________________________________________________ - -
    - -
    - OpenMediaVault LXC - -

    - -

    OpenMediaVault LXC

    - -[OpenMediaVault](https://www.openmediavault.org/) is the next generation network attached storage (NAS) solution based on Debian Linux. - -To create a new Proxmox OpenMediaVault LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omv-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**OpenMediaVault Interface - IP** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - openmediavault - ``` - -____________________________________________________________________________________________ - -
    - -
    - Navidrome LXC - -

    - -

    Navidrome LXC

    - -[Navidrome](https://www.navidrome.org/) allows you to enjoy your music collection from anywhere, by making it available through a modern Web UI and through a wide range of third-party compatible mobile apps, for both iOS and Android devices. - -To create a new Proxmox Navidrome LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/navidrome-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -To change Navidrome music folder path, edit: `/var/lib/navidrome/navidrome.toml` - -**Navidrome Interface - IP:4533** - -⚙️ **To Update Navidrome** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/navidrome-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - PhotoPrism LXC - -

    - -

    PhotoPrism LXC

    - -[PhotoPrism](https://photoprism.app/) is an AI-powered app for browsing, organizing & sharing your photo collection. - -To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**PhotoPrism Interface - IP:2342** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - changeme - ``` -[PhotoSync](https://www.photosync-app.com/home.html) - -⚙️ **To Update or Change Branch** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/photoprism-update.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - MotionEye VMS LXC - -

    - -

    MotionEye VMS LXC

    - -To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**MotionEye Interface - IP:8765** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - - ``` - -⚙️ **To Update MotionEye** - -Run in the LXC console - ```yaml -pip install motioneye --upgrade -``` - -____________________________________________________________________________________________ - -
    - -
    - File Browser - -

    - -

    File Browser

    - -To Install File Browser, ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/filebrowser.sh)" -``` - -[File Browser](https://filebrowser.org/features) is a create-your-own-cloud-kind of software where you can install it on a server, direct it to a path and then access your files through a nice web interface. Many available features! - - - -**File Browser Interface - http:// IP:8080** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - changeme - ``` - -⚙️ **To Update File Browser** - -```yaml -curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash -``` -___________________________________________________________________________________________ - -
    - -
    - VS Code Server - -

    - -

    VS Code Server

    - -To Install VS Code Server, ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/code-server.sh)" -``` - -[VS Code Server](https://code.visualstudio.com/docs/remote/vscode-server) is a service you can run on a remote development machine, like your desktop PC or a virtual machine (VM). It allows you to securely connect to that remote machine from anywhere through a vscode.dev URL, without the requirement of SSH. - - - -**VS Code Server Interface - http:// IP:8680** - -___________________________________________________________________________________________ - -
    - -
    - Webmin System Administration - -

    - -

    Webmin System Administration

    - -To Install Webmin System Administration [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png), ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/webmin.sh)" -``` - -If you prefer to manage all aspects of your Proxmox LXC from a graphical interface instead of the command line interface, Webmin might be right for you. - -Benefits include automatic daily security updates, backup and restore, file manager with editor, web control panel, and preconfigured system monitoring with optional email alerts. - - - -**Webmin Interface - https:// IP:10000 (https)** - -⚙️ **Initial Login** - -**username** - ```yaml - root - ``` - **password** - ```yaml - root - ``` - -⚙️ **To Update Webmin** - -```yaml -Update from the Webmin UI -``` -⚙️ **To Uninstall Webmin** - -Run in the LXC console -```yaml -bash /etc/webmin/uninstall.sh -``` -___________________________________________________________________________________________ - -
    - -
    - Syncthing LXC - -

    - -

    Syncthing LXC

    - -[Syncthing](https://syncthing.net/) is a continuous file synchronization program. It synchronizes files between two or more computers. - -To create a new Proxmox Syncthing LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/syncthing-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -⚙️ For the initial start, run `syncthing --gui-address=0.0.0.0:8384` in the LXC console, then go to the LXC IP:8384 In settings set the LXC IP address under the GUI (also set the GUI Authentication User and GUI Authentication Password) and Connections tab's and save. Reboot the LXC. - -**Syncthing Interface - IP:8384** - -⚙️ **To Update Syncthing** - -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - WireGuard LXC - -

    - -

    WireGuard LXC

    -

    With WGDashboard

    - -To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**WGDashboard Interface - http:// IP:10086** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` - -⚙️ **Host Configuration** - -Run in the LXC console - ```yaml - nano /etc/pivpn/wireguard/setupVars.conf - ``` - ⚙️**Add Clients** - - Run in the LXC console - ```yaml - pivpn add - ``` -⚙️ **To Update WireGuard** - -Run in the LXC console - ```yaml -apt update && apt upgrade -y -``` -____________________________________________________________________________________________ - -
    - - -
    - MeshCentral LXC - -

    - -

    MeshCentral LXC

    - -[MeshCentral](https://meshcentral.com/info/) is a full computer management web site. With MeshCentral, you can run your own web server to remotely manage and control computers on a local network or anywhere on the internet. - -To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**MeshCentral Interface - http:// IP** - -⚙️ **To Update MeshCentral** - -```yaml -Update from the MeshCentral UI -``` -____________________________________________________________________________________________ - -
    - -
    - Tailscale - -

    - -

    Tailscale

    - -[Tailscale](https://tailscale.com/) Creates a secure network between your servers, computers, and cloud instances. Even when separated by firewalls or subnets, Tailscale just works. - -To Install Talescale on an existing LXC, run the following in the Proxmox Shell (replace `106` with your LXC ID). - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/add-tailscale-lxc.sh)" -s 106 -``` -After the script finishes, reboot the LXC then run `tailscale up` in the LXC console - -[**Tailscale Login**](https://login.tailscale.com/start) - -⚙️ **To Update Tailscale** - -Run in the LXC console - ```yaml -apt update && apt upgrade -y -``` - -___________________________________________________________________________________________ - -
    - -
    - CrowdSec - -

    - -

    CrowdSec

    - -To Install CrowdSec, ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec.sh)" -``` - -[CrowdSec](https://crowdsec.net/) is a free, open-source and collaborative IPS. Analyze behaviors, respond to attacks & share signals across the community. - -[**Control center for your CrowdSec machines.**](https://app.crowdsec.net/product-tour) - -___________________________________________________________________________________________ - -
    - -
    - Keycloak LXC - -

    - -

    Keycloak LXC

    - -To create a new Proxmox Keycloak LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/keycloak-v4.sh)" -``` - -[Keycloak](https://www.keycloak.org/) is an Open Source Identity and Access Management solution for modern Applications and Services. - -**Keycloak Interface - http:// IP:8080** (First start can take a few minutes) - -⚙️ **Initial Login** - -The initial admin user can be added manually using the web frontend when accessed from localhost or automatically using environment variables. - -To add the initial admin user using environment variables, set `KEYCLOAK_ADMIN` for the initial admin username and `KEYCLOAK_ADMIN_PASSWORD` for the initial admin password. - -First, stop Keycloak -```yaml -systemctl stop keycloak.service -``` -then start Keycloak by coping & pasting the following (only needed once) -```yaml -cd /opt/keycloak -export KEYCLOAK_ADMIN=admin -export KEYCLOAK_ADMIN_PASSWORD=changeme - -bin/kc.sh start-dev -``` -⚙️ **To Update Keycloak** - -```yaml -working On -``` -___________________________________________________________________________________________ - -
    - -
    - Mikrotik RouterOS VM - -

    - -

    Mikrotik RouterOS VM

    - -[Mikrotik RouterOS](https://wiki.mikrotik.com/wiki/Manual:TOC) can be installed on a PC and will turn it into a router with all the necessary features - routing, firewall, bandwidth management, wireless access point, backhaul link, hotspot gateway, VPN server and more. - -To create a new Proxmox Mikrotik RouterOS VM, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/mikrotik-routeros-v4.sh)" -``` -Setup is done via VM console. - -

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1CPU ⚡

    - - -____________________________________________________________________________________________ - -
    - -
    - Vaultwarden LXC - -

    - -

    Vaultwarden LXC

    - -Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream [Bitwarden clients](https://bitwarden.com/download/), perfect for self-hosted deployment where running the official resource-heavy service might not be ideal. - -To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden-v4.sh)" -``` -⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. - -The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. - -Expect 30+ minute install time. -

    ⚡ Build Settings: 2048Mib RAM - 6GB Storage - 2vCPU ⚡

    -

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    - -**Vaultwarden Interface: CTIP:8000** - -⚙️ **Path to Vaultwarden .env file** (to find the `ADMIN_TOKEN`) -```yaml -/opt/vaultwarden/.env -``` - -⚙️ **To Update Vaultwarden (post 2022-05-29 installs only)** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/vaultwarden-update.sh)" -``` -⚙️ **To Update Web-vault (any)** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/web-vault-update.sh)" -``` - -____________________________________________________________________________________________ - -
    From fcb6baf8d45d68de2fc86c84bdfd370a33ed2d4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Nov 2022 05:38:27 -0400 Subject: [PATCH 3728/6505] Delete README_NEW.md --- README_NEW.md | 2642 ------------------------------------------------- 1 file changed, 2642 deletions(-) delete mode 100644 README_NEW.md diff --git a/README_NEW.md b/README_NEW.md deleted file mode 100644 index c6cff4fe..00000000 --- a/README_NEW.md +++ /dev/null @@ -1,2642 +0,0 @@ -

    Select a Proxmox Helper

    - -

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.

    - - -
    - Proxmox Tools -⬇__________________________________________________________________________________________ -
    - Proxmox VE 7 Post Install - -

    - -

    Proxmox VE 7 Post Install

    - -The script will give options to Disable the Enterprise Repo, Add/Correct PVE7 Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox VE and Reboot PVE. - -Run the following in the Proxmox Shell. ⚠️ **PVE7 ONLY** - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pve-install.sh)" -``` - -It's recommended to answer `y` to all options. - -____________________________________________________________________________________________ - -
    - -
    - Proxmox Kernel Clean - -

    - -

    Proxmox Kernel Clean

    - -Cleaning unused kernel images is not only good because of a reduced grub menu, but also gains some disk space. - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/kernel-clean.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox Edge Kernel Tool - -

    - -

    Proxmox Edge Kernel Tool

    - -Proxmox [Edge Kernels](https://github.com/fabianishere/pve-edge-kernel) are custom Linux Kernels for Proxmox VE 7. Keeping up with new Kernel releases instead of LTS - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox CPU Scaling Governor - -

    - -

    Proxmox CPU Scaling Governor

    - -CPU Scaling Governor enables the operating system to scale the CPU frequency up or down in order to save power or improve performance. - -[Generic Scaling Governors](https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html?#generic-scaling-governors) - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/scaling-governor.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox LXC Updater - -

    - -

    Proxmox LXC Updater

    - -Update All LXC's Fast & Easy - -Run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Proxmox Dark Theme - -

    - -

    Proxmox Discord Dark Theme

    - -A dark theme for the Proxmox Web UI by [Weilbyte](https://github.com/Weilbyte/PVEDiscordDark) - -Run the following in the Proxmox Shell. - -```yaml -bash <(curl -s https://raw.githubusercontent.com/Weilbyte/PVEDiscordDark/master/PVEDiscordDark.sh ) install -``` - -To uninstall the theme, simply run the script with the `uninstall` command. - -____________________________________________________________________________________________ - -
    - -
    - Proxmox Backup Server Post Install - -

    - -

    Proxmox Backup Server Post Install

    - -The script will give options to Disable the Enterprise Repo, Add/Correct PBS Sources, Enable the No-Subscription Repo, Add Test Repo, Disable Subscription Nag, Update Proxmox Backup Server and Reboot PBS. - -Run the following in the Proxmox Shell. ⚠️ **Proxmox Backup Server ONLY** - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pbs-install.sh)" -``` - -It's recommended to answer `y` to all options. - -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - Home Assistant -⬇__________________________________________________________________________________________ - -
    - Home Assistant OS VM - -

    - -

    Home Assistant OS VM

    -

    Option to create VM using Stable, Beta, Dev or Latest Image

    - -The script automates the manual process of finding, downloading and extracting the Official KVM (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. No hidden (kpartx, unzip, ect...) installs of any kind. Supports lvmthin, zfspool, nfs, dir and btrfs storage types. - -To create a new Proxmox Home Assistant OS VM, run the following in the Proxmox Shell - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/haos-vm-v4.sh)" -``` -

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    - -After the script completes, click on the VM, then on the **_Summary_** tab to find the VM IP. - -**Home Assistant Interface - IP:8123** - -____________________________________________________________________________________________ - -
    - -
    - PiMox HAOS VM - -

    - -

    PiMox HAOS VM

    -

    Option to create VM using Stable, Beta or Dev Image

    - -The script automates the manual process of finding, downloading and extracting the aarch64 (qcow2) disk image provided by the Home Assistant Team, creating a VM with user defined settings, importing and attaching the disk, setting the boot order and starting the VM. - -To create a new PiMox HAOS VM, run the following in the Proxmox Shell - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/pimox-haos-vm-v4.sh)" -``` -

    ⚡ Default Settings: 4GB RAM - 32GB Storage - 2vCPU - Stable Image⚡

    - -After the script completes, click on the VM Console to find the Home Assistant IP. - -**Home Assistant Interface - IP:8123** - -____________________________________________________________________________________________ - -
    - -
    - Home Assistant Container LXC - -

    Docker Logos | Docker -@home-assistantGitHub - portainer/portainer-docs: Portainer documentation

    - -

    Home Assistant Container LXC

    - -A standalone container-based installation of Home Assistant Core - -🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* - -To create a new Proxmox Home Assistant Container LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    - -**Home Assistant Interface - IP:8123** - -**Portainer Interface - IP:9000** - -⚙️ **Path to HA /config** -```yaml -/var/lib/docker/volumes/hass_config/_data - ``` -⚙️ **To Edit the HA configuration.yaml** (Recommend Using File Browser) - -Run in the LXC console -```yaml -nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -⚙️ **Copy Data From a Existing Home Assistant LXC to another Home Assistant LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data.sh)" - ``` - -⚙️ **To Install HACS:** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. - - -⚙️ [**Update Menu**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png) - -Run in the LXC console -```yaml -./update -``` -____________________________________________________________________________________________ -
    - -
    - Home Assistant Core LXC - -

    - -

    Home Assistant Core LXC

    - -A standalone installation of Home Assistant Core - -🛈 *If the LXC is created Privileged, the script will automatically set up USB passthrough.* - -To create a new Proxmox Home Assistant Core LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homeassistant-core-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 8GB Storage - 2vCPU ⚡

    - -⚠️ Initialize Home Assistant-Core (Only required once) - -Run in the LXC console -```yaml -cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass -``` - -***Home Assistant Interface - IP:8123*** - -⚙️ **Edit the HA configuration.yaml** - -Run in the LXC console -```yaml -nano .homeassistant/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -⚙️ **Install HACS:** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hacs-core.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. - -⚙️ **Update Home Assistant** - -Run in the LXC console -```yaml -systemctl stop homeassistant.service && source /srv/homeassistant/bin/activate && pip3 install --upgrade homeassistant && systemctl start homeassistant.service && exit -``` -____________________________________________________________________________________________ -
    - -
    - Podman Home Assistant Container LXC - -

    -@home-assistant

    - -

    Podman Home Assistant Container LXC

    -A standalone container-based installation of Home Assistant Core - -⚠️ Podman seems to need a privileged LXC - -To create a new Proxmox Podman Home Assistant Container LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/podman-homeassistant-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 16GB Storage - 2vCPU ⚡

    - -**Home Assistant Interface - IP:8123** - -**Yacht Interface - IP:8000** - -⚙️ **Path to HA /config** -```yaml -/var/lib/containers/storage/volumes/hass_config/_data - ``` -⚙️ **To edit the HA configuration.yaml** - -Run in the LXC console -```yaml -nano /var/lib/containers/storage/volumes/hass_config/_data/configuration.yaml -``` -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -⚙️ **Copy Data From a Existing Home Assistant LXC to a Podman Home Assistant LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/ha-copy-data-podman.sh)" - ``` - -⚙️ **To allow USB device passthrough:** - -Run in the Proxmox Shell. (**replace `106` with your LXC ID**) -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/usb-passthrough.sh)" -s 106 -``` - -Reboot the LXC to apply the changes - -⚙️ **To Install HACS:** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/podman_hacs.sh)" -``` -After install, reboot Home Assistant and **clear browser cache** then Add HACS integration. - -⚙️ **Initial Yacht Login** - -**username** - ```yaml - admin@yacht.local - ``` - **password** - ```yaml - pass - ``` - -____________________________________________________________________________________________ -
    -⬆__________________________________________________________________________________________ -
    - -
    - Automation -⬇__________________________________________________________________________________________ - -
    - ioBroker LXC - -

    - -

    ioBroker LXC

    - -[ioBroker](https://www.iobroker.net/#en/intro) is an open source automation platform. - -To create a new Proxmox ioBroker LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/iobroker-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**ioBroker Interface - IP:8081** - -⚙️ **To Update ioBroker** - -```yaml -update from the ioBroker UI -``` - -____________________________________________________________________________________________ - -
    - -
    - openHAB LXC - -

    - -

    openHAB LXC

    - -[openHAB](https://www.openhab.org/), a vendor and technology agnostic open source automation software for your home. - -To create a new Proxmox openHAB LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/openhab-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**openHAB Interface - IP:8080** - -⚙️ **To Update openHAB** - -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Homebridge LXC - -

    - -

    Homebridge LXC

    - -[Homebridge](https://homebridge.io/) allows you to integrate with smart home devices that do not natively support HomeKit - -To create a new Proxmox Homebridge LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homebridge-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -**Homebridge Interface - IP:8581** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` -Config File Path `/var/lib/homebridge/config.json` - -Storage Path `/var/lib/homebridge` - -Restart Command `sudo hb-service restart` - -Stop Command `sudo hb-service stop` - -Start Command `sudo hb-service start` - -View Logs Command `sudo hb-service logs` - -Systemd Service File `/etc/systemd/system/homebridge.service` - -Systemd Env File `/etc/default/homebridge` - -⚙️ **To Update Homebridge** - -```yaml -Update from the Homebridge UI -``` - - ___________________________________________________________________________________________ - -
    - - - -
    - ESPHome LXC - -

    - -

    ESPHome LXC

    - -[ESPHome](https://esphome.io/) is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems. - -To create a new Proxmox ESPHome LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/esphome-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**ESPHome Interface - IP:6052** - -⚙️ **To Update ESPHome** - -Run in the LXC console -```yaml -pip3 install esphome --upgrade -``` - -____________________________________________________________________________________________ - -
    - -
    - Node-Red LXC - -

    - -

    Node-Red LXC

    - -[Node-RED](https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. - -To create a new Proxmox Node-RED LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/node-red-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -**Node-Red Interface - IP:1880** - -⚙️ **To Restart Node-Red:** - -Run in the LXC console -```yaml -systemctl restart nodered -``` - -⚙️ **To Update Node-Red:** - -Run in the LXC console (Restart after update) -```yaml -npm install -g --unsafe-perm node-red -``` - -⚙️ **To Install Node-Red Themes** ⚠️ **Backup your flows before running this script!!** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/node-red-themes.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - n8n LXC - -

    - -

    n8n LXC

    - -[n8n](https://n8n.io/) is an extendable workflow automation tool which enables you to connect anything to everything. - -To create a new Proxmox n8n LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/n8n-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    - -**n8n Interface: IP:5678** - -⚙️ **To Update n8n** - -```yaml -npm update -g n8n -``` - -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - MQTT -⬇__________________________________________________________________________________________ - -
    - MQTT LXC - -

    - -

    MQTT LXC

    - -[Eclipse Mosquitto](https://mosquitto.org/) is an open source message broker that implements the MQTT protocol - -To create a new Proxmox MQTT LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mqtt-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -Mosquitto comes with a password file generating utility called mosquitto_passwd. -```yaml -sudo mosquitto_passwd -c /etc/mosquitto/passwd -``` -Password: < password > - -Create a configuration file for Mosquitto pointing to the password file we have just created. -```yaml -sudo nano /etc/mosquitto/conf.d/default.conf -``` -This will open an empty file. Paste the following into it. -```yaml -allow_anonymous false -persistence true -password_file /etc/mosquitto/passwd -listener 1883 -``` -Save and exit the text editor with "Ctrl+O", "Enter" and "Ctrl+X". - -Now restart Mosquitto server. -```yaml -sudo systemctl restart mosquitto -``` - -⚙️ **To Update MQTT:** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - EMQX LXC - -

    - - -

    EMQX LXC

    - -[EMQX](https://www.emqx.io/) is an Open-source MQTT broker with a high-performance real-time message processing engine, powering event streaming for IoT devices at massive scale. - -To create a new Proxmox EMQX LXC, run the following in the Proxmox Shell. - -```yaml - bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emqx-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - - -**EMQX Interface - IP:18083** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - public - ``` -⚙️ **Setup** - -Access Control ➡ Authentication ➡ Create ➡ Next ➡ Next ➡ Create ➡ Users ➡ Add ➡ Username / Password (to authenicate with MQTT) ➡ Save. You're now ready to enjoy a high-performance MQTT Broker. - -⚙️ **To Update EMQX** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - - ____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - - -
    - Database -⬇__________________________________________________________________________________________ - -
    - Mariadb LXC - -

    MariaDB

    - -

    Mariadb LXC

    -

    Option to Install Adminer

    - -[MariaDB](https://mariadb.org/) is a community-developed, commercially supported fork of the MySQL relational database management system. - -To create a new Proxmox Mariadb LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/mariadb-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -To enable MariaDB to listen to remote connections, you need to edit your defaults file. To do this, open the console in your MariaDB lxc: -```yaml -nano /etc/mysql/my.cnf -``` -Un-comment `port =3306` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". - -```yaml -nano /etc/mysql/mariadb.conf.d/50-server.cnf -``` -Comment `bind-address = 127.0.0.1` -Save and exit the editor with "Ctrl+O", "Enter" and "Ctrl+X". - -For new MariaDB installations, the next step is to run the included security script. This script changes some of the less secure default options. We will use it to block remote root logins and to remove unused database users. - -Run the security script: -```yaml -sudo mysql_secure_installation -``` -Enter current password for root (enter for none): `enter` - -Switch to unix_socket authentication [Y/n] `y` - -Change the root password? [Y/n] `n` - -Remove anonymous users? [Y/n] `y` - -Disallow root login remotely? [Y/n] `y` - -Remove test database and access to it? [Y/n] `y` - -Reload privilege tables now? [Y/n] `y` - -We will create a new account called admin with the same capabilities as the root account, but configured for password authentication. -```yaml -sudo mysql -``` -Prompt will change to ```MariaDB [(none)]>``` - -Create a new local admin (Change the username and password to match your preferences) -```yaml -CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password'; -``` -Give local admin root privileges (Change the username and password to match above) -```yaml -GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; -``` - -Now, we'll give the user admin root privileges and password-based access that can connect from anywhere on your local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.. Change the **_username_**, **_password_** and **_subnet_** to match your preferences: -```yaml -GRANT ALL ON *.* TO 'admin'@'192.168.100.%' IDENTIFIED BY 'password' WITH GRANT OPTION; -``` -Flush the privileges to ensure that they are saved and available in the current session: -```yaml -FLUSH PRIVILEGES; -``` -Following this, exit the MariaDB shell: -```yaml -exit -``` -Log in as the new database user you just created: -```yaml -mysql -u admin -p -``` -Create a new database: -```yaml -CREATE DATABASE homeassistant; -``` -Following this, exit the MariaDB shell: -```yaml -exit -``` -⚠️ Reboot the lxc - -Checking status. -```yaml -sudo systemctl status mariadb -``` -Change the recorder: `db_url:` in your HA configuration.yaml - -Example: -```yaml -recorder: - db_url: mysql://admin:password@192.168.100.26:3306/homeassistant?charset=utf8mb4 -``` - -⚙️ **To Update Mariadb:** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool - - `http://your-mariadb-lxc-ip/adminer/` - -____________________________________________________________________________________________ - -
    - -
    - PostgreSQL LXC - -

    - -

    PostgreSQL LXC

    -

    Option to Install Adminer

    - -[PostgreSQL](https://www.postgresql.org/), also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance. - -To create a new Proxmox PostgreSQL LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/postgresql-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -To make sure our PostgreSQL is secured with a strong password, set a password for its system user and then change the default database admin user account - -Change user password -```yaml -passwd postgres -``` -Login using Postgres system account - -```yaml -su - postgres -``` -Now, change the Admin database password -```yaml -psql -c "ALTER USER postgres WITH PASSWORD 'your-password';" -``` -Create a new user. -```yaml -psql -``` -```yaml -CREATE USER admin WITH PASSWORD 'your-password'; -``` -Create a new database: -```yaml -CREATE DATABASE homeassistant; -``` -Grant all rights or privileges on created database to the user -```yaml -GRANT ALL ON DATABASE homeassistant TO admin; -``` -To exit psql -```yaml -\q -``` -Then type exit to get back to root - -Change the recorder: `db_url:` in your HA configuration.yaml - -Example: -```yaml -recorder: - db_url: postgresql://admin:your-password@192.168.100.20:5432/homeassistant?client_encoding=utf8 -``` -⚙️ **To Update PostgreSQL** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -⚙️ [**Adminer**](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin) is a full-featured database management tool - - `http://your-PostgreSQL-lxc-ip/adminer/` - -____________________________________________________________________________________________ - -
    - -
    - InfluxDB LXC - -

    - -

    InfluxDB LXC

    - -

    Options to Install InfluxDB v1 or v2 and Telegraf

    - -[InfluxDB](https://www.influxdata.com/) is an open-source time series database developed by the company InfluxData. - -[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) is an open source plugin-driven server agent for collecting and reporting metrics. - -To create a new Proxmox InfluxDB LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/influxdb-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -⚙️ **InfluxDB Configuration** - -Run in the LXC console -```yaml -nano /etc/influxdb/influxdb.conf -``` - -⚙️ **Telegraf Configuration** - -Run in the LXC console -```yaml -nano /etc/telegraf/telegraf.conf -``` - -⚙️ **To Update InfluxDB/Telegraf** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - Zigbee - Zwave -⬇__________________________________________________________________________________________ - -
    - Zigbee2MQTT LXC - -

    - - -

    Zigbee2MQTT LXC

    - -

    Option to switch to Edge/dev branch

    - -[Zigbee2MQTT](https://www.zigbee2mqtt.io/) is a standalone nodejs application that connects a zigbee network to MQTT - -To create a new Proxmox Zigbee2MQTT LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zigbee2mqtt-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - - -⚙️ **Determine the location of your adapter** - -Run in the LXC console -```yaml -ls -l /dev/serial/by-id -``` -Example Output: ```lrwxrwxrwx 1 root root 13 Jun 19 17:30 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0``` - - -⚙️ ⚠️ **Before you start Zigbee2MQTT you need to edit the [configuration.yaml](https://www.zigbee2mqtt.io/guide/configuration/)** - -Run in the LXC console -```yaml -nano /opt/zigbee2mqtt/data/configuration.yaml -``` - -Save and exit the editor with “Ctrl+O”, “Enter” and “Ctrl+X” - -Example: -```yaml -frontend: - port: 9442 -homeassistant: true -permit_join: false -mqtt: - base_topic: zigbee2mqtt - server: 'mqtt://192.168.86.224:1883' - user: usr - password: pwd - keepalive: 60 - reject_unauthorized: true - version: 4 -serial: - port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 - #adapter: deconz #(uncomment for ConBee II) -advanced: - pan_id: GENERATE - network_key: GENERATE - channel: 20 -``` -⚙️ **Zigbee2MQTT can be started after completing the configuration** - -Run in the LXC console -```yaml -cd /opt/zigbee2mqtt && npm start -``` -⚙️ **To update Zigbee2MQTT** - -Run in the LXC console - ```yaml -cd /opt/zigbee2mqtt && bash update.sh - ``` -⚙️ **Copy Data From a Existing Zigbee2MQTT LXC to another Zigbee2MQTT LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/z2m-copy-data.sh)" - ``` - -____________________________________________________________________________________________ - -
    - -
    - deCONZ LXC - -

    - -

    deCONZ LXC

    - -[deCONZ](https://www.phoscon.de/en/conbee2/software#deconz) is used to configure, control and display Zigbee networks. - -To create a new Proxmox deCONZ LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/deconz-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**deCONZ Interface - IP:80** - -⚙️ **To Update deCONZ** - -Run in the LXC Console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Z-Wave JS UI LXC - -

    - -

    Z-Wave JS UI LXC

    - -[Z-Wave JS UI](https://github.com/zwave-js/zwave-js-ui#) is a fully configurable Z-Wave to MQTT Gateway and Control Panel. - -To create a new Proxmox Z-Wave JS UI LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/zwave-js-ui-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**Z-Wave JS UI Interface - IP:8091** - -⚙️ **Copy Data From a Existing Zwavejs2MQTT LXC to a Z-Wave JS UI LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-copy-data.sh)" - ``` -⚙️ **To Update Z-Wave JS UI** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/zwave-js-ui-update.sh)" -``` - -____________________________________________________________________________________________ -
    -⬆__________________________________________________________________________________________ -
    - -
    - Monitoring - Analytics -⬇__________________________________________________________________________________________ - -
    - Uptime Kuma LXC - -

    - -

    Uptime Kuma LXC

    - -Uptime Kuma is a self-hosted, open source, fancy uptime monitoring and alerting system. It can monitor HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server. - -To create a new Proxmox Uptime Kuma LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/uptimekuma-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1vCPU ⚡

    - -**Uptime Kuma Interface - IP:3001** - -⚙️ **To Update Uptime Kuma** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/uptimekuma-update.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Prometheus LXC - -

    - -

    Prometheus LXC

    - -[Prometheus](https://prometheus.io/) is an open-source systems monitoring and alerting toolkit - -To create a new Proxmox Prometheus LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/prometheus-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 1vCPU ⚡

    - -**Prometheus Interface - IP:9090** - -⚙️ **To Update Prometheus** - -```yaml -Working On -``` - -____________________________________________________________________________________________ - -
    - - -
    - Grafana LXC - -

    - -

    Grafana LXC

    - -[Grafana](https://grafana.com/) is a multi-platform open source analytics and interactive visualization web application. - -To create a new Proxmox Grafana LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grafana-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Grafana Interface - IP:3000** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` - -⚙️ **To Update Grafana** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - Docker -⬇__________________________________________________________________________________________ - -
    - Docker LXC - -

    - -

    Docker LXC

    -

    Options to Install Portainer and/or Docker Compose V2

    - -[Docker](https://www.docker.com/) is an open-source project for automating the deployment of applications as portable, self-sufficient containers. - -To create a new Proxmox Docker LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 4GB Storage - 2vCPU ⚡

    - -**⚠ Run Compose V2 by replacing the hyphen (-) with a space, using docker compose, instead of docker-compose.** - -**Portainer Interface - IP:9000** - -⚙️ **To Update** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Umbrel LXC - -

    - -

    Umbrel LXC

    - -[Umbrel](https://umbrel.com/) is a beautiful personal server OS for self-hosting. - - -To create a new Proxmox Umbrel LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/umbrel-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Umbrel Interface - IP** - -⚙️ **To Update Umbrel** - -```yaml -update from the Umbrel UI -``` - -____________________________________________________________________________________________ - -
    - -
    - CasaOS LXC - -

    - -

    CasaOS LXC

    - -[CasaOS](https://www.casaos.io/) is a community-based open source software focused on delivering simple home cloud experience around Docker ecosystem. - - -To create a new Proxmox CasaOS LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/casaos-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**CasaOS Interface - IP** - -⚙️ **To Update CasaOS** - -```yaml -update from the CasaOS UI -``` - -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - OS -⬇__________________________________________________________________________________________ - -
    - Debian LXC - -

    Debian

    - -

    Debian LXC

    -

    Option to select version 10 or 11

    - -To create a new Proxmox Debian (curl & sudo) LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/debian-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -⚙️ **To Update Debian** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - - -
    - Ubuntu LXC - -

    Ubuntu

    - -

    Ubuntu LXC

    -

    Option to select version 18.04, 20.04, 21.10 or 22.04

    - -To create a new Proxmox Ubuntu (curl & sudo) LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/ubuntu-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU - 22.04 ⚡

    - -⚙️ **To Update Ubuntu** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - Server - Networking -⬇__________________________________________________________________________________________ - -
    - Nginx Proxy Manager LXC - -

    hero

    - - -

    Nginx Proxy Manager LXC

    - -[Nginx Proxy Manager](https://nginxproxymanager.com/) Expose your services easily and securely - -To create a new Proxmox Nginx Proxy Manager LXC Container, run the following in the Proxmox Shell. - -```yaml - bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginx-proxy-manager-v4.sh)" -``` -

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 1vCPU ⚡

    - -____________________________________________________________________________________ - -Forward port `80` and `443` from your router to your Nginx Proxy Manager LXC IP. - -Add the following to your `configuration.yaml` in Home Assistant. -```yaml - http: - use_x_forwarded_for: true - trusted_proxies: - - 192.168.100.27 ###(Nginx Proxy Manager LXC IP)### -``` - -**Nginx Proxy Manager Interface - IP:81** - -⚙️ **Initial Login** - -**username** - ```yaml - admin@example.com - ``` - **password** - ```yaml - changeme - ``` -⚙️ **To Update Nginx Proxy Manager** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/npm_update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - UniFi Network Application LXC - -

    - -

    UniFi Network Application LXC

    - -

    With Local Controller Option

    - -An application designed to optimize UniFi home and business networks with ease. - -To create a new Proxmox UniFi Network Application LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/unifi-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**UniFi Interface - https:// IP:8443** - -⚙️ **To Update UniFi** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/unifi-update.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Omada Controller LXC - -

    - -

    Omada Controller LXC

    - -Omada Controller is software which is used to manage the EAP - -To create a new Proxmox Omada Controller LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omada-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Omada Interface - https:// IP:8043** - -`tpeap status` show status of Omada Controller - -`tpeap start` start Omada Controller - -`tpeap stop` stop Omada Controller - -⚙️ **To Update Omada** - -[#403](https://github.com/tteck/Proxmox/issues/402#issue-1328460983) - -____________________________________________________________________________________________ - -
    - -
    - WireGuard LXC - -

    - -

    WireGuard LXC

    -

    With WGDashboard

    - -To create a new Proxmox WireGuard LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wireguard-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**WGDashboard Interface - http:// IP:10086** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` - -⚙️ **Host Configuration** - -Run in the LXC console - ```yaml - nano /etc/pivpn/wireguard/setupVars.conf - ``` - ⚙️**Add Clients** - - Run in the LXC console - ```yaml - pivpn add - ``` -⚙️ **To Update WireGuard** - -Run in the LXC console - ```yaml -apt update && apt upgrade -y -``` -____________________________________________________________________________________________ - -
    - - -
    - MeshCentral LXC - -

    - -

    MeshCentral LXC

    - -[MeshCentral](https://meshcentral.com/info/) is a full computer management web site. With MeshCentral, you can run your own web server to remotely manage and control computers on a local network or anywhere on the internet. - -To create a new Proxmox MeshCentral LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/meshcentral-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**MeshCentral Interface - http:// IP** - -⚙️ **To Update MeshCentral** - -```yaml -Update from the MeshCentral UI -``` -____________________________________________________________________________________________ - -
    - -
    - Tailscale - -

    - -

    Tailscale

    - -[Tailscale](https://tailscale.com/) Creates a secure network between your servers, computers, and cloud instances. Even when separated by firewalls or subnets, Tailscale just works. - -To Install Talescale on an existing LXC, run the following in the Proxmox Shell (replace `106` with your LXC ID). - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/add-tailscale-lxc.sh)" -s 106 -``` -After the script finishes, reboot the LXC then run `tailscale up` in the LXC console - -[**Tailscale Login**](https://login.tailscale.com/start) - -⚙️ **To Update Tailscale** - -Run in the LXC console - ```yaml -apt update && apt upgrade -y -``` - -___________________________________________________________________________________________ - -
    - -
    - CrowdSec - -

    - -

    CrowdSec

    - -To Install CrowdSec, ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/crowdsec.sh)" -``` - -[CrowdSec](https://crowdsec.net/) is a free, open-source and collaborative IPS. Analyze behaviors, respond to attacks & share signals across the community. - -[**Control center for your CrowdSec machines.**](https://app.crowdsec.net/product-tour) - -___________________________________________________________________________________________ - -
    - -
    - Keycloak LXC - -

    - -

    Keycloak LXC

    - -To create a new Proxmox Keycloak LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/keycloak-v4.sh)" -``` - -[Keycloak](https://www.keycloak.org/) is an Open Source Identity and Access Management solution for modern Applications and Services. - -**Keycloak Interface - http:// IP:8080** (First start can take a few minutes) - -⚙️ **Initial Login** - -The initial admin user can be added manually using the web frontend when accessed from localhost or automatically using environment variables. - -To add the initial admin user using environment variables, set `KEYCLOAK_ADMIN` for the initial admin username and `KEYCLOAK_ADMIN_PASSWORD` for the initial admin password. - -First, stop Keycloak -```yaml -systemctl stop keycloak.service -``` -then start Keycloak by coping & pasting the following (only needed once) -```yaml -cd /opt/keycloak -export KEYCLOAK_ADMIN=admin -export KEYCLOAK_ADMIN_PASSWORD=changeme - -bin/kc.sh start-dev -``` -⚙️ **To Update Keycloak** - -```yaml -working On -``` -___________________________________________________________________________________________ - -
    - -
    - Mikrotik RouterOS VM - -

    - -

    Mikrotik RouterOS VM

    - -[Mikrotik RouterOS](https://wiki.mikrotik.com/wiki/Manual:TOC) can be installed on a PC and will turn it into a router with all the necessary features - routing, firewall, bandwidth management, wireless access point, backhaul link, hotspot gateway, VPN server and more. - -To create a new Proxmox Mikrotik RouterOS VM, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/vm/mikrotik-routeros-v4.sh)" -``` -Setup is done via VM console. - -

    ⚡ Default Settings: 1GB RAM - 2GB Storage - 1CPU ⚡

    - - -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - Media - Photo -⬇__________________________________________________________________________________________ - -
    - Plex Media Server LXC - -

    - -

    Plex Media Server LXC

    -

    With Hardware Acceleration Support

    -To create a new Proxmox Plex Media Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/plex-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Plex Media Server Interface - IP:32400/web** - -⚙️ **To Update Plex Media Server:** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -⚙️ **Copy Data From a Existing Plex Media Server LXC to another Plex Media Server LXC** - -Run in the Proxmox Shell -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/pms-copy-data.sh)" - ``` - -____________________________________________________________________________________________ - -
    - -
    - Emby Media Server LXC -

    -

    Emby Media Server LXC

    - -[Emby](https://emby.media/) brings together your personal videos, music, photos, and live television. - -To create a new Proxmox Emby Media Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/emby-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Emby Media Server Interface - IP:8096** - -⚙️ **To Update Emby** - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/emby-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - Jellyfin Media Server LXC -

    -

    Jellyfin Media Server LXC

    - -[TurnKey has a LXC CT for Jellyfin](https://www.turnkeylinux.org/mediaserver) - -To create a new Proxmox Jellyfin Media Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/jellyfin-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**Jellyfin Media Server Interface - IP:8096** - -FFmpeg path: `/usr/lib/jellyfin-ffmpeg/ffmpeg` - -⚙️ **To Update Jellyfin Media Server** - -Run in the LXC console -```yaml -apt update && apt upgrade -y -``` -____________________________________________________________________________________________ - -
    - -
    - NextCloudPi LXC - -

    - -

    NextCloudPi LXC

    - -[NextCloudPi LXC](https://github.com/nextcloud/nextcloudpi#features) is the most popular self-hosted collaboration solution. - -To create a new Proxmox NextCloudPi LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nextcloudpi-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -❗1️. Set nc trusted domains - -Run in the LXC console -``` -sudo ncp-config -``` -Go to config ➡ nc-trusted-domains, add `0.0.0.0` or a static NextCloudPi IP - -Get back to the command prompt, and restart Apache2 `sudo service apache2 restart` - -❗2. **NextCloudPi Interface - https:// IP/** - -____________________________________________________________________________________________ - -
    - -
    - OpenMediaVault LXC - -

    - -

    OpenMediaVault LXC

    - -[OpenMediaVault](https://www.openmediavault.org/) is the next generation network attached storage (NAS) solution based on Debian Linux. - -To create a new Proxmox OpenMediaVault LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/omv-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -**OpenMediaVault Interface - IP** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - openmediavault - ``` - -____________________________________________________________________________________________ - -
    - -
    - Navidrome LXC - -

    - -

    Navidrome LXC

    - -[Navidrome](https://www.navidrome.org/) allows you to enjoy your music collection from anywhere, by making it available through a modern Web UI and through a wide range of third-party compatible mobile apps, for both iOS and Android devices. - -To create a new Proxmox Navidrome LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/navidrome-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 2vCPU ⚡

    - -To change Navidrome music folder path, edit: `/var/lib/navidrome/navidrome.toml` - -**Navidrome Interface - IP:4533** - -⚙️ **To Update Navidrome** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/navidrome-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - PhotoPrism LXC - -

    - -

    PhotoPrism LXC

    - -[PhotoPrism](https://photoprism.app/) is an AI-powered app for browsing, organizing & sharing your photo collection. - -To create a new Proxmox PhotoPrism LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism-v4.sh)" -``` -The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. -

    ⚡ Build Settings: 3GB RAM - 8GB Storage - 2vCPU ⚡

    -

    ⚡ Normal Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**PhotoPrism Interface - IP:2342** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - changeme - ``` -[PhotoSync](https://www.photosync-app.com/home.html) - -⚙️ **To Update or Change Branch** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/photoprism-update.sh)" -``` -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - Ad Blocker - DNS -⬇__________________________________________________________________________________________ - -
    - Pi-hole LXC - -

    - -

    Pi-hole LXC

    - -[Pi-hole](https://pi-hole.net/) is a Linux network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole and optionally a DHCP server. - -To create a new Proxmox Pi-hole LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/pihole-v4.sh)" -``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -⚠️ **Reboot Pi-hole LXC after install** - -**Pi-hole Interface - http:// IP/admin** - -⚙️ **To set your password:** - -Run in the LXC console - -```yaml -pihole -a -p -``` -____________________________________________________________________________________________ - -
    - -
    - Technitium DNS LXC - -

    - -

    Technitium DNS LXC

    -An open source authoritative as well as recursive DNS server - -To create a new Proxmox Technitium DNS LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Technitium DNS Interface - IP:5380** - -⚙️ **To Update Technitium DNS** - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/technitiumdns-update.sh)" -``` -__________________________________________________________________________________________ - -
    - - -
    - AdGuard Home LXC - -

    - -

    AdGuard Home LXC

    - -To create a new Proxmox AdGuard Home LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/adguard-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**AdGuard Home Setup Interface - IP:3000 (After Setup use only IP)** - - (For the Home Assistant Integration, use port `80` not `3000`) - -⚙️ **To Update Adguard** - -```yaml -Update from the Adguard UI -``` -__________________________________________________________________________________________ - -
    - -
    - Blocky LXC - -

    - -

    Blocky LXC

    - -[Blocky](https://0xerr0r.github.io/blocky/) is a DNS proxy and ad-blocker for the local network written in Go. 🚨 For Advanced Users. No UI. - -To create a new Proxmox Blocky LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/blocky-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - - -⚙️ **Blocky Config Path** - -```yaml -/opt/blocky/config.yml -``` -__________________________________________________________________________________________ - -
    - -⬆__________________________________________________________________________________________ -
    - -
    - Document - Notes -⬇__________________________________________________________________________________________ - -
    - Paperless-ngx LXC - -

    - -

    Paperless-ngx LXC

    - -[Paperless-ngx](https://paperless-ngx.readthedocs.io/en/latest/#) is a document management system that transforms your physical documents into a searchable online archive so you can keep, well, less paper. - -To create a new Proxmox Paperless-ngx LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/paperless-ngx-v4.sh)" -``` - -

    ⚡ Default Settings: 2048MiB RAM - 4GB Storage - 2vCPU ⚡

    - -**Paperless-ngx Interface - IP:8000** - -🛈 A paperless.creds file is in root home directory that contains the usernames and passwords. - -Run in the LXC Console -```yaml -cat paperless.creds -``` - -⚙️ **To Update Paperless-ngx** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/paperless-ngx-update.sh)" -``` -____________________________________________________________________________________________ - -
    - -
    - Trilium LXC - -

    - -

    Trilium LXC

    - -[Trilium](https://github.com/zadam/trilium#trilium-notes) is a hierarchical note taking application with focus on building large personal knowledge bases. - -To create a new Proxmox Trilium LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/trilium-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Trilium Interface - IP:8080** - -⚙️ **To Update Trilium** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/trilium-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - Wiki.js LXC - -

    - -

    Wiki.js LXC

    - -[Wiki.js](https://js.wiki/) is a modern, lightweight and powerful wiki app built on NodeJS. - -To create a new Proxmox Wiki.js LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/wikijs-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Wiki.js Interface - IP:3000** - -____________________________________________________________________________________________ - -
    - -
    - NocoDB LXC - -

    - -

    NocoDB LXC

    - -[NocoDB](https://www.nocodb.com/) is an open source #NoCode platform that turns any database into a smart spreadsheet. Airtable Alternative. - -To create a new Proxmox NocoDB LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nocodb-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 4GB Storage - 1vCPU ⚡

    - -**NocoDB Interface - IP:8080/dashboard** - -⚙️ **To Update NocoDB** - -Run in the LXC console -```yaml -cd /opt/nocodb && npm run upgrade -``` - -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - -
    - Dashboards -⬇__________________________________________________________________________________________ - -
    - Heimdall Dashboard LXC - -

    - -

    Heimdall Dashboard LXC

    - -[Heimdall Application Dashboard](https://camo.githubusercontent.com/bcfd4f74c93b25bea7b14eacbafd649206bf754a3d4b596329968f0ee569cf3c/68747470733a2f2f692e696d6775722e636f6d2f4d72433451704e2e676966) is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like. - -To create a new Proxmox Heimdall Dashboard LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/heimdalldashboard-v4.sh)" -``` -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Heimdall Dashboard Interface - IP:7990** - -⚙️ **To Update Heimdall Dashboard** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/heimdalldashboard-all-update.sh)" -``` - -__________________________________________________________________________________________ - -
    - -
    - Homepage LXC - -

    - -

    Homepage LXC

    - -[Homepage](https://github.com/benphelps/homepage) is a self-hosted dashboard. - -To create a new Proxmox Homepage LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/homepage-v4.sh)" -``` - -

    ⚡ Default Settings: 1GB RAM - 3GB Storage - 2vCPU ⚡

    - -[Configuration](https://github.com/benphelps/homepage/wiki) (bookmarks.yaml, services.yaml, widgets.yaml) path: `/opt/homepage/config/` - -**Homepage Interface - IP:3000** - -⚙️ **To Update Homepage** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/homepage-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - Dashy LXC - -

    - -

    Dashy LXC

    - -Dashy helps you organize your self-hosted services by making them accessible from a single place - -To create a new Proxmox Dashy LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/dashy-v4.sh)" -``` -

    ⚡ Default Settings: 2GB RAM - 3GB Storage - 2vCPU ⚡

    - -**Dashy Interface - IP:4000** - -After getting everything setup the way you want in interactive mode and saved to disk, you have to go into update configuration and rebuild application. - -⚙️ **To Update Dashy** - -Run in the LXC Console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/dashy-update.sh)" -``` - -__________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ -
    - - -
    - File - Code -⬇__________________________________________________________________________________________ -
    - File Browser - -

    - -

    File Browser

    - -To Install File Browser, ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/filebrowser.sh)" -``` - -[File Browser](https://filebrowser.org/features) is a create-your-own-cloud-kind of software where you can install it on a server, direct it to a path and then access your files through a nice web interface. Many available features! - - - -**File Browser Interface - http:// IP:8080** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - changeme - ``` - -⚙️ **To Update File Browser** - -```yaml -curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash -``` -___________________________________________________________________________________________ - -
    - -
    - VS Code Server - -

    - -

    VS Code Server

    - -To Install VS Code Server, ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/code-server.sh)" -``` - -[VS Code Server](https://code.visualstudio.com/docs/remote/vscode-server) is a service you can run on a remote development machine, like your desktop PC or a virtual machine (VM). It allows you to securely connect to that remote machine from anywhere through a vscode.dev URL, without the requirement of SSH. - - - -**VS Code Server Interface - http:// IP:8680** - -___________________________________________________________________________________________ - -
    - -
    - Webmin System Administration - -

    - -

    Webmin System Administration

    - -To Install Webmin System Administration [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/file-manager.png), ⚠️ run the following in the LXC console. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/webmin.sh)" -``` - -If you prefer to manage all aspects of your Proxmox LXC from a graphical interface instead of the command line interface, Webmin might be right for you. - -Benefits include automatic daily security updates, backup and restore, file manager with editor, web control panel, and preconfigured system monitoring with optional email alerts. - - - -**Webmin Interface - https:// IP:10000 (https)** - -⚙️ **Initial Login** - -**username** - ```yaml - root - ``` - **password** - ```yaml - root - ``` - -⚙️ **To Update Webmin** - -```yaml -Update from the Webmin UI -``` -⚙️ **To Uninstall Webmin** - -Run in the LXC console -```yaml -bash /etc/webmin/uninstall.sh -``` -___________________________________________________________________________________________ - -
    - -
    - Syncthing LXC - -

    - -

    Syncthing LXC

    - -[Syncthing](https://syncthing.net/) is a continuous file synchronization program. It synchronizes files between two or more computers. - -To create a new Proxmox Syncthing LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/syncthing-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -⚙️ For the initial start, run `syncthing --gui-address=0.0.0.0:8384` in the LXC console, then go to the LXC IP:8384 In settings set the LXC IP address under the GUI (also set the GUI Authentication User and GUI Authentication Password) and Connections tab's and save. Reboot the LXC. - -**Syncthing Interface - IP:8384** - -⚙️ **To Update Syncthing** - -```yaml -apt update && apt upgrade -y -``` - -____________________________________________________________________________________________ - -
    - -
    - Daemon Sync Server LXC - -

    - -

    Daemon Sync Server LXC

    - -Sync files from app to server, share photos & videos, back up your data and stay secure inside local network. - -To create a new Proxmox Daemon Sync Server LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/daemonsync-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 8GB Storage - 1vCPU ⚡

    - -**Daemon Sync Server Interface - IP:8084** - -Search: `DAEMON Sync` in your favorite app store - -__________________________________________________________________________________________ - -
    -⬆________________________________________________________________________________________ - -
    - -
    - Misc. -⬇________________________________________________________________________________________ - -
    - Vaultwarden LXC - -

    - -

    Vaultwarden LXC

    - -Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream [Bitwarden clients](https://bitwarden.com/download/), perfect for self-hosted deployment where running the official resource-heavy service might not be ideal. - -To create a new Proxmox Vaultwarden LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/vaultwarden-v4.sh)" -``` -⚠️ Vaultwarden needs to be behind a proxy (Nginx Proxy Manager) to obtain HTTPS and to allow clients to connect. - -The script builds from source, which takes time and resources. After the build, the script will automatically set resources to Normal Settings. - -Expect 30+ minute install time. -

    ⚡ Build Settings: 3072Mib RAM - 6GB Storage - 2vCPU ⚡

    -

    ⚡ Normal Settings: 512Mib RAM - 6GB Storage - 1vCPU ⚡

    - -**Vaultwarden Interface: IP:8000** - -**Vaultwarden Admin Interface: IP:8000/admin** - -⚙️ **Vaultwarden .env file** (to find the `ADMIN_TOKEN`) -```yaml -cat /opt/vaultwarden/.env -``` - -⚙️ **To Update Vaultwarden (post 2022-05-29 installs only)** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/vaultwarden-update.sh)" -``` -⚙️ **To Update Web-vault (any)** - -Run in the LXC console -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/web-vault-update.sh)" -``` - -____________________________________________________________________________________________ - -
    - -
    - grocy LXC - -

    - -

    grocy LXC

    - -[grocy](https://grocy.info/) is a web-based self-hosted groceries & household management solution for your home. - -To create a new Proxmox grocy LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/grocy-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**grocy Interface: http:// IP** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - admin - ``` - -⚙️ **To Update grocy** - -Run in the LXC console - ```yaml -bash /var/www/html/update.sh -``` -____________________________________________________________________________________________ - -
    - -
    - MagicMirror Server LXC - -

    - -

    MagicMirror Server LXC

    - -[MagicMirror²](https://docs.magicmirror.builders/) is an open source modular smart mirror platform. - -To create a new MagicMirror Server LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/magicmirror-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 3GB Storage - 1vCPU ⚡

    - -**MagicMirror Interface - IP:8080** - -⚙️ **[Configuration](https://docs.magicmirror.builders/configuration/introduction.html#configuring-your-magicmirror)** -```yaml -/opt/magicmirror/config/config.js -``` -⚙️ **[Update MagicMirror](https://docs.magicmirror.builders/getting-started/upgrade-guide.html#upgrade-guide)** - -Run in the LXC Console -```yaml -cd /opt/magicmirror && git pull && npm install --only=prod --omit=dev -``` -____________________________________________________________________________________________ - -
    - -
    - Whoogle LXC - -

    - -

    Whoogle LXC

    - -Get Google search results, but without any ads, javascript, AMP links, cookies, or IP address tracking. - -To create a new Proxmox Whoogle LXC, run the following in the Proxmox Shell. - -```yaml -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/whoogle-v4.sh)" -``` - -

    ⚡ Default Settings: 512MiB RAM - 2GB Storage - 1vCPU ⚡

    - -**Whoogle Interface - IP:5000** - -⚙️ **To Update Whoogle** - -Run in the LXC console -```yaml -pip3 install whoogle-search --upgrade -``` -____________________________________________________________________________________________ - -
    - -
    - MotionEye VMS LXC - -

    - -

    MotionEye VMS LXC

    - -To create a new Proxmox MotionEye VMS LXC, run the following in the Proxmox Shell. - -``` -bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/motioneye-v4.sh)" -``` - -

    ⚡ Default Settings: 2GB RAM - 8GB Storage - 2vCPU ⚡

    - -**MotionEye Interface - IP:8765** - -⚙️ **Initial Login** - -**username** - ```yaml - admin - ``` - **password** - ```yaml - - ``` - -⚙️ **To Update MotionEye** - -Run in the LXC console - ```yaml -pip install motioneye --upgrade -``` -____________________________________________________________________________________________ - -
    -⬆__________________________________________________________________________________________ - -
    From fd9cab299fa76db5ebdd58553d4f50e784ccf294 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Nov 2022 05:40:46 -0400 Subject: [PATCH 3729/6505] Delete _config.yml --- _config.yml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 _config.yml diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 6979f9d8..00000000 --- a/_config.yml +++ /dev/null @@ -1,6 +0,0 @@ -theme: jekyll-theme-hacker -title: Proxmox Helper Scripts -description: Proxmox Scripts For Home Automation -markdown: kramdown -kramdown: - parse_block_html: true From 337d62d28d4a5136c0685d29619ca0e9b2eb3f92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Nov 2022 19:26:04 -0400 Subject: [PATCH 3730/6505] Create scrypted-install.sh --- setup/scrypted-install.sh | 195 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 setup/scrypted-install.sh diff --git a/setup/scrypted-install.sh b/setup/scrypted-install.sh new file mode 100644 index 00000000..2ad93568 --- /dev/null +++ b/setup/scrypted-install.sh @@ -0,0 +1,195 @@ +#!/usr/bin/env bash +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + exit 1 +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get -y install software-properties-common apt-utils &>/dev/null +apt-get -y update &>/dev/null +apt-get -y upgrade &>/dev/null +apt-get -y install \ + build-essential \ + gcc \ + gir1.2-gtk-3.0 \ + libcairo2-dev \ + libgirepository1.0-dev \ + libglib2.0-dev \ + libjpeg-dev \ + libgif-dev \ + libopenjp2-7 \ + libpango1.0-dev \ + librsvg2-dev \ + pkg-config \ + curl \ + sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing GStreamer" +apt-get -y install \ + gstreamer1.0-tools \ + libgstreamer1.0-dev \ + libgstreamer-plugins-base1.0-dev \ + libgstreamer-plugins-bad1.0-dev \ + gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-ugly \ + gstreamer1.0-libav \ + gstreamer1.0-alsa &>/dev/null +msg_ok "Installed GStreamer" + +msg_info "Setting up Node.js Repository" +curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Installing Python3" +apt-get -y install \ + python3 \ + python3-dev \ + python3-gi \ + python3-gst-1.0 \ + python3-matplotlib \ + python3-numpy \ + python3-opencv \ + python3-pil \ + python3-pip \ + python3-setuptools \ + python3-skimage \ + python3-wheel &>/dev/null +python3 -m pip install --upgrade pip &>/dev/null +python3 -m pip install aiofiles debugpy typing_extensions typing &>/dev/null +msg_ok "Installed Python3" + +read -r -p "Would you like to add Coral Edge TPU support? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + CORAL="Y" +else + CORAL="N" +fi + +if [[ $CORAL == "Y" ]]; then +msg_info "Adding Coral Edge TPU Support" +echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | tee /etc/apt/sources.list.d/coral-edgetpu.list &>/dev/null +curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - &>/dev/null +apt-get -y update &>/dev/null +apt-get -y install libedgetpu1-std &>/dev/null +msg_ok "Coral Edge TPU Support Added" +fi + +msg_info "Installing Scrypted" +sudo -u root npx -y scrypted@latest install-server &>/dev/null +msg_info "Installed Scrypted" + +msg_info "Creating Service" +service_path="/etc/systemd/system/scrypted.service" +echo "[Unit] +Description=Scrypted service +After=network.target + +[Service] +User=root +Group=root +Type=simple +ExecStart=/usr/bin/npx -y scrypted serve +Restart=on-failure +RestartSec=3 + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now scrypted.service &>/dev/null +msg_ok "Created Service" +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 690fb173fa6864fbe700973f841fc4c5dde5951c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Nov 2022 19:27:46 -0400 Subject: [PATCH 3731/6505] Create scrypted-v4.sh --- ct/scrypted-v4.sh | 283 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 ct/scrypted-v4.sh diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh new file mode 100644 index 00000000..1b696209 --- /dev/null +++ b/ct/scrypted-v4.sh @@ -0,0 +1,283 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Scrypted" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + cat <<"EOF" + _____ __ __ + / ___/____________v4______ / /____ ____/ / + \__ \/ ___/ ___/ / / / __ \/ __/ _ \/ __ / + ___/ / /__/ / / /_/ / /_/ / /_/ __/ /_/ / +/____/\___/_/ \__, / .___/\__/\___/\__,_/ + /____/_/ +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:10443${CL} \n" From e2158457fa25b5a4b9bbdf0470e837afbfe40905 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Nov 2022 20:20:46 -0400 Subject: [PATCH 3732/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c5cd9005..3bb962f9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-04 + +### Changed + +- **Scrypted LXC** + - NEW Script + ## 2022-11-01 ### Changed From 4559f66f97e2b2763a90c844bafb1c43581a69ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Nov 2022 08:14:27 -0400 Subject: [PATCH 3733/6505] Update photoprism-install.sh golang 1.19.3 --- setup/photoprism-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 67015a34..3cd2553c 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -98,8 +98,8 @@ apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" msg_info "Installing Golang (Patience)" -wget https://golang.org/dl/go1.19.2.linux-amd64.tar.gz &>/dev/null -tar -xzf go1.19.2.linux-amd64.tar.gz -C /usr/local &>/dev/null +wget https://golang.org/dl/go1.19.3.linux-amd64.tar.gz &>/dev/null +tar -xzf go1.19.3.linux-amd64.tar.gz -C /usr/local &>/dev/null ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null go install github.com/tianon/gosu@latest &>/dev/null go install golang.org/x/tools/cmd/goimports@latest &>/dev/null @@ -196,7 +196,7 @@ apt-get autoremove >/dev/null apt-get autoclean >/dev/null rm -rf /var/{cache,log}/* \ /photoprism \ - /go1.19.2.linux-amd64.tar.gz \ + /go1.19.3.linux-amd64.tar.gz \ /libtensorflow-linux-avx2-1.15.2.tar.gz \ /libtensorflow-linux-avx-1.15.2.tar.gz \ /libtensorflow-linux-cpu-1.15.2.tar.gz From 211c730f47f7015aee4ced10b999c5389db9a4a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Nov 2022 08:27:36 -0400 Subject: [PATCH 3734/6505] Update photoprism-update.sh changes from @chx0003 --- misc/photoprism-update.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/photoprism-update.sh b/misc/photoprism-update.sh index f6e99980..143eb9a2 100644 --- a/misc/photoprism-update.sh +++ b/misc/photoprism-update.sh @@ -91,7 +91,8 @@ echo -e "${CM}${CL} \r" echo -en "${GN} Building PhotoPrism ${BR} branch... " sudo make all &>/dev/null sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null -sudo cp -a assets/ /opt/photoprism/assets/ &>/dev/null +sudo rm -rf /opt/photoprism/assets +sudo cp -r assets/ /opt/photoprism/ &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Cleaning... " From 0d8b0faeec7f67806f5c0bab80115467889d15ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Nov 2022 08:29:00 -0400 Subject: [PATCH 3735/6505] Update photoprism-install.sh changes from @chx0003 --- setup/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 3cd2553c..449f86d7 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -139,7 +139,7 @@ msg_ok "Cloned PhotoPrism" msg_info "Building PhotoPrism (Patience)" NODE_OPTIONS=--max_old_space_size=2048 make all &>/dev/null ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null -cp -a assets/ /opt/photoprism/assets/ &>/dev/null +cp -r assets/ /opt/photoprism/ &>/dev/null msg_ok "Built PhotoPrism" env_path="/var/lib/photoprism/.env" From 6406ed569865f6c25abb5913b67c3bf52e14d128 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Nov 2022 07:33:12 -0500 Subject: [PATCH 3736/6505] Update scrypted-v4.sh fix path to scrypted-install.sh --- ct/scrypted-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh index 1b696209..a9de8c1c 100644 --- a/ct/scrypted-v4.sh +++ b/ct/scrypted-v4.sh @@ -273,7 +273,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ From 312377af97ee0a54fdc62eaca3b863416db6f7eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 6 Nov 2022 14:34:11 -0500 Subject: [PATCH 3737/6505] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b72e4da..5334d58e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,2 @@ -

    https://tteck.github.io/Proxmox/

    +

    Proxmox Helper Scripts

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.
    - From d521a3c682554890ae304d1f2b3cd4929cdf91cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Nov 2022 07:15:50 -0500 Subject: [PATCH 3738/6505] Update npm_update.sh remove junk --- misc/npm_update.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/misc/npm_update.sh b/misc/npm_update.sh index ca817b59..af3cef7e 100644 --- a/misc/npm_update.sh +++ b/misc/npm_update.sh @@ -54,7 +54,6 @@ function msg() { local TEXT="$1" echo -e "$TEXT" } -T="$(date +%M)" if [ -f /lib/systemd/system/npm.service ]; then echo -en "${GN} Prep For Update... " @@ -168,10 +167,9 @@ systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm echo -e "${CM}${CL} \r" -TS="$(($(date +%M) - T))" IP=$(hostname -I | cut -f1 -d ' ') -echo -e "${GN}Successfully Updated Nginx Proxy Manager to ${RD}${RELEASE}${CL} and it took ${RD}${TS} minutes.${CL} +echo -e "${GN}Successfully Updated Nginx Proxy Manager to ${RD}${RELEASE}${CL}. NPM should be reachable at ${BL}http://${IP}:81 ${CL} " From fe00c2974ce774391d7e18bb066c9f49fe761f71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 8 Nov 2022 09:35:55 -0500 Subject: [PATCH 3739/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 36ee3afa..668325c2 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -64,14 +64,14 @@ else exit fi function header_info { -echo -e "${HA} - __ __ ___ ____ _____ - / / / // |v4/ __ \/ ___/ - / /_/ // /| | / / / /\__ \ - / __ // ___ |/ /_/ /___/ / -/_/ /_//_/ |_|\____//____/ - Home Assistant OS -${CL}" +cat <<"EOF" + __ __ ___ _ __ __ ____ _____ + / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ + +EOF } function msg_info() { local msg="$1" From bd59aa04a236a75e58f61e68cbcb2b74d6c0d2b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Nov 2022 12:31:41 -0500 Subject: [PATCH 3740/6505] Create adguard-update.sh --- misc/adguard-update.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 misc/adguard-update.sh diff --git a/misc/adguard-update.sh b/misc/adguard-update.sh new file mode 100644 index 00000000..f3018cf1 --- /dev/null +++ b/misc/adguard-update.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +echo -e "\nStarting Update\n" +sleep 3 +wget -q --show-progress https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz +tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null +systemctl stop AdGuardHome +mkdir -p adguard-backup +cp -r /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ +cp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome +cp -r adguard-backup/* /opt/AdGuardHome/ +systemctl start AdGuardHome +rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup +echo -e "\nFinished\n" From 40223c0106536488de3182c2578b4cac1b9ab469 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Nov 2022 02:09:54 -0500 Subject: [PATCH 3741/6505] Update zigbee2mqtt-install.sh Add NODE_ENV environment variable to run in production mode --- setup/zigbee2mqtt-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 8631ec2a..7b8e283d 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -116,6 +116,7 @@ echo "[Unit] Description=zigbee2mqtt After=network.target [Service] +Environment=NODE_ENV=production ExecStart=/usr/bin/npm start WorkingDirectory=/opt/zigbee2mqtt StandardOutput=inherit From 079d72f21cc3ca90463050b7de10d6cc2bf510c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Nov 2022 09:36:28 -0500 Subject: [PATCH 3742/6505] Update vaultwarden-update.sh --- misc/vaultwarden-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 43bfa368..321e8066 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -22,7 +22,7 @@ ${CL}" update_info while true; do - read -p "This will Update Vaultwarden to $VAULT (set 2vCPU 2048MiB RAM Min.). Proceed(y/n)?" yn + read -p "This will Update Vaultwarden to $VAULT (set 2vCPU 3072MiB RAM Min.). Proceed(y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; From cbc9d446f038c98a4b137db324858a3cb53c07d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Nov 2022 10:25:48 -0500 Subject: [PATCH 3743/6505] Update vaultwarden-update.sh check for old path --- misc/vaultwarden-update.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 321e8066..25bc07ca 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -38,8 +38,12 @@ echo -e "${GN} Updating (Building) to ${VAULT} (Patience)... ${CL}" git clone https://github.com/dani-garcia/vaultwarden &>/dev/null cd vaultwarden cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null -cp target/release/vaultwarden /opt/vaultwarden/bin/ - +DIR=/usr/bin/vaultwarden +if [ -d "$DIR" ]; then + cp target/release/vaultwarden /usr/bin/ +else + cp target/release/vaultwarden /opt/vaultwarden/bin/ +fi echo -e "${GN} Starting Vaultwarden ${VAULT}... ${CL}" systemctl start vaultwarden.service sleep 1 From 0f83ba59ef8fa646041f32f2f0e85a2787fdd9bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Nov 2022 19:17:37 -0500 Subject: [PATCH 3744/6505] Create bluetooth.sh HA Bluetooth Integration Preparation --- misc/bluetooth.sh | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 misc/bluetooth.sh diff --git a/misc/bluetooth.sh b/misc/bluetooth.sh new file mode 100644 index 00000000..f7b1ef91 --- /dev/null +++ b/misc/bluetooth.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -e +clear + +while true; do + read -p "Start the Bluetooth Integration Preparation (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +clear + cat <<"EOF" + __ __ ___ _ __ __ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ + / __ )/ /_ _____ / /_____ ____ / /_/ /_ + / __ / / / / / _ \/ __/ __ \/ __ \/ __/ __ \ + / /_/ / / /_/ / __/ /_/ /_/ / /_/ / /_/ / / / + /_____/_/\__,_/\___/\__/\____/\____/\__/_/_/_/_ + / _/___ / /____ ____ __________ _/ /_(_)___ ____ + / // __ \/ __/ _ \/ __ `/ ___/ __ `/ __/ / __ \/ __ \ + _/ // / / / /_/ __/ /_/ / / / /_/ / /_/ / /_/ / / / / + /___/_/_/_/\__/\___/\__, /_/ \__,_/\__/_/\____/_/ /_/ + / __ \________/____/ ____ __________ _/ /_(_)___ ____ + / /_/ / ___/ _ \/ __ \/ __ `/ ___/ __ `/ __/ / __ \/ __ \ + / ____/ / / __/ /_/ / /_/ / / / /_/ / /_/ / /_/ / / / / + /_/ /_/ \___/ .___/\__,_/_/ \__,_/\__/_/\____/_/ /_/ + /_/ + +EOF +read -r -p "Switch from dbus-daemon to dbus-broker? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +cat <>/etc/apt/sources.list +deb http://deb.debian.org/debian bullseye-backports main contrib non-free + +deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free +EOF +apt-get update &>/dev/null +apt-get -t bullseye-backports install -y dbus-broker &>/dev/null +systemctl enable dbus-broker.service &>/dev/null +fi +read -r -p "Install BlueZ? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +apt-get -t bullseye-backports install -y bluez* &>/dev/null +fi +echo -e "Finished, reboot for changes to take affect" From a800ccc02d3ec24fe01a9d52874d6701600604dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Nov 2022 20:26:46 -0500 Subject: [PATCH 3745/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3bb962f9..c476225c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-11 + +### Changed + +- **HA Bluetooth Integration Preparation** + - [NEW Script](https://github.com/tteck/Proxmox/discussions/719) + ## 2022-11-04 ### Changed From 2b80b9c140c1418cb00ee2d6c363076a5f152e27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Nov 2022 21:09:04 -0500 Subject: [PATCH 3746/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c476225c..9b01a2a5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -31,7 +31,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Container & Core Restore from Backup** - - NEW Scripts https://github.com/tteck/Proxmox/discussions/674 + - [NEW Scripts](https://github.com/tteck/Proxmox/discussions/674) ## 2022-10-07 From 43683fce61268270ad16cd28091cc0cc69894b77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Nov 2022 15:35:44 -0500 Subject: [PATCH 3747/6505] Update umbrel-install.sh start Umbrel os --- setup/umbrel-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index 4da3411c..96f62b27 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -108,7 +108,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi - +cd ~/umbrel/scripts && bash start &>/dev/null msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null From c866343d29d84a764982eac65aaf083c7fdfd150 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Nov 2022 17:06:26 -0500 Subject: [PATCH 3748/6505] Update blocky-install.sh bug fix --- setup/blocky-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index 0f063c0b..64e4671f 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -84,7 +84,7 @@ systemctl disable systemd-resolved.service &>/dev/null RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz &>/dev/null mkdir -p /opt/blocky -tar -xf blocky_0.19_Linux_x86_64.tar.gz -C /opt/blocky +tar -xf blocky_${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz cat </opt/blocky/config.yml upstream: From dcd68b523a58fb4587c36c26233c27d13d4a2e78 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Nov 2022 17:25:58 -0500 Subject: [PATCH 3749/6505] Update umbrel-install.sh enable umbrel-startup.service --- setup/umbrel-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index 96f62b27..1cb751a8 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -89,6 +89,8 @@ EOF msg_info "Installing Umbrel (Patience)" curl -sL https://umbrel.sh | bash &>/dev/null +systemctl daemon-reload +systemctl enable --now umbrel-startup.service &>/dev/null msg_ok "Installed Umbrel" PASS=$(grep -w "root" /etc/shadow | cut -b6) @@ -108,7 +110,6 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -cd ~/umbrel/scripts && bash start &>/dev/null msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null From 5543667bd8e87ce10f880777773949e6d91af282 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 12 Nov 2022 17:30:07 -0500 Subject: [PATCH 3750/6505] Update umbrel-v4.sh a reboot is required before app installs --- ct/umbrel-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 8d02a0a6..f9591a5f 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -270,5 +270,5 @@ pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} Setup should be reachable by going to the following URL (a reboot is required before app installs). ${BL}http://${IP} ${CL} \n" From 40c63e2cd36342a1c0a609b7fbc071dce46a8f68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Nov 2022 06:44:26 -0500 Subject: [PATCH 3751/6505] add option to continue upon Internet NOT Connected (#727) --- setup/adguard-install.sh | 8 +++++++- setup/blocky-install.sh | 8 +++++++- setup/casaos-install.sh | 8 +++++++- setup/daemonsync-install.sh | 8 +++++++- setup/dashy-install.sh | 8 +++++++- setup/debian-install.sh | 8 +++++++- setup/deconz-install.sh | 8 +++++++- setup/docker-install.sh | 8 +++++++- setup/emby-install.sh | 8 +++++++- setup/emqx-install.sh | 8 +++++++- setup/esphome-install.sh | 8 +++++++- setup/grafana-install.sh | 8 +++++++- setup/grocy-install.sh | 8 +++++++- setup/heimdalldashboard-install.sh | 8 +++++++- setup/homeassistant-core-install.sh | 8 +++++++- setup/homeassistant-install.sh | 8 +++++++- setup/homebridge-install.sh | 8 +++++++- setup/homepage-install.sh | 8 +++++++- setup/influxdb-install.sh | 8 +++++++- setup/iobroker-install.sh | 8 +++++++- setup/jellyfin-install.sh | 8 +++++++- setup/keycloak-install.sh | 8 +++++++- setup/mariadb-install.sh | 8 +++++++- setup/meshcentral-install.sh | 8 +++++++- setup/motioneye-install.sh | 8 +++++++- setup/mqtt-install.sh | 8 +++++++- setup/n8n-install.sh | 8 +++++++- setup/navidrome-install.sh | 8 +++++++- setup/nextcloudpi-install.sh | 8 +++++++- setup/nginx-proxy-manager-install.sh | 8 +++++++- setup/nocodb-install.sh | 8 +++++++- setup/node-red-install.sh | 8 +++++++- setup/omada-install.sh | 8 +++++++- setup/omv-install.sh | 8 +++++++- setup/openhab-install.sh | 8 +++++++- setup/photoprism-install.sh | 8 +++++++- setup/pihole-install.sh | 8 +++++++- setup/plex-install.sh | 8 +++++++- setup/podman-homeassistant-install.sh | 8 +++++++- setup/postgresql-install.sh | 8 +++++++- setup/prometheus-install.sh | 8 +++++++- setup/scrypted-install.sh | 8 +++++++- setup/syncthing-install.sh | 8 +++++++- setup/technitiumdns-install.sh | 8 +++++++- setup/trilium-install.sh | 8 +++++++- setup/ubuntu-install.sh | 8 +++++++- setup/umbrel-install.sh | 8 +++++++- setup/unifi-install.sh | 8 +++++++- setup/uptimekuma-install.sh | 8 +++++++- setup/vaultwarden-install.sh | 8 +++++++- setup/whoogle-install.sh | 8 +++++++- setup/wikijs-install.sh | 8 +++++++- setup/wireguard-install.sh | 8 +++++++- setup/zigbee2mqtt-install.sh | 8 +++++++- setup/zwave-js-ui-install.sh | 8 +++++++- 55 files changed, 385 insertions(+), 55 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index e610ca68..e7b481e6 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index 64e4671f..dd78ada9 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index f5eaa998..41d64917 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index d635a284..16e696bc 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 76f44974..cd843b0a 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 1f8c6a20..0ff21992 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index 9b16f561..f1cc5feb 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/docker-install.sh b/setup/docker-install.sh index d28872cb..4cb1e052 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 9377cfb0..a61e4a59 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 33c85add..009445be 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 7c73b3e3..505a5bbf 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index fb212972..7eb61aee 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index d01878f5..b6292c92 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 3b63a1fb..c177c361 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 5f24cdc9..e07419e5 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index ade97b6d..bef7e7f1 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index c363270c..bfbe73a2 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 294dccde..f6a4d605 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 30a1d886..e050e093 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 46e2eae6..428d7f32 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index ba151b5d..040652bd 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index d7fdb4c0..fd90691d 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 1aa22a35..2c120f3a 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 8f7a4095..40fe2bb6 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 6fb9e71c..136c611f 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 225e6bd8..0a2facd6 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 00e48f8b..30e8f176 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index dabdf703..75676fde 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index 195dbc05..543510d6 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index a790811d..2b4da548 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 6d29b402..9030ac93 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 1b382cf1..8373a0e6 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 2bdf2f1f..7a6c7db4 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/omv-install.sh b/setup/omv-install.sh index e6b6b839..513290b3 100644 --- a/setup/omv-install.sh +++ b/setup/omv-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 02ef935f..a799182d 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 449f86d7..af60ccc0 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -63,7 +63,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index c64f26db..742e1b5f 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -63,7 +63,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 3cef5ed5..881d75ac 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 2900c446..45999889 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 7fa9dc77..dd191991 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index ba9b453e..8937ded9 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/scrypted-install.sh b/setup/scrypted-install.sh index 2ad93568..9b2e5e33 100644 --- a/setup/scrypted-install.sh +++ b/setup/scrypted-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh index 0a435c4d..d0cb5005 100644 --- a/setup/syncthing-install.sh +++ b/setup/syncthing-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index f97b40cd..12c78df6 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index a6aab029..bf5a1f78 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -61,7 +61,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index c7010188..85c25805 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index 1cb751a8..fa7f6cef 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 94100a0c..5f28058f 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -63,7 +63,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index 83c31b6c..b0fbd824 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index c5736db9..81599329 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index 3085e59b..4c324c89 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index 31f2ef9f..850bb44b 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 9dde9a1d..45206a29 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 7b8e283d..b6859a5d 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index d8dbaead..52800dbc 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -62,7 +62,13 @@ set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" - exit 1 + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi From 1c380355b01af1b5a7207e4e6f7a946cee4f66a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Nov 2022 07:10:04 -0500 Subject: [PATCH 3752/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9b01a2a5..6cec5a33 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-13 + +### Changed + +- **All LXC's** + - Add option to continue upon Internet NOT Connected + ## 2022-11-11 ### Changed From be152dd3aa2e1bbf97fce9e2b435916fe06da3e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Nov 2022 13:24:06 -0500 Subject: [PATCH 3753/6505] Update edge-kernel.sh 6.0-edge --- misc/edge-kernel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 74867e89..87c187bf 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -62,7 +62,7 @@ while [ $opt != '' ]; do curl -1sLf 'https://dl.cloudsmith.io/public/pve-edge/kernel/gpg.8EC01CCF309B98E7.key' | apt-key add - echo "deb https://dl.cloudsmith.io/public/pve-edge/kernel/deb/debian bullseye main" >/etc/apt/sources.list.d/pve-edge-kernel.list apt-get -y update - apt-get -y install pve-kernel-5.19-edge + apt-get -y install pve-kernel-6.0-edge reboot break ;; From 5733159956b1d2baa6e514b335d274a8056d9fbe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 13 Nov 2022 13:38:37 -0500 Subject: [PATCH 3754/6505] Update edge-kernel.sh fix "$opt" --- misc/edge-kernel.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 87c187bf..e13e4ed8 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -42,8 +42,8 @@ option_picked() { } clear show_menu -while [ $opt != '' ]; do - if [ $opt = '' ]; then +while [ "$opt" != "" ]; do + if [ "$opt" = "" ]; then exit else case $opt in From a16ab672c2dbdde598f4d03de4302a9ef1fb7e4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Nov 2022 06:57:24 -0500 Subject: [PATCH 3755/6505] Update grocy-install.sh install PHP 8.1 --- setup/grocy-install.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index b6292c92..c15713dc 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -85,13 +85,21 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y apache2 &>/dev/null apt-get install -y unzip &>/dev/null -apt-get install -y php &>/dev/null -apt-get install -y libapache2-mod-php &>/dev/null +apt-get install -y apt-transport-https &>/dev/null +apt-get install -y lsb-release &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing PHP 8.1" +curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg +sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' +apt-get update &>/dev/null +apt-get install -y php8.1 &>/dev/null +apt-get install -y libapache2-mod-php8.1 &>/dev/null apt-get install -y php-sqlite3 &>/dev/null apt-get install -y php-gd &>/dev/null apt-get install -y php-intl &>/dev/null apt-get install -y php-mbstring &>/dev/null -msg_ok "Installed Dependencies" +msg_ok "Installed PHP 8.1" msg_info "Installing grocy" wget https://releases.grocy.info/latest &>/dev/null From f004932f27ee4aa426877ea5bc9af1183a9411b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Nov 2022 07:10:08 -0500 Subject: [PATCH 3756/6505] Update unifi-install.sh correct Local Controller default --- setup/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 5f28058f..2adeda07 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -86,7 +86,7 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -read -r -p "Local Controller? " prompt +read -r -p "Local Controller? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then LOCAL="--local-controller" else From 7603bfc2f989ad4654d4dea0d7d82e662bec3bc6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Nov 2022 04:01:40 -0500 Subject: [PATCH 3757/6505] Update emby-v4.sh unprivileged no device passthrough --- ct/emby-v4.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 3a3096f4..c858bb44 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -264,6 +264,8 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm @@ -273,6 +275,7 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From 55c25de85ec65e4eaf9fa611158a1b9949a23119 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Nov 2022 04:03:05 -0500 Subject: [PATCH 3758/6505] Update jellyfin-v4.sh unprivileged no device passthrough --- ct/jellyfin-v4.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 3f49d1e7..a287b7e1 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -264,6 +264,8 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm @@ -273,6 +275,7 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From 9e16245ed0313d6fb33dd731d1376434d41b8f88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Nov 2022 04:04:26 -0500 Subject: [PATCH 3759/6505] Update plex-v4.sh unprivileged no device passthrough --- ct/plex-v4.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index d9c4b619..b2e631d9 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -264,6 +264,8 @@ export PCT_OPTIONS=" $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf LXC_CONFIG=/etc/pve/lxc/${CTID}.conf cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: c 226:0 rwm @@ -273,6 +275,7 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From e69b1a461a4e4d6a2f5a121c183e733aa0f2514e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Nov 2022 11:19:16 -0500 Subject: [PATCH 3760/6505] Update vaultwarden-update.sh stop execution instantly if a query exits while having a non-zero status. --- misc/vaultwarden-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 25bc07ca..60130d3c 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -e VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From b28568d0ca5b8d3247126d4c0df7e7928ce48235 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Nov 2022 11:32:52 -0500 Subject: [PATCH 3761/6505] Update vaultwarden-update.sh Ensure you set resources --- misc/vaultwarden-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh index 60130d3c..2a0c9436 100644 --- a/misc/vaultwarden-update.sh +++ b/misc/vaultwarden-update.sh @@ -23,7 +23,7 @@ ${CL}" update_info while true; do - read -p "This will Update Vaultwarden to $VAULT (set 2vCPU 3072MiB RAM Min.). Proceed(y/n)?" yn + read -p "This will Update Vaultwarden to $VAULT (Ensure you set 2vCPU 3072MiB RAM Min.). Proceed(y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; @@ -52,4 +52,4 @@ sleep 1 echo -e "${GN} Cleaning up... ${CL}" cd ~ && rm -rf vaultwarden -echo -e "${GN} Finished Update (set resources back to normal settings)${CL}" +echo -e "${GN} Finished Update (Ensure you set resources back to normal settings)${CL}" From 1b353883365f292efba62c537815e62442eef836 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Nov 2022 17:34:59 -0500 Subject: [PATCH 3762/6505] ubuntu os versions (#753) --- ct/emby-v4.sh | 5 +++-- ct/jellyfin-v4.sh | 5 +++-- ct/omada-v4.sh | 2 +- ct/plex-v4.sh | 5 +++-- ct/ubuntu-v4.sh | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index c858bb44..7bd7cced 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -98,10 +98,11 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ - "21.10" "Impish" OFF \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index a287b7e1..21af5b44 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -98,10 +98,11 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ - "21.10" "Impish" OFF \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 6cea6f85..7ef80131 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -100,8 +100,8 @@ function advanced_settings() { var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ - "21.10" "Impish" OFF \ "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index b2e631d9..71891a0f 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -98,10 +98,11 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ - "21.10" "Impish" OFF \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index ce011c0a..1cd16c05 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -100,8 +100,8 @@ function advanced_settings() { var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" OFF \ - "21.10" "Impish" OFF \ "22.04" "Jammy" ON \ + "22.10" "Kinetic" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi From 694002e14a85aafc6a507a035bc81d663dfe109a Mon Sep 17 00:00:00 2001 From: Uruk <68083474+Uruknara@users.noreply.github.com> Date: Tue, 22 Nov 2022 01:04:28 +0100 Subject: [PATCH 3763/6505] Adding more support and little feature (#755) Just adding support of other os and the hostname in the info bar [Update Ubuntu, Debian, Devuan, Alpine Linux, CentOS-Rocky-Alma, Fedora, ArchLinux ] New feature --- misc/update-lxcs.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 84a59274..59c8f0ce 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -34,16 +34,23 @@ function update_container() { container=$1 clear header_info - echo -e "${BL}[Info]${GN} Updating${BL} $container ${CL} \n" + name=`pct exec $container hostname` + echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} \n" pct config $container > temp os=`awk '/^ostype/' temp | cut -d' ' -f2` - if [ "$os" == "alpine" ] - then - pct exec $container -- ash -c "apk update && apk upgrade" + if [ "$os" == "alpine" ]; then + pct exec $container -- ash -c "apk update && apk upgrade -y" + elif [ "$os" == "ubuntu" ] || [ "$os" == "debian" ] || [ "$os" == "devuan" ]; then + pct exec $container -- bash -c "apt-get update && apt-get upgrade -y && apt-get clean && apt-get --purge autoremove -y" + elif [ "$os" == "fedora" ]; then + pct exec $container -- bash -c "dnf -y update && dnf -y upgrade && dnf -y --purge autoremove" + elif [ "$os" == "archlinux" ]; then + pct exec $container -- bash -c "pacman -Syyu --noconfirm" else - pct exec $container -- bash -c "apt update && apt upgrade -y && apt autoremove -y" + pct exec $container -- bash -c "yum -y update" fi } + read -p "Skip stopped containers? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then From 2abc2631429948e876905d4a29abb3752c4ff211 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Nov 2022 19:20:59 -0500 Subject: [PATCH 3764/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6cec5a33..ddec2910 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-21 + +### Changed + +- **Proxmox LXC Updater** + - Now updates Ubuntu, Debian, Devuan, Alpine Linux, CentOS-Rocky-Alma, Fedora, ArchLinux [(@Uruknara)](https://github.com/tteck/Proxmox/commits?author=Uruknara) + ## 2022-11-13 ### Changed From a8f6bd9eec1a4d58aca08c904d87cfb7f0964367 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Nov 2022 09:06:34 -0500 Subject: [PATCH 3765/6505] Update post-pve-install.sh update no-nag --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 7fb7bd7b..d5f40dce 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -100,7 +100,7 @@ fi read -r -p "Disable Subscription Nag? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then msg_info "Disabling Subscription Nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag (Delete browser cache)" fi From e9094021d8143954bc4cbe99caa69be4b3fd7996 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 22 Nov 2022 09:30:43 -0500 Subject: [PATCH 3766/6505] Update post-pbs-install.sh update no-nag --- misc/post-pbs-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index b96dbb93..7b29e5f4 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -94,7 +94,7 @@ fi read -r -p "Disable Subscription Nag? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then msg_info "Disabling Subscription Nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag" fi From a8433ea36c98e9a57d2d55ca47ba6df30719a02c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Nov 2022 10:00:42 -0500 Subject: [PATCH 3767/6505] Update debian-v4.sh Testing Enable Root SSH Access --- ct/debian-v4.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 443d577a..c2e7cfce 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version From 9f192aeec213436e343b44f0c31a1b7fe30071fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Nov 2022 10:04:35 -0500 Subject: [PATCH 3768/6505] Update debian-install.sh Testing Enable Root SSH Access --- setup/debian-install.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 0ff21992..96b5f984 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -42,7 +42,7 @@ function msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } -msg_info "Setting up Container OS " +msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null while [ "$(hostname -I)" = "" ]; do @@ -100,6 +100,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null From b54ba602ea9782c9a8e9fafe1fc02f4a9836e728 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Nov 2022 12:34:11 -0500 Subject: [PATCH 3769/6505] enable root ssh access during lxc creation (#765) --- ct/adguard-v4.sh | 12 +++++++++++- ct/alpine-v4.sh | 12 +++++++++++- ct/archlinux-v4.sh | 12 +++++++++++- ct/blocky-v4.sh | 12 +++++++++++- ct/casaos-v4.sh | 12 +++++++++++- ct/daemonsync-v4.sh | 12 +++++++++++- ct/dashy-v4.sh | 12 +++++++++++- ct/deconz-v4.sh | 12 +++++++++++- ct/docker-v4.sh | 12 +++++++++++- ct/emby-v4.sh | 12 +++++++++++- ct/emqx-v4.sh | 12 +++++++++++- ct/esphome-v4.sh | 12 +++++++++++- ct/grafana-v4.sh | 12 +++++++++++- ct/grocy-v4.sh | 12 +++++++++++- ct/heimdalldashboard-v4.sh | 12 +++++++++++- ct/homeassistant-core-v4.sh | 12 +++++++++++- ct/homeassistant-v4.sh | 12 +++++++++++- ct/homebridge-v4.sh | 12 +++++++++++- ct/homepage-v4.sh | 12 +++++++++++- ct/influxdb-v4.sh | 12 +++++++++++- ct/iobroker-v4.sh | 12 +++++++++++- ct/jellyfin-v4.sh | 12 +++++++++++- ct/keycloak-v4.sh | 12 +++++++++++- ct/magicmirror-v4.sh | 12 +++++++++++- ct/mariadb-v4.sh | 12 +++++++++++- ct/meshcentral-v4.sh | 12 +++++++++++- ct/motioneye-v4.sh | 12 +++++++++++- ct/mqtt-v4.sh | 7 +++++-- ct/n8n-v4.sh | 12 +++++++++++- ct/navidrome-v4.sh | 12 +++++++++++- ct/nextcloudpi-v4.sh | 12 +++++++++++- ct/nginx-proxy-manager-v4.sh | 12 +++++++++++- ct/nocodb-v4.sh | 12 +++++++++++- ct/node-red-v4.sh | 12 +++++++++++- ct/omada-v4.sh | 12 +++++++++++- ct/omv-v4.sh | 12 +++++++++++- ct/openhab-v4.sh | 12 +++++++++++- ct/paperless-ngx-v4.sh | 12 +++++++++++- ct/photoprism-v4.sh | 12 +++++++++++- ct/pihole-v4.sh | 12 +++++++++++- ct/plex-v4.sh | 12 +++++++++++- ct/podman-homeassistant-v4.sh | 12 +++++++++++- ct/postgresql-v4.sh | 12 +++++++++++- ct/prometheus-v4.sh | 12 +++++++++++- ct/scrypted-v4.sh | 12 +++++++++++- ct/syncthing-v4.sh | 12 +++++++++++- ct/technitiumdns-v4.sh | 12 +++++++++++- ct/trilium-v4.sh | 12 +++++++++++- ct/ubuntu-v4.sh | 12 +++++++++++- ct/umbrel-v4.sh | 12 +++++++++++- ct/unifi-v4.sh | 12 +++++++++++- ct/uptimekuma-v4.sh | 12 +++++++++++- ct/vaultwarden-v4.sh | 12 +++++++++++- ct/whoogle-v4.sh | 12 +++++++++++- ct/wikijs-v4.sh | 12 +++++++++++- ct/wireguard-v4.sh | 12 +++++++++++- ct/zigbee2mqtt-v4.sh | 12 +++++++++++- ct/zwave-js-ui-v4.sh | 12 +++++++++++- setup/adguard-install.sh | 6 ++++++ setup/blocky-install.sh | 6 ++++++ setup/casaos-install.sh | 6 ++++++ setup/daemonsync-install.sh | 6 ++++++ setup/dashy-install.sh | 6 ++++++ setup/deconz-install.sh | 6 ++++++ setup/docker-install.sh | 6 ++++++ setup/emby-install.sh | 6 ++++++ setup/emqx-install.sh | 6 ++++++ setup/esphome-install.sh | 6 ++++++ setup/grafana-install.sh | 6 ++++++ setup/grocy-install.sh | 6 ++++++ setup/heimdalldashboard-install.sh | 6 ++++++ setup/homeassistant-core-install.sh | 6 ++++++ setup/homeassistant-install.sh | 6 ++++++ setup/homebridge-install.sh | 6 ++++++ setup/homepage-install.sh | 6 ++++++ setup/influxdb-install.sh | 6 ++++++ setup/iobroker-install.sh | 6 ++++++ setup/jellyfin-install.sh | 6 ++++++ setup/keycloak-install.sh | 6 ++++++ setup/magicmirror-install.sh | 6 ++++++ setup/mariadb-install.sh | 6 ++++++ setup/meshcentral-install.sh | 6 ++++++ setup/motioneye-install.sh | 6 ++++++ setup/mqtt-install.sh | 6 ++++++ setup/n8n-install.sh | 6 ++++++ setup/navidrome-install.sh | 6 ++++++ setup/nextcloudpi-install.sh | 6 ++++++ setup/nginx-proxy-manager-install.sh | 6 ++++++ setup/nocodb-install.sh | 6 ++++++ setup/node-red-install.sh | 6 ++++++ setup/omada-install.sh | 6 ++++++ setup/omv-install.sh | 6 ++++++ setup/openhab-install.sh | 6 ++++++ setup/photoprism-install.sh | 6 ++++++ setup/pihole-install.sh | 6 ++++++ setup/plex-install.sh | 6 ++++++ setup/podman-homeassistant-install.sh | 6 ++++++ setup/postgresql-install.sh | 6 ++++++ setup/prometheus-install.sh | 6 ++++++ setup/scrypted-install.sh | 6 ++++++ setup/syncthing-install.sh | 6 ++++++ setup/technitiumdns-install.sh | 6 ++++++ setup/trilium-install.sh | 6 ++++++ setup/ubuntu-install.sh | 6 ++++++ setup/umbrel-install.sh | 6 ++++++ setup/unifi-install.sh | 6 ++++++ setup/uptimekuma-install.sh | 6 ++++++ setup/vaultwarden-install.sh | 6 ++++++ setup/whoogle-install.sh | 6 ++++++ setup/wikijs-install.sh | 6 ++++++ setup/wireguard-install.sh | 6 ++++++ setup/zigbee2mqtt-install.sh | 6 ++++++ setup/zwave-js-ui-install.sh | 6 ++++++ 113 files changed, 962 insertions(+), 59 deletions(-) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index 60b4e089..5d67195f 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/alpine-v4.sh b/ct/alpine-v4.sh index 11f8f2e7..546de0ad 100644 --- a/ct/alpine-v4.sh +++ b/ct/alpine-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -208,6 +210,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -237,6 +246,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/archlinux-v4.sh b/ct/archlinux-v4.sh index 6d3243ca..4b33de51 100644 --- a/ct/archlinux-v4.sh +++ b/ct/archlinux-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index ff4f3475..b861c58a 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index e1e701f6..2ac17453 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index 820267f4..27e49b1f 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index fa6e0ad6..abb1eae3 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 2605ceae..1b9d3f1a 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index 1e598396..d65fd6a0 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 7bd7cced..354d640b 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -95,6 +95,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -114,7 +116,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -221,6 +223,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -250,6 +259,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index 0a79efcf..fcc35a86 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index 95c5b25e..2429f988 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 6762da87..0678a118 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index f1ed2e1d..e41ada96 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 7912b71b..8c831979 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index 4098d9c0..fd3bb250 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 77b128df..a7d1fb71 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 861bc448..0b7510f2 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index 9c92edc8..7781857f 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 74121380..25cb3a3d 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 43436724..5b5d78b7 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 21af5b44..9ebf41d8 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -95,6 +95,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -114,7 +116,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -221,6 +223,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -250,6 +259,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 63d553f5..0b9babff 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 5a52a4de..78bd04a7 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index b2db3d31..a1201a89 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index a7b6767c..885a8a3c 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 4834b42e..d75d9e52 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index c9b3cfe6..dcdc2f71 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -93,7 +93,9 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ @@ -104,7 +106,7 @@ exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi -PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; @@ -216,6 +218,7 @@ if [ "$CT_TYPE" == "1" ]; then fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index c1f88353..18e74805 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 57bfe2a0..3e6d737f 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index 68e5aed5..d2b8d7a2 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 8e316769..bf9c0037 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 8c58f846..ba516ee4 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 434bd642..c95cc54b 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 7ef80131..ae0a1faf 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -113,7 +115,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -220,6 +222,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -249,6 +258,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index 2d58a0ad..628f4c11 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index fb07b1fd..d120b45d 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index f735b822..53ea9807 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index 69b2fd5e..217d1a31 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 65b1df79..83c7b06f 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index 71891a0f..d1798958 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -95,6 +95,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -114,7 +116,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -221,6 +223,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -250,6 +259,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 87bf6dea..bad2ad8f 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -97,6 +97,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -108,7 +110,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -215,6 +217,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -244,6 +253,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index 9fc542d3..ab0fa879 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index f17864ae..4d1c7e05 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh index a9de8c1c..4f1b213c 100644 --- a/ct/scrypted-v4.sh +++ b/ct/scrypted-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index e20ee8df..9084cd49 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -95,6 +95,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -106,7 +108,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -213,6 +215,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -242,6 +251,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index 7d36387e..5bcd7bfe 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index b64d1333..fa2f31de 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 1cd16c05..182cdd21 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -113,7 +115,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -220,6 +222,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -249,6 +258,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index f9591a5f..2d876e87 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index 0051f6a5..2d2582ad 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index f1779f12..fd2ee780 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index 1de5fc5d..c64c257a 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 9527d486..0d35cb1b 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -93,6 +93,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -104,7 +106,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -211,6 +213,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -240,6 +249,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index b4b50eff..df631e62 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 38e82951..7b3bc459 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -95,6 +95,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -106,7 +108,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -213,6 +215,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -242,6 +251,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index d19c5a03..335bf03e 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 0f2af7ab..8442a1ec 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -94,6 +94,8 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -105,7 +107,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -212,6 +214,13 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -241,6 +250,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os export PCT_OSVERSION=$var_version diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index e7b481e6..ec248d10 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -106,6 +106,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index dd78ada9..39690a37 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -362,6 +362,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index 41d64917..dbd62604 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -115,6 +115,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index 16e696bc..ef0b5f9b 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -108,6 +108,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index cd843b0a..7bd1c5a0 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -139,6 +139,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index f1cc5feb..476a61a9 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -132,6 +132,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 4cb1e052..6fc265d4 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -158,6 +158,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/emby-install.sh b/setup/emby-install.sh index a61e4a59..1c0b0622 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -121,6 +121,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index 009445be..da49201b 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -106,6 +106,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 505a5bbf..15160dce 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -128,6 +128,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 7eb61aee..0570d690 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -115,6 +115,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi systemctl start grafana-server systemctl enable grafana-server.service &>/dev/null diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index c15713dc..20166eb0 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -144,6 +144,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index c177c361..4f57ac50 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -139,6 +139,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index e07419e5..956db032 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -146,6 +146,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index bef7e7f1..6e78f010 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -342,6 +342,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index bfbe73a2..f6ab776c 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -118,6 +118,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index f6a4d605..80c4ef20 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -136,6 +136,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index e050e093..7e8aab4c 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -139,6 +139,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 428d7f32..271401b6 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -106,6 +106,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 040652bd..b9e9de7a 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -146,6 +146,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index fd90691d..b72f14fe 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -127,6 +127,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index cf71719d..a1ab2eec 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -223,6 +223,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 2c120f3a..b4e261ce 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -123,6 +123,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 40fe2bb6..1e5789be 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -117,6 +117,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index 136c611f..f718adc4 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -136,6 +136,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 0a2facd6..180b0c45 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -113,6 +113,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 30e8f176..70e4b615 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -129,6 +129,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index 75676fde..b6cc28e5 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -155,6 +155,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index 543510d6..c5f63f65 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -104,6 +104,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 2b4da548..9fc27d3d 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -261,6 +261,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Starting Services" systemctl enable npm &>/dev/null diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 9030ac93..be07ed72 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -135,6 +135,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 8373a0e6..8e7257ec 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -137,6 +137,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 7a6c7db4..0fd4551e 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -111,6 +111,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/omv-install.sh b/setup/omv-install.sh index 513290b3..f5bf3267 100644 --- a/setup/omv-install.sh +++ b/setup/omv-install.sh @@ -123,6 +123,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index a799182d..082db069 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -123,6 +123,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index af60ccc0..85349d25 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -196,6 +196,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 742e1b5f..a43a230e 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -126,6 +126,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 881d75ac..fad4c048 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -125,6 +125,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 45999889..c7e09cd7 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -159,6 +159,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index dd191991..8587b17c 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -230,6 +230,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 8937ded9..8b3f7907 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -135,6 +135,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/scrypted-install.sh b/setup/scrypted-install.sh index 9b2e5e33..b9b9223f 100644 --- a/setup/scrypted-install.sh +++ b/setup/scrypted-install.sh @@ -194,6 +194,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh index d0cb5005..cb3b2113 100644 --- a/setup/syncthing-install.sh +++ b/setup/syncthing-install.sh @@ -109,6 +109,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 12c78df6..ab51a406 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -106,6 +106,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index bf5a1f78..f62528e7 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -130,6 +130,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 85c25805..9b7597ba 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -101,6 +101,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index fa7f6cef..e233a6a7 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -116,6 +116,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null apt-get autoclean >/dev/null diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 2adeda07..0a7f87e3 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -114,6 +114,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index b0fbd824..a7305c9e 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -135,6 +135,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 81599329..bcd58970 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -191,6 +191,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index 4c324c89..3971ce10 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -122,6 +122,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index 850bb44b..01d3df47 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -151,6 +151,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 45206a29..6d726417 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -165,6 +165,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index b6859a5d..910dffb4 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -151,6 +151,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index 52800dbc..68ab1885 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -127,6 +127,12 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi msg_info "Cleaning up" rm zwave-js-ui-${RELEASE}-linux.zip From 9beca482179f94406fd08f1b6b86c13e6313ef1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Nov 2022 13:20:03 -0500 Subject: [PATCH 3770/6505] Update umbrel-v4.sh change wording --- ct/umbrel-v4.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 2d876e87..4e98420b 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -280,5 +280,5 @@ pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL (a reboot is required before app installs). - ${BL}http://${IP} ${CL} \n" +echo -e "${APP} should be reachable by going to the following URL (reboot is required before app installs). + ${BL}http://${IP} ${CL} \n" From 4f1d613ae9885abc038f561872ea6286b5053916 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Nov 2022 22:59:56 -0500 Subject: [PATCH 3771/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ddec2910..f1bc9b9e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,12 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-23 + +### Changed + +- **All LXC's** + - Now you can enable root ssh access during lxc creation (Advance) ## 2022-11-21 ### Changed From 14461857f6a20bad2aca5479b478c75b386a0b40 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Nov 2022 23:00:46 -0500 Subject: [PATCH 3772/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f1bc9b9e..ef98f502 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **All LXC's** - - Now you can enable root ssh access during lxc creation (Advance) + - Add option to enable root ssh access during lxc creation (Advance) ## 2022-11-21 ### Changed From f69227a38654a5d83e4acf80236dba4806038ac1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Nov 2022 06:43:53 -0500 Subject: [PATCH 3773/6505] Update omada-install.sh 5.7.4 --- setup/omada-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/omada-install.sh b/setup/omada-install.sh index 0fd4551e..dc5a8ded 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -91,8 +91,8 @@ sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Omada Controller v5.6.3" -wget -qL https://static.tp-link.com/upload/software/2022/202210/20221024/Omada_SDN_Controller_v5.6.3_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.6.3_Linux_x64.deb &>/dev/null +wget -qL https://static.tp-link.com/upload/software/2022/202211/20221121/Omada_SDN_Controller_v5.7.4_Linux_x64.deb +sudo dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6) From 3dacb89b25f264d5f364b1506509332a1cf29d4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Nov 2022 14:06:14 -0500 Subject: [PATCH 3774/6505] Update haos-vm-v4.sh add option to set machine type --- vm/haos-vm-v4.sh | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 668325c2..49e226fc 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -91,6 +91,9 @@ function default_settings() { BRANCH=${STABLE} echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" VMID=$NEXTID + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + FORMAT=",efitype=4m" + MACHINE="" echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" HN=haos${STABLE} echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" @@ -122,6 +125,20 @@ if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMI else if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; fi +MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +"i440fx" "Machine i440fx" ON \ +"q35" "Machine q35" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",format=raw" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" +fi VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $VM_NAME ]; then HN="haos${BRANCH}"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; @@ -255,12 +272,12 @@ for i in {0,1}; do done msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ + qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null qm set $VMID \ -boot order=scsi0 >/dev/null From 0d2bb7ac3a7a3626b97a4b72565222694962313f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Nov 2022 14:10:14 -0500 Subject: [PATCH 3775/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ef98f502..d3c0986c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,12 +3,20 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-24 + +### Changed + +- **Home Assistant OS VM** + - Add option to set machine type during VM creation (Advance) + ## 2022-11-23 ### Changed - **All LXC's** - - Add option to enable root ssh access during lxc creation (Advance) + - Add option to enable root ssh access during LXC creation (Advance) + ## 2022-11-21 ### Changed From d56341fe5fc5af8430146a79dd01994914531d4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Nov 2022 15:08:10 -0500 Subject: [PATCH 3776/6505] Update haos-vm-v4.sh clean --- vm/haos-vm-v4.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 49e226fc..6075915e 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -276,12 +276,11 @@ qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf -cores $COR -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null - qm set $VMID \ - -efidisk0 ${DISK0_REF}${FORMAT} \ - -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null qm set $VMID \ - -boot order=scsi0 >/dev/null -qm set $VMID -description "# Home Assistant OS + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 \ + -boot order=scsi0 \ + -description "# Home Assistant OS ### https://github.com/tteck/Proxmox [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}(${HN})" From 189439964f7c8d5ed91bc1f5bd6c612aa9ff0657 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Nov 2022 03:36:29 -0500 Subject: [PATCH 3777/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d3c0986c..ea4de26c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,14 +8,14 @@ All notable changes to this project will be documented in this file. ### Changed - **Home Assistant OS VM** - - Add option to set machine type during VM creation (Advance) + - Add option to set machine type during VM creation (Advanced) ## 2022-11-23 ### Changed - **All LXC's** - - Add option to enable root ssh access during LXC creation (Advance) + - Add option to enable root ssh access during LXC creation (Advanced) ## 2022-11-21 From 5fe82e720c73e412a14493a60339f02bd7d20839 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Nov 2022 10:41:57 -0500 Subject: [PATCH 3778/6505] Update whoogle-install.sh add dependency --- setup/whoogle-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index 3971ce10..964b437c 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -90,6 +90,7 @@ apt-get install python3-pip -y &>/dev/null msg_ok "Installed pip3" msg_info "Installing Whoogle" +pip install brotli &>/dev/null pip install whoogle-search &>/dev/null service_path="/etc/systemd/system/whoogle.service" From 0c88e26b0ee1464326873cd37aa5dfa85c3b44c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Nov 2022 18:50:55 -0500 Subject: [PATCH 3779/6505] Update crowdsec.sh make not installable on Proxmox --- misc/crowdsec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/crowdsec.sh b/misc/crowdsec.sh index 63d3645e..95984108 100644 --- a/misc/crowdsec.sh +++ b/misc/crowdsec.sh @@ -27,7 +27,7 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } - +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; fi while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in From 901e26b8ac5f7504b10669b1f75846104f21c73b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 25 Nov 2022 18:52:37 -0500 Subject: [PATCH 3780/6505] Update crowdsec.sh --- misc/crowdsec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/crowdsec.sh b/misc/crowdsec.sh index 95984108..7f509ba8 100644 --- a/misc/crowdsec.sh +++ b/misc/crowdsec.sh @@ -27,7 +27,7 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; fi +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in From a46082ffaac6a9bcfce559d06b31ee30a9112cdb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Nov 2022 06:30:39 -0500 Subject: [PATCH 3781/6505] Update technitiumdns-update.sh update .net to 7 --- misc/technitiumdns-update.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/misc/technitiumdns-update.sh b/misc/technitiumdns-update.sh index 0cfbd7f8..88494319 100644 --- a/misc/technitiumdns-update.sh +++ b/misc/technitiumdns-update.sh @@ -14,7 +14,7 @@ echo "===============================" echo "Technitium DNS Server Update" echo "===============================" -if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 6.0."; then +if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then dotnetFound="yes" else dotnetFound="no" @@ -22,21 +22,21 @@ fi if [ -d $dotnetDir ]; then dotnetUpdate="yes" - echo "Updating .NET 6 Runtime..." + echo "Updating .NET 7 Runtime..." fi -curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 6.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >>$installLog 2>&1 +curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 7.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >>$installLog 2>&1 if [ ! -f "/usr/bin/dotnet" ]; then ln -s $dotnetDir/dotnet /usr/bin >>$installLog 2>&1 fi -if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 6.0."; then +if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then if [ "$dotnetUpdate" = "yes" ]; then - echo ".NET 6 Runtime was updated successfully!" + echo ".NET 7 Runtime was updated successfully!" fi else - echo "Failed to update .NET 6 Runtime. Please try again." + echo "Failed to update .NET 7 Runtime. Please try again." exit 1 fi From a7f797ede23f906ecc5fca3dfe6512847366a310 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Nov 2022 18:01:55 -0500 Subject: [PATCH 3782/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 59c8f0ce..63b452c9 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -39,7 +39,7 @@ function update_container() { pct config $container > temp os=`awk '/^ostype/' temp | cut -d' ' -f2` if [ "$os" == "alpine" ]; then - pct exec $container -- ash -c "apk update && apk upgrade -y" + pct exec $container -- ash -c "apk update && apk upgrade" elif [ "$os" == "ubuntu" ] || [ "$os" == "debian" ] || [ "$os" == "devuan" ]; then pct exec $container -- bash -c "apt-get update && apt-get upgrade -y && apt-get clean && apt-get --purge autoremove -y" elif [ "$os" == "fedora" ]; then From 5e7ec6be42a1d853aaed0f2f32bc041ae49f2f71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Nov 2022 16:54:16 -0500 Subject: [PATCH 3783/6505] Create shinobi-install.sh --- setup/shinobi-install.sh | 177 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 setup/shinobi-install.sh diff --git a/setup/shinobi-install.sh b/setup/shinobi-install.sh new file mode 100644 index 00000000..6eeb65cc --- /dev/null +++ b/setup/shinobi-install.sh @@ -0,0 +1,177 @@ +#!/usr/bin/env bash +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +apt-get update --fix-missing &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +ubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) +if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then + apt install sudo wget -y + sudo apt install -y software-properties-common + sudo add-apt-repository universe -y + apt update -y + apt update --fix-missing -y +fi + +msg_info "Installing Dependencies" +apt-get install -y curl sudo git &>/dev/null +apt-get install -y make zip net-tools &>/dev/null +apt-get install -y gcc g++ cmake &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Installing FFMPEG" +apt-get install -y ffmpeg &>/dev/null +msg_ok "Installed FFMPEG" + +msg_info "Clonning Shinobi" +cd /opt +git clone https://gitlab.com/Shinobi-Systems/Shinobi.git -b master Shinobi &>/dev/null +cd Shinobi +gitVersionNumber=$(git rev-parse HEAD) +theDateRightNow=$(date) +touch version.json +chmod 777 version.json +echo '{"Product" : "'"Shinobi"'" , "Branch" : "'"master"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"https://gitlab.com/Shinobi-Systems/Shinobi.git"'"}' > version.json +msg_ok "Cloned Shinobi" + +msg_info "Installing Database" +sqlpass="" +echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections +echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections +apt-get install -y mariadb-server &>/dev/null +service mysql start +sqluser="root" +mysql -e "source sql/user.sql" || true +mysql -e "source sql/framework.sql" || true +msg_ok "Installed Database" +cp conf.sample.json conf.json +cronKey=$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)}') +sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json +cp super.sample.json super.json + +msg_info "Installing Shinobi" +npm i npm -g &>/dev/null +npm install --unsafe-perm &>/dev/null +npm install pm2@latest -g &>/dev/null +chmod -R 755 . +touch INSTALL/installed.txt +ln -s /opt/Shinobi/INSTALL/shinobi /usr/bin/shinobi +node /opt/Shinobi/tools/modifyConfiguration.js addToConfig="{\"cron\":{\"key\":\"$(head -c 64 < /dev/urandom | sha256sum | awk '{print substr($1,1,60)}')\"}}" &>/dev/null +pm2 start camera.js &>/dev/null +pm2 start cron.js &>/dev/null +pm2 startup &>/dev/null +pm2 save &>/dev/null +pm2 list &>/dev/null +msg_ok "Installed Shinobi" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From a9e5aebdbdcfdbd6069363ac5a0257f8ad75b1b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Nov 2022 16:55:41 -0500 Subject: [PATCH 3784/6505] Create shinobi-v4.sh --- ct/shinobi-v4.sh | 288 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 ct/shinobi-v4.sh diff --git a/ct/shinobi-v4.sh b/ct/shinobi-v4.sh new file mode 100644 index 00000000..ed3020b7 --- /dev/null +++ b/ct/shinobi-v4.sh @@ -0,0 +1,288 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Shinobi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="22.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + cat <<"EOF" + _____ __ _ __ _ + / ___// /_ (_)___v4____ / /_ (_) + \__ \/ __ \/ / __ \/ __ \/ __ \/ / + ___/ / / / / / / / / /_/ / /_/ / / +/____/_/ /_/_/_/ /_/\____/_.___/_/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" OFF \ + "22.04" "Jammy" ON \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8080/super${CL} \n" From 7a28d21247ac8c2b44f8c8abc54d80fa25e804ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Nov 2022 17:02:23 -0500 Subject: [PATCH 3785/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ea4de26c..3d3660c3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-11-27 + +### Changed + +- **Shinobi LXC** + - NEW Script + ## 2022-11-24 ### Changed From 4d66780ec121a5f08048f86845144dcda2808fb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 28 Nov 2022 13:56:14 -0500 Subject: [PATCH 3786/6505] Update paperless-ngx-install.sh --- setup/paperless-ngx-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index 01f85926..1a732217 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -196,12 +196,12 @@ msg_ok "Set up admin Paperless-ngx User & Password" cat </etc/systemd/system/paperless-scheduler.service [Unit] -Description=Paperless consumer +Description=Paperless Celery Beat Requires=redis.service [Service] WorkingDirectory=/opt/paperless/src -ExecStart=python3 manage.py qcluster +ExecStart=celery --app paperless beat --loglevel INFO [Install] WantedBy=multi-user.target From dae1040a24988076ecf6dfc198eaac3b0a70aa6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Nov 2022 10:28:05 -0500 Subject: [PATCH 3787/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 87cbf03f..ba5cfab3 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -38,7 +38,8 @@ cat <<"EOF" /_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| /_/ UPDATE /____/ EOF - +echo -e "🚨 This will break Paperless-ngx DO NOT UPGRADE to version 1.10.0" +echo -e "Working on a solution" while true; do read -p "This will Update Paperless-ngx to $RELEASE. Proceed(y/n)?" yn case $yn in From ba6d6bdc6a95187dbc29a19b54b30436c7b8671a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Nov 2022 10:33:32 -0500 Subject: [PATCH 3788/6505] Update paperless-ngx-install.sh switch back to v1.9.2 --- setup/paperless-ngx-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index 1a732217..cbf0b26e 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -137,10 +137,10 @@ msg_ok "Installed JBIG2" msg_info "Downloading Paperless-ngx" Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) cd /opt && - wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz &>/dev/null && - tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ &>/dev/null && + wget https://github.com/paperless-ngx/paperless-ngx/releases/download/v1.9.2/paperless-ngx-v1.9.2.tar.xz &>/dev/null && + tar -xf paperless-ngx-v1.9.2.tar.xz -C /opt/ &>/dev/null && mv paperless-ngx paperless && - rm paperless-ngx-$Paperlessngx.tar.xz + rm paperless-ngx-v1.9.2.tar.xz cd /opt/paperless ## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file @@ -201,7 +201,8 @@ Requires=redis.service [Service] WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless beat --loglevel INFO +#ExecStart=celery --app paperless beat --loglevel INFO +ExecStart=python3 manage.py qcluster [Install] WantedBy=multi-user.target From e3ebc43ae6fd685745c52260ea82cb56119f575e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Nov 2022 11:37:28 -0500 Subject: [PATCH 3789/6505] Update paperless-ngx-install.sh fix for v1.10.0 --- setup/paperless-ngx-install.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index cbf0b26e..41e72f36 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -137,10 +137,10 @@ msg_ok "Installed JBIG2" msg_info "Downloading Paperless-ngx" Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) cd /opt && - wget https://github.com/paperless-ngx/paperless-ngx/releases/download/v1.9.2/paperless-ngx-v1.9.2.tar.xz &>/dev/null && - tar -xf paperless-ngx-v1.9.2.tar.xz -C /opt/ &>/dev/null && + wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz &>/dev/null && + tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ &>/dev/null && mv paperless-ngx paperless && - rm paperless-ngx-v1.9.2.tar.xz + rm paperless-ngx-$Paperlessngx.tar.xz cd /opt/paperless ## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file @@ -196,13 +196,25 @@ msg_ok "Set up admin Paperless-ngx User & Password" cat </etc/systemd/system/paperless-scheduler.service [Unit] -Description=Paperless Celery Beat +Description=Paperless Celery beat Requires=redis.service [Service] WorkingDirectory=/opt/paperless/src -#ExecStart=celery --app paperless beat --loglevel INFO -ExecStart=python3 manage.py qcluster +ExecStart=celery --app paperless beat --loglevel INFO + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/paperless-task-queue.service +[Unit] +Description=Paperless Celery Workers +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless worker --loglevel INFO [Install] WantedBy=multi-user.target @@ -239,7 +251,7 @@ EOF sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml systemctl daemon-reload -systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler &>/dev/null +systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service &>/dev/null msg_ok "Finished installing Paperless-ngx" From 165ea5897bc8246c62aa6baac9652cc2e556138a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Nov 2022 12:02:29 -0500 Subject: [PATCH 3790/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index ba5cfab3..d6d93222 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -38,8 +38,7 @@ cat <<"EOF" /_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| /_/ UPDATE /____/ EOF -echo -e "🚨 This will break Paperless-ngx DO NOT UPGRADE to version 1.10.0" -echo -e "Working on a solution" + while true; do read -p "This will Update Paperless-ngx to $RELEASE. Proceed(y/n)?" yn case $yn in @@ -50,7 +49,7 @@ while true; do done sleep 2 msg_info "Stopping Paperless-ngx" -systemctl stop paperless-consumer paperless-webserver paperless-scheduler +systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service sleep 1 msg_ok "Stopped Paperless-ngx" @@ -64,6 +63,33 @@ sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://gi pip install -r requirements.txt &>/dev/null cd /opt/paperless/src /usr/bin/python3 manage.py migrate &>/dev/null +SER=/etc/systemd/system/paperless-task-queue.service +if [ -f "$SER" ]; then + msg_ok "paperless-task-queue.service Exists." +else +cat </etc/systemd/system/paperless-task-queue.service +[Unit] +Description=Paperless Celery Workers +Requires=redis.service +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless worker --loglevel INFO +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now paperless-task-queue +msg_ok "paperless-task-queue.service Created." +fi +cat </etc/systemd/system/paperless-scheduler.service +[Unit] +Description=Paperless Celery beat +Requires=redis.service +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless beat --loglevel INFO +[Install] +WantedBy=multi-user.target +EOF msg_ok "Updated to ${RELEASE}" msg_info "Cleaning up" @@ -73,7 +99,7 @@ rm -rf paperless-ngx msg_ok "Cleaned" msg_info "Starting Paperless-ngx" -systemctl start paperless-consumer paperless-webserver paperless-scheduler +systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service sleep 1 msg_ok "Finished Update" echo -e "\n${BL}It may take a minute or so for Paperless-ngx to become available.${CL}\n" From 2c3dfafae9182c9483584f22f07a41e150401419 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Nov 2022 12:05:08 -0500 Subject: [PATCH 3791/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index d6d93222..6b9c4dba 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -77,7 +77,7 @@ ExecStart=celery --app paperless worker --loglevel INFO [Install] WantedBy=multi-user.target EOF -systemctl enable --now paperless-task-queue +systemctl enable paperless-task-queue &>/dev/null msg_ok "paperless-task-queue.service Created." fi cat </etc/systemd/system/paperless-scheduler.service From 3f01bfcf3110e3b887e2524c1e795c4314e58b43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Nov 2022 12:08:17 -0500 Subject: [PATCH 3792/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 6b9c4dba..509067bc 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -99,6 +99,7 @@ rm -rf paperless-ngx msg_ok "Cleaned" msg_info "Starting Paperless-ngx" +systemctl daemon-reload systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service sleep 1 msg_ok "Finished Update" From 1068827ea0aeb29543ca4feb9a395ad88fd5d395 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Nov 2022 13:15:52 -0500 Subject: [PATCH 3793/6505] Update paperless-ngx-update.sh fix paperless-task-queue.service stop --- misc/paperless-ngx-update.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 509067bc..752c4376 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash clear RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +SER=/etc/systemd/system/paperless-task-queue.service YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -49,7 +50,10 @@ while true; do done sleep 2 msg_info "Stopping Paperless-ngx" -systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service +systemctl stop paperless-consumer paperless-webserver paperless-scheduler +if [ -f "$SER" ]; then + systemctl stop paperless-task-queue.service +fi sleep 1 msg_ok "Stopped Paperless-ngx" @@ -63,7 +67,6 @@ sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://gi pip install -r requirements.txt &>/dev/null cd /opt/paperless/src /usr/bin/python3 manage.py migrate &>/dev/null -SER=/etc/systemd/system/paperless-task-queue.service if [ -f "$SER" ]; then msg_ok "paperless-task-queue.service Exists." else From 1eaf803c29974c95a5e848554848a5f1d6096f34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Nov 2022 22:03:06 -0500 Subject: [PATCH 3794/6505] Update hacore2hacore-data.sh --- misc/hacore2hacore-data.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/hacore2hacore-data.sh b/misc/hacore2hacore-data.sh index 1faff32c..3f5352e6 100644 --- a/misc/hacore2hacore-data.sh +++ b/misc/hacore2hacore-data.sh @@ -81,15 +81,15 @@ if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then pct stop $CTID_TO fi msg "Mounting Container Disks..." -DOCKER_PATH=/var/lib/docker/volumes/hass_config/_data CORE_PATH=/root/.homeassistant +CORE_PATH2=/root/ CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." [ -d "${CTID_FROM_PATH}${CORE_PATH}" ] || die "Home Assistant directories in '$CTID_FROM' not found." CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") || die "There was a problem mounting the root disk of LXC '${CTID_TO}'." -[ -d "${CTID_TO_PATH}${CORE_PATH}" ] || +[ -d "${CTID_TO_PATH}${CORE_PATH2}" ] || die "Home Assistant directories in '$CTID_TO' not found." msg "Copying Data..." @@ -102,7 +102,7 @@ RSYNC_OPTIONS=( --info=progress2 ) msg "<======== Docker Data ========>" -rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${CORE_PATH} ${CTID_TO_PATH}${CORE_PATH} +rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${CORE_PATH} ${CTID_TO_PATH}${CORE_PATH2} echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." From a42bdbee40b19d265f72d9ce046fde6cc844471e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Nov 2022 22:04:27 -0500 Subject: [PATCH 3795/6505] Update homeassistant-core-install.sh remove bluez --- setup/homeassistant-core-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 956db032..397c7680 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -85,7 +85,6 @@ apt-get install -y \ python3-dev \ python3-venv \ python3-pip \ - bluez \ libffi-dev \ libssl-dev \ libjpeg-dev \ From 73d993a30d83be8a96b95b28c2fa653fb1ecdb90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 3 Dec 2022 10:03:56 -0500 Subject: [PATCH 3796/6505] Create pyenv2.sh --- misc/pyenv2.sh | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 misc/pyenv2.sh diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh new file mode 100644 index 00000000..9b7126fb --- /dev/null +++ b/misc/pyenv2.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -e +echo "Installing Python 3.10.8" +pyenv install 3.10.8 &>/dev/null +pyenv global 3.10.8 +echo "Installed Python 3.10.8" +read -r -p "Would you like to install Home Assistant Beta? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + HA="Y" +fi +if [[ $HA == "Y" ]]; then +echo "Installing Home Assistant Beta" +cat </etc/systemd/system/homeassistant.service +[Unit] +Description=Home Assistant +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/root/.homeassistant +ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" +RestartForceExitStatus=100 +[Install] +WantedBy=multi-user.target +EOF +mkdir /srv/homeassistant +cd /srv/homeassistant +python3 -m venv . +source bin/activate +python3 -m pip install wheel &>/dev/null +pip3 install psycopg2-binary &>/dev/null +pip3 install --pre homeassistant &>/dev/null +systemctl enable homeassistant &>/dev/null +echo "Installed Home Assistant Beta" +echo -e " Go to $(hostname -I | awk '{print $1}'):8123" +hass +fi From 9742c35d6ad5c26403725cdc2a0c4c6b50b536f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 3 Dec 2022 10:05:02 -0500 Subject: [PATCH 3797/6505] Create pyenv.sh --- misc/pyenv.sh | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 misc/pyenv.sh diff --git a/misc/pyenv.sh b/misc/pyenv.sh new file mode 100644 index 00000000..9d596f7c --- /dev/null +++ b/misc/pyenv.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -e +echo "Installing pyenv" +apt-get install -y \ +make \ +build-essential \ +libjpeg-dev \ +libpcap-dev \ +libssl-dev \ +zlib1g-dev \ +libbz2-dev \ +libreadline-dev \ +libsqlite3-dev \ +autoconf \ +git \ +llvm \ +libncursesw5-dev \ +xz-utils \ +tk-dev \ +libxml2-dev \ +libxmlsec1-dev \ +libffi-dev \ +libopenjp2-7 \ +libtiff5 \ +libturbojpeg0-dev \ +liblzma-dev &>/dev/null + +git clone https://github.com/pyenv/pyenv.git ~/.pyenv &>/dev/null + +echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc +echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc +echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc +echo "Installed pyenv" +echo "Restarting Shell" +echo "Run pyenv2.sh to finish" +exec $SHELL From 102a2061b4b404e073ac5599ab6fdef684284d1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 3 Dec 2022 15:27:42 -0500 Subject: [PATCH 3798/6505] options to set DNS (#803) --- ct/adguard-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/alpine-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/archlinux-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/blocky-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/casaos-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/daemonsync-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/dashy-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/debian-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/deconz-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/docker-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/emby-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/emqx-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/esphome-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/grafana-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/grocy-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/heimdalldashboard-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/homeassistant-core-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/homeassistant-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/homebridge-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/homepage-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/influxdb-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/iobroker-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/jellyfin-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/keycloak-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/magicmirror-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/mariadb-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/meshcentral-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/motioneye-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/mqtt-v4.sh | 2 ++ ct/n8n-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/navidrome-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/nextcloudpi-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/nginx-proxy-manager-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/nocodb-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/node-red-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/omada-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/omv-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/openhab-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/paperless-ngx-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/photoprism-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/pihole-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/plex-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/podman-homeassistant-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/postgresql-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/prometheus-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/scrypted-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/shinobi-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/syncthing-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/technitiumdns-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/trilium-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/ubuntu-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/umbrel-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/unifi-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/uptimekuma-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/vaultwarden-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/whoogle-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/wikijs-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/wireguard-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/zigbee2mqtt-v4.sh | 30 ++++++++++++++++++++++++++++++ ct/zwave-js-ui-v4.sh | 30 ++++++++++++++++++++++++++++++ 60 files changed, 1772 insertions(+) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index 5d67195f..1c50582a 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/alpine-v4.sh b/ct/alpine-v4.sh index 546de0ad..dd3a7d6d 100644 --- a/ct/alpine-v4.sh +++ b/ct/alpine-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -188,6 +192,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -254,6 +282,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/archlinux-v4.sh b/ct/archlinux-v4.sh index 4b33de51..6c8c294a 100644 --- a/ct/archlinux-v4.sh +++ b/ct/archlinux-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index b861c58a..0f6ebcad 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 2ac17453..9a2a9dee 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index 27e49b1f..ce51efa0 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index abb1eae3..43a9ce29 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index c2e7cfce..457e5bce 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 1b9d3f1a..f3aa35f4 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index d65fd6a0..aa82aafc 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 354d640b..06a83bf9 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -91,6 +91,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -201,6 +205,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -267,6 +295,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index fcc35a86..6dbffae3 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index 2429f988..45d2f651 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 0678a118..0a096cb5 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index e41ada96..3aa8b8a2 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 8c831979..1d20b4ab 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index fd3bb250..e2e6d324 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index a7d1fb71..b3c21663 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 0b7510f2..604e8756 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index 7781857f..e0079f56 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 25cb3a3d..544c08a6 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 5b5d78b7..bbea2222 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 9ebf41d8..e83f9b3b 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -91,6 +91,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -201,6 +205,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -267,6 +295,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 0b9babff..5ab128f3 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 78bd04a7..14686897 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index a1201a89..ba1848bc 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 885a8a3c..268be525 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index d75d9e52..70798f15 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index dcdc2f71..b511688d 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -226,6 +226,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index 18e74805..e864e714 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 3e6d737f..e274d0cf 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index d2b8d7a2..e5bb4d6f 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index bf9c0037..f6ec77d7 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index ba516ee4..8a7680e6 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index c95cc54b..87bf78e5 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index ae0a1faf..5ced9246 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -200,6 +204,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -266,6 +294,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index 628f4c11..9be51f0b 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index d120b45d..0ce75e46 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index 53ea9807..3b5247e8 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index 217d1a31..fad36764 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 83c7b06f..a34e8eb5 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index d1798958..8564195d 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -91,6 +91,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -201,6 +205,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -267,6 +295,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index bad2ad8f..c5944bef 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -93,6 +93,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -195,6 +199,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -261,6 +289,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index ab0fa879..a3c82982 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 4d1c7e05..a792708e 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh index 4f1b213c..cc23caee 100644 --- a/ct/scrypted-v4.sh +++ b/ct/scrypted-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/shinobi-v4.sh b/ct/shinobi-v4.sh index ed3020b7..265e7d23 100644 --- a/ct/shinobi-v4.sh +++ b/ct/shinobi-v4.sh @@ -91,6 +91,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -201,6 +205,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -267,6 +295,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index 9084cd49..c741c527 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -91,6 +91,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -193,6 +197,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -259,6 +287,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index 5bcd7bfe..ce8c822a 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index fa2f31de..c7b08580 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 182cdd21..13d9fa3d 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -200,6 +204,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -266,6 +294,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 4e98420b..1df43db6 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index 2d2582ad..329e3326 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index fd2ee780..d49cf8cc 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index c64c257a..ecf7d10f 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 0d35cb1b..3457e95e 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -89,6 +89,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -191,6 +195,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -257,6 +285,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index df631e62..13a5dccd 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 7b3bc459..da10e317 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -91,6 +91,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -193,6 +197,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -259,6 +287,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 335bf03e..5d726061 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 8442a1ec..d477aefb 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -90,6 +90,10 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" @@ -192,6 +196,30 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -258,6 +286,8 @@ export PCT_DISK_SIZE=$DISK_SIZE export PCT_OPTIONS=" -features $FEATURES -hostname $HN + $SD + $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN -onboot 1 -cores $CORE_COUNT From 68384f1e6efeb96b5efc0a9627313307c3abcbb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 3 Dec 2022 15:30:22 -0500 Subject: [PATCH 3799/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 3d3660c3..9d48acac 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-03 + +### Changed + +- **All LXC's** + - Add options to set DNS Server IP Address and DNS Search Domain (Advanced) + ## 2022-11-27 ### Changed From 1de5901ff48512164cd61c0bbc7fa898f9808532 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Dec 2022 13:44:27 -0500 Subject: [PATCH 3800/6505] Update mqtt-v4.sh --- ct/mqtt-v4.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index b511688d..b572a509 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -91,11 +91,11 @@ function default_settings() { GATE="" echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ From 9e1c5b15e069d5d4a5b8bdb7cc0f58425bc6b8fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Dec 2022 13:57:01 -0500 Subject: [PATCH 3801/6505] Update mqtt-v4.sh fix missing variables --- ct/mqtt-v4.sh | 89 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 27 deletions(-) diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index b572a509..afcb6892 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -69,33 +69,37 @@ if [[ $PVE != 1 ]]; then fi } function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ @@ -169,6 +173,30 @@ else echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -189,6 +217,13 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else From 34da49ea02a5d256b3adc107474b9a200cb9b553 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Dec 2022 17:35:28 -0500 Subject: [PATCH 3802/6505] Update haos-vm-v4.sh changes for non thin provisioned disks --- vm/haos-vm-v4.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 6075915e..d4890df0 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -18,6 +18,7 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" +THIN="discard=on,ssd=1," set -o errexit set -o errtrace set -o nounset @@ -132,7 +133,7 @@ MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script " exitstatus=$? if [ $MACH = q35 ]; then echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" - FORMAT=",format=raw" + FORMAT="" MACHINE=" -machine q35" else echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" @@ -254,15 +255,17 @@ unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in nfs|dir) - DISK_EXT=".qcow2" + DISK_EXT=".raw" DISK_REF="$VMID/" - DISK_IMPORT="-format qcow2" + DISK_IMPORT="-format raw" + THIN="" ;; btrfs) DISK_EXT=".raw" DISK_REF="$VMID/" - DISK_FORMAT="subvol" DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" ;; esac for i in {0,1}; do @@ -278,7 +281,7 @@ pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ - -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 \ + -scsi0 ${DISK1_REF},${THIN}size=32G \ -boot order=scsi0 \ -description "# Home Assistant OS ### https://github.com/tteck/Proxmox From 532da20188ecc9aa9091083eb7e4f70188d77f6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 10:25:37 -0500 Subject: [PATCH 3803/6505] Update pyenv2.sh --- misc/pyenv2.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 9b7126fb..70e99977 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -34,3 +34,25 @@ echo "Installed Home Assistant Beta" echo -e " Go to $(hostname -I | awk '{print $1}'):8123" hass fi + +read -r -p "Would you like to install ESPHome Beta? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + ESP="Y" +fi +if [[ $ESP == "Y" ]]; then +echo "Installing ESPHome" +pip3 install --pre esphome &>/dev/null +cat </etc/systemd/system/esphomeDashboard.service +[Unit] +Description=ESPHome Dashboard +After=network.target +[Service] +ExecStart=/root/.pyenv/versions/3.10.8/bin/esphome /root/.pyenv/versions/3.10.8/lib/python3.10/site-packages/esphome_dashboard dashboard +Restart=always +User=root +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now esphomeDashboard &>/dev/null +echo "Installed ESPHome" +fi From 124e0e191b7a8180c361d143bb1bc3bf39d18352 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 16:02:05 -0500 Subject: [PATCH 3804/6505] Update pyenv2.sh --- misc/pyenv2.sh | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 70e99977..77a3d610 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -27,6 +27,7 @@ cd /srv/homeassistant python3 -m venv . source bin/activate python3 -m pip install wheel &>/dev/null +pip3 install --upgrade pip &>/dev/null pip3 install psycopg2-binary &>/dev/null pip3 install --pre homeassistant &>/dev/null systemctl enable homeassistant &>/dev/null @@ -40,19 +41,35 @@ if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ] ESP="Y" fi if [[ $ESP == "Y" ]]; then -echo "Installing ESPHome" +echo "Installing ESPHome Beta" +mkdir /srv/esphome +cd /srv/esphome +python3 -m venv . +source bin/activate +python3 -m pip install wheel &>/dev/null +pip3 install --upgrade pip &>/dev/null pip3 install --pre esphome &>/dev/null -cat </etc/systemd/system/esphomeDashboard.service +cat </srv/esphome/start.sh +#!/bin/bash +source /srv/esphome/bin/activate +esphome dashboard /srv/esphome/ +EOF +chmod +x start.sh +cat </etc/systemd/system/esphomedashboard.service [Unit] -Description=ESPHome Dashboard +Description=ESPHome Dashboard Service After=network.target [Service] -ExecStart=/root/.pyenv/versions/3.10.8/bin/esphome /root/.pyenv/versions/3.10.8/lib/python3.10/site-packages/esphome_dashboard dashboard -Restart=always +Type=simple User=root +WorkingDirectory=/srv/esphome +ExecStart=/srv/esphome/start.sh +RestartSec=30 +Restart=on-failure [Install] WantedBy=multi-user.target EOF -systemctl enable --now esphomeDashboard &>/dev/null -echo "Installed ESPHome" +systemctl enable --now esphomedashboard &>/dev/null +echo "Installed ESPHome Beta" +echo -e " Go to $(hostname -I | awk '{print $1}'):6052" fi From f5595b070915e4f7af0b4d4e09060af7e5ffbe7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 18:38:58 -0500 Subject: [PATCH 3805/6505] Update pyenv2.sh --- misc/pyenv2.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 77a3d610..87349fde 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -73,3 +73,21 @@ systemctl enable --now esphomedashboard &>/dev/null echo "Installed ESPHome Beta" echo -e " Go to $(hostname -I | awk '{print $1}'):6052" fi + +read -r -p "Would you like to install Matter-Server? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + MTR="Y" +fi +if [[ $MTR == "Y" ]]; then +echo "Installing Matter Server" +apt-get install -y \ +libcairo2-dev \ +libjpeg62-turbo-dev \ +libgirepository1.0-dev \ +libpango1.0-dev \ +libgif-dev \ +g++ &>/dev/null +python3 -m pip install wheel +pip3 install --upgrade pip +pip install python-matter-server[server] +echo "Installed Matter Server" From 8b36a1953b1fe4853c65dc08da9d061029b1484b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 18:45:29 -0500 Subject: [PATCH 3806/6505] Update pyenv.sh --- misc/pyenv.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/pyenv.sh b/misc/pyenv.sh index 9d596f7c..a36ffdf5 100644 --- a/misc/pyenv.sh +++ b/misc/pyenv.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi set -e echo "Installing pyenv" apt-get install -y \ From e1355dc305dc1aa40d9c9c0a8887a6d7324bef5c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 18:45:58 -0500 Subject: [PATCH 3807/6505] Update pyenv2.sh --- misc/pyenv2.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 87349fde..6aff5940 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi set -e echo "Installing Python 3.10.8" pyenv install 3.10.8 &>/dev/null From bd4592523de09bf9d8d34105286f62ae6643135c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 18:51:59 -0500 Subject: [PATCH 3808/6505] Update pyenv2.sh --- misc/pyenv2.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 6aff5940..aef5896c 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -91,4 +91,5 @@ g++ &>/dev/null python3 -m pip install wheel pip3 install --upgrade pip pip install python-matter-server[server] +fi echo "Installed Matter Server" From 0fc2a3733414dddee4160cd5ebd4fcd60d8e2902 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 19:14:24 -0500 Subject: [PATCH 3809/6505] Update pyenv2.sh --- misc/pyenv2.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index aef5896c..0c744785 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -1,10 +1,15 @@ #!/usr/bin/env bash if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi set -e +DIR=/root/.pyenv/3.10.8 +if [ -d "$DIR" ]; then + echo "Python 3.10.8 is already installed, moving on..." +else echo "Installing Python 3.10.8" pyenv install 3.10.8 &>/dev/null pyenv global 3.10.8 echo "Installed Python 3.10.8" +fi read -r -p "Would you like to install Home Assistant Beta? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then HA="Y" From e86baf6a43b91683d176dc8774767fe8f6f22ee6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 19:16:13 -0500 Subject: [PATCH 3810/6505] Update pyenv2.sh --- misc/pyenv2.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 0c744785..46ee141a 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi set -e -DIR=/root/.pyenv/3.10.8 +DIR=/root/.pyenv/versions/3.10.8 if [ -d "$DIR" ]; then echo "Python 3.10.8 is already installed, moving on..." else From ee1c480ebf0982e4a8031ae0725e1663f603e8da Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 19:19:12 -0500 Subject: [PATCH 3811/6505] Update pyenv2.sh --- misc/pyenv2.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 46ee141a..751a8f9e 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -96,5 +96,6 @@ g++ &>/dev/null python3 -m pip install wheel pip3 install --upgrade pip pip install python-matter-server[server] -fi echo "Installed Matter Server" +fi +echo -e "\nFinished\n" From cd2acd8b972b4706fe6c1d55601302e2ee458889 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Dec 2022 19:41:47 -0500 Subject: [PATCH 3812/6505] Update pyenv2.sh --- misc/pyenv2.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh index 751a8f9e..58ae4351 100644 --- a/misc/pyenv2.sh +++ b/misc/pyenv2.sh @@ -97,5 +97,6 @@ python3 -m pip install wheel pip3 install --upgrade pip pip install python-matter-server[server] echo "Installed Matter Server" +echo -e "Start server > python -m matter_server.server" fi echo -e "\nFinished\n" From 227fb76e410ca564cbbd1891b280199dccad5225 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Dec 2022 10:18:55 -0500 Subject: [PATCH 3813/6505] Create changedetection-install.sh --- setup/changedetection-install.sh | 134 +++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 setup/changedetection-install.sh diff --git a/setup/changedetection-install.sh b/setup/changedetection-install.sh new file mode 100644 index 00000000..486c474b --- /dev/null +++ b/setup/changedetection-install.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y pip &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Change Detection" +mkdir /opt/changedetection +pip3 install changedetection.io &>/dev/null +msg_ok "Installed Change Detection" + +msg_info "Creating Service" +cat </etc/systemd/system/changedetection.service +[Unit] +Description=Change Detection +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/opt/changedetection +ExecStart=changedetection.io -d /opt/changedetection -p 5000 +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now changedetection &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + cat <>/etc/ssh/sshd_config +PermitRootLogin yes +EOF +systemctl restart sshd +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From a4ef550738992a4825706abec93a08b496c5c3b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Dec 2022 10:20:23 -0500 Subject: [PATCH 3814/6505] Create changedetection-v4.sh --- ct/changedetection-v4.sh | 309 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 ct/changedetection-v4.sh diff --git a/ct/changedetection-v4.sh b/ct/changedetection-v4.sh new file mode 100644 index 00000000..13f64d23 --- /dev/null +++ b/ct/changedetection-v4.sh @@ -0,0 +1,309 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Change Detection" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + cat <<"EOF" + ________ ____ __ __ _ + / ____/ /_v4____ _____ ____ ____ / __ \___ / /____ _____/ /_(_)___ ____ + / / / __ \/ __ `/ __ \/ __ `/ _ \ / / / / _ \/ __/ _ \/ ___/ __/ / __ \/ __ \ +/ /___/ / / / /_/ / / / / /_/ / __/ / /_/ / __/ /_/ __/ /__/ /_/ / /_/ / / / / +\____/_/ /_/\__,_/_/ /_/\__, /\___/ /_____/\___/\__/\___/\___/\__/_/\____/_/ /_/ + /____/ +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From 2f67cc885c6965cbf17ceb5440e3dd41d5fac46c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Dec 2022 11:04:19 -0500 Subject: [PATCH 3815/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9d48acac..e59cc515 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-09 + +### Changed + +- **Change Detection LXC** + - NEW Script + ## 2022-12-03 ### Changed From fef4ebe456441b31d9c8ee6db86ed9423b6ed207 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Dec 2022 20:12:33 -0500 Subject: [PATCH 3816/6505] mount fix (#830) --- ct/emby-v4.sh | 2 +- ct/jellyfin-v4.sh | 2 +- ct/plex-v4.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 06a83bf9..d8abcd6e 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -314,7 +314,7 @@ lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF fi msg_info "Starting LXC Container" diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index e83f9b3b..a0c417d0 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -314,7 +314,7 @@ lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF fi msg_info "Starting LXC Container" diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index 8564195d..cfcd9696 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -314,7 +314,7 @@ lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF fi msg_info "Starting LXC Container" From ef8238332ae95a82c3ff90700326aee6c2619c63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Dec 2022 06:27:22 -0500 Subject: [PATCH 3817/6505] Update nextcloudpi-install.sh php8.2 error fix --- setup/nextcloudpi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index c5f63f65..217eb7cf 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -85,7 +85,7 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" -curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null +curl -sSL https://raw.githubusercontent.com/tteck/nextcloudpi/master/install.sh | bash &>/dev/null msg_ok "Installed NextCloudPi" PASS=$(grep -w "root" /etc/shadow | cut -b6) From 7a788da1dea33763d1c789970787f29bcab33aa5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Dec 2022 11:24:37 -0500 Subject: [PATCH 3818/6505] check for wget --- vm/haos-vm-v4.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index d4890df0..2e6d6858 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -239,6 +239,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +if ! command -v wget >/dev/null 2>&1; then apt-get install -y wget &>/dev/null; fi if [ "$BRANCH" == "$DEV" ]; then URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz else From c76e4072da4f056a2114ee1adc2a2f12fac07c60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Dec 2022 07:59:52 -0500 Subject: [PATCH 3819/6505] Update homeassistant-core-install.sh --- setup/homeassistant-core-install.sh | 47 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 397c7680..3ca1a401 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -79,27 +79,48 @@ apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated Container OS" -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" apt-get install -y \ - python3 \ - python3-dev \ - python3-venv \ - python3-pip \ - libffi-dev \ - libssl-dev \ + make \ + build-essential \ libjpeg-dev \ libpcap-dev \ + libssl-dev \ zlib1g-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ autoconf \ - build-essential \ + git \ + curl \ + sudo \ + llvm \ + libncursesw5-dev \ + xz-utils \ + tk-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libffi-dev \ libopenjp2-7 \ libtiff5 \ libturbojpeg0-dev \ - tzdata \ - curl \ - sudo &>/dev/null + liblzma-dev &>/dev/null msg_ok "Installed Dependencies" +msg_info "Installing pyenv" +git clone https://github.com/pyenv/pyenv.git ~/.pyenv &>/dev/null +set +e +echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc +echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc +echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc +msg_ok "Installed pyenv" +. ~/.bashrc +set -e +msg_info "Installing Python 3.10.8" +pyenv install 3.10.8 &>/dev/null +pyenv global 3.10.8 +msg_ok "Installed Python 3.10.8" + msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant cd /srv/homeassistant @@ -107,14 +128,10 @@ python3 -m venv . source bin/activate python3 -m pip install wheel &>/dev/null pip3 install homeassistant &>/dev/null -pip3 install Cython &>/dev/null -pip3 install python-libpcap &>/dev/null -pip3 install psycopg2-binary &>/dev/null msg_ok "Installed Home Assistant-Core" msg_info "Creating Service" cat </etc/systemd/system/homeassistant.service - [Unit] Description=Home Assistant After=network-online.target From 9eb8c142972d2ef63ab1c6061c04a337b38b840c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Dec 2022 08:01:38 -0500 Subject: [PATCH 3820/6505] Update homeassistant-core-v4.sh --- ct/homeassistant-core-v4.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index e2e6d324..af70dd12 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -44,12 +44,12 @@ else fi function header_info { cat <<"EOF" - __ __ ___ _ __ __ ______ - / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / ____/___v4________ - / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / __ \/ ___/ _ \ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /___/ /_/ / / / __/ -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____/\____/_/ \___/ - + _ _ _ _ ___ + /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___v4_ __ ___ + / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ +/ __ / (_) | | | | | | __/ / _ \__ \__ \ \__ \ || (_| | | | | |_ / /__| (_) | | | __/ +\/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| + EOF } function msg_info() { From 90ed1a7de35740a203109126d15ef28978fd415d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Dec 2022 08:05:25 -0500 Subject: [PATCH 3821/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e59cc515..5f6f4bb7 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-16 + +### Changed + +- **Home Assistant Core LXC** + - Python 3.10.8 + ## 2022-12-09 ### Changed From 318eb7f4e22c59e9f8e09164b293b08fb2a32e9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Dec 2022 09:02:11 -0500 Subject: [PATCH 3822/6505] Update pyenv.sh --- misc/pyenv.sh | 175 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 147 insertions(+), 28 deletions(-) diff --git a/misc/pyenv.sh b/misc/pyenv.sh index a36ffdf5..51120c62 100644 --- a/misc/pyenv.sh +++ b/misc/pyenv.sh @@ -1,37 +1,156 @@ #!/usr/bin/env bash -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi set -e -echo "Installing pyenv" +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} +if command -v pveversion >/dev/null 2>&1; then msg_error "Can't Install on Proxmox "; exit; fi +msg_info "Installing pyenv" apt-get install -y \ -make \ -build-essential \ -libjpeg-dev \ -libpcap-dev \ -libssl-dev \ -zlib1g-dev \ -libbz2-dev \ -libreadline-dev \ -libsqlite3-dev \ -autoconf \ -git \ -llvm \ -libncursesw5-dev \ -xz-utils \ -tk-dev \ -libxml2-dev \ -libxmlsec1-dev \ -libffi-dev \ -libopenjp2-7 \ -libtiff5 \ -libturbojpeg0-dev \ -liblzma-dev &>/dev/null + make \ + build-essential \ + libjpeg-dev \ + libpcap-dev \ + libssl-dev \ + zlib1g-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + autoconf \ + git \ + curl \ + sudo \ + llvm \ + libncursesw5-dev \ + xz-utils \ + tk-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libffi-dev \ + libopenjp2-7 \ + libtiff5 \ + libturbojpeg0-dev \ + liblzma-dev &>/dev/null git clone https://github.com/pyenv/pyenv.git ~/.pyenv &>/dev/null - +set +e echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc -echo "Installed pyenv" -echo "Restarting Shell" -echo "Run pyenv2.sh to finish" +msg_ok "Installed pyenv" +. ~/.bashrc +set -e +msg_info "Installing Python 3.10.8" +pyenv install 3.10.8 &>/dev/null +pyenv global 3.10.8 +msg_ok "Installed Python 3.10.8" +read -r -p "Would you like to install Home Assistant Beta? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + HA="Y" +fi +if [[ $HA == "Y" ]]; then +msg_info "Installing Home Assistant Beta" +cat </etc/systemd/system/homeassistant.service +[Unit] +Description=Home Assistant +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/root/.homeassistant +ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" +RestartForceExitStatus=100 +[Install] +WantedBy=multi-user.target +EOF +mkdir /srv/homeassistant +cd /srv/homeassistant +python3 -m venv . +source bin/activate +python3 -m pip install wheel &>/dev/null +pip3 install --upgrade pip &>/dev/null +pip3 install psycopg2-binary &>/dev/null +pip3 install --pre homeassistant &>/dev/null +systemctl enable homeassistant &>/dev/null +msg_ok "Installed Home Assistant Beta" +echo -e " Go to $(hostname -I | awk '{print $1}'):8123" +hass +fi + +read -r -p "Would you like to install ESPHome Beta? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + ESP="Y" +fi +if [[ $ESP == "Y" ]]; then +msg_info "Installing ESPHome Beta" +mkdir /srv/esphome +cd /srv/esphome +python3 -m venv . +source bin/activate +python3 -m pip install wheel &>/dev/null +pip3 install --upgrade pip &>/dev/null +pip3 install --pre esphome &>/dev/null +cat </srv/esphome/start.sh +#!/bin/bash +source /srv/esphome/bin/activate +esphome dashboard /srv/esphome/ +EOF +chmod +x start.sh +cat </etc/systemd/system/esphomedashboard.service +[Unit] +Description=ESPHome Dashboard Service +After=network.target +[Service] +Type=simple +User=root +WorkingDirectory=/srv/esphome +ExecStart=/srv/esphome/start.sh +RestartSec=30 +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now esphomedashboard &>/dev/null +msg_ok "Installed ESPHome Beta" +echo -e " Go to $(hostname -I | awk '{print $1}'):6052" +exec $SHELL +fi + +read -r -p "Would you like to install Matter-Server (Beta)? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + MTR="Y" +fi +if [[ $MTR == "Y" ]]; then +msg_info "Installing Matter Server" +apt-get install -y \ +libcairo2-dev \ +libjpeg62-turbo-dev \ +libgirepository1.0-dev \ +libpango1.0-dev \ +libgif-dev \ +g++ &>/dev/null +python3 -m pip install wheel +pip3 install --upgrade pip +pip install python-matter-server[server] +msg_ok "Installed Matter Server" +echo -e "Start server > python -m matter_server.server" +fi +msg_ok "\nFinished\n" exec $SHELL From ac54183ec949f3ae515b3769038826014a4a3d62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Dec 2022 09:02:37 -0500 Subject: [PATCH 3823/6505] Delete pyenv2.sh --- misc/pyenv2.sh | 102 ------------------------------------------------- 1 file changed, 102 deletions(-) delete mode 100644 misc/pyenv2.sh diff --git a/misc/pyenv2.sh b/misc/pyenv2.sh deleted file mode 100644 index 58ae4351..00000000 --- a/misc/pyenv2.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env bash -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi -set -e -DIR=/root/.pyenv/versions/3.10.8 -if [ -d "$DIR" ]; then - echo "Python 3.10.8 is already installed, moving on..." -else -echo "Installing Python 3.10.8" -pyenv install 3.10.8 &>/dev/null -pyenv global 3.10.8 -echo "Installed Python 3.10.8" -fi -read -r -p "Would you like to install Home Assistant Beta? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - HA="Y" -fi -if [[ $HA == "Y" ]]; then -echo "Installing Home Assistant Beta" -cat </etc/systemd/system/homeassistant.service -[Unit] -Description=Home Assistant -After=network-online.target -[Service] -Type=simple -WorkingDirectory=/root/.homeassistant -ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" -RestartForceExitStatus=100 -[Install] -WantedBy=multi-user.target -EOF -mkdir /srv/homeassistant -cd /srv/homeassistant -python3 -m venv . -source bin/activate -python3 -m pip install wheel &>/dev/null -pip3 install --upgrade pip &>/dev/null -pip3 install psycopg2-binary &>/dev/null -pip3 install --pre homeassistant &>/dev/null -systemctl enable homeassistant &>/dev/null -echo "Installed Home Assistant Beta" -echo -e " Go to $(hostname -I | awk '{print $1}'):8123" -hass -fi - -read -r -p "Would you like to install ESPHome Beta? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - ESP="Y" -fi -if [[ $ESP == "Y" ]]; then -echo "Installing ESPHome Beta" -mkdir /srv/esphome -cd /srv/esphome -python3 -m venv . -source bin/activate -python3 -m pip install wheel &>/dev/null -pip3 install --upgrade pip &>/dev/null -pip3 install --pre esphome &>/dev/null -cat </srv/esphome/start.sh -#!/bin/bash -source /srv/esphome/bin/activate -esphome dashboard /srv/esphome/ -EOF -chmod +x start.sh -cat </etc/systemd/system/esphomedashboard.service -[Unit] -Description=ESPHome Dashboard Service -After=network.target -[Service] -Type=simple -User=root -WorkingDirectory=/srv/esphome -ExecStart=/srv/esphome/start.sh -RestartSec=30 -Restart=on-failure -[Install] -WantedBy=multi-user.target -EOF -systemctl enable --now esphomedashboard &>/dev/null -echo "Installed ESPHome Beta" -echo -e " Go to $(hostname -I | awk '{print $1}'):6052" -fi - -read -r -p "Would you like to install Matter-Server? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - MTR="Y" -fi -if [[ $MTR == "Y" ]]; then -echo "Installing Matter Server" -apt-get install -y \ -libcairo2-dev \ -libjpeg62-turbo-dev \ -libgirepository1.0-dev \ -libpango1.0-dev \ -libgif-dev \ -g++ &>/dev/null -python3 -m pip install wheel -pip3 install --upgrade pip -pip install python-matter-server[server] -echo "Installed Matter Server" -echo -e "Start server > python -m matter_server.server" -fi -echo -e "\nFinished\n" From f1e4e0c19c0012921ce422155b9007cbfea6281f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Dec 2022 19:04:22 -0500 Subject: [PATCH 3824/6505] Update haos-vm-v4.sh revert check for wget --- vm/haos-vm-v4.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 2e6d6858..d4890df0 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -239,7 +239,6 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" -if ! command -v wget >/dev/null 2>&1; then apt-get install -y wget &>/dev/null; fi if [ "$BRANCH" == "$DEV" ]; then URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz else From cd7a9c618d50ba0d4c258a6d3559d9b87c6161f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 09:40:45 -0500 Subject: [PATCH 3825/6505] Update core-restore-from-backup.sh check for PVE --- misc/core-restore-from-backup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh index afa664ee..6f65801b 100644 --- a/misc/core-restore-from-backup.sh +++ b/misc/core-restore-from-backup.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash clear +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") From bc3d30b4160fc79ed3965d08cd610398fe62e967 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 09:41:27 -0500 Subject: [PATCH 3826/6505] Update container-restore-from-backup.sh check for PVE --- misc/container-restore-from-backup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/container-restore-from-backup.sh b/misc/container-restore-from-backup.sh index f1526ec5..bc0a6b52 100644 --- a/misc/container-restore-from-backup.sh +++ b/misc/container-restore-from-backup.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash clear +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") From 1a4837e881e82efed65c1a08f410cb26221c30ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 09:43:25 -0500 Subject: [PATCH 3827/6505] Update hacs.sh check for PVE --- misc/hacs.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/hacs.sh b/misc/hacs.sh index 0c3cd2ad..e48dbf82 100644 --- a/misc/hacs.sh +++ b/misc/hacs.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" while true; do From 88647eee74ff627503a52f882ae8971da7a27523 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 09:44:07 -0500 Subject: [PATCH 3828/6505] Update hacs-core.sh check for PVE --- misc/hacs-core.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/hacs-core.sh b/misc/hacs-core.sh index 71a9524f..0479d932 100644 --- a/misc/hacs-core.sh +++ b/misc/hacs-core.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" while true; do From f22df25bd2eaecfa9f587452ff60fda1ae6c94cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 09:44:55 -0500 Subject: [PATCH 3829/6505] Update bluetooth.sh check for PVE --- misc/bluetooth.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/bluetooth.sh b/misc/bluetooth.sh index f7b1ef91..69ea28e4 100644 --- a/misc/bluetooth.sh +++ b/misc/bluetooth.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi set -e clear From 4e117988d20ed5e49f7abde87d083f77dc5e3e8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 09:47:13 -0500 Subject: [PATCH 3830/6505] Update podman_hacs.sh check for PVE --- misc/podman_hacs.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/podman_hacs.sh b/misc/podman_hacs.sh index 6936b066..10d5b1bf 100644 --- a/misc/podman_hacs.sh +++ b/misc/podman_hacs.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" while true; do From 32d804dbd748d5b8627930939cd3a859e8d63839 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 15:37:12 -0500 Subject: [PATCH 3831/6505] Update homeassistant-core-install.sh - Linux D-Bus Message Broker - Mariadb & PostgreSQL ready - fix for inconsistent dependency versions - Bluetooth ready --- setup/homeassistant-core-install.sh | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 3ca1a401..cde1bef3 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -90,6 +90,7 @@ apt-get install -y \ libbz2-dev \ libreadline-dev \ libsqlite3-dev \ + libmariadb-dev-compat \ autoconf \ git \ curl \ @@ -97,6 +98,8 @@ apt-get install -y \ llvm \ libncursesw5-dev \ xz-utils \ + tzdata \ + bluez \ tk-dev \ libxml2-dev \ libxmlsec1-dev \ @@ -107,6 +110,16 @@ apt-get install -y \ liblzma-dev &>/dev/null msg_ok "Installed Dependencies" +msg_info "Installing Linux D-Bus Message Broker" +cat <>/etc/apt/sources.list +deb http://deb.debian.org/debian bullseye-backports main contrib non-free +deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free +EOF +apt-get update &>/dev/null +apt-get -t bullseye-backports install -y dbus-broker &>/dev/null +systemctl enable --now dbus-broker.service &>/dev/null +msg_ok "Installed Linux D-Bus Message Broker" + msg_info "Installing pyenv" git clone https://github.com/pyenv/pyenv.git ~/.pyenv &>/dev/null set +e @@ -126,10 +139,19 @@ mkdir /srv/homeassistant cd /srv/homeassistant python3 -m venv . source bin/activate +pip install --upgrade pip &>/dev/null python3 -m pip install wheel &>/dev/null -pip3 install homeassistant &>/dev/null +pip install mysqlclient &>/dev/null +pip install psycopg2-binary &>/dev/null +pip install homeassistant &>/dev/null msg_ok "Installed Home Assistant-Core" +# fix for inconsistent versions, hopefully the HA team will get this fixed +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json + msg_info "Creating Service" cat </etc/systemd/system/homeassistant.service [Unit] From 5756b217d1e726d5edb248cba00c48d26687a6f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 15:41:44 -0500 Subject: [PATCH 3832/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 5f6f4bb7..afb53133 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,16 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-17 + +### Changed + +- **Home Assistant Core LXC** + - Linux D-Bus Message Broker + - Mariadb & PostgreSQL Ready + - Bluetooth Ready + - Fix for Inconsistent Dependency Versions (dbus-fast & bleak) + ## 2022-12-16 ### Changed From 71096ba2764536f1b7c522804a8a84d43e0d4041 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Dec 2022 21:59:55 -0500 Subject: [PATCH 3833/6505] Create core-update.sh --- misc/core-update.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 misc/core-update.sh diff --git a/misc/core-update.sh b/misc/core-update.sh new file mode 100644 index 00000000..b4e0acd2 --- /dev/null +++ b/misc/core-update.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +clear +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + cat <<"EOF" + _ _ _ _ ___ + /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___ _ __ ___ + / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ +/ __ / (_) | | | | | | __/ / _ \__ \__ \ \__ \ || (_| | | | | |_ / /__| (_) | | | __/ +\/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| + UPDATE +EOF +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +msg_info "Stopping Home Assistant" +systemctl stop homeassistant +msg_ok "Stopped Home Assistant" + +read -r -p "Use the Beta Branch? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + BR="--pre " +else + BR="" +fi +msg_info "Updating Home Assistant" +source /srv/homeassistant/bin/activate +pip install ${BR}--upgrade homeassistant &>/dev/null +msg_ok "Updated Home Assistant" + +msg_info "Setting Dependency Versions" +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +msg_ok "Set Dependency Versions" + +msg_info "Starting Home Assistant" +systemctl start homeassistant +msg_ok "Started Home Assistant" +msg_ok "Update Successful" +exit From 21230cedb2d92a07936ee03c06fc2be6383752c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Dec 2022 05:45:09 -0500 Subject: [PATCH 3834/6505] Update core-update.sh fix for python 3.9 --- misc/core-update.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/misc/core-update.sh b/misc/core-update.sh index b4e0acd2..47a72dfb 100644 --- a/misc/core-update.sh +++ b/misc/core-update.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash clear if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi +set -e YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -42,16 +43,23 @@ msg_info "Updating Home Assistant" source /srv/homeassistant/bin/activate pip install ${BR}--upgrade homeassistant &>/dev/null msg_ok "Updated Home Assistant" - +set +e msg_info "Setting Dependency Versions" +DIR=/srv/homeassistant/lib/python3.10 +if [ -d "$DIR" ]; then sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +else +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/package_constraints.txt +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/components/bluetooth/manifest.json +fi msg_ok "Set Dependency Versions" - +set -e msg_info "Starting Home Assistant" systemctl start homeassistant msg_ok "Started Home Assistant" msg_ok "Update Successful" -exit From daa9b78019a9befaf1a2ec3a169578b09718172d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Dec 2022 06:25:23 -0500 Subject: [PATCH 3835/6505] Update hacore2hacore-data.sh check PVE --- misc/hacore2hacore-data.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/hacore2hacore-data.sh b/misc/hacore2hacore-data.sh index 3f5352e6..28e0997b 100644 --- a/misc/hacore2hacore-data.sh +++ b/misc/hacore2hacore-data.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn case $yn in From 44da61804129380be1812826d602446f305ae50a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Dec 2022 06:26:33 -0500 Subject: [PATCH 3836/6505] Update hacontainer2hacore-data.sh check PVE --- misc/hacontainer2hacore-data.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/hacontainer2hacore-data.sh b/misc/hacontainer2hacore-data.sh index e6563275..29728e47 100644 --- a/misc/hacontainer2hacore-data.sh +++ b/misc/hacontainer2hacore-data.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC. Proceed(y/n)?" yn case $yn in From bc4640d589fcedc947e47ee19f334f45ea42eb46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Dec 2022 06:27:49 -0500 Subject: [PATCH 3837/6505] Update ha-copy-data.sh check PVE --- misc/ha-copy-data.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/ha-copy-data.sh b/misc/ha-copy-data.sh index 83f26a19..698c1cfb 100644 --- a/misc/ha-copy-data.sh +++ b/misc/ha-copy-data.sh @@ -2,6 +2,8 @@ # Use to copy all data from one Home Assistant LXC to another # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?" yn case $yn in From deb681a21186f16c97921e4cbc7095abee8f3e49 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Dec 2022 06:28:48 -0500 Subject: [PATCH 3838/6505] Update ha-copy-data-podman.sh check PVE --- misc/ha-copy-data-podman.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/ha-copy-data-podman.sh b/misc/ha-copy-data-podman.sh index 7296519c..2b8abc13 100644 --- a/misc/ha-copy-data-podman.sh +++ b/misc/ha-copy-data-podman.sh @@ -2,6 +2,8 @@ # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. # run from the Proxmox Shell # bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. Proceed(y/n)?" yn case $yn in From e994ce793ca06bbd62ea98e79e478137fabe9d70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Dec 2022 06:29:56 -0500 Subject: [PATCH 3839/6505] Update hacore2hacontainer-data.sh check PVE --- misc/hacore2hacontainer-data.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/hacore2hacontainer-data.sh b/misc/hacore2hacontainer-data.sh index ec40b43c..ab037fc1 100644 --- a/misc/hacore2hacontainer-data.sh +++ b/misc/hacore2hacontainer-data.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC. Proceed(y/n)?" yn case $yn in From 9507f9df5ca0285f6112fb574355e1e7cab5a10e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Dec 2022 14:18:23 -0500 Subject: [PATCH 3840/6505] Update core-update.sh clean code --- misc/core-update.sh | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/misc/core-update.sh b/misc/core-update.sh index 47a72dfb..105685e2 100644 --- a/misc/core-update.sh +++ b/misc/core-update.sh @@ -21,6 +21,10 @@ CROSS="${RD}✗${CL}" \/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| UPDATE EOF +PY=$(ls /srv/homeassistant/lib/) +IP=$(hostname -I | awk '{print $1}') +if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi +sleep 2 function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -33,7 +37,7 @@ msg_info "Stopping Home Assistant" systemctl stop homeassistant msg_ok "Stopped Home Assistant" -read -r -p "Use the Beta Branch? " prompt +read -r -p " Use the Beta Branch? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then BR="--pre " else @@ -43,23 +47,16 @@ msg_info "Updating Home Assistant" source /srv/homeassistant/bin/activate pip install ${BR}--upgrade homeassistant &>/dev/null msg_ok "Updated Home Assistant" -set +e + msg_info "Setting Dependency Versions" -DIR=/srv/homeassistant/lib/python3.10 -if [ -d "$DIR" ]; then -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -else -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/components/bluetooth/manifest.json -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/package_constraints.txt -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.9/site-packages/homeassistant/components/bluetooth/manifest.json -fi +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt +sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json msg_ok "Set Dependency Versions" -set -e + msg_info "Starting Home Assistant" systemctl start homeassistant msg_ok "Started Home Assistant" msg_ok "Update Successful" +echo -e "\n Go to http://${IP}:8123 \n" From 13ac5e607fe3526bac7d7a76e7bdf1039ce2b40e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Dec 2022 11:08:29 -0500 Subject: [PATCH 3841/6505] code refactoring (#845) --- setup/adguard-install.sh | 6 ++---- setup/blocky-install.sh | 6 ++---- setup/casaos-install.sh | 6 ++---- setup/changedetection-install.sh | 6 ++---- setup/daemonsync-install.sh | 6 ++---- setup/dashy-install.sh | 6 ++---- setup/debian-install.sh | 6 ++---- setup/deconz-install.sh | 6 ++---- setup/docker-install.sh | 6 ++---- setup/emby-install.sh | 6 ++---- setup/emqx-install.sh | 6 ++---- setup/esphome-install.sh | 6 ++---- setup/grafana-install.sh | 6 ++---- setup/grocy-install.sh | 6 ++---- setup/heimdalldashboard-install.sh | 6 ++---- setup/homeassistant-core-install.sh | 6 ++---- setup/homeassistant-install.sh | 6 ++---- setup/homebridge-install.sh | 6 ++---- setup/homepage-install.sh | 6 ++---- setup/influxdb-install.sh | 6 ++---- setup/iobroker-install.sh | 6 ++---- setup/jellyfin-install.sh | 6 ++---- setup/keycloak-install.sh | 6 ++---- setup/magicmirror-install.sh | 6 ++---- setup/mariadb-install.sh | 6 ++---- setup/meshcentral-install.sh | 6 ++---- setup/motioneye-install.sh | 6 ++---- setup/mqtt-install.sh | 6 ++---- setup/n8n-install.sh | 6 ++---- setup/navidrome-install.sh | 6 ++---- setup/nextcloudpi-install.sh | 6 ++---- setup/nginx-proxy-manager-install.sh | 6 ++---- setup/nocodb-install.sh | 6 ++---- setup/node-red-install.sh | 6 ++---- setup/omada-install.sh | 6 ++---- setup/omv-install.sh | 6 ++---- setup/openhab-install.sh | 6 ++---- setup/photoprism-install.sh | 6 ++---- setup/pihole-install.sh | 6 ++---- setup/plex-install.sh | 6 ++---- setup/podman-homeassistant-install.sh | 6 ++---- setup/postgresql-install.sh | 6 ++---- setup/prometheus-install.sh | 6 ++---- setup/scrypted-install.sh | 6 ++---- setup/shinobi-install.sh | 6 ++---- setup/syncthing-install.sh | 6 ++---- setup/technitiumdns-install.sh | 6 ++---- setup/trilium-install.sh | 6 ++---- setup/ubuntu-install.sh | 6 ++---- setup/umbrel-install.sh | 6 ++---- setup/unifi-install.sh | 6 ++---- setup/uptimekuma-install.sh | 6 ++---- setup/vaultwarden-install.sh | 6 ++---- setup/whoogle-install.sh | 6 ++---- setup/wikijs-install.sh | 6 ++---- setup/wireguard-install.sh | 6 ++---- setup/zigbee2mqtt-install.sh | 6 ++---- setup/zwave-js-ui-install.sh | 6 ++---- 58 files changed, 116 insertions(+), 232 deletions(-) diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index ec248d10..bfaf8b83 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -107,10 +107,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index 39690a37..620c57a2 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -363,10 +363,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index dbd62604..23ea0f98 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -116,10 +116,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/changedetection-install.sh b/setup/changedetection-install.sh index 486c474b..923ca216 100644 --- a/setup/changedetection-install.sh +++ b/setup/changedetection-install.sh @@ -122,10 +122,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index ef0b5f9b..e70c9943 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -109,10 +109,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 7bd1c5a0..677b4913 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -140,10 +140,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 96b5f984..124a8984 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -101,10 +101,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index 476a61a9..7c5f1b08 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -133,10 +133,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 6fc265d4..b455fbbc 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -159,10 +159,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 1c0b0622..979f1955 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -122,10 +122,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index da49201b..e73f7777 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -107,10 +107,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 15160dce..91092358 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -129,10 +129,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index 0570d690..c912e472 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -116,10 +116,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi systemctl start grafana-server systemctl enable grafana-server.service &>/dev/null diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 20166eb0..8740d66f 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -145,10 +145,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index 4f57ac50..ff8cc386 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -140,10 +140,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index cde1bef3..d49b08f2 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -185,10 +185,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 6e78f010..11af7412 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -343,10 +343,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index f6ab776c..8ce65cf0 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -119,10 +119,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 80c4ef20..0f60d5b1 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -137,10 +137,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 7e8aab4c..07c40091 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -140,10 +140,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 271401b6..5c2580db 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -107,10 +107,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index b9e9de7a..176dc5fc 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -147,10 +147,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index b72f14fe..6e412b6d 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -128,10 +128,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index a1ab2eec..e252fea4 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -224,10 +224,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index b4e261ce..6d0ad608 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -124,10 +124,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 1e5789be..114424d5 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -118,10 +118,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index f718adc4..b7528335 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -137,10 +137,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index 180b0c45..b0d2406d 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -114,10 +114,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index 70e4b615..a6689a66 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -130,10 +130,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index b6cc28e5..e08f0842 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -156,10 +156,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index 217eb7cf..dba702f4 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -105,10 +105,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index 9fc27d3d..f60e548d 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -262,10 +262,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Starting Services" diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index be07ed72..9244e605 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -136,10 +136,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index 8e7257ec..b535cf54 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -138,10 +138,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/omada-install.sh b/setup/omada-install.sh index dc5a8ded..d55510f9 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -112,10 +112,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/omv-install.sh b/setup/omv-install.sh index f5bf3267..3b8b07e3 100644 --- a/setup/omv-install.sh +++ b/setup/omv-install.sh @@ -124,10 +124,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 082db069..24600d2d 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -124,10 +124,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index 85349d25..a879cc0e 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -197,10 +197,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index a43a230e..1b785b05 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -127,10 +127,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/plex-install.sh b/setup/plex-install.sh index fad4c048..47883856 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -126,10 +126,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index c7e09cd7..9cd77087 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -160,10 +160,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 8587b17c..4b5986be 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -231,10 +231,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 8b3f7907..8c0b5dc8 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -136,10 +136,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/scrypted-install.sh b/setup/scrypted-install.sh index b9b9223f..1bb80bdc 100644 --- a/setup/scrypted-install.sh +++ b/setup/scrypted-install.sh @@ -195,10 +195,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/shinobi-install.sh b/setup/shinobi-install.sh index 6eeb65cc..a72a5572 100644 --- a/setup/shinobi-install.sh +++ b/setup/shinobi-install.sh @@ -165,10 +165,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh index cb3b2113..15e34ca2 100644 --- a/setup/syncthing-install.sh +++ b/setup/syncthing-install.sh @@ -110,10 +110,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index ab51a406..509e2fda 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -107,10 +107,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index f62528e7..f5080744 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -131,10 +131,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 9b7597ba..3cc2a4b3 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -102,10 +102,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index e233a6a7..11f26a6d 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -117,10 +117,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 0a7f87e3..2210a47e 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -115,10 +115,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index a7305c9e..f08f5021 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -136,10 +136,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index bcd58970..2047f631 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -192,10 +192,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index 964b437c..b574667a 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -124,10 +124,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index 01d3df47..51255211 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -152,10 +152,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index 6d726417..e8b82753 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -166,10 +166,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 910dffb4..2ac580b7 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -152,10 +152,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index 68ab1885..031ef329 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -128,10 +128,8 @@ EOF msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then - cat <>/etc/ssh/sshd_config -PermitRootLogin yes -EOF -systemctl restart sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd fi msg_info "Cleaning up" From e6ee476c49c28f6b612ff968b6276bf67662cb61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 02:14:26 -0500 Subject: [PATCH 3842/6505] Update edge-kernel.sh update code --- misc/edge-kernel.sh | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index e13e4ed8..52f83213 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -4,6 +4,9 @@ set -e KERNEL_ON=$(uname -r) PVE_KERNEL=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) EDGE_KERNEL=$(dpkg --list | grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) +VER=$(curl -s https://api.github.com/repos/fabianishere/pve-edge-kernel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-9) }') +KER=$(curl -s https://api.github.com/repos/fabianishere/pve-edge-kernel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-6) }') + clear while true; do read -p "This is a Proxmox Edge Kernel Tool, USE AT YOUR OWN RISK. Proceed(y/n)?" yn @@ -14,7 +17,16 @@ while true; do esac done clear - +function header_info { +cat <<"EOF" + ____ _ ________ ______ __ __ __ __ + / __ \ | / / ____/ / ____/___/ /___ ____ / //_/__ _________ ___ / /____ + / /_/ / | / / __/ / __/ / __ / __ `/ _ \ / ,< / _ \/ ___/ __ \/ _ \/ / ___/ + / ____/| |/ / /___ / /___/ /_/ / /_/ / __/ / /| / __/ / / / / / __/ (__ ) +/_/ |___/_____/ /_____/\__,_/\__, /\___/ /_/ |_\___/_/ /_/ /_/\___/_/____/ + /____/ +EOF +} show_menu() { normal=$(echo "\033[m") safe=$(echo "\033[32m") @@ -25,13 +37,13 @@ show_menu() { proxmox-boot-tool kernel list echo -e "\nCurrent Kernel: ${menu}${KERNEL_ON}${normal}" printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Install Proxmox Edge Kernel & Reboot\n" + printf "${menu}**${number} 1)${normal} Install Proxmox Edge Kernel ${menu}${KER}${normal} & Reboot\n" printf "${menu}**${number} 2)${normal} Switch to Proxmox VE 7 ${menu}${PVE_KERNEL}${normal} Kernel & Reboot\n" printf "${menu}**${number} 3)${normal} Switch to Proxmox Edge ${menu}${EDGE_KERNEL}${normal} Kernel & Reboot\n" printf "${menu}**${number} 4)${normal} Unpin Current Kernel\n" - printf "${menu}**${number} 5)${normal} Remove Proxmox Edge Kernel & Reboot\n" + printf "${menu}**${number} 5)${normal} Remove All Current ${menu}${VER}*${normal} Proxmox Edge Kernels & Reboot\n" printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu and enter or ${fgred}x${normal} to exit." + printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." read opt } option_picked() { @@ -41,6 +53,7 @@ option_picked() { printf "${msgcolor}${message}${normal}\n" } clear +header_info show_menu while [ "$opt" != "" ]; do if [ "$opt" = "" ]; then @@ -62,7 +75,7 @@ while [ "$opt" != "" ]; do curl -1sLf 'https://dl.cloudsmith.io/public/pve-edge/kernel/gpg.8EC01CCF309B98E7.key' | apt-key add - echo "deb https://dl.cloudsmith.io/public/pve-edge/kernel/deb/debian bullseye main" >/etc/apt/sources.list.d/pve-edge-kernel.list apt-get -y update - apt-get -y install pve-kernel-6.0-edge + apt-get -y install pve-kernel-${VER}-edge reboot break ;; @@ -122,7 +135,7 @@ while [ "$opt" != "" ]; do done clear option_picked "Removing Proxmox Edge Kernel & Rebooting" - apt-get purge -y ${EDGE_KERNEL} + apt --purge remove -y pve-kernel-${VER}*edge pve-headers-${VER}*edge rm -rf /etc/apt/sources.list.d/pve-edge-kernel.list proxmox-boot-tool kernel unpin reboot @@ -137,10 +150,11 @@ while [ "$opt" != "" ]; do *) clear option_picked "Please choose an option from the menu" + header_info show_menu ;; esac fi done - +header_info show_menu From 59de4ffdc918af6471b57df3f1375a7891ac7440 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 16:27:14 -0500 Subject: [PATCH 3843/6505] Create hyperion-install.sh --- setup/hyperion-install.sh | 121 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 setup/hyperion-install.sh diff --git a/setup/hyperion-install.sh b/setup/hyperion-install.sh new file mode 100644 index 00000000..682a0212 --- /dev/null +++ b/setup/hyperion-install.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y lsb-release &>/dev/null +apt-get install -y gnupg &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Hyperion" +wget -qO- https://apt.hyperion-project.org/hyperion.pub.key | sudo gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg &>/dev/null +echo "deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hyperion.list &>/dev/null +apt-get update &>/dev/null +apt-get install -y hyperion &>/dev/null +systemctl enable --now hyperion@root.service &>/dev/null +msg_ok "Installed Hyperion" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From fbc1d1b0ceff17781cd3427104f96f996244ecf2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 16:28:47 -0500 Subject: [PATCH 3844/6505] Create hyperion-v4.sh --- ct/hyperion-v4.sh | 324 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 ct/hyperion-v4.sh diff --git a/ct/hyperion-v4.sh b/ct/hyperion-v4.sh new file mode 100644 index 00000000..3386700b --- /dev/null +++ b/ct/hyperion-v4.sh @@ -0,0 +1,324 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Hyperion" +var_disk="2" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat <<"EOF" + __ __ _ + / / / /_ ______v4___ _____(_)___ ____ + / /_/ / / / / __ \/ _ \/ ___/ / __ \/ __ \ + / __ / /_/ / /_/ / __/ / / / /_/ / / / / +/_/ /_/\__, / .___/\___/_/ /_/\____/_/ /_/ + /____/_/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8090${CL} \n" From 01b814bdac7260cd1a93ceb18beb4577080d8b5e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 16:40:43 -0500 Subject: [PATCH 3845/6505] Update hyperion-install.sh add dependencies --- setup/hyperion-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/hyperion-install.sh b/setup/hyperion-install.sh index 682a0212..80c5de26 100644 --- a/setup/hyperion-install.sh +++ b/setup/hyperion-install.sh @@ -83,7 +83,8 @@ msg_info "Installing Dependencies" apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null apt-get install -y lsb-release &>/dev/null -apt-get install -y gnupg &>/dev/null +apt-get install -y gpg &>/dev/null +apt-get install -y apt-transport-https &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing Hyperion" From 283d7ef01cd423f4f5186a4cba7c896fe23e023f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 17:00:16 -0500 Subject: [PATCH 3846/6505] Update hyperion-v4.sh adjust ram --- ct/hyperion-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/hyperion-v4.sh b/ct/hyperion-v4.sh index 3386700b..75491664 100644 --- a/ct/hyperion-v4.sh +++ b/ct/hyperion-v4.sh @@ -3,7 +3,7 @@ echo -e "Loading..." APP="Hyperion" var_disk="2" var_cpu="1" -var_ram="1024" +var_ram="512" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') From 3e833e6b9ee3c36170b36066ecd2ab8f5ea6e9cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 17:06:08 -0500 Subject: [PATCH 3847/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index afb53133..b9e58383 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-20 + +### Changed + +- **Hyperion LXC** + - NEW Script + ## 2022-12-17 ### Changed From bb88143a653f997c981fb64ae87b208202f57e47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 21:25:33 -0500 Subject: [PATCH 3848/6505] Update nextcloudpi-install.sh switch back to github.com/nextcloud/ --- setup/nextcloudpi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index dba702f4..f45aadbc 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -85,7 +85,7 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" -curl -sSL https://raw.githubusercontent.com/tteck/nextcloudpi/master/install.sh | bash &>/dev/null +curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null msg_ok "Installed NextCloudPi" PASS=$(grep -w "root" /etc/shadow | cut -b6) From 1b1f7bd51fb80d4b27d82565a3750cd4ec6722ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Dec 2022 23:05:51 -0500 Subject: [PATCH 3849/6505] Update nextcloudpi-install.sh add 0.0.0.0 as a trusted domain --- setup/nextcloudpi-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index f45aadbc..a7a03299 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -86,6 +86,8 @@ msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null +sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php +sudo service apache2 restart msg_ok "Installed NextCloudPi" PASS=$(grep -w "root" /etc/shadow | cut -b6) From da7741e0f239d2b0d0f403a48462aa274f410886 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 08:26:16 -0500 Subject: [PATCH 3850/6505] Update paperless-ngx-update.sh check dependencies --- misc/paperless-ngx-update.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 752c4376..ca0a1989 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -58,6 +58,8 @@ sleep 1 msg_ok "Stopped Paperless-ngx" msg_info "Updating to ${RELEASE}" +if [ "$(dpkg -l | awk '/libmariadb-dev/ {print }'|wc -l)" != 1 ]; then apt-get install libmariadb-dev; fi &>/dev/null +if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install libmariadb-dev-compat; fi &>/dev/null wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null cp -r /opt/paperless/paperless.conf paperless-ngx/ From 221176f20d540cee2b8485793d368b7eb6b92851 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 08:41:08 -0500 Subject: [PATCH 3851/6505] Update paperless-ngx-update.sh check dependencies --- misc/paperless-ngx-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index ca0a1989..2f478912 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -58,7 +58,7 @@ sleep 1 msg_ok "Stopped Paperless-ngx" msg_info "Updating to ${RELEASE}" -if [ "$(dpkg -l | awk '/libmariadb-dev/ {print }'|wc -l)" != 1 ]; then apt-get install libmariadb-dev; fi &>/dev/null +if [ "$(dpkg -l | awk '/libmariadb-dev/ {print }'|wc -l)" != 2 ]; then apt-get install libmariadb-dev; fi &>/dev/null if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install libmariadb-dev-compat; fi &>/dev/null wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null From b0f5898f699c987aaf18a380fad698ac70eb1f4b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 08:48:29 -0500 Subject: [PATCH 3852/6505] Update to allow continue despite network issues (#855) (#856) Change to allow install to continue like it does for Postgres Co-authored-by: ThellraAK --- setup/paperless-ngx-install.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index 41e72f36..14fa3d1b 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -61,8 +61,14 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - exit 1 + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi From 5b03b47ee61d7634c4b5d900811c653c046f8d4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 09:19:47 -0500 Subject: [PATCH 3853/6505] Update magicmirror-install.sh (#857) (#858) Change connection prompt to allow bypass Co-authored-by: ThellraAK --- setup/magicmirror-install.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index e252fea4..1017de12 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -61,8 +61,14 @@ msg_ok "Network Connected: ${BL}$(hostname -I)" set +e alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - exit 1 + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi From 1c42003b641fcfc155f808d0e19e35c5933f459b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 11:48:27 -0500 Subject: [PATCH 3854/6505] Update paperless-ngx-update.sh add tag --- misc/paperless-ngx-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 2f478912..3b1d4719 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -58,8 +58,8 @@ sleep 1 msg_ok "Stopped Paperless-ngx" msg_info "Updating to ${RELEASE}" -if [ "$(dpkg -l | awk '/libmariadb-dev/ {print }'|wc -l)" != 2 ]; then apt-get install libmariadb-dev; fi &>/dev/null -if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install libmariadb-dev-compat; fi &>/dev/null +if [ "$(dpkg -l | awk '/libmariadb-dev/ {print }'|wc -l)" != 2 ]; then apt-get install -y libmariadb-dev; fi &>/dev/null +if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null cp -r /opt/paperless/paperless.conf paperless-ngx/ From 01bfd71633a4bcd6e015bd6a6e322f90a18f55ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 11:55:44 -0500 Subject: [PATCH 3855/6505] Update paperless-ngx-update.sh --- misc/paperless-ngx-update.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh index 3b1d4719..9ab62db6 100644 --- a/misc/paperless-ngx-update.sh +++ b/misc/paperless-ngx-update.sh @@ -58,7 +58,6 @@ sleep 1 msg_ok "Stopped Paperless-ngx" msg_info "Updating to ${RELEASE}" -if [ "$(dpkg -l | awk '/libmariadb-dev/ {print }'|wc -l)" != 2 ]; then apt-get install -y libmariadb-dev; fi &>/dev/null if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null From cb327cd55cfe8330aed57488875ab481955d00c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 15:04:51 -0500 Subject: [PATCH 3856/6505] add option for verbose mode (#859) --- ct/adguard-v4.sh | 11 +++++++++++ ct/alpine-v4.sh | 11 +++++++++++ ct/archlinux-v4.sh | 11 +++++++++++ ct/blocky-v4.sh | 11 +++++++++++ ct/casaos-v4.sh | 11 +++++++++++ ct/changedetection-v4.sh | 11 +++++++++++ ct/create_lxc.sh | 1 + ct/daemonsync-v4.sh | 11 +++++++++++ ct/dashy-v4.sh | 11 +++++++++++ ct/debian-v4.sh | 11 +++++++++++ ct/deconz-v4.sh | 11 +++++++++++ ct/docker-v4.sh | 11 +++++++++++ ct/emby-v4.sh | 11 +++++++++++ ct/emqx-v4.sh | 11 +++++++++++ ct/esphome-v4.sh | 11 +++++++++++ ct/grafana-v4.sh | 11 +++++++++++ ct/grocy-v4.sh | 11 +++++++++++ ct/heimdalldashboard-v4.sh | 11 +++++++++++ ct/homeassistant-core-v4.sh | 11 +++++++++++ ct/homeassistant-v4.sh | 11 +++++++++++ ct/homebridge-v4.sh | 11 +++++++++++ ct/homepage-v4.sh | 11 +++++++++++ ct/hyperion-v4.sh | 11 +++++++++++ ct/influxdb-v4.sh | 11 +++++++++++ ct/iobroker-v4.sh | 11 +++++++++++ ct/jellyfin-v4.sh | 11 +++++++++++ ct/keycloak-v4.sh | 11 +++++++++++ ct/magicmirror-v4.sh | 11 +++++++++++ ct/mariadb-v4.sh | 11 +++++++++++ ct/meshcentral-v4.sh | 11 +++++++++++ ct/motioneye-v4.sh | 11 +++++++++++ ct/mqtt-v4.sh | 21 ++++++++++++++++----- ct/n8n-v4.sh | 11 +++++++++++ ct/navidrome-v4.sh | 11 +++++++++++ ct/nextcloudpi-v4.sh | 11 +++++++++++ ct/nginx-proxy-manager-v4.sh | 11 +++++++++++ ct/nocodb-v4.sh | 11 +++++++++++ ct/node-red-v4.sh | 11 +++++++++++ ct/omada-v4.sh | 11 +++++++++++ ct/omv-v4.sh | 11 +++++++++++ ct/openhab-v4.sh | 11 +++++++++++ ct/paperless-ngx-v4.sh | 11 +++++++++++ ct/photoprism-v4.sh | 11 +++++++++++ ct/pihole-v4.sh | 11 +++++++++++ ct/plex-v4.sh | 11 +++++++++++ ct/podman-homeassistant-v4.sh | 11 +++++++++++ ct/postgresql-v4.sh | 11 +++++++++++ ct/prometheus-v4.sh | 11 +++++++++++ ct/scrypted-v4.sh | 11 +++++++++++ ct/shinobi-v4.sh | 11 +++++++++++ ct/syncthing-v4.sh | 11 +++++++++++ ct/technitiumdns-v4.sh | 11 +++++++++++ ct/trilium-v4.sh | 11 +++++++++++ ct/ubuntu-v4.sh | 11 +++++++++++ ct/umbrel-v4.sh | 11 +++++++++++ ct/unifi-v4.sh | 11 +++++++++++ ct/uptimekuma-v4.sh | 11 +++++++++++ ct/vaultwarden-v4.sh | 11 +++++++++++ ct/whoogle-v4.sh | 11 +++++++++++ ct/wikijs-v4.sh | 11 +++++++++++ ct/wireguard-v4.sh | 11 +++++++++++ ct/zigbee2mqtt-v4.sh | 11 +++++++++++ ct/zwave-js-ui-v4.sh | 11 +++++++++++ setup/adguard-install.sh | 1 + setup/blocky-install.sh | 1 + setup/casaos-install.sh | 1 + setup/changedetection-install.sh | 1 + setup/daemonsync-install.sh | 1 + setup/dashy-install.sh | 1 + setup/debian-install.sh | 1 + setup/deconz-install.sh | 1 + setup/docker-install.sh | 1 + setup/emby-install.sh | 1 + setup/emqx-install.sh | 1 + setup/esphome-install.sh | 1 + setup/grafana-install.sh | 1 + setup/grocy-install.sh | 1 + setup/heimdalldashboard-install.sh | 1 + setup/homeassistant-core-install.sh | 1 + setup/homeassistant-install.sh | 1 + setup/homebridge-install.sh | 1 + setup/homepage-install.sh | 1 + setup/hyperion-install.sh | 1 + setup/influxdb-install.sh | 1 + setup/iobroker-install.sh | 1 + setup/jellyfin-install.sh | 1 + setup/keycloak-install.sh | 1 + setup/magicmirror-install.sh | 1 + setup/mariadb-install.sh | 1 + setup/meshcentral-install.sh | 1 + setup/motioneye-install.sh | 1 + setup/mqtt-install.sh | 1 + setup/n8n-install.sh | 1 + setup/navidrome-install.sh | 1 + setup/nextcloudpi-install.sh | 1 + setup/nginx-proxy-manager-install.sh | 1 + setup/nocodb-install.sh | 1 + setup/node-red-install.sh | 1 + setup/omada-install.sh | 1 + setup/omv-install.sh | 1 + setup/openhab-install.sh | 1 + setup/paperless-ngx-install.sh | 1 + setup/photoprism-install.sh | 1 + setup/pihole-install.sh | 1 + setup/plex-install.sh | 1 + setup/podman-homeassistant-install.sh | 1 + setup/postgresql-install.sh | 1 + setup/prometheus-install.sh | 1 + setup/scrypted-install.sh | 1 + setup/shinobi-install.sh | 1 + setup/syncthing-install.sh | 1 + setup/technitiumdns-install.sh | 1 + setup/trilium-install.sh | 1 + setup/ubuntu-install.sh | 1 + setup/umbrel-install.sh | 1 + setup/unifi-install.sh | 1 + setup/uptimekuma-install.sh | 1 + setup/vaultwarden-install.sh | 1 + setup/whoogle-install.sh | 1 + setup/wikijs-install.sh | 1 + setup/wireguard-install.sh | 1 + setup/zigbee2mqtt-install.sh | 1 + setup/zwave-js-ui-install.sh | 1 + 123 files changed, 748 insertions(+), 5 deletions(-) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index 1c50582a..a21350c5 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/alpine-v4.sh b/ct/alpine-v4.sh index dd3a7d6d..74ca977f 100644 --- a/ct/alpine-v4.sh +++ b/ct/alpine-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -245,6 +247,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -267,6 +276,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -274,6 +284,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/archlinux-v4.sh b/ct/archlinux-v4.sh index 6c8c294a..0c88369e 100644 --- a/ct/archlinux-v4.sh +++ b/ct/archlinux-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index 0f6ebcad..07f58776 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 9a2a9dee..63819aa5 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/changedetection-v4.sh b/ct/changedetection-v4.sh index 13f64d23..0580a2cc 100644 --- a/ct/changedetection-v4.sh +++ b/ct/changedetection-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 43aea538..c0af30d9 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index ce51efa0..c9c19e9b 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 43a9ce29..5aac4c22 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 457e5bce..c70d40dc 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index f3aa35f4..83debc14 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index aa82aafc..1a6d2d50 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index d8abcd6e..6ad8344e 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -101,6 +101,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -258,6 +260,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -280,6 +289,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -287,6 +297,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index 6dbffae3..ee621375 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index 45d2f651..d7e7350d 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 0a096cb5..68a8488d 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 3aa8b8a2..7b4fae30 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 1d20b4ab..410d50fa 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index af70dd12..df5f2408 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index b3c21663..a4f50ad8 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 604e8756..c1305e20 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index e0079f56..95df4b44 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/hyperion-v4.sh b/ct/hyperion-v4.sh index 75491664..a4746631 100644 --- a/ct/hyperion-v4.sh +++ b/ct/hyperion-v4.sh @@ -101,6 +101,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -250,6 +252,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -272,6 +281,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -279,6 +289,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 544c08a6..9ba3a22b 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index bbea2222..7e91f90f 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index a0c417d0..44a18a47 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -101,6 +101,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -258,6 +260,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -280,6 +289,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -287,6 +297,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 5ab128f3..f145d045 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 14686897..28290847 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index ba1848bc..780ba45c 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 268be525..f91f91d3 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 70798f15..78d60c7b 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index afcb6892..84801204 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -224,6 +226,13 @@ fi echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -246,13 +255,15 @@ fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index e864e714..c7b0cc56 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index e274d0cf..750767a0 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index e5bb4d6f..0b119e71 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index f6ec77d7..c12d14d1 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 8a7680e6..2ca00f97 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 87bf78e5..97a94755 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 5ced9246..099deba7 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -257,6 +259,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -279,6 +288,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -286,6 +296,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index 9be51f0b..a649a28c 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index 0ce75e46..dc559dc3 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index 3b5247e8..37c347a7 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index fad36764..5f4a5827 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index a34e8eb5..01d25fff 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index cfcd9696..a490c938 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -101,6 +101,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -258,6 +260,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -280,6 +289,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -287,6 +297,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index c5944bef..e4d22054 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -103,6 +103,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -252,6 +254,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -274,6 +283,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -281,6 +291,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index a3c82982..aaa68b00 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index a792708e..6bb1b9db 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh index cc23caee..94f598d1 100644 --- a/ct/scrypted-v4.sh +++ b/ct/scrypted-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/shinobi-v4.sh b/ct/shinobi-v4.sh index 265e7d23..cfb70935 100644 --- a/ct/shinobi-v4.sh +++ b/ct/shinobi-v4.sh @@ -101,6 +101,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -258,6 +260,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -280,6 +289,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -287,6 +297,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index c741c527..6a5e0de7 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -101,6 +101,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -250,6 +252,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -272,6 +281,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -279,6 +289,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index ce8c822a..644ddd78 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index c7b08580..dbdf6585 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 13d9fa3d..44f3d233 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -257,6 +259,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -279,6 +288,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -286,6 +296,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 1df43db6..391b4578 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index 329e3326..3d60590d 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index d49cf8cc..b31b279f 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index ecf7d10f..9e5ffc70 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 3457e95e..a910806c 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -99,6 +99,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -270,6 +279,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -277,6 +287,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index 13a5dccd..54b25b7b 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index da10e317..946b6c00 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -101,6 +101,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -250,6 +252,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -272,6 +281,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -279,6 +289,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 5d726061..1d5e0bc8 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index d477aefb..46aa99ba 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -100,6 +100,8 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -249,6 +251,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else @@ -271,6 +280,7 @@ function start_script() { } clear start_script +if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" else @@ -278,6 +288,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/setup/adguard-install.sh b/setup/adguard-install.sh index bfaf8b83..ec37c2c9 100644 --- a/setup/adguard-install.sh +++ b/setup/adguard-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/blocky-install.sh b/setup/blocky-install.sh index 620c57a2..ff3ad10c 100644 --- a/setup/blocky-install.sh +++ b/setup/blocky-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index 23ea0f98..d2f383f9 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/changedetection-install.sh b/setup/changedetection-install.sh index 923ca216..8fe7d7fd 100644 --- a/setup/changedetection-install.sh +++ b/setup/changedetection-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/daemonsync-install.sh b/setup/daemonsync-install.sh index e70c9943..3936e378 100644 --- a/setup/daemonsync-install.sh +++ b/setup/daemonsync-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/dashy-install.sh b/setup/dashy-install.sh index 677b4913..72155a18 100644 --- a/setup/dashy-install.sh +++ b/setup/dashy-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/debian-install.sh b/setup/debian-install.sh index 124a8984..dca29c9b 100644 --- a/setup/debian-install.sh +++ b/setup/debian-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/deconz-install.sh b/setup/deconz-install.sh index 7c5f1b08..cef9767d 100644 --- a/setup/deconz-install.sh +++ b/setup/deconz-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/docker-install.sh b/setup/docker-install.sh index b455fbbc..8587b39b 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/emby-install.sh b/setup/emby-install.sh index 979f1955..fcd7396c 100644 --- a/setup/emby-install.sh +++ b/setup/emby-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/emqx-install.sh b/setup/emqx-install.sh index e73f7777..e40bed9c 100644 --- a/setup/emqx-install.sh +++ b/setup/emqx-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/esphome-install.sh b/setup/esphome-install.sh index 91092358..d624ad84 100644 --- a/setup/esphome-install.sh +++ b/setup/esphome-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/grafana-install.sh b/setup/grafana-install.sh index c912e472..4235bd26 100644 --- a/setup/grafana-install.sh +++ b/setup/grafana-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index 8740d66f..cab299fb 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/heimdalldashboard-install.sh b/setup/heimdalldashboard-install.sh index ff8cc386..c9ef0bd7 100644 --- a/setup/heimdalldashboard-install.sh +++ b/setup/heimdalldashboard-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index d49b08f2..f5ff284c 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 11af7412..1c42053c 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/homebridge-install.sh b/setup/homebridge-install.sh index 8ce65cf0..1841a555 100644 --- a/setup/homebridge-install.sh +++ b/setup/homebridge-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/homepage-install.sh b/setup/homepage-install.sh index 0f60d5b1..c48b139b 100644 --- a/setup/homepage-install.sh +++ b/setup/homepage-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/hyperion-install.sh b/setup/hyperion-install.sh index 80c5de26..ee8a3c9f 100644 --- a/setup/hyperion-install.sh +++ b/setup/hyperion-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 07c40091..83c6199e 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/iobroker-install.sh b/setup/iobroker-install.sh index 5c2580db..3bcb2570 100644 --- a/setup/iobroker-install.sh +++ b/setup/iobroker-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/jellyfin-install.sh b/setup/jellyfin-install.sh index 176dc5fc..d70f29ce 100644 --- a/setup/jellyfin-install.sh +++ b/setup/jellyfin-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/keycloak-install.sh b/setup/keycloak-install.sh index 6e412b6d..00128983 100644 --- a/setup/keycloak-install.sh +++ b/setup/keycloak-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/magicmirror-install.sh b/setup/magicmirror-install.sh index 1017de12..71bd489a 100644 --- a/setup/magicmirror-install.sh +++ b/setup/magicmirror-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/mariadb-install.sh b/setup/mariadb-install.sh index 6d0ad608..12eeba97 100644 --- a/setup/mariadb-install.sh +++ b/setup/mariadb-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/meshcentral-install.sh b/setup/meshcentral-install.sh index 114424d5..77233afc 100644 --- a/setup/meshcentral-install.sh +++ b/setup/meshcentral-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/motioneye-install.sh b/setup/motioneye-install.sh index b7528335..2d116c01 100644 --- a/setup/motioneye-install.sh +++ b/setup/motioneye-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/mqtt-install.sh b/setup/mqtt-install.sh index b0d2406d..70f9efeb 100644 --- a/setup/mqtt-install.sh +++ b/setup/mqtt-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/n8n-install.sh b/setup/n8n-install.sh index a6689a66..1cca4611 100644 --- a/setup/n8n-install.sh +++ b/setup/n8n-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/navidrome-install.sh b/setup/navidrome-install.sh index e08f0842..763d5353 100644 --- a/setup/navidrome-install.sh +++ b/setup/navidrome-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/nextcloudpi-install.sh b/setup/nextcloudpi-install.sh index a7a03299..ec0729d7 100644 --- a/setup/nextcloudpi-install.sh +++ b/setup/nextcloudpi-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/nginx-proxy-manager-install.sh b/setup/nginx-proxy-manager-install.sh index f60e548d..88c11cdd 100644 --- a/setup/nginx-proxy-manager-install.sh +++ b/setup/nginx-proxy-manager-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/nocodb-install.sh b/setup/nocodb-install.sh index 9244e605..0099b7bd 100644 --- a/setup/nocodb-install.sh +++ b/setup/nocodb-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/node-red-install.sh b/setup/node-red-install.sh index b535cf54..2169624a 100644 --- a/setup/node-red-install.sh +++ b/setup/node-red-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/omada-install.sh b/setup/omada-install.sh index d55510f9..0daab6a0 100644 --- a/setup/omada-install.sh +++ b/setup/omada-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/omv-install.sh b/setup/omv-install.sh index 3b8b07e3..415e428b 100644 --- a/setup/omv-install.sh +++ b/setup/omv-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/setup/openhab-install.sh b/setup/openhab-install.sh index 24600d2d..5736c2b0 100644 --- a/setup/openhab-install.sh +++ b/setup/openhab-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/paperless-ngx-install.sh b/setup/paperless-ngx-install.sh index 14fa3d1b..a994c2f3 100644 --- a/setup/paperless-ngx-install.sh +++ b/setup/paperless-ngx-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/photoprism-install.sh b/setup/photoprism-install.sh index a879cc0e..6b6ec3f7 100644 --- a/setup/photoprism-install.sh +++ b/setup/photoprism-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/setup/pihole-install.sh b/setup/pihole-install.sh index 1b785b05..8e3783ac 100644 --- a/setup/pihole-install.sh +++ b/setup/pihole-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/setup/plex-install.sh b/setup/plex-install.sh index 47883856..93527256 100644 --- a/setup/plex-install.sh +++ b/setup/plex-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/podman-homeassistant-install.sh b/setup/podman-homeassistant-install.sh index 9cd77087..7fb81641 100644 --- a/setup/podman-homeassistant-install.sh +++ b/setup/podman-homeassistant-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/postgresql-install.sh b/setup/postgresql-install.sh index 4b5986be..88cd544d 100644 --- a/setup/postgresql-install.sh +++ b/setup/postgresql-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/prometheus-install.sh b/setup/prometheus-install.sh index 8c0b5dc8..c0493b2f 100644 --- a/setup/prometheus-install.sh +++ b/setup/prometheus-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/scrypted-install.sh b/setup/scrypted-install.sh index 1bb80bdc..2347d59a 100644 --- a/setup/scrypted-install.sh +++ b/setup/scrypted-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/shinobi-install.sh b/setup/shinobi-install.sh index a72a5572..ba6fa2af 100644 --- a/setup/shinobi-install.sh +++ b/setup/shinobi-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/syncthing-install.sh b/setup/syncthing-install.sh index 15e34ca2..c16488f6 100644 --- a/setup/syncthing-install.sh +++ b/setup/syncthing-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/technitiumdns-install.sh b/setup/technitiumdns-install.sh index 509e2fda..dbd8ecd1 100644 --- a/setup/technitiumdns-install.sh +++ b/setup/technitiumdns-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/trilium-install.sh b/setup/trilium-install.sh index f5080744..c7f97023 100644 --- a/setup/trilium-install.sh +++ b/setup/trilium-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/ubuntu-install.sh b/setup/ubuntu-install.sh index 3cc2a4b3..b090d307 100644 --- a/setup/ubuntu-install.sh +++ b/setup/ubuntu-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index 11f26a6d..872a0907 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/unifi-install.sh b/setup/unifi-install.sh index 2210a47e..6dcd2e00 100644 --- a/setup/unifi-install.sh +++ b/setup/unifi-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/setup/uptimekuma-install.sh b/setup/uptimekuma-install.sh index f08f5021..c542bba5 100644 --- a/setup/uptimekuma-install.sh +++ b/setup/uptimekuma-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/vaultwarden-install.sh b/setup/vaultwarden-install.sh index 2047f631..72a03a9e 100644 --- a/setup/vaultwarden-install.sh +++ b/setup/vaultwarden-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/whoogle-install.sh b/setup/whoogle-install.sh index b574667a..dc3efde8 100644 --- a/setup/whoogle-install.sh +++ b/setup/whoogle-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/wikijs-install.sh b/setup/wikijs-install.sh index 51255211..8194d606 100644 --- a/setup/wikijs-install.sh +++ b/setup/wikijs-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/wireguard-install.sh b/setup/wireguard-install.sh index e8b82753..96e11ce9 100644 --- a/setup/wireguard-install.sh +++ b/setup/wireguard-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/zigbee2mqtt-install.sh b/setup/zigbee2mqtt-install.sh index 2ac580b7..1d488c49 100644 --- a/setup/zigbee2mqtt-install.sh +++ b/setup/zigbee2mqtt-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/setup/zwave-js-ui-install.sh b/setup/zwave-js-ui-install.sh index 031ef329..b67f28d5 100644 --- a/setup/zwave-js-ui-install.sh +++ b/setup/zwave-js-ui-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") From 6ca1374026e065ed3b5043e5fe9808f5a94ebc8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 15:13:10 -0500 Subject: [PATCH 3857/6505] Update influxdb-install.sh add `systemctl enable --now influxdb` --- setup/influxdb-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/influxdb-install.sh b/setup/influxdb-install.sh index 83c6199e..3c57b2c8 100644 --- a/setup/influxdb-install.sh +++ b/setup/influxdb-install.sh @@ -108,6 +108,7 @@ if [[ $INFLUX == "2" ]]; then else apt-get install -y influxdb &>/dev/null fi +systemctl enable --now influxdb &>/dev/null msg_ok "Installed InfluxDB" read -r -p "Would you like to add Telegraf? " prompt From 9bc78dcfe5e37ddf607732b12b089f1881a08064 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Dec 2022 15:19:38 -0500 Subject: [PATCH 3858/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b9e58383..384d090c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-22 + +### Changed + +- **All LXC's** + - Add an option to run the script in Verbose Mode (Advanced) + ## 2022-12-20 ### Changed From 5bc7e2fc7c90950e90ed65c2c7fe29ee2e3ab221 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Dec 2022 03:06:24 -0500 Subject: [PATCH 3859/6505] Update mqtt-v4.sh --- ct/mqtt-v4.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index 84801204..d8b09ed8 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -255,6 +255,11 @@ fi } clear start_script +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" From aff72290c44a8d5af286871284f72e5ddba91fc8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Dec 2022 03:07:34 -0500 Subject: [PATCH 3860/6505] Update mqtt-v4.sh --- ct/mqtt-v4.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index d8b09ed8..84801204 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -255,11 +255,6 @@ fi } clear start_script -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" From c176eb03fb946da2c7d56e5778768c515e7929da Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Dec 2022 19:56:40 -0500 Subject: [PATCH 3861/6505] Update homeassistant-core-install.sh dbus-fast==1.83.1 --- setup/homeassistant-core-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index f5ff284c..2ae98abd 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -148,8 +148,8 @@ pip install homeassistant &>/dev/null msg_ok "Installed Home Assistant-Core" # fix for inconsistent versions, hopefully the HA team will get this fixed -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json From c2c75f4788a5dab617f122429323c91288c372a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Dec 2022 19:57:42 -0500 Subject: [PATCH 3862/6505] Update core-update.sh dbus-fast==1.83.1 --- misc/core-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/core-update.sh b/misc/core-update.sh index 105685e2..64e60e9f 100644 --- a/misc/core-update.sh +++ b/misc/core-update.sh @@ -49,8 +49,8 @@ pip install ${BR}--upgrade homeassistant &>/dev/null msg_ok "Updated Home Assistant" msg_info "Setting Dependency Versions" -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.82.0/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json msg_ok "Set Dependency Versions" From a6b1722a27884ec21829272284503f8f140379a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Dec 2022 16:45:27 -0500 Subject: [PATCH 3863/6505] Update deconz-v4.sh set Advanced settings to default as Privileged --- ct/deconz-v4.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 83debc14..9faf169b 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -106,8 +106,8 @@ function default_settings() { } function advanced_settings() { CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then From 74bc5cd3cadc25bd452ad797c0370a5f8560c674 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Dec 2022 05:29:59 -0500 Subject: [PATCH 3864/6505] Update grocy-install.sh (#873) (#874) Fixes bug of missing packages when installing grocy php8.1-sqlite3, php8.1-gd, php8.1-intl and php8.1-mbstring Co-authored-by: Calvin --- setup/grocy-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/grocy-install.sh b/setup/grocy-install.sh index cab299fb..fcc019e7 100644 --- a/setup/grocy-install.sh +++ b/setup/grocy-install.sh @@ -96,10 +96,10 @@ sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://pa apt-get update &>/dev/null apt-get install -y php8.1 &>/dev/null apt-get install -y libapache2-mod-php8.1 &>/dev/null -apt-get install -y php-sqlite3 &>/dev/null -apt-get install -y php-gd &>/dev/null -apt-get install -y php-intl &>/dev/null -apt-get install -y php-mbstring &>/dev/null +apt-get install -y php8.1-sqlite3 &>/dev/null +apt-get install -y php8.1-gd &>/dev/null +apt-get install -y php8.1-intl &>/dev/null +apt-get install -y php8.1-mbstring &>/dev/null msg_ok "Installed PHP 8.1" msg_info "Installing grocy" From 93c9e0494adef46b254cebc8b838edb8ba261745 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Dec 2022 07:56:09 -0500 Subject: [PATCH 3865/6505] Update docker-install.sh fuse-overlayfs option --- setup/docker-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 8587b39b..54a51695 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -97,6 +97,13 @@ DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +fi cat >$DOCKER_CONFIG_PATH <<'EOF' { "log-driver": "journald" From 36d78d83b447799785eb610468cf2326e3d455e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Dec 2022 08:01:03 -0500 Subject: [PATCH 3866/6505] Update docker-v4.sh fuse-overlayfs option if created privileged, automatic usb passthrough --- ct/docker-v4.sh | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index 1a6d2d50..326fb3f9 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -97,8 +97,10 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" @@ -250,6 +252,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" @@ -280,13 +289,14 @@ function start_script() { clear start_script if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" else - FEATURES="nesting=1" +FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export ST=$FUSE export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID @@ -311,6 +321,18 @@ cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$CT_TYPE" == "0" ]; then +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From c0bad2760f26f1fb86199a226deed919efa99a26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Dec 2022 08:04:28 -0500 Subject: [PATCH 3867/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 384d090c..86f48bc6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,14 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-27 + +### Changed + +- **Docker LXC** + - Add an option to use Fuse Overlayfs (ZFS) (Advanced) + - If the LXC is created Privileged, the script will automatically set up USB passthrough. + ## 2022-12-22 ### Changed From 4dc248cfe47b348473fdadd49570d5ae91d3d9c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Dec 2022 09:17:21 -0500 Subject: [PATCH 3868/6505] Update homeassistant-install.sh fuse-overlayfs option --- setup/homeassistant-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 1c42053c..5e7e83f7 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -101,6 +101,13 @@ PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +fi cat >$DOCKER_CONFIG_PATH <<'EOF' { "log-driver": "journald" From 9ac80e6ebe8a9adf0693e5b5f056beb05d1b9a63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Dec 2022 09:19:53 -0500 Subject: [PATCH 3869/6505] Update homeassistant-v4.sh fuse-overlayfs option --- ct/homeassistant-v4.sh | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index a4f50ad8..dece5d89 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -97,8 +97,10 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" @@ -250,6 +252,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" @@ -280,13 +289,14 @@ function start_script() { clear start_script if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" else - FEATURES="nesting=1" +FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export ST=$FUSE export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID @@ -307,10 +317,13 @@ export PCT_OPTIONS=" " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -if [ "$CT_TYPE" == "0" ]; then - cat <>$LXC_CONFIG +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: +EOF +if [ "$CT_TYPE" == "0" ]; then +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: c 188:* rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir @@ -319,11 +332,6 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF -else - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF fi msg_info "Starting LXC Container" pct start $CTID From f3c45d0398ad1b1ec7f72c040a63b291a6b12be8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Dec 2022 09:22:06 -0500 Subject: [PATCH 3870/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 86f48bc6..b222837e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file. ### Changed +- **Home Assistant Container LXC** + - Add an option to use Fuse Overlayfs (ZFS) (Advanced) + - **Docker LXC** - Add an option to use Fuse Overlayfs (ZFS) (Advanced) - If the LXC is created Privileged, the script will automatically set up USB passthrough. From 552cff8a2c889b257ac565431b66b10c09836cc4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 06:41:43 -0500 Subject: [PATCH 3871/6505] fuse-overlayfs option (#876) CasaOS Umbrel --- ct/casaos-v4.sh | 18 ++++++++++++++---- ct/umbrel-v4.sh | 18 ++++++++++++++---- setup/casaos-install.sh | 7 +++++++ setup/umbrel-install.sh | 7 +++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 63819aa5..c3d54ea9 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -98,8 +98,10 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" @@ -251,6 +253,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" @@ -281,13 +290,14 @@ function start_script() { clear start_script if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" else - FEATURES="nesting=1" +FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export ST=$FUSE export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 391b4578..c19dce93 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -98,8 +98,10 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" @@ -251,6 +253,13 @@ function advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" @@ -281,13 +290,14 @@ function start_script() { clear start_script if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" else - FEATURES="nesting=1" +FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export ST=$FUSE export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/setup/casaos-install.sh b/setup/casaos-install.sh index d2f383f9..35e88e14 100644 --- a/setup/casaos-install.sh +++ b/setup/casaos-install.sh @@ -96,6 +96,13 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' EOF msg_info "Installing CasaOS (Patience)" +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +fi wget -qO- https://get.casaos.io | bash &>/dev/null msg_ok "Installed CasaOS" diff --git a/setup/umbrel-install.sh b/setup/umbrel-install.sh index 872a0907..95c1c376 100644 --- a/setup/umbrel-install.sh +++ b/setup/umbrel-install.sh @@ -95,6 +95,13 @@ cat >$DOCKER_CONFIG_PATH <<'EOF' EOF msg_info "Installing Umbrel (Patience)" +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +fi curl -sL https://umbrel.sh | bash &>/dev/null systemctl daemon-reload systemctl enable --now umbrel-startup.service &>/dev/null From 2cdc4d411546bacc8e7eda6c4df6b5c0da9cb8c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 10:18:52 -0500 Subject: [PATCH 3872/6505] Update docker-install.sh --- setup/docker-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 54a51695..a41bbc79 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -102,6 +102,7 @@ VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/la cd /usr/local/bin curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 chmod 755 /usr/local/bin/fuse-overlayfs +echo -e '{\n "storage-driver": "fuse-overlayfs"\n}' > /etc/docker/daemon.json cd ~ fi cat >$DOCKER_CONFIG_PATH <<'EOF' From 51667bbf9af59b10d716e6767fc3555d61d65501 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 11:46:44 -0500 Subject: [PATCH 3873/6505] Update docker-install.sh fix daemon.json --- setup/docker-install.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index a41bbc79..19b6c1ff 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -102,14 +102,11 @@ VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/la cd /usr/local/bin curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 chmod 755 /usr/local/bin/fuse-overlayfs -echo -e '{\n "storage-driver": "fuse-overlayfs"\n}' > /etc/docker/daemon.json cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "storage-driver": "overlay2",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json fi -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF sh <(curl -sSL https://get.docker.com) &>/dev/null msg_ok "Installed Docker $DOCKER_LATEST_VERSION" From 878eeb242973879911018d5ef708a4218be52940 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 15:10:36 -0500 Subject: [PATCH 3874/6505] Update homeassistant-core-install.sh option to run beta --- setup/homeassistant-core-install.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index 2ae98abd..b54381c2 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -135,6 +135,13 @@ pyenv install 3.10.8 &>/dev/null pyenv global 3.10.8 msg_ok "Installed Python 3.10.8" +read -r -p " Use the Beta Branch? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + BR="--pre " +else + BR="" +fi + msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant cd /srv/homeassistant @@ -144,7 +151,7 @@ pip install --upgrade pip &>/dev/null python3 -m pip install wheel &>/dev/null pip install mysqlclient &>/dev/null pip install psycopg2-binary &>/dev/null -pip install homeassistant &>/dev/null +pip install ${BR}homeassistant &>/dev/null msg_ok "Installed Home Assistant-Core" # fix for inconsistent versions, hopefully the HA team will get this fixed From 398f23c0b4d567070f56d3b692c9475954578fbd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 15:49:57 -0500 Subject: [PATCH 3875/6505] Update homeassistant-core-install.sh fix dependency versions for beta --- setup/homeassistant-core-install.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index b54381c2..d704fca5 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -155,8 +155,13 @@ pip install ${BR}homeassistant &>/dev/null msg_ok "Installed Home Assistant-Core" # fix for inconsistent versions, hopefully the HA team will get this fixed +if [ "${BR}" == "--pre " ]; then +sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +else sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +fi sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json From 791d8c91f74946a26f7599981dd7018e77d53195 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 15:53:47 -0500 Subject: [PATCH 3876/6505] Update core-update.sh fix dependency versions for beta --- misc/core-update.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/misc/core-update.sh b/misc/core-update.sh index 64e60e9f..1b618de9 100644 --- a/misc/core-update.sh +++ b/misc/core-update.sh @@ -49,8 +49,13 @@ pip install ${BR}--upgrade homeassistant &>/dev/null msg_ok "Updated Home Assistant" msg_info "Setting Dependency Versions" -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json +if [ "${BR}" == "--pre " ]; then +sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +else +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +fi sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json msg_ok "Set Dependency Versions" From a5a5374134a09d6069b69148ee89445065053a30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 17:27:12 -0500 Subject: [PATCH 3877/6505] Create k0s-install.sh --- setup/k0s-install.sh | 133 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 setup/k0s-install.sh diff --git a/setup/k0s-install.sh b/setup/k0s-install.sh new file mode 100644 index 00000000..1ed9806f --- /dev/null +++ b/setup/k0s-install.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +apt-get install -y git &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing k0s Kubernetes" +sh <(curl -sSLf https://get.k0s.sh) &>/dev/null +k0s install controller --single &>/dev/null +k0s start &>/dev/null +mkdir -p /etc/k0s +k0s config create > /etc/k0s/k0s.yaml +msg_ok "Installed k0s Kubernetes" + +read -r -p "Would you like to add Helm Package Manager? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + HELM="Y" +else + HELM="N" +fi + +if [[ $HELM == "Y" ]]; then +msg_info "Installing Helm" +curl -sSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash &>/dev/null +msg_ok "Installed Helm" +fi +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 3dfbe0a5daadd865c6977ee97047e0a453a37a60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 17:29:00 -0500 Subject: [PATCH 3878/6505] Create k0s-v4.sh --- ct/k0s-v4.sh | 318 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 ct/k0s-v4.sh diff --git a/ct/k0s-v4.sh b/ct/k0s-v4.sh new file mode 100644 index 00000000..1622434e --- /dev/null +++ b/ct/k0s-v4.sh @@ -0,0 +1,318 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="k0s" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + cat <<"EOF" + __ ____ + / /__/ __ \__v4_ + / //_/ / / / ___/ + / ,< / /_/ (__ ) +/_/|_|\____/____/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From d024c8d340c367d2ed7f3d6202bba4dfacb42b60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 19:35:30 -0500 Subject: [PATCH 3879/6505] Create podman-install.sh --- setup/podman-install.sh | 144 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 setup/podman-install.sh diff --git a/setup/podman-install.sh b/setup/podman-install.sh new file mode 100644 index 00000000..eabfdf02 --- /dev/null +++ b/setup/podman-install.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing Podman" +apt-get -y install podman &>/dev/null +systemctl enable --now podman.socket &>/dev/null +echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registries.conf +msg_ok "Installed Podman" + +read -r -p "Would you like to add Portainer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + PORTAINER="Y" +else + PORTAINER="N" +fi + +if [[ $PORTAINER == "Y" ]]; then + msg_info "Installing Portainer" + podman run -d \ + --name portainer \ + --restart always \ + -v /var/run/podman/podman.sock:/var/run/docker.sock \ + -v portainer:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + -p 8000:8000 \ + -p 9000:9000 \ + portainer/portainer-ce:latest &>/dev/null + podman generate systemd \ + --new --name portainer \ + >/etc/systemd/system/portainer.service + systemctl enable portainer &>/dev/null + msg_ok "Installed Portainer" +fi + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 4b5e5ef13b240fc000ebe07261e0af55b8b47e20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 19:37:33 -0500 Subject: [PATCH 3880/6505] Create podman-v4.sh --- ct/podman-v4.sh | 318 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 ct/podman-v4.sh diff --git a/ct/podman-v4.sh b/ct/podman-v4.sh new file mode 100644 index 00000000..97250e37 --- /dev/null +++ b/ct/podman-v4.sh @@ -0,0 +1,318 @@ +#!/usr/bin/env bash +echo -e "Loading..." +APP="Podman" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + cat <<"EOF" + ____ __ + / __ \____v4____/ /___ ___ ____ _____ + / /_/ / __ \/ __ / __ `__ \/ __ `/ __ \ + / ____/ /_/ / /_/ / / / / / / /_/ / / / / +/_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +start_script +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From c1ef7ad7b06dae06c86dc92930c27f5e9d3d3c1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Dec 2022 20:24:52 -0500 Subject: [PATCH 3881/6505] Update homeassistant-install.sh correct daemon.json --- setup/homeassistant-install.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 5e7e83f7..47ac3bba 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -107,12 +107,10 @@ cd /usr/local/bin curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 chmod 755 /usr/local/bin/fuse-overlayfs cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "storage-driver": "overlay2",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json fi -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF sh <(curl -sSL https://get.docker.com) &>/dev/null msg_ok "Installed Docker $DOCKER_LATEST_VERSION" From 734e978440822ee30f31de553b9315376533aa5b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Dec 2022 06:11:45 -0500 Subject: [PATCH 3882/6505] Update homeassistant-core-install.sh shorten code for inconsistent versions --- setup/homeassistant-core-install.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-install.sh index d704fca5..e997f268 100644 --- a/setup/homeassistant-core-install.sh +++ b/setup/homeassistant-core-install.sh @@ -156,14 +156,12 @@ msg_ok "Installed Home Assistant-Core" # fix for inconsistent versions, hopefully the HA team will get this fixed if [ "${BR}" == "--pre " ]; then -sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json else -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json fi -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json msg_info "Creating Service" cat </etc/systemd/system/homeassistant.service From 36b596dc97581f6a2f9fcc322618484c496b6993 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Dec 2022 06:14:13 -0500 Subject: [PATCH 3883/6505] Update core-update.sh shorten code for dependency versions --- misc/core-update.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/misc/core-update.sh b/misc/core-update.sh index 1b618de9..e3af18a1 100644 --- a/misc/core-update.sh +++ b/misc/core-update.sh @@ -50,14 +50,12 @@ msg_ok "Updated Home Assistant" msg_info "Setting Dependency Versions" if [ "${BR}" == "--pre " ]; then -sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.82.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json else -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i "s/dbus-fast==1.75.0/dbus-fast==1.83.1/g" /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json fi -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/package_constraints.txt -sed -i "s/bleak==0.19.2/bleak==0.19.5/g" /srv/homeassistant/lib/$PY/site-packages/homeassistant/components/bluetooth/manifest.json msg_ok "Set Dependency Versions" msg_info "Starting Home Assistant" From d4248dbe845efbab08b1b59c20b5ae5568c9c4e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Dec 2022 15:36:12 -0500 Subject: [PATCH 3884/6505] Update docker-install.sh adjust daemon.json --- setup/docker-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/docker-install.sh b/setup/docker-install.sh index 19b6c1ff..de2a015f 100644 --- a/setup/docker-install.sh +++ b/setup/docker-install.sh @@ -105,7 +105,7 @@ chmod 755 /usr/local/bin/fuse-overlayfs cd ~ echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json else -echo -e '{\n "storage-driver": "overlay2",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json fi sh <(curl -sSL https://get.docker.com) &>/dev/null msg_ok "Installed Docker $DOCKER_LATEST_VERSION" From 9d8c30981ddcf18e21c7c67383f1a9514c93a00b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Dec 2022 15:43:05 -0500 Subject: [PATCH 3885/6505] Update homeassistant-install.sh adjust daemon.json --- setup/homeassistant-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/homeassistant-install.sh b/setup/homeassistant-install.sh index 47ac3bba..7ad489d5 100644 --- a/setup/homeassistant-install.sh +++ b/setup/homeassistant-install.sh @@ -109,7 +109,7 @@ chmod 755 /usr/local/bin/fuse-overlayfs cd ~ echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json else -echo -e '{\n "storage-driver": "overlay2",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json fi sh <(curl -sSL https://get.docker.com) &>/dev/null msg_ok "Installed Docker $DOCKER_LATEST_VERSION" From ee832a3c6b91c028f5105333bf592f8e0fd85f5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Dec 2022 00:25:10 -0500 Subject: [PATCH 3886/6505] Update core-update.sh code refactoring --- misc/core-update.sh | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/misc/core-update.sh b/misc/core-update.sh index e3af18a1..b9a547ab 100644 --- a/misc/core-update.sh +++ b/misc/core-update.sh @@ -13,6 +13,7 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" +function header_info { cat <<"EOF" _ _ _ _ ___ /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___ _ __ ___ @@ -21,10 +22,12 @@ CROSS="${RD}✗${CL}" \/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| UPDATE EOF +} PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') -if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi -sleep 2 +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') +BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -33,16 +36,30 @@ function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +if (whiptail --title "CORE UPDATE" --yesno "This will update Home Assistant Core. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then + clear + header_info + echo -e "${GN}Updating to Version ${BETA}${CL}" + BR="--pre " +else + clear + header_info + echo -e "${GN}Updating to Version ${STABLE}${CL}" + BR="" +fi +if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi + msg_info "Stopping Home Assistant" systemctl stop homeassistant msg_ok "Stopped Home Assistant" -read -r -p " Use the Beta Branch? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - BR="--pre " -else - BR="" -fi msg_info "Updating Home Assistant" source /srv/homeassistant/bin/activate pip install ${BR}--upgrade homeassistant &>/dev/null @@ -56,10 +73,12 @@ else sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json fi +sleep 2 msg_ok "Set Dependency Versions" msg_info "Starting Home Assistant" systemctl start homeassistant +sleep 2 msg_ok "Started Home Assistant" msg_ok "Update Successful" echo -e "\n Go to http://${IP}:8123 \n" From ce90d7da2359f71c4cf139c4a4af8b0a1ae4a4e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 07:39:25 -0500 Subject: [PATCH 3887/6505] Update and rename vaultwarden-v4.sh to vaultwarden-v5.sh --- ct/{vaultwarden-v4.sh => vaultwarden-v5.sh} | 130 +++++++++++++++++--- 1 file changed, 111 insertions(+), 19 deletions(-) rename ct/{vaultwarden-v4.sh => vaultwarden-v5.sh} (77%) diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v5.sh similarity index 77% rename from ct/vaultwarden-v4.sh rename to ct/vaultwarden-v5.sh index 9e5ffc70..03dbef93 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v5.sh @@ -1,4 +1,14 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ __ ____ _ __ __ +| | / /___ ___v5__/ / /| | / /___ __________/ /__ ____ +| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ +| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / +|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ + +EOF +} echo -e "Loading..." APP="Vaultwarden" var_disk="6" @@ -8,7 +18,6 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -20,6 +29,7 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -35,30 +45,22 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${CL} - _ _____ __ ____ _______ _____ ____ ____ _______ __ -| | / / | / / / / / /_ __/ | / / | / __ \/ __ \/ ____/ | / / -| | / / /| |/ / / / / / / | | /| / / /| | / /_/ / / / / __/ / |/ / -| |/ / ___ / /_/ / /___/ / | |/ |/ / ___ |/ _, _/ /_/ / /___/ /| / -|___/_/ |_\____/_____/_/ v4 |__/|__/_/ |_/_/ |_/_____/_____/_/ |_/ -${CL}" -} + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } + function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then @@ -68,6 +70,28 @@ function PVE_CHECK() { exit fi } +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/vaultwarden ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP}. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -101,6 +125,7 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -253,9 +278,11 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" + VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -266,7 +293,7 @@ function advanced_settings() { advanced_settings fi } -function start_script() { +function install_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -277,8 +304,72 @@ function start_script() { advanced_settings fi } + +function update_script() { +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "VaultWarden" ON \ + "2" "Web-Vault" OFF \ + 3>&1 1>&2 2>&3) + clear -start_script +header_info +echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" +if [ "$UPD" == "1" ]; then +msg_info "Stopping Vaultwarden" +systemctl stop vaultwarden.service +msg_ok "Stopped Vaultwarden" + +msg_info "Updating VaultWarden (Patience)" +git clone https://github.com/dani-garcia/vaultwarden &>/dev/null +cd vaultwarden +cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null +DIR=/usr/bin/vaultwarden + if [ -d "$DIR" ]; then + cp target/release/vaultwarden /usr/bin/ + else + cp target/release/vaultwarden /opt/vaultwarden/bin/ + fi +msg_ok "Updated VaultWarden" + +msg_info "Cleaning up" +cd ~ && rm -rf vaultwarden +msg_ok "Cleaned" + +msg_info "Starting Vaultwarden" +systemctl start vaultwarden.service +msg_ok "Started Vaultwarden" + +msg_ok "Update Successful" +echo -e "\n ⚠️ Ensure you set resources back to normal settings \n" +exit; +fi +if [ "$UPD" == "2" ]; then +msg_info "Stopping Vaultwarden" +systemctl stop vaultwarden.service +msg_ok "Stopped Vaultwarden" + +msg_info "Updating Web-Vault" +curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null + if [ -d "/var/lib/vaultwarden" ]; then + tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null + else + tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null + fi +msg_ok "Updated Web-Vault" + +msg_info "Cleaning up" +rm bw_web_$VWRELEASE.tar.gz +msg_ok "Cleaned" + +msg_info "Starting Vaultwarden" +systemctl start vaultwarden.service +msg_ok "Started Vaultwarden" +msg_ok "Update Successful" +exit; +fi +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" @@ -288,6 +379,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export VERBOSE=$VERB +export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os From a9ea2cf3df1baa9bdf0975b6e2753f3c78b7424f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 07:43:46 -0500 Subject: [PATCH 3888/6505] Update and rename vaultwarden-v5.sh to vaultwarden-v4.sh --- ct/{vaultwarden-v5.sh => vaultwarden-v4.sh} | 130 +++----------------- 1 file changed, 19 insertions(+), 111 deletions(-) rename ct/{vaultwarden-v5.sh => vaultwarden-v4.sh} (77%) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v4.sh similarity index 77% rename from ct/vaultwarden-v5.sh rename to ct/vaultwarden-v4.sh index 03dbef93..9e5ffc70 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v4.sh @@ -1,14 +1,4 @@ #!/usr/bin/env bash -function header_info { - cat <<"EOF" - _ __ ____ _ __ __ -| | / /___ ___v5__/ / /| | / /___ __________/ /__ ____ -| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ -| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / -|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ - -EOF -} echo -e "Loading..." APP="Vaultwarden" var_disk="6" @@ -18,6 +8,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" +NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -29,7 +20,6 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -45,22 +35,30 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } - +if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { + echo -e "${CL} + _ _____ __ ____ _______ _____ ____ ____ _______ __ +| | / / | / / / / / /_ __/ | / / | / __ \/ __ \/ ____/ | / / +| | / / /| |/ / / / / / / | | /| / / /| | / /_/ / / / / __/ / |/ / +| |/ / ___ / /_/ / /___/ / | |/ |/ / ___ |/ _, _/ /_/ / /___/ /| / +|___/_/ |_\____/_____/_/ v4 |__/|__/_/ |_/_/ |_/_____/_____/_/ |_/ +${CL}" +} function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } - function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then @@ -70,28 +68,6 @@ function PVE_CHECK() { exit fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/vaultwarden ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP}. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -125,7 +101,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -278,11 +253,9 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -293,7 +266,7 @@ function advanced_settings() { advanced_settings fi } -function install_script() { +function start_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -304,72 +277,8 @@ function install_script() { advanced_settings fi } - -function update_script() { -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ - "1" "VaultWarden" ON \ - "2" "Web-Vault" OFF \ - 3>&1 1>&2 2>&3) - clear -header_info -echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" -if [ "$UPD" == "1" ]; then -msg_info "Stopping Vaultwarden" -systemctl stop vaultwarden.service -msg_ok "Stopped Vaultwarden" - -msg_info "Updating VaultWarden (Patience)" -git clone https://github.com/dani-garcia/vaultwarden &>/dev/null -cd vaultwarden -cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null -DIR=/usr/bin/vaultwarden - if [ -d "$DIR" ]; then - cp target/release/vaultwarden /usr/bin/ - else - cp target/release/vaultwarden /opt/vaultwarden/bin/ - fi -msg_ok "Updated VaultWarden" - -msg_info "Cleaning up" -cd ~ && rm -rf vaultwarden -msg_ok "Cleaned" - -msg_info "Starting Vaultwarden" -systemctl start vaultwarden.service -msg_ok "Started Vaultwarden" - -msg_ok "Update Successful" -echo -e "\n ⚠️ Ensure you set resources back to normal settings \n" -exit; -fi -if [ "$UPD" == "2" ]; then -msg_info "Stopping Vaultwarden" -systemctl stop vaultwarden.service -msg_ok "Stopped Vaultwarden" - -msg_info "Updating Web-Vault" -curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null - if [ -d "/var/lib/vaultwarden" ]; then - tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null - else - tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null - fi -msg_ok "Updated Web-Vault" - -msg_info "Cleaning up" -rm bw_web_$VWRELEASE.tar.gz -msg_ok "Cleaned" - -msg_info "Starting Vaultwarden" -systemctl start vaultwarden.service -msg_ok "Started Vaultwarden" -msg_ok "Update Successful" -exit; -fi -} -clear -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +start_script if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" @@ -379,7 +288,6 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os From 632d6f0e662fe64db4baa0e728e29843aacc2b26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 09:57:56 -0500 Subject: [PATCH 3889/6505] Rename docker-install.sh to docker-v5-install.sh --- setup/{docker-install.sh => docker-v5-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename setup/{docker-install.sh => docker-v5-install.sh} (100%) diff --git a/setup/docker-install.sh b/setup/docker-v5-install.sh similarity index 100% rename from setup/docker-install.sh rename to setup/docker-v5-install.sh From aa941a60cdc867268cc93dafc1505c81d009a966 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 09:59:24 -0500 Subject: [PATCH 3890/6505] Rename homeassistant-core-install.sh to homeassistant-core-v5-install.sh --- ...assistant-core-install.sh => homeassistant-core-v5-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename setup/{homeassistant-core-install.sh => homeassistant-core-v5-install.sh} (100%) diff --git a/setup/homeassistant-core-install.sh b/setup/homeassistant-core-v5-install.sh similarity index 100% rename from setup/homeassistant-core-install.sh rename to setup/homeassistant-core-v5-install.sh From 5ea4b1064e447a0619d50a227c5bc0e529546452 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 10:02:25 -0500 Subject: [PATCH 3891/6505] Rename homeassistant-core-v5-install.sh to homeassistant-core-install.sh --- ...assistant-core-v5-install.sh => homeassistant-core-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename setup/{homeassistant-core-v5-install.sh => homeassistant-core-install.sh} (100%) diff --git a/setup/homeassistant-core-v5-install.sh b/setup/homeassistant-core-install.sh similarity index 100% rename from setup/homeassistant-core-v5-install.sh rename to setup/homeassistant-core-install.sh From fce1839580c5974418847c936ca07ea26bba0dc9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 10:17:51 -0500 Subject: [PATCH 3892/6505] Rename docker-v5-install.sh to docker-install.sh --- setup/{docker-v5-install.sh => docker-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename setup/{docker-v5-install.sh => docker-install.sh} (100%) diff --git a/setup/docker-v5-install.sh b/setup/docker-install.sh similarity index 100% rename from setup/docker-v5-install.sh rename to setup/docker-install.sh From 049b2cf770e8d78868c302643592169bf519ee1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 10:53:32 -0500 Subject: [PATCH 3893/6505] purge (#884) --- ct/adguard-v1.sh | 162 -------- ct/adguard-v2.sh | 256 ------------ ct/adguard-v3.sh | 358 ----------------- ct/adguard-v4.sh | 2 +- ct/blocky-v4.sh | 2 +- ct/casaos-v4.sh | 2 +- ct/changedetection-v4.sh | 2 +- ct/daemonsync-v2.sh | 253 ------------ ct/daemonsync-v3.sh | 358 ----------------- ct/daemonsync-v4.sh | 2 +- ct/dashy-v2.sh | 254 ------------ ct/dashy-v3.sh | 358 ----------------- ct/dashy-v4.sh | 2 +- ct/debian-v1.sh | 165 -------- ct/debian-v2.sh | 257 ------------ ct/debian-v3.sh | 357 ----------------- ct/debian-v4.sh | 2 +- ct/deconz-v3.sh | 371 ----------------- ct/deconz-v4.sh | 2 +- ct/docker-v2.sh | 312 --------------- ct/docker-v3.sh | 361 ----------------- ct/docker-v4.sh | 2 +- ct/emby-v4.sh | 2 +- ct/emqx-v4.sh | 2 +- ct/esphome-v1.sh | 188 --------- ct/esphome-v2.sh | 259 ------------ ct/esphome-v3.sh | 357 ----------------- ct/esphome-v4.sh | 2 +- ct/grafana-v2.sh | 252 ------------ ct/grafana-v3.sh | 356 ----------------- ct/grafana-v4.sh | 2 +- ct/grocy-v3.sh | 359 ----------------- ct/grocy-v4.sh | 2 +- ct/heimdalldashboard-v2.sh | 259 ------------ ct/heimdalldashboard-v3.sh | 357 ----------------- ct/heimdalldashboard-v4.sh | 2 +- ct/homeassistant-core-v4.sh | 2 +- ct/homeassistant-v1.sh | 176 -------- ct/homeassistant-v2.sh | 316 --------------- ct/homeassistant-v3.sh | 365 ----------------- ct/homeassistant-v4.sh | 2 +- ct/homebridge-v2.sh | 251 ------------ ct/homebridge-v3.sh | 356 ----------------- ct/homebridge-v4.sh | 2 +- ct/homepage-v4.sh | 2 +- ct/hyperion-v4.sh | 2 +- ct/influxdb-v2.sh | 250 ------------ ct/influxdb-v3.sh | 355 ----------------- ct/influxdb-v4.sh | 2 +- ct/iobroker-v3.sh | 356 ----------------- ct/iobroker-v4.sh | 2 +- ct/jellyfin-v1.sh | 171 -------- ct/jellyfin-v3.sh | 370 ----------------- ct/jellyfin-v4.sh | 2 +- ct/k0s-v4.sh | 2 +- ct/keycloak-v3.sh | 360 ----------------- ct/keycloak-v4.sh | 2 +- ct/magicmirror-v3.sh | 359 ----------------- ct/magicmirror-v4.sh | 2 +- ct/mariadb-v1.sh | 168 -------- ct/mariadb-v2.sh | 252 ------------ ct/mariadb-v3.sh | 356 ----------------- ct/mariadb-v4.sh | 2 +- ct/meshcentral-v2.sh | 258 ------------ ct/meshcentral-v3.sh | 356 ----------------- ct/meshcentral-v4.sh | 2 +- ct/motioneye-v1.sh | 168 -------- ct/motioneye-v2.sh | 258 ------------ ct/motioneye-v3.sh | 356 ----------------- ct/motioneye-v4.sh | 2 +- ct/mqtt-v1.sh | 158 -------- ct/mqtt-v2.sh | 250 ------------ ct/mqtt-v3.sh | 354 ---------------- ct/mqtt-v4.sh | 2 +- ct/n8n-v3.sh | 356 ----------------- ct/n8n-v4.sh | 2 +- ct/navidrome-v4.sh | 2 +- ct/nextcloudpi-v4.sh | 2 +- ct/nginx-proxy-manager-v1.sh | 162 -------- ct/nginx-proxy-manager-v2.sh | 251 ------------ ct/nginx-proxy-manager-v3.sh | 356 ----------------- ct/nginx-proxy-manager-v4.sh | 2 +- ct/nocodb-v2.sh | 258 ------------ ct/nocodb-v3.sh | 356 ----------------- ct/nocodb-v4.sh | 2 +- ct/node-red-v1.sh | 161 -------- ct/node-red-v2.sh | 253 ------------ ct/node-red-v3.sh | 356 ----------------- ct/node-red-v4.sh | 2 +- ct/omada-v2.sh | 252 ------------ ct/omada-v3.sh | 356 ----------------- ct/omada-v4.sh | 2 +- ct/omv-v4.sh | 2 +- ct/openhab-v3.sh | 361 ----------------- ct/openhab-v4.sh | 2 +- ct/paperless-ngx-v4.sh | 2 +- ct/photoprism-v2.sh | 259 ------------ ct/photoprism-v3.sh | 357 ----------------- ct/photoprism-v4.sh | 2 +- ct/pihole-v1.sh | 162 -------- ct/pihole-v2.sh | 258 ------------ ct/pihole-v3.sh | 356 ----------------- ct/pihole-v4.sh | 2 +- ct/plex-v1.sh | 170 -------- ct/plex-v3.sh | 368 ----------------- ct/plex-v4.sh | 2 +- ct/podman-homeassistant-v1.sh | 189 --------- ct/podman-homeassistant-v3.sh | 371 ----------------- ct/podman-homeassistant-v4.sh | 2 +- ct/podman-v4.sh | 2 +- ct/postgresql-v3.sh | 361 ----------------- ct/postgresql-v4.sh | 2 +- ct/prometheus-v3.sh | 359 ----------------- ct/prometheus-v4.sh | 2 +- ct/scrypted-v4.sh | 2 +- ct/shinobi-v4.sh | 2 +- ct/syncthing-v4.sh | 2 +- ct/technitiumdns-v2.sh | 259 ------------ ct/technitiumdns-v3.sh | 356 ----------------- ct/technitiumdns-v4.sh | 2 +- ct/trilium-v4.sh | 2 +- ct/ubuntu-v1.sh | 164 -------- ct/ubuntu-v2.sh | 255 ------------ ct/ubuntu-v3.sh | 377 ------------------ ct/ubuntu-v4.sh | 2 +- ct/umbrel-v4.sh | 2 +- ct/unifi-v2.sh | 258 ------------ ct/unifi-v3.sh | 356 ----------------- ct/unifi-v4.sh | 2 +- ct/uptimekuma-v2.sh | 261 ------------ ct/uptimekuma-v3.sh | 358 ----------------- ct/uptimekuma-v4.sh | 2 +- ct/vaultwarden-v1.sh | 179 --------- ct/vaultwarden-v2.sh | 259 ------------ ct/vaultwarden-v3.sh | 361 ----------------- ct/vaultwarden-v4.sh | 2 +- ct/whoogle-v3.sh | 360 ----------------- ct/whoogle-v4.sh | 2 +- ct/wikijs-v4.sh | 2 +- ct/wireguard-v2.sh | 253 ------------ ct/wireguard-v3.sh | 357 ----------------- ct/wireguard-v4.sh | 2 +- ct/zigbee2mqtt-v1.sh | 173 -------- ct/zigbee2mqtt-v2.sh | 263 ------------ ct/zigbee2mqtt-v3.sh | 369 ----------------- ct/zigbee2mqtt-v4.sh | 2 +- ct/zwave-js-ui-v4.sh | 2 +- ct/zwavejs2mqtt-v1.sh | 191 --------- ct/zwavejs2mqtt-v2.sh | 266 ------------ ct/zwavejs2mqtt-v3.sh | 371 ----------------- {setup => install}/adguard-install.sh | 0 {setup => install}/blocky-install.sh | 0 {setup => install}/casaos-install.sh | 0 {setup => install}/changedetection-install.sh | 0 {setup => install}/daemonsync-install.sh | 0 {setup => install}/dashy-install.sh | 0 {setup => install}/debian-install.sh | 0 {setup => install}/deconz-install.sh | 0 {setup => install}/docker-install.sh | 0 {setup => install}/emby-install.sh | 0 {setup => install}/emqx-install.sh | 0 {setup => install}/esphome-install.sh | 0 {setup => install}/grafana-install.sh | 0 {setup => install}/grocy-install.sh | 0 .../heimdalldashboard-install.sh | 0 .../homeassistant-core-install.sh | 0 {setup => install}/homeassistant-install.sh | 0 {setup => install}/homebridge-install.sh | 0 {setup => install}/homepage-install.sh | 0 {setup => install}/hyperion-install.sh | 0 {setup => install}/influxdb-install.sh | 0 {setup => install}/iobroker-install.sh | 0 {setup => install}/jellyfin-install.sh | 0 {setup => install}/k0s-install.sh | 0 {setup => install}/keycloak-install.sh | 0 {setup => install}/magicmirror-install.sh | 0 {setup => install}/mariadb-install.sh | 0 {setup => install}/meshcentral-install.sh | 0 {setup => install}/motioneye-install.sh | 0 {setup => install}/mqtt-install.sh | 0 {setup => install}/n8n-install.sh | 0 {setup => install}/navidrome-install.sh | 0 {setup => install}/nextcloudpi-install.sh | 0 .../nginx-proxy-manager-install.sh | 0 {setup => install}/nocodb-install.sh | 0 {setup => install}/node-red-install.sh | 0 {setup => install}/omada-install.sh | 0 {setup => install}/omv-install.sh | 0 {setup => install}/openhab-install.sh | 0 {setup => install}/paperless-ngx-install.sh | 0 {setup => install}/photoprism-install.sh | 0 {setup => install}/pihole-install.sh | 0 {setup => install}/plex-install.sh | 0 .../podman-homeassistant-install.sh | 0 {setup => install}/podman-install.sh | 0 {setup => install}/postgresql-install.sh | 0 {setup => install}/prometheus-install.sh | 0 {setup => install}/scrypted-install.sh | 0 {setup => install}/shinobi-install.sh | 0 {setup => install}/syncthing-install.sh | 0 {setup => install}/technitiumdns-install.sh | 0 {setup => install}/trilium-install.sh | 0 {setup => install}/ubuntu-install.sh | 0 {setup => install}/umbrel-install.sh | 0 {setup => install}/unifi-install.sh | 0 {setup => install}/uptimekuma-install.sh | 0 {setup => install}/vaultwarden-install.sh | 0 {setup => install}/whoogle-install.sh | 0 {setup => install}/wikijs-install.sh | 0 {setup => install}/wireguard-install.sh | 0 {setup => install}/zigbee2mqtt-install.sh | 0 {setup => install}/zwave-js-ui-install.sh | 0 setup/adguard_setup.sh | 73 ---- setup/debian11_setup.sh | 78 ---- setup/esphome_setup.sh | 104 ----- setup/ha_setup.sh | 296 -------------- setup/jellyfin_setup.sh | 98 ----- setup/mariadb_setup.sh | 93 ----- setup/motioneye_setup.sh | 97 ----- setup/mqtt_setup.sh | 80 ---- setup/node-red_setup.sh | 74 ---- setup/npm_setup.sh | 216 ---------- setup/pihole_setup.sh | 73 ---- setup/plex_setup.sh | 86 ---- setup/podman_ha_setup.sh | 157 -------- setup/ubuntu_setup.sh | 77 ---- setup/vault_setup.sh | 157 -------- setup/zigbee2mqtt_setup.sh | 97 ----- setup/zwavejs2mqtt_setup.sh | 104 ----- 229 files changed, 62 insertions(+), 27584 deletions(-) delete mode 100644 ct/adguard-v1.sh delete mode 100644 ct/adguard-v2.sh delete mode 100644 ct/adguard-v3.sh delete mode 100644 ct/daemonsync-v2.sh delete mode 100644 ct/daemonsync-v3.sh delete mode 100644 ct/dashy-v2.sh delete mode 100644 ct/dashy-v3.sh delete mode 100644 ct/debian-v1.sh delete mode 100644 ct/debian-v2.sh delete mode 100644 ct/debian-v3.sh delete mode 100644 ct/deconz-v3.sh delete mode 100644 ct/docker-v2.sh delete mode 100644 ct/docker-v3.sh delete mode 100644 ct/esphome-v1.sh delete mode 100644 ct/esphome-v2.sh delete mode 100644 ct/esphome-v3.sh delete mode 100644 ct/grafana-v2.sh delete mode 100644 ct/grafana-v3.sh delete mode 100644 ct/grocy-v3.sh delete mode 100644 ct/heimdalldashboard-v2.sh delete mode 100644 ct/heimdalldashboard-v3.sh delete mode 100644 ct/homeassistant-v1.sh delete mode 100644 ct/homeassistant-v2.sh delete mode 100644 ct/homeassistant-v3.sh delete mode 100644 ct/homebridge-v2.sh delete mode 100644 ct/homebridge-v3.sh delete mode 100644 ct/influxdb-v2.sh delete mode 100644 ct/influxdb-v3.sh delete mode 100644 ct/iobroker-v3.sh delete mode 100644 ct/jellyfin-v1.sh delete mode 100644 ct/jellyfin-v3.sh delete mode 100644 ct/keycloak-v3.sh delete mode 100644 ct/magicmirror-v3.sh delete mode 100644 ct/mariadb-v1.sh delete mode 100644 ct/mariadb-v2.sh delete mode 100644 ct/mariadb-v3.sh delete mode 100644 ct/meshcentral-v2.sh delete mode 100644 ct/meshcentral-v3.sh delete mode 100644 ct/motioneye-v1.sh delete mode 100644 ct/motioneye-v2.sh delete mode 100644 ct/motioneye-v3.sh delete mode 100644 ct/mqtt-v1.sh delete mode 100644 ct/mqtt-v2.sh delete mode 100644 ct/mqtt-v3.sh delete mode 100644 ct/n8n-v3.sh delete mode 100644 ct/nginx-proxy-manager-v1.sh delete mode 100644 ct/nginx-proxy-manager-v2.sh delete mode 100644 ct/nginx-proxy-manager-v3.sh delete mode 100644 ct/nocodb-v2.sh delete mode 100644 ct/nocodb-v3.sh delete mode 100644 ct/node-red-v1.sh delete mode 100644 ct/node-red-v2.sh delete mode 100644 ct/node-red-v3.sh delete mode 100644 ct/omada-v2.sh delete mode 100644 ct/omada-v3.sh delete mode 100644 ct/openhab-v3.sh delete mode 100644 ct/photoprism-v2.sh delete mode 100644 ct/photoprism-v3.sh delete mode 100644 ct/pihole-v1.sh delete mode 100644 ct/pihole-v2.sh delete mode 100644 ct/pihole-v3.sh delete mode 100644 ct/plex-v1.sh delete mode 100644 ct/plex-v3.sh delete mode 100644 ct/podman-homeassistant-v1.sh delete mode 100644 ct/podman-homeassistant-v3.sh delete mode 100644 ct/postgresql-v3.sh delete mode 100644 ct/prometheus-v3.sh delete mode 100644 ct/technitiumdns-v2.sh delete mode 100644 ct/technitiumdns-v3.sh delete mode 100644 ct/ubuntu-v1.sh delete mode 100644 ct/ubuntu-v2.sh delete mode 100644 ct/ubuntu-v3.sh delete mode 100644 ct/unifi-v2.sh delete mode 100644 ct/unifi-v3.sh delete mode 100644 ct/uptimekuma-v2.sh delete mode 100644 ct/uptimekuma-v3.sh delete mode 100644 ct/vaultwarden-v1.sh delete mode 100644 ct/vaultwarden-v2.sh delete mode 100644 ct/vaultwarden-v3.sh delete mode 100644 ct/whoogle-v3.sh delete mode 100644 ct/wireguard-v2.sh delete mode 100644 ct/wireguard-v3.sh delete mode 100644 ct/zigbee2mqtt-v1.sh delete mode 100644 ct/zigbee2mqtt-v2.sh delete mode 100644 ct/zigbee2mqtt-v3.sh delete mode 100644 ct/zwavejs2mqtt-v1.sh delete mode 100644 ct/zwavejs2mqtt-v2.sh delete mode 100644 ct/zwavejs2mqtt-v3.sh rename {setup => install}/adguard-install.sh (100%) rename {setup => install}/blocky-install.sh (100%) rename {setup => install}/casaos-install.sh (100%) rename {setup => install}/changedetection-install.sh (100%) rename {setup => install}/daemonsync-install.sh (100%) rename {setup => install}/dashy-install.sh (100%) rename {setup => install}/debian-install.sh (100%) rename {setup => install}/deconz-install.sh (100%) rename {setup => install}/docker-install.sh (100%) rename {setup => install}/emby-install.sh (100%) rename {setup => install}/emqx-install.sh (100%) rename {setup => install}/esphome-install.sh (100%) rename {setup => install}/grafana-install.sh (100%) rename {setup => install}/grocy-install.sh (100%) rename {setup => install}/heimdalldashboard-install.sh (100%) rename {setup => install}/homeassistant-core-install.sh (100%) rename {setup => install}/homeassistant-install.sh (100%) rename {setup => install}/homebridge-install.sh (100%) rename {setup => install}/homepage-install.sh (100%) rename {setup => install}/hyperion-install.sh (100%) rename {setup => install}/influxdb-install.sh (100%) rename {setup => install}/iobroker-install.sh (100%) rename {setup => install}/jellyfin-install.sh (100%) rename {setup => install}/k0s-install.sh (100%) rename {setup => install}/keycloak-install.sh (100%) rename {setup => install}/magicmirror-install.sh (100%) rename {setup => install}/mariadb-install.sh (100%) rename {setup => install}/meshcentral-install.sh (100%) rename {setup => install}/motioneye-install.sh (100%) rename {setup => install}/mqtt-install.sh (100%) rename {setup => install}/n8n-install.sh (100%) rename {setup => install}/navidrome-install.sh (100%) rename {setup => install}/nextcloudpi-install.sh (100%) rename {setup => install}/nginx-proxy-manager-install.sh (100%) rename {setup => install}/nocodb-install.sh (100%) rename {setup => install}/node-red-install.sh (100%) rename {setup => install}/omada-install.sh (100%) rename {setup => install}/omv-install.sh (100%) rename {setup => install}/openhab-install.sh (100%) rename {setup => install}/paperless-ngx-install.sh (100%) rename {setup => install}/photoprism-install.sh (100%) rename {setup => install}/pihole-install.sh (100%) rename {setup => install}/plex-install.sh (100%) rename {setup => install}/podman-homeassistant-install.sh (100%) rename {setup => install}/podman-install.sh (100%) rename {setup => install}/postgresql-install.sh (100%) rename {setup => install}/prometheus-install.sh (100%) rename {setup => install}/scrypted-install.sh (100%) rename {setup => install}/shinobi-install.sh (100%) rename {setup => install}/syncthing-install.sh (100%) rename {setup => install}/technitiumdns-install.sh (100%) rename {setup => install}/trilium-install.sh (100%) rename {setup => install}/ubuntu-install.sh (100%) rename {setup => install}/umbrel-install.sh (100%) rename {setup => install}/unifi-install.sh (100%) rename {setup => install}/uptimekuma-install.sh (100%) rename {setup => install}/vaultwarden-install.sh (100%) rename {setup => install}/whoogle-install.sh (100%) rename {setup => install}/wikijs-install.sh (100%) rename {setup => install}/wireguard-install.sh (100%) rename {setup => install}/zigbee2mqtt-install.sh (100%) rename {setup => install}/zwave-js-ui-install.sh (100%) delete mode 100644 setup/adguard_setup.sh delete mode 100644 setup/debian11_setup.sh delete mode 100644 setup/esphome_setup.sh delete mode 100644 setup/ha_setup.sh delete mode 100644 setup/jellyfin_setup.sh delete mode 100644 setup/mariadb_setup.sh delete mode 100644 setup/motioneye_setup.sh delete mode 100644 setup/mqtt_setup.sh delete mode 100644 setup/node-red_setup.sh delete mode 100644 setup/npm_setup.sh delete mode 100644 setup/pihole_setup.sh delete mode 100644 setup/plex_setup.sh delete mode 100644 setup/podman_ha_setup.sh delete mode 100644 setup/ubuntu_setup.sh delete mode 100644 setup/vault_setup.sh delete mode 100644 setup/zigbee2mqtt_setup.sh delete mode 100644 setup/zwavejs2mqtt_setup.sh diff --git a/ct/adguard-v1.sh b/ct/adguard-v1.sh deleted file mode 100644 index daada894..00000000 --- a/ct/adguard-v1.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New AdGuard Home LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "LXC ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=adguard -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" -pct start $CTID -pct push $CTID adguard_setup.sh /adguard_setup.sh -perms 755 -pct exec $CTID /adguard_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a AdGuard Home LXC to $CTID" -echo -e "\e[1;92m AdGuard Home Setup should be reachable by going to the following URL. - http://${IP}:3000 -\e[0m" diff --git a/ct/adguard-v2.sh b/ct/adguard-v2.sh deleted file mode 100644 index 9838585b..00000000 --- a/ct/adguard-v2.sh +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env bash - -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Adguard Home LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${GN} - _ _ - /\ | | | | - / \ __| | __ _ _ _ __ _ _ __ __| | - / /\ \ / _ |/ _ | | | |/ _ | __/ _ | - / ____ \ (_| | (_| | |_| | (_| | | | (_| | - /_/ \_\__,_|\__, |\__,_|\__,_|_| \__,_| - __/ | - |___/ - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname adguard - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Adguard Home LXC to${CL} ${BL}$CTID${CL}. -${GN}Adguard${CL} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" - diff --git a/ct/adguard-v3.sh b/ct/adguard-v3.sh deleted file mode 100644 index 26955d34..00000000 --- a/ct/adguard-v3.sh +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Adguard" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${GN} - _ _ - /\ | | | | - / \ __| | __ _ _ _ __ _ _ __ __| | - / /\ \ / _ |/ _ | | | |/ _ | __/ _ | - / ____ \ (_| | (_| | |_| | (_| | | | (_| | - /_/ \_\__,_|\__, |\__,_|\__,_|_| \__,_| - v3__/ | - |___/ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/adguard-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# AdGuard Home LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "Adguard Setup should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index a21350c5..1b65ff63 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index 07f58776..122669b1 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index c3d54ea9..b6c9364a 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -325,7 +325,7 @@ EOF msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/changedetection-v4.sh b/ct/changedetection-v4.sh index 0580a2cc..db179033 100644 --- a/ct/changedetection-v4.sh +++ b/ct/changedetection-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/daemonsync-v2.sh b/ct/daemonsync-v2.sh deleted file mode 100644 index 5b47dfa6..00000000 --- a/ct/daemonsync-v2.sh +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Daemon Sync Server LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _____ _____ - | __ \ / ____| - | | | | __ _ ___ _ __ ___ ___ _ __ | (___ _ _ _ __ ___ - | | | |/ _ |/ _ \ _ _ \ / _ \| _ \ \___ \| | | | _ \ / __| - | |__| | (_| | __/ | | | | | (_) | | | | ____) | |_| | | | | (__ - |_____/ \__,_|\___|_| |_| |_|\___/|_| |_| |_____/ \__, |_| |_|\___| - __/ | - |___/ -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname daemonsync - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/daemonsync-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Daemon Sync Server LXC to${CL} ${BL}$CTID${CL}. - Daemon Sync should be reachable by going to the following URL. - ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/daemonsync-v3.sh b/ct/daemonsync-v3.sh deleted file mode 100644 index df44541e..00000000 --- a/ct/daemonsync-v3.sh +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Daemon Sync" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _____ _____ - | __ \ / ____| - | | | | __ _v3___ _ __ ___ ___ _ __ | (___ _ _ _ __ ___ - | | | |/ _ |/ _ \ _ _ \ / _ \| _ \ \___ \| | | | _ \ / __| - | |__| | (_| | __/ | | | | | (_) | | | | ____) | |_| | | | | (__ - |_____/ \__,_|\___|_| |_| |_|\___/|_| |_| |_____/ \__, |_| |_|\___| - __/ | - |___/ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/daemonsync-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index c9c19e9b..33bc978f 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/dashy-v2.sh b/ct/dashy-v2.sh deleted file mode 100644 index 49e63390..00000000 --- a/ct/dashy-v2.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env bash -clear -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Dashy LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _____ _ - | __ \ | | - | | | | __ _ ___| |__ _ _ - | | | |/ _ / __| _ \| | | | - | |__| | (_| \__ \ | | | |_| | - |_____/ \__,_|___/_| |_|\__, | - __/ | - |___/ -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=3 -export PCT_OPTIONS=" - -features $FEATURES - -hostname dashy - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/dashy-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Dashy LXC to${CL} ${BL}$CTID${CL}. -${BL}Dashy${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/dashy-v3.sh b/ct/dashy-v3.sh deleted file mode 100644 index b7e795d2..00000000 --- a/ct/dashy-v3.sh +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Dashy" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _____ _ - | __ \ | | - | | | | __ _ ___| |__ _ _ - | | | |/ _ / __| _ \| | | | - | |__| | (_| \__ \ | | | |_| | - |_____/ \__,_|___/_| |_|\__, | - v3__/ | - |___/ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}3${CL}${DGN}GB${CL}" - DISK_SIZE="3" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/dashy-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 5aac4c22..4f777b81 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/debian-v1.sh b/ct/debian-v1.sh deleted file mode 100644 index c002b0c6..00000000 --- a/ct/debian-v1.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Debian 11 LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/debian11_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=debian11 -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID debian11_setup.sh /debian11_setup.sh -perms 755 -pct exec $CTID /debian11_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Debian 11 LXC Container to $CTID at IP Address ${IP}" diff --git a/ct/debian-v2.sh b/ct/debian-v2.sh deleted file mode 100644 index 36ed693b..00000000 --- a/ct/debian-v2.sh +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[32m"` -CL=`echo "\033[m"` -APP="Debian" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _____ _ _ - | __ \ | | (_) - | | | | ___| |__ _ __ _ _ __ - | | | |/ _ \ _ \| |/ _ | _ \ - | |__| | __/ |_) | | (_| | | | | - |_____/ \___|_.__/|_|\__,_|_| |_| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. \n" diff --git a/ct/debian-v3.sh b/ct/debian-v3.sh deleted file mode 100644 index 79c9bdd1..00000000 --- a/ct/debian-v3.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Debian" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _____ _ _ - | __ \ | | (_) - | | | | ___| |__ _ __ _ _ __ - | | | |/ _ \ _ \| |/ _ | _ \ - | |__| | __/ |_) | | (_| | | | | - |_${YW}v3${RD}__/ \___|_.__/|_|\__,_|_| |_| -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index c70d40dc..25501b0e 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/deconz-v3.sh b/ct/deconz-v3.sh deleted file mode 100644 index 3679fb6c..00000000 --- a/ct/deconz-v3.sh +++ /dev/null @@ -1,371 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="deCONZ" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="ubuntu" -var_version="20.04" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _____ - | | / ____| - __| | v3_| | ___ _ __ ____ - / _ |/ _ \ | / _ \| _ \|_ / - | (_| | __/ |___| (_) | | | |/ / - \__,_|\___|\_____\___/|_| |_/___| -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 9faf169b..0a373336 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -324,7 +324,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/docker-v2.sh b/ct/docker-v2.sh deleted file mode 100644 index 43ceb81b..00000000 --- a/ct/docker-v2.sh +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Docker LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _____ _ - | __ \ | | - | | | | ___ ___| | _____ _ __ - | | | |/ _ \ / __| |/ / _ \ __| - | |__| | (_) | (__| < __/ | - |_____/ \___/ \___|_|\_\___|_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${RD} If Using ZFS, You Have Storage Driver Options${CL}\n" - printf " ${RD} Non ZFS, Select Standard overlay2 Storage Driver${CL}\n" - printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" - printf " ${YW} 2)${GN} Use Standard overlay2 Storage Driver${CL}\n" - - printf "Please choose a Storage Driver and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using fuse-overlayfs Storage Driver"; - STORAGE_DRIVER="fuse" - break; - ;; - 2) clear; - header_info; - option_picked "Using overlay2 Storage Driver"; - STORAGE_DRIVER=" " - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Storage Driver from the menu"; - show_menu3; - ;; - esac - done -show_menu4(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message4=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" - printf " ${YW}${message4}${CL}\n" -} -show_menu4 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu4; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == " " ]; then - FEATURES="nesting=1,keyctl=1" - elif - [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then - FEATURES="nesting=1,keyctl=1,fuse=1" - elif - [ "$IM" == "0" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then - FEATURES="nesting=1,fuse=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname docker - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - - if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then - pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 - info "Using ${BL}fuse-overlayfs${CL} Storage Driver." - else - info "Using ${BL}overlay2${CL} Storage Driver." - fi - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/docker-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Docker LXC to${CL} ${BL}$CTID${CL}. \n" diff --git a/ct/docker-v3.sh b/ct/docker-v3.sh deleted file mode 100644 index 3c2c71a4..00000000 --- a/ct/docker-v3.sh +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Docker" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _____ _ - | __ \ | | - | | | | ___ ___| | _____ _ __ - | |v3| |/ _ \ / __| |/ / _ \ __| - | |__| | (_) | (__| < __/ | - |_____/ \___/ \___|_|\_\___|_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -PVE_CHECK -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/docker-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index 326fb3f9..fcaf2469 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -336,7 +336,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 6ad8344e..c1461b71 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -331,7 +331,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index ee621375..21499816 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/esphome-v1.sh b/ct/esphome-v1.sh deleted file mode 100644 index 902c9969..00000000 --- a/ct/esphome-v1.sh +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env bash - -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` - -while true; do - read -p "This will create a New ESPHome LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${CL} - ______ _____ _____ _ _ ____ __ __ ______ - | ____|/ ____| __ \| | | |/ __ \| \/ | ____| - | |__ | (___ | |__) | |__| | | | | \ / | |__ - | __| \___ \| ___/| __ | | | | |\/| | __| - | |____ ____) | | | | | | |__| | | | | |____ - |______|_____/|_| |_| |_|\____/|_| |_|______| - -${CL}" -} - -header_info - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/esphome_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using ${BL}$STORAGE${CL} for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is ${BL}$CTID.${CL}" - -echo -en "${GN} Updating LXC Template List... " -pveam update >/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Downloading LXC Template... " -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -echo -e "${CM}${CL} \r" - -echo -en "${GN} Creating LXC Container... " -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=esphome -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -pct push $CTID esphome_setup.sh /esphome_setup.sh -perms 755 -echo -e "${CM}${CL} \r" -pct exec $CTID /esphome_setup.sh - - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created ESPHome LXC Container to ${BL}$CTID${CL}" -echo -e "${CL} ESPHome should be reachable by going to the following URL. - ${BL}http://${IP}:6052${CL} -\n" diff --git a/ct/esphome-v2.sh b/ct/esphome-v2.sh deleted file mode 100644 index 8fcbf29b..00000000 --- a/ct/esphome-v2.sh +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="ESPHome" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - ______ _____ _____ _ _ ____ __ __ ______ - | ____|/ ____| __ \| | | |/ __ \| \/ | ____| - | |__ | (___ | |__) | |__| | | | | \ / | |__ - | __| \___ \| ___/| __ | | | | |\/| | __| - | |____ ____) | | | | | | |__| | | | | |____ - |______|_____/|_| |_| |_|\____/|_| |_|______| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/esphome-v3.sh b/ct/esphome-v3.sh deleted file mode 100644 index b39f4f07..00000000 --- a/ct/esphome-v3.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="ESPHome" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - ______ _____ _____ _ _ ____ __ __ ______ - | ____|/ ____| __ \| | | |/ __ \| \/ | ____| - | |__ | (___ | |__) | |__| | | | | \ / | |__ - | __| \___ \| ___/| __ | | | | |\/| | __| - | |____ ____) | | | | | | |__| | | | | |____ - |______|_____/|_| v3 |_| |_|\____/|_| |_|______| - -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/esphome-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index d7e7350d..ff206eec 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/grafana-v2.sh b/ct/grafana-v2.sh deleted file mode 100644 index 04d65207..00000000 --- a/ct/grafana-v2.sh +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Grafana LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _____ __ - / ____| / _| - | | __ _ __ __ _| |_ __ _ _ __ __ _ - | | |_ | __/ _ | _/ _ | _ \ / _ | - | |__| | | | (_| | || (_| | | | | (_| | - \_____|_| \__,_|_| \__,_|_| |_|\__,_| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname grafana - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/grafana-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Grafana LXC to${CL} ${BL}$CTID${CL}. -${BL}Grafana${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grafana-v3.sh b/ct/grafana-v3.sh deleted file mode 100644 index cf708a67..00000000 --- a/ct/grafana-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Grafana" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _____ __ - / ____| / _| - | | __ _ __ __ _| |_ __ _ _ __ __ _ - | | |_ | __/ _ | _/ _ | _ \ / _ | - | |__| | | | (_| | || (_| | | | | (_| | - \_____|_|v3\__,_|_| \__,_|_| |_|\__,_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/grafana-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index 68a8488d..f72fd3cf 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/grocy-v3.sh b/ct/grocy-v3.sh deleted file mode 100644 index 38f6b555..00000000 --- a/ct/grocy-v3.sh +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="grocy" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - __ _ _ __ ___ ___ _ _ - / _ | __/ _ \ / __| | | | - | (_| | | | (_) | (__| |_| | - \__, |_| \___/ \___|\__, | - __/ | v3 __/ | - |___/ |___/ -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 7b4fae30..3c0f7e0e 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/heimdalldashboard-v2.sh b/ct/heimdalldashboard-v2.sh deleted file mode 100644 index 1a60e74c..00000000 --- a/ct/heimdalldashboard-v2.sh +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env bash -PP=`echo "\e[1;35m"` -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="Heimdall Dashboard" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _ _ _ _ _ _ _____ _ _ _ - | | | | (_) | | | | | | __ \ | | | | | | - | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | - | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | - | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | - |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and press [ENTER] or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and press [ENTER] or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and press [ENTER] or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press [ENTER]." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/heimdalldashboard-v3.sh b/ct/heimdalldashboard-v3.sh deleted file mode 100644 index 1a1eb641..00000000 --- a/ct/heimdalldashboard-v3.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -PP=`echo "\e[1;35m"` -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Heimdall Dashboard" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _ _ _ _ _ _ _____ _ _ _ - | | | | (_) | | | | | | __ \ | | | | | | - | |__| | ___ _ _ __ ___ __| | __v3| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | - | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | - | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | - |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/heimdalldashboard-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 410d50fa..6c4b3492 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index df5f2408..684577a7 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -324,7 +324,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/homeassistant-v1.sh b/ct/homeassistant-v1.sh deleted file mode 100644 index 40c7652e..00000000 --- a/ct/homeassistant-v1.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ha_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi - ARCH=$(dpkg --print-architecture) -HOSTNAME=homeassistant -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -if [ "$STORAGE_TYPE" == "zfspool" ]; then - CT_FEATURES="fuse=1,keyctl=1,mknod=1,nesting=1" -else - CT_FEATURES="nesting=1" -fi -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features $CT_FEATURES \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -if [ "$STORAGE_TYPE" == "zfspool" ]; then -pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 -info "Using fuse-overlayfs." -fi -pct push $CTID ha_setup.sh /ha_setup.sh -perms 755 -pct exec $CTID /ha_setup.sh -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Home Assistant Container LXC to $CTID." -msg " - -Home Assistant should be reachable by going to the following URL. - - http://${IP}:8123 -" diff --git a/ct/homeassistant-v2.sh b/ct/homeassistant-v2.sh deleted file mode 100644 index 938b6921..00000000 --- a/ct/homeassistant-v2.sh +++ /dev/null @@ -1,316 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[94m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _ _ _ _ - | | (_) | | | | - | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ - | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${RD} If Using ZFS, You Have Storage Driver Options${CL}\n" - printf " ${RD} Non ZFS, Select Standard overlay2 Storage Driver${CL}\n" - printf " ${YW} 1)${GN} Use fuse-overlayfs Storage Driver${CL}\n" - printf " ${YW} 2)${GN} Use Standard overlay2 Storage Driver${CL}\n" - - printf "Please choose a Storage Driver and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using fuse-overlayfs Storage Driver"; - STORAGE_DRIVER="fuse" - break; - ;; - 2) clear; - header_info; - option_picked "Using overlay2 Storage Driver"; - STORAGE_DRIVER=" " - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Storage Driver from the menu"; - show_menu3; - ;; - esac - done -show_menu4(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message4=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" - printf " ${YW}${message4}${CL}\n" -} -show_menu4 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu4; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == " " ]; then - FEATURES="nesting=1,keyctl=1" - elif - [ "$IM" == "1" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then - FEATURES="nesting=1,keyctl=1,fuse=1" - elif - [ "$IM" == "0" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then - FEATURES="nesting=1,fuse=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=16 -export PCT_OPTIONS=" - -features $FEATURES - -hostname homeassistant - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - wget -qL -O fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/v1.8.2/fuse-overlayfs-x86_64 - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - - if [ "$STORAGE_TYPE" == "zfspool" ] && [ "$STORAGE_DRIVER" == "fuse" ]; then - pct push $CTID fuse-overlayfs /usr/local/bin/fuse-overlayfs -perms 755 - info "Using ${BL}fuse-overlayfs${CL} Storage Driver." - else - info "Using ${BL}overlay2${CL} Storage Driver." - fi - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Home Assistant Container LXC to${CL} ${BL}$CTID${CL}. -${BL}Home Assistant${CL} should be reachable by going to the following URL. - - ${BL}http://${IP}:8123${CL} \n" diff --git a/ct/homeassistant-v3.sh b/ct/homeassistant-v3.sh deleted file mode 100644 index ad4dc553..00000000 --- a/ct/homeassistant-v3.sh +++ /dev/null @@ -1,365 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Home Assistant" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _ _ _ _ - | | ${YW}v3${CL}${BL} (_) | | | | - | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ - | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}16${CL}${DGN}GB${CL}" - DISK_SIZE="16" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="16"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -PVE_CHECK -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homeassistant-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} -Portainer should be reachable by going to the following URL. - ${BL}http://${IP}:9000${CL}\n" diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index dece5d89..23577ce7 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -336,7 +336,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/homebridge-v2.sh b/ct/homebridge-v2.sh deleted file mode 100644 index 3e045697..00000000 --- a/ct/homebridge-v2.sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Homebridge LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _ ____ __ __ ______ ____ _____ _____ _____ _____ ______ - | | | |/ __ \| \/ | ____| _ \| __ \|_ _| __ \ / ____| ____| - | |__| | | | | \ / | |__ | |_) | |__) | | | | | | | | __| |__ - | __ | | | | |\/| | __| | _ <| _ / | | | | | | | |_ | __| - | | | | |__| | | | | |____| |_) | | \ \ _| |_| |__| | |__| | |____ - |_| |_|\____/|_| |_|______|____/|_| \_\_____|_____/ \_____|______| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname homebridge - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homebridge-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Homebridge LXC to${CL} ${BL}$CTID${CL}. -${BL}Homebridge${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/homebridge-v3.sh b/ct/homebridge-v3.sh deleted file mode 100644 index 629a9a19..00000000 --- a/ct/homebridge-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Homebridge" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _ ____ __ __ ______ ____ _____ _____ _____ _____ ______ - | | | |/ __ \| \/ | ____| _ \| __ \|_ _| __ \ / ____| ____| - | |__| | | | | \ / | |__ | |_) | |__) | | | | | | | | __| |__ - | __ | | | | |\/| | __| | _ <| _ / | | | | | | | |_ | __| - | | | | |__| | | | | |____| |_) | | \ \ _| |_| |__| | |__| | |____ - |_|v3|_|\____/|_| |_|______|____/|_| \_\_____|_____/ \_____|______| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/homebridge-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "Homebridge should be reachable by going to the following URL. - ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index c1305e20..ff5edd74 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index 95df4b44..a7713489 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/hyperion-v4.sh b/ct/hyperion-v4.sh index a4746631..80f618eb 100644 --- a/ct/hyperion-v4.sh +++ b/ct/hyperion-v4.sh @@ -325,7 +325,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/influxdb-v2.sh b/ct/influxdb-v2.sh deleted file mode 100644 index 0d9e113c..00000000 --- a/ct/influxdb-v2.sh +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New InfluxDB LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _____ __ _ _____ ____ - |_ _| / _| | | __ \| _ \ - | | _ __ | |_| |_ ___ _| | | | |_) | - | | | _ \| _| | | | \ \/ / | | | _ < - _| |_| | | | | | | |_| |> <| |__| | |_) | - |_____|_| |_|_| |_|\__,_/_/\_\_____/|____/ - with Telegraf -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname influxdb - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/influxdb-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created InfluxDB LXC to${CL} ${BL}$CTID${CL}. \n" diff --git a/ct/influxdb-v3.sh b/ct/influxdb-v3.sh deleted file mode 100644 index d4288d8b..00000000 --- a/ct/influxdb-v3.sh +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="InfluxDB" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _____ __ _ _____ ____ - |_ _| / _| | | __ \| _ \ - | | _ __ | |_| |_ v3___ _| | | | |_) | - | | | _ \| _| | | | \ \/ / | | | _ < - _| |_| | | | | | | |_| |> <| |__| | |_) | - |_____|_| |_|_| |_|\__,_/_/\_\_____/|____/ - with Telegraf -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/influxdb-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 9ba3a22b..81b5457e 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/iobroker-v3.sh b/ct/iobroker-v3.sh deleted file mode 100644 index f6a52106..00000000 --- a/ct/iobroker-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="ioBroker" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _ ____ _ - (_) | _ \ | | - _ ___ | |_) |_ __ ___ | | _____ _ __ - | |/ _ \| _ <| __/ _ \| |/ / _ \ __| - | | (_) | |_) | | | (_) | < __/ | - |_|\___/|____/|_|v3\___/|_|\_\___|_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/iobroker-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8081${CL} \n" diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 7e91f90f..17f878fe 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/jellyfin-v1.sh b/ct/jellyfin-v1.sh deleted file mode 100644 index 3b8e674a..00000000 --- a/ct/jellyfin-v1.sh +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a Jellyfin Media Server LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for Storage Location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-20.04 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=jellyfin -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID jellyfin_setup.sh /jellyfin_setup.sh -perms 755 -pct exec $CTID /jellyfin_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Jellyfin Media Server LXC to $CTID." -echo -e "\e[1;92m Jellyfin Media Server should be reachable by going to the following URL. - http://${IP}:8096 -\e[0m" diff --git a/ct/jellyfin-v3.sh b/ct/jellyfin-v3.sh deleted file mode 100644 index 59b4cae9..00000000 --- a/ct/jellyfin-v3.sh +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -APP="Jellyfin" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${DGN} - _ _ _ __ _ - | | | | | / _(_) - | | ___| | |_v3 _| |_ _ _ __ - _ | |/ _ \ | | | | | _| | _ \ - | |__| | __/ | | |_| | | | | | | | - \____/ \___|_|_|\__, |_| |_|_| |_| - __/ | - |___/ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -PVE_CHECK -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=20.04 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/jellyfin-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "Jellyfin Media Server should be reachable by going to the following URL. - ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 44a18a47..37905cd7 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -331,7 +331,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/k0s-v4.sh b/ct/k0s-v4.sh index 1622434e..7e8ac4ba 100644 --- a/ct/k0s-v4.sh +++ b/ct/k0s-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/keycloak-v3.sh b/ct/keycloak-v3.sh deleted file mode 100644 index f11080d3..00000000 --- a/ct/keycloak-v3.sh +++ /dev/null @@ -1,360 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Keycloak" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - - _ __________ _______ _ ____ _ __ - | |/ / ____\ \ / / ____| | / __ \ /\ | |/ / - | ' /| |__ \ \_/ / | | | | | | | / \ | ' / - | < | __| \ /| | v3 | | | | | |/ /\ \ | < - | . \| |____ | | | |____| |___| |__| / ____ \| . \ - |_|\_\______| |_| \_____|______\____/_/ \_\_|\_\ -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index f145d045..4702c46e 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/magicmirror-v3.sh b/ct/magicmirror-v3.sh deleted file mode 100644 index fc2fa201..00000000 --- a/ct/magicmirror-v3.sh +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="MagicMirror" -var_disk="3" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ _____ _____ _____ __ __ _____ _____ _____ ____ _____ - | \/ | /\ / ____|_ _/ ____| \/ |_ _| __ \| __ \ / __ \| __ \ - | \ / | / \ | | __ | || | | \ / | | | | |__) | |__) | | | | |__) | - | |\/| | / /\ \| | |_ | | || | v3 | |\/| | | | | _ /| _ /| | | | _ / - | | | |/ ____ \ |__| |_| || |____| | | |_| |_| | \ \| | \ \| |__| | | \ \ - |_| |_/_/ \_\_____|_____\_____|_| |_|_____|_| \_\_| \_\ ____/|_| \_\ -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 28290847..ff4c7365 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/mariadb-v1.sh b/ct/mariadb-v1.sh deleted file mode 100644 index c3f09991..00000000 --- a/ct/mariadb-v1.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Mariadb LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using ${BL}${STORAGE}${CL} for Storage Location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is ${BL}${CTID}${CL}." - -echo -en "${GN} Updating LXC Template List... " -pveam update >/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Downloading LXC Template... " -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -echo -e "${CM}${CL} \r" - -echo -en "${GN} Creating LXC Container... " -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=mariadb -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -pct push $CTID mariadb_setup.sh /mariadb_setup.sh -perms 755 -echo -e "${CM}${CL} \r" -pct exec $CTID /mariadb_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "${GN} Successfully created a MariaDB LXC Container to ${BL}${CTID}${CL}" -echo -e "${CL} Adminer should be reachable by going to the following URL. - ${BL} http://${IP}/adminer/ ${CL}" diff --git a/ct/mariadb-v2.sh b/ct/mariadb-v2.sh deleted file mode 100644 index 233296d4..00000000 --- a/ct/mariadb-v2.sh +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Mariadb LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ _ _ _ - | \/ | (_) | | | - | \ / | __ _ _ __ _ __ _ __| | |__ - | |\/| |/ _ | __| |/ _ |/ _ | _ \ - | | | | (_| | | | | (_| | (_| | |_) | - |_| |_|\__,_|_| |_|\__,_|\__,_|_.__/ - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname mariadb - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Mariadb LXC to${CL} ${BL}$CTID${CL}. -${BL}Adminer${CL} should be reachable by going to the following URL. - ${BL}http://${IP}/adminer/${CL} \n" diff --git a/ct/mariadb-v3.sh b/ct/mariadb-v3.sh deleted file mode 100644 index 74c52575..00000000 --- a/ct/mariadb-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="MariaDB" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ _ _ _ - | \/ | (_) | | | - | \ / | __ _ _ __ _ __ _ __| | |__ - | |\/| |/ _ | __| |/ _ |/ _ | _ \ - | | | | (_| | | | | (_| | (_| | |_) | - |_| |_|\__,_|_|v3|_|\__,_|\__,_|_.__/ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mariadb-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "Adminer should be reachable by going to the following URL. - ${BL}http://${IP}/adminer/${CL} \n" diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index 780ba45c..20a1ff7a 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/meshcentral-v2.sh b/ct/meshcentral-v2.sh deleted file mode 100644 index f8df0b17..00000000 --- a/ct/meshcentral-v2.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="MeshCentral" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ _ _____ _ _ - | \/ | | | / ____| | | | | - | \ / | ___ ___| |__ | | ___ _ __ | |_ _ __ __ _| | - | |\/| |/ _ \/ __| _ \| | / _ \ _ \| __| __/ _ | | - | | | | __/\__ \ | | | |___| __/ | | | |_| | | (_| | | - |_| |_|\___||___/_| |_|\_____\___|_| |_|\__|_| \__,_|_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/meshcentral-v3.sh b/ct/meshcentral-v3.sh deleted file mode 100644 index ff411439..00000000 --- a/ct/meshcentral-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="MeshCentral" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ _ _____ _ _ - | \/ | | | / ____| | | | | - | \ / | ___ ___| |__ | | ___ _ __ | |_ _ __ __ _| | - | |\/| |/ _ \/ __| _ \| | v3 / _ \ _ \| __| __/ _ | | - | | | | __/\__ \ | | | |___| __/ | | | |_| | | (_| | | - |_| |_|\___||___/_| |_|\_____\___|_| |_|\__|_| \__,_|_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/meshcentral-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index f91f91d3..8de241a6 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/motioneye-v1.sh b/ct/motioneye-v1.sh deleted file mode 100644 index 944ee9b6..00000000 --- a/ct/motioneye-v1.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New MotionEye NVR LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/motioneye_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=motioneye -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID motioneye_setup.sh /motioneye_setup.sh -perms 755 -pct exec $CTID /motioneye_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created MotionEye LXC to $CTID." -echo -e "\e[1;92m MotionEye NVR should be reachable by going to the following URL. - http://${IP}:8765 -\e[0m" diff --git a/ct/motioneye-v2.sh b/ct/motioneye-v2.sh deleted file mode 100644 index 0c3449b3..00000000 --- a/ct/motioneye-v2.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="Motioneye" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ ____ _______ _____ ____ _ _ ________ ________ - | \/ |/ __ \__ __|_ _/ __ \| \ | | ____\ \ / / ____| - | \ / | | | | | | | || | | | \| | |__ \ \_/ /| |__ - | |\/| | | | | | | | || | | | | __| \ / | __| - | | | | |__| | | | _| || |__| | |\ | |____ | | | |____ - |_| |_|\____/ |_| |_____\____/|_| \_|______| |_| |______| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/motioneye-v3.sh b/ct/motioneye-v3.sh deleted file mode 100644 index 1c3ca29e..00000000 --- a/ct/motioneye-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Motioneye" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ ____ _______ _____ ____ _ _ ________ ________ - | \/ |/ __ \__ __|_ _/ __ \| \ | | ____\ \ / / ____| - | \ / | | | | | | | || | | | \| | |__ \ \_/ /| |__ - | |\/| | | | | | | | || | | | | __| \ / | __| - | | | | |__| | | | v3_| || |__| | |\ | |____ | | | |____ - |_| |_|\____/ |_| |_____\____/|_| \_|______| |_| |______| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/motioneye-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 78d60c7b..f8a8663b 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/mqtt-v1.sh b/ct/mqtt-v1.sh deleted file mode 100644 index bda6ed8e..00000000 --- a/ct/mqtt-v1.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New MQTT LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=mqtt -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID mqtt_setup.sh /mqtt_setup.sh -perms 755 -pct exec $CTID /mqtt_setup.sh -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a MQTT LXC Container to $CTID at IP Address ${IP}" diff --git a/ct/mqtt-v2.sh b/ct/mqtt-v2.sh deleted file mode 100644 index 7bd70ed0..00000000 --- a/ct/mqtt-v2.sh +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New MQTT LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ ____ _______ _______ - | \/ |/ __ \__ __|__ __| - | \ / | | | | | | | | - | |\/| | | | | | | | | - | | | | |__| | | | | | - |_| |_|\___\_\ |_| |_| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname mqtt - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created MQTT LXC to${CL} ${BL}$CTID${CL}. \n" diff --git a/ct/mqtt-v3.sh b/ct/mqtt-v3.sh deleted file mode 100644 index 7d74a950..00000000 --- a/ct/mqtt-v3.sh +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="MQTT" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ ____ _______ _______ - | \/ |/ __ \__ __|__ __| - | \ / | | | | | | | | - | |\/| | | | | | | | | - | | | | |__| | | | | | - |_| |_|\___\_\ |_| v3 |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/mqtt-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index 84801204..0518991c 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -285,7 +285,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/n8n-v3.sh b/ct/n8n-v3.sh deleted file mode 100644 index 1347f25c..00000000 --- a/ct/n8n-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="n8n" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - ___ - / _ \ - _ __ | (_) |_v3_ - | _ \ > _ <| _ \ - | | | | (_) | | | | - |_| |_|\___/|_| |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}3${CL}${DGN}GB${CL}" - DISK_SIZE="3" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/n8n-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5678${CL} \n" diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index c7b0cc56..f09ea205 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 750767a0..ed513d68 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index 0b119e71..84ed147c 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/nginx-proxy-manager-v1.sh b/ct/nginx-proxy-manager-v1.sh deleted file mode 100644 index efc67e28..00000000 --- a/ct/nginx-proxy-manager-v1.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env bash - -#!/usr/bin/env bash -while true; do - read -p "This will create a New Nginx Proxy Manager LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/npm_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "LXC ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" -DISK_SIZE=3G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=npm -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" -pct start $CTID -pct push $CTID npm_setup.sh /npm_setup.sh -perms 755 -pct exec $CTID /npm_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Nginx Proxy Manager LXC to $CTID." -echo -e "\e[1;92m Nginx Proxy Manager should be reachable by going to the following URL. - http://${IP}:81 -\e[0m" diff --git a/ct/nginx-proxy-manager-v2.sh b/ct/nginx-proxy-manager-v2.sh deleted file mode 100644 index 2b147d60..00000000 --- a/ct/nginx-proxy-manager-v2.sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Nginx Proxy Manager LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _ _ _____ __ __ - | \ | | __ \| \/ | - | \| | |__) | \ / | - | | ___/| |\/| | - | |\ | | | | | | - |_| \_|_| |_| |_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=3 -export PCT_OPTIONS=" - -features $FEATURES - -hostname npm - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nginx-proxy-manager-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Nginx Proxy Manager LXC to${CL} ${BL}$CTID${CL}. -Nginx Proxy Manager should be reachable by going to the following URL. - ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nginx-proxy-manager-v3.sh b/ct/nginx-proxy-manager-v3.sh deleted file mode 100644 index bfcf2225..00000000 --- a/ct/nginx-proxy-manager-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Nginx Proxy Manager" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _ _ _____ __ __ - | \ | | __ \| \/ | - | \| | |__) | \ / | - | | ___/| |\/| | - | |\ | | | | | | - |_| \_|_| v3 |_| |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}3${CL}${DGN}GB${CL}" - DISK_SIZE="3" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 3 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="3"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nginx-proxy-manager-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index c12d14d1..6cc5cb1b 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nginx-proxy-manager-install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/nginx-proxy-manager-install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/nocodb-v2.sh b/ct/nocodb-v2.sh deleted file mode 100644 index 4eafd1cf..00000000 --- a/ct/nocodb-v2.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="NocoDB" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _ _____ ____ - | \ | | | __ \| _ \ - | \| | ___ ___ ___ | | | | |_) | - | |/ _ \ / __/ _ \| | | | _ < - | |\ | (_) | (_| (_) | |__| | |_) | - |_| \_|\___/ \___\___/|_____/|____/ -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:8080/dashboard${CL}\n" diff --git a/ct/nocodb-v3.sh b/ct/nocodb-v3.sh deleted file mode 100644 index 9ede88a8..00000000 --- a/ct/nocodb-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="NocoDB" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _ _____ ____ - | \ | | | __ \| _ \ - | \| | ___ v3___ ___ | | | | |_) | - | |/ _ \ / __/ _ \| | | | _ < - | |\ | (_) | (_| (_) | |__| | |_) | - |_| \_|\___/ \___\___/|_____/|____/ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/nocodb-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080/dashboard${CL}\n" diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 2ca00f97..7503fb7a 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/node-red-v1.sh b/ct/node-red-v1.sh deleted file mode 100644 index ebd544b3..00000000 --- a/ct/node-red-v1.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Node-Red LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=nodered -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID node-red_setup.sh /node-red_setup.sh -perms 755 -pct exec $CTID /node-red_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Node-Red LXC to $CTID." -echo -e "\e[1;92m Node-Red should be reachable by going to the following URL. - http://${IP}:1880 -\e[0m" diff --git a/ct/node-red-v2.sh b/ct/node-red-v2.sh deleted file mode 100644 index 9ecc7d17..00000000 --- a/ct/node-red-v2.sh +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Node-Red LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _ _ _ _____ _ - | \ | | | | | __ \ | | - | \| | ___ __| | ___ ______| |__) |___ __| | - | |/ _ \ / _ |/ _ \______| _ // _ \/ _ | - | |\ | (_) | (_| | __/ | | \ \ __/ (_| | - |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname node-red - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Node-Red LXC to${CL} ${BL}$CTID${CL}. -${RD}Node-Red${CL} should be reachable by going to the following URL. - - ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/node-red-v3.sh b/ct/node-red-v3.sh deleted file mode 100644 index 58252e17..00000000 --- a/ct/node-red-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Node Red" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _ _ _ _____ _ - | \ | | | | | __ \ | | - | \| | ___ __| | ___ ______| |__) |___ __| | - | |/ _ \ / _ |/ _ \__v3__| _ // _ \/ _ | - | |\ | (_) | (_| | __/ | | \ \ __/ (_| | - |_| \_|\___/ \__,_|\___| |_| \_\___|\__,_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/node-red-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 97a94755..2ca913de 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/omada-v2.sh b/ct/omada-v2.sh deleted file mode 100644 index 6ec8036b..00000000 --- a/ct/omada-v2.sh +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/env bash -clear -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Omada Controller LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - ____ _ _____ _ _ _ - / __ \ | | / ____| | | | | | - | | | |_ __ ___ __ _ __| | __ _ | | ___ _ __ | |_ _ __ ___ | | | ___ _ __ - | | | | _ _ \ / _ |/ _ |/ _ | | | / _ \| _ \| __| __/ _ \| | |/ _ \ __| - | |__| | | | | | | (_| | (_| | (_| | | |___| (_) | | | | |_| | | (_) | | | __/ | - \____/|_| |_| |_|\__,_|\__,_|\__,_| \_____\___/|_| |_|\__|_| \___/|_|_|\___|_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose an Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=20.04 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname omada - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/omada-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Omada Controller LXC to${CL} ${BL}$CTID${CL}. -${BL}Omada${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:8043${CL} \n" diff --git a/ct/omada-v3.sh b/ct/omada-v3.sh deleted file mode 100644 index 7b97dace..00000000 --- a/ct/omada-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Omada" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - ____ _ _____ _ _ _ - / __ \ | | / ____| | | | | | - | | | |_ __ ___ v3__ _ __| | __ _ | | ___ _ __ | |_ _ __ ___ | | | ___ _ __ - | | | | _ _ \ / _ |/ _ |/ _ | | | / _ \| _ \| __| __/ _ \| | |/ _ \ __| - | |__| | | | | | | (_| | (_| | (_| | | |___| (_) | | | | |_| | | (_) | | | __/ | - \____/|_| |_| |_|\__,_|\__,_|\__,_| \_____\___/|_| |_|\__|_| \___/|_|_|\___|_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=20.04 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/omada-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}https://${IP}:8043${CL} \n" diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 099deba7..2b48b2a4 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -318,7 +318,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index a649a28c..9aa13239 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -320,7 +320,7 @@ EOF msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/openhab-v3.sh b/ct/openhab-v3.sh deleted file mode 100644 index a4726cb0..00000000 --- a/ct/openhab-v3.sh +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="openHAB" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _ ____ - | | | | /\ | _ \ - ___ _ __ ___ _ __ | |__| | / \ | |_) | - / _ \| _ \ / _ \ _ \| __ | / /\ \ | _ < - | (_) | |_) | __/ | | | | | |/ ____ \| |_) | - \___/| .__/ \___|_| |_|_| |_/_/ v3 \_\____/ - | | - |_| -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL}\n" diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index dc559dc3..75d60950 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index 37c347a7..b51119b6 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/photoprism-v2.sh b/ct/photoprism-v2.sh deleted file mode 100644 index 31035d89..00000000 --- a/ct/photoprism-v2.sh +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -PP=`echo "\e[1;35m"` -APP="PhotoPrism" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _____ _ _ _____ _ - | __ \| | | | | __ \ (_) - | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ - | ___/| _ \ / _ \| __/ _ \| ___/ __| / __| _ _ \ - | | | | | | (_) | || (_) | | | | | \__ \ | | | | | - |_| |_| |_|\___/ \__\___/|_| |_| |_|___/_| |_| |_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/photoprism-v3.sh b/ct/photoprism-v3.sh deleted file mode 100644 index 3f90236f..00000000 --- a/ct/photoprism-v3.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -PP=`echo "\e[1;35m"` -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="PhotoPrism" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - _____ _ _ _____ _ - | __ \| | | | | __ \ (_) - | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ - | ___/| _ \ / _ \| __/ _ \| ___/ __| / __| _ _ \ - | | | | | | (_) | || (_) | | | | | \__ \ | | | | | - |_| v3 |_| |_|\___/ \__\___/|_| |_| |_|___/_| |_| |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/photoprism-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index 5f4a5827..fc5b8c7f 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/pihole-v1.sh b/ct/pihole-v1.sh deleted file mode 100644 index 1d420089..00000000 --- a/ct/pihole-v1.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Pi-hole LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/pihole_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "LXC ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=pi-hole -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" -pct start $CTID -pct push $CTID pihole_setup.sh /pihole_setup.sh -perms 755 -pct exec $CTID /pihole_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Pi-hole LXC to $CTID" -echo -e "\e[1;92m Pi-hole should be reachable by going to the following URL. - http://${IP} -\e[0m" diff --git a/ct/pihole-v2.sh b/ct/pihole-v2.sh deleted file mode 100644 index 9a0abcdd..00000000 --- a/ct/pihole-v2.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="Pihole" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _____ _____ _ _ ____ _ ______ - | __ \_ _| | | |/ __ \| | | ____| - | |__) || | | |__| | | | | | | |__ - | ___/ | | | __ | | | | | | __| - | | _| |_| | | | |__| | |____| |____ - |_| |_____|_| |_|\____/|______|______| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/pihole-v3.sh b/ct/pihole-v3.sh deleted file mode 100644 index 03a5b577..00000000 --- a/ct/pihole-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Pihole" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _____ _____ _ _ ____ _ ______ - | __ \_ _| | | |/ __ \| | | ____| - | |__) || | | |__| | | | | | | |__ - | ___/ | | | __ | | | | | | __| - | | v3 _| |_| | | | |__| | |____| |____ - |_| |_____|_| |_|\____/|______|______| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/pihole-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}/admin${CL} \n" diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 01d25fff..e6a8b6d8 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/plex-v1.sh b/ct/plex-v1.sh deleted file mode 100644 index 68949613..00000000 --- a/ct/plex-v1.sh +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Plex Media Server LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for Storage Location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-20.04 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=plex -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID plex_setup.sh /plex_setup.sh -perms 755 -pct exec $CTID /plex_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Plex Media Server LXC to $CTID." -echo -e "\e[1;92m Plex Media Server should be reachable by going to the following URL. - http://${IP}:32400/web -\e[0m" diff --git a/ct/plex-v3.sh b/ct/plex-v3.sh deleted file mode 100644 index da77b58e..00000000 --- a/ct/plex-v3.sh +++ /dev/null @@ -1,368 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -APP="Plex" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _____ _ - | __ \| | - | |__) | | _____ __ - | ___/| |/ _ \ \/ / - | | | | __/> < - |_| v3 |_|\___/_/\_\ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}Unprivileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -PVE_CHECK -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=20.04 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/plex-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "Plex Media Server should be reachable by going to the following URL. - ${BL}http://${IP}:32400/web${CL}\n" diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index a490c938..6566426f 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -331,7 +331,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/podman-homeassistant-v1.sh b/ct/podman-homeassistant-v1.sh deleted file mode 100644 index 7bf3164a..00000000 --- a/ct/podman-homeassistant-v1.sh +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Podman Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _____ _ - | __ \ | | - | |__) |__ __| |_ __ ___ __ _ _ __ - | ___/ _ \ / _ | _ _ \ / _ | _ \ - | | | (_) | (_| | | | | | | (_| | | | | - |_| \___/ \__,_|_| |_| |_|\__,_|_| |_| _ _ _ - | | (_) | | | | - | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ - | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| - -${CL}" -} -header_info -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman_ha_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using ${BL}$STORAGE${CL} for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is ${BL}$CTID${CL}" -echo -en "${GN} Updating LXC Template List... " -pveam update >/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Downloading LXC Template... " -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} -echo -e "${CM}${CL} \r" - -echo -en "${GN} Creating LXC Container... " -DISK_SIZE=16G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi - ARCH=$(dpkg --print-architecture) -HOSTNAME=p-homeassistant -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 2048 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT -echo -e "${CM}${CL} \r" -echo -en "${GN} Starting LXC Container... " -pct start $CTID -pct push $CTID podman_ha_setup.sh /podman_ha_setup.sh -perms 755 -echo -e "${CM}${CL} \r" -pct exec $CTID /podman_ha_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully Created Podman Home Assistant Container LXC to ${BL}$CTID${CL}." -echo -e "${CL} Home Assistant Container should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} -Yacht should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/podman-homeassistant-v3.sh b/ct/podman-homeassistant-v3.sh deleted file mode 100644 index 30985849..00000000 --- a/ct/podman-homeassistant-v3.sh +++ /dev/null @@ -1,371 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -APP="P-Home Assistant" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _____ _ - | __ \ | | - | |__) |__ __| |_ __ ___ __ _ _ __ - | ___/ _ \ / _ | _ _ \ / _ | _ \ - | | | (_) | (_| | | | | | | (_| | | | | - |_| \___/ \__,_|_| |_| |_|\__,_|_| |_| _ _ _ - | | v3 (_) | | | | - | |__ ___ _ __ ___ ___ __ _ ___ ___ _ ___| |_ __ _ _ __ | |_ - | _ \ / _ \| _ _ \ / _ \/ _ / __/ __| / __| __/ _ | _ \| __| - | | | | (_) | | | | | | __/ (_| \__ \__ \ \__ \ || (_| | | | | |_ - |_| |_|\___/|_| |_| |_|\___|\__,_|___/___/_|___/\__\__,_|_| |_|\__| - -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}16${CL}${DGN}GB${CL}" - DISK_SIZE="16" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Unprivileged" - CT_TYPE="1" - echo -en "${DGN}Set CT Type ${BL}UnPrivileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 16 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="16"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} -PVE_CHECK -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/podman-homeassistant-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} -Yacht should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL}\n" diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index e4d22054..9aaa9f40 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -333,7 +333,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/podman-v4.sh b/ct/podman-v4.sh index 97250e37..49878c07 100644 --- a/ct/podman-v4.sh +++ b/ct/podman-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/postgresql-v3.sh b/ct/postgresql-v3.sh deleted file mode 100644 index d68d8102..00000000 --- a/ct/postgresql-v3.sh +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="PostgreSQL" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _____ _ _____ ____ _ - | __ \ | | / ____|/ __ \| | - | |__) |__ ___| |_ __ _ _ __ ___| (___ | | | | | - | ___/ _ \/ __| __/ _ | __/ _ \\___ \| | | | | - | | | (_) \__ \ || (_| | | | __/____) | |__| | |____ - |_| \___/|___/\__\__, |_| \___|_____/ \___\_\______| - __/ | - v3|___/ -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "Adminer should be reachable by going to the following URL. - ${BL}http://${IP}/adminer/${CL} \n" diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index aaa68b00..cee3ec14 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/prometheus-v3.sh b/ct/prometheus-v3.sh deleted file mode 100644 index a41f5125..00000000 --- a/ct/prometheus-v3.sh +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Prometheus" -var_disk="4" -var_cpu="1" -var_ram="2048" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _____ _____ ____ __ __ ______ _______ _ _ ______ _ _ _____ - | __ \| __ \ / __ \| \/ | ____|__ __| | | | ____| | | |/ ____| - | |__) | |__) | | | | \ / | |__ | | | |__| | |__ | | | | (___ - | ___/| _ /| | | | |\/| | __| v3 | | | __ | __| | | | |\___ \ - | | | | \ \| |__| | | | | |____ | | | | | | |____| |__| |____) | - |_| |_| \_\\_____/|_| |_|______| |_| |_| |_|______|\____/|_____/ -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:9090${CL} \n" diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 6bb1b9db..3cc52e25 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh index 94f598d1..77f84839 100644 --- a/ct/scrypted-v4.sh +++ b/ct/scrypted-v4.sh @@ -324,7 +324,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/shinobi-v4.sh b/ct/shinobi-v4.sh index cfb70935..08b8fcb9 100644 --- a/ct/shinobi-v4.sh +++ b/ct/shinobi-v4.sh @@ -319,7 +319,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index 6a5e0de7..85da6fc5 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -311,7 +311,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/technitiumdns-v2.sh b/ct/technitiumdns-v2.sh deleted file mode 100644 index 2d960480..00000000 --- a/ct/technitiumdns-v2.sh +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="Technitium DNS" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - - _______ _ _ _ _ - |__ __| | | (_) | (_) - | | ___ ___| |__ _ __ _| |_ _ _ _ _ __ ___ - | |/ _ \/ __| _ \| _ \| | __| | | | | _ _ \ - | | __/ (__| | | | | | | | |_| | |_| | | | | | | - |_|\___|\___|_| |_|_| |_|_|\__|_|\__,_|_| |_| |_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/technitiumdns-v3.sh b/ct/technitiumdns-v3.sh deleted file mode 100644 index 201b6267..00000000 --- a/ct/technitiumdns-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Technitium DNS" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - _______ _ _ _ _ - |__ __| | | (_) | (_) - | | ___v3___| |__ _ __ _| |_ _ _ _ _ __ ___ - | |/ _ \/ __| _ \| _ \| | __| | | | | _ _ \ - | | __/ (__| | | | | | | | |_| | |_| | | | | | | - |_|\___|\___|_| |_|_| |_|_|\__|_|\__,_|_| |_| |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/technitiumdns-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index 644ddd78..70716601 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index dbdf6585..4342cf70 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/ubuntu-v1.sh b/ct/ubuntu-v1.sh deleted file mode 100644 index 3703d85a..00000000 --- a/ct/ubuntu-v1.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Ubuntu 21.10 LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=ubuntu -OSVERSION=${OSTYPE}-21.10 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC... \e[0m" -DISK_SIZE=2G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=$OSTYPE -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 1 -memory 512\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC... \e[0m" -pct start $CTID -pct push $CTID ubuntu_setup.sh /ubuntu_setup.sh -perms 755 -pct exec $CTID /ubuntu_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Ubuntu LXC Container to $CTID at IP Address ${IP}" diff --git a/ct/ubuntu-v2.sh b/ct/ubuntu-v2.sh deleted file mode 100644 index 4152e1d0..00000000 --- a/ct/ubuntu-v2.sh +++ /dev/null @@ -1,255 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Ubuntu 21.10 LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _ _ _ - | | | | | | | - | | | | |__ _ _ _ __ | |_ _ _ - | | | | _ \| | | | _ \| __| | | | - | |__| | |_) | |_| | | | | |_| |_| | - \____/|_.__/ \__,_|_| |_|\__|\__,_| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=21.10 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname ubuntu - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Ubuntu 21.10 LXC to${CL} ${BL}$CTID${CL}. \n" diff --git a/ct/ubuntu-v3.sh b/ct/ubuntu-v3.sh deleted file mode 100644 index 5f5b38b1..00000000 --- a/ct/ubuntu-v3.sh +++ /dev/null @@ -1,377 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Ubuntu" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _ _ _ _ - | | | | | | | - | | | | |__ _ v3_ _ __ | |_ _ _ - | | | | _ \| | | | _ \| __| | | | - | |__| | |_) | |_| | | | | |_| |_| | - \____/|_.__/ \__,_|_| |_|\__|\__,_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using Version ${BGN}22.04${CL}" - VER="22.04" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type 18.04, 20.04, 21.10 or Press [ENTER] for Default: 22.04" - read VER - if [ -z $VER ]; then VER="22.04"; fi; - echo -en "${DGN}Set Version To ${BL}$VER${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using Version ${BGN}$VER${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=ubuntu -export PCT_OSVERSION=$VER -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/ubuntu-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 44f3d233..755af1cd 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -318,7 +318,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index c19dce93..859696e8 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -325,7 +325,7 @@ EOF msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/unifi-v2.sh b/ct/unifi-v2.sh deleted file mode 100644 index 077f3cc1..00000000 --- a/ct/unifi-v2.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="UniFi" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _ _ _ ______ _ - | | | | (_) ____(_) - | | | |_ __ _| |__ _ - | | | | _ \| | __| | | - | |__| | | | | | | | | - \____/|_| |_|_|_| |_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 2048 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:8443${CL} \n" diff --git a/ct/unifi-v3.sh b/ct/unifi-v3.sh deleted file mode 100644 index 158758b1..00000000 --- a/ct/unifi-v3.sh +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Unifi" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - _ _ _ ______ _ - | | | | (_) ____(_) - | | | |_ __ _| |__ _ - | | | | _ \| | __| | | - | |__| | | | | | | | | - \____/|_| |_|_|_| v3 |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}8${CL}${DGN}GB${CL}" - DISK_SIZE="8" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 8 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="8"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/unifi-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP}${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:8443${CL} \n" diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index 3d60590d..b0a9bfd4 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/uptimekuma-v2.sh b/ct/uptimekuma-v2.sh deleted file mode 100644 index b40519ba..00000000 --- a/ct/uptimekuma-v2.sh +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -APP="Uptime Kuma" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${DGN} - _ _ _ _ _ __ - | | | | | | (_) | |/ / - | | | |_ __ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ - | | | | _ \| __| | _ _ \ / _ \ | <| | | | _ _ \ / _ | - | |__| | |_) | |_| | | | | | | __/ | . \ |_| | | | | | | (_| | - \____/| .__/ \__|_|_| |_| |_|\___| |_|\_\__,_|_| |_| |_|\__,_| - | | - |_| -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some applications may not work properly due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:3001${CL}\n" diff --git a/ct/uptimekuma-v3.sh b/ct/uptimekuma-v3.sh deleted file mode 100644 index d9cb376b..00000000 --- a/ct/uptimekuma-v3.sh +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Uptime Kuma" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${DGN} - _ _ _ _ _ __ - | | | | | | (_) | |/ / - | | | |_v3_ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ - | | | | _ \| __| | _ _ \ / _ \ | <| | | | _ _ \ / _ | - | |__| | |_) | |_| | | | | | | __/ | . \ |_| | | | | | | (_| | - \____/| .__/ \__|_|_| |_| |_|\___| |_|\_\__,_|_| |_| |_|\__,_| - | | - |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/uptimekuma-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3001${CL}\n" diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index b31b279f..297aae54 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/vaultwarden-v1.sh b/ct/vaultwarden-v1.sh deleted file mode 100644 index 56b5ac3b..00000000 --- a/ct/vaultwarden-v1.sh +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/env bash -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Vaultwarden LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - __ __ _ _ _ - \ \ / / | | | | | - \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ - \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ - \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | - \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| - -${CL}" -} - -header_info -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vault_setup.sh - -load_module overlay -echo -e "${RD} Expect 30+ minute install time. ${CL} \n" -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=8G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=vaultwarden -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 4 -memory 4096\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID vault_setup.sh /vault_setup.sh -perms 755 -pct exec $CTID /vault_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Vaultwarden LXC Container to $CTID" -echo -e "\e[1;92m Vaultwarden should be reachable by going to the following URL. - http://${IP}:8000 -\e[0m" diff --git a/ct/vaultwarden-v2.sh b/ct/vaultwarden-v2.sh deleted file mode 100644 index fe16570c..00000000 --- a/ct/vaultwarden-v2.sh +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="Vaultwarden" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - __ __ _ _ _ - \ \ / / | | | | | - \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ - \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ - \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | - \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=8 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 4 - -memory 4096 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/vaultwarden-v3.sh b/ct/vaultwarden-v3.sh deleted file mode 100644 index 735160ff..00000000 --- a/ct/vaultwarden-v3.sh +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Vaultwarden" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - __ __ _ _ _ - \ \ v3 / / | | | | | - \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ - \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ - \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | - \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}6${CL}${DGN}GB${CL}" - DISK_SIZE="6" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}2048${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="2048" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 6 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="6"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 2048 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="2048"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/vaultwarden-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 512 -pct set $CTID -cores 1 -msg_ok "Set Container to Normal Resources" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index 9e5ffc70..a57b2191 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/whoogle-v3.sh b/ct/whoogle-v3.sh deleted file mode 100644 index 59274f4e..00000000 --- a/ct/whoogle-v3.sh +++ /dev/null @@ -1,360 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Whoogle" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -PP=`echo "\e[1;35m"` -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${PP} - __ ___ _ ____ ____ _____ _ ______ - \ \ v3 / / | | |/ __ \ / __ \ / ____| | | ____| - \ \ /\ / /| |__| | | | | | | | | __| | | |__ - \ \/ \/ / | __ | | | | | | | | |_ | | | __| - \ /\ / | | | | |__| | |__| | |__| | |____| |____ - \/ \/ |_| |_|\____/ \____/ \_____|______|______| -${CL}" -} - -header_info - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Using ${BGN}$var_cpu${CL}${DGN}vCPU${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Using ${BGN}$var_ram${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: $var_disk " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: $var_cpu " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: $var_ram " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index a910806c..422e9d46 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -309,7 +309,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index 54b25b7b..486100a7 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -310,7 +310,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/wireguard-v2.sh b/ct/wireguard-v2.sh deleted file mode 100644 index 7137c4d3..00000000 --- a/ct/wireguard-v2.sh +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New WireGuard LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - __ ___ _____ _ - \ \ / (_) / ____| | | - \ \ /\ / / _ _ __ ___| | __ _ _ __ _ _ __ __| | - \ \/ \/ / | | __/ _ \ | |_ | | | |/ _ | __/ _ | - \ /\ / | | | | __/ |__| | |_| | (_| | | | (_| | - \/ \/ |_|_| \___|\_____|\__,_|\__,_|_| \__,_| - ${YW}With WGDashboard -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${YW} Privileged ${CL}\n" - printf " ${YW} 2)${GN} Unprivileged ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=2 -export PCT_OPTIONS=" - -features $FEATURES - -hostname wireguard - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 1 - -memory 512 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/wireguard-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created WireGuard LXC to${CL} ${BL}$CTID${CL}. - -${BL}WGDashboard${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:10086${CL} \n" diff --git a/ct/wireguard-v3.sh b/ct/wireguard-v3.sh deleted file mode 100644 index 284f665c..00000000 --- a/ct/wireguard-v3.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Wireguard" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - __ ___ _____ _ - \ \ / (_) / ____| | | - \ \ /\ / / _ _ __ ___| | __ _ _ __ _ _ __ __| | - \ \/ \/ / | | __/ _ \ | |_ | | | |/ _ | __/ _ | - \ /\ / | | | | __/ |__| | |_| | (_| | | | (_| | - \/ \/ v3|_|_| \___|\_____|\__,_|\__,_|_| \__,_| - ${YW}With WGDashboard -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}2${CL}${DGN}GB${CL}" - DISK_SIZE="2" - echo -e "${DGN}Using ${BGN}1${CL}${DGN}vCPU${CL}" - CORE_COUNT="1" - echo -e "${DGN}Using ${BGN}512${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="512" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type Privileged, or Press [ENTER] for Default: Unprivileged (${RD}NO DEVICE PASSTHROUGH${CL}${YW})" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Unprivileged" CT_TYPE="1"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 2 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="2"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 1 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="1"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 512 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="512"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/wireguard-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "WGDashboard should be reachable by going to the following URL. - ${BL}http://${IP}:10086${CL} \n" diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 946b6c00..95bfda0a 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -311,7 +311,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/zigbee2mqtt-v1.sh b/ct/zigbee2mqtt-v1.sh deleted file mode 100644 index 4e7d8c65..00000000 --- a/ct/zigbee2mqtt-v1.sh +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Zigbee2MQTT LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for storage location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC Template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=zigbee2mqtt -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024 \ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID zigbee2mqtt_setup.sh /zigbee2mqtt_setup.sh -perms 755 -pct exec $CTID /zigbee2mqtt_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created zigbee2mqtt LXC Container to $CTID at IP Address ${IP}" -echo -echo -e "\e[1;31m Updating the configuration.yaml is required and found at /opt/zigbee2mqtt/data/ \e[0m" -echo -echo diff --git a/ct/zigbee2mqtt-v2.sh b/ct/zigbee2mqtt-v2.sh deleted file mode 100644 index f4a0c0fd..00000000 --- a/ct/zigbee2mqtt-v2.sh +++ /dev/null @@ -1,263 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -while true; do - read -p "This will create a New Zigbee2MQTT LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _______ _ ___ __ __ ____ _______ _______ - |___ (_) | | |__ \| \/ |/ __ \__ __|__ __| - / / _ __ _| |__ ___ ___ ) | \ / | | | | | | | | - / / | |/ _ | _ \ / _ \/ _ \ / /| |\/| | | | | | | | | - / /__| | (_| | |_) | __/ __// /_| | | | |__| | | | | | - /_____|_|\__, |____/ \___|\___|____|_| |_|\___\_\ |_| |_| - __/ | - |___/ - -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${GN} Privileged ${CL}\n" - printf " ${YW} 2)${RD} Unprivileged (no device passthrough) ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname zigbee2mqtt - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created Zigbee2MQTT LXC to${CL} ${BL}$CTID${CL}. \n" diff --git a/ct/zigbee2mqtt-v3.sh b/ct/zigbee2mqtt-v3.sh deleted file mode 100644 index 46a61c82..00000000 --- a/ct/zigbee2mqtt-v3.sh +++ /dev/null @@ -1,369 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -APP="Zigbee2MQTT" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${YW} - _______ _ ___ __ __ ____ _______ _______ - |___ (_) | | |__ \| \/ |/ __ \__ __|__ __| - / / _ __ _| |__ ___ ___ ) | \ / | | | | | | | | - / / | |/ _ | _ \ / _ \/ _ \ / /| |\/| | | | | | | | | - / /__| | (_| | |_) | __/ __// /_| | | | |__| | | | | | - /_____|_|\__, |____/ \___|\___|____|_| |_|\___\_\ |_| |_| - v3 __/ | - |___/ -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -PVE_CHECK -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zigbee2mqtt-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 1d5e0bc8..53a0cc5b 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -324,7 +324,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 46aa99ba..5928e9b9 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -324,7 +324,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ diff --git a/ct/zwavejs2mqtt-v1.sh b/ct/zwavejs2mqtt-v1.sh deleted file mode 100644 index fb21a900..00000000 --- a/ct/zwavejs2mqtt-v1.sh +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` - -while true; do - read -p "This will create a New Zwavejs2MQTT LXC Container. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${RD} - ______ _ ___ __ __ ____ _______ _______ - |___ / (_) |__ \| \/ |/ __ \__ __|__ __| - / /_ ____ ___ _____ _ ___ ) | \ / | | | | | | | | - / /\ \ /\ / / _ \ \ / / _ \ / __| / /| |\/| | | | | | | | | - / /__\ V V / (_| |\ V / __/ \__ \/ /_| | | | |__| | | | | | - /_____|\_/\_/ \__,_| \_/ \___| |___/____|_| |_|\___\_\ |_| |_| - _/ | - |__/ -${CL}" -} - -header_info - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if [ ! -z ${MOUNT+x} ]; then - pct unmount $CTID - fi - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -function load_module() { - if ! $(lsmod | grep -Fq $1); then - modprobe $1 &>/dev/null || \ - die "Failed to load '$1' module." - fi - MODULES_PATH=/etc/modules - if ! $(grep -Fxq "$1" $MODULES_PATH); then - echo "$1" >> $MODULES_PATH || \ - die "Failed to add '$1' module to load at boot." - fi -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -wget -qL https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zwavejs2mqtt_setup.sh - -load_module overlay - -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content rootdir | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then - warn "'Container' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the container?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -info "Using '$STORAGE' for Storage Location." - -CTID=$(pvesh get /cluster/nextid) -info "Container ID is $CTID." - -echo -e "${CHECKMARK} \e[1;92m Updating LXC Template List... \e[0m" -pveam update >/dev/null -echo -e "${CHECKMARK} \e[1;92m Downloading LXC Template... \e[0m" -OSTYPE=debian -OSVERSION=${OSTYPE}-11 -mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($OSVERSION.*\)/\1/p" | sort -t - -k 2 -V) -TEMPLATE="${TEMPLATES[-1]}" -pveam download local $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." - -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - dir|nfs) - DISK_EXT=".raw" - DISK_REF="$CTID/" - ;; - zfspool) - DISK_PREFIX="subvol" - DISK_FORMAT="subvol" - ;; -esac -DISK=${DISK_PREFIX:-vm}-${CTID}-disk-0${DISK_EXT-} -ROOTFS=${STORAGE}:${DISK_REF-}${DISK} - -echo -e "${CHECKMARK} \e[1;92m Creating LXC Container... \e[0m" -DISK_SIZE=4G -pvesm alloc $STORAGE $CTID $DISK $DISK_SIZE --format ${DISK_FORMAT:-raw} >/dev/null -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some containers may not work properly due to ZFS not supporting 'fallocate'." -else - mkfs.ext4 $(pvesm path $ROOTFS) &>/dev/null -fi -ARCH=$(dpkg --print-architecture) -HOSTNAME=zwavejs2mqtt -TEMPLATE_STRING="local:vztmpl/${TEMPLATE}" -pct create $CTID $TEMPLATE_STRING -arch $ARCH -features nesting=1 \ - -hostname $HOSTNAME -net0 name=eth0,bridge=vmbr0,ip=dhcp -onboot 1 -cores 2 -memory 1024\ - -ostype $OSTYPE -rootfs $ROOTFS,size=$DISK_SIZE -storage $STORAGE >/dev/null - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF - -MOUNT=$(pct mount $CTID | cut -d"'" -f 2) -ln -fs $(readlink /etc/localtime) ${MOUNT}/etc/localtime -pct unmount $CTID && unset MOUNT - -echo -e "${CHECKMARK} \e[1;92m Starting LXC Container... \e[0m" -pct start $CTID -pct push $CTID zwavejs2mqtt_setup.sh /zwavejs2mqtt_setup.sh -perms 755 -pct exec $CTID /zwavejs2mqtt_setup.sh - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -info "Successfully created a Zwavejs2MQTT LXC Container to $CTID at IP Address ${IP}:8091" diff --git a/ct/zwavejs2mqtt-v2.sh b/ct/zwavejs2mqtt-v2.sh deleted file mode 100644 index 72669df9..00000000 --- a/ct/zwavejs2mqtt-v2.sh +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/env bash -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -APP="Zwavejs2MQTT" -HN=$(echo ${APP,,} | tr -d ' ') -while true; do - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - ______ _ ___ __ __ ____ _______ _______ - |___ / (_) |__ \| \/ |/ __ \__ __|__ __| - / /_ ____ ___ _____ _ ___ ) | \ / | | | | | | | | - / /\ \ /\ / / _ \ \ / / _ \ / __| / /| |\/| | | | | | | | | - / /__\ V V / (_| |\ V / __/ \__ \/ /_| | | | |__| | | | | | - /_____|\_/\_/ \__,_| \_/ \___| |___/____|_| |_|\___\_\ |_| |_| - _/ | - |__/ -${CL}" -} - -header_info -show_menu(){ - printf " ${YW} 1)${GN} Privileged ${CL}\n" - printf " ${YW} 2)${RD} Unprivileged (no device passthrough) ${CL}\n" - - printf "Please choose a Install Method and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Privileged Install"; - IM=0 - break; - ;; - 2) clear; - header_info; - option_picked "Using Unprivileged Install"; - IM=1 - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Install Method from the menu"; - show_menu; - ;; - esac - done -show_menu2(){ - printf " ${YW} 1)${GN} Use Automatic Login ${CL}\n" - printf " ${YW} 2)${GN} Use Password (changeme) ${CL}\n" - - printf "Please choose a Password Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message2=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" -} -show_menu2 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic Login"; - PW=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Password (changeme)"; - PW="-password changeme" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a Password Type from the menu"; - show_menu2; - ;; - esac - done -show_menu3(){ - printf " ${YW} 1)${GN} Automatic DHCP ${CL}\n" - printf " ${YW} 2)${GN} Manual DHCP ${CL}\n" - - printf "Please choose a DHCP Type and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked(){ - message3=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" - printf " ${YW}${message2}${CL}\n" - printf " ${YW}${message3}${CL}\n" -} -show_menu3 -while [ "$opt" != " " ] - do - case $opt in - 1) clear; - header_info; - option_picked "Using Automatic DHCP"; - DHCP=" " - break; - ;; - 2) clear; - header_info; - option_picked "Using Manual DHCP"; - DHCP="1" - break; - ;; - - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose a DHCP Type from the menu"; - show_menu3; - ;; - esac - done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if $(pct status $CTID &>/dev/null); then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - elif [ "$(pvesm list $STORAGE --vmid $CTID)" != "" ]; then - pvesm free $ROOTFS - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - if [ "$IM" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$(pvesh get /cluster/nextid) -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=4 -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -onboot 1 - -cores 2 - -memory 1024 - -unprivileged ${IM} - ${PW} -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -STORAGE_TYPE=$(pvesm status -storage $(pct config $CTID | grep rootfs | awk -F ":" '{print $2}') | awk 'NR>1 {print $2}') -if [ "$STORAGE_TYPE" == "zfspool" ]; then - warn "Some addons may not work due to ZFS not supporting 'fallocate'." -fi -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -if [ "$DHCP" == "1" ]; then -MAC=$(pct config $CTID \ -| grep -i hwaddr \ -| awk '{print substr($2, 31, length($3) 17 ) }') \ - -echo -e "MAC Address ${BL}$MAC${CL}" - -dhcp_reservation(){ - printf "Please set DHCP reservation and press Enter." - read -} -dhcp_reservation -fi - -echo -en "${GN} Starting LXC Container... " -pct start $CTID -echo -e "${CM}${CL} \r" - -alias lxc-cmd="lxc-attach -n $CTID --" - -lxc-cmd bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/$HN-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -echo -e "${GN}Successfully created ${APP} LXC to${CL} ${BL}$CTID${CL}. -${BL}${APP}${CL} should be reachable by going to the following URL. - ${BL}http://${IP}:8091${CL} \n" diff --git a/ct/zwavejs2mqtt-v3.sh b/ct/zwavejs2mqtt-v3.sh deleted file mode 100644 index 88b9c87c..00000000 --- a/ct/zwavejs2mqtt-v3.sh +++ /dev/null @@ -1,371 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -APP="Zwavejs2MQTT" -NSAPP=$(echo ${APP,,} | tr -d ' ') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - clear - read -p "This will create a New ${APP} LXC. Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -clear -function header_info { -echo -e "${BL} - ______ _ ___ __ __ ____ _______ _______ - |___ / (_) |__ \| \/ |/ __ \__ __|__ __| - / /_ ____ ___ _____ _ ___ ) | \ / | | | | | | | | - / /\ \ /\ / / _ \ \ / / _ \ / __| / /| |\/| | | | | | | | | - / /__\ V V / (_| |\ V / __/ \__ \/ /_| | | | |__| | | | | | - /_____|\_/\_/ \__,_| \_/ \___| |___/____|_| |_|\___\_\ |_| v3 |_| - _/ | - |__/ -${CL}" -} -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function default_settings() { - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using CT Password ${BGN}Automatic Login${CL}" - PW=" " - echo -e "${DGN}Using CT ID ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using CT Name ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size ${BGN}4${CL}${DGN}GB${CL}" - DISK_SIZE="4" - echo -e "${DGN}Using ${BGN}2${CL}${DGN}vCPU${CL}" - CORE_COUNT="2" - echo -e "${DGN}Using ${BGN}1024${CL}${DGN}MiB RAM${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address ${BGN}DHCP${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address ${BGN}NONE${CL}" - GATE="" - echo -e "${DGN}Using VLAN Tag ${BGN}NONE${CL}" - VLAN="" -} - -function advanced_settings() { - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${YW}Type ${CROSS}${YW}Unprivileged, or Press [ENTER] for Default: Privileged" - read CT_TYPE1 - if [ -z $CT_TYPE1 ]; then CT_TYPE1="Privileged" CT_TYPE="0"; - echo -en "${DGN}Set CT Type ${BL}$CT_TYPE1${CL}" - else - CT_TYPE1="Privileged" - CT_TYPE="0" - echo -en "${DGN}Set CT Type ${BL}Privileged${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${YW}Set Password, or Press [ENTER] for Default: Automatic Login " - read PW1 - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -en "${DGN}Set CT ${BL}$PW1${CL}" - else - PW="-password $PW1" - echo -en "${DGN}Set CT Password ${BL}$PW1${CL}" - fi; -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${YW}Enter the CT ID, or Press [ENTER] to automatically generate (${NEXTID}) " - read CT_ID - if [ -z $CT_ID ]; then CT_ID=$NEXTID; fi; - echo -en "${DGN}Set CT ID To ${BL}$CT_ID${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${YW}Enter CT Name (no-spaces), or Press [ENTER] for Default: $NSAPP " - read CT_NAME - if [ -z $CT_NAME ]; then - HN=$NSAPP - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -en "${DGN}Set CT Name To ${BL}$HN${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${YW}Enter a Disk Size, or Press [ENTER] for Default: 4 " - read DISK_SIZE - if [ -z $DISK_SIZE ]; then DISK_SIZE="4"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo "ERROR! DISK SIZE MUST HAVE INTEGER NUMBER!"; exit; fi; - echo -en "${DGN}Set Disk Size To ${BL}$DISK_SIZE${CL}${DGN}GB${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${YW}Allocate CPU cores, or Press [ENTER] for Default: 2 " - read CORE_COUNT - if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; fi; - echo -en "${DGN}Set Cores To ${BL}$CORE_COUNT${CL}${DGN}vCPU${CL}" -echo -e " ${CM}${CL} \r" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${YW}Allocate RAM in MiB, or Press [ENTER] for Default: 1024 " - read RAM_SIZE - if [ -z $RAM_SIZE ]; then RAM_SIZE="1024"; fi; - echo -en "${DGN}Set RAM To ${BL}$RAM_SIZE${CL}${DGN}MiB RAM${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${YW}Enter a Bridge, or Press [ENTER] for Default: vmbr0 " - read BRG - if [ -z $BRG ]; then BRG="vmbr0"; fi; - echo -en "${DGN}Set Bridge To ${BL}$BRG${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${YW}Enter a Static IPv4 CIDR Address, or Press [ENTER] for Default: DHCP " - read NET - if [ -z $NET ]; then NET="dhcp"; fi; - echo -en "${DGN}Set Static IP Address To ${BL}$NET${CL}" -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${YW}Enter a Gateway IP (mandatory if static IP is used), or Press [ENTER] for Default: NONE " - read GATE1 - if [ -z $GATE1 ]; then GATE1="NONE" GATE=""; - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -en "${DGN}Set Gateway IP To ${BL}$GATE1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${YW}Enter a VLAN Tag, or Press [ENTER] for Default: NONE " - read VLAN1 - if [ -z $VLAN1 ]; then VLAN1="NONE" VLAN=""; - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -en "${DGN}Set VLAN Tag To ${BL}$VLAN1${CL}" - fi; -echo -e " ${CM}${CL} \n" -sleep 1 -clear -header_info - echo -e "${RD}Using Advanced Settings${CL}" - echo -e "${DGN}Using CT Type ${BGN}$CT_TYPE1${CL}" - echo -e "${DGN}Using CT Password ${BGN}$PW1${CL}" - echo -e "${DGN}Using CT ID ${BGN}$CT_ID${CL}" - echo -e "${DGN}Using CT Name ${BGN}$HN${CL}" - echo -e "${DGN}Using Disk Size ${BGN}$DISK_SIZE${CL}${DGN}GB${CL}" - echo -e "${DGN}Using ${BGN}${CORE_COUNT}${CL}${DGN}vCPU${CL}" - echo -e "${DGN}Using ${BGN}${RAM_SIZE}${CL}${DGN}MiB RAM${CL}" - echo -e "${DGN}Using Bridge ${BGN}${BRG}${CL}" - echo -e "${DGN}Using Static IP Address ${BGN}$NET${CL}" - echo -e "${DGN}Using Gateway IP Address ${BGN}$GATE1${CL}" - echo -e "${DGN}Using VLAN Tag ${BGN}$VLAN1${CL}" - -read -p "Are these settings correct(y/n)? " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]] -then - advanced_settings -fi -} - -function start_script() { - echo -e "${YW}Type Advanced, or Press [ENTER] for Default Settings " - read SETTINGS - if [ -z $SETTINGS ]; then default_settings; - else - advanced_settings - fi; -} - -PVE_CHECK -start_script - -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -export CTID=$CT_ID -export PCT_OSTYPE=debian -export PCT_OSVERSION=11 -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - -net0 name=eth0,bridge=$BRG,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <> $LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF - -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" - -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/setup/zwavejs2mqtt-install.sh)" || exit - -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') - -pct set $CTID -description "# ${APP} LXC -### https://github.com/tteck/Proxmox" - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8091${CL} \n" diff --git a/setup/adguard-install.sh b/install/adguard-install.sh similarity index 100% rename from setup/adguard-install.sh rename to install/adguard-install.sh diff --git a/setup/blocky-install.sh b/install/blocky-install.sh similarity index 100% rename from setup/blocky-install.sh rename to install/blocky-install.sh diff --git a/setup/casaos-install.sh b/install/casaos-install.sh similarity index 100% rename from setup/casaos-install.sh rename to install/casaos-install.sh diff --git a/setup/changedetection-install.sh b/install/changedetection-install.sh similarity index 100% rename from setup/changedetection-install.sh rename to install/changedetection-install.sh diff --git a/setup/daemonsync-install.sh b/install/daemonsync-install.sh similarity index 100% rename from setup/daemonsync-install.sh rename to install/daemonsync-install.sh diff --git a/setup/dashy-install.sh b/install/dashy-install.sh similarity index 100% rename from setup/dashy-install.sh rename to install/dashy-install.sh diff --git a/setup/debian-install.sh b/install/debian-install.sh similarity index 100% rename from setup/debian-install.sh rename to install/debian-install.sh diff --git a/setup/deconz-install.sh b/install/deconz-install.sh similarity index 100% rename from setup/deconz-install.sh rename to install/deconz-install.sh diff --git a/setup/docker-install.sh b/install/docker-install.sh similarity index 100% rename from setup/docker-install.sh rename to install/docker-install.sh diff --git a/setup/emby-install.sh b/install/emby-install.sh similarity index 100% rename from setup/emby-install.sh rename to install/emby-install.sh diff --git a/setup/emqx-install.sh b/install/emqx-install.sh similarity index 100% rename from setup/emqx-install.sh rename to install/emqx-install.sh diff --git a/setup/esphome-install.sh b/install/esphome-install.sh similarity index 100% rename from setup/esphome-install.sh rename to install/esphome-install.sh diff --git a/setup/grafana-install.sh b/install/grafana-install.sh similarity index 100% rename from setup/grafana-install.sh rename to install/grafana-install.sh diff --git a/setup/grocy-install.sh b/install/grocy-install.sh similarity index 100% rename from setup/grocy-install.sh rename to install/grocy-install.sh diff --git a/setup/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh similarity index 100% rename from setup/heimdalldashboard-install.sh rename to install/heimdalldashboard-install.sh diff --git a/setup/homeassistant-core-install.sh b/install/homeassistant-core-install.sh similarity index 100% rename from setup/homeassistant-core-install.sh rename to install/homeassistant-core-install.sh diff --git a/setup/homeassistant-install.sh b/install/homeassistant-install.sh similarity index 100% rename from setup/homeassistant-install.sh rename to install/homeassistant-install.sh diff --git a/setup/homebridge-install.sh b/install/homebridge-install.sh similarity index 100% rename from setup/homebridge-install.sh rename to install/homebridge-install.sh diff --git a/setup/homepage-install.sh b/install/homepage-install.sh similarity index 100% rename from setup/homepage-install.sh rename to install/homepage-install.sh diff --git a/setup/hyperion-install.sh b/install/hyperion-install.sh similarity index 100% rename from setup/hyperion-install.sh rename to install/hyperion-install.sh diff --git a/setup/influxdb-install.sh b/install/influxdb-install.sh similarity index 100% rename from setup/influxdb-install.sh rename to install/influxdb-install.sh diff --git a/setup/iobroker-install.sh b/install/iobroker-install.sh similarity index 100% rename from setup/iobroker-install.sh rename to install/iobroker-install.sh diff --git a/setup/jellyfin-install.sh b/install/jellyfin-install.sh similarity index 100% rename from setup/jellyfin-install.sh rename to install/jellyfin-install.sh diff --git a/setup/k0s-install.sh b/install/k0s-install.sh similarity index 100% rename from setup/k0s-install.sh rename to install/k0s-install.sh diff --git a/setup/keycloak-install.sh b/install/keycloak-install.sh similarity index 100% rename from setup/keycloak-install.sh rename to install/keycloak-install.sh diff --git a/setup/magicmirror-install.sh b/install/magicmirror-install.sh similarity index 100% rename from setup/magicmirror-install.sh rename to install/magicmirror-install.sh diff --git a/setup/mariadb-install.sh b/install/mariadb-install.sh similarity index 100% rename from setup/mariadb-install.sh rename to install/mariadb-install.sh diff --git a/setup/meshcentral-install.sh b/install/meshcentral-install.sh similarity index 100% rename from setup/meshcentral-install.sh rename to install/meshcentral-install.sh diff --git a/setup/motioneye-install.sh b/install/motioneye-install.sh similarity index 100% rename from setup/motioneye-install.sh rename to install/motioneye-install.sh diff --git a/setup/mqtt-install.sh b/install/mqtt-install.sh similarity index 100% rename from setup/mqtt-install.sh rename to install/mqtt-install.sh diff --git a/setup/n8n-install.sh b/install/n8n-install.sh similarity index 100% rename from setup/n8n-install.sh rename to install/n8n-install.sh diff --git a/setup/navidrome-install.sh b/install/navidrome-install.sh similarity index 100% rename from setup/navidrome-install.sh rename to install/navidrome-install.sh diff --git a/setup/nextcloudpi-install.sh b/install/nextcloudpi-install.sh similarity index 100% rename from setup/nextcloudpi-install.sh rename to install/nextcloudpi-install.sh diff --git a/setup/nginx-proxy-manager-install.sh b/install/nginx-proxy-manager-install.sh similarity index 100% rename from setup/nginx-proxy-manager-install.sh rename to install/nginx-proxy-manager-install.sh diff --git a/setup/nocodb-install.sh b/install/nocodb-install.sh similarity index 100% rename from setup/nocodb-install.sh rename to install/nocodb-install.sh diff --git a/setup/node-red-install.sh b/install/node-red-install.sh similarity index 100% rename from setup/node-red-install.sh rename to install/node-red-install.sh diff --git a/setup/omada-install.sh b/install/omada-install.sh similarity index 100% rename from setup/omada-install.sh rename to install/omada-install.sh diff --git a/setup/omv-install.sh b/install/omv-install.sh similarity index 100% rename from setup/omv-install.sh rename to install/omv-install.sh diff --git a/setup/openhab-install.sh b/install/openhab-install.sh similarity index 100% rename from setup/openhab-install.sh rename to install/openhab-install.sh diff --git a/setup/paperless-ngx-install.sh b/install/paperless-ngx-install.sh similarity index 100% rename from setup/paperless-ngx-install.sh rename to install/paperless-ngx-install.sh diff --git a/setup/photoprism-install.sh b/install/photoprism-install.sh similarity index 100% rename from setup/photoprism-install.sh rename to install/photoprism-install.sh diff --git a/setup/pihole-install.sh b/install/pihole-install.sh similarity index 100% rename from setup/pihole-install.sh rename to install/pihole-install.sh diff --git a/setup/plex-install.sh b/install/plex-install.sh similarity index 100% rename from setup/plex-install.sh rename to install/plex-install.sh diff --git a/setup/podman-homeassistant-install.sh b/install/podman-homeassistant-install.sh similarity index 100% rename from setup/podman-homeassistant-install.sh rename to install/podman-homeassistant-install.sh diff --git a/setup/podman-install.sh b/install/podman-install.sh similarity index 100% rename from setup/podman-install.sh rename to install/podman-install.sh diff --git a/setup/postgresql-install.sh b/install/postgresql-install.sh similarity index 100% rename from setup/postgresql-install.sh rename to install/postgresql-install.sh diff --git a/setup/prometheus-install.sh b/install/prometheus-install.sh similarity index 100% rename from setup/prometheus-install.sh rename to install/prometheus-install.sh diff --git a/setup/scrypted-install.sh b/install/scrypted-install.sh similarity index 100% rename from setup/scrypted-install.sh rename to install/scrypted-install.sh diff --git a/setup/shinobi-install.sh b/install/shinobi-install.sh similarity index 100% rename from setup/shinobi-install.sh rename to install/shinobi-install.sh diff --git a/setup/syncthing-install.sh b/install/syncthing-install.sh similarity index 100% rename from setup/syncthing-install.sh rename to install/syncthing-install.sh diff --git a/setup/technitiumdns-install.sh b/install/technitiumdns-install.sh similarity index 100% rename from setup/technitiumdns-install.sh rename to install/technitiumdns-install.sh diff --git a/setup/trilium-install.sh b/install/trilium-install.sh similarity index 100% rename from setup/trilium-install.sh rename to install/trilium-install.sh diff --git a/setup/ubuntu-install.sh b/install/ubuntu-install.sh similarity index 100% rename from setup/ubuntu-install.sh rename to install/ubuntu-install.sh diff --git a/setup/umbrel-install.sh b/install/umbrel-install.sh similarity index 100% rename from setup/umbrel-install.sh rename to install/umbrel-install.sh diff --git a/setup/unifi-install.sh b/install/unifi-install.sh similarity index 100% rename from setup/unifi-install.sh rename to install/unifi-install.sh diff --git a/setup/uptimekuma-install.sh b/install/uptimekuma-install.sh similarity index 100% rename from setup/uptimekuma-install.sh rename to install/uptimekuma-install.sh diff --git a/setup/vaultwarden-install.sh b/install/vaultwarden-install.sh similarity index 100% rename from setup/vaultwarden-install.sh rename to install/vaultwarden-install.sh diff --git a/setup/whoogle-install.sh b/install/whoogle-install.sh similarity index 100% rename from setup/whoogle-install.sh rename to install/whoogle-install.sh diff --git a/setup/wikijs-install.sh b/install/wikijs-install.sh similarity index 100% rename from setup/wikijs-install.sh rename to install/wikijs-install.sh diff --git a/setup/wireguard-install.sh b/install/wireguard-install.sh similarity index 100% rename from setup/wireguard-install.sh rename to install/wireguard-install.sh diff --git a/setup/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh similarity index 100% rename from setup/zigbee2mqtt-install.sh rename to install/zigbee2mqtt-install.sh diff --git a/setup/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh similarity index 100% rename from setup/zwave-js-ui-install.sh rename to install/zwave-js-ui-install.sh diff --git a/setup/adguard_setup.sh b/setup/adguard_setup.sh deleted file mode 100644 index bd48318d..00000000 --- a/setup/adguard_setup.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -y install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing AdGuard Home... \e[0m" -curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /adguard_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/debian11_setup.sh b/setup/debian11_setup.sh deleted file mode 100644 index e1cbf177..00000000 --- a/setup/debian11_setup.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /debian11_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/esphome_setup.sh b/setup/esphome_setup.sh deleted file mode 100644 index 001730f0..00000000 --- a/setup/esphome_setup.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing pip3... " -apt-get install python3-pip -y &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing ESPHome... " -pip3 install esphome &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing ESPHome Dashboard... " -pip3 install tornado esptool &>/dev/null - -service_path="/etc/systemd/system/esphomeDashboard.service" -echo "[Unit] -Description=ESPHome Dashboard -After=network.target -[Service] -ExecStart=/usr/local/bin/esphome /root/config/ dashboard -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path -systemctl enable esphomeDashboard.service &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -systemctl start esphomeDashboard -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf /esphome_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \r" diff --git a/setup/ha_setup.sh b/setup/ha_setup.sh deleted file mode 100644 index a97b62e8..00000000 --- a/setup/ha_setup.sh +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing pip3... \e[0m" -apt-get install -y python3-pip &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Docker... \e[0m" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF -sh <(curl -sSL https://get.docker.com) &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Pulling Portainer Image...\e[0m" -docker pull portainer/portainer-ce:latest &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Portainer... \e[0m" -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Pulling Home Assistant Image...\e[0m" -docker pull homeassistant/home-assistant:stable &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Home Assistant... \e[0m" -docker volume create hass_config >/dev/null -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Creating Update Menu Script... \e[0m" -pip3 install runlike &>/dev/null -UPDATE_PATH='/root/update' -UPDATE_CONTAINERS_PATH='/root/update-containers.sh' -cat >$UPDATE_PATH <<'EOF' -#!/bin/sh -set -o errexit -show_menu(){ - normal=`echo "\033[m"` - safe=`echo "\033[32m"` - menu=`echo "\033[36m"` - number=`echo "\033[33m"` - bgred=`echo "\033[41m"` - fgred=`echo "\033[31m"` - hostname -I - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" - printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" - printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" - printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" - printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" - printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" - printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" - printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" - printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" - printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" - read opt -} -option_picked(){ - msgcolor=`echo "\033[01;31m"` - normal=`echo "\033[00;00m"` - message=${@:-"${normal}Error: No message passed"} - printf "${msgcolor}${message}${normal}\n" -} -clear -show_menu -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - option_picked "Switching to Stable Branch"; - TAG=stable - break; - ;; - 2) clear; - option_picked "Switching to Beta Branch"; - TAG=beta - break; - ;; - 3) while true; do - read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Switching to Dev Branch"; - TAG=dev - break; - ;; - 4) clear; - option_picked "Backing up Home Assistant Data to root (hass_config)"; - rm -r hass_config; - cp -pR /var/lib/docker/volumes/hass_config/ /root/; - sleep 2; - clear; - show_menu; - ;; - 5) while true; do - read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Restoring Home Assistant Data from root (hass_config)"; - rm -r /var/lib/docker/volumes/hass_config/_data; - cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - sleep 2; - clear; - show_menu; - ;; - 6) while true; do - read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Editing Home Assistant Configuration"; - nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - clear; - show_menu; - ;; - 7) clear; - option_picked "Restarting Home Assistant"; - docker restart homeassistant; - exit; - ;; - 8) clear; - option_picked "Just Updating Containers"; - ./update-containers.sh; - sleep 2; - clear; - show_menu; - ;; - 9) clear; - option_picked "Removing Unused Images"; - docker image prune -af; - sleep 2; - clear; - show_menu; - ;; - 10) clear; - option_picked "Updating Host OS"; - apt update && apt upgrade -y; - sleep 2; - clear; - show_menu; - ;; - 11) clear; - option_picked "Reboot Host OS"; - reboot; - exit; - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose an option from the menu"; - show_menu; - ;; - esac - fi - done -docker pull homeassistant/home-assistant:$TAG -docker rm --force homeassistant -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:$TAG -EOF -sudo chmod +x /root/update -cat >$UPDATE_CONTAINERS_PATH <<'EOF' -#!/bin/bash -set -o errexit -CONTAINER_LIST="${1:-$(docker ps -q)}" -for container in ${CONTAINER_LIST}; do - CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" - RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" - docker pull "${CONTAINER_IMAGE}" - LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" - if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then - echo "Updating ${container} image ${CONTAINER_IMAGE}" - DOCKER_COMMAND="$(runlike "${container}")" - docker rm --force "${container}" - eval ${DOCKER_COMMAND} - fi -done -EOF -sudo chmod +x /root/update-containers.sh - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -mkdir /root/hass_config -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/jellyfin_setup.sh b/setup/jellyfin_setup.sh deleted file mode 100644 index 0f7a2549..00000000 --- a/setup/jellyfin_setup.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" - apt-get update &>/dev/null - apt-get -qqy install \ - curl \ - sudo &>/dev/null - sudo apt install apt-transport-https -y &>/dev/null - sudo apt-get install software-properties-common -y &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting Up Jellyfin Repository... \e[0m" -sudo add-apt-repository universe -y &>/dev/null -wget -q -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Jellyfin... \e[0m" -apt-get update &>/dev/null -sudo apt install jellyfin-server -y &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Creating Jellyfin Service... \e[0m" -cat << 'EOF' > /lib/systemd/system/jellyfin.service -[Unit] -Description = Jellyfin Media Server -After = network.target - -[Service] -Type = simple -EnvironmentFile = /etc/default/jellyfin -User = root -ExecStart = /usr/bin/jellyfin ${JELLYFIN_WEB_OPT} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELL> -Restart = on-failure -TimeoutSec = 15 - -[Install] -WantedBy = multi-user.target -EOF - -ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /jellyfin_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/mariadb_setup.sh b/setup/mariadb_setup.sh deleted file mode 100644 index b3d8b445..00000000 --- a/setup/mariadb_setup.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS}${RD} No Network! \r" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing MariaDB... " -curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null -apt-get update >/dev/null -apt-get install -y mariadb-server &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Adminer... " -sudo apt install adminer -y &>/dev/null -sudo a2enconf adminer &>/dev/null -sudo systemctl reload apache2 &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing Container... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf /mariadb_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* -mkdir /var/log/apache2 -echo -e "${CM}${CL} \r" diff --git a/setup/motioneye_setup.sh b/setup/motioneye_setup.sh deleted file mode 100644 index ee7a6301..00000000 --- a/setup/motioneye_setup.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" - sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen - locale-gen >/dev/null - while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi - done -echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" - apt-get update &>/dev/null - apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" - apt-get update &>/dev/null - apt-get -qqy install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Motion... \e[0m" - apt-get install motion -y &>/dev/null - systemctl stop motion &>/dev/null - systemctl disable motion &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing FFmpeg... \e[0m" - apt-get install ffmpeg v4l-utils -y &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get update &>/dev/null - apt-get install python2 -y &>/dev/null - curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null - python2 get-pip.py &>/dev/null - apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null - apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing MotionEye... \e[0m" - apt-get update &>/dev/null - sudo pip install motioneye &>/dev/null - mkdir -p /etc/motioneye - cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf - mkdir -p /var/lib/motioneye - -echo -e "${CHECKMARK} \e[1;92m Creating Service file motioneye.service... \e[0m" - cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat << EOF > $GETTY_OVERRIDE - [Service] - ExecStart= - ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - systemctl enable motioneye &>/dev/null - systemctl start motioneye - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" - rm -rf /motioneye_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/mqtt_setup.sh b/setup/mqtt_setup.sh deleted file mode 100644 index 13d42531..00000000 --- a/setup/mqtt_setup.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - gnupg \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Mosquitto MQTT Broker.. \e[0m" -wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null -apt-key add mosquitto-repo.gpg.key &>/dev/null -cd /etc/apt/sources.list.d/ -wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list &>/dev/null -apt-get update >/dev/null -apt-get -y install mosquitto &>/dev/null -apt-get -y install mosquitto-clients &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/node-red_setup.sh b/setup/node-red_setup.sh deleted file mode 100644 index def5d877..00000000 --- a/setup/node-red_setup.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Node-Red... \e[0m" -bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-root --confirm-install --skip-pi &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -systemctl start nodered.service &>/dev/null -systemctl enable nodered.service &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /node-red_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/npm_setup.sh b/setup/npm_setup.sh deleted file mode 100644 index c3917d44..00000000 --- a/setup/npm_setup.sh +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - sudo \ - curl \ - wget \ - gnupg \ - openssl \ - ca-certificates \ - apache2-utils \ - logrotate \ - build-essential \ - python3-dev \ - git \ - lsb-release &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Installing Python... \e[0m" - apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null - pip3 install --upgrade setuptools &>/dev/null - pip3 install --upgrade pip &>/dev/null - python3 -m venv /opt/certbot/ &>/dev/null - if [ "$(getconf LONG_BIT)" = "32" ]; then - python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null - fi - python3 -m pip install --no-cache-dir cffi certbot &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Openresty... \e[0m" -wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null -codename=`grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release` &>/dev/null -echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null -apt-get -y update &>/dev/null -apt-get -y install --no-install-recommends openresty &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Yarn... \e[0m" -npm install --global yarn &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Downloading NPM v2.9.16... \e[0m" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.16 -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-2.9.16 - -echo -e "${CHECKMARK} \e[1;92m Setting up Enviroment... \e[0m" -ln -sf /usr/bin/python3 /usr/bin/python -ln -sf /usr/bin/certbot /opt/certbot/bin/certbot -ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx -ln -sf /usr/local/openresty/nginx/ /etc/nginx - -sed -i "s+0.0.0+#v2.9.16+g" backend/package.json -sed -i "s+0.0.0+#v2.9.16+g" frontend/package.json - -sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf -NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") -for NGINX_CONF in $NGINX_CONFS; do - sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" -done - -mkdir -p /var/www/html /etc/nginx/logs -cp -r docker/rootfs/var/www/html/* /var/www/html/ -cp -r docker/rootfs/etc/nginx/* /etc/nginx/ -cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini -cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager -ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf -rm -f /etc/nginx/conf.d/dev.conf - -mkdir -p /tmp/nginx/body \ -/run/nginx \ -/data/nginx \ -/data/custom_ssl \ -/data/logs \ -/data/access \ -/data/nginx/default_host \ -/data/nginx/default_www \ -/data/nginx/proxy_host \ -/data/nginx/redirection_host \ -/data/nginx/stream \ -/data/nginx/dead_host \ -/data/nginx/temp \ -/var/lib/nginx/cache/public \ -/var/lib/nginx/cache/private \ -/var/cache/nginx/proxy_temp - -chmod -R 777 /var/cache/nginx -chown root /tmp/nginx - -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf - -if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null -fi - -mkdir -p /app/global /app/frontend/images -cp -r backend/* /app -cp -r global/* /app/global - -echo -e "${CHECKMARK} \e[1;92m Building Frontend... \e[0m" -cd ./frontend -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -yarn build &>/dev/null -cp -r dist/* /app/frontend -cp -r app-images/* /app/frontend/images - -echo -e "${CHECKMARK} \e[1;92m Initializing Backend... \e[0m" -rm -rf /app/config/default.json &>/dev/null -if [ ! -f /app/config/production.json ]; then -cat << 'EOF' > /app/config/production.json -{ - "database": { - "engine": "knex-native", - "knex": { - "client": "sqlite3", - "connection": { - "filename": "/data/database.sqlite" - } - } - } -} -EOF -fi -cd /app -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Creating NPM Service... \e[0m" -cat << 'EOF' > /lib/systemd/system/npm.service -[Unit] -Description=Nginx Proxy Manager -After=network.target -Wants=openresty.service - -[Service] -Type=simple -Environment=NODE_ENV=production -ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge -ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 -WorkingDirectory=/app -Restart=on-failure - -[Install] -WantedBy=multi-user.target -EOF - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Starting Services... \e[0m" -systemctl enable npm &>/dev/null -systemctl start openresty -systemctl start npm - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /npm_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/pihole_setup.sh b/setup/pihole_setup.sh deleted file mode 100644 index d6d7eb4e..00000000 --- a/setup/pihole_setup.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up LXC OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Pi-hole... \e[0m" -curl -sSL https://install.pi-hole.net | bash - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /pihole_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/plex_setup.sh b/setup/plex_setup.sh deleted file mode 100644 index 8d10d71a..00000000 --- a/setup/plex_setup.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - gnupg &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting Up Hardware Acceleration... \e[0m" -apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - -/bin/chgrp video /dev/dri -/bin/chmod 755 /dev/dri -/bin/chmod 660 /dev/dri/* - -echo -e "${CHECKMARK} \e[1;92m Setting Up Plex Media Server Repository... \e[0m" -wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null -echo "deb [arch=$( dpkg --print-architecture )] https://downloads.plex.tv/repo/deb/ public main" | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Installing Plex Media Server... \e[0m" -apt-get update &>/dev/null -apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /plex_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/podman_ha_setup.sh b/setup/podman_ha_setup.sh deleted file mode 100644 index 8cc8d414..00000000 --- a/setup/podman_ha_setup.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM - -echo -en "${GN} Setting up Container OS... " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -echo -e "${CM}${CL} \r" -echo -en "${GN} Network Connected: ${BL}$(hostname -I)${CL} " -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Container OS... " -apt update &>/dev/null -apt-get -qqy upgrade &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Dependencies... " -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - runc &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Podman... " -apt-get -y install podman &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Pulling Yacht Image... " -podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Yacht... " -podman volume create yacht >/dev/null -podman run -d \ - --privileged \ - --name yacht \ - --restart always \ - -v /var/run/podman/podman.sock:/var/run/docker.sock \ - -v yacht:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - -p 8000:8000 \ - selfhostedpro/yacht:latest &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Pulling Home Assistant Image... " -podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Installing Home Assistant... " -podman volume create hass_config >/dev/null -podman run -d \ - --privileged \ - --name homeassistant \ - --restart unless-stopped \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Creating Update Script... " -file_path="/root/update.sh" -echo "#!/bin/bash -echo -e '\e[1;33m Pulling New Stable Version... \e[0m' -podman pull docker.io/homeassistant/home-assistant:stable -echo -e '\e[1;33m Stopping Home Assistant... \e[0m' -podman stop homeassistant -echo -e '\e[1;33m Removing Home Assistant... \e[0m' -podman rm homeassistant -echo -e '\e[1;33m Starting Home Assistant... \e[0m' -podman run -d \ - --name homeassistant \ - --restart unless-stopped \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:stable -echo -e '\e[1;33m Removing Old Image... \e[0m' -podman image prune -f -echo -e '\e[1;33m Finished Update! \e[0m'" > $file_path -sudo chmod +x /root/update.sh -echo -e "${CM}${CL} \r" - -echo -en "${GN} Customizing LXC... " -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -podman generate systemd \ - --new --name homeassistant \ - > /etc/systemd/system/homeassistant.service -systemctl enable homeassistant &>/dev/null - -podman generate systemd \ - --new --name yacht \ - > /etc/systemd/system/yacht.service -systemctl enable yacht &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -rm -rf /podman_ha_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* -echo -e "${CM}${CL} \n" diff --git a/setup/ubuntu_setup.sh b/setup/ubuntu_setup.sh deleted file mode 100644 index ea116c5b..00000000 --- a/setup/ubuntu_setup.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -chmod -x /etc/update-motd.d/* -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /ubuntu_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/vault_setup.sh b/setup/vault_setup.sh deleted file mode 100644 index 57f2117c..00000000 --- a/setup/vault_setup.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RD=`echo "\033[01;31m"` -BL=`echo "\033[36m"` -CM='\xE2\x9C\x94\033' -GN=`echo "\033[1;92m"` -CL=`echo "\033[m"` -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - git \ - nano \ - wget \ - htop \ - pkg-config \ - openssl \ - libssl1.1 \ - libssl-dev \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Build Essentials... \e[0m" -apt-get install -y build-essential &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Rust... \e[0m" -curl https://sh.rustup.rs -sSf | sh -s -- -y &>/dev/null -echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc &>/dev/null -export PATH=~/.cargo/bin:$PATH &>/dev/null -which rustc &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" -curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -apt-get install -y nodejs &>/dev/null -npm -g install npm@7 &>/dev/null -which npm &>/dev/null -npm i npm@latest -g &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Building Vaultwarden (Patience)... \e[0m" -git clone https://github.com/dani-garcia/vaultwarden &>/dev/null -pushd vaultwarden &>/dev/null -cargo clean &>/dev/null -cargo build --features sqlite --release &>/dev/null -file target/release/vaultwarden &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Building Web-Vault... \e[0m" -pushd target/release/ &>/dev/null -git clone --recurse-submodules https://github.com/bitwarden/web.git web-vault.git &>/dev/null -cd web-vault.git &>/dev/null -git checkout v2.25.1 &>/dev/null -git submodule update --init --recursive &>/dev/null -wget https://raw.githubusercontent.com/dani-garcia/bw_web_builds/master/patches/v2.25.0.patch &>/dev/null -git apply v2.25.0.patch &>/dev/null -npm ci --silent --legacy-peer-deps &>/dev/null -npm audit fix --silent --legacy-peer-deps || true &>/dev/null -npm run --silent dist:oss:selfhost &>/dev/null -cp -a build ../web-vault &>/dev/null -cd .. -mkdir data - -echo -e "${CHECKMARK} \e[1;92m Create Systemd Service... \e[0m" -cp ../../.env.template /etc/vaultwarden.env &>/dev/null -cp vaultwarden /usr/bin/vaultwarden &>/dev/null -chmod +x /usr/bin/vaultwarden &>/dev/null -useradd -m -d /var/lib/vaultwarden vaultwarden &>/dev/null -sudo cp -R data /var/lib/vaultwarden/ &>/dev/null -cp -R web-vault /var/lib/vaultwarden/ &>/dev/null -chown -R vaultwarden:vaultwarden /var/lib/vaultwarden &>/dev/null - -service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null - -echo "[Unit] -Description=Bitwarden Server (Powered by Vaultwarden) -Documentation=https://github.com/dani-garcia/vaultwarden - -After=network.target - -[Service] -User=vaultwarden -Group=vaultwarden -EnvironmentFile=/etc/vaultwarden.env -ExecStart=/usr/bin/vaultwarden -LimitNOFILE=1048576 -LimitNPROC=64 -PrivateTmp=true -PrivateDevices=true -ProtectHome=true -ProtectSystem=strict -WorkingDirectory=/var/lib/vaultwarden -ReadWriteDirectories=/var/lib/vaultwarden -AmbientCapabilities=CAP_NET_BIND_SERVICE - -[Install] -WantedBy=multi-user.target" > $service_path - -echo -e "${CHECKMARK} \e[1;92m Customizing Container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -systemctl enable vaultwarden.service &>/dev/null -systemctl start vaultwarden.service &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /vault_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/zigbee2mqtt_setup.sh b/setup/zigbee2mqtt_setup.sh deleted file mode 100644 index d0ce0c01..00000000 --- a/setup/zigbee2mqtt_setup.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Dependencies... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" -sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Setting up Zigbee2MQTT Repository... \e[0m" -sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Zigbee2MQTT... \e[0m" -cd /opt/zigbee2mqtt &>/dev/null -npm ci &>/dev/null - -service_path="/etc/systemd/system/zigbee2mqtt.service" -echo "[Unit] -Description=zigbee2mqtt -After=network.target -[Service] -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zigbee2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path - -echo -e "${CHECKMARK} \e[1;92m Customizing LXC... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') -systemctl enable zigbee2mqtt.service &>/dev/null -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /zigbee2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* diff --git a/setup/zwavejs2mqtt_setup.sh b/setup/zwavejs2mqtt_setup.sh deleted file mode 100644 index b4cdd610..00000000 --- a/setup/zwavejs2mqtt_setup.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -CROSS='\033[1;31m\xE2\x9D\x8C\033[0m' -CHECKMARK='\033[0;32m\xE2\x9C\x94\033[0m' -RETRY_NUM=5 -RETRY_EVERY=3 -NUM=$RETRY_NUM -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -echo -e "${CHECKMARK} \e[1;92m Setting up Container OS... \e[0m" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - 1>&2 echo -e "${CROSS} \e[1;31m No Network: \e[0m $(date)" - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ] - then - 1>&2 echo -e "${CROSS} \e[1;31m No Network After $RETRY_NUM Tries \e[0m" - exit 1 - fi -done - echo -e "${CHECKMARK} \e[1;92m Network Connected: \e[0m $(hostname -I)" - -echo -e "${CHECKMARK} \e[1;92m Updating Container OS... \e[0m" -apt-get update &>/dev/null -apt-get -qqy upgrade &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Installing Prerequisites... \e[0m" -apt-get update &>/dev/null -apt-get -qqy install \ - curl \ - sudo \ - unzip &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Setting up Node.js Repository... \e[0m" - sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Installing Node.js... \e[0m" - sudo apt-get install -y nodejs git make g++ gcc &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Installing yarn... \e[0m" - npm install --global yarn &>/dev/null - - echo -e "${CHECKMARK} \e[1;92m Build/Install Zwavejs2MQTT (5-6 min)... \e[0m" - sudo git clone https://github.com/zwave-js/zwavejs2mqtt /opt/zwavejs2mqtt &>/dev/null - cd /opt/zwavejs2mqtt &>/dev/null - yarn install &>/dev/null - yarn run build &>/dev/null - -echo -e "${CHECKMARK} \e[1;92m Creating Service file zwavejs2mqtt.service... \e[0m" -service_path="/etc/systemd/system/zwavejs2mqtt.service" - -echo "[Unit] -Description=zwavejs2mqtt -After=network.target -[Service] -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zwavejs2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" > $service_path - -echo -e "${CHECKMARK} \e[1;92m Customizing container... \e[0m" -rm /etc/motd -rm /etc/update-motd.d/10-uname -touch ~/.hushlogin -GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" -mkdir -p $(dirname $GETTY_OVERRIDE) -cat << EOF > $GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF -systemctl daemon-reload -systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - -echo -e "${CHECKMARK} \e[1;92m Cleanup... \e[0m" -rm -rf /zwavejs2mqtt_setup.sh /var/{cache,log}/* /var/lib/apt/lists/* -systemctl start zwavejs2mqtt -systemctl enable zwavejs2mqtt &>/dev/null From a6dc675d2316a1a855a141d59d691c209b419f9e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:08:44 -0500 Subject: [PATCH 3894/6505] Create docker-v5.sh --- ct/docker-v5.sh | 382 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 ct/docker-v5.sh diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh new file mode 100644 index 00000000..363e6a7b --- /dev/null +++ b/ct/docker-v5.sh @@ -0,0 +1,382 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \____ _____/ /_v5__ _____ + / / / / __ \/ ___/ //_/ _ \/ ___/ + / /_/ / /_/ / /__/ ,< / __/ / +/_____/\____/\___/_/|_|\___/_/ + +EOF +} +echo -e "Loading..." +APP="Docker" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/docker ]]; then + msg_error "No Docker Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Updating Docker LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Docker LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" +else +FEATURES="keyctl=1,nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export ST=$FUSE +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$CT_TYPE" == "0" ]; then +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/setup/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From b00184759ba75d2a670a5ef7a58da5aaff8230d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:10:34 -0500 Subject: [PATCH 3895/6505] Create docker-v5-install.sh --- install/docker-v5-install.sh | 175 +++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 install/docker-v5-install.sh diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh new file mode 100644 index 00000000..82cd8d7f --- /dev/null +++ b/install/docker-v5-install.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") +DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") + +msg_info "Installing Docker $DOCKER_LATEST_VERSION" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +fi +$STD sh <(curl -sSL https://get.docker.com) +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" + +read -r -p "Would you like to add Portainer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + PORTAINER="Y" +else + PORTAINER="N" +fi + +if [[ $PORTAINER == "Y" ]]; then + msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" + docker volume create portainer_data >/dev/null + $STD docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest + msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" +fi + +read -r -p "Would you like to add Docker Compose? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + DOCKER_COMPOSE="Y" +else + DOCKER_COMPOSE="N" +fi + +if [[ $DOCKER_COMPOSE == "Y" ]]; then + msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} + mkdir -p $DOCKER_CONFIG/cli-plugins + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose + chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose + msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" +fi + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From bedfb91fdc429a2eac9eae9f1cbb5cde9b548530 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:11:48 -0500 Subject: [PATCH 3896/6505] Update docker-v5.sh --- ct/docker-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 363e6a7b..04c639dc 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -374,7 +374,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/setup/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ From 58d471c8b2de8eb0eccd33139afebeb2bb0523e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:15:08 -0500 Subject: [PATCH 3897/6505] Create homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 413 ++++++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 ct/homeassistant-core-v5.sh diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh new file mode 100644 index 00000000..76ff5b92 --- /dev/null +++ b/ct/homeassistant-core-v5.sh @@ -0,0 +1,413 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ _ _ _ ___ + /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___v5_ __ ___ + / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ +/ __ / (_) | | | | | | __/ / _ \__ \__ \ \__ \ || (_| | | | | |_ / /__| (_) | | | __/ +\/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| + +EOF +} +echo -e "Loading..." +APP="Home Assistant-Core" +var_disk="8" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') +BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + msg_error "This script requires Proxmox Virtual Environment 7.0 or greater" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /srv/homeassistant ]]; then + msg_error "No Home Assistant Core Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC to ${STABLE} Or, Beta to ${BETA}. Proceed?" 10 58); then + echo "User selected Yes" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { + PY=$(ls /srv/homeassistant/lib/) + IP=$(hostname -I | awk '{print $1}') + if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then + clear + header_info + echo -e "${GN}Updating to Version ${BETA}${CL}" + BR="--pre " + else + clear + header_info + echo -e "${GN}Updating to Version ${STABLE}${CL}" + BR="" + fi + if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi + +msg_info "Stopping Home Assistant" +systemctl stop homeassistant +msg_ok "Stopped Home Assistant" + +msg_info "Updating Home Assistant" +source /srv/homeassistant/bin/activate +pip install ${BR}--upgrade homeassistant &>/dev/null +msg_ok "Updated Home Assistant" + +msg_info "Setting Dependency Versions" +if [ "${BR}" == "--pre " ]; then +sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +else +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json +fi +sleep 2 +msg_ok "Set Dependency Versions" + +msg_info "Starting Home Assistant" +systemctl start homeassistant +sleep 2 +msg_ok "Started Home Assistant" +msg_ok "Update Successful" +echo -e "\n Go to http://${IP}:8123 \n" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable (after it's initialized) by going to the following URL. + ${BL}http://${IP}:8123${CL}" From a3a63d929876d2ac8961c5350b06eae0e4475ef4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:16:43 -0500 Subject: [PATCH 3898/6505] Create homeassistant-core-v5-install.sh --- install/homeassistant-core-v5-install.sh | 195 +++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 install/homeassistant-core-v5-install.sh diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh new file mode 100644 index 00000000..1ee82a65 --- /dev/null +++ b/install/homeassistant-core-v5-install.sh @@ -0,0 +1,195 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y \ + make \ + build-essential \ + libjpeg-dev \ + libpcap-dev \ + libssl-dev \ + zlib1g-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + libmariadb-dev-compat \ + autoconf \ + git \ + curl \ + sudo \ + llvm \ + libncursesw5-dev \ + xz-utils \ + tzdata \ + bluez \ + tk-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libffi-dev \ + libopenjp2-7 \ + libtiff5 \ + libturbojpeg0-dev \ + liblzma-dev +msg_ok "Installed Dependencies" + +msg_info "Installing Linux D-Bus Message Broker" +cat <>/etc/apt/sources.list +deb http://deb.debian.org/debian bullseye-backports main contrib non-free +deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free +EOF +$STD apt-get update +$STD apt-get -t bullseye-backports install -y dbus-broker +$STD systemctl enable --now dbus-broker.service +msg_ok "Installed Linux D-Bus Message Broker" + +msg_info "Installing pyenv" +$STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv +set +e +echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc +echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc +echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc +msg_ok "Installed pyenv" +. ~/.bashrc +set -e +msg_info "Installing Python 3.10.8" +$STD pyenv install 3.10.8 +pyenv global 3.10.8 +msg_ok "Installed Python 3.10.8" + +msg_info "Installing Home Assistant-Core" +mkdir /srv/homeassistant +cd /srv/homeassistant +python3 -m venv . +source bin/activate +$STD pip install --upgrade pip +$STD python3 -m pip install wheel +$STD pip install mysqlclient +$STD pip install psycopg2-binary +$STD pip install homeassistant +msg_ok "Installed Home Assistant-Core" + +# fix for inconsistent versions, hopefully the HA team will get this fixed +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt +sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json + +msg_info "Creating Service" +cat </etc/systemd/system/homeassistant.service +[Unit] +Description=Home Assistant +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/root/.homeassistant +ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" +RestartForceExitStatus=100 +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable homeassistant +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 8e17349c672a9b10875101cce7b94770f4d9efc8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:19:11 -0500 Subject: [PATCH 3899/6505] Create photoprism-v5.sh --- ct/photoprism-v5.sh | 384 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 ct/photoprism-v5.sh diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh new file mode 100644 index 00000000..398908b6 --- /dev/null +++ b/ct/photoprism-v5.sh @@ -0,0 +1,384 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ ______ __________ ____ ____ _________ __ ___ + / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / + / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / + / ____/ __ / /_/ / / / / /_/ / ____/ _, _// / v5_/ / / / / +/_/ /_/ /_/\____/ /_/ \____/_/ /_/ |_/___//____/_/ /_/ + +EOF +} +echo -e "Loading..." +APP="PhotoPrism" +var_disk="8" +var_cpu="2" +var_ram="3072" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/photoprism ]]; then + msg_error "No PhotoPrism Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" +msg_info "Stopping PhotoPrism" +sudo systemctl stop photoprism +msg_ok "Stopped PhotoPrism" + +msg_info "Cloning PhotoPrism" +git clone https://github.com/photoprism/photoprism.git &>/dev/null +cd photoprism +git checkout release &>/dev/null +msg_ok "Cloned PhotoPrism" + +msg_info "Building PhotoPrism" +sudo make all &>/dev/null +sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null +sudo rm -rf /opt/photoprism/assets +sudo cp -r assets/ /opt/photoprism/ &>/dev/null +msg_ok "Built PhotoPrism" + +msg_info "Cleaning" +cd ~ +rm -rf photoprism +msg_ok "Cleaned" + +msg_info "Starting PhotoPrism" +sudo systemctl start photoprism +msg_ok "Started PhotoPrism" +msg_ok "Update Successful" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 2048 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:2342${CL} \n" From 620965e14b48008471f993e0b35e812dc4dd6f87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:21:05 -0500 Subject: [PATCH 3900/6505] Create photoprism-v5-install.sh --- photoprism-v5-install.sh | 220 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 photoprism-v5-install.sh diff --git a/photoprism-v5-install.sh b/photoprism-v5-install.sh new file mode 100644 index 00000000..384c0074 --- /dev/null +++ b/photoprism-v5-install.sh @@ -0,0 +1,220 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gcc +$STD apt-get install -y g++ +$STD apt-get install -y git +$STD apt-get install -y gnupg +$STD apt-get install -y make +$STD apt-get install -y zip +$STD apt-get install -y unzip +$STD apt-get install -y exiftool +$STD apt-get install -y ffmpeg +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +wget -qL https://deb.nodesource.com/setup_18.x +$STD bash setup_18.x +rm setup_18.x +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get -y install nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Golang (Patience)" +$STD wget https://golang.org/dl/go1.19.3.linux-amd64.tar.gz +$STD tar -xzf go1.19.3.linux-amd64.tar.gz -C /usr/local +$STD ln -s /usr/local/go/bin/go /usr/local/bin/go +$STD go install github.com/tianon/gosu@latest +$STD go install golang.org/x/tools/cmd/goimports@latest +$STD go install github.com/psampaz/go-mod-outdated@latest +$STD go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest +$STD go install github.com/mikefarah/yq/v4@latest +$STD go install github.com/kyoh86/richgo@latest +cp /root/go/bin/* /usr/local/go/bin/ +cp /usr/local/go/bin/richgo /usr/local/bin/richgo +cp /usr/local/go/bin/gosu /usr/local/sbin/gosu +chown root:root /usr/local/sbin/gosu +chmod 755 /usr/local/sbin/gosu +msg_ok "Installed Golang" + +msg_info "Installing Tensorflow" +if [[ "$AVX" =~ avx2 ]]; then + $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz + $STD tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz +elif [[ "$AVX" =~ avx ]]; then + $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz + $STD tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz +else + $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz + $STD tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz +fi +$STD ldconfig +msg_ok "Installed Tensorflow" + +msg_info "Cloning PhotoPrism" +mkdir -p /opt/photoprism/bin +mkdir -p /var/lib/photoprism/storage +$STD git clone https://github.com/photoprism/photoprism.git +cd photoprism +$STD git checkout release +msg_ok "Cloned PhotoPrism" + +msg_info "Building PhotoPrism (Patience)" +$STD make -B +$STD ./scripts/build.sh prod /opt/photoprism/bin/photoprism +$STD cp -r assets/ /opt/photoprism/ +msg_ok "Built PhotoPrism" + +env_path="/var/lib/photoprism/.env" +echo " +PHOTOPRISM_AUTH_MODE='password' +PHOTOPRISM_ADMIN_PASSWORD='changeme' +PHOTOPRISM_HTTP_HOST='0.0.0.0' +PHOTOPRISM_HTTP_PORT='2342' +PHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/' +PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' +PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' +PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' +" >$env_path + +msg_info "Creating Service" +service_path="/etc/systemd/system/photoprism.service" + +echo "[Unit] +Description=PhotoPrism service +After=network.target + +[Service] +Type=forking +User=root +WorkingDirectory=/opt/photoprism +EnvironmentFile=/var/lib/photoprism/.env +ExecStart=/opt/photoprism/bin/photoprism up -d +ExecStop=/opt/photoprism/bin/photoprism down + +[Install] +WantedBy=multi-user.target" >$service_path +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /var/{cache,log}/* \ + /photoprism \ + /go1.19.3.linux-amd64.tar.gz \ + /libtensorflow-linux-avx2-1.15.2.tar.gz \ + /libtensorflow-linux-avx-1.15.2.tar.gz \ + /libtensorflow-linux-cpu-1.15.2.tar.gz +msg_ok "Cleaned" + +msg_info "Starting PhotoPrism" +$STD systemctl enable --now photoprism +msg_ok "Started PhotoPrism" From 8b455d7b16b032da11cef54e17ce7588cda1c1ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:22:38 -0500 Subject: [PATCH 3901/6505] Create vaultwarden-v5.sh --- ct/vaultwarden-v5.sh | 422 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 422 insertions(+) create mode 100644 ct/vaultwarden-v5.sh diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh new file mode 100644 index 00000000..fb314d38 --- /dev/null +++ b/ct/vaultwarden-v5.sh @@ -0,0 +1,422 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ __ ____ _ __ __ +| | / /___ ___v5__/ / /| | / /___ __________/ /__ ____ +| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ +| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / +|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ + +EOF +} +echo -e "Loading..." +APP="Vaultwarden" +var_disk="6" +var_cpu="2" +var_ram="3072" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/vaultwarden ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP}. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') +WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') + +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "VaultWarden $VAULT" ON \ + "2" "Web-Vault $WVRELEASE" OFF \ + 3>&1 1>&2 2>&3) + +clear +header_info +echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" +if [ "$UPD" == "1" ]; then +msg_info "Stopping Vaultwarden" +systemctl stop vaultwarden.service +msg_ok "Stopped Vaultwarden" + +msg_info "Updating VaultWarden to $VAULT (Patience)" +git clone https://github.com/dani-garcia/vaultwarden &>/dev/null +cd vaultwarden +cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null +DIR=/usr/bin/vaultwarden + if [ -d "$DIR" ]; then + cp target/release/vaultwarden /usr/bin/ + else + cp target/release/vaultwarden /opt/vaultwarden/bin/ + fi +msg_ok "Updated VaultWarden" + +msg_info "Cleaning up" +cd ~ && rm -rf vaultwarden +msg_ok "Cleaned" + +msg_info "Starting Vaultwarden" +systemctl start vaultwarden.service +msg_ok "Started Vaultwarden" + +msg_ok "$VAULT Update Successful" +echo -e "\n ⚠️ Ensure you set resources back to normal settings \n" +exit; +fi +if [ "$UPD" == "2" ]; then + +msg_info "Stopping Vaultwarden" +systemctl stop vaultwarden.service +msg_ok "Stopped Vaultwarden" + +msg_info "Updating Web-Vault to $WVRELEASE" +curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WVRELEASE/bw_web_$WVRELEASE.tar.gz &>/dev/null +tar -zxf bw_web_$WVRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null +msg_ok "Updated Web-Vault" + +msg_info "Cleaning up" +rm bw_web_$WVRELEASE.tar.gz +msg_ok "Cleaned" + +msg_info "Starting Vaultwarden" +systemctl start vaultwarden.service +msg_ok "Started Vaultwarden" +msg_ok "$WVRELEASE Update Successful" +exit; +fi +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 512 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From f23d3e7088e36ac32f0c3510c75b4fc012cc77ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:24:33 -0500 Subject: [PATCH 3902/6505] Create vaultwarden-v5-install.sh --- install/vaultwarden-v5-install.sh | 204 ++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 install/vaultwarden-v5-install.sh diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh new file mode 100644 index 00000000..510d78c1 --- /dev/null +++ b/install/vaultwarden-v5-install.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get update +$STD apt-get -qqy install \ + git \ + build-essential \ + pkgconf \ + libssl-dev \ + libmariadb-dev-compat \ + libpq-dev \ + curl \ + sudo +msg_ok "Installed Dependencies" + +WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') + +VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') + +msg_info "Installing Rust" +wget -qL https://sh.rustup.rs +$STD bash index.html -y --profile minimal +echo 'export PATH=~/.cargo/bin:$PATH' >>~/.bashrc +export PATH=~/.cargo/bin:$PATH +rm index.html +msg_ok "Installed Rust" + +msg_info "Building Vaultwarden ${VAULT} (Patience)" +$STD git clone https://github.com/dani-garcia/vaultwarden +cd vaultwarden +$STD cargo build --features "sqlite,mysql,postgresql" --release +msg_ok "Built Vaultwarden ${VAULT}" + +$STD addgroup --system vaultwarden +$STD adduser --system --home /opt/vaultwarden --shell /usr/sbin/nologin --no-create-home --gecos 'vaultwarden' --ingroup vaultwarden --disabled-login --disabled-password vaultwarden +mkdir -p /opt/vaultwarden/bin +mkdir -p /opt/vaultwarden/data +cp target/release/vaultwarden /opt/vaultwarden/bin/ + +msg_info "Downloading Web-Vault ${WEBVAULT}" +$STD curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz +$STD tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ +msg_ok "Downloaded Web-Vault ${WEBVAULT}" + +cat </opt/vaultwarden/.env +ADMIN_TOKEN=$(openssl rand -base64 48) +ROCKET_ADDRESS=0.0.0.0 +DATA_FOLDER=/opt/vaultwarden/data +DATABASE_MAX_CONNS=10 +WEB_VAULT_FOLDER=/opt/vaultwarden/web-vault +WEB_VAULT_ENABLED=true +EOF + +msg_info "Creating Service" +chown -R vaultwarden:vaultwarden /opt/vaultwarden/ +chown root:root /opt/vaultwarden/bin/vaultwarden +chmod +x /opt/vaultwarden/bin/vaultwarden +chown -R root:root /opt/vaultwarden/web-vault/ +chmod +r /opt/vaultwarden/.env + +service_path="/etc/systemd/system/vaultwarden.service" +echo "[Unit] +Description=Bitwarden Server (Powered by Vaultwarden) +Documentation=https://github.com/dani-garcia/vaultwarden +After=network.target +[Service] +User=vaultwarden +Group=vaultwarden +EnvironmentFile=-/opt/vaultwarden/.env +ExecStart=/opt/vaultwarden/bin/vaultwarden +LimitNOFILE=65535 +LimitNPROC=4096 +PrivateTmp=true +PrivateDevices=true +ProtectHome=true +ProtectSystem=strict +DevicePolicy=closed +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictNamespaces=yes +RestrictRealtime=yes +MemoryDenyWriteExecute=yes +LockPersonality=yes +WorkingDirectory=/opt/vaultwarden +ReadWriteDirectories=/opt/vaultwarden/data +AmbientCapabilities=CAP_NET_BIND_SERVICE +[Install] +WantedBy=multi-user.target" >$service_path +systemctl daemon-reload +$STD systemctl enable --now vaultwarden.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 3a858e4b29a31defce2d8918602b67f6f5863c85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:26:38 -0500 Subject: [PATCH 3903/6505] Delete photoprism-v5-install.sh --- photoprism-v5-install.sh | 220 --------------------------------------- 1 file changed, 220 deletions(-) delete mode 100644 photoprism-v5-install.sh diff --git a/photoprism-v5-install.sh b/photoprism-v5-install.sh deleted file mode 100644 index 384c0074..00000000 --- a/photoprism-v5-install.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -silent() { "$@" > /dev/null 2>&1; } -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y gcc -$STD apt-get install -y g++ -$STD apt-get install -y git -$STD apt-get install -y gnupg -$STD apt-get install -y make -$STD apt-get install -y zip -$STD apt-get install -y unzip -$STD apt-get install -y exiftool -$STD apt-get install -y ffmpeg -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -wget -qL https://deb.nodesource.com/setup_18.x -$STD bash setup_18.x -rm setup_18.x -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get -y install nodejs -msg_ok "Installed Node.js" - -msg_info "Installing Golang (Patience)" -$STD wget https://golang.org/dl/go1.19.3.linux-amd64.tar.gz -$STD tar -xzf go1.19.3.linux-amd64.tar.gz -C /usr/local -$STD ln -s /usr/local/go/bin/go /usr/local/bin/go -$STD go install github.com/tianon/gosu@latest -$STD go install golang.org/x/tools/cmd/goimports@latest -$STD go install github.com/psampaz/go-mod-outdated@latest -$STD go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest -$STD go install github.com/mikefarah/yq/v4@latest -$STD go install github.com/kyoh86/richgo@latest -cp /root/go/bin/* /usr/local/go/bin/ -cp /usr/local/go/bin/richgo /usr/local/bin/richgo -cp /usr/local/go/bin/gosu /usr/local/sbin/gosu -chown root:root /usr/local/sbin/gosu -chmod 755 /usr/local/sbin/gosu -msg_ok "Installed Golang" - -msg_info "Installing Tensorflow" -if [[ "$AVX" =~ avx2 ]]; then - $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz - $STD tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz -elif [[ "$AVX" =~ avx ]]; then - $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz - $STD tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz -else - $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz - $STD tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz -fi -$STD ldconfig -msg_ok "Installed Tensorflow" - -msg_info "Cloning PhotoPrism" -mkdir -p /opt/photoprism/bin -mkdir -p /var/lib/photoprism/storage -$STD git clone https://github.com/photoprism/photoprism.git -cd photoprism -$STD git checkout release -msg_ok "Cloned PhotoPrism" - -msg_info "Building PhotoPrism (Patience)" -$STD make -B -$STD ./scripts/build.sh prod /opt/photoprism/bin/photoprism -$STD cp -r assets/ /opt/photoprism/ -msg_ok "Built PhotoPrism" - -env_path="/var/lib/photoprism/.env" -echo " -PHOTOPRISM_AUTH_MODE='password' -PHOTOPRISM_ADMIN_PASSWORD='changeme' -PHOTOPRISM_HTTP_HOST='0.0.0.0' -PHOTOPRISM_HTTP_PORT='2342' -PHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/' -PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' -PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' -PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -" >$env_path - -msg_info "Creating Service" -service_path="/etc/systemd/system/photoprism.service" - -echo "[Unit] -Description=PhotoPrism service -After=network.target - -[Service] -Type=forking -User=root -WorkingDirectory=/opt/photoprism -EnvironmentFile=/var/lib/photoprism/.env -ExecStart=/opt/photoprism/bin/photoprism up -d -ExecStop=/opt/photoprism/bin/photoprism down - -[Install] -WantedBy=multi-user.target" >$service_path -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -rm -rf /var/{cache,log}/* \ - /photoprism \ - /go1.19.3.linux-amd64.tar.gz \ - /libtensorflow-linux-avx2-1.15.2.tar.gz \ - /libtensorflow-linux-avx-1.15.2.tar.gz \ - /libtensorflow-linux-cpu-1.15.2.tar.gz -msg_ok "Cleaned" - -msg_info "Starting PhotoPrism" -$STD systemctl enable --now photoprism -msg_ok "Started PhotoPrism" From 14dcfe29f6b6ad98f52238bc03b1ad904e046f0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 11:27:25 -0500 Subject: [PATCH 3904/6505] Create photoprism-v5-install.sh --- install/photoprism-v5-install.sh | 220 +++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 install/photoprism-v5-install.sh diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh new file mode 100644 index 00000000..384c0074 --- /dev/null +++ b/install/photoprism-v5-install.sh @@ -0,0 +1,220 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gcc +$STD apt-get install -y g++ +$STD apt-get install -y git +$STD apt-get install -y gnupg +$STD apt-get install -y make +$STD apt-get install -y zip +$STD apt-get install -y unzip +$STD apt-get install -y exiftool +$STD apt-get install -y ffmpeg +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +wget -qL https://deb.nodesource.com/setup_18.x +$STD bash setup_18.x +rm setup_18.x +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get -y install nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Golang (Patience)" +$STD wget https://golang.org/dl/go1.19.3.linux-amd64.tar.gz +$STD tar -xzf go1.19.3.linux-amd64.tar.gz -C /usr/local +$STD ln -s /usr/local/go/bin/go /usr/local/bin/go +$STD go install github.com/tianon/gosu@latest +$STD go install golang.org/x/tools/cmd/goimports@latest +$STD go install github.com/psampaz/go-mod-outdated@latest +$STD go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest +$STD go install github.com/mikefarah/yq/v4@latest +$STD go install github.com/kyoh86/richgo@latest +cp /root/go/bin/* /usr/local/go/bin/ +cp /usr/local/go/bin/richgo /usr/local/bin/richgo +cp /usr/local/go/bin/gosu /usr/local/sbin/gosu +chown root:root /usr/local/sbin/gosu +chmod 755 /usr/local/sbin/gosu +msg_ok "Installed Golang" + +msg_info "Installing Tensorflow" +if [[ "$AVX" =~ avx2 ]]; then + $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz + $STD tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz +elif [[ "$AVX" =~ avx ]]; then + $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz + $STD tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz +else + $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz + $STD tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz +fi +$STD ldconfig +msg_ok "Installed Tensorflow" + +msg_info "Cloning PhotoPrism" +mkdir -p /opt/photoprism/bin +mkdir -p /var/lib/photoprism/storage +$STD git clone https://github.com/photoprism/photoprism.git +cd photoprism +$STD git checkout release +msg_ok "Cloned PhotoPrism" + +msg_info "Building PhotoPrism (Patience)" +$STD make -B +$STD ./scripts/build.sh prod /opt/photoprism/bin/photoprism +$STD cp -r assets/ /opt/photoprism/ +msg_ok "Built PhotoPrism" + +env_path="/var/lib/photoprism/.env" +echo " +PHOTOPRISM_AUTH_MODE='password' +PHOTOPRISM_ADMIN_PASSWORD='changeme' +PHOTOPRISM_HTTP_HOST='0.0.0.0' +PHOTOPRISM_HTTP_PORT='2342' +PHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/' +PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' +PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' +PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' +" >$env_path + +msg_info "Creating Service" +service_path="/etc/systemd/system/photoprism.service" + +echo "[Unit] +Description=PhotoPrism service +After=network.target + +[Service] +Type=forking +User=root +WorkingDirectory=/opt/photoprism +EnvironmentFile=/var/lib/photoprism/.env +ExecStart=/opt/photoprism/bin/photoprism up -d +ExecStop=/opt/photoprism/bin/photoprism down + +[Install] +WantedBy=multi-user.target" >$service_path +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /var/{cache,log}/* \ + /photoprism \ + /go1.19.3.linux-amd64.tar.gz \ + /libtensorflow-linux-avx2-1.15.2.tar.gz \ + /libtensorflow-linux-avx-1.15.2.tar.gz \ + /libtensorflow-linux-cpu-1.15.2.tar.gz +msg_ok "Cleaned" + +msg_info "Starting PhotoPrism" +$STD systemctl enable --now photoprism +msg_ok "Started PhotoPrism" From 77ea6abde8ed674cd017c54b3aa4aff6469a9f3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 15:23:16 -0500 Subject: [PATCH 3905/6505] Create adguard-v5.sh --- ct/adguard-v5.sh | 376 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 ct/adguard-v5.sh diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh new file mode 100644 index 00000000..b87bdd93 --- /dev/null +++ b/ct/adguard-v5.sh @@ -0,0 +1,376 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ___ __ __ + / | ____/ /___ ___v5______ __________/ / + / /| |/ __ / __ / / / / __ / ___/ __ / + / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / +/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ + /____/ + +EOF +} +echo -e "Loading..." +APP="Adguard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/AdGuardHome ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Stopping AdguardHome" +systemctl stop AdGuardHome +msg_ok "Stopped AdguardHome" + +msg_info "Updating AdguardHome" +wget -qL https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz +tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null +mkdir -p adguard-backup +cp -r /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ +cp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome +cp -r adguard-backup/* /opt/AdGuardHome/ +msg_ok "Updated AdguardHome" + +msg_info "Starting AdguardHome" +systemctl start AdGuardHome +msg_ok "Started AdguardHome" + +msg_info "Cleaning Up" +rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup +msg_ok "Cleaned" +msg_ok "Update Successfull" +exit +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 09350d5067bad326788e2b691a3feca7c386f416 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 15:24:51 -0500 Subject: [PATCH 3906/6505] Create adguard-v5-install.sh --- install/adguard-v5-install.sh | 120 ++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 install/adguard-v5-install.sh diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh new file mode 100644 index 00000000..637375f6 --- /dev/null +++ b/install/adguard-v5-install.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing AdGuard Home" +wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh +$STD bash install.sh +rm install.sh +msg_ok "Installed AdGuard Home" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From a483f4bd06675d09d0995e7a2b6554b26830f656 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 16:54:05 -0500 Subject: [PATCH 3907/6505] Update homeassistant-core-v5.sh combine initialize, update and hacs --- ct/homeassistant-core-v5.sh | 43 ++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 76ff5b92..ef3f59dd 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -79,7 +79,7 @@ if ! command -v pveversion >/dev/null 2>&1; then msg_error "No Home Assistant Core Installation Found!"; exit fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC to ${STABLE} Or, Beta to ${BETA}. Proceed?" 10 58); then + if (whiptail --title "${APP} LXC TOOLS" --yesno "Tools to Initialize, Update and Install HACS. Proceed?" 10 58); then echo "User selected Yes" else clear @@ -315,6 +315,20 @@ function install_script() { function update_script() { PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ + "1" "Initialize" ON \ + "2" "Update" OFF \ + "3" "HACS" OFF \ + 3>&1 1>&2 2>&3) + +if [ "$UPD" == "1" ]; then +clear +header_info +echo -e "\n LOG VIEWER - Go to http://${IP}:8123 to setup \n" +cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass +exit +fi +if [ "$UPD" == "2" ]; then if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then clear header_info @@ -338,13 +352,13 @@ pip install ${BR}--upgrade homeassistant &>/dev/null msg_ok "Updated Home Assistant" msg_info "Setting Dependency Versions" -if [ "${BR}" == "--pre " ]; then -sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -else -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -fi + if [ "${BR}" == "--pre " ]; then + sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt + sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json + else + sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt + sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json + fi sleep 2 msg_ok "Set Dependency Versions" @@ -355,6 +369,19 @@ msg_ok "Started Home Assistant" msg_ok "Update Successful" echo -e "\n Go to http://${IP}:8123 \n" exit +fi +if [ "$UPD" == "3" ]; then +clear +header_info +msg_info "Installing Home Assistant Comunity Store (HACS)" +apt update &>/dev/null +apt install unzip &>/dev/null +cd .homeassistant +wget -O - https://get.hacs.xyz | bash - &>/dev/null +msg_ok "Installed Home Assistant Comunity Store (HACS)" +echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" +exit +fi } clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi From 3b66ad0fcb1575833baaefe31de0c124501f8737 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 17:47:36 -0500 Subject: [PATCH 3908/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b222837e..a5ec895a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,17 @@ # Change Log All notable changes to this project will be documented in this file. +## 2022-12-31 + +### Changed + +- **v5 Sccripts** (Testing before moving forward) + - Adguard Home LXC + - Docker LXC + - Home Assistant Core LXC + - PhotoPrism LXC + - Vaultwarden LXC + ## 2022-12-27 ### Changed From 4b71001ea269de2f2fec9f5af06223062205a081 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 17:55:20 -0500 Subject: [PATCH 3909/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a5ec895a..33730f30 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **v5 Sccripts** (Testing before moving forward) +- **v5 Sccripts** (Testing before moving forward https://github.com/tteck/Proxmox/discussions/881) - Adguard Home LXC - Docker LXC - Home Assistant Core LXC From e13909d86ed0c628c2c00c7dda7891627d360e9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 18:23:45 -0500 Subject: [PATCH 3910/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 33730f30..53db4db6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed -- **v5 Sccripts** (Testing before moving forward https://github.com/tteck/Proxmox/discussions/881) +- **v5 Scripts** (Testing before moving forward https://github.com/tteck/Proxmox/discussions/881) - Adguard Home LXC - Docker LXC - Home Assistant Core LXC From 08e6a95a2731a0bb6ce2f876165ead3e53aa4d85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 19:01:24 -0500 Subject: [PATCH 3911/6505] Update adguard-v5.sh --- ct/adguard-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index b87bdd93..7255389e 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -30,6 +30,7 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset From 0a7b8629ea7d8a3f4ab4c9d0a3ea455dc1e94e1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 19:44:14 -0500 Subject: [PATCH 3912/6505] Create shinobi-v5.sh --- ct/shinobi-v5.sh | 367 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 ct/shinobi-v5.sh diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh new file mode 100644 index 00000000..27c98ae5 --- /dev/null +++ b/ct/shinobi-v5.sh @@ -0,0 +1,367 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _____ __ _ __ _ + / ___// /_ (_)___v4____ / /_ (_) + \__ \/ __ \/ / __ \/ __ \/ __ \/ / + ___/ / / / / / / / / /_/ / /_/ / / +/____/_/ /_/_/_/ /_/\____/_.___/_/ + +EOF +} +echo -e "Loading..." +APP="Shinobi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="22.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/Shinobi ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" OFF \ + "22.04" "Jammy" ON \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Updating Shinobi LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Shinobi LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8080/super${CL} \n" From 14db7a3e08b7daf7410aa1ca0f30c8299b097a8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 19:45:28 -0500 Subject: [PATCH 3913/6505] Create shinobi-v5-install.sh --- install/shinobi-v5-install.sh | 178 ++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 install/shinobi-v5-install.sh diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh new file mode 100644 index 00000000..b0a00306 --- /dev/null +++ b/install/shinobi-v5-install.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update --fix-missing +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +ubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) +if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then + apt install sudo wget -y + sudo apt install -y software-properties-common + sudo add-apt-repository universe -y + apt update -y + apt update --fix-missing -y +fi + +msg_info "Installing Dependencies" +$STD apt-get install -y curl sudo git +$STD apt-get install -y make zip net-tools +$STD apt-get install -y gcc g++ cmake +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +wget -qL https://deb.nodesource.com/setup_18.x +$STD bash setup_18.x +rm setup_18.x +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing FFMPEG" +$STD apt-get install -y ffmpeg +msg_ok "Installed FFMPEG" + +msg_info "Clonning Shinobi" +cd /opt +$STD git clone https://gitlab.com/Shinobi-Systems/Shinobi.git -b master Shinobi +cd Shinobi +gitVersionNumber=$(git rev-parse HEAD) +theDateRightNow=$(date) +touch version.json +chmod 777 version.json +echo '{"Product" : "'"Shinobi"'" , "Branch" : "'"master"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"https://gitlab.com/Shinobi-Systems/Shinobi.git"'"}' > version.json +msg_ok "Cloned Shinobi" + +msg_info "Installing Database" +sqlpass="" +echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections +echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections +$STD apt-get install -y mariadb-server +service mysql start +sqluser="root" +mysql -e "source sql/user.sql" || true +mysql -e "source sql/framework.sql" || true +msg_ok "Installed Database" +cp conf.sample.json conf.json +cronKey=$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)}') +sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json +cp super.sample.json super.json + +msg_info "Installing Shinobi" +$STD npm i npm -g +$STD npm install --unsafe-perm +$STD npm install pm2@latest -g +chmod -R 755 . +touch INSTALL/installed.txt +ln -s /opt/Shinobi/INSTALL/shinobi /usr/bin/shinobi +node /opt/Shinobi/tools/modifyConfiguration.js addToConfig="{\"cron\":{\"key\":\"$(head -c 64 < /dev/urandom | sha256sum | awk '{print substr($1,1,60)}')\"}}" &>/dev/null +$STD pm2 start camera.js +$STD pm2 start cron.js +$STD pm2 startup +$STD pm2 save +$STD pm2 list +msg_ok "Installed Shinobi" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 475649dad9244abbe3845b83b28ade48791c1153 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 20:09:32 -0500 Subject: [PATCH 3914/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 53db4db6..227a0893 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. - Docker LXC - Home Assistant Core LXC - PhotoPrism LXC + - Shinobi - Vaultwarden LXC ## 2022-12-27 From 2f2683fd9c571e643209b9166f7952d9e2a3a98b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 20:31:20 -0500 Subject: [PATCH 3915/6505] Update shinobi-v5.sh add update --- ct/shinobi-v5.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 27c98ae5..43892a32 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -319,8 +319,11 @@ function update_script() { clear header_info msg_info "Updating Shinobi LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +cd /home/Shinobi +sh UPDATE.sh +pm2 flush +pm2 restart camera +pm2 restart cron msg_ok "Updated Shinobi LXC" exit } From bb5cf805d9d2a4f2086ed2675d771a37be6143d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 20:36:40 -0500 Subject: [PATCH 3916/6505] Update shinobi-v5.sh --- ct/shinobi-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 43892a32..be99877d 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -319,7 +319,7 @@ function update_script() { clear header_info msg_info "Updating Shinobi LXC" -cd /home/Shinobi +cd /opt/Shinobi sh UPDATE.sh pm2 flush pm2 restart camera From cbd076508d96d7c7b535f9991b77fc335b99ba41 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 31 Dec 2022 21:11:25 -0500 Subject: [PATCH 3917/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 227a0893..7c4331cc 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file. - Docker LXC - Home Assistant Core LXC - PhotoPrism LXC - - Shinobi + - Shinobi NVR LXC - Vaultwarden LXC ## 2022-12-27 From 01b2069280525ff3d9cbbc609cfd386d9a4c4482 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 08:42:22 -0500 Subject: [PATCH 3918/6505] Update vaultwarden-v5.sh adjust build resources --- ct/vaultwarden-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index fb314d38..65c34c46 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -12,8 +12,8 @@ EOF echo -e "Loading..." APP="Vaultwarden" var_disk="6" -var_cpu="2" -var_ram="3072" +var_cpu="4" +var_ram="4096" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') From 6c7d5141a5b0f30ff26ea976c3a8e7545d914dba Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 08:43:31 -0500 Subject: [PATCH 3919/6505] Update photoprism-v5.sh adjust build resources --- ct/photoprism-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 398908b6..4d9fc8a5 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -12,8 +12,8 @@ EOF echo -e "Loading..." APP="PhotoPrism" var_disk="8" -var_cpu="2" -var_ram="3072" +var_cpu="4" +var_ram="4096" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') From ba98f45614dee14ff9b10e1150c2de31f072c1ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 10:19:43 -0500 Subject: [PATCH 3920/6505] Create homeassistant-v5.sh --- ct/homeassistant-v5.sh | 412 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 ct/homeassistant-v5.sh diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh new file mode 100644 index 00000000..13041638 --- /dev/null +++ b/ct/homeassistant-v5.sh @@ -0,0 +1,412 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ ___ _ __ __ + / / / /___v5____ ___ ___ / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ + +EOF +} +echo -e "Loading..." +APP="Home Assistant" +var_disk="16" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +NEXTID=$(pvesh get /cluster/nextid) +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /root/hass_config ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Yes" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Update ALL Containers" ON \ + "2" "Remove ALL Unused Images" OFF \ + 3>&1 1>&2 2>&3) +clear +header_info +if [ "$UPD" == "1" ]; then +msg_info "Updating All Containers" +CONTAINER_LIST="${1:-$(docker ps -q)}" +for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike "${container}")" + docker rm --force "${container}" + eval ${DOCKER_COMMAND} + fi +done +msg_ok "Updated All Containers" +exit +fi +if [ "$UPD" == "2" ]; then +msg_info "Removing ALL Unused Images" +docker image prune -af +msg_ok "Removed ALL Unused Images" +exit +fi +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" +else +FEATURES="keyctl=1,nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export ST=$FUSE +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$CT_TYPE" == "0" ]; then +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} +Portainer should be reachable by going to the following URL. + ${BL}http://${IP}:9000${CL}\n" From 8476dadf24e099492f2869dd07560229d35ef909 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 10:21:17 -0500 Subject: [PATCH 3921/6505] Create homeassistant-v5-install.sh --- install/homeassistant-v5-install.sh | 178 ++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 install/homeassistant-v5-install.sh diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh new file mode 100644 index 00000000..cb1fa779 --- /dev/null +++ b/install/homeassistant-v5-install.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing runlike" +$STD apt-get install -y python3-pip +$STD pip3 install runlike +msg_ok "Installed runlike" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") + +msg_info "Installing Docker $DOCKER_LATEST_VERSION" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +fi +$STD sh <(curl -sSL https://get.docker.com) +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" + +msg_info "Pulling Portainer $PORTAINER_LATEST_VERSION Image" +$STD docker pull portainer/portainer-ce:latest +msg_ok "Pulled Portainer $PORTAINER_LATEST_VERSION Image" + +msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" +$STD docker volume create portainer_data +$STD docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest +msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" + +msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" +$STD docker pull homeassistant/home-assistant:stable +msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" + +msg_info "Installing Home Assistant $CORE_LATEST_VERSION" +$STD docker volume create hass_config +$STD docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable + mkdir /root/hass_config +msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 92e4c446ef3908c9ce84fb26ba20dd446e1ad9fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 10:22:28 -0500 Subject: [PATCH 3922/6505] Update homeassistant-v5.sh switch branch --- ct/homeassistant-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 13041638..7791ece8 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -400,7 +400,7 @@ fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ From 4a997ef40b788d2846d3858d00b380072a1d3404 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 10:41:11 -0500 Subject: [PATCH 3923/6505] Update homeassistant-v5.sh add install hacs --- ct/homeassistant-v5.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 7791ece8..13530f91 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -321,6 +321,7 @@ function update_script() { UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ "1" "Update ALL Containers" ON \ "2" "Remove ALL Unused Images" OFF \ + "3" "Install HACS" OFF \ 3>&1 1>&2 2>&3) clear header_info @@ -348,6 +349,18 @@ docker image prune -af msg_ok "Removed ALL Unused Images" exit fi +if [ "$UPD" == "3" ]; then +clear +header_info +msg_info "Installing Home Assistant Comunity Store (HACS)" +apt update &>/dev/null +apt install unzip &>/dev/null +cd /var/lib/docker/volumes/hass_config/_data +wget -O - https://get.hacs.xyz | bash - +msg_ok "Installed Home Assistant Comunity Store (HACS)" +echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" +exit +fi } clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi From f6395c6550256047d4f70f602f39a1be72b1344a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 10:57:25 -0500 Subject: [PATCH 3924/6505] Update homeassistant-v5.sh --- ct/homeassistant-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 13530f91..76923192 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -318,7 +318,7 @@ function install_script() { fi } function update_script() { -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ "1" "Update ALL Containers" ON \ "2" "Remove ALL Unused Images" OFF \ "3" "Install HACS" OFF \ From 31b8c786cb0f0e16934c6c95197365fe1c98bd7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 11:11:24 -0500 Subject: [PATCH 3925/6505] Delete latest-update-menu.sh prune --- misc/latest-update-menu.sh | 209 ------------------------------------- 1 file changed, 209 deletions(-) delete mode 100644 misc/latest-update-menu.sh diff --git a/misc/latest-update-menu.sh b/misc/latest-update-menu.sh deleted file mode 100644 index 90d6f25b..00000000 --- a/misc/latest-update-menu.sh +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env bash - -while true; do - read -p "This will create a New Update Menu for Home Assistant Container LXC. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -set -o errexit -rm -rf /root/update.sh update update-containers.sh -echo -e "\e[1;92m Creating New Update Menu Script... \e[0m" -if [ -f /usr/local/lib/python3.9/dist-packages/runlike/runlike.py ]; then - echo -e "\e[1;92m pip3/runlike Already Installed! \e[0m" -else - apt-get update &>/dev/null - echo -e "\e[1;92m Installing pip3... \e[0m" - apt-get install -y python3-pip &>/dev/null - echo -e "\e[1;92m Installing runlike... \e[0m" - pip3 install runlike &>/dev/null -fi -echo -e "\e[1;92m Creating Update Script... \e[0m" -if [ -d /root/hass_config ]; then - echo -e "\e[1;92m There's Already (hass_config) Folder! \e[0m" -else - mkdir /root/hass_config -fi -UPDATE_PATH='/root/update' -UPDATE_CONTAINERS_PATH='/root/update-containers.sh' -cat >$UPDATE_PATH <<'EOF' -#!/bin/sh -set -o errexit -show_menu(){ - normal=`echo "\033[m"` - safe=`echo "\033[32m"` - menu=`echo "\033[36m"` - number=`echo "\033[33m"` - bgred=`echo "\033[41m"` - fgred=`echo "\033[31m"` - hostname -I - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" - printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" - printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" - printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" - printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" - printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" - printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" - printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" - printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" - printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" - read opt -} -option_picked(){ - msgcolor=`echo "\033[01;31m"` - normal=`echo "\033[00;00m"` - message=${@:-"${normal}Error: No message passed"} - printf "${msgcolor}${message}${normal}\n" -} -clear -show_menu -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - option_picked "Switching to Stable Branch"; - TAG=stable - break; - ;; - 2) clear; - option_picked "Switching to Beta Branch"; - TAG=beta - break; - ;; - 3) while true; do - read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Switching to Dev Branch"; - TAG=dev - break; - ;; - 4) clear; - option_picked "Backing up Home Assistant Data to root (hass_config)"; - rm -r hass_config; - cp -pR /var/lib/docker/volumes/hass_config/ /root/; - sleep 2; - clear; - show_menu; - ;; - 5) while true; do - read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Restoring Home Assistant Data from root (hass_config)"; - rm -r /var/lib/docker/volumes/hass_config/_data; - cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - sleep 2; - clear; - show_menu; - ;; - 6) while true; do - read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Editing Home Assistant Configuration"; - nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - clear; - show_menu; - ;; - 7) clear; - option_picked "Restarting Home Assistant"; - docker restart homeassistant; - exit; - ;; - 8) clear; - option_picked "Just Updating Containers"; - ./update-containers.sh; - sleep 2; - clear; - show_menu; - ;; - 9) clear; - option_picked "Removing Unused Images"; - docker image prune -af; - sleep 2; - clear; - show_menu; - ;; - 10) clear; - option_picked "Updating Host OS"; - apt update && apt upgrade -y; - sleep 2; - clear; - show_menu; - ;; - 11) clear; - option_picked "Reboot Host OS"; - reboot; - exit; - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose an option from the menu"; - show_menu; - ;; - esac - fi - done -docker pull homeassistant/home-assistant:$TAG -docker rm --force homeassistant -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:$TAG -EOF -sudo chmod +x /root/update -cat >$UPDATE_CONTAINERS_PATH <<'EOF' -#!/bin/bash -set -o errexit -CONTAINER_LIST="${1:-$(docker ps -q)}" -for container in ${CONTAINER_LIST}; do - CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" - RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" - docker pull "${CONTAINER_IMAGE}" - LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" - if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then - echo "Updating ${container} image ${CONTAINER_IMAGE}" - DOCKER_COMMAND="$(runlike "${container}")" - docker rm --force "${container}" - eval ${DOCKER_COMMAND} - fi -done -EOF -sudo chmod +x /root/update-containers.sh -echo -e "\e[1;92m Finished. Type ./update in the LXC console\e[0m" From 2f6cf1addc5cdfa287c57bccaf6f27ae12dbf4e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 12:26:54 -0500 Subject: [PATCH 3926/6505] Delete hacs-core.sh prune --- misc/hacs-core.sh | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 misc/hacs-core.sh diff --git a/misc/hacs-core.sh b/misc/hacs-core.sh deleted file mode 100644 index 0479d932..00000000 --- a/misc/hacs-core.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi -echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" - -while true; do - read -p "Start the HACS Install Script (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -apt update &>/dev/null -apt install unzip &>/dev/null -cd .homeassistant -wget -O - https://get.hacs.xyz | bash - - -# To install HACS run the following from the container (LXC) console -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs-core.sh)" -# Then add the integration in HA From ac4877334e5b1208a3410a9030bcbc1e5cd7501b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 12:27:15 -0500 Subject: [PATCH 3927/6505] Delete hacs.sh prune --- misc/hacs.sh | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 misc/hacs.sh diff --git a/misc/hacs.sh b/misc/hacs.sh deleted file mode 100644 index e48dbf82..00000000 --- a/misc/hacs.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi -echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" - -while true; do - read -p "Start the HACS Install Script (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -apt update &>/dev/null -apt install unzip &>/dev/null -cd /var/lib/docker/volumes/hass_config/_data -wget -O - https://get.hacs.xyz | bash - - -# To install HACS run the following from the container (LXC) console -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacs.sh)" -# Then add the integration in HA From edd5e451e04cce9d5db1533e7e832a821fcfaad9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 12:28:10 -0500 Subject: [PATCH 3928/6505] Delete photoprism-update.sh prune --- misc/photoprism-update.sh | 107 -------------------------------------- 1 file changed, 107 deletions(-) delete mode 100644 misc/photoprism-update.sh diff --git a/misc/photoprism-update.sh b/misc/photoprism-update.sh deleted file mode 100644 index 143eb9a2..00000000 --- a/misc/photoprism-update.sh +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env bash -set -e -RELEASE=$(curl -s https://api.github.com/repos/photoprism/photoprism/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-4) }') - -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -PP=$(echo "\e[1;35m") - -while true; do - read -p "Update PhotoPrism LXC. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - echo -e "${PP} - _____ _ _ _____ _ - | __ \| | | | | __ \ (_) - | |__) | |__ ___ | |_ ___ | |__) | __ _ ___ _ __ ___ - | ___/| _ \ / _ \| __/ _ \| ___/ __| / __| _ _ \ - | | | | | | (_) | || (_) | | | | | \__ \ | | | | | - |_| |_| |_|\___/ \__\___/|_| |_| |_|___/_| |_| |_| - ${RD} UPDATE -${CL}" -} - -header_info -show_menu() { - printf " ${YW} 1)${GN} Release Branch ${CL}\n" - printf " ${YW} 2)${YW} Develop Branch ${CL}\n" - - printf "Please choose a Install Branch and hit enter or ${RD}x${CL} to exit." - read opt -} - -option_picked() { - message1=${@:-"${CL}Error: No message passed"} - printf " ${YW}${message1}${CL}\n" -} -show_menu -while [ "$opt" != " " ]; do - case $opt in - 1) - clear - header_info - option_picked "Using Release Branch" - BR="release" - break - ;; - 2) - clear - header_info - option_picked "Using Develop Branch" - BR="develop" - break - ;; - - x) - exit - ;; - \n) - exit - ;; - *) - clear - option_picked "Please choose a Install Branch from the menu" - show_menu - ;; - esac -done - -echo -en "${GN} Stopping PhotoPrism... " -sudo systemctl stop photoprism -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cloning PhotoPrism ${BR} branch... " -git clone https://github.com/photoprism/photoprism.git &>/dev/null -cd photoprism -git checkout ${BR} &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Building PhotoPrism ${BR} branch... " -sudo make all &>/dev/null -sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null -sudo rm -rf /opt/photoprism/assets -sudo cp -r assets/ /opt/photoprism/ &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleaning... " -cd ~ -rm -rf photoprism -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting PhotoPrism... " -sudo systemctl start photoprism -echo -e "${CM}${CL} \n" - -echo -e "${GN} Finished ${CL} \n " From 9261df49f82e41eeb10a8f2095381a1a4f204b0e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 12:28:42 -0500 Subject: [PATCH 3929/6505] Delete vaultwarden-update.sh prune --- misc/vaultwarden-update.sh | 55 -------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 misc/vaultwarden-update.sh diff --git a/misc/vaultwarden-update.sh b/misc/vaultwarden-update.sh deleted file mode 100644 index 2a0c9436..00000000 --- a/misc/vaultwarden-update.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -set -e -VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -function update_info { - echo -e "${BL} - __ __ _ _ _ - \ \ / / | | | | | - \ \ / /_ _ _ _| | |___ ____ _ _ __ __| | ___ _ __ - \ \/ / _ | | | | | __\ \ /\ / / _ | __/ _ |/ _ \ _ \ - \ / (_| | |_| | | |_ \ V V / (_| | | | (_| | __/ | | | - \/ \__,_|\__,_|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| - ${VAULT} UPDATE -${CL}" -} - -update_info -while true; do - read -p "This will Update Vaultwarden to $VAULT (Ensure you set 2vCPU 3072MiB RAM Min.). Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -sleep 2 -echo -e "${GN} Stopping Vaultwarden... ${CL}" -systemctl stop vaultwarden.service -sleep 1 - -echo -e "${GN} Updating (Building) to ${VAULT} (Patience)... ${CL}" -git clone https://github.com/dani-garcia/vaultwarden &>/dev/null -cd vaultwarden -cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null -DIR=/usr/bin/vaultwarden -if [ -d "$DIR" ]; then - cp target/release/vaultwarden /usr/bin/ -else - cp target/release/vaultwarden /opt/vaultwarden/bin/ -fi -echo -e "${GN} Starting Vaultwarden ${VAULT}... ${CL}" -systemctl start vaultwarden.service -sleep 1 - -echo -e "${GN} Cleaning up... ${CL}" -cd ~ && rm -rf vaultwarden - -echo -e "${GN} Finished Update (Ensure you set resources back to normal settings)${CL}" From 61bf8aa2d56a4024d94de5a156832fb6a1dc69f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 12:29:01 -0500 Subject: [PATCH 3930/6505] Delete web-vault-update.sh prune --- misc/web-vault-update.sh | 50 ---------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 misc/web-vault-update.sh diff --git a/misc/web-vault-update.sh b/misc/web-vault-update.sh deleted file mode 100644 index 5b2e61b9..00000000 --- a/misc/web-vault-update.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -VWRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -function update_info { - echo -e "${BL} - __ __ _ _ _ - \ \ / / | | | | | - \ \ /\ / /__| |__ ________ ____ _ _ _| | |_ - \ \/ \/ / _ \ _ \______\ \ / / _ | | | | | __| - \ /\ / __/ |_) | \ V / (_| | |_| | | |_ - \/ \/ \___|_.__/ \_/ \__,_|\__,_|_|\__| - ${VWRELEASE} UPDATE -${CL}" -} -update_info -while true; do - read -p "This will Update Web-Vault to $VWRELEASE. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -sleep 2 -echo -e "${GN} Stopping Vaultwarden... ${CL}" -systemctl stop vaultwarden.service -sleep 1 - -echo -e "${GN} Updating to ${VWRELEASE}... ${CL}" -curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$VWRELEASE/bw_web_$VWRELEASE.tar.gz &>/dev/null -if [ -d "/var/lib/vaultwarden" ]; then - tar -xzf bw_web_$VWRELEASE.tar.gz -C /var/lib/vaultwarden/ &>/dev/null -else - tar -zxf bw_web_$VWRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null -fi - -echo -e "${GN} Cleaning up... ${CL}" -rm bw_web_$VWRELEASE.tar.gz - -echo -e "${GN} Starting Vaultwarden... ${CL}" -systemctl start vaultwarden.service -sleep 1 -echo -e "${GN} Finished Update ${CL}" From e12e6e25543461e656720ba079fce7ffc2ee3310 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 12:47:26 -0500 Subject: [PATCH 3931/6505] Update shinobi-v5.sh --- ct/shinobi-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index be99877d..dd10e026 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -2,7 +2,7 @@ function header_info { cat <<"EOF" _____ __ _ __ _ - / ___// /_ (_)___v4____ / /_ (_) + / ___// /_ (_)___v5____ / /_ (_) \__ \/ __ \/ / __ \/ __ \/ __ \/ / ___/ / / / / / / / / /_/ / /_/ / / /____/_/ /_/_/_/ /_/\____/_.___/_/ From 8a697b817489060173659039fa018eabf5c7e291 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 17:25:23 -0500 Subject: [PATCH 3932/6505] Update photoprism-v5-install.sh tweaking --- install/photoprism-v5-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 384c0074..352d6096 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -97,9 +97,7 @@ $STD apt-get install -y ffmpeg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -wget -qL https://deb.nodesource.com/setup_18.x -$STD bash setup_18.x -rm setup_18.x +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 62d843dc0a676165c0716a0ad2fc11c273c48844 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 17:26:05 -0500 Subject: [PATCH 3933/6505] Update shinobi-v5-install.sh tweaking --- install/shinobi-v5-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index b0a00306..73e5eadb 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -97,9 +97,7 @@ $STD apt-get install -y gcc g++ cmake msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -wget -qL https://deb.nodesource.com/setup_18.x -$STD bash setup_18.x -rm setup_18.x +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From c1d460c1501652e454f1903e029f5b8600e6f39e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 18:12:02 -0500 Subject: [PATCH 3934/6505] Create zigbee2mqtt-v5.sh --- ct/zigbee2mqtt-v5.sh | 402 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 ct/zigbee2mqtt-v5.sh diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh new file mode 100644 index 00000000..af31077f --- /dev/null +++ b/ct/zigbee2mqtt-v5.sh @@ -0,0 +1,402 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _____ _ __ ___ __ _______ ____________ +/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ + / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / + / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / +/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ + v5 /____/ 🐝 + +EOF +} +echo -e "Loading..." +APP="Zigbee2MQTT" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/zigbee2mqtt ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +cd /opt/zigbee2mqtt +msg_info "Checking for Backup Directory" +if [ -d data-backup ]; then + echo "ERROR: Backup directory exists. May be previous restoring was failed?" + echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later." + echo "2. Manually delete 'data-backup' dir and try again." + exit 1 +fi +msg_ok "No Backup Directory Exists" + +msg_info "Stopping Zigbee2MQTT" +systemctl stop zigbee2mqtt +msg_ok "Stopped Zigbee2MQTT" + +msg_info "Creating Backup of Configuration" +cp -R data data-backup +msg_ok "Created Backup of Configuration" + +msg_info "Updating Zigbee2MQTT" +git pull &>/dev/null +msg_ok "Updated Zigbee2MQTT" + +msg_info "Installing Dependencies" +npm ci &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Restoring Configuration" +cp -R data-backup/* data +rm -rf data-backup +msg_ok "Restored Configuration" + +msg_info "Starting Zigbee2MQTT" +systemctl start zigbee2mqtt +msg_ok "Started Zigbee2MQTT" +msg_ok "Update Successful" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 8e5c90245dfb446d6645cee7bc11ea279cb6330b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 18:13:16 -0500 Subject: [PATCH 3935/6505] Create zigbee2mqtt-v5-install.sh --- install/zigbee2mqtt-v5-install.sh | 163 ++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 install/zigbee2mqtt-v5-install.sh diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh new file mode 100644 index 00000000..81452490 --- /dev/null +++ b/install/zigbee2mqtt-v5-install.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Setting up Zigbee2MQTT Repository" +$STD git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt +msg_ok "Set up Zigbee2MQTT Repository" + +read -r -p "Switch to Edge/dev branch? (y/N) " prompt +if [[ $prompt == "y" ]]; then + DEV="y" +else + DEV="n" +fi + +msg_info "Installing Zigbee2MQTT" +cd /opt/zigbee2mqtt +if [[ $DEV == "y" ]]; then +$STD git checkout dev +fi +$STD npm ci +msg_ok "Installed Zigbee2MQTT" + +msg_info "Creating Service" +service_path="/etc/systemd/system/zigbee2mqtt.service" +echo "[Unit] +Description=zigbee2mqtt +After=network.target +[Service] +Environment=NODE_ENV=production +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zigbee2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable zigbee2mqtt.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 0aeffb93251b60f4879c8756818cb16d7aaffe68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 18:14:58 -0500 Subject: [PATCH 3936/6505] Create zwave-js-ui-v5-install.sh --- install/zwave-js-ui-v5-install.sh | 140 ++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 install/zwave-js-ui-v5-install.sh diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh new file mode 100644 index 00000000..601d9082 --- /dev/null +++ b/install/zwave-js-ui-v5-install.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing Z-Wave JS UI" +mkdir /opt/zwave-js-ui +cd /opt/zwave-js-ui +RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +$STD wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip +$STD unzip zwave-js-ui-${RELEASE}-linux.zip +msg_ok "Installed Z-Wave JS UI" + +msg_info "Creating Service" +service_path="/etc/systemd/system/zwave-js-ui.service" +echo "[Unit] +Description=zwave-js-ui +Wants=network-online.target +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/zwave-js-ui +ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux +[Install] +WantedBy=multi-user.target" >$service_path +systemctl start zwave-js-ui +$STD systemctl enable zwave-js-ui +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm zwave-js-ui-${RELEASE}-linux.zip +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 5053a545ee97926b60563c5316969bd6b42e715b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 18:16:18 -0500 Subject: [PATCH 3937/6505] Create zwave-js-ui-v5.sh --- ct/zwave-js-ui-v5.sh | 387 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 ct/zwave-js-ui-v5.sh diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh new file mode 100644 index 00000000..0abaf0de --- /dev/null +++ b/ct/zwave-js-ui-v5.sh @@ -0,0 +1,387 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _____ _______ __ ______ +/__ /_ ______ __v5 _____ / / ___/ / / / / _/ + / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / + / /_| |/ |/ / /_/ /| |/ / __/ / /_/ /___/ / / /_/ // / +/____/__/|__/\__,_/ |___/\___/ \____//____/ \____/___/ + +EOF +} +echo -e "Loading..." +APP="Zwave-JS-UI" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/zwave-js-ui ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +msg_info "Stopping Z-wave JS UI" +systemctl stop zwave-js-ui.service +msg_ok "Stopped Z-wave JS UI" + +msg_info "Updating Z-wave JS UI" +wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null +unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null +\cp -R zwave-js-ui-linux /opt/zwave-js-ui +msg_ok "Updated Z-wave JS UI" + +msg_info "Starting Z-wave JS UI" +systemctl enable --now zwave-js-ui.service +msg_ok "Started Z-wave JS UI" + +msg_info "Cleanup" +rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store +msg_ok "Cleaned" +msg_ok "Updated Successfully!\n" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8091${CL} \n" From 9d4543859c6ee8f28fb400afd882d2b6ed080dcc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 19:40:59 -0500 Subject: [PATCH 3938/6505] Update vaultwarden-v5.sh get admin token in updates --- ct/vaultwarden-v5.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 65c34c46..756b6439 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -315,15 +315,16 @@ WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/relea grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ "1" "VaultWarden $VAULT" ON \ "2" "Web-Vault $WVRELEASE" OFF \ + "3" "Get Admin Token" OFF \ 3>&1 1>&2 2>&3) clear header_info -echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" if [ "$UPD" == "1" ]; then +echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" msg_info "Stopping Vaultwarden" systemctl stop vaultwarden.service msg_ok "Stopped Vaultwarden" @@ -373,6 +374,10 @@ msg_ok "Started Vaultwarden" msg_ok "$WVRELEASE Update Successful" exit; fi +if [ "$UPD" == "3" ]; then +cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" +exit +fi } clear From d837f80df674c739409ac539cfd4dcd55b042543 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 19:46:09 -0500 Subject: [PATCH 3939/6505] Update vaultwarden-v5.sh --- ct/vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 756b6439..b0c24459 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -318,7 +318,7 @@ WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/relea UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ "1" "VaultWarden $VAULT" ON \ "2" "Web-Vault $WVRELEASE" OFF \ - "3" "Get Admin Token" OFF \ + "3" "Show Admin Token" OFF \ 3>&1 1>&2 2>&3) clear From 8de8fdddb5b0febacadde8353278c6bd6767c26c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 20:33:39 -0500 Subject: [PATCH 3940/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index ef3f59dd..d4c9ddb2 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -316,8 +316,8 @@ function update_script() { PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ - "1" "Initialize" ON \ - "2" "Update" OFF \ + "1" "Initialize" OFF \ + "2" "Update" ON \ "3" "HACS" OFF \ 3>&1 1>&2 2>&3) From 277a0df9436c65fcbcfc78363b8417f9864b1e6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 20:41:11 -0500 Subject: [PATCH 3941/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index d4c9ddb2..48f56625 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -317,8 +317,8 @@ function update_script() { IP=$(hostname -I | awk '{print $1}') UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ "1" "Initialize" OFF \ - "2" "Update" ON \ - "3" "HACS" OFF \ + "2" "Update Core" ON \ + "3" "Install HACS" OFF \ 3>&1 1>&2 2>&3) if [ "$UPD" == "1" ]; then From 3e85d59cdb4e35330acba9ef6be5d4703db9a4f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 20:55:04 -0500 Subject: [PATCH 3942/6505] Delete adguard-update.sh prune --- misc/adguard-update.sh | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 misc/adguard-update.sh diff --git a/misc/adguard-update.sh b/misc/adguard-update.sh deleted file mode 100644 index f3018cf1..00000000 --- a/misc/adguard-update.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -echo -e "\nStarting Update\n" -sleep 3 -wget -q --show-progress https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz -tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null -systemctl stop AdGuardHome -mkdir -p adguard-backup -cp -r /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ -cp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome -cp -r adguard-backup/* /opt/AdGuardHome/ -systemctl start AdGuardHome -rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup -echo -e "\nFinished\n" From 7cad46820a08477c820992ff426fa836af0fee13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 20:56:18 -0500 Subject: [PATCH 3943/6505] Delete zwave-js-ui-update.sh prune --- misc/zwave-js-ui-update.sh | 85 -------------------------------------- 1 file changed, 85 deletions(-) delete mode 100644 misc/zwave-js-ui-update.sh diff --git a/misc/zwave-js-ui-update.sh b/misc/zwave-js-ui-update.sh deleted file mode 100644 index e52fad51..00000000 --- a/misc/zwave-js-ui-update.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -set -e -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} -clear -cat <<"EOF" - _____ _______ __ ______ -/__ /_ ______ __ _____ / / ___/ / / / / _/ - / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / - / /_| |/ |/ / /_/ /| |/ / __/ / /_/ /___/ / / /_/ // / -/____/__/|__/\__,_/ |___/\___/ \____//____/ \____/___/ - UPDATE - -EOF - -while true; do - read -p "This will update ZWave JS UI to $RELEASE. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -if [ ! -d /opt/zwave-js-ui ]; then - msg_error "No Zwave JS UI Install Detected!" - exit -fi - -msg_info "Stopping Z-wave JS UI" -systemctl stop zwave-js-ui.service -msg_ok "Stopped Z-wave JS UI" - -msg_info "Updating Z-wave JS UI" -wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -\cp -R zwave-js-ui-linux /opt/zwave-js-ui -msg_ok "Updated Z-wave JS UI" - -msg_info "Updating Z-wave JS UI service file" -cat </etc/systemd/system/zwave-js-ui.service -[Unit] -Description=zwave-js-ui -Wants=network-online.target -After=network-online.target -[Service] -User=root -WorkingDirectory=/opt/zwave-js-ui -ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux -[Install] -WantedBy=multi-user.target -EOF -systemctl daemon-reload -msg_ok "Updated Z-wave JS UI service file" - -msg_info "Cleanup" -rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store -msg_ok "Cleaned" - -msg_info "Starting Z-wave JS UI" -systemctl enable --now zwave-js-ui.service -msg_info "Started Z-wave JS UI" - -msg_ok "Completed Successfully!\n" From 87203859d57b15da95217ab6251189bd9ecf2b14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 20:57:45 -0500 Subject: [PATCH 3944/6505] Delete core-update.sh prune --- misc/core-update.sh | 84 --------------------------------------------- 1 file changed, 84 deletions(-) delete mode 100644 misc/core-update.sh diff --git a/misc/core-update.sh b/misc/core-update.sh deleted file mode 100644 index b9a547ab..00000000 --- a/misc/core-update.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash -clear -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi -set -e -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -function header_info { - cat <<"EOF" - _ _ _ _ ___ - /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___ _ __ ___ - / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ -/ __ / (_) | | | | | | __/ / _ \__ \__ \ \__ \ || (_| | | | | |_ / /__| (_) | | | __/ -\/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| - UPDATE -EOF -} -PY=$(ls /srv/homeassistant/lib/) -IP=$(hostname -I | awk '{print $1}') -STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') -BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -if (whiptail --title "CORE UPDATE" --yesno "This will update Home Assistant Core. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then - clear - header_info - echo -e "${GN}Updating to Version ${BETA}${CL}" - BR="--pre " -else - clear - header_info - echo -e "${GN}Updating to Version ${STABLE}${CL}" - BR="" -fi -if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi - -msg_info "Stopping Home Assistant" -systemctl stop homeassistant -msg_ok "Stopped Home Assistant" - -msg_info "Updating Home Assistant" -source /srv/homeassistant/bin/activate -pip install ${BR}--upgrade homeassistant &>/dev/null -msg_ok "Updated Home Assistant" - -msg_info "Setting Dependency Versions" -if [ "${BR}" == "--pre " ]; then -sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -else -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -fi -sleep 2 -msg_ok "Set Dependency Versions" - -msg_info "Starting Home Assistant" -systemctl start homeassistant -sleep 2 -msg_ok "Started Home Assistant" -msg_ok "Update Successful" -echo -e "\n Go to http://${IP}:8123 \n" From 0a73bc84140b5b2eb320b73498831e655a95a018 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 22:11:58 -0500 Subject: [PATCH 3945/6505] Create paperless-ngx-v5.sh --- ct/paperless-ngx-v5.sh | 429 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 ct/paperless-ngx-v5.sh diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh new file mode 100644 index 00000000..49f780b0 --- /dev/null +++ b/ct/paperless-ngx-v5.sh @@ -0,0 +1,429 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \____ _____ ___ _____/ /__v5__________ ____ ____ __ __ + / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ + / ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> < +/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| + /_/ /____/ + +EOF +} +echo -e "Loading..." +APP="Paperless-ngx" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/paperless ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +SER=/etc/systemd/system/paperless-task-queue.service + +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Update Paperless-ngx to $RELEASE" ON \ + "2" "Paperless-ngx Credentials" OFF \ + 3>&1 1>&2 2>&3) +clear +header_info +if [ "$UPD" == "1" ]; then +msg_info "Stopping Paperless-ngx" +systemctl stop paperless-consumer paperless-webserver paperless-scheduler + if [ -f "$SER" ]; then + systemctl stop paperless-task-queue.service + fi +sleep 1 +msg_ok "Stopped Paperless-ngx" + +msg_info "Updating to ${RELEASE}" + if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null + wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null + tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null + cp -r /opt/paperless/paperless.conf paperless-ngx/ + cp -r paperless-ngx/* /opt/paperless/ + cd /opt/paperless + sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt + pip install -r requirements.txt &>/dev/null + cd /opt/paperless/src + /usr/bin/python3 manage.py migrate &>/dev/null + if [ -f "$SER" ]; then + msg_ok "paperless-task-queue.service Exists." + else +cat </etc/systemd/system/paperless-task-queue.service +[Unit] +Description=Paperless Celery Workers +Requires=redis.service +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless worker --loglevel INFO +[Install] +WantedBy=multi-user.target +EOF +systemctl enable paperless-task-queue &>/dev/null +msg_ok "paperless-task-queue.service Created." + fi +cat </etc/systemd/system/paperless-scheduler.service +[Unit] +Description=Paperless Celery beat +Requires=redis.service +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless beat --loglevel INFO +[Install] +WantedBy=multi-user.target +EOF +msg_ok "Updated to ${RELEASE}" + +msg_info "Cleaning up" +cd ~ +rm paperless-ngx-$RELEASE.tar.xz +rm -rf paperless-ngx +msg_ok "Cleaned" + +msg_info "Starting Paperless-ngx" +systemctl daemon-reload +systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service +sleep 1 +msg_ok "Started Paperless-ngx" +msg_ok "Updated Successfully!\n" +exit +fi +if [ "$UPD" == "2" ]; then +clear +header_info +cat paperless.creds +exit +fi +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From 86baaf0b31dc16ae913f15ff2d43d480f3733761 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 22:13:23 -0500 Subject: [PATCH 3946/6505] Create paperless-ngx-v5-install.sh --- install/paperless-ngx-v5-install.sh | 288 ++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 install/paperless-ngx-v5-install.sh diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh new file mode 100644 index 00000000..ce87d088 --- /dev/null +++ b/install/paperless-ngx-v5-install.sh @@ -0,0 +1,288 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Paperless-ngx Dependencies" +$STD apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + python3-dev \ + imagemagick \ + fonts-liberation \ + optipng \ + gnupg \ + libpq-dev \ + libmagic-dev \ + mime-support \ + libzbar0 \ + poppler-utils \ + default-libmysqlclient-dev \ + sudo +msg_ok "Installed Paperless-ngx Dependencies" + +msg_info "Installing OCR Dependencies" +$STD apt-get install -y --no-install-recommends \ + unpaper \ + ghostscript \ + icc-profiles-free \ + qpdf \ + liblept5 \ + libxml2 \ + pngquant \ + zlib1g \ + tesseract-ocr \ + tesseract-ocr-eng +msg_ok "Installed OCR Dependencies" + +msg_info "Installing Extra Dependencies" +$STD apt-get install -y --no-install-recommends \ + redis \ + postgresql \ + build-essential \ + python3-setuptools \ + python3-wheel +msg_ok "Installed Extra Dependencies" + +msg_info "Installing JBIG2" +$STD apt-get install -y --no-install-recommends \ + automake \ + libtool \ + pkg-config \ + git \ + curl \ + libtiff-dev \ + libpng-dev \ + libleptonica-dev + +$STD git clone https://github.com/agl/jbig2enc /opt/jbig2enc +cd /opt/jbig2enc +$STD bash ./autogen.sh +$STD bash ./configure +$STD make +$STD make install +rm -rf /opt/jbig2enc +msg_ok "Installed JBIG2" + +msg_info "Installing Paperless-ngx (Patience)" +Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) +cd /opt +$STD wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz +$STD tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ +mv paperless-ngx paperless +rm paperless-ngx-$Paperlessngx.tar.xz +cd /opt/paperless + +## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file +sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt + +$STD pip install --upgrade pip +$STD pip install -r requirements.txt +msg_ok "Installed Paperless-ngx" + +msg_info "Setting up database" +DB_USER=paperless +DB_PASS="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" +DB_NAME=paperlessdb + +$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" + +echo "Paperless-ngx Database User" >>~/paperless.creds +echo $DB_USER >>~/paperless.creds +echo "Paperless-ngx Database Password" >>~/paperless.creds +echo $DB_PASS >>~/paperless.creds +echo "Paperless-ngx Database Name" >>~/paperless.creds +echo $DB_NAME >>~/paperless.creds + +/bin/bash -c "mkdir -p {consume,media}" + +sed -i -e 's|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=paperlessdb|' /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" /opt/paperless/paperless.conf +SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" +sed -i -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" /opt/paperless/paperless.conf + +cd /opt/paperless/src +$STD /usr/bin/python3 manage.py migrate +msg_ok "Set up database" + +msg_info "Setting up admin Paperless-ngx User & Password" +## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations +cat <>~/paperless.creds +echo "Paperless-ngx WebUI User" >>~/paperless.creds +echo admin >>~/paperless.creds +echo "Paperless-ngx WebUI Password" >>~/paperless.creds +echo $DB_PASS >>~/paperless.creds +msg_ok "Set up admin Paperless-ngx User & Password" + +msg_info "Creating Services" +cat </etc/systemd/system/paperless-scheduler.service +[Unit] +Description=Paperless Celery beat +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless beat --loglevel INFO + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/paperless-task-queue.service +[Unit] +Description=Paperless Celery Workers +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless worker --loglevel INFO + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/paperless-consumer.service +[Unit] +Description=Paperless consumer +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=python3 manage.py document_consumer + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/paperless-webserver.service +[Unit] +Description=Paperless webserver +After=network.target +Wants=network.target +Requires=redis.service + +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=/usr/local/bin/gunicorn -c /opt/paperless/gunicorn.conf.py paperless.asgi:application + +[Install] +WantedBy=multi-user.target +EOF + +sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml + +systemctl daemon-reload +$STD systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service + +msg_ok "Created Services" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 0128a240e11d064351f4b6464b0f5326a5eb8f55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 22:30:40 -0500 Subject: [PATCH 3947/6505] Delete paperless-ngx-update.sh prune --- misc/paperless-ngx-update.sh | 110 ----------------------------------- 1 file changed, 110 deletions(-) delete mode 100644 misc/paperless-ngx-update.sh diff --git a/misc/paperless-ngx-update.sh b/misc/paperless-ngx-update.sh deleted file mode 100644 index 9ab62db6..00000000 --- a/misc/paperless-ngx-update.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env bash -clear -RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -SER=/etc/systemd/system/paperless-task-queue.service -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -e - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -cat <<"EOF" - ____ __ - / __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __ - / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ - / ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> < -/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| - /_/ UPDATE /____/ -EOF - -while true; do - read -p "This will Update Paperless-ngx to $RELEASE. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -sleep 2 -msg_info "Stopping Paperless-ngx" -systemctl stop paperless-consumer paperless-webserver paperless-scheduler -if [ -f "$SER" ]; then - systemctl stop paperless-task-queue.service -fi -sleep 1 -msg_ok "Stopped Paperless-ngx" - -msg_info "Updating to ${RELEASE}" -if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null -wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null -tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null -cp -r /opt/paperless/paperless.conf paperless-ngx/ -cp -r paperless-ngx/* /opt/paperless/ -cd /opt/paperless -sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt -pip install -r requirements.txt &>/dev/null -cd /opt/paperless/src -/usr/bin/python3 manage.py migrate &>/dev/null -if [ -f "$SER" ]; then - msg_ok "paperless-task-queue.service Exists." -else -cat </etc/systemd/system/paperless-task-queue.service -[Unit] -Description=Paperless Celery Workers -Requires=redis.service -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless worker --loglevel INFO -[Install] -WantedBy=multi-user.target -EOF -systemctl enable paperless-task-queue &>/dev/null -msg_ok "paperless-task-queue.service Created." -fi -cat </etc/systemd/system/paperless-scheduler.service -[Unit] -Description=Paperless Celery beat -Requires=redis.service -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless beat --loglevel INFO -[Install] -WantedBy=multi-user.target -EOF -msg_ok "Updated to ${RELEASE}" - -msg_info "Cleaning up" -cd ~ -rm paperless-ngx-$RELEASE.tar.xz -rm -rf paperless-ngx -msg_ok "Cleaned" - -msg_info "Starting Paperless-ngx" -systemctl daemon-reload -systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service -sleep 1 -msg_ok "Finished Update" -echo -e "\n${BL}It may take a minute or so for Paperless-ngx to become available.${CL}\n" From 99d8cb4e623237fb2adc5866b82924fc870366ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 23:09:50 -0500 Subject: [PATCH 3948/6505] Create esphome-v5.sh --- ct/esphome-v5.sh | 366 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 ct/esphome-v5.sh diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh new file mode 100644 index 00000000..b2d8d894 --- /dev/null +++ b/ct/esphome-v5.sh @@ -0,0 +1,366 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ___________ ____ __ __ + / ____/ ___// __ \/ / / /___v5____ ___ ___ + / __/ \__ \/ /_/ / /_/ / __ \/ __ `__ \/ _ \ + / /___ ___/ / ____/ __ / /_/ / / / / / / __/ +/_____//____/_/ /_/ /_/\____/_/ /_/ /_/\___/ + +EOF +} +echo -e "Loading..." +APP="ESPHome" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /usr/local/bin/esphome ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Stopping ESPHome" +systemctl stop esphomeDashboard +msg_ok "Stopped ESPHome" + +msg_info "Updating ESPHome" +pip3 install esphome --upgrade &>/dev/null +msg_ok "Updated ESPHome" + +msg_info "Starting ESPHome" +systemctl stop esphomeDashboard +msg_ok "Started ESPHome" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6052${CL} \n" From 36462296d3360e8a19fb15e528bf446be1f35d90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Jan 2023 23:11:27 -0500 Subject: [PATCH 3949/6505] Create esphome-v5-install.sh --- install/esphome-v5-install.sh | 140 ++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 install/esphome-v5-install.sh diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh new file mode 100644 index 00000000..22f1a6f2 --- /dev/null +++ b/install/esphome-v5-install.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Installing pip3" +$STD apt-get install -y python3-pip +msg_ok "Installed pip3" + +msg_info "Installing ESPHome" +$STD pip3 install esphome +msg_ok "Installed ESPHome" + +msg_info "Installing ESPHome Dashboard" +$STD pip3 install tornado esptool + +service_path="/etc/systemd/system/esphomeDashboard.service" +echo "[Unit] +Description=ESPHome Dashboard +After=network.target +[Service] +ExecStart=/usr/local/bin/esphome /root/config/ dashboard +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable esphomeDashboard.service +systemctl start esphomeDashboard +msg_ok "Installed ESPHome Dashboard" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From fbe5a0bed69943711a6c347763da174369df61c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 08:06:33 -0500 Subject: [PATCH 3950/6505] Update homeassistant-v5.sh rename --- ct/homeassistant-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 76923192..651d322b 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -86,7 +86,7 @@ if ! command -v pveversion >/dev/null 2>&1; then msg_error "No ${APP} Installation Found!"; exit fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + if (whiptail --title "${APP} LXC TOOLS" --yesno "This provides ${APP} Tools. Proceed?" 10 58); then echo "User selected Yes" else clear From 3f75be8ce51dc7c017a47a2159653a25be81920c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 09:20:34 -0500 Subject: [PATCH 3951/6505] Update paperless-ngx-v5.sh tweak --- ct/paperless-ngx-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 49f780b0..fb3aa3f6 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -86,8 +86,8 @@ if ! command -v pveversion >/dev/null 2>&1; then msg_error "No ${APP} Installation Found!"; exit fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" + if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then + echo "User selected support" else clear echo -e "⚠ User exited script \n" From 19fdc661f5c8849db1eaf58886e81f40ee7bdcdd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 09:22:34 -0500 Subject: [PATCH 3952/6505] Update paperless-ngx-v5-install.sh tweak --- install/paperless-ngx-v5-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index ce87d088..d9bf955e 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -173,7 +173,7 @@ echo $DB_PASS >>~/paperless.creds echo "Paperless-ngx Database Name" >>~/paperless.creds echo $DB_NAME >>~/paperless.creds -/bin/bash -c "mkdir -p {consume,media}" +mkdir -p {consume,media} sed -i -e 's|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=paperlessdb|' /opt/paperless/paperless.conf sed -i -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" /opt/paperless/paperless.conf @@ -181,7 +181,7 @@ SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" sed -i -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" /opt/paperless/paperless.conf cd /opt/paperless/src -$STD /usr/bin/python3 manage.py migrate +$STD python3 manage.py migrate msg_ok "Set up database" msg_info "Setting up admin Paperless-ngx User & Password" From f4113c4129331881d7b49d26b84310818ddca653 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 09:27:37 -0500 Subject: [PATCH 3953/6505] Update homeassistant-core-v5.sh tweak --- ct/homeassistant-core-v5.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 48f56625..ce167db9 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -74,22 +74,22 @@ function PVE_CHECK() { fi } -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /srv/homeassistant ]]; then - msg_error "No Home Assistant Core Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC TOOLS" --yesno "Tools to Initialize, Update and Install HACS. Proceed?" 10 58); then - echo "User selected Yes" +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) else clear echo -e "⚠ User exited script \n" exit fi fi -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /srv/homeassistant ]]; then + msg_error "No Home Assistant Core Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC SUPPORT" --yesno "Initialize, Update or Install HACS. Proceed?" 10 58); then + echo "User selected Support" else clear echo -e "⚠ User exited script \n" From e45acf93bf009142c2c46e7ca1ad3f93da9885e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 09:32:57 -0500 Subject: [PATCH 3954/6505] Update homeassistant-v5.sh tweak --- ct/homeassistant-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 651d322b..e54c59af 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -86,8 +86,8 @@ if ! command -v pveversion >/dev/null 2>&1; then msg_error "No ${APP} Installation Found!"; exit fi - if (whiptail --title "${APP} LXC TOOLS" --yesno "This provides ${APP} Tools. Proceed?" 10 58); then - echo "User selected Yes" + if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then + echo "User selected support" else clear echo -e "⚠ User exited script \n" From 2deeaffd69b9662d321b9ca398a2b1c0bd634388 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 09:35:41 -0500 Subject: [PATCH 3955/6505] Update vaultwarden-v5.sh tweak --- ct/vaultwarden-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index b0c24459..f7e9b34e 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -84,8 +84,8 @@ if ! command -v pveversion >/dev/null 2>&1; then msg_error "No ${APP} Installation Found!"; exit fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP}. Proceed?" 10 58); then - echo "User selected Update" + if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then + echo "User selected support" else clear echo -e "⚠ User exited script \n" From 0880352c1a969b06a33378bad8f3fab5abd65b5a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 09:57:48 -0500 Subject: [PATCH 3956/6505] Update docker-v5.sh tweak --- ct/docker-v5.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 04c639dc..50ddd2b7 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -81,7 +81,7 @@ if command -v pveversion >/dev/null 2>&1; then fi if ! command -v pveversion >/dev/null 2>&1; then if [[ ! -d /etc/docker ]]; then - msg_error "No Docker Installation Found!"; + msg_error "No ${APP} Installation Found!"; exit fi if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then @@ -317,10 +317,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Docker LXC" +msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Docker LXC" +msg_ok "Updated ${APP} LXC" exit } clear From 3413c4e6e40d4813f5eea28c2319d308b7dc81ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 10:33:10 -0500 Subject: [PATCH 3957/6505] Create mqtt-v5.sh --- ct/mqtt-v5.sh | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 ct/mqtt-v5.sh diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh new file mode 100644 index 00000000..9b8f137c --- /dev/null +++ b/ct/mqtt-v5.sh @@ -0,0 +1,358 @@ +#!/usr/bin/env bash +function header_info { +cat <<"EOF" + __ ___ ____ _ ____________ + / |/ /___v5_____/ __ \__ __(_)_ __/_ __/___ + / /|_/ / __ \/ ___/ / / / / / / / / / / / / __ \ + / / / / /_/ (__ ) /_/ / /_/ / / / / / / / /_/ / +/_/ /_/\____/____/\___\_\__,_/_/ /_/ /_/ \____/ + +EOF +} +echo -e "Loading..." +APP="MQTT" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/mosquitto-bullseye.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 96bafed52efa5fad957bd12cecde87d7a7154cb0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 10:34:19 -0500 Subject: [PATCH 3958/6505] Create mqtt-v5-install.sh --- install/mqtt-v5-install.sh | 125 +++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 install/mqtt-v5-install.sh diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh new file mode 100644 index 00000000..8ab82ce6 --- /dev/null +++ b/install/mqtt-v5-install.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing Mosquitto MQTT Broker" +$STD wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key +$STD apt-key add mosquitto-repo.gpg.key +cd /etc/apt/sources.list.d/ +$STD wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list +$STD apt-get update +$STD apt-get -y install mosquitto +$STD apt-get -y install mosquitto-clients +msg_ok "Installed Mosquitto MQTT Broker" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 79a4c050d737ab5ed0d54502c5bebd0a77bb7fd2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 14:45:34 -0500 Subject: [PATCH 3959/6505] Create node-red-v5.sh --- ct/node-red-v5.sh | 398 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 ct/node-red-v5.sh diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh new file mode 100644 index 00000000..c0b801b8 --- /dev/null +++ b/ct/node-red-v5.sh @@ -0,0 +1,398 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ __ __ ____ __ + / | / /___ ____/ /__ v5 / __ \___ ____/ / + / |/ / __ \/ __ / _ \ / /_/ / _ \/ __ / + / /| / /_/ / /_/ / __/ / _, _/ __/ /_/ / +/_/ |_/\____/\__,_/\___/ /_/ |_|\___/\__,_/ + +EOF +} +echo -e "Loading..." +APP="Node-Red" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /root/.node-red ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then + echo "User selected support" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Update ${APP}" ON \ + "2" "Install Themes" OFF \ + 3>&1 1>&2 2>&3) +clear +header_info +if [ "$UPD" == "1" ]; then +msg_info "Stopping ${APP}" +systemctl stop nodered +msg_ok "Stopped ${APP}" + +msg_info "Updating ${APP}" +npm install -g --unsafe-perm node-red &>/dev/null +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +systemctl start nodered +msg_ok "Started ${APP}" +msg_ok "Update Successful" +exit +fi +if [ "$UPD" == "2" ]; then +clear +header_info +THEME=$(whiptail --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ + "dark" "" OFF \ + "dracula" "" OFF \ + "midnight-red" "" ON \ + "oled" "" OFF \ + "solarized-dark" "" OFF \ + "solarized-light" "" OFF \ + 3>&1 1>&2 2>&3) +clear +header_info +msg_info "Installing ${THEME} Theme" +cd /root/.node-red +sed -i 's|//theme: "",|theme: "",|g' /root/.node-red/settings.js +npm install @node-red-contrib-themes/${THEME} &>/dev/null +sed -i "{s/theme: ".*"/theme: '${THEME}',/g}" /root/.node-red/settings.js +msg_ok "Installed ${THEME} Theme" + +msg_info "Restarting ${APP}" +systemctl restart nodered +msg_ok "Restarted ${APP}" +exit +fi +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:1880${CL} \n" From de8e2a02f639f3b1d9a643ef6fc40accf95c81eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 14:47:09 -0500 Subject: [PATCH 3960/6505] Create node-red-v5-install.sh --- install/node-red-v5-install.sh | 150 +++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 install/node-red-v5-install.sh diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh new file mode 100644 index 00000000..a6613d6e --- /dev/null +++ b/install/node-red-v5-install.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Node-Red" +$STD npm install -g --unsafe-perm node-red +msg_ok "Installed Node-Red" + +msg_info "Creating Service" +service_path="/etc/systemd/system/nodered.service" +echo "[Unit] +Description=Node-RED +After=syslog.target network.target + +[Service] +ExecStart=/usr/bin/node-red --max-old-space-size=128 -v +Restart=on-failure +KillSignal=SIGINT + +SyslogIdentifier=node-red +StandardOutput=syslog + +WorkingDirectory=/root/ +User=root +Group=root + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now nodered.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From a109366472a36ba0652ff6dd23f2601570b65d6c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 15:34:59 -0500 Subject: [PATCH 3961/6505] Delete node-red-themes.sh prune --- misc/node-red-themes.sh | 146 ---------------------------------------- 1 file changed, 146 deletions(-) delete mode 100644 misc/node-red-themes.sh diff --git a/misc/node-red-themes.sh b/misc/node-red-themes.sh deleted file mode 100644 index 1a813bc1..00000000 --- a/misc/node-red-themes.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env bash -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/node-red-themes.sh)" -set -o errexit -show_menu() { - YW=$(echo "\033[33m") - RD=$(echo "\033[01;31m") - BL=$(echo "\033[36m") - CM='\xE2\x9C\x94\033' - GN=$(echo "\033[1;92m") - CL=$(echo "\033[m") - echo -e "${RD} Backup your Node-Red flows before running this script!!${CL} \n " - while true; do - read -p "This will Install Node-Red Themes. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac - done - clear - echo -e "${RD} Backup your Node-Red flows before installing any theme!!${CL} \n " - printf "\n${BL}*********************************************${CL}\n" - printf "${BL}**${YW} 1)${GN} Default Theme ${CL}\n" - printf "${BL}**${YW} 2)${GN} Dark Theme ${CL}\n" - printf "${BL}**${YW} 3)${GN} Dracula Theme ${CL}\n" - printf "${BL}**${YW} 4)${GN} Midnight-Red Theme ${CL}\n" - printf "${BL}**${YW} 5)${GN} Oled Theme ${CL}\n" - printf "${BL}**${YW} 6)${GN} Solarized-Dark Theme ${CL}\n" - printf "${BL}**${YW} 7)${GN} Solarized-Light Theme ${CL}\n" - printf "${BL}*********************************************${CL}\n" - printf "Please choose a theme from the menu and enter or ${RD}x to exit. ${CL}" - read opt -} - -option_picked() { - msgcolor=$(echo "\033[01;31m") - normal=$(echo "\033[00;00m") - message=${@:-"${CL}Error: No message passed"} - printf "${RD}${message}${CL}\n" -} - -clear -show_menu -while [ "$opt" != " " ]; do - case $opt in - 1) - clear - option_picked "Installing Default Theme" - THEME= - JS=// - break - ;; - 2) - clear - option_picked "Installing Dark Theme" - THEME=dark - break - ;; - 3) - clear - option_picked "Installing Dracula Theme" - THEME=dracula - break - ;; - 4) - clear - option_picked "Installing Midnight-Red Theme" - THEME=midnight-red - break - ;; - 5) - clear - option_picked "Installing Oled Theme" - THEME=oled - break - ;; - 6) - clear - option_picked "Installing Solarized-Dark Theme" - THEME=solarized-dark - break - ;; - 7) - clear - option_picked "Installing Solarized-Light Theme" - THEME=solarized-light - break - ;; - - x) - exit - ;; - \n) - exit - ;; - *) - clear - option_picked "Please choose a theme from the menu" - show_menu - ;; - esac -done -echo -en "${GN} Installing ${THEME} Theme... " -cd /root/.node-red -if [ "${THEME}" = "" ]; then - echo -e "${CM}${CL} \r" -else - npm install @node-red-contrib-themes/${THEME} &>/dev/null - echo -e "${CM}${CL} \r" -fi -echo -en "${GN} Writing Settings... " -cat </root/.node-red/settings.js -module.exports = { uiPort: process.env.PORT || 1880, - mqttReconnectTime: 15000, - serialReconnectTime: 15000, - debugMaxLength: 1000, - functionGlobalContext: { - }, - exportGlobalContextKeys: false, - - // Configure the logging output - logging: { - console: { - level: "info", - metrics: false, - audit: false - } - }, - - // Customising the editor - editorTheme: { - ${JS}theme: "${THEME}" - }, - projects: { - // To enable the Projects feature, set this value to true - enabled: false - } -} -EOF -echo -e "${CM}${CL} \r" - -echo -en "${GN} Restarting Node-Red... " -echo -e "${CM}${CL} \r" -systemctl restart nodered -echo -en "${GN} Finished... ${CL} \n" -exit From 4a8e00adf74e5dd744dc18512767207e47a07398 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 16:42:47 -0500 Subject: [PATCH 3962/6505] Create emqx-v5.sh --- ct/emqx-v5.sh | 359 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 ct/emqx-v5.sh diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh new file mode 100644 index 00000000..7efa5a96 --- /dev/null +++ b/ct/emqx-v5.sh @@ -0,0 +1,359 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ________ _______v5 _ __ + / ____/ |/ / __ \ | |/ / + / __/ / /|_/ / / / / | / + / /___/ / / / /_/ / / | +/_____/_/ /_/\___\_\/_/|_| + +EOF +} +echo -e "Loading..." +APP="EMQX" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:18083${CL} \n" From a4b723d64f31f9d3b92c93e5019b942eb50b78aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 16:43:50 -0500 Subject: [PATCH 3963/6505] Create emqx-v5-install.sh --- install/emqx-v5-install.sh | 118 +++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 install/emqx-v5-install.sh diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh new file mode 100644 index 00000000..cc8f968f --- /dev/null +++ b/install/emqx-v5-install.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing EMQX" +$STD bash <(curl -fsSL https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh) +$STD apt-get install -y emqx +$STD systemctl enable --now emqx +msg_ok "Installed EMQX" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 86a346aeaf26181eca41f2b361ff335a34e71a8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 17:50:31 -0500 Subject: [PATCH 3964/6505] Create haos-vm-tteck.sh --- vm/haos-vm-tteck.sh | 276 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 vm/haos-vm-tteck.sh diff --git a/vm/haos-vm-tteck.sh b/vm/haos-vm-tteck.sh new file mode 100644 index 00000000..668325c2 --- /dev/null +++ b/vm/haos-vm-tteck.sh @@ -0,0 +1,276 @@ +#!/usr/bin/env bash +echo -e "Loading..." +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +NEXTID=$(pvesh get /cluster/nextid) +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') +LATEST=$(curl -s https://api.github.com/repos/home-assistant/operating-system/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +YW=`echo "\033[33m"` +BL=`echo "\033[36m"` +HA=`echo "\033[1;34m"` +RD=`echo "\033[01;31m"` +BGN=`echo "\033[4;92m"` +GN=`echo "\033[1;92m"` +DGN=`echo "\033[32m"` +CL=`echo "\033[m"` +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: 7.XX" + echo "Exiting..." + sleep 3 + exit +fi +if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi +function header_info { +cat <<"EOF" + __ __ ___ _ __ __ ____ _____ + / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ + +EOF +} +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function default_settings() { + echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" + HN=haos${STABLE} + echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" +} +function advanced_settings() { +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 4 \ +"$STABLE" "Stable" ON \ +"$BETA" "Beta" OFF \ +"$DEV" "Dev" OFF \ +"$LATEST" "Latest" OFF \ +3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi +VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; +fi +VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $VM_NAME ]; then HN="haos${BRANCH}"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; +else + if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; +fi +CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; +fi +RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; +fi +BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; +else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; +fi +MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ -z $MAC1 ]; then MAC="$GEN_MAC"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}"; +else + if [ $exitstatus = 0 ]; then MAC="$MAC1"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"; fi +fi +VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi +fi +if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" +else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" +fi +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +function start_script() { +if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} +start_script +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi +STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then +msg_error "Unable to detect a valid storage location." + exit +elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the HAOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +if [ "$BRANCH" == "$DEV" ]; then +URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +else +URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +fi +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" +msg_info "Extracting KVM Disk Image" +unxz $FILE +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in + nfs|dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; + btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_FORMAT="subvol" + DISK_IMPORT="-format raw" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +msg_ok "Extracted KVM Disk Image" +msg_info "Creating HAOS VM" +qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ + -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null +qm set $VMID \ + -boot order=scsi0 >/dev/null +qm set $VMID -description "# Home Assistant OS +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null +msg_ok "Created HAOS VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then +msg_info "Starting Home Assistant OS VM" +qm start $VMID +msg_ok "Started Home Assistant OS VM" +fi +msg_ok "Completed Successfully!\n" From 0f71fadbd5958fe7fa6c914f6e50dbded45541d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 18:28:18 -0500 Subject: [PATCH 3965/6505] Update haos-vm-v4.sh tweak --- vm/haos-vm-v4.sh | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index d4890df0..6ff12f64 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -1,6 +1,18 @@ #!/usr/bin/env bash -echo -e "Loading..." -GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +function header_info { +cat <<"EOF" + __ __ ___ _ __ __ ____ _____ + / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ + +EOF +} +clear +header_info +echo -e "\n Loading..." +GEN_MAC=$(echo 'AE 1A 60'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') @@ -64,16 +76,7 @@ else echo -e "⚠ User exited script \n" exit fi -function header_info { -cat <<"EOF" - __ __ ___ _ __ __ ____ _____ - / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ - / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ -EOF -} function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." From 4fd380b34c19a0020b4ee029cd41bbd02c57ca74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 18:29:37 -0500 Subject: [PATCH 3966/6505] Delete haos-vm-tteck.sh --- vm/haos-vm-tteck.sh | 276 -------------------------------------------- 1 file changed, 276 deletions(-) delete mode 100644 vm/haos-vm-tteck.sh diff --git a/vm/haos-vm-tteck.sh b/vm/haos-vm-tteck.sh deleted file mode 100644 index 668325c2..00000000 --- a/vm/haos-vm-tteck.sh +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') -NEXTID=$(pvesh get /cluster/nextid) -STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -LATEST=$(curl -s https://api.github.com/repos/home-assistant/operating-system/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -HA=`echo "\033[1;34m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: 7.XX" - echo "Exiting..." - sleep 3 - exit -fi -if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { -cat <<"EOF" - __ __ ___ _ __ __ ____ _____ - / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ - / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function default_settings() { - echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" - HN=haos${STABLE} - echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" - CORE_COUNT="2" - echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" - echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" -} -function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 4 \ -"$STABLE" "Stable" ON \ -"$BETA" "Beta" OFF \ -"$DEV" "Dev" OFF \ -"$LATEST" "Latest" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi -VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; -fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $VM_NAME ]; then HN="haos${BRANCH}"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $MAC1 ]; then MAC="$GEN_MAC"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}"; -else - if [ $exitstatus = 0 ]; then MAC="$MAC1"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"; fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" -else - echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" - START_VM="no" -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} -function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} -start_script -msg_info "Validating Storage" -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi -STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content images | awk 'NR>1') -VALID=$(pvesm status -content images | awk 'NR>1') -if [ -z "$VALID" ]; then -msg_error "Unable to detect a valid storage location." - exit -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the HAOS VM?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" -if [ "$BRANCH" == "$DEV" ]; then -URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -else -URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -fi -sleep 2 -msg_ok "${CL}${BL}${URL}${CL}" -wget -q --show-progress $URL -echo -en "\e[1A\e[0K" -FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" -msg_info "Extracting KVM Disk Image" -unxz $FILE -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DISK_IMPORT="-format qcow2" - ;; - btrfs) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_FORMAT="subvol" - DISK_IMPORT="-format raw" - ;; -esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done -msg_ok "Extracted KVM Disk Image" -msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ - -scsi0 ${DISK1_REF},discard=on,size=32G,ssd=1 >/dev/null -qm set $VMID \ - -boot order=scsi0 >/dev/null -qm set $VMID -description "# Home Assistant OS -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null -msg_ok "Created HAOS VM ${CL}${BL}(${HN})" -if [ "$START_VM" == "yes" ]; then -msg_info "Starting Home Assistant OS VM" -qm start $VMID -msg_ok "Started Home Assistant OS VM" -fi -msg_ok "Completed Successfully!\n" From 588b7b5942f21ca5265be9d7cd54bfa0dbe0fd7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 19:09:02 -0500 Subject: [PATCH 3967/6505] Update haos-vm-v4.sh set minimum PVE version 7.2 --- vm/haos-vm-v4.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 6ff12f64..ee2c7cd2 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -62,9 +62,9 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then +if [ `pveversion | grep "pve-manager/7.2" | wc -l` -ne 1 ]; then echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: 7.XX" + echo "Requires PVE Version: =>7.2" echo "Exiting..." sleep 3 exit From b402e0d5fe7b68d14fae5ecef769f45fabece532 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 19:54:25 -0500 Subject: [PATCH 3968/6505] Update haos-vm-v4.sh --- vm/haos-vm-v4.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index ee2c7cd2..6c321bfb 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -62,7 +62,7 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7.2" | wc -l` -ne 1 ]; then +if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then echo "⚠ This version of Proxmox Virtual Environment is not supported" echo "Requires PVE Version: =>7.2" echo "Exiting..." From 1a876727af51c06f1365a1c20910fcf3c5f2f357 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 20:18:51 -0500 Subject: [PATCH 3969/6505] Update haos-vm-v4.sh fix minimum PVE check --- vm/haos-vm-v4.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 6c321bfb..85e12e84 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -62,13 +62,15 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then +if [ `pveversion | grep "pve-manager/7.2" | wc -l` -ne 1 ]; then + if [ `pveversion | grep "pve-manager/7.3" | wc -l` -ne 1 ]; then echo "⚠ This version of Proxmox Virtual Environment is not supported" echo "Requires PVE Version: =>7.2" echo "Exiting..." sleep 3 exit -fi + fi +fi if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then echo "User selected Yes" else From a0f9a1c20de708094229dfca90e924e1ac980018 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 2 Jan 2023 20:37:59 -0500 Subject: [PATCH 3970/6505] Update haos-vm-v4.sh tweak --- vm/haos-vm-v4.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index 85e12e84..c66b2e6f 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -62,14 +62,12 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7.2" | wc -l` -ne 1 ]; then - if [ `pveversion | grep "pve-manager/7.3" | wc -l` -ne 1 ]; then +if [ `pveversion | grep "pve-manager/7.2\|7.3" | wc -l` -ne 1 ]; then echo "⚠ This version of Proxmox Virtual Environment is not supported" echo "Requires PVE Version: =>7.2" echo "Exiting..." sleep 3 exit - fi fi if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then echo "User selected Yes" From cdf10a1c95388f3c473ec136e90b5cbbf710f644 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 07:15:12 -0500 Subject: [PATCH 3971/6505] Update vaultwarden-v5.sh remove update redirects --- ct/vaultwarden-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index f7e9b34e..2f7d16ae 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -330,9 +330,9 @@ systemctl stop vaultwarden.service msg_ok "Stopped Vaultwarden" msg_info "Updating VaultWarden to $VAULT (Patience)" -git clone https://github.com/dani-garcia/vaultwarden &>/dev/null +git clone https://github.com/dani-garcia/vaultwarden cd vaultwarden -cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null +cargo build --features "sqlite,mysql,postgresql" --release DIR=/usr/bin/vaultwarden if [ -d "$DIR" ]; then cp target/release/vaultwarden /usr/bin/ From f0964ac751d4d4d0e51f588ba43b5dd21b30a964 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 07:29:03 -0500 Subject: [PATCH 3972/6505] Update homeassistant-core-v5.sh Dependency Version issue fixed in Beta --- ct/homeassistant-core-v5.sh | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index ce167db9..195be24c 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -351,16 +351,10 @@ source /srv/homeassistant/bin/activate pip install ${BR}--upgrade homeassistant &>/dev/null msg_ok "Updated Home Assistant" -msg_info "Setting Dependency Versions" - if [ "${BR}" == "--pre " ]; then - sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt - sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json - else + if [ "${BR}" == "" ]; then sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json fi -sleep 2 -msg_ok "Set Dependency Versions" msg_info "Starting Home Assistant" systemctl start homeassistant From c26fe0e79058db8ae73dd5b31eafa20c308af030 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 07:53:28 -0500 Subject: [PATCH 3973/6505] Update adguard-v5.sh add endpoint in notes --- ct/adguard-v5.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 7255389e..ed6b2621 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -370,6 +370,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC +Setup http://${IP}:3000 +http://${IP} ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" From 7f076f04629aaf1ea5bd79919f16fcafeab40324 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 07:56:44 -0500 Subject: [PATCH 3974/6505] Update adguard-v5.sh tweak --- ct/adguard-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index ed6b2621..0f9fd64b 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -371,6 +371,7 @@ lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/ IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC Setup http://${IP}:3000 + http://${IP} ### https://tteck.github.io/Proxmox/ " From 8484a5fd27ffe4df40c9e559af26564f5f0a9431 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 08:01:23 -0500 Subject: [PATCH 3975/6505] Update adguard-v5.sh tweak --- ct/adguard-v5.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 0f9fd64b..92aaeabf 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -370,9 +370,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -Setup http://${IP}:3000 - -http://${IP} +### Setup http://${IP}:3000 +### http://${IP} ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" From 313f1d7c8462eed2ff8e5dfd024e6722ef894b37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 08:05:05 -0500 Subject: [PATCH 3976/6505] Update adguard-v5.sh tweak --- ct/adguard-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 92aaeabf..7066f8ac 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -370,8 +370,8 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -### Setup http://${IP}:3000 -### http://${IP} +#### Setup http://${IP}:3000 +#### http://${IP} ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" From 2827c54ef87a038818f32fe01f67f5d45a17b8b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 08:25:02 -0500 Subject: [PATCH 3977/6505] Update adguard-v5.sh revert endpoint in notes --- ct/adguard-v5.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 7066f8ac..7255389e 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -370,8 +370,6 @@ msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC -#### Setup http://${IP}:3000 -#### http://${IP} ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" From 44168d628f0ffdfd74602c9765e8cfb089341d3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 09:00:43 -0500 Subject: [PATCH 3978/6505] Create uptimekuma-v5.sh --- ct/uptimekuma-v5.sh | 377 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 ct/uptimekuma-v5.sh diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh new file mode 100644 index 00000000..2bbad0d6 --- /dev/null +++ b/ct/uptimekuma-v5.sh @@ -0,0 +1,377 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ __ _ __ __ + / / / /___ / /_(_)___ ___ ___ v5 / //_/_ ______ ___ ____ _ + / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / +/ /_/ / /_/ / /_/ / / / / / / __/ / /| / /_/ / / / / / / /_/ / +\____/ .___/\__/_/_/ /_/ /_/\___/ /_/ |_\__,_/_/ /_/ /_/\__,_/ + /_/ + +EOF +} +echo -e "Loading..." +APP="Uptime Kuma" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/uptime-kuma ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Stopping ${APP}" +sudo systemctl stop uptime-kuma &>/dev/null +msg_ok "Stopped ${APP}" + +cd /opt/uptime-kuma + +msg_info "Pulling ${APP} ${LATEST}" +git fetch --all &>/dev/null +git checkout $LATEST --force &>/dev/null +git pull &>/dev/null +msg_ok "Pulled ${APP} ${LATEST}" + +msg_info "Updating ${APP} to ${LATEST}" +npm install --production &>/dev/null +npm run download-dist &>/dev/null +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +sudo systemctl start uptime-kuma &>/dev/null +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3001${CL} \n" From 0a910530aafc7118c118292a82294cca71e54db3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 09:02:07 -0500 Subject: [PATCH 3979/6505] Create uptimekuma-v5-install.sh --- install/uptimekuma-v5-install.sh | 147 +++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 install/uptimekuma-v5-install.sh diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh new file mode 100644 index 00000000..87e80bc2 --- /dev/null +++ b/install/uptimekuma-v5-install.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD sudo apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Uptime Kuma" +$STD git clone https://github.com/louislam/uptime-kuma.git +mv uptime-kuma /opt/uptime-kuma +cd /opt/uptime-kuma +$STD npm run setup +msg_ok "Installed Uptime Kuma" + +msg_info "Creating Service" +service_path="/etc/systemd/system/uptime-kuma.service" +echo "[Unit] +Description=uptime-kuma + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/uptime-kuma +ExecStart=/usr/bin/npm start + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now uptime-kuma.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 8dcfdff45757302de49251ecd049eb878cd794d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 10:22:39 -0500 Subject: [PATCH 3980/6505] Update uptimekuma-v5.sh tweak --- ct/uptimekuma-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 2bbad0d6..b867ffe4 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -311,6 +311,7 @@ function install_script() { function update_script() { clear header_info +LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Stopping ${APP}" sudo systemctl stop uptime-kuma &>/dev/null msg_ok "Stopped ${APP}" From fb7c87245c1ef3017890b8bd655f07503514d64a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 10:44:48 -0500 Subject: [PATCH 3981/6505] Update uptimekuma-v5.sh --- ct/uptimekuma-v5.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index b867ffe4..6a5c16a1 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -321,7 +321,6 @@ cd /opt/uptime-kuma msg_info "Pulling ${APP} ${LATEST}" git fetch --all &>/dev/null git checkout $LATEST --force &>/dev/null -git pull &>/dev/null msg_ok "Pulled ${APP} ${LATEST}" msg_info "Updating ${APP} to ${LATEST}" From 2b88f1567ce1e5fe32e660f2b820dd8f747b2f01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 10:47:50 -0500 Subject: [PATCH 3982/6505] Delete uptimekuma-update.sh prune --- misc/uptimekuma-update.sh | 74 --------------------------------------- 1 file changed, 74 deletions(-) delete mode 100644 misc/uptimekuma-update.sh diff --git a/misc/uptimekuma-update.sh b/misc/uptimekuma-update.sh deleted file mode 100644 index be946ea7..00000000 --- a/misc/uptimekuma-update.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash -ex -LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Uptime Kuma" -while true; do - read -p "This will Update ${APP} to ${LATEST}. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - echo -e "${DGN} - _ _ _ _ _ __ - | | | | | | (_) | |/ / - | | | |_v3_ | |_ _ _ __ ___ ___ | ' /_ _ _ __ ___ __ _ - | | | | _ \| __| | _ _ \ / _ \ | <| | | | _ _ \ / _ | - | |__| | |_) | |_| | | | | | | __/ | . \ |_| | | | | | | (_| | - \____/| .__/ \__|_|_| |_| |_|\___| |_|\_\__,_|_| |_| |_|\__,_| - | | - |_| UPDATE -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -if [ ! -d "/opt/uptime-kuma" ]; then - echo -e "No Uptime Kuma Directory Found." - exit -fi - -msg_info "Stopping ${APP}" -sudo systemctl stop uptime-kuma &>/dev/null -msg_ok "Stopped ${APP}" - -cd /opt/uptime-kuma - -msg_info "Pulling ${APP} ${LATEST}" -git fetch --all &>/dev/null -git checkout $LATEST --force &>/dev/null -git pull &>/dev/null -msg_ok "Pulled ${APP} ${LATEST}" - -msg_info "Updating ${APP} to ${LATEST}" -npm install --production &>/dev/null -npm run download-dist &>/dev/null -msg_ok "Updated ${APP}" - -msg_info "Starting ${APP}" -sudo systemctl start uptime-kuma &>/dev/null -msg_ok "Started ${APP}" - -msg_ok "Done!" From 3c651637d8aac9caa3878172810baef98c3d251e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 11:32:21 -0500 Subject: [PATCH 3983/6505] Create pihole-v5-install.sh --- install/pihole-v5-install.sh | 138 +++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 install/pihole-v5-install.sh diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh new file mode 100644 index 00000000..300ed2d8 --- /dev/null +++ b/install/pihole-v5-install.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +export DEBIAN_FRONTEND=noninteractive +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y ufw +$STD apt-get install -y ntp +msg_ok "Installed Dependencies" + +msg_info "Installing Pi-hole" +mkdir -p /etc/pihole/ +cat </etc/pihole/setupVars.conf +PIHOLE_INTERFACE=eth0 +PIHOLE_DNS_1=8.8.8.8 +PIHOLE_DNS_2=8.8.4.4 +QUERY_LOGGING=true +INSTALL_WEB_SERVER=true +INSTALL_WEB_INTERFACE=true +LIGHTTPD_ENABLED=true +CACHE_SIZE=10000 +DNS_FQDN_REQUIRED=true +DNS_BOGUS_PRIV=true +DNSMASQ_LISTENING=local +WEBPASSWORD=$(openssl rand -base64 48) +BLOCKING_ENABLED=true +EOF + +$STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended +msg_ok "Installed Pi-hole" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 78580ba07408e2097b0fbbad65f0cf9d8dea14b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 11:34:24 -0500 Subject: [PATCH 3984/6505] Create pihole-v5.sh --- ct/pihole-v5.sh | 360 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 ct/pihole-v5.sh diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh new file mode 100644 index 00000000..0de027c9 --- /dev/null +++ b/ct/pihole-v5.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ ____ __ ______ __ ______ + / __ \/ _/ / / / / __ \/ / / ____/ + / /_/ // /___/ /_/ / / / / / / __/ + / ____// /___/ __ / /_/ / /v5_/ /___ +/_/ /___/ /_/ /_/\____/_____/_____/ + +EOF +} +echo -e "Loading..." +APP="Pihole" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}/admin${CL} \n" From f00f6b31daa3c635c76f04ba1e4e4e4e828eeb6d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 11:38:18 -0500 Subject: [PATCH 3985/6505] Update pihole-v5.sh --- ct/pihole-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 0de027c9..3357d5c0 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -81,7 +81,7 @@ if command -v pveversion >/dev/null 2>&1; then fi fi if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + if [[ ! -d /etc/pihole ]]; then msg_error "No ${APP} Installation Found!"; exit fi From 7f910107d391aca413aad68011a8450361eba8d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 12:12:53 -0500 Subject: [PATCH 3986/6505] Update vaultwarden-v5.sh --- ct/vaultwarden-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 2f7d16ae..6f69bed5 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -330,6 +330,7 @@ systemctl stop vaultwarden.service msg_ok "Stopped Vaultwarden" msg_info "Updating VaultWarden to $VAULT (Patience)" +cd ~ && rm -rf vaultwarden git clone https://github.com/dani-garcia/vaultwarden cd vaultwarden cargo build --features "sqlite,mysql,postgresql" --release From 8c9b48f15c4781712f66fccb3b520c46cab29dc7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 12:34:19 -0500 Subject: [PATCH 3987/6505] Update vaultwarden-v5.sh revert "remove update redirects" --- ct/vaultwarden-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 6f69bed5..d157cd11 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -331,9 +331,9 @@ msg_ok "Stopped Vaultwarden" msg_info "Updating VaultWarden to $VAULT (Patience)" cd ~ && rm -rf vaultwarden -git clone https://github.com/dani-garcia/vaultwarden +git clone https://github.com/dani-garcia/vaultwarden &>/dev/null cd vaultwarden -cargo build --features "sqlite,mysql,postgresql" --release +cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null DIR=/usr/bin/vaultwarden if [ -d "$DIR" ]; then cp target/release/vaultwarden /usr/bin/ From 1b7e8c2a2dadd17b29c26a99c2c23fd0c6100037 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 12:58:41 -0500 Subject: [PATCH 3988/6505] Create heimdalldashboard-v5.sh --- ct/heimdalldashboard-v5.sh | 439 +++++++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 ct/heimdalldashboard-v5.sh diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh new file mode 100644 index 00000000..becc47e9 --- /dev/null +++ b/ct/heimdalldashboard-v5.sh @@ -0,0 +1,439 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ _ _ _ ___ _ _ _ + /\ /\___(_)_ __ ___ __| | __ _| | | / \__ _ ___| |__ | |__ ___ __ _ _ __ __| | + / /_/ / _ \ | '_ ` _ \ / _` |/ _` | | | / /\ / _` / __| '_ \| '_ \ / _ \ / _` | '__/ _` | +/ __ / __/ | | | | | | (_| | (_| | | |v5/ /_// (_| \__ \ | | | |_) | (_) | (_| | | | (_| | +\/ /_/ \___|_|_| |_| |_|\__,_|\__,_|_|_| /___,' \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| + +EOF +} +echo -e "Loading..." +APP="Heimdall Dashboard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/Heimdall ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Stopping ${APP}" +systemctl disable heimdall.service &>/dev/null +systemctl stop heimdall +sleep 1 +msg_ok "Stopped ${APP}" + +msg_info "Backing up Data" +if [ -d "/opt/Heimdall-2.4.6" ]; then + cp -R /opt/Heimdall-2.4.6/database database-backup + cp -R /opt/Heimdall-2.4.6/public public-backup +elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then + cp -R /opt/Heimdall-2.4.7b/database database-backup + cp -R /opt/Heimdall-2.4.7b/public public-backup +elif [[ -d "/opt/Heimdall-2.4.8" ]]; then + cp -R /opt/Heimdall-2.4.8/database database-backup + cp -R /opt/Heimdall-2.4.8/public public-backup +else + cp -R /opt/Heimdall/database database-backup + cp -R /opt/Heimdall/public public-backup +fi +sleep 1 +msg_ok "Backed up Data" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +msg_info "Updating Heimdall Dashboard to ${RELEASE}" +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null +tar xvzf ${RELEASE}.tar.gz &>/dev/null +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +if [ ! -d "/opt/Heimdall" ]; then + mv Heimdall-${VER} /opt/Heimdall +else + cp -R Heimdall-${VER}/* /opt/Heimdall +fi + +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 +[Install] +WantedBy=multi-user.target" >$service_path +msg_ok "Updated Heimdall Dashboard to ${RELEASE}" + +msg_info "Restoring Data" +cp -R database-backup/* /opt/Heimdall/database +cp -R public-backup/* /opt/Heimdall/public +sleep 1 +msg_ok "Restored Data" + +msg_info "Cleanup" +if [ -d "/opt/Heimdall-2.4.6" ]; then + rm -rf /opt/Heimdall-2.4.6 + rm -rf /opt/v2.4.6.tar.gz +elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then + rm -rf /opt/Heimdall-2.4.7b + rm -rf /opt/v2.4.7b.tar.gz +elif [[ -d "/opt/Heimdall-2.4.8" ]]; then + rm -rf /opt/Heimdall-2.4.8 + rm -rf /opt/v2.4.8.tar.gz +fi + +rm -rf ${RELEASE}.tar.gz +rm -rf Heimdall-${VER} +rm -rf public-backup +rm -rf database-backup +rm -rf Heimdall +sleep 1 +msg_ok "Cleaned" + +msg_info "Starting ${APP}" +systemctl enable --now heimdall.service &>/dev/null +sleep 2 +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7990${CL} \n" From 7bb1329a801eca8feb532d572171f45517d460ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 13:00:03 -0500 Subject: [PATCH 3989/6505] Create heimdalldashboard-v5-install.sh --- install/heimdalldashboard-v5-install.sh | 151 ++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 install/heimdalldashboard-v5-install.sh diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh new file mode 100644 index 00000000..41185b39 --- /dev/null +++ b/install/heimdalldashboard-v5-install.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing PHP" +$STD apt-get install -y php +$STD apt-get install -y php-sqlite3 +$STD apt-get install -y php-zip +msg_ok "Installed PHP" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +msg_info "Installing Heimdall Dashboard ${RELEASE}" +$STD curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" +$STD tar xvzf ${RELEASE}.tar.gz +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') +rm -rf ${RELEASE}.tar.gz +mv Heimdall-${VER} /opt/Heimdall +msg_ok "Installed Heimdall Dashboard ${RELEASE}" + +msg_info "Creating Service" +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target + +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 + +[Install] +WantedBy=multi-user.target" >$service_path +$STD sudo systemctl enable --now heimdall.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From fbbe3e64c1f0449c424217a861378c8a739cd7c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 13:00:42 -0500 Subject: [PATCH 3990/6505] Update heimdalldashboard-v5.sh --- ct/heimdalldashboard-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index becc47e9..5ed5886b 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -429,7 +429,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ From acb4d7c0e8b815bf818d169a2c483ed6b38b65de Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 14:29:38 -0500 Subject: [PATCH 3991/6505] Create grafana-v5-install.sh --- install/grafana-v5-install.sh | 131 ++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 install/grafana-v5-install.sh diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh new file mode 100644 index 00000000..7647e08f --- /dev/null +++ b/install/grafana-v5-install.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +$STD apt-get install -y apt-transport-https +$STD apt-get install -y software-properties-common +msg_ok "Installed Dependencies" + +msg_info "Setting up Grafana Repository" +$STD apt-key add <(curl -fsSL https://packages.grafana.com/gpg.key) +cat </etc/apt/sources.list.d/grafana.list +deb https://packages.grafana.com/oss/deb stable main +EOF +msg_ok "Set up Grafana Repository" + +msg_info "Installing Grafana" +$STD apt-get update +$STD apt-get install -y grafana +msg_ok "Installed Grafana" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi +systemctl start grafana-server +$STD systemctl enable grafana-server.service + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 2062a81b0bfedeb5f526a62cd6957e4f442f5a71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 14:31:18 -0500 Subject: [PATCH 3992/6505] Create grafana-v5.sh --- ct/grafana-v5.sh | 360 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 ct/grafana-v5.sh diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh new file mode 100644 index 00000000..9eace3c6 --- /dev/null +++ b/ct/grafana-v5.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ ____ + / ____/________ _/ __/___ _____v5____ _ + / / __/ ___/ __ / /_/ __ / __ \/ __ / +/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / +\____/_/ \__,_/_/ \__,_/_/ /_/\__,_/ + +EOF +} +echo -e "Loading..." +APP="Grafana" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/grafana.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From b18212e89e07b1fa089ba2f77becfcf3edfeafd4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 15:58:26 -0500 Subject: [PATCH 3993/6505] Create wireguard-v5.sh --- ct/wireguard-v5.sh | 408 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 408 insertions(+) create mode 100644 ct/wireguard-v5.sh diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh new file mode 100644 index 00000000..33cfc4cd --- /dev/null +++ b/ct/wireguard-v5.sh @@ -0,0 +1,408 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ ___ ______ __ +| | / (_)_______ / ____/_ ______ __________/ / +| | /| / / / ___/ _ \/ / __/ / / / __ `/ ___/ __ / +| |/ |/ / / / / __/ /_/ / /_/ / /_/ / / / /_/ / +|__/|__/_/_/ v5\___/\____/\__,_/\__,_/_/ \__,_/ + +EOF +} +echo -e "Loading..." +APP="Wireguard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/pivpn/wireguard ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Update ${APP} LXC" ON \ + "2" "Install WGDashboard" OFF \ + 3>&1 1>&2 2>&3) +clear +header_info +if [ "$UPD" == "1" ]; then +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +fi +if [ "$UPD" == "2" ]; then +IP=$(hostname -I | awk '{print $1}') +msg_info "Installing pip3" +apt-get install -y python3-pip &>/dev/null +pip install flask &>/dev/null +pip install ifcfg &>/dev/null +pip install flask_qrcode &>/dev/null +pip install icmplib &>/dev/null +msg_ok "Installed pip3" + +msg_info "Installing WGDashboard" +WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') + +git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null +cd /etc/wgdashboard/src +sudo chmod u+x wgd.sh +sudo ./wgd.sh install &>/dev/null +sudo chmod -R 755 /etc/wireguard +msg_ok "Installed WGDashboard" + +msg_info "Creating Service" +service_path="/etc/systemd/system/wg-dashboard.service" +echo "[Unit] +After=netword.service + +[Service] +WorkingDirectory=/etc/wgdashboard/src +ExecStart=/usr/bin/python3 /etc/wgdashboard/src/dashboard.py +Restart=always + + +[Install] +WantedBy=default.target" >$service_path +chmod 664 /etc/systemd/system/wg-dashboard.service +systemctl daemon-reload +systemctl enable wg-dashboard.service &>/dev/null +systemctl start wg-dashboard.service &>/dev/null +msg_ok "Created Service" +echo -e "WGDashboard should be reachable by going to the following URL. + ${BL}http://${IP}:10086${CL} admin|admin \n" +exit +fi +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 7720c05b2837f57af6db918366894810aff73fe5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 15:58:54 -0500 Subject: [PATCH 3994/6505] Update wireguard-v5.sh --- ct/wireguard-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 33cfc4cd..aa13e0b2 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -400,7 +400,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ From edc1e16bf1e4b452cd3c4c82d358e80daa68083a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 16:00:07 -0500 Subject: [PATCH 3995/6505] Create wireguard-v5-install.sh --- install/wireguard-v5-install.sh | 136 ++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 install/wireguard-v5-install.sh diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh new file mode 100644 index 00000000..10da01e4 --- /dev/null +++ b/install/wireguard-v5-install.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +OPTIONS_PATH='/options.conf' +cat >$OPTIONS_PATH <<'EOF' +IPv4dev=eth0 +install_user=root +VPN=wireguard +pivpnNET=10.6.0.0 +subnetClass=24 +ALLOWED_IPS="0.0.0.0/0, ::0/0" +pivpnMTU=1420 +pivpnPORT=51820 +pivpnDNS1=1.1.1.1 +pivpnDNS2=8.8.8.8 +pivpnHOST= +pivpnPERSISTENTKEEPALIVE=25 +UNATTUPG=1 +EOF + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gunicorn +msg_ok "Installed Dependencies" + +msg_info "Installing WireGuard (using pivpn.io)" +$STD bash <(curl -fsSL https://install.pivpn.io) --unattended options.conf +msg_ok "Installed WireGuard" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 66da79154cac6d5b5f57632b8bf65608302418b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 17:23:42 -0500 Subject: [PATCH 3996/6505] Create jellyfin-v5.sh --- ct/jellyfin-v5.sh | 381 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 381 insertions(+) create mode 100644 ct/jellyfin-v5.sh diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh new file mode 100644 index 00000000..06d532e0 --- /dev/null +++ b/ct/jellyfin-v5.sh @@ -0,0 +1,381 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ____ _____ + / /__ / / /_v5__/ __(_)___ + __ / / _ \/ / / / / / /_/ / __ \ +/ /_/ / __/ / / /_/ / __/ / / / / +\____/\___/_/_/\__, /_/ /_/_/ /_/ + /____/ + +EOF +} +echo -e "Loading..." +APP="Jellyfin" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /usr/lib/jellyfin ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8096${CL}\n" From 61123bbd0781927d020c191d284ed2c863cf3cc2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 3 Jan 2023 17:24:51 -0500 Subject: [PATCH 3997/6505] Create jellyfin-v5-install.sh --- install/jellyfin-v5-install.sh | 160 +++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 install/jellyfin-v5-install.sh diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh new file mode 100644 index 00000000..7038cd18 --- /dev/null +++ b/install/jellyfin-v5-install.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y apt-transport-https +$STD apt-get install -y software-properties-common +msg_ok "Installed Dependencies" + +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + +msg_info "Setting Up Jellyfin Repository" +$STD add-apt-repository universe -y +$STD apt-key add <(curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key) +cat </etc/apt/sources.list.d/jellyfin.list +deb [arch=amd64] https://repo.jellyfin.org/ubuntu focal main +EOF +msg_ok "Set Up Jellyfin Repository" + +msg_info "Installing Jellyfin" +$STD apt-get update +$STD apt install jellyfin-server -y +$STD apt install jellyfin-ffmpeg -y +msg_ok "Installed Jellyfin" + +msg_info "Creating Service" +cat <<'EOF' >/lib/systemd/system/jellyfin.service +[Unit] +Description = Jellyfin Media Server +After = network.target +[Service] +Type = simple +EnvironmentFile = /etc/default/jellyfin +User = root +ExecStart = /usr/bin/jellyfin +Restart = on-failure +TimeoutSec = 15 +[Install] +WantedBy = multi-user.target +EOF +ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From fd25ff3b7a27cf93d7f868d90ca3e4502396fe34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:10:07 -0500 Subject: [PATCH 3998/6505] Create wikijs-v5-install.sh --- install/wikijs-v5-install.sh | 163 +++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 install/wikijs-v5-install.sh diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh new file mode 100644 index 00000000..3b7a1cea --- /dev/null +++ b/install/wikijs-v5-install.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Wiki.js" +mkdir -p /opt/wikijs +cd /opt/wikijs +$STD wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz +tar xzf wiki-js.tar.gz +rm wiki-js.tar.gz + +cat </opt/wikijs/config.yml +bindIP: 0.0.0.0 +port: 3000 +db: + type: sqlite + storage: /opt/wikijs/db.sqlite +logLevel: info +logFormat: default +dataPath: /opt/wikijs/data +bodyParserLimit: 5mb +EOF +$STD npm rebuild sqlite3 +msg_ok "Installed Wiki.js" + +msg_info "Creating Service" +service_path="/etc/systemd/system/wikijs.service" + +echo "[Unit] +Description=Wiki.js +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/node server +Restart=always +User=root +Environment=NODE_ENV=production +WorkingDirectory=/opt/wikijs + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now wikijs +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From c9d8bff31577a09ebc22ae0db86c01b469fd7bda Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:11:28 -0500 Subject: [PATCH 3999/6505] Create wikijs-v5.sh --- ct/wikijs-v5.sh | 373 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 ct/wikijs-v5.sh diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh new file mode 100644 index 00000000..772a9212 --- /dev/null +++ b/ct/wikijs-v5.sh @@ -0,0 +1,373 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ ___ __ _ _ +| | v5 / (_) /__(_) (_)____ +| | /| / / / //_/ / / / ___/ +| |/ |/ / / ,< / / / (__ ) +|__/|__/_/_/|_/_(_)_/ /____/ + /___/ + +EOF +} +echo -e "Loading..." +APP="Wikijs" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/wikijs ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Stopping ${APP}" +systemctl stop wikijs +msg_ok "Stopped ${APP}" + +msg_info "Updating ${APP}" +cp /opt/wiki/config.yml ~/config.yml.bak +rm -rf /opt/wiki/* +cd /opt/wiki +wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz &>/dev/null +tar xzf wiki-js.tar.gz +cp ~/config.yml.bak ./config.yml +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +systemctl stop wikijs +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 6ba1afdd45c0c7f85b470745929da097c8c50eca Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:12:31 -0500 Subject: [PATCH 4000/6505] Create whoogle-v5.sh --- ct/whoogle-v5.sh | 359 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 ct/whoogle-v5.sh diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh new file mode 100644 index 00000000..aeda75c5 --- /dev/null +++ b/ct/whoogle-v5.sh @@ -0,0 +1,359 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ ____ ______ ____ ________ ______ +| | v5 / / / / / __ \/ __ \/ ____/ / / ____/ +| | /| / / /_/ / / / / / / / / __/ / / __/ +| |/ |/ / __ / /_/ / /_/ / /_/ / /___/ /___ +|__/|__/_/ /_/\____/\____/\____/_____/_____/ + +EOF +} +echo -e "Loading..." +APP="Whoogle" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /usr/local/bin/whoogle-search ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +pip3 install whoogle-search --upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From ac6bfab23841b809bf19cdc52cf298e02883f996 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:13:30 -0500 Subject: [PATCH 4001/6505] Create whoogle-v5-install.sh --- install/whoogle-v5-install.sh | 135 ++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 install/whoogle-v5-install.sh diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh new file mode 100644 index 00000000..c8cb5ed3 --- /dev/null +++ b/install/whoogle-v5-install.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing pip3" +$STD apt-get install -y python3-pip +msg_ok "Installed pip3" + +msg_info "Installing Whoogle" +$STD pip install brotli +$STD pip install whoogle-search + +service_path="/etc/systemd/system/whoogle.service" +echo "[Unit] +Description=Whoogle-Search +After=network.target +[Service] +ExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0 +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path + +$STD systemctl enable --now whoogle.service +msg_ok "Installed Whoogle" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 771af5224f3295dbeb7c95035f7342e28c98f1ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:14:28 -0500 Subject: [PATCH 4002/6505] Create unifi-v5-install.sh --- install/unifi-v5-install.sh | 127 ++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 install/unifi-v5-install.sh diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh new file mode 100644 index 00000000..6b8f7bfd --- /dev/null +++ b/install/unifi-v5-install.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +#https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +read -r -p "Local Controller? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + LOCAL="--local-controller" +else + LOCAL="" +fi + +msg_info "Installing UniFi Network Application (Patience)" +wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh +$STD bash unifi-latest.sh --skip --add-repository $LOCAL +msg_ok "Installed UniFi Network Application" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From def818b9339e9ab6d561f31e85b73f85ac64e73b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:15:49 -0500 Subject: [PATCH 4003/6505] Create unifi-v5.sh --- ct/unifi-v5.sh | 360 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 ct/unifi-v5.sh diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh new file mode 100644 index 00000000..2f7ca498 --- /dev/null +++ b/ct/unifi-v5.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ _ _____ + / / / /_v5 (_) __(_) + / / / / __ \/ / /_/ / +/ /_/ / / / / / __/ / +\____/_/ /_/_/_/ /_/ + +EOF +} +echo -e "Loading..." +APP="Unifi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /usr/lib/unifi ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP}" +wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh +bash unifi-update.sh +msg_ok "Updated ${APP}" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP}${CL} should be reachable by going to the following URL. + ${BL}https://${IP}:8443${CL} \n" From 95530edc10a9e2210c3a6be310de0d7f555d78c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:16:52 -0500 Subject: [PATCH 4004/6505] Create umbrel-v5.sh --- ct/umbrel-v5.sh | 373 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 ct/umbrel-v5.sh diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh new file mode 100644 index 00000000..a3b29936 --- /dev/null +++ b/ct/umbrel-v5.sh @@ -0,0 +1,373 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ __ __ + / / / /___ ___v5/ /_ ________ / / + / / / / __ `__ \/ __ \/ ___/ _ \/ / +/ /_/ / / / / / / /_/ / / / __/ / +\____/_/ /_/ /_/_.___/_/ \___/_/ + +EOF +} +echo -e "Loading..." +APP="Umbrel" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /root/umbrel ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" +else +FEATURES="keyctl=1,nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export ST=$FUSE +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL (reboot is required before app installs). + ${BL}http://${IP} ${CL} \n" From 97e08ba8e144ba74db60accad7d90d61461e1a45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:17:47 -0500 Subject: [PATCH 4005/6505] Create umbrel-v5-install.sh --- install/umbrel-v5-install.sh | 134 +++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 install/umbrel-v5-install.sh diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh new file mode 100644 index 00000000..e14653a6 --- /dev/null +++ b/install/umbrel-v5-install.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +msg_info "Installing Umbrel (Patience)" +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +fi +$STD bash <(curl -fsSL https://umbrel.sh) +systemctl daemon-reload +$STD systemctl enable --now umbrel-startup.service +msg_ok "Installed Umbrel" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 0d7f88d1086e47f844079c2db3552b4a32611419 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:19:13 -0500 Subject: [PATCH 4006/6505] Create ubuntu-v5-install.sh --- install/ubuntu-v5-install.sh | 134 +++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 install/ubuntu-v5-install.sh diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh new file mode 100644 index 00000000..e14653a6 --- /dev/null +++ b/install/ubuntu-v5-install.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +cat >$DOCKER_CONFIG_PATH <<'EOF' +{ + "log-driver": "journald" +} +EOF + +msg_info "Installing Umbrel (Patience)" +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +fi +$STD bash <(curl -fsSL https://umbrel.sh) +systemctl daemon-reload +$STD systemctl enable --now umbrel-startup.service +msg_ok "Installed Umbrel" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From e6a3a8b37d7316697e5b66c35c5ea22698ee3efe Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:20:16 -0500 Subject: [PATCH 4007/6505] Create ubuntu-v5.sh --- ct/ubuntu-v5.sh | 361 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 ct/ubuntu-v5.sh diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh new file mode 100644 index 00000000..039e5f49 --- /dev/null +++ b/ct/ubuntu-v5.sh @@ -0,0 +1,361 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ____ __ + / / / / /_v5__ ______ / /___ __ + / / / / __ \/ / / / __ \/ __/ / / / +/ /_/ / /_/ / /_/ / / / / /_/ /_/ / +\____/_.___/\__,_/_/ /_/\__/\__,_/ + +EOF +} +echo -e "Loading..." +APP="Ubuntu" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="ubuntu" +var_version="22.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" OFF \ + "22.04" "Jammy" ON \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 75157905cdfb09b0964d4fc5d5f794f3b0c08830 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:21:35 -0500 Subject: [PATCH 4008/6505] Create trilium-v5.sh --- ct/trilium-v5.sh | 379 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 379 insertions(+) create mode 100644 ct/trilium-v5.sh diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh new file mode 100644 index 00000000..1d705081 --- /dev/null +++ b/ct/trilium-v5.sh @@ -0,0 +1,379 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ _ ___ + /_ __/_v5_(_) (_)_ ______ ___ + / / / ___/ / / / / / / __ `__ \ + / / / / / / / / /_/ / / / / / / +/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ + +EOF +} +echo -e "Loading..." +APP="Trilium" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/trilium/ ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Stopping ${APP}" +systemctl stop trilium.service +sleep 1 +msg_ok "Stopped ${APP}" + +msg_info "Updating to v${RELEASE}" +wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz +tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null +cp -r trilium-linux-x64-server/* /opt/trilium/ +msg_ok "Updated to v${RELEASE}" + +msg_info "Cleaning up" +rm -rf trilium-linux-x64-server-$RELEASE.tar.xz trilium-linux-x64-server +msg_ok "Cleaned" + +msg_info "Starting ${APP}" +systemctl start trilium.service +sleep 1 +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" From 2bb7a48eff1e3c82602fd8b6ee9234acdf8e1df9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:22:38 -0500 Subject: [PATCH 4009/6505] Create trilium-v5-install.sh --- install/trilium-v5-install.sh | 143 ++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 install/trilium-v5-install.sh diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh new file mode 100644 index 00000000..936eb6c6 --- /dev/null +++ b/install/trilium-v5-install.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Installing Trilium" +wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz +$STD tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz +mv trilium-linux-x64-server /opt/trilium +msg_ok "Installed Trilium" + +msg_info "Creating Service" +service_path="/etc/systemd/system/trilium.service" + +echo "[Unit] +Description=Trilium Daemon +After=syslog.target network.target + +[Service] +User=root +Type=simple +ExecStart=/opt/trilium/trilium.sh +WorkingDirectory=/opt/trilium/ +TimeoutStopSec=20 +Restart=always + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q trilium +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/trilium-linux-x64-server-$RELEASE.tar.xz +msg_ok "Cleaned" From 9b5d7da849306abe63205c7166ba13d5d1d6431f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:23:28 -0500 Subject: [PATCH 4010/6505] Create technitiumdns-v5-install.sh --- install/technitiumdns-v5-install.sh | 118 ++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 install/technitiumdns-v5-install.sh diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh new file mode 100644 index 00000000..e3645c7c --- /dev/null +++ b/install/technitiumdns-v5-install.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing Technitium DNS" +$STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) +msg_ok "Installed Technitium DNS" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From d6d3dcfc390fba2a857655b5a6f9a2d75c3de658 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:24:55 -0500 Subject: [PATCH 4011/6505] Create technitiumdns-v5.sh --- ct/technitiumdns-v5.sh | 422 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 422 insertions(+) create mode 100644 ct/technitiumdns-v5.sh diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh new file mode 100644 index 00000000..245bd0e8 --- /dev/null +++ b/ct/technitiumdns-v5.sh @@ -0,0 +1,422 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ __ _ __ _ ____ _ _______ + /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ v5 / __ \/ | / / ___/ + / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ + / / / __/ /__/ / / / / / / / /_/ / /_/ / / / / / / / /_/ / /| /___/ / +/_/ \___/\___/_/ /_/_/ /_/_/\__/_/\__,_/_/ /_/ /_/ /_____/_/ |_//____/ + +EOF +} +echo -e "Loading..." +APP="Technitium DNS" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/dns ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +dotnetDir="/opt/dotnet" +dnsDir="/etc/dns" +dnsTar="/etc/dns/DnsServerPortable.tar.gz" +dnsUrl="https://download.technitium.com/dns/DnsServerPortable.tar.gz" + +mkdir -p $dnsDir +installLog="$dnsDir/install.log" +echo "" >$installLog + +echo "" +echo "===============================" +echo "Technitium DNS Server Update" +echo "===============================" + +if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then + dotnetFound="yes" +else + dotnetFound="no" +fi + +if [ -d $dotnetDir ]; then + dotnetUpdate="yes" + echo "Updating .NET 7 Runtime..." +fi + +curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 7.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >>$installLog 2>&1 + +if [ ! -f "/usr/bin/dotnet" ]; then + ln -s $dotnetDir/dotnet /usr/bin >>$installLog 2>&1 +fi + +if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then + if [ "$dotnetUpdate" = "yes" ]; then + echo ".NET 7 Runtime was updated successfully!" + fi +else + echo "Failed to update .NET 7 Runtime. Please try again." + exit 1 +fi + +if curl -o $dnsTar --fail $dnsUrl >>$installLog 2>&1; then + if [ -d $dnsDir ]; then + echo "Updating Technitium DNS Server..." + fi + + tar -zxf $dnsTar -C $dnsDir >>$installLog 2>&1 + + if [ "$(ps --no-headers -o comm 1 | tr -d '\n')" = "systemd" ]; then + if [ -f "/etc/systemd/system/dns.service" ]; then + echo "Restarting systemd service..." + systemctl restart dns.service >>$installLog 2>&1 + fi + + echo "" + echo "Technitium DNS Server was updated successfully!" + else + echo "" + echo "Failed to update Technitium DNS Server: systemd was not detected." + exit 1 + fi +else + echo "" + echo "Failed to download Technitium DNS Server from: $dnsUrl" + exit 1 +fi +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5380${CL} \n" From 9374dab4a5674cb637df89aa8720911b4c0c2b13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:47:09 -0500 Subject: [PATCH 4012/6505] Delete trilium-update.sh prune --- misc/trilium-update.sh | 47 ------------------------------------------ 1 file changed, 47 deletions(-) delete mode 100644 misc/trilium-update.sh diff --git a/misc/trilium-update.sh b/misc/trilium-update.sh deleted file mode 100644 index 5670c49e..00000000 --- a/misc/trilium-update.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -function update_info { - cat <<"EOF" - ______ _ ___ - /_ __/____(_) (_)_ ______ ___ - / / / ___/ / / / / / / __ `__ \ - / / / / / / / / /_/ / / / / / / -/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ - UPDATE - -EOF -} -update_info -while true; do - read -p "This will Update Trilium to v$RELEASE. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -sleep 2 -echo -e "${GN} Stopping Trilium... ${CL}" -systemctl stop trilium.service -sleep 1 - -echo -e "${GN} Updating to v${RELEASE}... ${CL}" -wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz - -tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null -cp -r trilium-linux-x64-server/* /opt/trilium/ -echo -e "${GN} Cleaning up... ${CL}" -rm -rf trilium-linux-x64-server-$RELEASE.tar.xz trilium-linux-x64-server - -echo -e "${GN} Starting Trilium... ${CL}" -systemctl start trilium.service -sleep 1 -echo -e "${GN} Finished Update ${CL}" From 0c493fc586fd5b6d65afb8bc4b0e7079f6e89532 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:47:42 -0500 Subject: [PATCH 4013/6505] Delete technitiumdns-update.sh prune --- misc/technitiumdns-update.sh | 67 ------------------------------------ 1 file changed, 67 deletions(-) delete mode 100644 misc/technitiumdns-update.sh diff --git a/misc/technitiumdns-update.sh b/misc/technitiumdns-update.sh deleted file mode 100644 index 88494319..00000000 --- a/misc/technitiumdns-update.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh -set -e -dotnetDir="/opt/dotnet" -dnsDir="/etc/dns" -dnsTar="/etc/dns/DnsServerPortable.tar.gz" -dnsUrl="https://download.technitium.com/dns/DnsServerPortable.tar.gz" - -mkdir -p $dnsDir -installLog="$dnsDir/install.log" -echo "" >$installLog - -echo "" -echo "===============================" -echo "Technitium DNS Server Update" -echo "===============================" - -if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then - dotnetFound="yes" -else - dotnetFound="no" -fi - -if [ -d $dotnetDir ]; then - dotnetUpdate="yes" - echo "Updating .NET 7 Runtime..." -fi - -curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 7.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >>$installLog 2>&1 - -if [ ! -f "/usr/bin/dotnet" ]; then - ln -s $dotnetDir/dotnet /usr/bin >>$installLog 2>&1 -fi - -if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then - if [ "$dotnetUpdate" = "yes" ]; then - echo ".NET 7 Runtime was updated successfully!" - fi -else - echo "Failed to update .NET 7 Runtime. Please try again." - exit 1 -fi - -if curl -o $dnsTar --fail $dnsUrl >>$installLog 2>&1; then - if [ -d $dnsDir ]; then - echo "Updating Technitium DNS Server..." - fi - - tar -zxf $dnsTar -C $dnsDir >>$installLog 2>&1 - - if [ "$(ps --no-headers -o comm 1 | tr -d '\n')" = "systemd" ]; then - if [ -f "/etc/systemd/system/dns.service" ]; then - echo "Restarting systemd service..." - systemctl restart dns.service >>$installLog 2>&1 - fi - - echo "" - echo "Technitium DNS Server was updated successfully!" - else - echo "" - echo "Failed to update Technitium DNS Server: systemd was not detected." - exit 1 - fi -else - echo "" - echo "Failed to download Technitium DNS Server from: $dnsUrl" - exit 1 -fi From 06093e9588707eaace258cb58124264410dc0616 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 09:48:02 -0500 Subject: [PATCH 4014/6505] Delete unifi-update.sh prune --- misc/unifi-update.sh | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 misc/unifi-update.sh diff --git a/misc/unifi-update.sh b/misc/unifi-update.sh deleted file mode 100644 index 6befdb24..00000000 --- a/misc/unifi-update.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -APP="UniFi Update" -while true; do - read -p "This will run ${APP}. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - echo -e "${RD} - _ _ _ ______ _ - | | | | (_) ____(_) - | | | |_ __ _| |__ _ - | | | | _ \| | __| | | - | |__| | | | | | | | | - \____/|_| |_|_|_| |_| - UPDATE -${CL}" -} - -header_info -sleep 3 -wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh && bash unifi-update.sh From c2efd82b0215846ffea7a72cb35c805921078458 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 11:09:45 -0500 Subject: [PATCH 4015/6505] Create debian-v5-install.sh --- install/debian-v5-install.sh | 112 +++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 install/debian-v5-install.sh diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh new file mode 100644 index 00000000..13ff3d34 --- /dev/null +++ b/install/debian-v5-install.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From d4dc586b583325906b00183a21af32ee3a74c41e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 11:11:08 -0500 Subject: [PATCH 4016/6505] Create debian-v5.sh --- ct/debian-v5.sh | 353 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 ct/debian-v5.sh diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh new file mode 100644 index 00000000..5483076f --- /dev/null +++ b/ct/debian-v5.sh @@ -0,0 +1,353 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __________ _______ _ __ + / __ \/ ____/ __ )/ _/ | / | / / + / / / / __/ / __ |/ // /| | / |/ / + / /_/ / /_v5/ /_/ // // ___ |/ /| / +/_____/_____/_____/___/_/ |_/_/ |_/ + +EOF +} +echo -e "Loading..." +APP="Debian" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 2fc71ff407c520854496caeeff19771d4154e168 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 16:38:41 -0500 Subject: [PATCH 4017/6505] Create nginxproxymanager-v5-install.sh --- install/nginxproxymanager-v5-install.sh | 279 ++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 install/nginxproxymanager-v5-install.sh diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh new file mode 100644 index 00000000..25de6ad9 --- /dev/null +++ b/install/nginxproxymanager-v5-install.sh @@ -0,0 +1,279 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get update +$STD apt-get -y install \ + sudo \ + curl \ + gnupg \ + make \ + g++ \ + gcc \ + ca-certificates \ + apache2-utils \ + logrotate \ + build-essential \ + python3-dev \ + git \ + lsb-release +msg_ok "Installed Dependencies" + +msg_info "Installing Python" +$STD apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv +$STD pip3 install --upgrade setuptools +$STD pip3 install --upgrade pip +$STD python3 -m venv /opt/certbot/ +if [ "$(getconf LONG_BIT)" = "32" ]; then + $STD python3 -m pip install --no-cache-dir -U cryptography==3.3.2 +fi +$STD python3 -m pip install --no-cache-dir cffi certbot +msg_ok "Installed Python" + +msg_info "Installing Openresty" +$STD apt-key add <(curl -fsSL https://openresty.org/package/pubkey.gpg) +cat </etc/apt/sources.list.d/openresty.list +deb http://openresty.org/package/debian bullseye openresty +EOF +$STD apt-get -y update +$STD apt-get -y install --no-install-recommends openresty +msg_ok "Installed Openresty" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Yarn" +$STD npm install --global yarn +msg_ok "Installed Yarn" + +RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Downloading Nginx Proxy Manager v${RELEASE}" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz +cd ./nginx-proxy-manager-${RELEASE} +msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" + +msg_info "Setting up Enviroment" +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /usr/bin/certbot /opt/certbot/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx + +sed -i "s+0.0.0+${RELEASE}+g" backend/package.json +sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json + +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done + +mkdir -p /var/www/html /etc/nginx/logs +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf + +mkdir -p /tmp/nginx/body \ + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp + +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx + +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf + +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -en "${GN} Generating dummy SSL Certificate... " + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi + +mkdir -p /app/global /app/frontend/images +cp -r backend/* /app +cp -r global/* /app/global +msg_ok "Set up Enviroment" + +msg_info "Building Frontend" +cd ./frontend +export NODE_ENV=development +$STD yarn install --network-timeout=30000 +$STD yarn build +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images +msg_ok "Built Frontend" + +msg_info "Initializing Backend" +rm -rf /app/config/default.json +if [ ! -f /app/config/production.json ]; then + cat <<'EOF' >/app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF +fi +cd /app +export NODE_ENV=development +$STD yarn install --network-timeout=30000 +msg_ok "Initialized Backend" + +msg_info "Creating Service" +cat <<'EOF' >/lib/systemd/system/npm.service +[Unit] +Description=Nginx Proxy Manager +After=network.target +Wants=openresty.service + +[Service] +Type=simple +Environment=NODE_ENV=production +ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge +ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 +WorkingDirectory=/app +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Starting Services" +$STD systemctl enable --now openresty +$STD systemctl enable --now npm +msg_ok "Started Services" + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 614c6aa95b50a629a7688e7b29a32e115ef86a6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 16:40:13 -0500 Subject: [PATCH 4018/6505] Create nginxproxymanager-v5.sh --- ct/nginxproxymanager-v5.sh | 469 +++++++++++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 ct/nginxproxymanager-v5.sh diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh new file mode 100644 index 00000000..ac5fb686 --- /dev/null +++ b/ct/nginxproxymanager-v5.sh @@ -0,0 +1,469 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ __ _ ____ __ ___ + / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____ + / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ + / /| / /_/ / / / / /> < / ____/ / / /_/ /> &2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /lib/systemd/system/npm.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Stopping Services" +systemctl stop openresty +systemctl stop npm +msg_ok "Stopped Services" + +msg_info "Cleaning Old Files" + rm -rf /app \ + /var/www/html \ + /etc/nginx \ + /var/log/nginx \ + /var/lib/nginx \ + /var/cache/nginx &>/dev/null +msg_ok "Cleaned Old Files" + +msg_info "Downloading NPM v${RELEASE}" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null +cd nginx-proxy-manager-${RELEASE} +msg_ok "Downloaded NPM v${RELEASE}" + +msg_info "Setting up Enviroment" +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /usr/bin/certbot /opt/certbot/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx +sed -i "s+0.0.0+${RELEASE}+g" backend/package.json +sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done +mkdir -p /var/www/html /etc/nginx/logs +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf +mkdir -p /tmp/nginx/body \ + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi +mkdir -p /app/global /app/frontend/images +cp -r backend/* /app +cp -r global/* /app/global +msg_ok "Setup Enviroment" + +msg_info "Building Frontend" +cd ./frontend +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +yarn build &>/dev/null +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images +msg_ok "Built Frontend" + + +msg_info "Initializing Backend" +rm -rf /app/config/default.json &>/dev/null +if [ ! -f /app/config/production.json ]; then + cat <<'EOF' >/app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF +fi +cd /app +export NODE_ENV=development +yarn install --network-timeout=30000 &>/dev/null +msg_ok "Initialized Backend" + +msg_info "Starting Services" +systemctl enable npm &>/dev/null +systemctl start openresty +systemctl start npm +msg_ok "Started Services" + +msg_info "Cleaning up" +rm -rf nginx-proxy-manager-${RELEASE} +msg_ok "Cleaned" + +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:81${CL} \n" From 2a5b620d00fdd116a4c9db445b9b8243ecaa77ef Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 16:57:15 -0500 Subject: [PATCH 4019/6505] Create yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 117 +++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 install/yunohost-v5-install.sh diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh new file mode 100644 index 00000000..29262c7f --- /dev/null +++ b/install/yunohost-v5-install.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing YunoHost (Patience)" +$STD bash <(curl -fsSL https://install.yunohost.org) -a +$STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' +msg_ok "Installed YunoHost" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 00f7f194e1a98855dac1bb53a6fb5207a880adbe Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 16:58:25 -0500 Subject: [PATCH 4020/6505] Create yunohost-v5.sh --- ct/yunohost-v5.sh | 355 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 ct/yunohost-v5.sh diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh new file mode 100644 index 00000000..9a5d9ee6 --- /dev/null +++ b/ct/yunohost-v5.sh @@ -0,0 +1,355 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" +__ __ __ __ __ +\ \/ /_ ______v5____ / / / /___ _____/ /_ + \ / / / / __ \/ __ \/ /_/ / __ \/ ___/ __/ + / / /_/ / / / / /_/ / __ / /_/ (__ ) /_ +/_/\__,_/_/ /_/\____/_/ /_/\____/____/\__/ + +EOF +} +echo -e "Loading..." +APP="YunoHost" +var_disk="20" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}/ ${CL}" From b73200e11a72a95bc7080f786bdf1677afee07ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 17:24:19 -0500 Subject: [PATCH 4021/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7c4331cc..e701762e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-1-04 + +### Changed + +- **YunoHost LXC** + - NEW Script + ## 2022-12-31 ### Changed From 1d6aaca35aa2277feab86b005e6e7f391b2c5d0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 17:24:44 -0500 Subject: [PATCH 4022/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e701762e..9ec9f85c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,7 +3,7 @@ # Change Log All notable changes to this project will be documented in this file. -## 2023-1-04 +## 2023-01-04 ### Changed From 77a16af2c2c7d8ac0952602ac1dc7080dfe13e0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 17:32:17 -0500 Subject: [PATCH 4023/6505] Update post-pbs-install.sh --- misc/post-pbs-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index 7b29e5f4..b96dbb93 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -94,7 +94,7 @@ fi read -r -p "Disable Subscription Nag? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then msg_info "Disabling Subscription Nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag" fi From 3582365cedcc0600735f6ddd18e068840eae56ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 17:38:39 -0500 Subject: [PATCH 4024/6505] Update homeassistant-core-v5.sh HA team fixed dependency issues. Remove temp fix --- ct/homeassistant-core-v5.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 195be24c..32191909 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -351,11 +351,6 @@ source /srv/homeassistant/bin/activate pip install ${BR}--upgrade homeassistant &>/dev/null msg_ok "Updated Home Assistant" - if [ "${BR}" == "" ]; then - sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt - sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json - fi - msg_info "Starting Home Assistant" systemctl start homeassistant sleep 2 From 43022d00b3335ac51d8afb22faca1677b20f192e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 17:39:24 -0500 Subject: [PATCH 4025/6505] Update homeassistant-core-v5-install.sh HA team fixed dependency issues. Remove temp fix --- install/homeassistant-core-v5-install.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 1ee82a65..3c88bd62 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -148,10 +148,6 @@ $STD pip install psycopg2-binary $STD pip install homeassistant msg_ok "Installed Home Assistant-Core" -# fix for inconsistent versions, hopefully the HA team will get this fixed -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json - msg_info "Creating Service" cat </etc/systemd/system/homeassistant.service [Unit] From cbad086cda12ec7e6791699ea42dbdc5e3417ecc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 18:21:16 -0500 Subject: [PATCH 4026/6505] Update post-pbs-install.sh --- misc/post-pbs-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index b96dbb93..7b29e5f4 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -94,7 +94,7 @@ fi read -r -p "Disable Subscription Nag? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then msg_info "Disabling Subscription Nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag" fi From dab84ea29cf844569e0140338b34a6bab0ee4b34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Jan 2023 19:01:46 -0500 Subject: [PATCH 4027/6505] Delete npm_update.sh prune --- misc/npm_update.sh | 175 --------------------------------------------- 1 file changed, 175 deletions(-) delete mode 100644 misc/npm_update.sh diff --git a/misc/npm_update.sh b/misc/npm_update.sh deleted file mode 100644 index af3cef7e..00000000 --- a/misc/npm_update.sh +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") - -function update_info { - echo -e "${RD} - _ _ _____ __ __ - | \ | | | __ \ | \/ | - | \| | | |__) | | \ / | - | | | ___/ | |\/| | - | |\ | | | | | | | - |_| \_| |_| |_| |_| - UPDATE v${RELEASE} -${CL}" -} - -update_info - -while true; do - read -p "This will update Nginx Proxy Manager to v${RELEASE}. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -update_info -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap 'die "Script interrupted."' INT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR:LXC] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} - -if [ -f /lib/systemd/system/npm.service ]; then - echo -en "${GN} Prep For Update... " - sleep 2 - echo -e "${CM}${CL} \r" - echo -en "${GN} Stopping Services... " - systemctl stop openresty - systemctl stop npm - echo -e "${CM}${CL} \r" - - echo -en "${GN} Cleaning Old Files... " - rm -rf /app \ - /var/www/html \ - /etc/nginx \ - /var/log/nginx \ - /var/lib/nginx \ - /var/cache/nginx &>/dev/null - echo -e "${CM}${CL} \r" -else - echo -en "${RD} No NPM to Update! ${CL}" - exit -fi - -echo -en "${GN} Downloading NPM v${RELEASE}... " -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-${RELEASE} -echo -e "${CM}${CL} \r" - -echo -en "${GN} Setting up Enviroment... " -ln -sf /usr/bin/python3 /usr/bin/python -ln -sf /usr/bin/certbot /opt/certbot/bin/certbot -ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx -ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+${RELEASE}+g" backend/package.json -sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json -sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf -NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") -for NGINX_CONF in $NGINX_CONFS; do - sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" -done -mkdir -p /var/www/html /etc/nginx/logs -cp -r docker/rootfs/var/www/html/* /var/www/html/ -cp -r docker/rootfs/etc/nginx/* /etc/nginx/ -cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini -cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager -ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf -rm -f /etc/nginx/conf.d/dev.conf -mkdir -p /tmp/nginx/body \ - /run/nginx \ - /data/nginx \ - /data/custom_ssl \ - /data/logs \ - /data/access \ - /data/nginx/default_host \ - /data/nginx/default_www \ - /data/nginx/proxy_host \ - /data/nginx/redirection_host \ - /data/nginx/stream \ - /data/nginx/dead_host \ - /data/nginx/temp \ - /var/lib/nginx/cache/public \ - /var/lib/nginx/cache/private \ - /var/cache/nginx/proxy_temp -chmod -R 777 /var/cache/nginx -chown root /tmp/nginx -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf -echo -e "${CM}${CL} \r" - -if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null -fi - -mkdir -p /app/global /app/frontend/images -cp -r backend/* /app -cp -r global/* /app/global - -echo -en "${GN} Building Frontend... " -cd ./frontend -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -yarn build &>/dev/null -cp -r dist/* /app/frontend -cp -r app-images/* /app/frontend/images -echo -e "${CM}${CL} \r" - -echo -en "${GN} Initializing Backend... " -rm -rf /app/config/default.json &>/dev/null -if [ ! -f /app/config/production.json ]; then - cat <<'EOF' >/app/config/production.json -{ - "database": { - "engine": "knex-native", - "knex": { - "client": "sqlite3", - "connection": { - "filename": "/data/database.sqlite" - } - } - } -} -EOF -fi -cd /app -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting Services... " -systemctl enable npm &>/dev/null -systemctl start openresty -systemctl start npm -echo -e "${CM}${CL} \r" - -IP=$(hostname -I | cut -f1 -d ' ') -echo -e "${GN}Successfully Updated Nginx Proxy Manager to ${RD}${RELEASE}${CL}. - NPM should be reachable at ${BL}http://${IP}:81 ${CL} - - " From 8e35fdadca14db1dc7de74647e937e18280e0574 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 10:56:25 -0500 Subject: [PATCH 4028/6505] Create syncthing-v5.sh --- ct/syncthing-v5.sh | 361 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 ct/syncthing-v5.sh diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh new file mode 100644 index 00000000..a24cedc2 --- /dev/null +++ b/ct/syncthing-v5.sh @@ -0,0 +1,361 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _____ __ __ _ + / ___/__ ______v5_____/ /_/ /_ (_)___ ____ _ + \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ + ___/ / /_/ / / / / /__/ /_/ / / / / / / / /_/ / +/____/\__, /_/ /_/\___/\__/_/ /_/_/_/ /_/\__, / + /____/ /____/ + +EOF +} +echo -e "Loading..." +APP="Syncthing" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/syncthing.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8384 ${CL} \n" From c36c5cd1ec639240c95697d85499667cdcf79c54 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 10:58:07 -0500 Subject: [PATCH 4029/6505] Create syncthing-v5-install.sh --- install/syncthing-v5-install.sh | 127 ++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 install/syncthing-v5-install.sh diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh new file mode 100644 index 00000000..42f34a10 --- /dev/null +++ b/install/syncthing-v5-install.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing Syncthing" +curl -s -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg +cat </etc/apt/sources.list.d/syncthing.list +deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable +EOF +$STD apt-get update +$STD apt-get install -y syncthing +$STD systemctl enable syncthing@root.service +systemctl start syncthing@root.service +sleep 5 +sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.config/syncthing/config.xml +systemctl restart syncthing@root.service +msg_ok "Installed Syncthing" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From e90ed19caffcdd775befedfade160dbd613d44f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 11:28:01 -0500 Subject: [PATCH 4030/6505] Update syncthing-install.sh code refactoring --- install/syncthing-install.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh index c16488f6..f4f9d2ec 100644 --- a/install/syncthing-install.sh +++ b/install/syncthing-install.sh @@ -92,6 +92,10 @@ echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https:// apt-get update &>/dev/null apt-get install -y syncthing &>/dev/null systemctl enable syncthing@root.service &>/dev/null +systemctl start syncthing@root.service +sleep 5 +sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.config/syncthing/config.xml +systemctl restart syncthing@root.service msg_ok "Installed Syncthing" PASS=$(grep -w "root" /etc/shadow | cut -b6) From f15fca3e2ce2226f9d81b9ad1900ba57bd125453 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 12:57:32 -0500 Subject: [PATCH 4031/6505] Create scrypted-v5-install.sh --- install/scrypted-v5-install.sh | 208 +++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 install/scrypted-v5-install.sh diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh new file mode 100644 index 00000000..1a08672c --- /dev/null +++ b/install/scrypted-v5-install.sh @@ -0,0 +1,208 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get -y install software-properties-common apt-utils +$STD apt-get -y update +$STD apt-get -y upgrade +$STD apt-get -y install \ + build-essential \ + gcc \ + gir1.2-gtk-3.0 \ + libcairo2-dev \ + libgirepository1.0-dev \ + libglib2.0-dev \ + libjpeg-dev \ + libgif-dev \ + libopenjp2-7 \ + libpango1.0-dev \ + librsvg2-dev \ + pkg-config \ + curl \ + sudo +msg_ok "Installed Dependencies" + +msg_info "Installing GStreamer" +$STD apt-get -y install \ + gstreamer1.0-tools \ + libgstreamer1.0-dev \ + libgstreamer-plugins-base1.0-dev \ + libgstreamer-plugins-bad1.0-dev \ + gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-ugly \ + gstreamer1.0-libav \ + gstreamer1.0-alsa +msg_ok "Installed GStreamer" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Python3" +$STD apt-get -y install \ + python3 \ + python3-dev \ + python3-gi \ + python3-gst-1.0 \ + python3-matplotlib \ + python3-numpy \ + python3-opencv \ + python3-pil \ + python3-pip \ + python3-setuptools \ + python3-skimage \ + python3-wheel +$STD python3 -m pip install --upgrade pip +$STD python3 -m pip install aiofiles debugpy typing_extensions typing +msg_ok "Installed Python3" + +read -r -p "Would you like to add Coral Edge TPU support? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + CORAL="Y" +else + CORAL="N" +fi + +if [[ $CORAL == "Y" ]]; then +msg_info "Adding Coral Edge TPU Support" +$STD apt-key add <(curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg) +cat </etc/apt/sources.list.d/coral-edgetpu.list +deb https://packages.cloud.google.com/apt coral-edgetpu-stable main +EOF +$STD apt-get -y update +$STD apt-get -y install libedgetpu1-std +msg_ok "Coral Edge TPU Support Added" +fi + +msg_info "Installing Scrypted" +$STD sudo -u root npx -y scrypted@latest install-server +msg_info "Installed Scrypted" + +msg_info "Creating Service" +service_path="/etc/systemd/system/scrypted.service" +echo "[Unit] +Description=Scrypted service +After=network.target + +[Service] +User=root +Group=root +Type=simple +ExecStart=/usr/bin/npx -y scrypted serve +Restart=on-failure +RestartSec=3 + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now scrypted.service +msg_ok "Created Service" +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 6385d1d1fe1d8abbebe8fc2e72a0fafd4a5bf8d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 12:58:49 -0500 Subject: [PATCH 4032/6505] Create scrypted-v5.sh --- ct/scrypted-v5.sh | 375 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 ct/scrypted-v5.sh diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh new file mode 100644 index 00000000..b03095b5 --- /dev/null +++ b/ct/scrypted-v5.sh @@ -0,0 +1,375 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _____ __ __ + / ___/____________v5______ / /____ ____/ / + \__ \/ ___/ ___/ / / / __ \/ __/ _ \/ __ / + ___/ / /__/ / / /_/ / /_/ / /_/ __/ /_/ / +/____/\___/_/ \__, / .___/\__/\___/\__,_/ + /____/_/ + +EOF +} +echo -e "Loading..." +APP="Scrypted" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/scrypted.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:10443${CL} \n" From da2ca3ce781acadf94b444ac167408b2485202a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 12:59:56 -0500 Subject: [PATCH 4033/6505] Create prometheus-v5.sh --- ct/prometheus-v5.sh | 360 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 ct/prometheus-v5.sh diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh new file mode 100644 index 00000000..30b211dc --- /dev/null +++ b/ct/prometheus-v5.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ __ + / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ + / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ + / ____/ / / /_/ / / / / / / __/ /_/ / / / __/ /_/ (__ ) +/_/ v5/_/ \____/_/ /_/ /_/\___/\__/_/ /_/\___/\__,_/____/ + +EOF +} +echo -e "Loading..." +APP="Prometheus" +var_disk="4" +var_cpu="1" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/prometheus.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9090${CL} \n" From b49f5370f3f7749bef636df89d32ace3eb822a24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 13:01:06 -0500 Subject: [PATCH 4034/6505] Create prometheus-v5-install.sh --- install/prometheus-v5-install.sh | 149 +++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 install/prometheus-v5-install.sh diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh new file mode 100644 index 00000000..f46343fa --- /dev/null +++ b/install/prometheus-v5-install.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing Prometheus" +RELEASE=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +mkdir -p /etc/prometheus +mkdir -p /var/lib/prometheus +$STD wget https://github.com/prometheus/prometheus/releases/download/v${RELEASE}/prometheus-${RELEASE}.linux-amd64.tar.gz +$STD tar -xvf prometheus-${RELEASE}.linux-amd64.tar.gz +cd prometheus-${RELEASE}.linux-amd64 +mv prometheus promtool /usr/local/bin/ +mv consoles/ console_libraries/ /etc/prometheus/ +mv prometheus.yml /etc/prometheus/prometheus.yml +msg_ok "Installed Prometheus" + +msg_info "Creating Service" +service_path="/etc/systemd/system/prometheus.service" +echo "[Unit] +Description=Prometheus +Wants=network-online.target +After=network-online.target + +[Service] +User=root +Restart=always +Type=simple +ExecStart=/usr/local/bin/prometheus \ + --config.file=/etc/prometheus/prometheus.yml \ + --storage.tsdb.path=/var/lib/prometheus/ \ + --web.console.templates=/etc/prometheus/consoles \ + --web.console.libraries=/etc/prometheus/console_libraries \ + --web.listen-address=0.0.0.0:9090 + +[Install] +WantedBy=multi-user.target" >$service_path +$STD sudo systemctl enable --now prometheus +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/prometheus-${RELEASE}.linux-amd64 /root/prometheus-${RELEASE}.linux-amd64.tar.gz +msg_ok "Cleaned" From 1c778f2c2bb783ddd2805a153edc840ba6fe2c82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 13:05:10 -0500 Subject: [PATCH 4035/6505] Update vaultwarden-v5.sh fix for older installs --- ct/vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index d157cd11..c2695c4a 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -80,7 +80,7 @@ if command -v pveversion >/dev/null 2>&1; then fi fi if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/vaultwarden ]]; then + if [[ ! -f /etc/systemd/system/vaultwarden.service ]]; then msg_error "No ${APP} Installation Found!"; exit fi From 44a1e88842e979bb350f453938de4ee4c6bf79fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 13:22:36 -0500 Subject: [PATCH 4036/6505] Create postgresql-v5.sh --- ct/postgresql-v5.sh | 358 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 ct/postgresql-v5.sh diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh new file mode 100644 index 00000000..c5cacfde --- /dev/null +++ b/ct/postgresql-v5.sh @@ -0,0 +1,358 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ _____ ____ __ + / __ \____ _____/ /_____ _________ / ___// __ \ / / + / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / + / ____/ /_/ (__ ) /_/ /_/ / / / __/__/ / /_/ / / /___ +/_/ \____/____/\__/\__, /_/v5 \___/____/\___\_\/_____/ + /____/ +EOF +} +echo -e "Loading..." +APP="PostgreSQL" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 83252cbfa30665d793c52c60b435e587f33337dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 13:23:48 -0500 Subject: [PATCH 4037/6505] Create postgresql-v5-install.sh --- install/postgresql-v5-install.sh | 241 +++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 install/postgresql-v5-install.sh diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh new file mode 100644 index 00000000..7ab0e05f --- /dev/null +++ b/install/postgresql-v5-install.sh @@ -0,0 +1,241 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Setting up PostgreSQL Repository" +sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main" > /etc/apt/sources.list.d/pgdg.list' +$STD apt-key add <(curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc) +msg_ok "Setup PostgreSQL Repository" + +msg_info "Installing PostgreSQL" +$STD apt-get update +$STD apt-get install -y postgresql + +cat </etc/postgresql/15/main/pg_hba.conf +# PostgreSQL Client Authentication Configuration File +local all postgres peer +# TYPE DATABASE USER ADDRESS METHOD +# "local" is for Unix domain socket connections only +local all all peer +# IPv4 local connections: +host all all 127.0.0.1/32 scram-sha-256 +host all all 0.0.0.0/24 md5 +# IPv6 local connections: +host all all ::1/128 scram-sha-256 +host all all 0.0.0.0/0 md5 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 scram-sha-256 +host replication all ::1/128 scram-sha-256 +EOF + +cat </etc/postgresql/15/main/postgresql.conf +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +data_directory = '/var/lib/postgresql/15/main' +hba_file = '/etc/postgresql/15/main/pg_hba.conf' +ident_file = '/etc/postgresql/15/main/pg_ident.conf' +external_pid_file = '/var/run/postgresql/15-main.pid' + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '*' +port = 5432 +max_connections = 100 +unix_socket_directories = '/var/run/postgresql' + +# - SSL - + +ssl = on +ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' +ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +shared_buffers = 128MB +dynamic_shared_memory_type = posix + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +max_wal_size = 1GB +min_wal_size = 80MB + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - What to Log - + +log_line_prefix = '%m [%p] %q%u@%d ' +log_timezone = 'Etc/UTC' + +#------------------------------------------------------------------------------ +# PROCESS TITLE +#------------------------------------------------------------------------------ + +cluster_name = '15/main' + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Locale and Formatting - + +datestyle = 'iso, mdy' +timezone = 'Etc/UTC' +lc_messages = 'C' +lc_monetary = 'C' +lc_numeric = 'C' +lc_time = 'C' +default_text_search_config = 'pg_catalog.english' + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +include_dir = 'conf.d' +EOF + +sudo systemctl restart postgresql +msg_ok "Installed PostgreSQL" + +read -r -p "Would you like to add Adminer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + ADMINER="Y" +else + ADMINER="N" +fi + +if [[ $ADMINER == "Y" ]]; then + msg_info "Installing Adminer" + $STD apt install -y adminer + $STD sudo a2enconf adminer + $STD systemctl reload apache2 + msg_ok "Installed Adminer" +fi + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 5765b0c800a32254e4fbc441ced7c0158554cfb6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 13:30:21 -0500 Subject: [PATCH 4038/6505] Update vaultwarden-v5.sh fix for older installs --- ct/vaultwarden-v5.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index c2695c4a..c16b0a8b 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -376,7 +376,12 @@ msg_ok "$WVRELEASE Update Successful" exit; fi if [ "$UPD" == "3" ]; then -cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" +DIR=/usr/bin/vaultwarden + if [ -d "$DIR" ]; then + cat /usr/bin/vaultwarden/.env | grep "ADMIN_TOKEN" + else + cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" + fi exit fi } From a62ae77a517df06817996230a1365de64b1d0ad8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 13:35:49 -0500 Subject: [PATCH 4039/6505] Create plex-v5.sh --- ct/plex-v5.sh | 380 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 ct/plex-v5.sh diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh new file mode 100644 index 00000000..fc40ecfb --- /dev/null +++ b/ct/plex-v5.sh @@ -0,0 +1,380 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ __ ___ ___ _____ + / __ \/ /__ _ __ / |/ /__v5____/ (_)___ _ / ___/___ ______ _____ _____ + / /_/ / / _ \| |/_/ / /|_/ / _ \/ __ / / __ `/ \__ \/ _ \/ ___/ | / / _ \/ ___/ + / ____/ / __/> < / / / / __/ /_/ / / /_/ / ___/ / __/ / | |/ / __/ / +/_/ /_/\___/_/|_| /_/ /_/\___/\__,_/_/\__,_/ /____/\___/_/ |___/\___/_/ + +EOF +} +echo -e "Loading..." +APP="Plex" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:32400/web${CL}\n" From 4336e422012f1db3412ed01c495543ab8edafc34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 13:36:47 -0500 Subject: [PATCH 4040/6505] Create plex-v5-install.sh --- install/plex-v5-install.sh | 139 +++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 install/plex-v5-install.sh diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh new file mode 100644 index 00000000..2a5cb5c2 --- /dev/null +++ b/install/plex-v5-install.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + +msg_info "Setting Up Plex Media Server Repository" +$STD apt-key add <(curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key) +cat </etc/apt/sources.list.d/plexmediaserver.list +deb [arch=amd64] https://downloads.plex.tv/repo/deb/ public main +EOF +msg_ok "Set Up Plex Media Server Repository" + +msg_info "Installing Plex Media Server" +$STD apt-get update +$STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver +msg_ok "Installed Plex Media Server" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From d9e02063ce245d33e3cfab9bc044c36ea1799f29 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 14:19:22 -0500 Subject: [PATCH 4041/6505] Update vaultwarden-v5.sh --- ct/vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index c16b0a8b..154540d4 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -378,7 +378,7 @@ fi if [ "$UPD" == "3" ]; then DIR=/usr/bin/vaultwarden if [ -d "$DIR" ]; then - cat /usr/bin/vaultwarden/.env | grep "ADMIN_TOKEN" + cat cat /etc/vaultwarden.env | grep "ADMIN_TOKEN" else cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" fi From 9411a14f08092eb514fee8bd56676337527988b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 14:26:56 -0500 Subject: [PATCH 4042/6505] Update vaultwarden-v5.sh --- ct/vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 154540d4..816f8cb9 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -378,7 +378,7 @@ fi if [ "$UPD" == "3" ]; then DIR=/usr/bin/vaultwarden if [ -d "$DIR" ]; then - cat cat /etc/vaultwarden.env | grep "ADMIN_TOKEN" + cat /etc/vaultwarden.env | grep "ADMIN_TOKEN" else cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" fi From bf6c1f03bcf4b0ce7bb968645ef08825efd0e242 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 15:38:06 -0500 Subject: [PATCH 4043/6505] Create openhab-v5.sh --- ct/openhab-v5.sh | 361 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 ct/openhab-v5.sh diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh new file mode 100644 index 00000000..7259e024 --- /dev/null +++ b/ct/openhab-v5.sh @@ -0,0 +1,361 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ _____ ____ + ____v5____ ___ ____ / / / / | / __ ) + / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __ | +/ /_/ / /_/ / __/ / / / __ / ___ |/ /_/ / +\____/ .___/\___/_/ /_/_/ /_/_/ |_/_____/ + /_/ + +EOF +} +echo -e "Loading..." +APP="openHAB" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/openhab.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" From 4ad99239f50f13be7215b8541ceaff98ccb7cb83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 15:39:16 -0500 Subject: [PATCH 4044/6505] Create openhab-v5-install.sh --- install/openhab-v5-install.sh | 134 ++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 install/openhab-v5-install.sh diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh new file mode 100644 index 00000000..f5df107e --- /dev/null +++ b/install/openhab-v5-install.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +$STD apt-get install -y apt-transport-https +msg_ok "Installed Dependencies" + +msg_info "Installing Azul Zulu" +$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 +wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb +$STD apt-get install ./zulu-repo_1.0.0-3_all.deb +$STD apt-get update +$STD apt-get -y install zulu11-jdk +msg_ok "Installed Azul Zulu" + +msg_info "Installing openHAB" +curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor >openhab.gpg +mv openhab.gpg /usr/share/keyrings +chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg +sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main" > /etc/apt/sources.list.d/openhab.list' +$STD apt update +$STD apt-get -y install openhab +systemctl daemon-reload +$STD systemctl enable --now openhab.service +msg_ok "Installed openHAB" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From b8145ae0cf8aa87157d9f3df065a28080476ecbf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 16:00:20 -0500 Subject: [PATCH 4045/6505] Create omv-v5.sh --- ct/omv-v5.sh | 371 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 ct/omv-v5.sh diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh new file mode 100644 index 00000000..ff71fa08 --- /dev/null +++ b/ct/omv-v5.sh @@ -0,0 +1,371 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ ___ ___ _ __ ____ + / __ \____v5___ ____ / |/ /__ ____/ (_)___ | | / /___ ___ __/ / /_ + / / / / __ \/ _ \/ __ \/ /|_/ / _ \/ __ / / __ `/ | / / __ `/ / / / / __/ +/ /_/ / /_/ / __/ / / / / / / __/ /_/ / / /_/ /| |/ / /_/ / /_/ / / /_ +\____/ .___/\___/_/ /_/_/ /_/\___/\__,_/_/\__,_/ |___/\__,_/\__,_/_/\__/ + /_/ + +EOF +} +echo -e "Loading..." +APP="OMV" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From 67a5d9db545f28fa850085717657f7e196f0773c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 16:01:19 -0500 Subject: [PATCH 4046/6505] Create omv-v5-install.sh --- install/omv-v5-install.sh | 135 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 install/omv-v5-install.sh diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh new file mode 100644 index 00000000..c3a10912 --- /dev/null +++ b/install/omv-v5-install.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +export DEBIAN_FRONTEND=noninteractive +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing OpenMediaVault (Patience)" +wget -q -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key +$STD apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" &>/dev/null + +cat <>/etc/apt/sources.list.d/openmediavault.list +deb https://packages.openmediavault.org/public shaitan main +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main +## Uncomment the following line to add software from the proposed repository. +# deb https://packages.openmediavault.org/public shaitan-proposed main +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan-proposed main +## This software is not part of OpenMediaVault, but is offered by third-party +## developers as a service to OpenMediaVault users. +# deb https://packages.openmediavault.org/public shaitan partner +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner +EOF +$STD apt-get update +$STD apt-get -y install openmediavault-keyring +$STD apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends install openmediavault +omv-confdbadm populate +msg_ok "Installed OpenMediaVault" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From f80668d25727adc088c4b2820fd51389cc0c11f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 16:17:26 -0500 Subject: [PATCH 4047/6505] Create nocodb-v5.sh --- ct/nocodb-v5.sh | 363 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 ct/nocodb-v5.sh diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh new file mode 100644 index 00000000..adc7d0c3 --- /dev/null +++ b/ct/nocodb-v5.sh @@ -0,0 +1,363 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ __ ____ ____ + / | / /___ ____v5___ / __ \/ __ ) + / |/ / __ \/ ___/ __ \/ / / / __ | + / /| / /_/ / /__/ /_/ / /_/ / /_/ / +/_/ |_/\____/\___/\____/_____/_____/ + +EOF +} +echo -e "Loading..." +APP="NocoDB" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/nocodb.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP}" +cd /opt/nocodb +npm uninstall -s --save nocodb &>/dev/null +npm install -s --save nocodb &>/dev/null +systemctl restart nocodb.service +msg_ok "Updated ${APP}" +msg_ok "Update Successfull" + +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080/dashboard${CL} \n" From 92f7b58e89e6530364060f3586b18718e03ff226 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 16:20:31 -0500 Subject: [PATCH 4048/6505] Create nocodb-v5-install.sh --- install/nocodb-v5-install.sh | 147 +++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 install/nocodb-v5-install.sh diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh new file mode 100644 index 00000000..967a506e --- /dev/null +++ b/install/nocodb-v5-install.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD sudo apt-get install -y nodejs git make g++ gcc +msg_ok "Installed Node.js" + +msg_info "Installing NocoDB" +$STD git clone https://github.com/nocodb/nocodb-seed +mv nocodb-seed /opt/nocodb +cd /opt/nocodb +$STD npm install +msg_ok "Installed NocoDB" + +msg_info "Creating Service" +service_path="/etc/systemd/system/nocodb.service" +echo "[Unit] +Description=nocodb + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/nocodb +ExecStart=/usr/bin/npm start + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now nocodb.service &>/dev/null +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 49ccdfc55a79e9425b1d3c00b346484817642c0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 16:29:58 -0500 Subject: [PATCH 4049/6505] Update omv-v5.sh --- ct/omv-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index ff71fa08..5db16487 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -82,7 +82,7 @@ if command -v pveversion >/dev/null 2>&1; then fi fi if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + if [[ ! -f /etc/apt/sources.list.d/openmediavault.list ]]; then msg_error "No ${APP} Installation Found!"; exit fi From b3bcfbf2750b02a516c3dba4b0ad2624a9323241 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 16:42:47 -0500 Subject: [PATCH 4050/6505] Create omada-v5.sh --- ct/omada-v5.sh | 358 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 ct/omada-v5.sh diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh new file mode 100644 index 00000000..e97af3d9 --- /dev/null +++ b/ct/omada-v5.sh @@ -0,0 +1,358 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \____ ___v5____ _____/ /___ _ + / / / / __ __ \/ __ / __ / __ / +/ /_/ / / / / / / /_/ / /_/ / /_/ / +\____/_/ /_/ /_/\__,_/\__,_/\__,_/ + +EOF +} +echo -e "Loading..." +APP="Omada" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/tplink ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:8043${CL} \n" From e4b4a3408a329fab6333e922b6ab21b8524f6d25 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 16:44:09 -0500 Subject: [PATCH 4051/6505] Create omada-v5-install.sh --- install/omada-v5-install.sh | 124 ++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 install/omada-v5-install.sh diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh new file mode 100644 index 00000000..898c75a4 --- /dev/null +++ b/install/omada-v5-install.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get -y install curl +$STD apt-get -y install sudo +$STD apt-get -y install gnupg +$STD apt-get -y install openjdk-8-jre-headless +$STD apt-get -y install jsvc +wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb +$STD dpkg -i mongodb-org-server_3.6.23_amd64.deb +msg_ok "Installed Dependencies" + +msg_info "Installing Omada Controller v5.7.4" +wget -qL https://static.tp-link.com/upload/software/2022/202211/20221121/Omada_SDN_Controller_v5.7.4_Linux_x64.deb +$STD dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb +msg_ok "Installed Omada Controller" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf Omada_SDN_Controller_v5.7.4_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 24f121446527a4c834dffe69560911026c2735be Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Jan 2023 17:14:37 -0500 Subject: [PATCH 4052/6505] Delete nocodb-update.sh prune --- misc/nocodb-update.sh | 84 ------------------------------------------- 1 file changed, 84 deletions(-) delete mode 100644 misc/nocodb-update.sh diff --git a/misc/nocodb-update.sh b/misc/nocodb-update.sh deleted file mode 100644 index 3cc7494c..00000000 --- a/misc/nocodb-update.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="NocoDB" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - read -p "This will Update ${APP}. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - echo -e "${YW} - _ _ _____ ____ - | \ | | | __ \| _ \ - | \| | ___ v3___ ___ | | | | |_) | - | |/ _ \ / __/ _ \| | | | _ < - | |\ | (_) | (_| (_) | |__| | |_) | - |_| \_|\___/ \___\___/|_____/|____/ - UPDATE -${CL}" -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_info "Updating ${APP}" -cd /opt/nocodb -npm uninstall -s --save nocodb &>/dev/null -npm install -s --save nocodb &>/dev/null -msg_ok "Updated ${APP}" - -read -p "${APP} LXC needs to reboot to apply the update. Reboot now? " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]]; then - reboot=yes -else - reboot=no -fi - -if [ "$reboot" == "yes" ]; then - msg_info "Rebooting ${APP} LXC" - reboot -fi - -if [ "$reboot" == "no" ]; then - msg_ok "Finished Updating ${APP}. Reboot to apply the update." -fi From 849c65dc631b8491e9631d64c2cb33e8f3804608 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 00:53:08 -0500 Subject: [PATCH 4053/6505] Update homeassistant-core-v5.sh tweak --- ct/homeassistant-core-v5.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 32191909..010d5ee2 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Home Assistant-Core" var_disk="8" From 3a6d7cb0cb6de3d8c9d3d6aa5ea8b8f2e78a9f9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 01:17:13 -0500 Subject: [PATCH 4054/6505] small tweak --- ct/adguard-v5.sh | 2 ++ ct/debian-v5.sh | 2 ++ ct/docker-v5.sh | 2 ++ ct/emqx-v5.sh | 2 ++ ct/esphome-v5.sh | 2 ++ ct/grafana-v5.sh | 2 ++ ct/heimdalldashboard-v5.sh | 2 ++ ct/homeassistant-v5.sh | 2 ++ ct/jellyfin-v5.sh | 2 ++ ct/mqtt-v5.sh | 2 ++ ct/nginxproxymanager-v5.sh | 2 ++ ct/nocodb-v5.sh | 2 ++ ct/node-red-v5.sh | 2 ++ ct/omada-v5.sh | 2 ++ ct/omv-v5.sh | 2 ++ ct/openhab-v5.sh | 2 ++ ct/paperless-ngx-v5.sh | 2 ++ ct/photoprism-v5.sh | 2 ++ ct/pihole-v5.sh | 2 ++ ct/plex-v5.sh | 2 ++ ct/postgresql-v5.sh | 2 ++ ct/prometheus-v5.sh | 2 ++ ct/scrypted-v5.sh | 2 ++ ct/shinobi-v5.sh | 2 ++ ct/syncthing-v5.sh | 2 ++ ct/technitiumdns-v5.sh | 2 ++ ct/trilium-v5.sh | 2 ++ ct/ubuntu-v5.sh | 2 ++ ct/umbrel-v5.sh | 2 ++ ct/unifi-v5.sh | 2 ++ ct/uptimekuma-v5.sh | 2 ++ ct/vaultwarden-v5.sh | 2 ++ ct/whoogle-v5.sh | 2 ++ ct/wikijs-v5.sh | 2 ++ ct/wireguard-v5.sh | 2 ++ ct/yunohost-v5.sh | 2 ++ ct/zigbee2mqtt-v5.sh | 2 ++ ct/zwave-js-ui-v5.sh | 2 ++ 38 files changed, 76 insertions(+) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 7255389e..a9b1d654 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Adguard" var_disk="2" diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 5483076f..ff89f394 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Debian" var_disk="2" diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 50ddd2b7..9bfefa5d 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Docker" var_disk="4" diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 7efa5a96..516dcb11 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="EMQX" var_disk="4" diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index b2d8d894..c0075256 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="ESPHome" var_disk="4" diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 9eace3c6..f44e350b 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Grafana" var_disk="2" diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 5ed5886b..1893c29b 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Heimdall Dashboard" var_disk="2" diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index e54c59af..3d438741 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Home Assistant" var_disk="16" diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 06d532e0..eeece3f7 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Jellyfin" var_disk="8" diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 9b8f137c..f755ee24 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -9,6 +9,8 @@ cat <<"EOF" EOF } +clear +header_info echo -e "Loading..." APP="MQTT" var_disk="2" diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index ac5fb686..5f6dc182 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Nginx Proxy Manager" var_disk="4" diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index adc7d0c3..2e100e69 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="NocoDB" var_disk="4" diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index c0b801b8..4ab0b95e 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Node-Red" var_disk="4" diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index e97af3d9..2d68c82e 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Omada" var_disk="8" diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 5db16487..23f9be1e 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="OMV" var_disk="4" diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 7259e024..42edfccf 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="openHAB" var_disk="8" diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index fb3aa3f6..6b034fb2 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Paperless-ngx" var_disk="4" diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 4d9fc8a5..5a697f43 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="PhotoPrism" var_disk="8" diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 3357d5c0..b5728a0e 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Pihole" var_disk="2" diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index fc40ecfb..f437089b 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Plex" var_disk="8" diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index c5cacfde..02acf365 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -9,6 +9,8 @@ function header_info { /____/ EOF } +clear +header_info echo -e "Loading..." APP="PostgreSQL" var_disk="4" diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 30b211dc..bdddfc63 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Prometheus" var_disk="4" diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index b03095b5..eaa3cb62 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Scrypted" var_disk="8" diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index dd10e026..bf576ece 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Shinobi" var_disk="8" diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index a24cedc2..480b4529 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Syncthing" var_disk="8" diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 245bd0e8..bbc02657 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Technitium DNS" var_disk="2" diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 1d705081..7a49b2bf 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Trilium" var_disk="2" diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 039e5f49..bcbc59a0 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Ubuntu" var_disk="2" diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index a3b29936..b63fa1ba 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Umbrel" var_disk="8" diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 2f7ca498..e94cf63f 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Unifi" var_disk="8" diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 6a5c16a1..5ba683a2 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Uptime Kuma" var_disk="4" diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 816f8cb9..beed903f 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Vaultwarden" var_disk="6" diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index aeda75c5..a68174af 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Whoogle" var_disk="2" diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 772a9212..ebf035af 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Wikijs" var_disk="2" diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index aa13e0b2..d5432e0a 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Wireguard" var_disk="2" diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 9a5d9ee6..401b5a8a 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -9,6 +9,8 @@ __ __ __ __ __ EOF } +clear +header_info echo -e "Loading..." APP="YunoHost" var_disk="20" diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index af31077f..26382ab0 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -10,6 +10,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Zigbee2MQTT" var_disk="4" diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 0abaf0de..ce3b0d83 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="Zwave-JS-UI" var_disk="4" From 120da5bea6b6beaaa145346a0bbe2a9282df38ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 10:27:15 -0500 Subject: [PATCH 4055/6505] Update ubuntu-v5-install.sh fix --- install/ubuntu-v5-install.sh | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index e14653a6..03415a4b 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -86,32 +86,10 @@ $STD apt-get install -y curl $STD apt-get install -y sudo msg_ok "Installed Dependencies" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -msg_info "Installing Umbrel (Patience)" -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -fi -$STD bash <(curl -fsSL https://umbrel.sh) -systemctl daemon-reload -$STD systemctl enable --now umbrel-startup.service -msg_ok "Installed Umbrel" - PASS=$(grep -w "root" /etc/shadow | cut -b6) if [[ $PASS != $ ]]; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname + chmod -x /etc/update-motd.d/* touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -128,6 +106,7 @@ if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config systemctl restart sshd fi + msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean From 2eb375a516a545e7acbd33fb6a8fb9d41bab009c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 10:36:13 -0500 Subject: [PATCH 4056/6505] Update wikijs-v5.sh fix path --- ct/wikijs-v5.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index ebf035af..465d6f82 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -318,9 +318,9 @@ systemctl stop wikijs msg_ok "Stopped ${APP}" msg_info "Updating ${APP}" -cp /opt/wiki/config.yml ~/config.yml.bak -rm -rf /opt/wiki/* -cd /opt/wiki +cp /opt/wikijs/config.yml ~/config.yml.bak +rm -rf /opt/wikijs/* +cd /opt/wikijs wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz &>/dev/null tar xzf wiki-js.tar.gz cp ~/config.yml.bak ./config.yml From 91da8137545c286751e71ac9bd0c1a6f03a284b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 12:54:41 -0500 Subject: [PATCH 4057/6505] Update yunohost-v5-install.sh adjust dependencies --- install/yunohost-v5-install.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 29262c7f..a1f498f9 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -81,13 +81,17 @@ $STD apt-get -y upgrade msg_ok "Updated Container OS" msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo +$STD apt-get install -y \ +curl \ +sudo \ +apt-transport-https \ +lsb-release \ +ca-certificates msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" $STD bash <(curl -fsSL https://install.yunohost.org) -a -$STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' +wget -s -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg msg_ok "Installed YunoHost" PASS=$(grep -w "root" /etc/shadow | cut -b6) From f10275f8da092783d1dbec95968caae80d8bcb9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 13:00:12 -0500 Subject: [PATCH 4058/6505] Update yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index a1f498f9..f2783bd5 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -82,11 +82,11 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y \ -curl \ -sudo \ -apt-transport-https \ -lsb-release \ -ca-certificates + curl \ + sudo \ + apt-transport-https \ + lsb-release \ + ca-certificates msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" From 2e697748882c3242c554ff8bdcc966d545b1b0f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 13:01:12 -0500 Subject: [PATCH 4059/6505] Update yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index f2783bd5..d454382a 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -91,7 +91,7 @@ msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" $STD bash <(curl -fsSL https://install.yunohost.org) -a -wget -s -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg +wget -q -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg msg_ok "Installed YunoHost" PASS=$(grep -w "root" /etc/shadow | cut -b6) From 796822d451c4933f16acae2bd9cdc42d93905950 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 13:26:42 -0500 Subject: [PATCH 4060/6505] Update yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index d454382a..a3897aae 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -81,12 +81,11 @@ $STD apt-get -y upgrade msg_ok "Updated Container OS" msg_info "Installing Dependencies" -$STD apt-get install -y \ - curl \ - sudo \ - apt-transport-https \ - lsb-release \ - ca-certificates +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y apt-transport-https +$STD apt-get install -y lsb-release +$STD apt-get install -y ca-certificates msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" From 9a56cba0d916221a8ca77b3edd57dc00fbf3c0b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 14:28:29 -0500 Subject: [PATCH 4061/6505] Update yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index a3897aae..298f5469 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -90,7 +90,7 @@ msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" $STD bash <(curl -fsSL https://install.yunohost.org) -a -wget -q -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg +$STD wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg msg_ok "Installed YunoHost" PASS=$(grep -w "root" /etc/shadow | cut -b6) From 26da03b58ee776e629838528bddb72be3a925d4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 14:49:08 -0500 Subject: [PATCH 4062/6505] Update yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 298f5469..a2fbcbe0 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -89,8 +89,8 @@ $STD apt-get install -y ca-certificates msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" +wget -q -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg $STD bash <(curl -fsSL https://install.yunohost.org) -a -$STD wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg msg_ok "Installed YunoHost" PASS=$(grep -w "root" /etc/shadow | cut -b6) From 0d26ac813b83da9d137fc8bd5f26a58e1b8564f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 14:59:03 -0500 Subject: [PATCH 4063/6505] Update yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index a2fbcbe0..55163f04 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' $STD apt-get install -y apt-transport-https $STD apt-get install -y lsb-release $STD apt-get install -y ca-certificates From 57452c3defda3fb10877e3981b4d64278c7d46be Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Jan 2023 15:07:55 -0500 Subject: [PATCH 4064/6505] Update yunohost-v5-install.sh --- install/yunohost-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 55163f04..19eeec06 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y gnupg $STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' $STD apt-get install -y apt-transport-https $STD apt-get install -y lsb-release From 94dc697f2a37d278a8b9855f59767eade7fa04cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 09:47:30 -0500 Subject: [PATCH 4065/6505] Create emby-v5.sh --- ct/emby-v5.sh | 393 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 ct/emby-v5.sh diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh new file mode 100644 index 00000000..47f97452 --- /dev/null +++ b/ct/emby-v5.sh @@ -0,0 +1,393 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ __ + / ____/___ v5_ / /_ __ __ + / __/ / __ __ \/ __ \/ / / / + / /___/ / / / / / /_/ / /_/ / +/_____/_/ /_/ /_/_.___/\__, / + /____/ +EOF +} +clear +header_info +echo -e "Loading..." +APP="Emby" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/emby-server ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +msg_info "Stopping ${APP}" +systemctl stop emby-server +msg_ok "Stopped ${APP}" + +msg_info "Updating ${APP}" +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null +dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null +rm emby-server-deb_${LATEST}_amd64.deb +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +systemctl start emby-server +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8096${CL}\n" From aef6478a9709815c6e57450ef9f1829a2331d5bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 09:48:39 -0500 Subject: [PATCH 4066/6505] Create emby-v5-install.sh --- install/emby-v5-install.sh | 134 +++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 install/emby-v5-install.sh diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh new file mode 100644 index 00000000..8caf588b --- /dev/null +++ b/install/emby-v5-install.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + beignet-opencl-icd + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + +LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) + +msg_info "Installing Emby" +wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb +$STD dpkg -i emby-server-deb_${LATEST}_amd64.deb +msg_ok "Installed Emby" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm emby-server-deb_${LATEST}_amd64.deb +msg_ok "Cleaned" From 31db188ccaa7bf832c8bb9caae5a5c230a24e9f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 10:05:16 -0500 Subject: [PATCH 4067/6505] Update and rename nextcloudpi-install.sh to nextcloudpi-v5-install.sh --- ...pi-install.sh => nextcloudpi-v5-install.sh} | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) rename install/{nextcloudpi-install.sh => nextcloudpi-v5-install.sh} (90%) diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-v5-install.sh similarity index 90% rename from install/nextcloudpi-install.sh rename to install/nextcloudpi-v5-install.sh index ec0729d7..45f6b6d3 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -19,7 +19,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR - +silent() { "$@" > /dev/null 2>&1; } function error_exit() { trap - ERR local reason="Unknown failure occurred." @@ -76,19 +76,19 @@ alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +$STD apt-get update +$STD apt-get -y upgrade msg_ok "Updated Container OS" msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null +$STD apt-get install -y curl +$STD apt-get install -y sudo msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" -curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php -sudo service apache2 restart +service apache2 restart msg_ok "Installed NextCloudPi" PASS=$(grep -w "root" /etc/shadow | cut -b6) @@ -113,6 +113,6 @@ if [[ "${SSH_ROOT}" == "yes" ]]; then fi msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null +$STD apt-get autoremove +$STD apt-get autoclean msg_ok "Cleaned" From d66e0aa0595c5568b91d4f0a139429d329f002cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 10:10:01 -0500 Subject: [PATCH 4068/6505] Create nextcloudpi-install.sh --- install/nextcloudpi-install.sh | 118 +++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 install/nextcloudpi-install.sh diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh new file mode 100644 index 00000000..ec0729d7 --- /dev/null +++ b/install/nextcloudpi-install.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +apt-get install -y curl &>/dev/null +apt-get install -y sudo &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Installing NextCloudPi (Patience)" +curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null +sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php +sudo service apache2 restart +msg_ok "Installed NextCloudPi" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" From 6527e93d240b4895f123dbe0d9df29bd478e5c15 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 10:26:47 -0500 Subject: [PATCH 4069/6505] Create nextcloudpi-v5.sh --- ct/nextcloudpi-v5.sh | 362 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 ct/nextcloudpi-v5.sh diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh new file mode 100644 index 00000000..21a33b6f --- /dev/null +++ b/ct/nextcloudpi-v5.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ __ __ ________ ______ _ + / | / /__ _ __/ /_/ ____/ /___ __v5______/ / __ \(_) + / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / /_/ / / + / /| / __/> &2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}https://${IP}/${CL} \n" From 1dc7c180d303bea8ee337de51dbd700f3f697ce9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 11:21:31 -0500 Subject: [PATCH 4070/6505] Delete emby-update.sh prune --- misc/emby-update.sh | 52 --------------------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 misc/emby-update.sh diff --git a/misc/emby-update.sh b/misc/emby-update.sh deleted file mode 100644 index 85f7bc83..00000000 --- a/misc/emby-update.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash -LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Emby" -while true; do - read -p "This will Update ${APP} to ${LATEST}. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - cat <<"EOF" - ______ __ - / ____/___ ___ / /_ __ __ - / __/ / __ __ \/ __ \/ / / / - / /___/ / / / / / /_/ / /_/ / -/_____/_/ /_/ /_/_.___/\__, / - UPDATE /____/ -EOF -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_info "Updating ${APP}" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null -systemctl stop emby-server -dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null -systemctl start emby-server -rm emby-server-deb_${LATEST}_amd64.deb -msg_ok "Updated ${APP}" From 025c7f45ce3cd20fb25bced82860b2c0612c077a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 11:57:13 -0500 Subject: [PATCH 4071/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 010d5ee2..5ac794f1 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -317,10 +317,11 @@ function install_script() { function update_script() { PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 4 \ "1" "Initialize" OFF \ "2" "Update Core" ON \ "3" "Install HACS" OFF \ + "4" "Install FileBrowser" OFF \ 3>&1 1>&2 2>&3) if [ "$UPD" == "1" ]; then @@ -373,6 +374,35 @@ msg_ok "Installed Home Assistant Comunity Store (HACS)" echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" exit fi +if [ "$UPD" == "4" ]; then +clear +header_info +msg_info "Installing FileBrowser" +curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null +filebrowser config init -a '0.0.0.0' &>/dev/null +filebrowser config set -a '0.0.0.0' &>/dev/null +filebrowser users add admin changeme --perm.admin &>/dev/null +msg_ok "Installed FileBrowser on $hostname" + +msg_info "Creating Service" +service_path="/etc/systemd/system/filebrowser.service" +echo "[Unit] +Description=Filebrowser +After=network-online.target +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r / +[Install] +WantedBy=default.target" >$service_path + +systemctl enable --now filebrowser.service &>/dev/null +msg_ok "Created Service" + +msg_ok "Completed Successfully!\n" +echo -e "FileBrowser should be reachable by going to the following URL. + ${BL}http://$IP:8080${CL} \n" +exit } clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi From c59c795b1ce68f6dc91f205a90cf2cf256df8d82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:01:28 -0500 Subject: [PATCH 4072/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 5ac794f1..cfe06b12 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -403,7 +403,9 @@ msg_ok "Completed Successfully!\n" echo -e "FileBrowser should be reachable by going to the following URL. ${BL}http://$IP:8080${CL} \n" exit +fi } + clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi From 240695d613e80ff8b9b8f0141fba1391a115f2f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:04:18 -0500 Subject: [PATCH 4073/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index cfe06b12..f793b868 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -317,7 +317,7 @@ function install_script() { function update_script() { PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 4 \ + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 15 58 4 \ "1" "Initialize" OFF \ "2" "Update Core" ON \ "3" "Install HACS" OFF \ From ead749947267918c44a75c5fa3a3a94e05ba8042 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:16:42 -0500 Subject: [PATCH 4074/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index f793b868..6c26cb99 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -382,7 +382,7 @@ curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bas filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null -msg_ok "Installed FileBrowser on $hostname" +msg_ok "Installed FileBrowser" msg_info "Creating Service" service_path="/etc/systemd/system/filebrowser.service" From 0882f89db6d79aec93b5b07cfca6d7e9d6e8a996 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:21:14 -0500 Subject: [PATCH 4075/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 6c26cb99..01d835e6 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -392,7 +392,7 @@ After=network-online.target [Service] User=root WorkingDirectory=/root/ -ExecStart=/usr/local/bin/filebrowser -r / +ExecStart=/usr/local/bin/filebrowser -r /root/.homeassistant [Install] WantedBy=default.target" >$service_path @@ -401,7 +401,7 @@ msg_ok "Created Service" msg_ok "Completed Successfully!\n" echo -e "FileBrowser should be reachable by going to the following URL. - ${BL}http://$IP:8080${CL} \n" + ${BL}http://$IP:8080${CL} admin|changeme\n" exit fi } From 7417027d0fc72915cb18446d62e1378754d3544e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:36:45 -0500 Subject: [PATCH 4076/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 01d835e6..35e73e5b 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -90,7 +90,7 @@ if ! command -v pveversion >/dev/null 2>&1; then msg_error "No Home Assistant Core Installation Found!"; exit fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "Initialize, Update or Install HACS. Proceed?" 10 58); then + if (whiptail --title "${APP} LXC SUPPORT" --yesno "Initialize, Update Core, Install HACS or FileBrowser. Proceed?" 10 58); then echo "User selected Support" else clear From de15171b094b9a590347ec5085bb618dcca72134 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:41:59 -0500 Subject: [PATCH 4077/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 35e73e5b..51c2da41 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -369,7 +369,7 @@ msg_info "Installing Home Assistant Comunity Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null cd .homeassistant -wget -O - https://get.hacs.xyz | bash - &>/dev/null +bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null msg_ok "Installed Home Assistant Comunity Store (HACS)" echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" exit From a5d75b921ddb777652c86925d6a0ce6861897dc0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:50:32 -0500 Subject: [PATCH 4078/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 51c2da41..ce077d53 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -90,7 +90,7 @@ if ! command -v pveversion >/dev/null 2>&1; then msg_error "No Home Assistant Core Installation Found!"; exit fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "Initialize, Update Core, Install HACS or FileBrowser. Proceed?" 10 58); then + if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC" 10 58); then echo "User selected Support" else clear From 5fb0e81effa65a52daca2297b1c9d406257f1c96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 12:51:10 -0500 Subject: [PATCH 4079/6505] Update homeassistant-v5.sh --- ct/homeassistant-v5.sh | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 3d438741..c83f05b5 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -320,10 +320,11 @@ function install_script() { fi } function update_script() { -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ +UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 15 58 4 \ "1" "Update ALL Containers" ON \ "2" "Remove ALL Unused Images" OFF \ "3" "Install HACS" OFF \ + "4" "Install FileBrowser" OFF \ 3>&1 1>&2 2>&3) clear header_info @@ -358,11 +359,42 @@ msg_info "Installing Home Assistant Comunity Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null cd /var/lib/docker/volumes/hass_config/_data -wget -O - https://get.hacs.xyz | bash - +bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null msg_ok "Installed Home Assistant Comunity Store (HACS)" echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" exit fi +if [ "$UPD" == "4" ]; then +clear +header_info +msg_info "Installing FileBrowser" +curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null +filebrowser config init -a '0.0.0.0' &>/dev/null +filebrowser config set -a '0.0.0.0' &>/dev/null +filebrowser users add admin changeme --perm.admin &>/dev/null +msg_ok "Installed FileBrowser" + +msg_info "Creating Service" +service_path="/etc/systemd/system/filebrowser.service" +echo "[Unit] +Description=Filebrowser +After=network-online.target +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r / +[Install] +WantedBy=default.target" >$service_path + +systemctl enable --now filebrowser.service &>/dev/null +msg_ok "Created Service" + +msg_ok "Completed Successfully!\n" +echo -e "FileBrowser should be reachable by going to the following URL. + ${BL}http://$IP:8080${CL} admin|changeme\n" +exit +fi +} } clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi From f88f59cc42cc2157ec033369e706dfe8b294a048 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 15:54:03 -0500 Subject: [PATCH 4080/6505] Update homeassistant-v5.sh --- ct/homeassistant-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index c83f05b5..cb0745a6 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -395,7 +395,7 @@ echo -e "FileBrowser should be reachable by going to the following URL. exit fi } -} + clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi From 232c9d03f0bdaea4416c76c430b3a78fd06bc15f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 16:40:04 -0500 Subject: [PATCH 4081/6505] Update homeassistant-v5.sh --- ct/homeassistant-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index cb0745a6..2979ae73 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -367,6 +367,7 @@ fi if [ "$UPD" == "4" ]; then clear header_info +IP=$(hostname -I | awk '{print $1}') msg_info "Installing FileBrowser" curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null From 2172a2031ae02b8c8fa7e78b019954dc06b66e9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 20:21:24 -0500 Subject: [PATCH 4082/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index ce077d53..45dc9abb 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -317,7 +317,7 @@ function install_script() { function update_script() { PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 15 58 4 \ + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Initialize" OFF \ "2" "Update Core" ON \ "3" "Install HACS" OFF \ From 891e6ef1e20e98040b3dac018be2ef02e81274c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 20:42:08 -0500 Subject: [PATCH 4083/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 45dc9abb..ed7518a8 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -323,10 +323,9 @@ function update_script() { "3" "Install HACS" OFF \ "4" "Install FileBrowser" OFF \ 3>&1 1>&2 2>&3) - -if [ "$UPD" == "1" ]; then clear header_info +if [ "$UPD" == "1" ]; then echo -e "\n LOG VIEWER - Go to http://${IP}:8123 to setup \n" cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass exit @@ -363,8 +362,6 @@ echo -e "\n Go to http://${IP}:8123 \n" exit fi if [ "$UPD" == "3" ]; then -clear -header_info msg_info "Installing Home Assistant Comunity Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null @@ -375,8 +372,6 @@ echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integrat exit fi if [ "$UPD" == "4" ]; then -clear -header_info msg_info "Installing FileBrowser" curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null From 6a132e0305f0065d4fe2fb19990d6a9f92a4d901 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 20:43:08 -0500 Subject: [PATCH 4084/6505] Update homeassistant-v5.sh --- ct/homeassistant-v5.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 2979ae73..01b3ec40 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -320,7 +320,7 @@ function install_script() { fi } function update_script() { -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 15 58 4 \ + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update ALL Containers" ON \ "2" "Remove ALL Unused Images" OFF \ "3" "Install HACS" OFF \ @@ -353,8 +353,6 @@ msg_ok "Removed ALL Unused Images" exit fi if [ "$UPD" == "3" ]; then -clear -header_info msg_info "Installing Home Assistant Comunity Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null @@ -365,8 +363,6 @@ echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integrat exit fi if [ "$UPD" == "4" ]; then -clear -header_info IP=$(hostname -I | awk '{print $1}') msg_info "Installing FileBrowser" curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null From 091bc88d44d0abd6a3b38168801ec86fefc28c9e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 21:04:04 -0500 Subject: [PATCH 4085/6505] Small Tweak --- ct/node-red-v5.sh | 2 +- ct/paperless-ngx-v5.sh | 2 +- ct/vaultwarden-v5.sh | 2 +- ct/wireguard-v5.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 4ab0b95e..f1ab8ffc 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -309,7 +309,7 @@ function install_script() { fi } function update_script() { -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update ${APP}" ON \ "2" "Install Themes" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 6b034fb2..469e764c 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -313,7 +313,7 @@ function update_script() { RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') SER=/etc/systemd/system/paperless-task-queue.service -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update Paperless-ngx to $RELEASE" ON \ "2" "Paperless-ngx Credentials" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index beed903f..8da83b3b 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -317,7 +317,7 @@ WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/relea grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 3 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "VaultWarden $VAULT" ON \ "2" "Web-Vault $WVRELEASE" OFF \ "3" "Show Admin Token" OFF \ diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index d5432e0a..5c6a2ddf 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -310,7 +310,7 @@ function install_script() { } function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update ${APP} LXC" ON \ "2" "Install WGDashboard" OFF \ 3>&1 1>&2 2>&3) From 6ec035f346df52f540db736f66297f2fabc4fc03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 21:06:00 -0500 Subject: [PATCH 4086/6505] tweak --- ct/node-red-v5.sh | 2 +- ct/paperless-ngx-v5.sh | 2 +- ct/vaultwarden-v5.sh | 2 +- ct/wireguard-v5.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index f1ab8ffc..c9665f5a 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -309,7 +309,7 @@ function install_script() { fi } function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ "2" "Install Themes" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 469e764c..1c6abd8e 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -313,7 +313,7 @@ function update_script() { RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') SER=/etc/systemd/system/paperless-task-queue.service -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update Paperless-ngx to $RELEASE" ON \ "2" "Paperless-ngx Credentials" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 8da83b3b..484b6cf8 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -317,7 +317,7 @@ WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/relea grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ "1" "VaultWarden $VAULT" ON \ "2" "Web-Vault $WVRELEASE" OFF \ "3" "Show Admin Token" OFF \ diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 5c6a2ddf..ed69d7ee 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -310,7 +310,7 @@ function install_script() { } function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP} LXC" ON \ "2" "Install WGDashboard" OFF \ 3>&1 1>&2 2>&3) From e7d298ca3bd0ad42c9999d651ceb2052f52d6f30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 21:10:04 -0500 Subject: [PATCH 4087/6505] tweak --- ct/node-red-v5.sh | 2 -- ct/paperless-ngx-v5.sh | 3 +-- ct/vaultwarden-v5.sh | 1 - ct/wireguard-v5.sh | 1 + 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index c9665f5a..81173327 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -331,8 +331,6 @@ msg_ok "Update Successful" exit fi if [ "$UPD" == "2" ]; then -clear -header_info THEME=$(whiptail --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ "dark" "" OFF \ "dracula" "" OFF \ diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 1c6abd8e..15a1b86e 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -382,12 +382,11 @@ msg_ok "Updated Successfully!\n" exit fi if [ "$UPD" == "2" ]; then -clear -header_info cat paperless.creds exit fi } + clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 484b6cf8..af50e1f4 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -357,7 +357,6 @@ echo -e "\n ⚠️ Ensure you set resources back to normal settings \n" exit; fi if [ "$UPD" == "2" ]; then - msg_info "Stopping Vaultwarden" systemctl stop vaultwarden.service msg_ok "Stopped Vaultwarden" diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index ed69d7ee..a7cae47a 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -369,6 +369,7 @@ echo -e "WGDashboard should be reachable by going to the following URL. exit fi } + clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi From e387388c87bd013b8cda691fdcbcafd4745da8d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 23:47:08 -0500 Subject: [PATCH 4088/6505] Update ubuntu-v5.sh --- ct/ubuntu-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index bcbc59a0..5433958e 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -130,7 +130,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" OFF \ "22.04" "Jammy" ON \ @@ -138,7 +138,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) From e04913f9839d6b766995a62f7b70a050634034d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 23:48:31 -0500 Subject: [PATCH 4089/6505] Update emby-v5.sh --- ct/emby-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 47f97452..d437d570 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ @@ -142,7 +142,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) From 2a87fea9924aa7746bd0d01f4bb20f033cb3ca32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Jan 2023 23:56:54 -0500 Subject: [PATCH 4090/6505] whiptail tweaks --- ct/adguard-v4.sh | 2 +- ct/adguard-v5.sh | 2 +- ct/alpine-v4.sh | 2 +- ct/archlinux-v4.sh | 2 +- ct/blocky-v4.sh | 2 +- ct/casaos-v4.sh | 2 +- ct/changedetection-v4.sh | 2 +- ct/daemonsync-v4.sh | 2 +- ct/dashy-v4.sh | 2 +- ct/debian-v4.sh | 2 +- ct/debian-v5.sh | 2 +- ct/deconz-v4.sh | 2 +- ct/docker-v4.sh | 2 +- ct/docker-v5.sh | 2 +- ct/emby-v4.sh | 2 +- ct/emqx-v4.sh | 2 +- ct/emqx-v5.sh | 2 +- ct/esphome-v4.sh | 2 +- ct/esphome-v5.sh | 2 +- ct/grafana-v4.sh | 2 +- ct/grafana-v5.sh | 2 +- ct/grocy-v4.sh | 2 +- ct/heimdalldashboard-v4.sh | 2 +- ct/heimdalldashboard-v5.sh | 2 +- ct/homeassistant-core-v4.sh | 2 +- ct/homeassistant-core-v5.sh | 2 +- ct/homeassistant-v4.sh | 2 +- ct/homeassistant-v5.sh | 2 +- ct/homebridge-v4.sh | 2 +- ct/homepage-v4.sh | 2 +- ct/hyperion-v4.sh | 2 +- ct/influxdb-v4.sh | 2 +- ct/iobroker-v4.sh | 2 +- ct/jellyfin-v4.sh | 4 ++-- ct/jellyfin-v5.sh | 4 ++-- ct/k0s-v4.sh | 2 +- ct/keycloak-v4.sh | 2 +- ct/magicmirror-v4.sh | 2 +- ct/mariadb-v4.sh | 2 +- ct/meshcentral-v4.sh | 2 +- ct/motioneye-v4.sh | 2 +- ct/mqtt-v4.sh | 2 +- ct/mqtt-v5.sh | 2 +- ct/n8n-v4.sh | 2 +- ct/navidrome-v4.sh | 2 +- ct/nextcloudpi-v4.sh | 2 +- ct/nextcloudpi-v5.sh | 2 +- ct/nginx-proxy-manager-v4.sh | 2 +- ct/nginxproxymanager-v5.sh | 2 +- ct/nocodb-v4.sh | 2 +- ct/nocodb-v5.sh | 2 +- ct/node-red-v4.sh | 2 +- ct/node-red-v5.sh | 2 +- ct/omada-v4.sh | 4 ++-- ct/omada-v5.sh | 4 ++-- ct/omv-v4.sh | 2 +- ct/omv-v5.sh | 2 +- ct/openhab-v4.sh | 2 +- ct/openhab-v5.sh | 2 +- ct/paperless-ngx-v4.sh | 2 +- ct/paperless-ngx-v5.sh | 2 +- ct/photoprism-v4.sh | 2 +- ct/photoprism-v5.sh | 2 +- ct/pihole-v4.sh | 2 +- ct/pihole-v5.sh | 2 +- ct/plex-v4.sh | 4 ++-- ct/plex-v5.sh | 4 ++-- ct/podman-homeassistant-v4.sh | 2 +- ct/podman-v4.sh | 2 +- ct/postgresql-v4.sh | 2 +- ct/postgresql-v5.sh | 2 +- ct/prometheus-v4.sh | 2 +- ct/prometheus-v5.sh | 2 +- ct/scrypted-v4.sh | 2 +- ct/scrypted-v5.sh | 2 +- ct/shinobi-v4.sh | 2 +- ct/shinobi-v5.sh | 2 +- ct/syncthing-v4.sh | 2 +- ct/syncthing-v5.sh | 2 +- ct/technitiumdns-v4.sh | 2 +- ct/technitiumdns-v5.sh | 2 +- ct/trilium-v4.sh | 2 +- ct/trilium-v5.sh | 2 +- ct/ubuntu-v4.sh | 2 +- ct/umbrel-v4.sh | 2 +- ct/umbrel-v5.sh | 2 +- ct/unifi-v4.sh | 2 +- ct/unifi-v5.sh | 2 +- ct/uptimekuma-v4.sh | 2 +- ct/uptimekuma-v5.sh | 2 +- ct/vaultwarden-v4.sh | 2 +- ct/vaultwarden-v5.sh | 2 +- ct/whoogle-v4.sh | 2 +- ct/whoogle-v5.sh | 2 +- ct/wikijs-v4.sh | 2 +- ct/wikijs-v5.sh | 2 +- ct/wireguard-v4.sh | 2 +- ct/wireguard-v5.sh | 2 +- ct/yunohost-v5.sh | 2 +- ct/zigbee2mqtt-v4.sh | 2 +- ct/zigbee2mqtt-v5.sh | 2 +- ct/zwave-js-ui-v4.sh | 2 +- ct/zwave-js-ui-v5.sh | 2 +- vm/haos-vm-v4.sh | 2 +- 104 files changed, 110 insertions(+), 110 deletions(-) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index 1b65ff63..c430c632 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index a9b1d654..19253057 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -132,7 +132,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/alpine-v4.sh b/ct/alpine-v4.sh index 74ca977f..a95cc37d 100644 --- a/ct/alpine-v4.sh +++ b/ct/alpine-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/archlinux-v4.sh b/ct/archlinux-v4.sh index 0c88369e..001ab7ff 100644 --- a/ct/archlinux-v4.sh +++ b/ct/archlinux-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index 122669b1..7c681676 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index b6c9364a..59da684a 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -107,7 +107,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/changedetection-v4.sh b/ct/changedetection-v4.sh index db179033..61bec458 100644 --- a/ct/changedetection-v4.sh +++ b/ct/changedetection-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index 33bc978f..d8d5fca0 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index 4f777b81..d824ab70 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 25501b0e..7f6c9410 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index ff89f394..d357e70c 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -129,7 +129,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 0a373336..7740e731 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index fcaf2469..6e18ded5 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -106,7 +106,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 9bfefa5d..05a3e7d1 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index c1461b71..0c381a19 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -114,7 +114,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index 21499816..64779851 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 516dcb11..1c7fd2d7 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index ff206eec..e6f44de4 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index c0075256..08853e26 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index f72fd3cf..f6de91c3 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index f44e350b..d8e30cfa 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 3c0f7e0e..90e9cd22 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index 6c4b3492..af75b933 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 1893c29b..6105a6b5 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index 684577a7..93a64643 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index ed7518a8..c4a108af 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -137,7 +137,7 @@ function default_settings() { } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 23577ce7..80218197 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -106,7 +106,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 01b3ec40..f2c18915 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -137,7 +137,7 @@ function default_settings() { } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index ff5edd74..2c3eaa77 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index a7713489..5b7430fe 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/hyperion-v4.sh b/ct/hyperion-v4.sh index 80f618eb..d9125d52 100644 --- a/ct/hyperion-v4.sh +++ b/ct/hyperion-v4.sh @@ -106,7 +106,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index 81b5457e..b1ca3aa8 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 17f878fe..4b54689b 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index 37905cd7..aab2b0a2 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -106,7 +106,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ @@ -114,7 +114,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index eeece3f7..1c500c18 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -136,7 +136,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ @@ -144,7 +144,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/k0s-v4.sh b/ct/k0s-v4.sh index 7e8ac4ba..8254c26c 100644 --- a/ct/k0s-v4.sh +++ b/ct/k0s-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 4702c46e..3266c386 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index ff4c7365..6c172502 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index 20a1ff7a..cf31225e 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 8de241a6..54c21a91 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index f8a8663b..41ead7e5 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh index 0518991c..16d80e43 100644 --- a/ct/mqtt-v4.sh +++ b/ct/mqtt-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index f755ee24..bff59605 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -131,7 +131,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index f09ea205..8cff0d8d 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index ed513d68..893f9311 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index 84ed147c..e0a70b50 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 21a33b6f..511f39f8 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index 6cc5cb1b..a6ab98ad 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 5f6dc182..ccb6d296 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 7503fb7a..2406fd20 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 2e100e69..1b6510da 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index 2ca913de..fec6b066 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 81173327..0a207309 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index 2b48b2a4..f4db3280 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ @@ -113,7 +113,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 2d68c82e..ef01599e 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ @@ -142,7 +142,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index 9aa13239..e279912a 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 23f9be1e..a9a5366a 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index 75d60950..2c1e1541 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 42edfccf..033c762c 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index b51119b6..6ed7022c 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 15a1b86e..9e6d1c24 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index fc5b8c7f..e645f8f2 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 5a697f43..5e5a9961 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -132,7 +132,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index e6a8b6d8..492692bc 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index b5728a0e..9e8bb637 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index 6566426f..9f12ecb5 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -106,7 +106,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ @@ -114,7 +114,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index f437089b..944e9165 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -135,7 +135,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ @@ -143,7 +143,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 9aaa9f40..36a5fef9 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -108,7 +108,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/podman-v4.sh b/ct/podman-v4.sh index 49878c07..1a28ea73 100644 --- a/ct/podman-v4.sh +++ b/ct/podman-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index cee3ec14..771d0568 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index 02acf365..e1412d2f 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 3cc52e25..474cc21e 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index bdddfc63..490bd911 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh index 77f84839..e8d364c9 100644 --- a/ct/scrypted-v4.sh +++ b/ct/scrypted-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index eaa3cb62..788759d7 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/shinobi-v4.sh b/ct/shinobi-v4.sh index 08b8fcb9..427e7e7a 100644 --- a/ct/shinobi-v4.sh +++ b/ct/shinobi-v4.sh @@ -114,7 +114,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index bf576ece..94d0b2f8 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -142,7 +142,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index 85da6fc5..c66e96e1 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -106,7 +106,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 480b4529..892c06f1 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index 70716601..d726ba0c 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index bbc02657..696fdd95 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index 4342cf70..3a9ebe38 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 7a49b2bf..54cbf786 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 755af1cd..4c47da6d 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -113,7 +113,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 859696e8..2d663fca 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -107,7 +107,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index b63fa1ba..047ec077 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -135,7 +135,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index b0a9bfd4..bf24121e 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index e94cf63f..02550614 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index 297aae54..630b2b04 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 5ba683a2..a82870c4 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index a57b2191..f4ec98da 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index af50e1f4..0a607672 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -133,7 +133,7 @@ function default_settings() { } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 422e9d46..41cc947e 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -104,7 +104,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index a68174af..08741c4c 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index 486100a7..bb5ad6b3 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 465d6f82..c38f34d1 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index 95bfda0a..dd3b594f 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -106,7 +106,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index a7cae47a..824e6f7c 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 401b5a8a..a1382e7f 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -129,7 +129,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 53a0cc5b..46a81164 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 26382ab0..5c8348f4 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -134,7 +134,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 5928e9b9..317f5841 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -105,7 +105,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index ce3b0d83..1b5fb451 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -133,7 +133,7 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ 3>&1 1>&2 2>&3) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v4.sh index c66b2e6f..8dbf2889 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v4.sh @@ -129,7 +129,7 @@ if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMI else if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; fi -MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "i440fx" "Machine i440fx" ON \ "q35" "Machine q35" OFF \ 3>&1 1>&2 2>&3) From 33017199339b50366d4d0367137b6d05845746fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 13:51:26 -0500 Subject: [PATCH 4091/6505] Create navidrome-v5-install.sh --- install/navidrome-v5-install.sh | 168 ++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 install/navidrome-v5-install.sh diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh new file mode 100644 index 00000000..a6230259 --- /dev/null +++ b/install/navidrome-v5-install.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies (patience)" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y ffmpeg +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Installing Navidrome" +install -d -o root -g root /opt/navidrome +install -d -o root -g root /var/lib/navidrome +$STD wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz +$STD tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ +chown -R root:root /opt/navidrome +mkdir -p /music +cat </var/lib/navidrome/navidrome.toml +MusicFolder = '/music' +EOF +msg_ok "Installed Navidrome" + +msg_info "Creating Service" +service_path="/etc/systemd/system/navidrome.service" + +echo "[Unit] +Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic +After=remote-fs.target network.target +AssertPathExists=/var/lib/navidrome + +[Service] +User=root +Group=root +Type=simple +ExecStart=/opt/navidrome/navidrome --configfile '/var/lib/navidrome/navidrome.toml' +WorkingDirectory=/var/lib/navidrome +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +DevicePolicy=closed +NoNewPrivileges=yes +PrivateTmp=yes +PrivateUsers=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +RestrictNamespaces=yes +RestrictRealtime=yes +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap +ReadWritePaths=/var/lib/navidrome +ProtectSystem=full + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl daemon-reload +$STD systemctl enable --now navidrome.service + +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/Navidrome.tar.gz +msg_ok "Cleaned" From 0f40096eed72b82f750bb9eec1eca75bb2e3a1ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 13:52:37 -0500 Subject: [PATCH 4092/6505] Create n8n-v5-install.sh --- install/n8n-v5-install.sh | 140 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 install/n8n-v5-install.sh diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh new file mode 100644 index 00000000..64f241d5 --- /dev/null +++ b/install/n8n-v5-install.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing n8n (Patience)" +$STD npm install --global n8n +msg_ok "Installed n8n" + +msg_info "Creating Service" +cat </etc/systemd/system/n8n.service +[Unit] +Description=n8n + +[Service] +Type=simple +ExecStart=n8n start +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now n8n +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 4058222b23791e5a7b06353328437f5d4a751f90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 13:55:46 -0500 Subject: [PATCH 4093/6505] Create motioneye-v5-install.sh --- install/motioneye-v5-install.sh | 148 ++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 install/motioneye-v5-install.sh diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh new file mode 100644 index 00000000..f6a1e5e4 --- /dev/null +++ b/install/motioneye-v5-install.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y cifs-utils +msg_ok "Installed Dependencies" + +msg_info "Installing Motion" +$STD apt-get install -y motion +systemctl stop motion +$STD systemctl disable motion +msg_ok "Installed Motion" + +msg_info "Installing FFmpeg" +$STD apt-get install -y ffmpeg v4l-utils +msg_ok "Installed FFmpeg" + +msg_info "Installing Python" +$STD apt-get update +$STD apt-get install -y python2 +curl -sSL https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py +$STD python2 get-pip.py +$STD apt-get install -y libffi-dev libzbar-dev libzbar0 +$STD apt-get install -y python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev +msg_ok "Installed Python" + +msg_info "Installing MotionEye" +$STD apt-get update +$STD pip install motioneye +mkdir -p /etc/motioneye +cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf +mkdir -p /var/lib/motioneye +msg_ok "Installed MotionEye" + +msg_info "Creating Service" +cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service +$STD systemctl enable motioneye +systemctl start motioneye +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 653de892517f48720a4530fa6f2edda27fca3f86 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 13:56:43 -0500 Subject: [PATCH 4094/6505] Create meshcentral-v5-install.sh --- install/meshcentral-v5-install.sh | 129 ++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 install/meshcentral-v5-install.sh diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh new file mode 100644 index 00000000..ebc598f8 --- /dev/null +++ b/install/meshcentral-v5-install.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing MeshCentral" +mkdir /opt/meshcentral +cd /opt/meshcentral +$STD npm install meshcentral +$STD node node_modules/meshcentral --install +msg_ok "Installed MeshCentral" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From b05aa11bc9d31c02abaf68f6b37e69f652bd516a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 13:57:40 -0500 Subject: [PATCH 4095/6505] Create mariadb-v5-install.sh --- install/mariadb-v5-install.sh | 135 ++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 install/mariadb-v5-install.sh diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh new file mode 100644 index 00000000..83f6d689 --- /dev/null +++ b/install/mariadb-v5-install.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing MariaDB" +$STD bash <(curl -fsSL https://r.mariadb.com/downloads/mariadb_repo_setup) +$STD apt-get update +$STD apt-get install -y mariadb-server +msg_ok "Installed MariaDB" + +read -r -p "Would you like to add Adminer? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + ADMINER="Y" +else + ADMINER="N" +fi + +if [[ $ADMINER == "Y" ]]; then + msg_info "Installing Adminer" + $STD apt install -y adminer + $STD a2enconf adminer + systemctl reload apache2 + msg_ok "Installed Adminer" +fi + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From b2e17c04953080e2a21332c8ded0428408ddc738 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 13:58:36 -0500 Subject: [PATCH 4096/6505] Create magicmirror-v5-install.sh --- install/magicmirror-v5-install.sh | 241 ++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 install/magicmirror-v5-install.sh diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh new file mode 100644 index 00000000..3405239b --- /dev/null +++ b/install/magicmirror-v5-install.sh @@ -0,0 +1,241 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Setting up MagicMirror Repository" +$STD git clone https://github.com/MichMich/MagicMirror /opt/magicmirror +msg_ok "Set up MagicMirror Repository" + +msg_info "Installing MagicMirror" +cd /opt/magicmirror +$STD npm install --only=prod --omit=dev + +cat </opt/magicmirror/config/config.js +let config = { + address: "0.0.0.0", + port: 8080, + basePath: "/", + ipWhitelist: [], + useHttps: false, + httpsPrivateKey: "", + httpsCertificate: "", + language: "en", + locale: "en-US", + logLevel: ["INFO", "LOG", "WARN", "ERROR"], + timeFormat: 24, + units: "metric", + serverOnly: true, + modules: [ + { + module: "alert", + }, + { + module: "updatenotification", + position: "top_bar" + }, + { + module: "clock", + position: "top_left" + }, + { + module: "calendar", + header: "US Holidays", + position: "top_left", + config: { + calendars: [ + { + symbol: "calendar-check", + url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + } + ] + } + }, + { + module: "compliments", + position: "lower_third" + }, + { + module: "weather", + position: "top_right", + config: { + weatherProvider: "openweathermap", + type: "current", + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + apiKey: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "weather", + position: "top_right", + header: "Weather Forecast", + config: { + weatherProvider: "openweathermap", + type: "forecast", + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + apiKey: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "newsfeed", + position: "bottom_bar", + config: { + feeds: [ + { + title: "New York Times", + url: "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" + } + ], + showSourceTitle: true, + showPublishDate: true, + broadcastNewsFeeds: true, + broadcastNewsUpdates: true + } + }, + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} +EOF +msg_ok "Installed MagicMirror" + +msg_info "Creating Service" +service_path="/etc/systemd/system/magicmirror.service" +echo "[Unit] +Description=Magic Mirror +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +WorkingDirectory=/opt/magicmirror/ +ExecStart=/usr/bin/node serveronly + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now magicmirror +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From ad525d9bd4722aa59418193c5de0a792796c2394 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 13:59:41 -0500 Subject: [PATCH 4097/6505] Create keycloak-v5-install.sh --- install/keycloak-v5-install.sh | 136 +++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 install/keycloak-v5-install.sh diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh new file mode 100644 index 00000000..032c6a6b --- /dev/null +++ b/install/keycloak-v5-install.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y openjdk-11-jdk +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +msg_info "Installing Keycloak v$RELEASE" +cd /opt +wget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz +$STD tar -xvf keycloak-$RELEASE.tar.gz +mv keycloak-$RELEASE keycloak +msg_ok "Installed Keycloak" + +msg_info "Creating Service" +service_path="/etc/systemd/system/keycloak.service" +echo "[Unit] +Description=Keycloak +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/keycloak +ExecStart=/opt/keycloak/bin/kc.sh start-dev +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now keycloak.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 59597dbf8f6d6a8b814c6c168fd59593203fb49c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:00:59 -0500 Subject: [PATCH 4098/6505] Create iobroker-v5-install.sh --- install/iobroker-v5-install.sh | 118 +++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 install/iobroker-v5-install.sh diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh new file mode 100644 index 00000000..c25ff672 --- /dev/null +++ b/install/iobroker-v5-install.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing ioBroker (Patience)" +$STD bash <(curl -fsSL https://iobroker.net/install.sh) +msg_ok "Installed ioBroker" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 8a1b797b8117ab7dd488f9750199385f5e4c6d21 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:02:39 -0500 Subject: [PATCH 4099/6505] Create influxdb-v5-install.sh --- install/influxdb-v5-install.sh | 154 +++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 install/influxdb-v5-install.sh diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh new file mode 100644 index 00000000..dcd61d3d --- /dev/null +++ b/install/influxdb-v5-install.sh @@ -0,0 +1,154 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y lsb-base +$STD apt-get install -y lsb-release +$STD apt-get install -y gnupg2 +msg_ok "Installed Dependencies" + +msg_info "Setting up InfluxDB Repository" +$STD apt-key add <(curl -fsSL https://repos.influxdata.com/influxdb.key) +cat </etc/apt/sources.list.d/influxdb.list +deb https://repos.influxdata.com/debian bullseye stable +EOF +msg_ok "Set up InfluxDB Repository" + +read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt +if [[ $prompt == "2" ]]; then + INFLUX="2" +else + INFLUX="1" +fi + +msg_info "Installing InfluxDB" +$STD apt-get update +if [[ $INFLUX == "2" ]]; then + $STD apt-get install -y influxdb2 +else + $STD apt-get install -y influxdb +fi +$STD systemctl enable --now influxdb +msg_ok "Installed InfluxDB" + +read -r -p "Would you like to add Telegraf? " prompt +if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + TELEGRAF="Y" +else + TELEGRAF="N" +fi + +if [[ $TELEGRAF == "Y" ]]; then + msg_info "Installing Telegraf" + $STD apt-get install -y telegraf + msg_ok "Installed Telegraf" +fi + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 9df08670e0b779c5d9b13c486769aac497f734f4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:04:21 -0500 Subject: [PATCH 4100/6505] Create hyperion-v5-install.sh --- install/hyperion-v5-install.sh | 125 +++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 install/hyperion-v5-install.sh diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh new file mode 100644 index 00000000..fca9b2d9 --- /dev/null +++ b/install/hyperion-v5-install.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y lsb-release +$STD apt-get install -y gpg +$STD apt-get install -y apt-transport-https +msg_ok "Installed Dependencies" + +msg_info "Installing Hyperion" +wget -qO- https://apt.hyperion-project.org/hyperion.pub.key | gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg +cat </etc/apt/sources.list.d/hyperion.list +deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ bullseye main +EOF +$STD apt-get update +$STD apt-get install -y hyperion +$STD systemctl enable --now hyperion@root.service +msg_ok "Installed Hyperion" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove >/dev/null +$STD apt-get autoclean >/dev/null +msg_ok "Cleaned" From ccc8f1c5c03729064fe620dd4426d98f048e7a1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:06:06 -0500 Subject: [PATCH 4101/6505] Create navidrome-v5.sh --- ct/navidrome-v5.sh | 373 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 ct/navidrome-v5.sh diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh new file mode 100644 index 00000000..53750da7 --- /dev/null +++ b/ct/navidrome-v5.sh @@ -0,0 +1,373 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ __ _ __ + / | / /___ __ v5__(_)___/ /________ ____ ___ ___ + / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ + / /| / /_/ /| |/ / / /_/ / / / /_/ / / / / / / __/ +/_/ |_/\__,_/ |___/_/\__,_/_/ \____/_/ /_/ /_/\___/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Navidrome" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/navidrome ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Stopping ${APP}" +systemctl stop navidrome.service +msg_ok "Stopped Navidrome" + +msg_info "Updating to v${RELEASE}" +wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null +tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null +msg_ok "Updated ${APP}" +rm Navidrome.tar.gz + +msg_info "${GN} Starting ${APP}" +systemctl start navidrome.service +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:4533${CL} \n" From ff7e51ca4c0d0d28b0e86f62991e351a175fe2d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:07:10 -0500 Subject: [PATCH 4102/6505] Create n8n-v5.sh --- ct/n8n-v5.sh | 362 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 ct/n8n-v5.sh diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh new file mode 100644 index 00000000..de9aef30 --- /dev/null +++ b/ct/n8n-v5.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ___ + / _ \ + _ __ | (_) |_v5_ + | _ \ > _ <| _ \ + | | | | (_) | | | | + |_| |_|\___/|_| |_| + +EOF +} +clear +header_info +echo -e "Loading..." +APP="n8n" +var_disk="3" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/n8n.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +npm update -g n8n &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5678${CL} \n" From 29a52c8fa89360d85bca0be897e8031d5aa12773 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:08:22 -0500 Subject: [PATCH 4103/6505] Create motioneye-v5.sh --- ct/motioneye-v5.sh | 361 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 ct/motioneye-v5.sh diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh new file mode 100644 index 00000000..94b1d14a --- /dev/null +++ b/ct/motioneye-v5.sh @@ -0,0 +1,361 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ___ __ _ + / |/ /___ / /_(_)___ ____v5___ __ _____ + / /|_/ / __ \/ __/ / __ \/ __ \/ _ \/ / / / _ \ + / / / / /_/ / /_/ / /_/ / / / / __/ /_/ / __/ +/_/ /_/\____/\__/_/\____/_/ /_/\___/\__, /\___/ + /____/ +EOF +} +clear +header_info +echo -e "Loading..." +APP="Motioneye" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/motioneye.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +pip install motioneye --upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8765${CL} \n" From 2f77898de3c155d9c2d0c284f3c9720058531707 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:11:43 -0500 Subject: [PATCH 4104/6505] Create meshcentral-v5.sh --- ct/meshcentral-v5.sh | 362 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 ct/meshcentral-v5.sh diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh new file mode 100644 index 00000000..6f83cd69 --- /dev/null +++ b/ct/meshcentral-v5.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ___ __ ______ __ __ + / |/ /__ _____/ /_ / ____/__ ____ / /__________ _/ / + / /|_/ / _ \/ ___/ __ \/ / / _ \/ __ \/ __/ ___/ __ / / + / / / / __(__ ) / / / /___/ __/ / / / /_/ / / /_/ / / +/_/ /_/\___/____/_/ /_/\____/\___/_/ /_/\__/_/ v5\__,_/_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="MeshCentral" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/meshcentral ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From 667a34b11afec9fc0ba1e9c8a850e684f13cd09c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:12:52 -0500 Subject: [PATCH 4105/6505] Create mariadb-v5.sh --- ct/mariadb-v5.sh | 360 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 ct/mariadb-v5.sh diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh new file mode 100644 index 00000000..72d2af41 --- /dev/null +++ b/ct/mariadb-v5.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ___ _ ____ ____ + / |/ /___ ______(_)___ _/ __ \/ __ ) + / /|_/ / __ / ___/ / __ / / / / __ | + / / / / /_/ / / / / /_/ / /_/ / /_/ / +/_/ /_/\__,_/_/v5/_/\__,_/_____/_____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="MariaDB" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/mariadb.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From dda940d8f6e8336f7ffaf888d61f05d1f91262d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:14:27 -0500 Subject: [PATCH 4106/6505] Create magicmirror-v5.sh --- ct/magicmirror-v5.sh | 364 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 ct/magicmirror-v5.sh diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh new file mode 100644 index 00000000..74e32759 --- /dev/null +++ b/ct/magicmirror-v5.sh @@ -0,0 +1,364 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ___ _ __ ____ + / |/ /___ _____ _(_)____/ |/ (_)_____________ _____ + / /|_/ / __ / __ / / ___/ /|_/ / / ___/ ___/ __ \/ ___/ + / / / / /_/ / /_/ / / /__/ / / / / / / / / /_/ / / +/_/ /_/\__,_/\__, /_/\___/_/ /_/_/_/ /_/ \____/_/ + /____/ v5 + +EOF +} +clear +header_info +echo -e "Loading..." +APP="MagicMirror" +var_disk="3" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/magicmirror ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +cd /opt/magicmirror +git pull &>/dev/null +npm install --only=prod --omit=dev &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" From 7577965e6255014d49faa2baac056bea0aa91b39 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:15:59 -0500 Subject: [PATCH 4107/6505] Create keycloak-v5.sh --- ct/keycloak-v5.sh | 363 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 ct/keycloak-v5.sh diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh new file mode 100644 index 00000000..78dfca0a --- /dev/null +++ b/ct/keycloak-v5.sh @@ -0,0 +1,363 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ __ __ + / //_/__v5__ _______/ /___ ____ _/ /__ + / ,< / _ \/ / / / ___/ / __ \/ __ / //_/ + / /| / __/ /_/ / /__/ / /_/ / /_/ / ,< +/_/ |_\___/\__, /\___/_/\____/\__,_/_/|_| + /____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Keycloak" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/keycloak.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" From a41f82172fee54929fd616394282f4cf8a188087 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:17:22 -0500 Subject: [PATCH 4108/6505] Create iobroker-v5.sh --- ct/iobroker-v5.sh | 362 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 ct/iobroker-v5.sh diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh new file mode 100644 index 00000000..f5e08b8e --- /dev/null +++ b/ct/iobroker-v5.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ ____ __ + (_)___ / __ )_________ / /_____ _____ + / / __ \/ __ / ___/ __ \/ //_/ _ \/ ___/ + / / /_/ / /_/ / / / /_/ / ,< / __/ / +/_/\____/_____/_/ v5\____/_/|_|\___/_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="ioBroker" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/iobroker ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8081${CL} \n" From 2e8b9db4ded961f45fb67993d813c7553de1cc1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:19:19 -0500 Subject: [PATCH 4109/6505] Create influxdb-v5.sh --- ct/influxdb-v5.sh | 360 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 ct/influxdb-v5.sh diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh new file mode 100644 index 00000000..0c854a39 --- /dev/null +++ b/ct/influxdb-v5.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ ______ ____ ____ + / _/_v5 / __/ /_ ___ __/ __ \/ __ ) + / // __ \/ /_/ / / / / |/_/ / / / __ | + _/ // / / / __/ / /_/ /> &2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/influxdb.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From f76c939d88d0860863a0f8bee5a1ab4eac84aa4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 14:20:30 -0500 Subject: [PATCH 4110/6505] Create hyperion-v5.sh --- ct/hyperion-v5.sh | 377 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 ct/hyperion-v5.sh diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh new file mode 100644 index 00000000..ea2db61e --- /dev/null +++ b/ct/hyperion-v5.sh @@ -0,0 +1,377 @@ +#!/usr/bin/env bash +function header_info { +cat <<"EOF" + __ __ _ + / / / /_ ______v5___ _____(_)___ ____ + / /_/ / / / / __ \/ _ \/ ___/ / __ \/ __ \ + / __ / /_/ / /_/ / __/ / / / /_/ / / / / +/_/ /_/\__, / .___/\___/_/ /_/\____/_/ /_/ + /____/_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Hyperion" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/hyperion.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8090${CL} \n" From 3320b6361091f7d45364cac951b4c10bb2ffe034 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 15:19:54 -0500 Subject: [PATCH 4111/6505] Delete navidrome-update.sh prune --- misc/navidrome-update.sh | 46 ---------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 misc/navidrome-update.sh diff --git a/misc/navidrome-update.sh b/misc/navidrome-update.sh deleted file mode 100644 index 333632cc..00000000 --- a/misc/navidrome-update.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -function update_info { - cat <<"EOF" - _ __ _ __ - / | / /___ __ __(_)___/ /________ ____ ___ ___ - / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ - / /| / /_/ /| |/ / / /_/ / / / /_/ / / / / / / __/ -/_/ |_/\__,_/ |___/_/\__,_/_/ \____/_/ /_/ /_/\___/ - UPDATE - -EOF -} -update_info -while true; do - read -p "This will Update Navidrome to v$RELEASE. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -sleep 2 -echo -e "${GN} Stopping Navidrome... ${CL}" -systemctl stop navidrome.service -sleep 1 - -echo -e "${GN} Updating to v${RELEASE}... ${CL}" -wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null -tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null - -echo -e "${GN} Cleaning up... ${CL}" -rm Navidrome.tar.gz - -echo -e "${GN} Starting Navidrome... ${CL}" -systemctl start navidrome.service -sleep 1 -echo -e "${GN} Finished Update ${CL}" From bbe75faf40544ebf1206b51635663c9ad094a055 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 15:20:54 -0500 Subject: [PATCH 4112/6505] Delete heimdalldashboard-all-update.sh prune --- misc/heimdalldashboard-all-update.sh | 118 --------------------------- 1 file changed, 118 deletions(-) delete mode 100644 misc/heimdalldashboard-all-update.sh diff --git a/misc/heimdalldashboard-all-update.sh b/misc/heimdalldashboard-all-update.sh deleted file mode 100644 index e7b1de62..00000000 --- a/misc/heimdalldashboard-all-update.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env bash -set -e -PP=$(echo "\e[1;35m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -while true; do - read -p "This will Update Heimdall Dashboard. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - echo -e "${PP} - _ _ _ _ _ _ _____ _ _ _ - | | | | (_) | | | | | | __ \ | | | | | | - | |__| | ___ _ _ __ ___ __| | __ _| | | | | | | __ _ ___| |__ | |__ ___ __ _ _ __ __| | - | __ |/ _ \ | _ _ \ / _ |/ _ | | | | | | |/ _ / __| _ \| _ \ / _ \ / _ | __/ _ | - | | | | __/ | | | | | | (_| | (_| | | | | |__| | (_| \__ \ | | | |_) | (_) | (_| | | | (_| | - |_| |_|\___|_|_| |_| |_|\__,_|\__,_|_|_| |_____/ \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| - ${RD}UPDATE -${CL}" -} - -header_info - -echo -en "${GN} Stopping Heimdall Dashboard... " -systemctl disable heimdall.service &>/dev/null -systemctl stop heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Backing up Data... " -if [ -d "/opt/Heimdall-2.4.6" ]; then - cp -R /opt/Heimdall-2.4.6/database database-backup - cp -R /opt/Heimdall-2.4.6/public public-backup -elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then - cp -R /opt/Heimdall-2.4.7b/database database-backup - cp -R /opt/Heimdall-2.4.7b/public public-backup -elif [[ -d "/opt/Heimdall-2.4.8" ]]; then - cp -R /opt/Heimdall-2.4.8/database database-backup - cp -R /opt/Heimdall-2.4.8/public public-backup -else - cp -R /opt/Heimdall/database database-backup - cp -R /opt/Heimdall/public public-backup -fi -sleep 1 -echo -e "${CM}${CL} \r" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -echo -en "${GN} Updating Heimdall Dashboard to ${RELEASE}... " -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -if [ ! -d "/opt/Heimdall" ]; then - mv Heimdall-${VER} /opt/Heimdall -else - cp -R Heimdall-${VER}/* /opt/Heimdall -fi -echo -e "${CM}${CL} \r" - -service_path="/etc/systemd/system/heimdall.service" -echo "[Unit] -Description=Heimdall -After=network.target - -[Service] -Restart=always -RestartSec=5 -Type=simple -User=root -WorkingDirectory=/opt/Heimdall -ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 -TimeoutStopSec=30 - -[Install] -WantedBy=multi-user.target" >$service_path - -echo -en "${GN} Restoring Data... " -cp -R database-backup/* /opt/Heimdall/database -cp -R public-backup/* /opt/Heimdall/public -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleanup... " -if [ -d "/opt/Heimdall-2.4.6" ]; then - rm -rf /opt/Heimdall-2.4.6 - rm -rf /opt/v2.4.6.tar.gz -elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then - rm -rf /opt/Heimdall-2.4.7b - rm -rf /opt/v2.4.7b.tar.gz -elif [[ -d "/opt/Heimdall-2.4.8" ]]; then - rm -rf /opt/Heimdall-2.4.8 - rm -rf /opt/v2.4.8.tar.gz -fi - -rm -rf ${RELEASE}.tar.gz -rm -rf Heimdall-${VER} -rm -rf public-backup -rm -rf database-backup -rm -rf Heimdall -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting Heimdall Dashboard... " -systemctl enable --now heimdall.service &>/dev/null -sleep 2 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Finished! ${CL}\n" From b839862989718c2780c62313280c81d3db9cbca5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 15:35:22 -0500 Subject: [PATCH 4113/6505] Create homepage-v5-install.sh --- install/homepage-v5-install.sh | 148 +++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 install/homepage-v5-install.sh diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh new file mode 100644 index 00000000..b477f518 --- /dev/null +++ b/install/homepage-v5-install.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +$STD npm install -g pnpm +msg_ok "Installed Node.js" + +msg_info "Installing Homepage" +$STD git clone https://github.com/benphelps/homepage.git /opt/homepage +cd /opt/homepage +mkdir -p config +$STD pnpm install +$STD pnpm build +msg_ok "Installed Homepage" + +msg_info "Creating Service" +service_path="/etc/systemd/system/homepage.service" +echo "[Unit] +Description=Homepage +After=network.target +StartLimitIntervalSec=0 +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +WorkingDirectory=/opt/homepage/ +ExecStart=pnpm start +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now homepage +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 0a0a67151e49d27707cad27cb33823a27bbf5fc4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 15:37:29 -0500 Subject: [PATCH 4114/6505] Create homepage-v5.sh --- ct/homepage-v5.sh | 368 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 ct/homepage-v5.sh diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh new file mode 100644 index 00000000..08342af6 --- /dev/null +++ b/ct/homepage-v5.sh @@ -0,0 +1,368 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ + / / / /___ ____ ___ ___ ____ ____ _____ ____ + / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ + / __ / /_/ / / / / / / __/ /_/ / /_/ / /_/ / __/ +/_/ /_/\____/_/ /_/ /_/\___/ .___/\__,_/\__, /\___/ + /_/ v5 /____/ +EOF +} +clear +header_info +echo -e "Loading..." +APP="Homepage" +var_disk="3" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/homepage.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP}" +if ! command -v pnpm >/dev/null 2>&1; then + npm install -g pnpm &>/dev/null +fi +cd /opt/homepage +systemctl stop homepage +git pull --force &>/dev/null +pnpm install &>/dev/null +pnpm build &>/dev/null +systemctl start homepage +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 330669c54293e17d85e195e1c5008e1e68bab192 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 15:45:38 -0500 Subject: [PATCH 4115/6505] Delete homepage-update.sh prune --- misc/homepage-update.sh | 72 ----------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 misc/homepage-update.sh diff --git a/misc/homepage-update.sh b/misc/homepage-update.sh deleted file mode 100644 index 49a65168..00000000 --- a/misc/homepage-update.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -APP="Homepage" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -while true; do - read -p "This will Update ${APP}. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - cat <<"EOF" - __ __ - / / / /___ ____ ___ ___ ____ ____ _____ ____ - / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ - / __ / /_/ / / / / / / __/ /_/ / /_/ / /_/ / __/ -/_/ /_/\____/_/ /_/ /_/\___/ .___/\__,_/\__, /\___/ - /_/ UPDATE /____/ -EOF -} - -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_info "Updating ${APP}" -if ! command -v pnpm >/dev/null 2>&1; then - npm install -g pnpm &>/dev/null -fi -cd /opt/homepage -systemctl stop homepage -git pull --force &>/dev/null -pnpm install &>/dev/null -pnpm build &>/dev/null -systemctl start homepage -msg_ok "Updated ${APP}" From 32e38c12499a4de0a265b8a5948e3922f21626ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 17:29:36 -0500 Subject: [PATCH 4116/6505] Create podman-homeassistant-v5-install.sh --- install/podman-homeassistant-v5-install.sh | 140 +++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 install/podman-homeassistant-v5-install.sh diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh new file mode 100644 index 00000000..5f302e48 --- /dev/null +++ b/install/podman-homeassistant-v5-install.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing Podman" +$STD apt-get -y install podman +$STD systemctl enable --now podman.socket +msg_ok "Installed Podman" + +msg_info "Pulling Home Assistant Image" +$STD podman pull docker.io/homeassistant/home-assistant:stable +msg_ok "Pulled Home Assistant Image" + +msg_info "Installing Home Assistant" +$STD podman volume create hass_config +$STD podman run -d \ + --name homeassistant \ + --restart unless-stopped \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:stable +podman generate systemd \ + --new --name homeassistant \ + >/etc/systemd/system/homeassistant.service +$STD systemctl enable --now homeassistant +msg_ok "Installed Home Assistant" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From da6b03cd1f0dba6a57c1ba2e51d8f362fda0ba98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 17:31:30 -0500 Subject: [PATCH 4117/6505] Create podman-homeassistant-v5.sh --- ct/podman-homeassistant-v5.sh | 386 ++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 ct/podman-homeassistant-v5.sh diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh new file mode 100644 index 00000000..22bc0292 --- /dev/null +++ b/ct/podman-homeassistant-v5.sh @@ -0,0 +1,386 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \____ ____/ /___ ___ ____ _____ + / /_/ / __ \/ __ / __ __ \/ __ / __ \ + / ____/ /_/ / /_/ / / / / / / /_/ / / / / + __ __ /_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/__ __ + / / / /___ ____ ___ ___ v5 / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Podman-Home Assistant" +var_disk="16" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/homeassistant.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +if [ "$CT_TYPE" == "0" ]; then + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +else + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} \n" From 2d8a304d57a7916555397d47e2dc384dfe416456 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 17:49:36 -0500 Subject: [PATCH 4118/6505] Update podman-homeassistant-v5.sh --- ct/podman-homeassistant-v5.sh | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 22bc0292..43d158ec 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -314,15 +314,61 @@ function install_script() { } function update_script() { + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + "1" "Update Podman" ON \ + "2" "Install HACS" OFF \ + "3" "Install FileBrowser" OFF \ + 3>&1 1>&2 2>&3) clear header_info +if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit +if [ "$UPD" == "2" ]; then +msg_info "Installing Home Assistant Comunity Store (HACS)" +apt update &>/dev/null +apt install unzip &>/dev/null +cd /var/lib/containers/storage/volumes/hass_config/_data +bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null +msg_ok "Installed Home Assistant Comunity Store (HACS)" +echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" +exit +fi +if [ "$UPD" == "3" ]; then +IP=$(hostname -I | awk '{print $1}') +msg_info "Installing FileBrowser" +curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null +filebrowser config init -a '0.0.0.0' &>/dev/null +filebrowser config set -a '0.0.0.0' &>/dev/null +filebrowser users add admin changeme --perm.admin &>/dev/null +msg_ok "Installed FileBrowser" + +msg_info "Creating Service" +service_path="/etc/systemd/system/filebrowser.service" +echo "[Unit] +Description=Filebrowser +After=network-online.target +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r / +[Install] +WantedBy=default.target" >$service_path + +systemctl enable --now filebrowser.service &>/dev/null +msg_ok "Created Service" + +msg_ok "Completed Successfully!\n" +echo -e "FileBrowser should be reachable by going to the following URL. + ${BL}http://$IP:8080${CL} admin|changeme\n" +exit +fi } + clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi From df2c70a65f7086e282bbf3b34c8ac9b80a424770 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 18:03:13 -0500 Subject: [PATCH 4119/6505] Delete podman.md prune --- misc/podman.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 misc/podman.md diff --git a/misc/podman.md b/misc/podman.md deleted file mode 100644 index 34b45371..00000000 --- a/misc/podman.md +++ /dev/null @@ -1,11 +0,0 @@ -

    - -Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System. Similar to Docker, Podman is an open source project. Anybody can check out the source code for the program. Contrary to Docker, Podman does not require a daemon process to launch and manage containers. This is an important difference between the two projects. - -Podman seeks to improve on some of Docker’s drawbacks. For one, Podman does not require a daemon running as root. In fact, Podman containers run with the same permissions as the user who launched them. This addresses a significant security concern, although you can still run containers with root permissions if you really want to. - -Podman seeks to be a drop-in replacement for Docker as far as the CLI is concerned. The developers boast that most users can simply use alias docker=podman and continue running the same familiar commands. The container image format is also fully compatible between Docker and Podman, so existing containers built on Dockerfiles will work with Podman. - -Another key difference is that, it handles running containers, but not building them (non-monolithic). The goal here is to have a set of container standards that any application can be developed to support, rather than relying on a single monolithic application such as Docker to perform all duties. - -https://www.liquidweb.com/kb/podman-vs-docker/ ___ https://github.com/containers/podman-compose ___ https://podman.io/ From 499dfd734aaadb4cd5dcf9e48a1bef176e108204 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Jan 2023 18:03:34 -0500 Subject: [PATCH 4120/6505] Delete podman_hacs.sh prune --- misc/podman_hacs.sh | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 misc/podman_hacs.sh diff --git a/misc/podman_hacs.sh b/misc/podman_hacs.sh deleted file mode 100644 index 10d5b1bf..00000000 --- a/misc/podman_hacs.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi -echo -e "\e[1;33m This script will install Home Assistant Community Store (HACS) \e[0m" - -while true; do - read -p "Start the HACS Install Script (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -apt update &>/dev/null -apt install unzip &>/dev/null -cd /var/lib/containers/storage/volumes/hass_config/_data -wget -O - https://get.hacs.xyz | bash - - -# To install HACS run the following from the container (LXC) console -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman_hacs.sh)" -# Then add the integration in HA From b4fe32dcd7e26624754dda8047bc42bc666458d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 10:11:16 -0500 Subject: [PATCH 4121/6505] Update umbrel-v5-install.sh adjust daemon.json --- install/umbrel-v5-install.sh | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index e14653a6..0de53375 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -86,21 +86,18 @@ $STD apt-get install -y curl $STD apt-get install -y sudo msg_ok "Installed Dependencies" +msg_info "Installing Umbrel (Patience)" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -msg_info "Installing Umbrel (Patience)" if [ "$ST" == "yes" ]; then VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') cd /usr/local/bin curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 chmod 755 /usr/local/bin/fuse-overlayfs cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json fi $STD bash <(curl -fsSL https://umbrel.sh) systemctl daemon-reload From bc75366de036e68e8d9155292d9e8b57e2a4051c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:22:08 -0500 Subject: [PATCH 4122/6505] Create homebridge-v5-install.sh --- install/homebridge-v5-install.sh | 130 +++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 install/homebridge-v5-install.sh diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh new file mode 100644 index 00000000..af5fdd30 --- /dev/null +++ b/install/homebridge-v5-install.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs gcc g++ make python net-tools +msg_ok "Installed Node.js" + +msg_info "Installing Homebridge" +$STD npm install -g --unsafe-perm homebridge homebridge-config-ui-x +msg_info "Installed Homebridge" + +msg_info "Creating Service" +$STD hb-service install --user homebridge +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 50a94e5c473d6e84939aa765453f8564a6d26c6b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:23:18 -0500 Subject: [PATCH 4123/6505] Create grocy-v5-install.sh --- install/grocy-v5-install.sh | 157 ++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 install/grocy-v5-install.sh diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh new file mode 100644 index 00000000..85ee376c --- /dev/null +++ b/install/grocy-v5-install.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y apache2 +$STD apt-get install -y unzip +$STD apt-get install -y apt-transport-https +$STD apt-get install -y lsb-release +msg_ok "Installed Dependencies" + +msg_info "Installing PHP 8.1" +curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg +sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' +$STD apt-get update +$STD apt-get install -y php8.1 +$STD apt-get install -y libapache2-mod-php8.1 +$STD apt-get install -y php8.1-sqlite3 +$STD apt-get install -y php8.1-gd +$STD apt-get install -y php8.1-intl +$STD apt-get install -y php8.1-mbstring +msg_ok "Installed PHP 8.1" + +msg_info "Installing grocy" +wget -q https://releases.grocy.info/latest +$STD unzip latest -d /var/www/html +chown -R www-data:www-data /var/www/html +cp /var/www/html/config-dist.php /var/www/html/data/config.php +chmod +x /var/www/html/update.sh + +cat </etc/apache2/sites-available/grocy.conf + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html/public + ErrorLog /var/log/apache2/error.log + + Options Indexes FollowSymLinks MultiViews + AllowOverride All + Order allow,deny + allow from all + + +EOF + +$STD a2dissite 000-default.conf +$STD a2ensite grocy.conf +$STD a2enmod rewrite +systemctl reload apache2 +msg_ok "Installed grocy" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/latest +msg_ok "Cleaned" From 60a022099fc654b415e6d39c06cf121aabf68f3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:24:20 -0500 Subject: [PATCH 4124/6505] Create deconz-v5-install.sh --- install/deconz-v5-install.sh | 143 +++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 install/deconz-v5-install.sh diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh new file mode 100644 index 00000000..691f8f65 --- /dev/null +++ b/install/deconz-v5-install.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Setting Phoscon Repository" +$STD apt-key add <(curl -fsSL http://phoscon.de/apt/deconz.pub.key) +sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" +msg_ok "Setup Phoscon Repository" + +msg_info "Installing deConz" +$STD apt-get update +$STD apt-get install -y deconz +msg_ok "Installed deConz" + +msg_info "Creating Service" +service_path="/lib/systemd/system/deconz.service" +echo "[Unit] +Description=deCONZ: ZigBee gateway -- REST API +Wants=deconz-init.service deconz-update.service +StartLimitIntervalSec=0 + +[Service] +User=root +ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80 +Restart=on-failure +RestartSec=30 +AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now deconz +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 9faed9ab99850a189668c59dc6d19ae63419e319 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:25:25 -0500 Subject: [PATCH 4125/6505] Create dashy-v5-install.sh --- install/dashy-v5-install.sh | 151 ++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 install/dashy-v5-install.sh diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh new file mode 100644 index 00000000..3e6391e8 --- /dev/null +++ b/install/dashy-v5-install.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs git make g++ gcc +msg_ok "Installed Node.js" + +msg_info "Installing Yarn" +$STD npm install --global yarn +msg_ok "Installed Yarn" + +msg_info "Installing Dashy (Patience)" +$STD git clone https://github.com/Lissy93/dashy.git +cd /dashy +$STD yarn +export NODE_OPTIONS=--max-old-space-size=1000 +$STD yarn build +msg_ok "Installed Dashy" + +msg_info "Creating Service" +cat </etc/systemd/system/dashy.service +[Unit] +Description=dashy + +[Service] +Type=simple +WorkingDirectory=/dashy +ExecStart=/usr/bin/yarn start +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable dashy +systemctl start dashy +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 898bb31497c1088467c561fa54df83e19b8c0ffe Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:26:15 -0500 Subject: [PATCH 4126/6505] Create daemonsync-v5-install.sh --- install/daemonsync-v5-install.sh | 121 +++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 install/daemonsync-v5-install.sh diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh new file mode 100644 index 00000000..557f6505 --- /dev/null +++ b/install/daemonsync-v5-install.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y g++-multilib +msg_ok "Installed Dependencies" + +msg_info "Installing Daemon Sync Server" +wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_amd64.deb +$STD dpkg -i daemonsync_2.2.0.0059_amd64.deb +msg_ok "Installed Daemon Sync Server" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf daemonsync_2.2.0.0059_amd64.deb +$STD apt-get autoremove >/dev/null +$STD apt-get autoclean >/dev/null +msg_ok "Cleaned" From ff55edbf7cbcf63e4226773693b3c95bbb49b267 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:27:13 -0500 Subject: [PATCH 4127/6505] Create changedetection-v5-install.sh --- install/changedetection-v5-install.sh | 133 ++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 install/changedetection-v5-install.sh diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh new file mode 100644 index 00000000..c2835894 --- /dev/null +++ b/install/changedetection-v5-install.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y pip +msg_ok "Installed Dependencies" + +msg_info "Installing Change Detection" +mkdir /opt/changedetection +$STD pip3 install changedetection.io +msg_ok "Installed Change Detection" + +msg_info "Creating Service" +cat </etc/systemd/system/changedetection.service +[Unit] +Description=Change Detection +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/opt/changedetection +ExecStart=changedetection.io -d /opt/changedetection -p 5000 +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now changedetection +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 79c20ba91e36c3ff8e3a75ba5907cfc40c080c6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:28:04 -0500 Subject: [PATCH 4128/6505] Create casaos-v5-install.sh --- install/casaos-v5-install.sh | 131 +++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 install/casaos-v5-install.sh diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh new file mode 100644 index 00000000..7ff88b3b --- /dev/null +++ b/install/casaos-v5-install.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing CasaOS (Patience)" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +fi +$STD bash <(curl -fsSL https://get.casaos.io) +msg_ok "Installed CasaOS" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + rm /etc/motd + rm /etc/update-motd.d/10-uname + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 2bedefd00bc17637e206dec9e8046725e41f060b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:29:14 -0500 Subject: [PATCH 4129/6505] Create blocky-v5-install.sh --- install/blocky-v5-install.sh | 374 +++++++++++++++++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 install/blocky-v5-install.sh diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh new file mode 100644 index 00000000..dbb72503 --- /dev/null +++ b/install/blocky-v5-install.sh @@ -0,0 +1,374 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing Blocky" +systemctl stop systemd-resolved +$STD systemctl disable systemd-resolved.service +RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz +mkdir -p /opt/blocky +tar -xf blocky_${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky +rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz +cat </opt/blocky/config.yml +upstream: + # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query + # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) + # this configuration is mandatory, please define at least one external DNS resolver + default: + # example for tcp+udp IPv4 server (https://digitalcourage.de/) + #- 5.9.164.112 + # Cloudflare + - 1.1.1.1 + # example for DNS-over-TLS server (DoT) + #- tcp-tls:fdns1.dismail.de:853 + # example for DNS-over-HTTPS (DoH) + #- https://dns.digitale-gesellschaft.ch/dns-query + # optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range) + # or single ip address / client subnet as CIDR notation + #laptop*: + #- 123.123.123.123 + +# optional: timeout to query the upstream resolver. Default: 2s +#upstreamTimeout: 2s + +# optional: If true, blocky will fail to start unless at least one upstream server per group is reachable. Default: false +#startVerifyUpstream: true + +# optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists. +# accepted: dual, v4, v6 +# default: dual +#connectIPVersion: dual + +# optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma +# example: query "printer.lan" or "my.printer.lan" will return 192.168.178.3 +#customDNS: + #customTTL: 1h + # optional: if true (default), return empty result for unmapped query types (for example TXT, MX or AAAA if only IPv4 address is defined). + # if false, queries with unmapped types will be forwarded to the upstream resolver + #filterUnmappedTypes: true + # optional: replace domain in the query with other domain before resolver lookup in the mapping + #rewrite: + #example.com: printer.lan + #mapping: + #printer.lan: 192.168.178.3,2001:0db8:85a3:08d3:1319:8a2e:0370:7344 + +# optional: definition, which DNS resolver(s) should be used for queries to the domain (with all sub-domains). Multiple resolvers must be separated by a comma +# Example: Query client.fritz.box will ask DNS server 192.168.178.1. This is necessary for local network, to resolve clients by host name +#conditional: + # optional: if false (default), return empty result if after rewrite, the mapped resolver returned an empty answer. If true, the original query will be sent to the upstream resolver + # Example: The query "blog.example.com" will be rewritten to "blog.fritz.box" and also redirected to the resolver at 192.168.178.1. If not found and if was set to , the original query "blog.example.com" will be sent upstream. + # Usage: One usecase when having split DNS for internal and external (internet facing) users, but not all subdomains are listed in the internal domain. + #fallbackUpstream: false + # optional: replace domain in the query with other domain before resolver lookup in the mapping + #rewrite: + #example.com: fritz.box + #mapping: + #fritz.box: 192.168.178.1 + #lan.net: 192.168.178.1,192.168.178.2 + +# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.) +blocking: + # definition of blacklist groups. Can be external link (http/https) or local file + blackLists: + ads: + - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt + - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts + - http://sysctl.org/cameleon/hosts + - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt + - | + # inline definition with YAML literal block scalar style + # hosts format + someadsdomain.com + special: + - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts + # definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked + whiteLists: + ads: + - whitelist.txt + - | + # inline definition with YAML literal block scalar style + # hosts format + whitelistdomain.com + # this is a regex + /^banners?[_.-]/ + # definition: which groups should be applied for which client + clientGroupsBlock: + # default will be used, if no special definition for a client name exists + default: + - ads + - special + # use client name (with wildcard support: * - sequence of any characters, [0-9] - range) + # or single ip address / client subnet as CIDR notation + #laptop*: + #- ads + #192.168.178.1/24: + #- special + # which response will be sent, if query is blocked: + # zeroIp: 0.0.0.0 will be returned (default) + # nxDomain: return NXDOMAIN as return code + # comma separated list of destination IP addresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. + blockType: zeroIp + # optional: TTL for answers to blocked domains + # default: 6h + blockTTL: 1m + # optional: automatically list refresh period (in duration format). Default: 4h. + # Negative value -> deactivate automatically refresh. + # 0 value -> use default + refreshPeriod: 4h + # optional: timeout for list download (each url). Default: 60s. Use large values for big lists or slow internet connections + downloadTimeout: 4m + # optional: Download attempt timeout. Default: 60s + downloadAttempts: 5 + # optional: Time between the download attempts. Default: 1s + downloadCooldown: 10s + # optional: if failOnError, application startup will fail if at least one list can't be downloaded / opened. Default: blocking + #startStrategy: failOnError + +# optional: configuration for caching of DNS responses +caching: + # duration how long a response must be cached (min value). + # If <=0, use response's TTL, if >0 use this value, if TTL is smaller + # Default: 0 + minTime: 5m + # duration how long a response must be cached (max value). + # If <0, do not cache responses + # If 0, use TTL + # If > 0, use this value, if TTL is greater + # Default: 0 + maxTime: 30m + # Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + maxItemsCount: 0 + # if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2-hour time window) + # this improves the response time for often used queries, but significantly increases external traffic + # default: false + prefetching: true + # prefetch track time window (in duration format) + # default: 120 + prefetchExpires: 2h + # name queries threshold for prefetch + # default: 5 + prefetchThreshold: 5 + # Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + #prefetchMaxItemsCount: 0 + +# optional: configuration of client name resolution +clientLookup: + # optional: this DNS resolver will be used to perform reverse DNS lookup (typically local router) + #upstream: 192.168.178.1 + # optional: some routers return multiple names for client (host name and user defined name). Define which single name should be used. + # Example: take second name if present, if not take first name + #singleNameOrder: + #- 2 + #- 1 + # optional: custom mapping of client name to IP addresses. Useful if reverse DNS does not work properly or just to have custom client names. + #clients: + #laptop: + #- 192.168.178.29 +# optional: configuration for prometheus metrics endpoint +prometheus: + # enabled if true + #enable: true + # url path, optional (default '/metrics') + #path: /metrics + +# optional: write query information (question, answer, client, duration etc.) to daily csv file +queryLog: + # optional one of: mysql, postgresql, csv, csv-client. If empty, log to console + #type: mysql + # directory (should be mounted as volume in docker) for csv, db connection string for mysql/postgresql + #target: db_user:db_password@tcp(db_host_or_ip:3306)/db_name?charset=utf8mb4&parseTime=True&loc=Local + #postgresql target: postgres://user:password@db_host_or_ip:5432/db_name + # if > 0, deletes log files which are older than ... days + #logRetentionDays: 7 + # optional: Max attempts to create specific query log writer, default: 3 + #creationAttempts: 1 + # optional: Time between the creation attempts, default: 2s + #creationCooldown: 2s + +# optional: Blocky can synchronize its cache and blocking state between multiple instances through redis. +redis: + # Server address and port + #address: redis:6379 + # Password if necessary + #password: passwd + # Database, default: 0 + #database: 2 + # Connection is required for blocky to start. Default: false + #required: true + # Max connection attempts, default: 3 + #connectionAttempts: 10 + # Time between the connection attempts, default: 1s + #connectionCooldown: 3s + +# optional: DNS listener port(s) and bind ip address(es), default 53 (UDP and TCP). Example: 53, :53, "127.0.0.1:5353,[::1]:5353" +port: 553 +# optional: Port(s) and bind ip address(es) for DoT (DNS-over-TLS) listener. Example: 853, 127.0.0.1:853 +#tlsPort: 853 +# optional: HTTPS listener port(s) and bind ip address(es), default empty = no http listener. If > 0, will be used for prometheus metrics, pprof, REST API, DoH... Example: 443, :443, 127.0.0.1:443 +#httpPort: 4000 +#httpsPort: 443 +# optional: Mininal TLS version that the DoH and DoT server will use +#minTlsServeVersion: 1.3 +# if https port > 0: path to cert and key file for SSL encryption. if not set, self-signed certificate will be generated +#certFile: server.crt +#keyFile: server.key +# optional: use this DNS server to resolve blacklist urls and upstream DNS servers. Useful if no DNS resolver is configured and blocky needs to resolve a host name. Format net:IP:port, net must be udp or tcp +#bootstrapDns: tcp+udp:1.1.1.1 + +filtering: +# optional: drop all queries with following query types. Default: empty + #queryTypes: + #- AAAA + +# optional: if path defined, use this file for query resolution (A, AAAA and rDNS). Default: empty +hostsFile: + # optional: Path to hosts file (e.g. /etc/hosts on Linux) + #filePath: /etc/hosts + # optional: TTL, default: 1h + #hostsTTL: 60m + # optional: Time between hosts file refresh, default: 1h + #refreshPeriod: 30m + # optional: Whether loopback hosts addresses (127.0.0.0/8 and ::1) should be filtered or not, default: false + #filterLoopback: true +# optional: Log level (one from debug, info, warn, error). Default: info +#logLevel: info +# optional: Log format (text or json). Default: text +#logFormat: text +# optional: log timestamps. Default: true +#logTimestamp: true +# optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false +#logPrivacy: false + +# optional: add EDE error codes to dns response +#ede: + # enabled if true, Default: false + #enable: true +EOF +msg_ok "Installed Blocky" + +msg_info "Creating Service" +cat </etc/systemd/system/blocky.service +[Unit] +Description=Blocky +After=network.target +[Service] +User=root +WorkingDirectory=/opt/blocky +ExecStart=/opt/blocky/./blocky --config config.yml +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now blocky +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 69cd9880a656e590bfdc5610f9b347a3897f93ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:30:36 -0500 Subject: [PATCH 4130/6505] Create homebridge-v5.sh --- ct/homebridge-v5.sh | 362 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 ct/homebridge-v5.sh diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh new file mode 100644 index 00000000..3e8d27d1 --- /dev/null +++ b/ct/homebridge-v5.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ______ __ _____________ ____ ________ ____________ + / / / / __ \/ |/ / ____/ __ )/ __ \/ _/ __ \/ ____/ ____/ + / /_/ / / / / /|_/ / __/ / __ / /_/ // // / / / / __/ __/ + / __ / /_/ / / / / /___/ /_/ / _, _// // /_/ / /_/ / /___ +/_/ /_/\____/_/v5/_/_____/_____/_/ |_/___/_____/\____/_____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Homebridge" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8581${CL} \n" From 51935edf279b51cb552bdbc062e457eae5386d29 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:31:36 -0500 Subject: [PATCH 4131/6505] Create grocy-v5.sh --- ct/grocy-v5.sh | 361 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 ct/grocy-v5.sh diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh new file mode 100644 index 00000000..4c968ca2 --- /dev/null +++ b/ct/grocy-v5.sh @@ -0,0 +1,361 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __________ _______ __ + / __ / ___/ __ \/ ___/ / / / + / /_/ / / / /_/ / /__/ /_/ / + \__, /_/ v5\____/\___/\__, / +/____/ /____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="grocy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP}" +bash /var/www/html/update.sh +msg_ok "Updated ${APP}" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From 82d1dd1d28c9be3e1c5dfe0d609c1a871aaca25d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:32:41 -0500 Subject: [PATCH 4132/6505] Create deconz-v5.sh --- ct/deconz-v5.sh | 376 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 ct/deconz-v5.sh diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh new file mode 100644 index 00000000..96f6c164 --- /dev/null +++ b/ct/deconz-v5.sh @@ -0,0 +1,376 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __________ _ _______ + ____/ /v5 / ____/ __ \/ | / /__ / + / __ / _ \/ / / / / / |/ / / / +/ /_/ / __/ /___/ /_/ / /| / / /__ +\__,_/\___/\____/\____/_/ |_/ /____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="deCONZ" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="ubuntu" +var_version="20.04" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/deconz.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL}\n" From 26c85937dbe6c5b69fe67e157c64bf1f9ae83789 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:33:49 -0500 Subject: [PATCH 4133/6505] Create dashy-v5.sh --- ct/dashy-v5.sh | 388 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 ct/dashy-v5.sh diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh new file mode 100644 index 00000000..68308c59 --- /dev/null +++ b/ct/dashy-v5.sh @@ -0,0 +1,388 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \____ ______/ /_ __ __ + / / / / __ / ___/ __ \/ / / / + / /_/ / /_/ (__ ) / / / /_/ / +/_____/\__,_/____/_/ /_/\__, / + v5 /____/ +EOF +} +clear +header_info +echo -e "Loading..." +APP="Dashy" +var_disk="3" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/dashy.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Stopping ${APP}" +systemctl stop dashy +msg_ok "Stopped ${APP}" + +msg_info "Backing up conf.yml" +cd ~ +cp -R /dashy/public/conf.yml conf.yml +msg_ok "Backed up conf.yml" + +msg_info "Updating Dashy" +cd /dashy +git merge &>/dev/null +git pull origin master &>/dev/null +yarn &>/dev/null +yarn build &>/dev/null +msg_ok "Updated Dashy" + +msg_info "Restoring conf.yml" +cd ~ +cp -R conf.yml /dashy/public +msg_ok "Restored conf.yml" + +msg_info "Cleaning" +rm -rf conf.yml +msg_ok "Cleaned" + +msg_info "Starting Dashy" +systemctl start dashy +msg_ok "Started Dashy" +msg_ok "Update Successfull" +exit +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:4000${CL} \n" From 2e2a1ef35a7088400329df83cd39db1322263b45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:34:46 -0500 Subject: [PATCH 4134/6505] Create daemonsync-v5.sh --- ct/daemonsync-v5.sh | 362 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 ct/daemonsync-v5.sh diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh new file mode 100644 index 00000000..9aeafa7a --- /dev/null +++ b/ct/daemonsync-v5.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ _____ + / __ \____ ____ ____ ___ ____ ____ / ___/__v5______ _____ + / / / / __ / _ \/ __ __ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/ + / /_/ / /_/ / __/ / / / / / /_/ / / / / ___/ / /_/ / / / / /__ +/_____/\__,_/\___/_/ /_/ /_/\____/_/ /_/ /____/\__, /_/ /_/\___/ + /____/ +EOF +} +clear +header_info +echo -e "Loading..." +APP="Daemon Sync" +var_disk="8" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/daemonsync ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8084${CL} \n" From c314744a91d3e21406c6a68f53c2292fa997f822 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:35:40 -0500 Subject: [PATCH 4135/6505] Create changedetection-v5.sh --- ct/changedetection-v5.sh | 361 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 ct/changedetection-v5.sh diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh new file mode 100644 index 00000000..7facabc7 --- /dev/null +++ b/ct/changedetection-v5.sh @@ -0,0 +1,361 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ________ ____ __ __ _ + / ____/ /_v5____ _____ ____ ____ / __ \___ / /____ _____/ /_(_)___ ____ + / / / __ \/ __ `/ __ \/ __ `/ _ \ / / / / _ \/ __/ _ \/ ___/ __/ / __ \/ __ \ +/ /___/ / / / /_/ / / / / /_/ / __/ / /_/ / __/ /_/ __/ /__/ /_/ / /_/ / / / / +\____/_/ /_/\__,_/_/ /_/\__, /\___/ /_____/\___/\__/\___/\___/\__/_/\____/_/ /_/ + /____/ +EOF +} +clear +header_info +echo -e "Loading..." +APP="Change Detection" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/changedetection.service ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +pip3 install changedetection.io --upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From 5db986c0981a6e37b0097b64509d5864d74d5ee4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:36:30 -0500 Subject: [PATCH 4136/6505] Create casaos-v5.sh --- ct/casaos-v5.sh | 377 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 ct/casaos-v5.sh diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh new file mode 100644 index 00000000..6540b4d1 --- /dev/null +++ b/ct/casaos-v5.sh @@ -0,0 +1,377 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ ____ _____ + / ____/___ __v5______ _/ __ \/ ___/ + / / / __ `/ ___/ __ `/ / / /\__ \ +/ /___/ /_/ (__ ) /_/ / /_/ /___/ / +\____/\__,_/____/\__,_/\____//____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="CasaOS" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/docker ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + FUSE="yes" + else + echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + FUSE="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$FUSE" == "yes" ]; then +FEATURES="fuse=1,keyctl=1,nesting=1" +else +FEATURES="keyctl=1,nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export ST=$FUSE +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP} ${CL} \n" From 8ecfa0c7c8ab4c29c47b623dfe07b6075dfb714b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:37:31 -0500 Subject: [PATCH 4137/6505] Create blocky-v5.sh --- ct/blocky-v5.sh | 360 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 ct/blocky-v5.sh diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh new file mode 100644 index 00000000..d460035c --- /dev/null +++ b/ct/blocky-v5.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ __ + / __ )/ /___v5_____/ /____ __ + / __ / / __ \/ ___/ //_/ / / / + / /_/ / / /_/ / /__/ ,< / /_/ / +/_____/_/\____/\___/_/|_|\__, / + /____/ +EOF +} +clear +header_info +echo -e "Loading..." +APP="Blocky" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/blocky/ ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 68c7adf107b06baa95705cfb48ccd065fc676047 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 11:59:34 -0500 Subject: [PATCH 4138/6505] Delete dashy-update.sh prune --- misc/dashy-update.sh | 68 -------------------------------------------- 1 file changed, 68 deletions(-) delete mode 100644 misc/dashy-update.sh diff --git a/misc/dashy-update.sh b/misc/dashy-update.sh deleted file mode 100644 index d9c3826f..00000000 --- a/misc/dashy-update.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash -set -e -clear -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -while true; do - read -p "This will Update Dashy LXC. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -function header_info { - echo -e "${RD} - _____ _ - | __ \ | | - | | | | __ _ ___| |__ _ _ - | | | |/ _ / __| _ \| | | | - | |__| | (_| \__ \ | | | |_| | - |_____/ \__,_|___/_| |_|\__, | - UPDATE __/ | - |___/ -${CL}" -} - -header_info -echo -en "${GN} Stopping Dashy... " -systemctl stop dashy -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Backup conf.yml... " -cd ~ -cp -R /dashy/public/conf.yml conf.yml -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Updating Dashy... " -cd /dashy -git merge &>/dev/null -git pull origin master &>/dev/null -yarn &>/dev/null -yarn build &>/dev/null -echo -e "${CM}${CL} \r" - -echo -en "${GN} Restoring conf.yml... " -cd ~ -cp -R conf.yml /dashy/public -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Cleaning... " -rm -rf conf.yml -sleep 1 -echo -e "${CM}${CL} \r" - -echo -en "${GN} Starting Dashy... " -systemctl start dashy -sleep 1 -echo -e "${CM}${CL} \r" - -echo -e "${GN} Finished ${CL}\n" From bf3bf3daa859c347ecbcbe48456baee9162c936c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 12:01:22 -0500 Subject: [PATCH 4139/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 9ec9f85c..62ee50d6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-09 + +### Changed + +- **ALL LXC's** + - v5 + ## 2023-01-04 ### Changed From 411af1c39eab1b2660306d20e3edee0a7498ef81 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 12:08:25 -0500 Subject: [PATCH 4140/6505] Update and rename k0s-v4.sh to k0s-v5.sh --- ct/{k0s-v4.sh => k0s-v5.sh} | 84 +++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 22 deletions(-) rename ct/{k0s-v4.sh => k0s-v5.sh} (88%) diff --git a/ct/k0s-v4.sh b/ct/k0s-v5.sh similarity index 88% rename from ct/k0s-v4.sh rename to ct/k0s-v5.sh index 8254c26c..3e5ddf1a 100644 --- a/ct/k0s-v4.sh +++ b/ct/k0s-v5.sh @@ -1,4 +1,14 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ ____ + / /__/ __ \__v4_ + / //_/ / / / ___/ + / ,< / /_/ (__ ) +/_/|_|\____/____/ + +EOF +} echo -e "Loading..." APP="k0s" var_disk="4" @@ -7,8 +17,7 @@ var_ram="2048" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) +var_install="${NSAPP}-v5-install" INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -20,6 +29,7 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -35,31 +45,22 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - __ ____ - / /__/ __ \__v4_ - / //_/ / / / ___/ - / ,< / /_/ (__ ) -/_/|_|\____/____/ - -EOF -} + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } + function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then @@ -69,6 +70,30 @@ function PVE_CHECK() { exit fi } + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/k0s/k0s.yaml ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -102,6 +127,7 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -113,7 +139,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -254,9 +280,11 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" + VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -267,7 +295,7 @@ function advanced_settings() { advanced_settings fi } -function start_script() { +function install_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -278,8 +306,19 @@ function start_script() { advanced_settings fi } + +function update_script() { clear -start_script +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" @@ -289,6 +328,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export VERBOSE=$VERB +export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os From bdaaed3aaf67bdb3a362baf79d1dc730700de6fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 12:12:40 -0500 Subject: [PATCH 4141/6505] Update and rename k0s-install.sh to k0s-v5-install.sh --- install/{k0s-install.sh => k0s-v5-install.sh} | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) rename install/{k0s-install.sh => k0s-v5-install.sh} (88%) diff --git a/install/k0s-install.sh b/install/k0s-v5-install.sh similarity index 88% rename from install/k0s-install.sh rename to install/k0s-v5-install.sh index 1ed9806f..785160c7 100644 --- a/install/k0s-install.sh +++ b/install/k0s-v5-install.sh @@ -19,7 +19,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR - +silent() { "$@" > /dev/null 2>&1; } function error_exit() { trap - ERR local reason="Unknown failure occurred." @@ -76,20 +76,20 @@ alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +$STD apt-get update +$STD apt-get -y upgrade msg_ok "Updated Container OS" msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git msg_ok "Installed Dependencies" msg_info "Installing k0s Kubernetes" -sh <(curl -sSLf https://get.k0s.sh) &>/dev/null -k0s install controller --single &>/dev/null -k0s start &>/dev/null +$STD bash <(curl -sSLf https://get.k0s.sh) +$STD k0s install controller --single +$STD k0s start mkdir -p /etc/k0s k0s config create > /etc/k0s/k0s.yaml msg_ok "Installed k0s Kubernetes" @@ -103,7 +103,7 @@ fi if [[ $HELM == "Y" ]]; then msg_info "Installing Helm" -curl -sSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash &>/dev/null +$STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) msg_ok "Installed Helm" fi PASS=$(grep -w "root" /etc/shadow | cut -b6) @@ -128,6 +128,6 @@ if [[ "${SSH_ROOT}" == "yes" ]]; then fi msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null +$STD apt-get autoremove +$STD apt-get autoclean msg_ok "Cleaned" From 2d50962d2515b378c19bcef01f05ffca5afb2253 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 12:15:45 -0500 Subject: [PATCH 4142/6505] Update k0s-v5.sh --- ct/k0s-v5.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 3e5ddf1a..47a801f0 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -9,6 +9,8 @@ function header_info { EOF } +clear +header_info echo -e "Loading..." APP="k0s" var_disk="4" From aa14ce6f7ef6e5cad1631efa73d1f272bdc62a40 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 12:19:12 -0500 Subject: [PATCH 4143/6505] Update k0s-v5.sh --- ct/k0s-v5.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 47a801f0..194d5d25 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash function header_info { cat <<"EOF" - __ ____ - / /__/ __ \__v4_ - / //_/ / / / ___/ - / ,< / /_/ (__ ) -/_/|_|\____/____/ - + __ ____ __ __ __ __ + / /__/ __ \_____ / //_/_ __/ /_ ___v5_________ ___ / /____ _____ + / //_/ / / / ___/ / ,< / / / / __ \/ _ \/ ___/ __ \/ _ \/ __/ _ \/ ___/ + / ,< / /_/ (__ ) / /| / /_/ / /_/ / __/ / / / / / __/ /_/ __(__ ) +/_/|_|\____/____/ /_/ |_\__,_/_.___/\___/_/ /_/ /_/\___/\__/\___/____/ + EOF } clear From 7289a21172c222852f732c03070da42d7c4db1ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 12:40:28 -0500 Subject: [PATCH 4144/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 62ee50d6..122f6b92 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **ALL LXC's** - v5 +- **k0s Kubernetes LXC** + - NEW Script ## 2023-01-04 From 79c4dd0dfe92fb72a9c98cb829d7a4fe773a49df Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 14:20:35 -0500 Subject: [PATCH 4145/6505] Update and rename archlinux-v4.sh to archlinux-v5.sh --- ct/{archlinux-v4.sh => archlinux-v5.sh} | 85 +++++++++++++++++++------ 1 file changed, 64 insertions(+), 21 deletions(-) rename ct/{archlinux-v4.sh => archlinux-v5.sh} (88%) diff --git a/ct/archlinux-v4.sh b/ct/archlinux-v5.sh similarity index 88% rename from ct/archlinux-v4.sh rename to ct/archlinux-v5.sh index 001ab7ff..c56f9b8a 100644 --- a/ct/archlinux-v4.sh +++ b/ct/archlinux-v5.sh @@ -1,4 +1,16 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + ___ __ __ _ + / | __________/ /_ v5 / / (_)___ __ ___ __ + / /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ + / ___ |/ / / /__/ / / / / /___/ / / / / /_/ /> < +/_/ |_/_/ \___/_/ /_/ /_____/_/_/ /_/\__,_/_/|_| + +EOF +} +clear +header_info echo -e "Loading..." APP="Arch Linux" var_disk="1" @@ -7,7 +19,7 @@ var_ram="512" var_os="archlinux" var_version="base" NSAPP=$(echo ${APP,,} | tr -d ' ') -NEXTID=$(pvesh get /cluster/nextid) +var_install="${NSAPP}-v5-install" INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -19,6 +31,7 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -34,31 +47,22 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ___ __ __ _ - / | __________/ /_ v4 / / (_)___ __ ___ __ - / /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ - / ___ |/ / / /__/ / / / / /___/ / / / / /_/ /> < -/_/ |_/_/ \___/_/ /_/ /_____/_/_/ /_/\__,_/_/|_| - -EOF -} + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } + function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then @@ -68,6 +72,30 @@ function PVE_CHECK() { exit fi } + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/pacman.d ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -97,10 +125,11 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -253,9 +282,11 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" + VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -266,7 +297,7 @@ function advanced_settings() { advanced_settings fi } -function start_script() { +function install_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -277,8 +308,19 @@ function start_script() { advanced_settings fi } + +function update_script() { clear -start_script +header_info +msg_info "Updating ${APP} LXC" +pacman-key --init +pacman-key --populate archlinux +pacman -Sy archlinux-keyring && pacman -Su +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" @@ -288,6 +330,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export VERBOSE=$VERB +export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os From ee09697ddb16a8c06fe18b754706140cf8c595a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 14:39:36 -0500 Subject: [PATCH 4146/6505] Update and rename alpine-v4.sh to alpine-v5.sh --- ct/{alpine-v4.sh => alpine-v5.sh} | 85 +++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 21 deletions(-) rename ct/{alpine-v4.sh => alpine-v5.sh} (88%) diff --git a/ct/alpine-v4.sh b/ct/alpine-v5.sh similarity index 88% rename from ct/alpine-v4.sh rename to ct/alpine-v5.sh index a95cc37d..ce28c2a8 100644 --- a/ct/alpine-v4.sh +++ b/ct/alpine-v5.sh @@ -1,4 +1,17 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + ___ v5 __ _ + / | / /___ (_)___ ___ + / /| | / / __ \/ / __ \/ _ \ + / ___ |/ / /_/ / / / / / __/ +/_/ |_/_/ .___/_/_/ /_/\___/ + /_/ + +EOF +} +clear +header_info echo -e "Loading..." APP="Alpine" var_disk="0.1" @@ -7,7 +20,7 @@ var_ram="512" var_os="alpine" var_version="3.16" NSAPP=$(echo ${APP,,} | tr -d ' ') -NEXTID=$(pvesh get /cluster/nextid) +var_install="${NSAPP}-v5-install" INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -19,6 +32,7 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -34,32 +48,22 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ___ v4 __ _ - / | / /___ (_)___ ___ - / /| | / / __ \/ / __ \/ _ \ - / ___ |/ / /_/ / / / / / __/ -/_/ |_/_/ .___/_/_/ /_/\___/ - /_/ -EOF -} function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } + function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then @@ -69,6 +73,30 @@ function PVE_CHECK() { exit fi } + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -98,10 +126,11 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -250,9 +279,11 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" + VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -263,7 +294,7 @@ function advanced_settings() { advanced_settings fi } -function start_script() { +function install_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -274,8 +305,19 @@ function start_script() { advanced_settings fi } + +function update_script() { clear -start_script +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" @@ -285,6 +327,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export VERBOSE=$VERB +export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os From 6a26f5991cfd98836c716207ce25a3cc1f7f5a1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 14:44:12 -0500 Subject: [PATCH 4147/6505] Update alpine-v5.sh --- ct/alpine-v5.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index ce28c2a8..e43b5c22 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -84,7 +84,7 @@ if command -v pveversion >/dev/null 2>&1; then fi fi if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + if [[ ! -f /etc/alpine-release ]]; then msg_error "No ${APP} Installation Found!"; exit fi @@ -310,9 +310,8 @@ function update_script() { clear header_info msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" +apk update &>/dev/null +apk upgrade &>/dev/null msg_ok "Update Successfull" exit } From d0e43fa657e9cb113ed4aa290466dad1387f684a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 15:05:39 -0500 Subject: [PATCH 4148/6505] Update and rename podman-v4.sh to podman-v5.sh --- ct/{podman-v4.sh => podman-v5.sh} | 86 +++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 22 deletions(-) rename ct/{podman-v4.sh => podman-v5.sh} (88%) diff --git a/ct/podman-v4.sh b/ct/podman-v5.sh similarity index 88% rename from ct/podman-v4.sh rename to ct/podman-v5.sh index 1a28ea73..23cda1c9 100644 --- a/ct/podman-v4.sh +++ b/ct/podman-v5.sh @@ -1,4 +1,16 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \____v5____/ /___ ___ ____ _____ + / /_/ / __ \/ __ / __ `__ \/ __ `/ __ \ + / ____/ /_/ / /_/ / / / / / / /_/ / / / / +/_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/ + +EOF +} +clear +header_info echo -e "Loading..." APP="Podman" var_disk="4" @@ -7,8 +19,7 @@ var_ram="2048" var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) +var_install="${NSAPP}-v5-install" INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -20,6 +31,7 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -o errexit set -o errtrace set -o nounset @@ -35,31 +47,22 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ____ __ - / __ \____v4____/ /___ ___ ____ _____ - / /_/ / __ \/ __ / __ `__ \/ __ `/ __ \ - / ____/ /_/ / /_/ / / / / / / /_/ / / / / -/_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/ - -EOF -} + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } + function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + function PVE_CHECK() { PVE=$(pveversion | grep "pve-manager/7" | wc -l) if [[ $PVE != 1 ]]; then @@ -69,6 +72,30 @@ function PVE_CHECK() { exit fi } + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/systemd/system/podman.socket ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -102,6 +129,7 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -113,7 +141,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then @@ -254,9 +282,11 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" + VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" + VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -267,7 +297,7 @@ function advanced_settings() { advanced_settings fi } -function start_script() { +function install_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -278,8 +308,19 @@ function start_script() { advanced_settings fi } + +function update_script() { clear -start_script +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" @@ -289,6 +330,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export VERBOSE=$VERB +export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os From 60e5cec0bfee13ba441b2f13c96b6d4f5179846d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 15:10:13 -0500 Subject: [PATCH 4149/6505] Update and rename podman-install.sh to podman-v5-install.sh --- ...podman-install.sh => podman-v5-install.sh} | 44 ++++--------------- 1 file changed, 9 insertions(+), 35 deletions(-) rename install/{podman-install.sh => podman-v5-install.sh} (74%) diff --git a/install/podman-install.sh b/install/podman-v5-install.sh similarity index 74% rename from install/podman-install.sh rename to install/podman-v5-install.sh index eabfdf02..82432ae6 100644 --- a/install/podman-install.sh +++ b/install/podman-v5-install.sh @@ -19,7 +19,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR - +silent() { "$@" > /dev/null 2>&1; } function error_exit() { trap - ERR local reason="Unknown failure occurred." @@ -76,47 +76,21 @@ alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +$STD apt-get update +$STD apt-get -y upgrade msg_ok "Updated Container OS" msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null +$STD apt-get install -y curl +$STD apt-get install -y sudo msg_ok "Installed Dependencies" msg_info "Installing Podman" -apt-get -y install podman &>/dev/null -systemctl enable --now podman.socket &>/dev/null +$STD apt-get -y install podman +$STD systemctl enable --now podman.socket echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registries.conf msg_ok "Installed Podman" -read -r -p "Would you like to add Portainer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - PORTAINER="Y" -else - PORTAINER="N" -fi - -if [[ $PORTAINER == "Y" ]]; then - msg_info "Installing Portainer" - podman run -d \ - --name portainer \ - --restart always \ - -v /var/run/podman/podman.sock:/var/run/docker.sock \ - -v portainer:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - -p 8000:8000 \ - -p 9000:9000 \ - portainer/portainer-ce:latest &>/dev/null - podman generate systemd \ - --new --name portainer \ - >/etc/systemd/system/portainer.service - systemctl enable portainer &>/dev/null - msg_ok "Installed Portainer" -fi - PASS=$(grep -w "root" /etc/shadow | cut -b6) if [[ $PASS != $ ]]; then msg_info "Customizing Container" @@ -139,6 +113,6 @@ if [[ "${SSH_ROOT}" == "yes" ]]; then fi msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null +$STD apt-get autoremove +$STD apt-get autoclean msg_ok "Cleaned" From dd34b1dfc1f5527e1040db040e4602fcaae473bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 15:12:32 -0500 Subject: [PATCH 4150/6505] Update podman-v5.sh --- ct/podman-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 23cda1c9..9ce8f0d8 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -83,7 +83,7 @@ if command -v pveversion >/dev/null 2>&1; then fi fi if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/podman.socket ]]; then + if [[ ! -f /etc/containers/registries.conf ]]; then msg_error "No ${APP} Installation Found!"; exit fi From 592f34b4fa9d6e42e986caa1539b1a94054653c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 15:26:22 -0500 Subject: [PATCH 4151/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 122f6b92..f9011dad 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - v5 - **k0s Kubernetes LXC** - NEW Script +- **Podman LXC** + - NEW Script ## 2023-01-04 From 75e422132405d8a8b9f146275dd7118720f2952a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 16:40:50 -0500 Subject: [PATCH 4152/6505] Update wikijs-v5-install.sh change node.js v16 --- install/wikijs-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 3b7a1cea..4806102b 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -88,7 +88,7 @@ $STD apt-get install -y git msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From c448a4ba538f2dd7a2677150f25f4dac8007fb51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 21:33:57 -0500 Subject: [PATCH 4153/6505] Update plex-v5.sh add plexupdate option --- ct/plex-v5.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 944e9165..348bca7f 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -319,13 +319,24 @@ function install_script() { fi } function update_script() { +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 10 58 2 \ + "1" "Update LXC" ON \ + "2" "Run plexupdate" OFF \ + 3>&1 1>&2 2>&3) + clear header_info +if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit +fi +if [ "$UPD" == "2" ]; then +bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)" +exit +fi } clear if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi From 7b238075350d25c4a34cc79e65d82a45c7867c57 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Jan 2023 22:12:45 -0500 Subject: [PATCH 4154/6505] Update plex-v5.sh add "plexupdate info >> https://github.com/mrworf/plexupdate" --- ct/plex-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 348bca7f..c6d04cf2 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -319,7 +319,7 @@ function install_script() { fi } function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 10 58 2 \ +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ "1" "Update LXC" ON \ "2" "Run plexupdate" OFF \ 3>&1 1>&2 2>&3) From 3f84544b09bea40433075eb5954c09e5ce2e0a58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 10:51:02 -0500 Subject: [PATCH 4155/6505] Update edge-kernel.sh tweak --- misc/edge-kernel.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 52f83213..7214595d 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -1,13 +1,24 @@ #!/usr/bin/env bash # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" +function header_info { +cat <<"EOF" + ____ _ ________ ______ __ __ __ __ + / __ \ | / / ____/ / ____/___/ /___ ____ / //_/__ _________ ___ / /____ + / /_/ / | / / __/ / __/ / __ / __ `/ _ \ / ,< / _ \/ ___/ __ \/ _ \/ / ___/ + / ____/| |/ / /___ / /___/ /_/ / /_/ / __/ / /| / __/ / / / / / __/ (__ ) +/_/ |___/_____/ /_____/\__,_/\__, /\___/ /_/ |_\___/_/ /_/ /_/\___/_/____/ + /____/ + +EOF +} set -e KERNEL_ON=$(uname -r) PVE_KERNEL=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) EDGE_KERNEL=$(dpkg --list | grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) VER=$(curl -s https://api.github.com/repos/fabianishere/pve-edge-kernel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-9) }') KER=$(curl -s https://api.github.com/repos/fabianishere/pve-edge-kernel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-6) }') - clear +header_info while true; do read -p "This is a Proxmox Edge Kernel Tool, USE AT YOUR OWN RISK. Proceed(y/n)?" yn case $yn in @@ -17,16 +28,7 @@ while true; do esac done clear -function header_info { -cat <<"EOF" - ____ _ ________ ______ __ __ __ __ - / __ \ | / / ____/ / ____/___/ /___ ____ / //_/__ _________ ___ / /____ - / /_/ / | / / __/ / __/ / __ / __ `/ _ \ / ,< / _ \/ ___/ __ \/ _ \/ / ___/ - / ____/| |/ / /___ / /___/ /_/ / /_/ / __/ / /| / __/ / / / / / __/ (__ ) -/_/ |___/_____/ /_____/\__,_/\__, /\___/ /_/ |_\___/_/ /_/ /_/\___/_/____/ - /____/ -EOF -} +header_info show_menu() { normal=$(echo "\033[m") safe=$(echo "\033[32m") From 7d3417b25aa000c37bb5674550c7e23e28627652 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 10:56:36 -0500 Subject: [PATCH 4156/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index d5f40dce..2c3031fd 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -1,4 +1,14 @@ #!/usr/bin/env bash -ex +function header_info { + cat <<"EOF" + ____ _ _____________ ____ __ ____ __ ____ + / __ \ | / / ____/__ / / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / + / ____/| |/ / /___ / / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/ /_/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + +EOF +} set -euo pipefail shopt -s inherit_errexit nullglob YW=$(echo "\033[33m") @@ -13,6 +23,7 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" clear +header_info echo -e "${BL}This script will Perform Post Install Routines.${CL}" while true; do read -p "Start the PVE7 Post Install Script (y/n)?" yn @@ -35,15 +46,6 @@ if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then sleep 3 exit fi -function header_info { - echo -e "${RD} - ____ _ _____________ ____ __ ____ __ ____ - / __ \ | / / ____/__ / / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / - / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / - / ____/| |/ / /___ / / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / -/_/ |___/_____/ /_/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ -${CL}" -} function msg_info() { local msg="$1" From f48837c643d2509c014cb06440b64b49477d0eaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 11:08:36 -0500 Subject: [PATCH 4157/6505] Update kernel-clean.sh tweak --- misc/kernel-clean.sh | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index a7b6319d..5b072c18 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -1,4 +1,14 @@ #!/usr/bin/env bash -ex +function header_info { + cat <<"EOF" + __ __ __ ________ + / //_/__ _________ ___ / / / ____/ /__ ____ _____ + / ,< / _ \/ ___/ __ \/ _ \/ / / / / / _ \/ __ `/ __ \ + / /| / __/ / / / / / __/ / / /___/ / __/ /_/ / / / / +/_/ |_\___/_/ /_/ /_/\___/_/ \____/_/\___/\__,_/_/ /_/ + +EOF +} set -euo pipefail shopt -s inherit_errexit nullglob YW=$(echo "\033[33m") @@ -14,7 +24,8 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" PARTY="🎉" current_kernel=$(uname -r) - +clear +header_info while true; do read -p "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed(y/n)?" yn case $yn in @@ -24,19 +35,6 @@ while true; do esac done clear - -function header_info { - echo -e "${RD} - _ __ _ _____ _ - | |/ / | | / ____| | - | / ___ _ __ _ __ ___| | | | | | ___ __ _ _ __ - | < / _ \ __| _ \ / _ \ | | | | |/ _ \/ _ | _ \ - | \ __/ | | | | | __/ | | |____| | __/ (_| | | | | - |_|\_\___|_| |_| |_|\___|_| \_____|_|\___|\__,_|_| |_| - -${CL}" -} - function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." From a8c22e0c67e7493a228f736982038a2d15c0acb2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 11:16:26 -0500 Subject: [PATCH 4158/6505] Update scaling-governor.sh tweak --- misc/scaling-governor.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 1d0774c2..e7eea1d2 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -1,5 +1,17 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + __________ __ __ + / ____/ __ \/ / / / + / / / /_/ / / / / +/ /___/ ____/ /_/ / +\____/_/ \____/ +Scaling Governors + +EOF +} clear +header_info set -e while true; do read -p "View CPU Scaling Governors. Proceed(y/n)?" yn @@ -10,17 +22,7 @@ while true; do esac done clear -function header_info { - echo -e " - _____ _____ _ _ - / ____| __ \| | | | - | | | |__) | | | | - | | | ___/| | | | - | |____| | | |__| | - \_____|_| \____/ - Scaling Governors -" -} + show_menu() { CL=$(echo "\033[m") GN=$(echo "\033[32m") From 35d1a9b6c525dcacb19cdfa08713d725f924eaf5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 11:31:30 -0500 Subject: [PATCH 4159/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 63b452c9..80bd78cc 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -1,20 +1,4 @@ #!/bin/bash -set -e -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -while true; do - read -p "This Will Update All LXC Containers. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear function header_info { cat <<"EOF" __ __ __ __ __ _ ________ @@ -26,8 +10,24 @@ function header_info { EOF } +set -e +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +CM='\xE2\x9C\x94\033' +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +clear header_info - +while true; do + read -p "This Will Update All LXC Containers. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +clear containers=$(pct list | tail -n +2 | cut -f1 -d' ') function update_container() { @@ -50,7 +50,7 @@ function update_container() { pct exec $container -- bash -c "yum -y update" fi } - +header_info read -p "Skip stopped containers? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then @@ -82,4 +82,6 @@ for container in $containers; do done wait rm -rf temp +clear +header_info echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From 33ad41c028faa9113ae4d5981fa36c93d8fb9235 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 14:23:00 -0500 Subject: [PATCH 4160/6505] Add files via upload --- vm/haos.sh.gpg | Bin 0 -> 3852 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 vm/haos.sh.gpg diff --git a/vm/haos.sh.gpg b/vm/haos.sh.gpg new file mode 100644 index 0000000000000000000000000000000000000000..c887542bcb808d9e1094be86e8b595681a0ba1a1 GIT binary patch literal 3852 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 OV|9-rFHVs{mGX|rqg5RM literal 0 HcmV?d00001 From a7d3f03be5d61bbddaa2ba5f62a8fdcb4104372c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 14:55:44 -0500 Subject: [PATCH 4161/6505] Update add-tailscale-lxc.sh tweak --- misc/add-tailscale-lxc.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index e9a54a2d..73ee67ee 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -1,4 +1,16 @@ #!/usr/bin/env bash +function header_info { +cat <<"EOF" + ______ _ __ __ + /_ __/___ _(_) /_____________ _/ /__ + / / / __ `/ / / ___/ ___/ __ `/ / _ \ + / / / /_/ / / (__ ) /__/ /_/ / / __/ +/_/ \__,_/_/_/____/\___/\__,_/_/\___/ + +EOF +} +clear +header_info echo -e "\e[1;33mThis script will add Tailscale to an existing LXC Container ONLY\e[0m" while true; do read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn @@ -37,9 +49,9 @@ lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF -msg "⏳ Installing Tailscale..." +msg "Installing Tailscale..." lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" &>/dev/null || exit -msg "⌛ Installed Tailscale" +msg "Installed Tailscale" sleep 2 msg "\e[1;32m ✔ Completed Successfully!\e[0m" msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run tailscale up in the LXC console\e[0m" From ab832403713cf736d9ed8d56a3bdd6e9d52f98d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 10 Jan 2023 15:01:30 -0500 Subject: [PATCH 4162/6505] Update code-server.sh tweak --- misc/code-server.sh | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/misc/code-server.sh b/misc/code-server.sh index dfadd067..cb55416b 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -1,4 +1,14 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ __ _____ + / ____/___ ____/ /__ / ___/___ ______ _____ _____ + / / / __ \/ __ / _ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ +/ /___/ /_/ / /_/ / __/ ___/ / __/ / | |/ / __/ / +\____/\____/\__,_/\___/ /____/\___/_/ |___/\___/_/ + +EOF +} IP=$(hostname -I | awk '{print $1}') YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -28,7 +38,8 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } - +clear +header_info while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in @@ -37,18 +48,6 @@ while true; do *) echo "Please answer yes or no." ;; esac done -clear -function header_info { - echo -e "${BL} - ______ __ _____ - / ____/___ ____/ /__ / ___/___ ______ _____ _____ - / / / __ \/ __ / _ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ -/ /___/ /_/ / /_/ / __/ ___/ / __/ / | |/ / __/ / -\____/\____/\__,_/\___/ /____/\___/_/ |___/\___/_/ -${CL}" -} - -header_info function msg_info() { local msg="$1" From f8b11c9fa4534031b621562a3de070592ea2c093 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 07:00:10 -0500 Subject: [PATCH 4163/6505] Update pihole-v5.sh switch branch --- ct/pihole-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 9e8bb637..a153ed0f 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -352,7 +352,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/v5/install/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ From ee99360c80522607e7f4286c89793d4ce238cd01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 12:36:44 -0500 Subject: [PATCH 4164/6505] Update homeassistant-core-v5-install.sh Pre-Initialize --- install/homeassistant-core-v5-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 3c88bd62..37131755 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -146,6 +146,7 @@ $STD python3 -m pip install wheel $STD pip install mysqlclient $STD pip install psycopg2-binary $STD pip install homeassistant +mkdir -p /root/.homeassistant msg_ok "Installed Home Assistant-Core" msg_info "Creating Service" @@ -161,7 +162,7 @@ RestartForceExitStatus=100 [Install] WantedBy=multi-user.target EOF -$STD systemctl enable homeassistant +$STD systemctl enable --now homeassistant msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) From 7b7b7851080525e5c08a6e5c3ad04ee60dc4d5c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 12:46:25 -0500 Subject: [PATCH 4165/6505] Update homeassistant-core-v5.sh auto initialize --- ct/homeassistant-core-v5.sh | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index c4a108af..8008bf97 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -317,20 +317,14 @@ function install_script() { function update_script() { PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ - "1" "Initialize" OFF \ - "2" "Update Core" ON \ - "3" "Install HACS" OFF \ - "4" "Install FileBrowser" OFF \ + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ + "1" "Update Core" ON \ + "2" "Install HACS" OFF \ + "3" "Install FileBrowser" OFF \ 3>&1 1>&2 2>&3) clear header_info -if [ "$UPD" == "1" ]; then -echo -e "\n LOG VIEWER - Go to http://${IP}:8123 to setup \n" -cd /srv/homeassistant && python3 -m venv . && source bin/activate && hass -exit -fi -if [ "$UPD" == "2" ]; then +if [ "$UPD" == "1" ]; then if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then clear header_info @@ -361,7 +355,7 @@ msg_ok "Update Successful" echo -e "\n Go to http://${IP}:8123 \n" exit fi -if [ "$UPD" == "3" ]; then +if [ "$UPD" == "2" ]; then msg_info "Installing Home Assistant Comunity Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null @@ -371,7 +365,7 @@ msg_ok "Installed Home Assistant Comunity Store (HACS)" echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" exit fi -if [ "$UPD" == "4" ]; then +if [ "$UPD" == "3" ]; then msg_info "Installing FileBrowser" curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null @@ -454,5 +448,5 @@ pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable (after it's initialized) by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL}" From e4fc7869c5146fc7503014589d247b30137d9913 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 12:50:30 -0500 Subject: [PATCH 4166/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f9011dad..63ece923 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-11 + +### Changed + +- **Home Assistant Core LXC** + - Auto Initialize + ## 2023-01-09 ### Changed From abbd3a069b598adab555a5615efaf836971d7c14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 19:10:36 -0500 Subject: [PATCH 4167/6505] Create cronicle-v5.sh --- ct/cronicle-v5.sh | 401 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 401 insertions(+) create mode 100644 ct/cronicle-v5.sh diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh new file mode 100644 index 00000000..f03b7f4b --- /dev/null +++ b/ct/cronicle-v5.sh @@ -0,0 +1,401 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ _ __ + / ____/________v5____ (_)____/ /__ + / / / ___/ __ \/ __ \/ / ___/ / _ \ +/ /___/ / / /_/ / / / / / /__/ / __/ +\____/_/ \____/_/ /_/_/\___/_/\___/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Cronicle" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +hostname="$(hostname)" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} Master LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + SERVER="y" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} SUPPORT" --yesno "Options to Update or Install ${APP} Worker on $hostname. Proceed?" 10 58); then + echo "User selected Support" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + "1" "Update ${APP}" ON \ + "2" "Install ${APP} Worker" OFF \ + 3>&1 1>&2 2>&3) + +clear +header_info +if [ "$UPD" == "1" ]; then +msg_info "Updating ${APP}" +/opt/cronicle/bin/control.sh upgrade &>/dev/null +msg_ok "Updated ${APP}" +exit +fi +if [ "$UPD" == "2" ]; then +LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +IP=$(hostname -I | awk '{print $1}') +msg_info "Installing Dependencies" + +apt-get install -y git &>/dev/null +apt-get install -y make &>/dev/null +apt-get install -y g++ &>/dev/null +apt-get install -y gcc &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Installing Cronicle Worker" +mkdir -p /opt/cronicle +cd /opt/cronicle +tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 &>/dev/null +npm install &>/dev/null +node bin/build.js dist &>/dev/null +sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json +/opt/cronicle/bin/control.sh start &>/dev/null +cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled &>/dev/null +chmod 775 /etc/init.d/cronicled +update-rc.d cronicled defaults &>/dev/null +msg_ok "Installed Cronicle Worker on $hostname" +echo -e "\n Add Masters secret key to /opt/cronicle/conf/config.json \n" +exit +fi +} + +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export SERV=$SERVER +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Master should be reachable by going to the following URL. + ${BL}http://${IP}:3012${CL} admin|admin \n" From 8ffb8ba16d7ef115d755a1253adbec83e909a559 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 19:11:47 -0500 Subject: [PATCH 4168/6505] Create cronicle-v5-install.sh --- install/cronicle-v5-install.sh | 140 +++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 install/cronicle-v5-install.sh diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh new file mode 100644 index 00000000..5f1f8ff3 --- /dev/null +++ b/install/cronicle-v5-install.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Cronicle Master" +LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +IP=$(hostname -I | awk '{print $1}') +mkdir -p /opt/cronicle +cd /opt/cronicle +$STD tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 +$STD npm install +$STD node bin/build.js dist +sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json +if [[ $SERV == "y" ]]; then $STD /opt/cronicle/bin/control.sh setup; fi +$STD /opt/cronicle/bin/control.sh start +$STD cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled +chmod 775 /etc/init.d/cronicled +$STD update-rc.d cronicled defaults +msg_ok "Installed Cronicle Master" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 6789b685a6f5f425920ccb62bb8955ac72efadb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 19:34:35 -0500 Subject: [PATCH 4169/6505] Update cronicle-v5.sh add directory checks --- ct/cronicle-v5.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index f03b7f4b..f88bc6c0 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -316,12 +316,20 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb clear header_info if [ "$UPD" == "1" ]; then + if [[ ! -d /opt/cronicle ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi msg_info "Updating ${APP}" /opt/cronicle/bin/control.sh upgrade &>/dev/null msg_ok "Updated ${APP}" exit fi if [ "$UPD" == "2" ]; then + if [[ -d /opt/cronicle ]]; then + msg_error "${APP} Installation Found!"; + exit + fi LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) IP=$(hostname -I | awk '{print $1}') msg_info "Installing Dependencies" From 5c4cc1a4a59abdc033a159ce85157e96837fcde4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 19:45:53 -0500 Subject: [PATCH 4170/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 63ece923..15405049 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **Home Assistant Core LXC** - Auto Initialize +- **Cronicle Master/Worker LXC** + - NEW Script ## 2023-01-09 From daa747e66b909b96f857e014b047c0fc00225d93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 19:52:08 -0500 Subject: [PATCH 4171/6505] Update cronicle-v5-install.sh --- install/cronicle-v5-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 5f1f8ff3..ebd00e41 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -97,7 +97,7 @@ msg_info "Installing Node.js" $STD apt-get install -y nodejs msg_ok "Installed Node.js" -msg_info "Installing Cronicle Master" +msg_info "Installing Cronicle Primary Server" LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) IP=$(hostname -I | awk '{print $1}') mkdir -p /opt/cronicle @@ -111,7 +111,7 @@ $STD /opt/cronicle/bin/control.sh start $STD cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled chmod 775 /etc/init.d/cronicled $STD update-rc.d cronicled defaults -msg_ok "Installed Cronicle Master" +msg_ok "Installed Cronicle Primary Server" PASS=$(grep -w "root" /etc/shadow | cut -b6) if [[ $PASS != $ ]]; then From aba51cc393b4844bd1a9340d142cf3f924e9dfb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 19:52:54 -0500 Subject: [PATCH 4172/6505] Update cronicle-v5.sh --- ct/cronicle-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index f88bc6c0..366f1a15 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -405,5 +405,5 @@ pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" -echo -e "${APP} Master should be reachable by going to the following URL. +echo -e "${APP} Primary should be reachable by going to the following URL. ${BL}http://${IP}:3012${CL} admin|admin \n" From 487c46728fb4af82273d8838e4b6cb749e903d47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Jan 2023 19:53:22 -0500 Subject: [PATCH 4173/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 15405049..238e46d1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. - **Home Assistant Core LXC** - Auto Initialize -- **Cronicle Master/Worker LXC** +- **Cronicle Primary/Worker LXC** - NEW Script ## 2023-01-09 From 32d9d83bcffa8a3b354c04dda6dfb9ab47f3b94d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 Jan 2023 09:48:24 -0500 Subject: [PATCH 4174/6505] Update filebrowser.sh tweak --- misc/filebrowser.sh | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index dc322299..893c834b 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -1,4 +1,14 @@ #!/usr/bin/env bash +function header_info { + cat <<"EOF" + _______ __ ____ + / ____(_) /__ / __ )_________ _ __________ _____ + / /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/ + / __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ / +/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/ + +EOF +} IP=$(hostname -I | awk '{print $1}') YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -28,7 +38,8 @@ function error_exit() { echo -e "$flag $msg" 1>&2 exit $EXIT } - +clear +header_info while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in @@ -38,20 +49,7 @@ while true; do esac done clear -function header_info { - echo -e "${DGN} - - ______ _ _ ____ - | ____(_) | | _ \ - | |__ _| | ___| |_) |_ __ _____ _____ ___ _ __ - | __| | | |/ _ \ _ <| __/ _ \ \ /\ / / __|/ _ \ __| - | | | | | __/ |_) | | | (_) \ V V /\__ \ __/ | - |_| |_|_|\___|____/|_| \___/ \_/\_/ |___/\___|_| -${CL}" -} - header_info - function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -63,7 +61,7 @@ function msg_ok() { } msg_info "Installing ${APP}" -curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null +bash <(curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh) &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null From 48babec3bd43598b5589d2034a7fced866b167b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 Jan 2023 10:51:43 -0500 Subject: [PATCH 4175/6505] Update wireguard-v5.sh tweak --- ct/wireguard-v5.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 824e6f7c..4d825bd5 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -325,6 +325,10 @@ msg_ok "Update Successfull" exit fi if [ "$UPD" == "2" ]; then + if [[ -f /etc/systemd/system/wg-dashboard.service ]]; then + msg_error "Existing WGDashboard Installation Found!"; + exit + fi IP=$(hostname -I | awk '{print $1}') msg_info "Installing pip3" apt-get install -y python3-pip &>/dev/null From 28e198f56741d5f8a0e000da01041d982c8bade0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 Jan 2023 11:27:26 -0500 Subject: [PATCH 4176/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 238e46d1..006aa53e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,4 +1,4 @@ - + # Change Log All notable changes to this project will be documented in this file. From a84c54d3cc28c6fae840c7435d7e5f602ec52a2a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 Jan 2023 13:33:22 -0500 Subject: [PATCH 4177/6505] Option to set MTU size (#930) * option to change mtu value --- ct/adguard-v5.sh | 15 ++++++++++++++- ct/alpine-v5.sh | 15 ++++++++++++++- ct/archlinux-v5.sh | 15 ++++++++++++++- ct/blocky-v5.sh | 15 ++++++++++++++- ct/casaos-v5.sh | 15 ++++++++++++++- ct/changedetection-v5.sh | 15 ++++++++++++++- ct/cronicle-v5.sh | 15 ++++++++++++++- ct/daemonsync-v5.sh | 15 ++++++++++++++- ct/dashy-v5.sh | 15 ++++++++++++++- ct/debian-v5.sh | 15 ++++++++++++++- ct/deconz-v5.sh | 15 ++++++++++++++- ct/docker-v5.sh | 15 ++++++++++++++- ct/emby-v5.sh | 15 ++++++++++++++- ct/emqx-v5.sh | 15 ++++++++++++++- ct/esphome-v5.sh | 15 ++++++++++++++- ct/grafana-v5.sh | 15 ++++++++++++++- ct/grocy-v5.sh | 15 ++++++++++++++- ct/heimdalldashboard-v5.sh | 15 ++++++++++++++- ct/homeassistant-core-v5.sh | 15 ++++++++++++++- ct/homeassistant-v5.sh | 15 ++++++++++++++- ct/homebridge-v5.sh | 15 ++++++++++++++- ct/homepage-v5.sh | 15 ++++++++++++++- ct/hyperion-v5.sh | 15 ++++++++++++++- ct/influxdb-v5.sh | 15 ++++++++++++++- ct/iobroker-v5.sh | 15 ++++++++++++++- ct/jellyfin-v5.sh | 15 ++++++++++++++- ct/k0s-v5.sh | 15 ++++++++++++++- ct/keycloak-v5.sh | 15 ++++++++++++++- ct/magicmirror-v5.sh | 15 ++++++++++++++- ct/mariadb-v5.sh | 15 ++++++++++++++- ct/meshcentral-v5.sh | 15 ++++++++++++++- ct/motioneye-v5.sh | 15 ++++++++++++++- ct/mqtt-v5.sh | 15 ++++++++++++++- ct/n8n-v5.sh | 15 ++++++++++++++- ct/navidrome-v5.sh | 15 ++++++++++++++- ct/nextcloudpi-v5.sh | 15 ++++++++++++++- ct/nginxproxymanager-v5.sh | 15 ++++++++++++++- ct/nocodb-v5.sh | 15 ++++++++++++++- ct/node-red-v5.sh | 15 ++++++++++++++- ct/omada-v5.sh | 15 ++++++++++++++- ct/omv-v5.sh | 15 ++++++++++++++- ct/openhab-v5.sh | 15 ++++++++++++++- ct/paperless-ngx-v5.sh | 15 ++++++++++++++- ct/photoprism-v5.sh | 15 ++++++++++++++- ct/pihole-v5.sh | 15 ++++++++++++++- ct/plex-v5.sh | 15 ++++++++++++++- ct/podman-homeassistant-v5.sh | 15 ++++++++++++++- ct/podman-v5.sh | 15 ++++++++++++++- ct/postgresql-v5.sh | 15 ++++++++++++++- ct/prometheus-v5.sh | 15 ++++++++++++++- ct/scrypted-v5.sh | 15 ++++++++++++++- ct/shinobi-v5.sh | 15 ++++++++++++++- ct/syncthing-v5.sh | 15 ++++++++++++++- ct/technitiumdns-v5.sh | 15 ++++++++++++++- ct/trilium-v5.sh | 15 ++++++++++++++- ct/ubuntu-v5.sh | 15 ++++++++++++++- ct/umbrel-v5.sh | 15 ++++++++++++++- ct/unifi-v5.sh | 15 ++++++++++++++- ct/uptimekuma-v5.sh | 15 ++++++++++++++- ct/vaultwarden-v5.sh | 15 ++++++++++++++- ct/whoogle-v5.sh | 15 ++++++++++++++- ct/wikijs-v5.sh | 15 ++++++++++++++- ct/wireguard-v5.sh | 15 ++++++++++++++- ct/yunohost-v5.sh | 15 ++++++++++++++- ct/zigbee2mqtt-v5.sh | 15 ++++++++++++++- ct/zwave-js-ui-v5.sh | 15 ++++++++++++++- 66 files changed, 924 insertions(+), 66 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 19253057..da147dfc 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -116,6 +116,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -225,6 +227,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -358,7 +371,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index e43b5c22..db759dd5 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -223,6 +225,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -337,7 +350,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index c56f9b8a..da561a1f 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index d460035c..59d2c74d 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 6540b4d1..740930aa 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -228,6 +230,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -351,7 +364,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 7facabc7..88aa8595 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -340,7 +353,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 366f1a15..f10caccb 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -115,6 +115,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -224,6 +226,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -388,7 +401,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 9aeafa7a..39305f4a 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 68308c59..eb18f3a7 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -367,7 +380,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index d357e70c..f4a14602 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -113,6 +113,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -222,6 +224,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -336,7 +349,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 96f6c164..4a50fe38 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 05a3e7d1..c90ee4b0 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -116,6 +116,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -348,7 +361,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index d437d570..1c8f4031 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -235,6 +237,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -360,7 +373,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 1c7fd2d7..053de5a0 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -340,7 +353,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index 08853e26..647a05ca 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,7 +360,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index d8e30cfa..71c801d9 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 4c968ca2..1f45f898 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -340,7 +353,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 6105a6b5..466269e5 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -420,7 +433,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 8008bf97..46bf2b5f 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -120,6 +120,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -230,6 +232,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -417,7 +430,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index f2c18915..043eebb4 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -230,6 +232,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -416,7 +429,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 3e8d27d1..f635f3d6 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 08342af6..5e293376 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,7 +360,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index ea2db61e..f2b83c82 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -342,7 +355,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 0c854a39..18e5e1ef 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index f5e08b8e..e5863828 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 1c500c18..91b007ef 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -120,6 +120,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -237,6 +239,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -350,7 +363,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 194d5d25..7a578549 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 78dfca0a..f23f1c32 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -342,7 +355,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 74e32759..199ded64 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -343,7 +356,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 72d2af41..82f7c71a 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 6f83cd69..ac9500ff 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 94b1d14a..7d4fe34c 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -340,7 +353,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index bff59605..707624b8 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -115,6 +115,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -224,6 +226,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index de9aef30..69437e2a 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 53750da7..beab0978 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,7 +365,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 511f39f8..a993d3bc 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index ccb6d296..94954f7f 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -450,7 +463,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 1b6510da..1fd54974 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -344,7 +357,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 0a207309..3743a71a 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -377,7 +390,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index ef01599e..e6aa93bd 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -235,6 +237,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -339,7 +352,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index a9a5366a..e7ed0d62 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -342,7 +355,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 033c762c..401b85b7 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -342,7 +355,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 9e6d1c24..411463c0 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -409,7 +422,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 5e5a9961..4691eb67 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -116,6 +116,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -225,6 +227,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -362,7 +375,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index a153ed0f..a6e3e22f 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index c6d04cf2..537f8bf5 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -119,6 +119,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -236,6 +238,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -360,7 +373,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 43d158ec..995ca428 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -121,6 +121,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -230,6 +232,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -391,7 +404,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 9ce8f0d8..32670543 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index e1412d2f..73bf41f5 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 490bd911..8b46ddcf 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 788759d7..1070f901 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -342,7 +355,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 94d0b2f8..4e3f1107 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -235,6 +237,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -351,7 +364,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 892c06f1..4825b5ab 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -342,7 +355,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 696fdd95..9e55abd1 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -403,7 +416,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 54cbf786..88cdc017 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -360,7 +373,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 5433958e..6fb92d13 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -114,6 +114,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -231,6 +233,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -344,7 +357,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 047ec077..9a2b7b0e 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -228,6 +230,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -349,7 +362,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 02550614..d8f71fe2 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -341,7 +354,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index a82870c4..81f77d75 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -358,7 +371,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 0a607672..65002322 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -116,6 +116,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -409,7 +422,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 08741c4c..a92970eb 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -340,7 +353,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index c38f34d1..a8785853 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -354,7 +367,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 4d825bd5..333635b5 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -396,7 +409,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index a1382e7f..9a44f24e 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -113,6 +113,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -222,6 +224,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -336,7 +349,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 5c8348f4..1d4d9cc1 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -118,6 +118,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -227,6 +229,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -371,7 +384,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 1b5fb451..3b7394df 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -117,6 +117,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" SD="" echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" @@ -226,6 +228,17 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -354,7 +367,7 @@ export PCT_OPTIONS=" -hostname $HN $SD $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU -onboot 1 -cores $CORE_COUNT -memory $RAM_SIZE From 4c829312ba5b0075539ad1a329145afeeb2713ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 Jan 2023 13:37:58 -0500 Subject: [PATCH 4178/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 006aa53e..b31cefcf 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-12 + +### Changed + +- **ALL LXC's** + - Add an option to set MTU size (Advanced) + ## 2023-01-11 ### Changed From 3641028e1dcc97d18dfe9d1d8d3ce8e2f33b7e00 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 Jan 2023 06:18:33 -0500 Subject: [PATCH 4179/6505] Update grafana-v5-install.sh Grafana packages will be served from a new repository --- install/grafana-v5-install.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 7647e08f..23fc0f5b 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -90,10 +90,8 @@ $STD apt-get install -y software-properties-common msg_ok "Installed Dependencies" msg_info "Setting up Grafana Repository" -$STD apt-key add <(curl -fsSL https://packages.grafana.com/gpg.key) -cat </etc/apt/sources.list.d/grafana.list -deb https://packages.grafana.com/oss/deb stable main -EOF +wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key +sh -c 'echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list' msg_ok "Set up Grafana Repository" msg_info "Installing Grafana" From 06e40224729b67982786195ad612103e2a608244 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 Jan 2023 14:09:44 -0500 Subject: [PATCH 4180/6505] Create the arr's (#938) lidarr, prowlarr, radarr, readarr, sonarr, whisparr --- ct/lidarr-v5.sh | 370 ++++++++++++++++++++++++++++++++ ct/prowlarr-v5.sh | 370 ++++++++++++++++++++++++++++++++ ct/radarr-v5.sh | 370 ++++++++++++++++++++++++++++++++ ct/readarr-v5.sh | 370 ++++++++++++++++++++++++++++++++ ct/sonarr-v5.sh | 370 ++++++++++++++++++++++++++++++++ ct/whisparr-v5.sh | 371 +++++++++++++++++++++++++++++++++ install/lidarr-v5-install.sh | 144 +++++++++++++ install/prowlarr-v5-install.sh | 142 +++++++++++++ install/radarr-v5-install.sh | 142 +++++++++++++ install/readarr-v5-install.sh | 142 +++++++++++++ install/sonarr-v5-install.sh | 121 +++++++++++ install/whisparr-v5-install.sh | 142 +++++++++++++ 12 files changed, 3054 insertions(+) create mode 100644 ct/lidarr-v5.sh create mode 100644 ct/prowlarr-v5.sh create mode 100644 ct/radarr-v5.sh create mode 100644 ct/readarr-v5.sh create mode 100644 ct/sonarr-v5.sh create mode 100644 ct/whisparr-v5.sh create mode 100644 install/lidarr-v5-install.sh create mode 100644 install/prowlarr-v5-install.sh create mode 100644 install/radarr-v5-install.sh create mode 100644 install/readarr-v5-install.sh create mode 100644 install/sonarr-v5-install.sh create mode 100644 install/whisparr-v5-install.sh diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh new file mode 100644 index 00000000..aa63a68d --- /dev/null +++ b/ct/lidarr-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ _ __ + / / (_)___/ /___v5__________ + / / / / __ / __ `/ ___/ ___/ + / /___/ / /_/ / /_/ / / / / +/_____/_/\__,_/\__,_/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Lidarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8686${CL} \n" diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh new file mode 100644 index 00000000..dbf5a5e8 --- /dev/null +++ b/ct/prowlarr-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \_________ _ __/ /___v5__________ + / /_/ / ___/ __ \ | /| / / / __ `/ ___/ ___/ + / ____/ / / /_/ / |/ |/ / / /_/ / / / / +/_/ /_/ \____/|__/|__/_/\__,_/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Prowlarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9696${CL} \n" diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh new file mode 100644 index 00000000..ad68253e --- /dev/null +++ b/ct/radarr-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \____ _____/ /___v5__________ + / /_/ / __ `/ __ / __ `/ ___/ ___/ + / _, _/ /_/ / /_/ / /_/ / / / / +/_/ |_|\__,_/\__,_/\__,_/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Radarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7878${CL} \n" diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh new file mode 100644 index 00000000..a8e596d0 --- /dev/null +++ b/ct/readarr-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \___ ____ _____/ /___v5__________ + / /_/ / _ \/ __ `/ __ / __ `/ ___/ ___/ + / _, _/ __/ /_/ / /_/ / /_/ / / / / +/_/ |_|\___/\__,_/\__,_/\__,_/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Readarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8787${CL} \n" diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh new file mode 100644 index 00000000..2207fb65 --- /dev/null +++ b/ct/sonarr-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _____ + / ___/____ ____ ____v5__________ + \__ \/ __ \/ __ \/ __ `/ ___/ ___/ + ___/ / /_/ / / / / /_/ / / / / +/____/\____/_/ /_/\__,_/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Sonarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8989${CL} \n" diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh new file mode 100644 index 00000000..ed21646d --- /dev/null +++ b/ct/whisparr-v5.sh @@ -0,0 +1,371 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _ ____ _ +| | / / /_ (_)________ ____v5__________ +| | /| / / __ \/ / ___/ __ \/ __ `/ ___/ ___/ +| |/ |/ / / / / (__ ) /_/ / /_/ / / / / +|__/|__/_/ /_/_/____/ .___/\__,_/_/ /_/ + /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Whisparr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6969${CL} \n" diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh new file mode 100644 index 00000000..53d35fcc --- /dev/null +++ b/install/lidarr-v5-install.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y sqlite3 +$STD apt-get install -y libchromaprint-tools +$STD apt-get install -y mediainfo +msg_ok "Installed Dependencies" + +msg_info "Installing Lidarr" +mkdir -p /var/lib/lidarr/ +chmod 775 /var/lib/lidarr/ +$STD wget --content-disposition 'https://lidarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Lidarr.master.*.tar.gz +mv Lidarr /opt +chmod 775 /opt/Lidarr +msg_ok "Installed Lidarr" + +msg_info "Creating Service" +cat </etc/systemd/system/lidarr.service +[Unit] +Description=Lidarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Lidarr/Lidarr -nobrowser -data=/var/lib/lidarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q lidarr +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf Lidarr.master.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh new file mode 100644 index 00000000..71fcd5fb --- /dev/null +++ b/install/prowlarr-v5-install.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Prowlarr" +mkdir -p /var/lib/prowlarr/ +chmod 775 /var/lib/prowlarr/ +$STD wget --content-disposition 'https://prowlarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Prowlarr.master.*.tar.gz +mv Prowlarr /opt +chmod 775 /opt/Prowlarr +msg_ok "Installed Prowlarr" + +msg_info "Creating Service" +cat </etc/systemd/system/prowlarr.service +[Unit] +Description=Prowlarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q prowlarr +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf Prowlarr.master.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh new file mode 100644 index 00000000..63536c41 --- /dev/null +++ b/install/radarr-v5-install.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Radarr" +mkdir -p /var/lib/radarr/ +chmod 775 /var/lib/radarr/ +$STD wget --content-disposition 'https://radarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Radarr.master.*.tar.gz +mv Radarr /opt +chmod 775 /opt/Radarr +msg_ok "Installed Radarr" + +msg_info "Creating Service" +cat </etc/systemd/system/radarr.service +[Unit] +Description=Radarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q radarr +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf Radarr.master.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh new file mode 100644 index 00000000..4ab6fd6c --- /dev/null +++ b/install/readarr-v5-install.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Readarr" +mkdir -p /var/lib/readarr/ +chmod 775 /var/lib/readarr/ +$STD wget --content-disposition 'https://readarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Readarr.develop.*.tar.gz +mv Readarr /opt +chmod 775 /opt/Readarr +msg_ok "Installed Readarr" + +msg_info "Creating Service" +cat </etc/systemd/system/readarr.service +[Unit] +Description=Readarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q readarr +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf Readarr.develop.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh new file mode 100644 index 00000000..19deb39c --- /dev/null +++ b/install/sonarr-v5-install.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +$STD apt-get install -y ca-certificates +msg_ok "Installed Dependencies" + +msg_info "Installing Sonarr" +$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 +sh -c 'echo "deb https://apt.sonarr.tv/debian buster-develop main" > /etc/apt/sources.list.d/sonarr.list' +$STD apt-get update +$STD apt-get install -y sonarr +msg_ok "Installed Sonarr" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh new file mode 100644 index 00000000..f05cf265 --- /dev/null +++ b/install/whisparr-v5-install.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Whisparr" +mkdir -p /var/lib/whisparr/ +chmod 775 /var/lib/whisparr/ +$STD wget --content-disposition 'https://whisparr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Whisparr.develop.*.tar.gz +mv Whisparr /opt +chmod 775 /opt/Whisparr +msg_ok "Installed Whisparr" + +msg_info "Creating Service" +cat </etc/systemd/system/whisparr.service +[Unit] +Description=whisparr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Whisparr/Whisparr -nobrowser -data=/var/lib/whisparr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q whisparr +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf Whisparr.develop.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 2f8417c4ee43638258104fb7b333cefbd69ad86f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 Jan 2023 14:13:25 -0500 Subject: [PATCH 4181/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b31cefcf..ca9e2e4c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,23 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-13 + +### Changed + +- **Lidarr LXC** + - NEW Script +- **Prowlarr LXC** + - NEW Script +- **Radarr LXC** + - NEW Script +- **Readarr LXC** + - NEW Script +- **Sonarr LXC** + - NEW Script +- **Whisparr LXC** + - NEW Script + ## 2023-01-12 ### Changed From cbd1c350458f1dcf9bbdeae0da226522a3340b47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 Jan 2023 14:39:10 -0500 Subject: [PATCH 4182/6505] Update sonarr-v5-install.sh --- install/sonarr-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 19deb39c..9cb4a4b9 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -91,7 +91,7 @@ msg_info "Installing Sonarr" $STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 sh -c 'echo "deb https://apt.sonarr.tv/debian buster-develop main" > /etc/apt/sources.list.d/sonarr.list' $STD apt-get update -$STD apt-get install -y sonarr +$STD apt-get -o Dpkg::Options::="--force-confold" install -y sonarr msg_ok "Installed Sonarr" PASS=$(grep -w "root" /etc/shadow | cut -b6) From f351e7ef54ac749b2ff527409d4b6e4bb738f836 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 Jan 2023 14:44:34 -0500 Subject: [PATCH 4183/6505] Update sonarr-v5-install.sh --- install/sonarr-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 9cb4a4b9..9d8a6585 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +export DEBIAN_FRONTEND=noninteractive if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") From 6ee0e2047a0ea8e521e95b0a0451f1ed313196b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 07:58:12 -0500 Subject: [PATCH 4184/6505] Update scrypted-v5-install.sh node v18 --- install/scrypted-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 1a08672c..27ae70da 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -116,7 +116,7 @@ $STD apt-get -y install \ msg_ok "Installed GStreamer" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 7c75036e3c246e5072e9fa9e22e3d9e5fd5a0e46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 14:18:23 -0500 Subject: [PATCH 4185/6505] Update nextcloudpi-v5-install.sh fix shell access --- install/nextcloudpi-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 45f6b6d3..9aeeb72e 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -88,6 +88,7 @@ msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" $STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php +sed -i '{s|root:/usr/sbin/nologing|root:/bin/bash|g}' /etc/passwd service apache2 restart msg_ok "Installed NextCloudPi" From d632dd48d46efe913c4a35c2c8a96a0f7d195c28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 14:42:36 -0500 Subject: [PATCH 4186/6505] Update nextcloudpi-v5-install.sh --- install/nextcloudpi-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 9aeeb72e..356f2a8c 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -88,7 +88,7 @@ msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" $STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php -sed -i '{s|root:/usr/sbin/nologing|root:/bin/bash|g}' /etc/passwd +sed -i '{s|root:/usr/sbin/nologin|root:/bin/bash|g}' /etc/passwd service apache2 restart msg_ok "Installed NextCloudPi" From 6b9da63d5b19b2091bfafaaeffe9f8c2f1282b7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 20:06:44 -0500 Subject: [PATCH 4187/6505] Create tdarr-v5.sh --- ct/tdarr-v5.sh | 370 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 ct/tdarr-v5.sh diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh new file mode 100644 index 00000000..20c495b2 --- /dev/null +++ b/ct/tdarr-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ __ + /_ __/___/ /___v5__________ + / / / __ / __ `/ ___/ ___/ + / / / /_/ / /_/ / / / / +/_/ \__,_/\__,_/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Tdarr" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8265${CL} \n" From e3bb3d8e84830ae0dd76d3be18a79511f37818b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 20:08:08 -0500 Subject: [PATCH 4188/6505] Create tdarr-v5-install.sh --- install/tdarr-v5-install.sh | 169 ++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 install/tdarr-v5-install.sh diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh new file mode 100644 index 00000000..0bce29cd --- /dev/null +++ b/install/tdarr-v5-install.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing Tdarr" +mkdir -p /opt/tdarr +cd /opt/tdarr +wget -q https://f000.backblazeb2.com/file/tdarrs/versions/2.00.15/linux_x64/Tdarr_Updater.zip +$STD unzip Tdarr_Updater.zip +chmod +x Tdarr_Updater +$STD ./Tdarr_Updater +msg_ok "Installed Tdarr" + +msg_info "Creating Service" +service_path="/etc/systemd/system/tdarr-server.service" +echo "[Unit] +Description=Tdarr Server Daemon +After=network.target +# Enable if using ZFS, edit and enable if other FS mounting is required to access directory +#Requires=zfs-mount.service + +[Service] +User=root +Group=root + +Type=simple +WorkingDirectory=/opt/tdarr/Tdarr_Server +ExecStartPre=/opt/tdarr/Tdarr_Updater +ExecStart=/opt/tdarr/Tdarr_Server/Tdarr_Server +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path + +service_path="/etc/systemd/system/tdarr-node.service" +echo "[Unit] +Description=Tdarr Node Daemon +After=network.target +Requires=tdarr-server.service + +[Service] +User=root +Group=root + +Type=simple +WorkingDirectory=/opt/tdarr/Tdarr_Node +ExecStart=/opt/tdarr/Tdarr_Node/Tdarr_Node +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q tdarr-server.service +systemctl enable --now -q tdarr-node.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +rm -rf Tdarr_Updater.zip +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 581f73637a854a4a50dfaf55568efda17cc242ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 20:11:26 -0500 Subject: [PATCH 4189/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ca9e2e4c..1acfe6c5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-14 + +### Changed + +- **Tdarr LXC** + - NEW Script + ## 2023-01-13 ### Changed From bdcd1c40a3817ec40bfd35eb223f3d1ded7cbee1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 21:05:41 -0500 Subject: [PATCH 4190/6505] Create deluge-v5-install.sh --- install/deluge-v5-install.sh | 156 +++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 install/deluge-v5-install.sh diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh new file mode 100644 index 00000000..0ec88f4e --- /dev/null +++ b/install/deluge-v5-install.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing pip3" +$STD apt-get install -y python3-pip +msg_ok "Installed pip3" + +msg_info "Installing Deluge" +$STD pip install deluge[all] +msg_ok "Installed Deluge" + +msg_info "Creating Service" +service_path="/etc/systemd/system/deluged.service" +echo "[Unit] +Description=Deluge Bittorrent Client Daemon +Documentation=man:deluged +After=network-online.target + +[Service] +Type=simple +UMask=007 +ExecStart=/usr/local/bin/deluged -d +Restart=on-failure +TimeoutStopSec=300 + +[Install] +WantedBy=multi-user.target" >$service_path + +service_path="/etc/systemd/system/deluge-web.service" +echo "[Unit] +Description=Deluge Bittorrent Client Web Interface +Documentation=man:deluge-web +After=deluged.service +Wants=deluged.service + +[Service] +Type=simple +UMask=027 +ExecStart=/usr/local/bin/deluge-web -d +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q deluged.service +systemctl enable --now -q deluge-web.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From bdd7afce64624ef1b9ffcb879aa13dfabdb49e84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 21:06:58 -0500 Subject: [PATCH 4191/6505] Create deluge-v5.sh --- ct/deluge-v5.sh | 371 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 ct/deluge-v5.sh diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh new file mode 100644 index 00000000..d77b8d36 --- /dev/null +++ b/ct/deluge-v5.sh @@ -0,0 +1,371 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ + / __ \___ / /_v5______ ____ + / / / / _ \/ / / / / __ `/ _ \ + / /_/ / __/ / /_/ / /_/ / __/ +/_____/\___/_/\__,_/\__, /\___/ + /____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Deluge" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8112${CL} \n" From 2150de088cdd51c461f107d5215f35f513060640 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 21:07:32 -0500 Subject: [PATCH 4192/6505] Update tdarr-v5.sh --- ct/tdarr-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 20c495b2..0de99210 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -362,7 +362,7 @@ pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} ${var_version} LXC +pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" From fc9b42bc5bcc02b4c4da813a867799582caed6e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Jan 2023 21:21:37 -0500 Subject: [PATCH 4193/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1acfe6c5..60905879 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. - **Tdarr LXC** - NEW Script +- **Deluge LXC** + - NEW Script ## 2023-01-13 From 313de1c3aa20f739b2b6102752bad3cf2e9e9816 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:48:57 -0500 Subject: [PATCH 4194/6505] Delete docker.png --- misc/images/docker.png | Bin 49776 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/docker.png diff --git a/misc/images/docker.png b/misc/images/docker.png deleted file mode 100644 index 210598c29e4e83090b4df0a8cd2ca424c37d61a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49776 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 From 918914c1b6c558ac76ea2e3e53da337e4fa29547 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:49:08 -0500 Subject: [PATCH 4195/6505] Delete add_integration.png --- misc/images/add_integration.png | Bin 2749 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/add_integration.png diff --git a/misc/images/add_integration.png b/misc/images/add_integration.png deleted file mode 100644 index 64d19fd2a24fb2838def65c1fd723513bad01ed5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2749 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 Dr(IED From b2e0e57b90d8c8c3c24e1e35780d76859f6ed13e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:49:18 -0500 Subject: [PATCH 4196/6505] Delete adminer.png --- misc/images/adminer.png | Bin 139371 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/adminer.png diff --git a/misc/images/adminer.png b/misc/images/adminer.png deleted file mode 100644 index bede27577be12d9b28646562fdd8ebec0e7e67c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139371 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 Date: Sun, 15 Jan 2023 22:49:30 -0500 Subject: [PATCH 4197/6505] Delete adminer_logo-cl.png --- misc/images/adminer_logo-cl.png | Bin 14993 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/adminer_logo-cl.png diff --git a/misc/images/adminer_logo-cl.png b/misc/images/adminer_logo-cl.png deleted file mode 100644 index 0d3b6bd4c90ec7569dbc3f6ef727d4f8d0b7a6d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14993 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 Date: Sun, 15 Jan 2023 22:49:41 -0500 Subject: [PATCH 4198/6505] Delete change.png --- misc/images/change.png | Bin 5753 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/change.png diff --git a/misc/images/change.png b/misc/images/change.png deleted file mode 100644 index 5543ec3e9623496d85062400384d3c90621eab76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5753 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 From a97140b62687504ffc61c61e753b8f0b30945352 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:50:08 -0500 Subject: [PATCH 4199/6505] Delete changelog.png --- misc/images/changelog.png | Bin 2421 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/changelog.png diff --git a/misc/images/changelog.png b/misc/images/changelog.png deleted file mode 100644 index f762d00ee6a53d0987096a338da0e0523151a829..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2421 zcmV-*35xcKP)Px;FG)l}R9HvNn0ruE*B!^dcVD0)zHmeVLrU5twoPqP-L9kJH~@afj&5PxI`4i-C}@Nz7v7bHqtrT z5IiIPZ&E!6foj&;L)XV7#QkDM@I*?B_=bUN??58f{z{`vK| zdv6GXLw1VV(b10W`jknbCIM>V^oa(x*LG_ZL~{aY#-$1}5+p=;JRUfm zPB=y!a5@}_T)Y@zv%_%p>Q(&eDnXM3f^(2IO1BKdFw6w7@lk)~j9K{j+?xyvWXNYXK1UWO8aM>)L%kFL$Q4Ma=6`YT)K1#8jS|OeECK2yr16Bo;{n+zhM4C z{P9prS^CawZb~5Y!A3S&pUU03LlgomR!b0!BpSt#KUt$uqqE~83JVMA_?tIxQlB9u zGBOfjVPR-*Z%1cmCswariMY7$(Z1*lCtm_YlZ7RR7& ze{EUjbP6?@>sdo`8m9pHd|tR*WR=NqG7P!2esqc|Ltr-T>4IV7Q{Z_Kk1Ptu-~%_D zZXa4ZEEu@!#L=SFh>MG(P;YGgHI_t16Cf^gXZF+zDL}V-rB&A5Z4EfLB#!jAqrH>D zba!`Cn5{28fz8i74i&?|>lfhi_~7>X;r8;l_;oK1pT33*#!aZGsK5?G5+WBxp{}8Z z%S_Lm#$-)KF4d65k~l=CmTfft-rRfusi~=0U;GKuH$8(FpN>JORt>e9fzL0%_V`E`78j+Wm_i#YI&8)B0Lm2tqN*}0WS#f^8!`J<@Mtq*Zbk)f%AX2;LvYhfXQT{>ekj) zmStxbOufqL>y2DmS{B>ae}@9yun?0`4+^ZXzFr&Fu3d+bkrAXdT*jW1bqLj}pw$o{ z&>V?u%981LT(;QYxCw9FTzOYPjsoX-sCSujVq+asuhcD2M{Y;M%pX z@%_hsK!LLMe~H~G&mvT(LWo8MjhcaqKnZ}C7hvffhRZ9^T5n+TvkR7+i&lqia17`@cKPaK}DB7iNacq8gs(uV`ylInrvUr&k+`?hE7fT zKvg1vs;6%lZode(PlVGa;-gRhjryFmXl`z%p`xm$qAWkRaB7p8>Z{p|v>eVpV3Pu) zg`^)6NbvRC+4D$ANx?6QKS9cdWq2}X9&{Q&qmnjc5~)3Yz{4|e`+=$xU*W^I)?mSc z1!!z+Kv7XKs%k5_{Op3MS6Q`bAD5GnM{{b)T+#*+0Fr&Fv7w2|-qX`VReC#l9cJlN zn5k1EL`TfVz{iW!hdeyMHMQex`397hmVzrQ#oRgbQCU?{R**l9LPk?Ho0XBn4Gi{E zMaVYbc6;dRm(k=<#Ng-$M^RK%1gq78*M8rHxAiNa)iBVir6B4T0ON@(=;?Eyja^3r zV@*vBlD6wHCwv|%Ybv;c+`_39GMe_WSs8g0h^S(*SSN)c6RK4zbaws?85tSWwCQ#K zg#Df;cx$3&(rUF>x^yWF1_S=}QUala2 z8lZjECQn*kt)(+RiB1%|9;FiHr+KfMA8ufK{VOBUn#_~-Brw;L-~tSBogd~51e_Wr(dZdcwYkg}~ z>eRA%f|tCM)5{Z!0(f44Kq_hDdFh$nlQE?7fyhnz4e8lP-?}^x0GYwE-N5$C>SJ=mWpI+kS3(Z9G+y1G6;p>DTv=MUCA@qMtpuhTuvukZZ}G} zcagj;0Rk`L$z_jYe`9k1Di}x&V6IlHjqC2VUW|&09Lm38YE=fqT-XRMMx6 zQO5gxJ~$i>np=^?E;D}@wrt)Aoh}4%k3EW}=9X7Zo;cY$UZJ@F7G-8<6vxIcO_Cs# zQ^hDBnS}U?l1~!=scqap9i*R2Zy`q_pN}4g2;7b9mecm(2QR(;+6J6E|2fW_{!0V^ z$9NzOfLQ=$03_L%vIPHDT7puU^Z+RLY2|m5IY`w-$HqQ&tEcBv0OVL}|E3=k^Zh>x nnU8!Z`EUY9uA~Y8+@$^wf+lo|W<$Yl00000NkvXXu0mjfBt3h1 From 499b4d9c80052acfe11d22edfb861e4785882123 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:50:32 -0500 Subject: [PATCH 4200/6505] Delete discussions.png --- misc/images/discussions.png | Bin 17536 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/discussions.png diff --git a/misc/images/discussions.png b/misc/images/discussions.png deleted file mode 100644 index ea6678899a14853d59e2621fc2fbf124666209f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17536 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 Date: Sun, 15 Jan 2023 22:51:07 -0500 Subject: [PATCH 4201/6505] Delete gamuntu1.png --- misc/images/gamuntu1.png | Bin 25791 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/gamuntu1.png diff --git a/misc/images/gamuntu1.png b/misc/images/gamuntu1.png deleted file mode 100644 index 3502838d710d1938a697515d0d2967a85acdcd32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25791 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 O0000 Date: Sun, 15 Jan 2023 22:51:20 -0500 Subject: [PATCH 4202/6505] Delete gamuntu.png --- misc/images/gamuntu.png | Bin 1071038 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/gamuntu.png diff --git a/misc/images/gamuntu.png b/misc/images/gamuntu.png deleted file mode 100644 index b29f215865c839beda3fce5218517c7a63e27a2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1071038 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
    wv(2u9pB$mKvcALC{7UlrOS>KNuL|Ag z91Ez4;|~SgqhYwHs9Z?Yb%PKdyhl;!eTaIY2>1yBSPTC?mt(SratpH96od_Cy@sHJ zZ!Hj@AH$9n~kkVR<|7hyTP5k7=UaW3_0G1Qwzk7&Bq?dPuYLiUIfRNJ{@lyui#B zPr8=50>Z7Z=%*B-; z_|HVG1THh-cqI=hN?dqP=yaR@FP6N#1EWI=nY??v-a*;%Z^{PpLoI|IJtlQDSy?+n zC~W;$<|SYYWYDKE?5H_wykJCIH$yViNg&wrj6$@e>67&L_2ys@7Ss;(c~^j1Opp=q z4hlGYN@?;eJk^~J=N*-)bb#kEc|4BhCv_h1*l?HNCu)mync`0^c>^&o;()rv+n-l^=e67D$zTju}I|)crJuIBw{y7xNKK zQF?z;ug~({hRjGgnT?6q<%be$)dNGkxR;iC83mmN^)l(mS__{uCdEvu(Ru@hx(o5UxlPE25D)mZyYH%lX+r8(1dMPv?3Nx}}(Polo*tc)l+I4a;I>leItg3<7douG|@*MkArc~k8~ ztPEy)AW$5JROCS=>3@4(oL{T4e$Y57!n_U<8xL{TkCAPM-Mr?w(+Q{J)Z8v)FC z5zAIzPf+y~g!42kYOb};KKoB}t03sp-nS?a_8gWjfD0ydtv)B)&!}y;=r*}uS5?Y! zb7BZj(xij&kC0;~3nWJ;QU-T=x^o<;J2P(1(?M9uw*Zx@jJUC1;r>j&b%#EX=DnCI zW1%?kkN1*ozq0!0hdOKV-FbP)-RM4;y!?wOu(slQG~0&9YmGJc5E5R@%s&VMe#M9B zHPk{(qvq|R`4xFM-?Y3RF(qphz?rYYfZXdT-ZD17+<_AxV2$6kkD0S5BYJf zo}`MG;P*&2Y0;VyLik{XdNZf`&)a8k2iJ$5Khl+u3-hDSL!w#n;tA2aBIoLG2jq|< z8)z{7))7X5jP&6_4ZG!;95Fb@I8^b08Da_B92i8a!wL(~p-Mbq-;9*-P{2C(VXDzz z;_o4(wknbANC&XzT%^!i~l45fj@6ZMcJ!Pu*g`k(k%zAI? zYfpvsFZ@Q9Db&v<8Y_}h>xCubcBpd%vlpU;+ZV_pxTLoW7dR;7YUi|78tjLAb}iFI z^NE`-x4HNv52aWymRO}vJGZz2m$v48xhk3)5k!u=UZqDB_+pglvQ7Zba!(&$YvF)Z_APvv}F{8Jyc-LP(zd_MO)!42Z=+OOF$=t4pBav2T z*iX%mJ-wB1g9=3kq}?u`f8ED_4|MnyRx?ia9$tQC^QE^P!>PTqF`gc@yMF#jZ~|13 z8G2r@8W1WsbI}Oq`4t=-Ea^r-TfYvXU{g308d#Mud!Ue~g8-{#-swzM#W4_Lxw%{T z{hWx0tlSGghn2)Kw&%TCqde!_F+}!6DZ8}kK;NVy!&5`%$R4drAp|A4>juZ(f<9j4YkB*zFQ|&x|D{Q#Bx{!GMe5sM5Sm#2hNcvGu+bx|roV(Cx zT{n)AO{(KL`K+m({RNfq>tzw26j1nivn(2NlM!EuSZ=5dYjvubm4ffG!xczk&tHS= z%ShnAttYo~%m>``T!><;*kYxc8bN9Iggu`IiqH1Ei$aW{H|t+btL)9x@ElsU$U|Ms zW*VyYC?4la!|Rw7r&P`VBP>DvCXIVsx+3imkO5)dJMMTR>OE#lV~Q3p2Sc)5vIAyb$*1@blIR6>9?g8SNqO^;TocV;7Ar9R{W_3!rU)o=+#k|#Bp1&>>7 zNonPK`%p*Nz)oo^rG<$}yAO+8kJ;8TMkHa%HT=p6CbL z3qC^#H{q=4$2lrFyDvEBwSFs|aJ=}mXDS8zESh=8Xi;Zb1S_sF^<*mb;iPLY8&;gC z|Lj%Cy=7aU&+oU!O5V|IhK$(%1^R)oCxPEy&ZtyU*0E!lA%cTOlmk!Q^qlnsYRMq$ z4Uq_J-;puWivOn)C8B}OOV8do%7MEgUI3L`Z&o1Sm<$x9{3cShd-ZwrKIj@CfR#bY z^N-KA2T}9F#4%Olq#oo>tJ)$oIbm>SxvOdvY~6Mov(=S|BbDNc-K)fxLB)8%ev7 z320Xo->d}Y~MVl&n`%rY> zYik`Va}^8&X`?WAIYZxeE}bR=Pzz|TLW+DkU8PS)qtKLsrDD-J`!;P9NmvgMBh~ER zd**&`aprw(o;)Qiq=sd{fd<>d z?%6f-PFPhxvh#QQ%dS@vBy0I45%Lh^M#3{#))y`>0r`!pAD}4XYhrIYEOrrR&8yQ2FVqWTdg#>D) zP|^M1C$Rm98s6?VwG!RURf^qBtxSrFqNODcy&;c6L=;inangn^=Y{zn%W9Gz+}35T zj3(LVTxOmI3xZhY&aa7wh_OeAvGT^O*E^F1az3xpKAWM> zAwvVxKHHqwzDCn?DaT^ynu20#*nY+x z-f~Dj7)Q?!XvMrccSCD&P%$7+CSi656Hh0b-=-CAb@J!onry0x_P^~`Kej(U2*xFO zy>K8>816H|K!zbkA6_rmC3}|N5#I>k%RQNTICJ}YzQ7TNp0{Kf^UH!yWgh>9Mqj>b zCqKoA2q=A;lZPVx?k()TA`=E`A6Q?1wLNl9U);<+QFwzPR&1zm5_)I5=48tZaa5SC z)a5M{_h;_@dqFM04>Tf1s-#DuT9XsyRJoxstr*phrnRIy({l*Yq(P(MSzOqw#`x6A z>5RN?KYRPq8fUe4e>aX~8I8}Snds%rLk6;>27+~OYZ zxNXrxetw+jEx8o>nXvVcg+?^={O>ld{q30%y(QhI1nfs}CLAhH6r(M#-ZUgk|`wcnxw2mEv}T3oumP`?b|h9`M9T^B4-)w6f@`#_vMMSYml6^ z(s35z%We{5eYoLC9Ha34^y!1E&eIQ8KfH>;)>_{*=n+Kpq~Q8JA~?_Qc5768Esj;) z5#a=Vq|VS#i)@OZVi@GBdKti|anL6Z4U6nspfI0_H#5O1Hn1QYoRDIi24{?BQn8ur z*4^SujhsgOQIy1c+Mx+kBMwVJSf$hjFj#{hLubYL&8NKGOU}`Q+>ytW9%1+zAfBtTP_xVAJ*9s0^{MS-=e4ZQjm5a^0w3DgFDB_9zMvHc?v(DrHr}Xc}_3aQy(166(^p} z-*m9CUb61nic1D=#q(R?-Yfq$S^U#x>z}zEeqJ%YAO;2BULIARoO^k(q7*>%<3r=Fby=bR{M7vR$Xk{>k?#0`mF{fo2PWWZ#!2O zT6~|NZ2GtNs)zFDeMbV3qhGf}tGJcLE0xEI+l`1%`DVs=N=?BS2uX~E^Pz>~p$j!G z68K>Sm^bhcc5e;VGG6>QBCPWSn{9o1KP?Jao8@$h(+{ zggKGh#`rgqq!;B5uu)K|9vG<5MU$5`JWs@=f&U?eaaM{sFJf_7(j_#>0wQ^V=zV>*Y)Xzz4-!K|4=0Tvs_PG&@2m zG(AG@pWM~uc$`9Cc+AU^po|E`OSrAlA@Zujl`Z^i_>TP9GF1NRN02~}J1JXeyC_>o z`CYc44zB&LUow@J^9?x~JoOG5Mk?nlHl}oSeRuw91fPsuDul4=u&T}fsg-MWHhD?> z@t-(18+~n_(VMdJaReP~_8yv6;2{TiG+2KpjzmBH^P&2+kQ&mO49%@jticIZouO4_ ztDyH5=$3i|A><1Pm&gcc>S3Fgz8wk){D3j3JJ52R+N(|ib55!7v+3J=YMp_ zA4e9kf%+4`5R!6eoe`=gTNV3y5*mw_f-v*3)~a|`L^r)1kc4?S6w1I?H)&!DqvfAl zkv%|(m(BLx6KVpd4h1vcVJw_up^Z}h`U>Qu5>#rh^_3u7y5?U(M!oeh^1W5BtUc0_ zKbA;^;Ti?K<3jx#z-jJawLwWDApc%tN*7T$RoVv_(M^;~dnqHIngza!gqA(!BSwGP zGkSLs=w~|Q!tSv=uNGY3*w#hx;sTO@eNr_{XfMd_kl>O-ZtJs(7J_tvJf2@8$ zoQU%-yB(4vHXds+)v4+M5e=-&EH(2U$UIoomiHNEzYhNwown7(oj;CAU2i*=5|yf^ zvGdg0*)brC@=7DS_*Ti;l-wH(`~Y4qXG&p}OO*DuGt7Jbjr$kwBlmRh1A!3-F=5NL z7&n<`&XCv$HuT573^*~&?w6XMbXp?yBSL*qmt;p#-i3HJ)vxcBYnNYBc6X|qFTWCR zSDno5{zQ|-x!A6v1bE_bOQOo96y-3m`gk!x3$zxL8p;ILI_rHL>~6#xS*jK8PDb>k z8e}M1@82@+O5q*!^CJwA8jx#D>`^AeN*u#XeOFo=Uu7a;r5g$KGbG6)qJR%Bk9HEp z^Fm_Ps6GG%c$w}Z^&XK<5k*-UNM4aYUx_(Xc0$pQKH`zjX%%uMSP9_TN?>I!{%ju^ zcdP~<=gj`OlPln^=c1?28HswU^7=uKO3XVl=)wDU?^!KhDREfFDGyZaj&QbCdEBFs zg6))pDJN6!G&7?!&a`bEq{uM0eVKryRTKfE&A=erP&K1M-&V(uY~UIx`=wG7)nup2 zpiR~$fUWvSn(VZ@=NYM7E1WEIMb4!N(XEdO>GlZLX3(!I|E6IqgAhyS7v(RHRAovT zt>N};?R?2$=E?i30&`R+>X_4$i^sMdP_hTrFEjn%PR-H> zEUPueqQJ?{`Eo#99M%*s{q`pw5qn=F|Kk^CD3=gEpND7=v=Q<`;%d` z6LT8S2rorkv1UOV-1kbO9`k%kuj-t=7 zN511~2V5;j_8qNn|80!DLwfIGPo8xSmm@}MSntaw>(Fv1@@J?OnUKa!no9F}YfU=4 z&^`#J^t|L;C^{A=!Lg0AzdQV^m^c%slzv9jLWGmfZXRE=`ZQP0(CbI z#1FLoe!~t^sWXrQrCMSElap_KU2_ELX8UrXsc!1t=H!ho;?8Xaz+8o;(~>G2j!FwW)gJkjB|g#pn4ms&4R*)YacxoxoG_jWrRFQy`cvzXiBudrP4R@KSm$Ekle?OYj z5I$0vdC3$>P_xaTTNvTmF;XO@Jl&{CSxD`DMo-?cbAHQ9n@#Zh@Uv|}M%(K#ZJQsz z-$F6#|76|29EM$7cDwE@h^|aeFd9zHCTZ=wN&2_5@ONVSqTp=Dy06~v^t|O{4+mJg zuT%W~9#@{M5BYBYJL8%9E2ByHng=HA*mm!1m=;#N`!jU6BNE?2(D2rcEoY@fb z8)se4|MJ;Qd+SVkGeN}g{e;WWf5p6eJ=A7xjzg@_7!lCQG{;-_;cz8TRtofa5igl+ z(@$6ASoyx`Yj<9?)z5PGPd0uEMRcsh~WurWC7fx^_#C^UiVir9&$>Z@9KIo;QJ2AC}Fi8mMlwqBa}=_8|qJtl00PL|1Nt> zVIWM zMz+7wk8HJFklM>zf=Axl>7vgc81Tw59la2#wiXe5uq&HqS}UU%dRE3X?J{ji&dx>Y>3mq!kCL@N zML>laB?^ovyx%2WCtmUUc_J7XQ>qB3#^3XGVs|dz{K7e}{|zQg4IuX`qoA=|2*}XM z$<+D#Ye1$xse+#H%Q9A5mM&oB4X%Te4~qH4Ugp_93=@5FJlUb7)cJ>E)E*ezf* zTk>Qw?8+FJzopsUu8d%7rQ>s`nd!3IKk3AF+BqH`@Aw-cSev_DZDf>JzIi+ua=P1+ z9L^3>Q9t|Q71j4rn02P#zVs+Xe*1O51Kp;q5YVf=E5jE~KArg~&m`$virIeIl^3?` zKX4m!z9G`t?0M}i*rlii$>;(jRc!N=+$gb{DX&|yWBLL`DOuRxNO6|2QX`W1IWbL% z<^}uwJ?2V6{ul;_`bxw(rNLqp4({(H>JO<=+;Do#i?z8|X3&(|T8yg2Q&3W7$d3Rn zwKhWsl-+{yy^$Is$1d?aF?YO)Va>QxnUF<2Gj%2P;A5nu(I;cul+!v5v;Gike)zqH zmyf}1IOrb=$nMEx=Yn?YOX-YSr@|>-qc=h#0`k2F25&*)W`xACn%v zZ6cG<{9vUC!ntHb73zmT>f!yQremndGNqn-aw*ZCUH$SS?viBCiWi#ur(Zw~wVP zjyh7+m`330P-j`YTjiWrwHs-#N?-5ey!Y)tcgn2wd)`#BOmW$sq~0|v+%67G#3est zZhYdd$H7R2>5PD(t^U$PHu>#QR8m?rSELT^_!;A2b0T!7QkSZ2;9bPKFsxScCp!~~IMt1R^1Co6;#7lA@zcoe#2FU1x|bw{w0bDu^y}f%j#CLu*XLhobXXfW6V|(*Mzcb*7tTSZe*~MwE%SG@6<;CCW;FE#4 ztex*RPTT$UG24rbp_2t$^3yxji>7^9!aL`9{q6Zw9>0wYo|99xzbCUXDegBUDefy@ z!WLTON|l_@-@27bl^%?ycO-H?<5v5A^dKZyTST!36<1PFs&;ov;NCYS#W+AdsHQS4 zoccP!OkaFVpqin&o=;Kj`QwZnb3}}-QuHLfj_ftV zG9w2R64_xDX#`?-phU*QN8YM2Kn46!bl_h^p|bWGNLGu=rkMcUePERkYpUi*O>ayJ z3b-{8xt&G}hK5(RJK44myTxj@*{&Lu(T&=Xr9`R)mx8`}1FxJ;;*Ost=SRHgTNU$+ zv~+knf@TNGG)`i4ww++VDLaz4e>f5j2_4H`%!{LfiJU~n(VXPzkm&-E$o@gEkqJN3 zfL=9;!Szv4m^RTVqIZxhTNOM&5F@&SBs9*b&D>^2smt%UE9Zn2X>c1sCpPJ9p9rG) zG=+)OCF@q!9gu#*D`vx-sd$6h`&|K5WR3T~WP8jFBYQX^w;Wb|cO15TWz};MsL8Mb zIjzn~RgzE6`9i{mm?^LS$dar<1^5dFo8uF85u|FP@j6xFmsDBHi8y<(37>4Hju#4Q z$99jKaS_I5SUn)x;XdV1`I%~W0~f^x^oltB_3iE{jeb9T^z~m(^8`^vr1;NMibJuk zF^9X4F?qR5Ta|6luQo10?u)E6in0^>i(8#;(?X0S)oE$J0rR+Bq4bOzJ-K*TfFlIs zGq<3-^f$OdoCy%s(6uKJ0*ENoV}5T*r2PE!iL3d|NqhURslKf$wzXspR*P@*A91r?dPt1oM}L|mdTOPp1dTcM zqjDq#7L{Sye#T_6ZT;>Q>f(g;|L+BO)@5HCO&nkT$9%H4dhlXa&>bOp8dGrIUi{_=e!AEvBM269chyW$@fB+EImN z|3x<3+x0rz-ftXGqT59DkyQPF$UJC;Ws1J9D)I5*M+7Rj83f6huK8b=k4s*ANul{_ z@RX)lvLc5bNjqpAvWGg31j>9II8n6okYrK|I+uq5#A*!gPE53maHpIk;(p~@FimUX z>m+H=RZm@9*GZ1$gTOsBBB1o|);-R0Se1CTad7QT-LctCg|DUgCfsN1H4q zDIJXxxhlWjNd!QP>6`8BZY2(qz~azovf=NjkyjLIOg)GZ`211!Kn=0#HLkBMPWjPY z5*%Wr>}&|4bX!FE%r*{}?1LyCTFl$N=<{c_3BFNN5Kt>1hNmpp4bj*`o!>WyN9@I_PV46Gi?`q74 zTU7I-dV#B9MNYb0r|Q;i(0V6W&;!R{Rd3NKK;uDVFA32+L$vmn-Iw;{E_VcON2?G* z-HPf_vN&QX==z|Msg-%a%2dO<3aWV*QwX2xVFc@sJNN-5;&V_Xm@|8eHX240Ki}l2 z*l7PIcc`s3?60`TT)R|db!Gg!n#KKW80^Eg1%3rH#GIOss>wAUal0+L1=b;P%)9Mn z3=;djgX7iU$*E(3_kR)D9i!iP%k|Cgmp(5EF3XG68MQII#|`dJX;GYtdHT?scbsDu z^Zqi3ajE0_)>Xh?o6bL`Acm`_n5d`9WD{2@(bX%JkE`vf>a_yJVP2J`XD`c3m5L3O z!%(sBL;u-z9xfo|&rH1K-__qL4z5xRKQ_}92uV|!3BdD-J2TI2GT(vv-Vg`_4 z^3)xYaAM3f4oZCpfg7-wmB9qo!ow9Z17ypKk_P<(r^BI`v$NmgaB<{OXAM>%_2;kh z3|l5udA!S*e&g}djO>uM9Eee$WxXovKnyN^$-rUm5HCudh(i#srh7mU8)aD@LSXc5 zH2=nLNwpQG<%suku_FFP0&6t3f0@}SL69>sg^1yy@Q=^(=L}^Lh~w?b>Oxb^kiweq zpxb;fzoQ#dtAI-bHb2>7AE8K?qHgG)ZJjJ${Ys}e4j04&ZQS>NH5eBOh=_?WH^GZo z3a}0E`5*2g%UAi9rACe9KZd$+E&VTZ2AgkXF7w^@j4C7VjkhY~<#M*i4 zoABeRB!l-q%GE^Qx}DK`g@h&KebGNAbUhPc9#O^{jCW;@6Dlih-Z$-joM=#jVrv9{ zav4ERC-9t;!h7I9kDjbkYQ1V#@HtuCo;C0sm{=l>YzkiwtZBI-aa~shJTT6tX|I7?MfJc}qAvy9^uh>@%i#yHUSOCCJwWASJgORGs zspH02=YN7#oArBimY^PrnA+C^U0*xGZo3qZ5itd%l`x*|1r@58Ha|8_VgVcN&VL-i#J8dndNm6(JSZjj zB@B!q45nWXD0SFyCtO{Me2u)w5&ml9TcuaJ`HR`A2$xP}Kc=?MB<5J7DNQQa?FGFX zm3@@Qjf}AI^?lm96J%F6-#4Frk<*yDTUi6AF&YBA(iy{6yX3)FUP{Y@9J`8rsvuSP z{Sev9F44PuR6Cyfe_6${*JMcMO1xOR&lmWX)zvO&RU|7!oBAC61UPP;mHzEK_hm@i zlWRZvOT*Y_R7LnBG^87rA|t!}Z(sfB7mKTB=yRnPm*%!oSL^7#&|=`(*b;tho(lX$H-W8v$+O%E2~b z+i!RNe_!D9Z>Kl0RTQE&$<$7qTf))G<$$=j1iK6Z>gHF-T6O4>oM0~H%4PXxgaTc?Lb&C=`Z9- zMAemXJa2q9ejbgp$V>g%8Cn@Bvw6FM26>hVvQuchJzli{At8P>j>|Wqk}2&@VFT>CG2~3!uh6S7D)rKTpXCb?Mg)9`JvA z(pShD66i0|-6mdScfU}}@bhC;ExYmD6U*AOPC~R!#J=uFSKr|15|th{A41DsSL;K+ z+nz#wOFCI;PX5ZB$`!HlBNCbhwEg^am$W7c%b@6UG^letFt)FMQ4Ps?2xu1 z*#jboJ%YoSAoGpU zf{KACWB@5U;q$Evw;Z1-`wiU`M{=;F<$Hcb0&xYBEsr1tO7jEg?MkLh@!iVWD@Dn- zJ(iJAeUxeRcS+oSQ^Hbz{-_EK4MA8bnApSIWGX1 zw`J6Z`FEaw)fL7Uqmx=qUp!hNy5g-}yzuVRGD__=5F|wCGC>6~0PfH)l&%8ubW?xG zZ%^fvf-qTtjr+gWNR_Ajv2IEXD+pd4hi#qb40Blegn}^#_cRsWsqHvJ)>ebtx%U;VQbPfko^_JjMi8CU!X-lcbI-0Z zNb&6pJMycpMU|E3+hx87@;hUTB1{uKasH`iL4U*J8cJ^>=YoR|Bn+M3&Wcsp6sjA0lnFeF-uA2*dt~y{O`;EJK}n$FdYXT}vKal{!bHnS z#abwqK$*(p4;R2`v&HH__#|ubZ_4Sc7p<*ugc__xY?IfLJTWHIqtMJ2t~5jU#d%ft zyK^Po(Sv&C349%QyiPu!0M3WI(S{2+7Oz4`i9lE?zXiAO6GQ{kGnU2y0HUbO(OQth z2HlYj9za+l6`#Z9j%TLRpat43D0G+_813c01=&rh)z{pnrz9Q^$RDf8rH}kjQ8#F7 zHV4l&fdIM)C|XLO@C*HO1|%sF55SD^#g@~l&bWWC4cgq|8n$PUAc+JT@*PM}#8$X_ z$`yU^=J;^PJZUnq1+7aIQ`O6C>|7 zPIENEg8W8%IHhh0bMl6;Q$F&;tUiY9&teeMOPRp!@}Z+HXfXXR*(QCUW-2JFO>X!1 zZ>mHC+zodAW#Rze!P((^B97AWe=LkRL`(0N#5DJb(c)nHz*MEMM$n}^QGW(Ag!f2n zIw)M)+rD>8R8W=HEy|N?$YS{q#Qs2AX%I2eHT)ZNLw70c2k0PpjxTpJ;m=)Zq0R!? zf^iorv*}885ltpgwSo>lwE`z$d|?4jc?+FVUl-u#Vw$1;-}__2 zZLmv@gQ@E4IhIK%g7t~O`gME@dT2KFmA)$dBAt4Q8EdO)jo;~=4E~=fLz>4Ny{f3K z@j@*HR<(E;Q?R};=gYVNdN&DRXvs<{1`NSF!f2OV357f!o}wT`@-L}#d$Je{|3eOQ zFn&?P;mX2+U@eMRvPW5rm$~yBGlSn?9)o2dkeBr5Ha!-7tA(@i=B>}B!OZfHkj@p= zI>lv+n@E~C%ea+&7&l={gl$p>hnZ6Wv6GPo%bBhcROBMar6wGaPrjEMj6ayEtjxkq zaA%d-HO`XO(nO{Yz3ggaIoKo2Xh_7#?tHVMHrMsfABv&w9LehRJbp3LC^vQVV#@wk z(piAXvqPEAKgVR0*FX?w?ew6hd^J|lZ+|S*?{r4c?{r?`WY3ajdQbDM(5YNtj17#t51g=5@;27;dBGe$kokd zzx6!3hmxkf^iz!z#I3>QrR|0kgaB+GInVE-naJMN<71N6$6nHkcSVy*3Rudje>|#{ z@4pWM_Y;vgqRWgxj%W{>xnvrG0Je_-&j1r~{bb`srpnHk=HkXu*+=Dspl0YAcSRLS zd>BAO_%@6k2m}B0_|k2J4!4Yv2tiGaTo5*i2pd+c5tgE1#jztuh9yoN=r&#qb1ai| zaHHzAtMwdcz(-l75%=Jl%~Z*HkCfs{UIprch6ICVDYH$5mTFG&oE`6z|16Juu)9FKI%fhKtkm)AGdWzGrnGcrG~Z z^8$)BD7?F@y@KW^g&(beJPg!^n7*gV!x1_uoCCoBx0N&@q+(;cu9CH;P-Kwj+v*>c z1FADgx~`6)paBA782gQ94y&<$662qLJ9gJkJmz$Hm2a-9Tu~=-5}z_MI2CpAYMz1V zqx%(q_7@51eOx=!X zBpp{r?u=9iJGa-1uh|r4N|m$LY%@ak7|u&-hT5_ePJX!X7DvRCQkAYT^&KRv*c{#> z!o`S)&9g-es~jl*EE~#oC5-S>7b;Dua9zmOJl}#c6PWOcj*6_3!HAe`NnXYG-&771 z^EtQd&XF-9;XljPUv+L5YrSZ7=}h8*`k1byLb3V`V=DXfsBCL=pgI+tj8GHl@wR$7 zO?2StOVWdbDTNqo@UHQDo65vG3wma7ihRwI1}HkRUys~_JnO?f@NQYXv9L}Ld0R|E zX8>w2@9j-&Tg;oIkI!18-BPUFaWXNgzEG39`U4>qspYw_uNL!+^)wHKI$G;6lSWno zw%KX5rbP$!7PfVH+5dHuRo+*O6cvlYH5H;As1&ynTg&gkw5B@cb>vd4Jt!EEJll3L z3)*m_8Y&kk3}{MK#nXMMy}cs?$$`07_*e8GzX(dK{k`7L*D z^p3Q06VpgzA6n*fsv=e$&T7AR?Vxhxr{qmt+G0eq#=P8<;B=Rx1rO0EM**Ixo{`1n zALsGUDU|THsLu8ma?Px+|19cWUvLE8qjLPX=s&^-SDDQR*h2+oJh|_5lQ;6?YdGMDjZ=@V7dyv^0`nPb6O^%$eQy4+MxMiz z+#SXE6LN+4!!m*T2$VHjYgMZCnwZ6vgOC&|S3anozr1-yC994yQuQ50Z>c$hBp&d^ zhJ&4$K7B9&>zDRfrEGbVf%Pwq3*GMf$4sK!^htzunOdXSdk26MI#F9s+_holEb!X5NZ(>=m1D1?P zLT8}tuDmBaqYssjizGCb0e;*1NEp2h8OC6DN>#-^&BDXyKYpuom+m&xzK6G1_bP@- zicj{76ov&?hnG0nd%kDzzNGo=ihQzGNpbZ+;XVz))mvcw8uPDx1LJrok!mROgYYZm>&dV@kz*>+ zT4=qjh0FA4lF!b%@O{72^f=Y(>DmoHo}6B?qYr)&Jql`Kn6rsYZpFQGr;SYI^!R-UIT4OkMSxXGQ$Kb7 zHc0ovjIv$|<@qOd;23&3ZtHfCX^5uRQ(6fAA9f}#9?+0*=SCzR04shRgel>$C zUu?^HIG3|u6}FFwL{Tz4U296CS`2EizvVJ->L8mD_4J7$W6JIiI_|^w%OZvU{Zm|X zsydWS;C%MPuvk^#a61ETQc>{7GfmWpbw+ktW!%TM^-*Gy$WN>ZAZlyr7zKtrh{Dal zkM8lN|4Fb`je9BhC{hT$P?My(RVV=sfFspe62CjSnUtz<+sm7=uAZs^fG~G1t$MnA zhsms({bngtcYuRuHN!c1$I(cgX6g@{{A9!b%4vsF)Fq2`5{D#6@7Vfrruo)x47yQX zNyqEFq|RKq%3J|UK*eF@n;&Qz6AUU%CnL!BRXh2V8Nq%Ihr6rgpv&OZV-! zJSBB!3FPVP)4qe-#&mL>_BVU^4 zi(!@?L;h2wPW5AA@sZRqCW4Z%^@zsEw?DkcTBt%J{HbiB)Q=E&aCe*1{$_rUdg1M$ z_VM65_otRQlaXU!w8KG->*d`vS-Hw6bJAa#a*Xf#d-r!PJcHNb1w74aF;cBM`Tt?X1pLjAO)ekY zfd*4BWY2QW$V%e7w6*00tpFeJJ*t|cDzJ;2p#yYnqf?APc&iSAlnl&7`uG-nP{TxH zT~K4DKM0UL>NT@ffil}g5A#`1UMS4Nxk;0IHlo}`1Kgh&SZjxgRKwE=IH&h_Lj<$4 zzR;WBSc|})&#`ffdc87-0M@EVie6whuOGM;cQKsV&11|URTt<-=HcmB#a`rsJNyZ; zCPm#BdQ=}~+D&j=JVk2pQMAA0aoJ5sqL*R@RGOG8Dn}A#L88W=n<=h<7)4YYyDM@+ zt5Tf(o}WLTZE(4uRh{{_youg6rKM0y?}!XQFqkp{_0>ION2Z**m&a?eq~kx1m?y+6-DFp=lxShSz%@;Ow=)kYWwCJa#$ucr;ai}Dl?6nq@{;C%0O!-8V)L7Em zA(S^r;P3j1!GaS0_>X9=-phbruih-#`OH0clPFj;r|Dmjs*s^{Oup#Tkuiqoww3VB zK5tS*5bN^C465^dOMY)6YilM|{z_=5;6lY+rf*N``+99~OVvZ3m=mK&q^2OW9e|h( z)ZhDJCCROL*Ojd*UShItqr0Z?#0T!uz+`W14|->rg6Y zz%M(kj(0>^geKTXr6*KUUU!c;G_=!#|1^}vp*+^c9hw^0W58fwat;)2^Jdbb5h4IH zLv?7QpDH%GA|8kWX3xI1#}@pE2W^=aFRet@yWY0&$;c#$Pq9#J1S7!RV*Qly5mD+= z7m5PJUSt>nN#qeme6dtTp9u3;WOsf{1;~yKpyLzhvip`jXXG841-0IV@unQ?Re0M0 z!;t^|-h+brSEHaIkD9a6PA5Moc@>KFYH+-7&EPGZ<2&EeptMuc*HA7lU!~FF3vv{- zz57q>%HsUCt=u)M?ezui#m=Zcut^O}(n!FT4Y%w#G+gbO)K?T%iYZHe-Qz8B(;wn^ ztTIG|p%H_6O;o<(_*D6d{S%Hv;nzx`+CP~sLLM~wfBD}hj}YI|)kpnB_v^VGC2j#*sjD1r}TICeO_E^!4UngKzBq%uuf z|73EZSqZCx?G^I^t6;PqGQ}*4N6Dm_oN5M3LUx_I*?P&5FJwM60vlAoM$&XYj!1iiWg;7~X4kRBG@yP6F0DpVqjqqj{c9hDjNf9=t&7WEPZdDDRNUmCC% zOE$l;`7VcD)9D_Om@SzaTd#qc8Xv~B+sx-ZSx(qQFE@HVhf^#~)xN?Qg6dGV zg%3Qe!G?8zkA^P1zmqa$GR1HxH^r~04?>niKdludM@}?kF)%$7VPPjb)h3! zQwM%CUG!yU)|x?yNTGJlh^_@grqN#8lQ-8>S{Viv)3JdPZhiC6-MP=h=GSxdXM!rPCBvW(P9dQpLIZ8l+si(Cfq-iYGnQNV^&7Ru-g_I z#06AN&UU-|<$`{X$Fa5gU}LbTPk|o0-?xg?N?a8`BC%1gxJ~TYGOrUiyF~!1T;uBt>e?2j*CW zaEgO3?)WxG5xlLY^D?*nhx*&_L5Hf;*4%rLIodDvUhsa5i4^A4V|y7hYj$sePpgsC zTnmz8l-(c1zRmz0c^%0yqhhXWWdm1fL<|;L&}R_A?>M&xJkZc)kvhd#R1#`pc@*Iy z_=KEMEo&n;K6q?XIWW7Tf)LB0bt*u?EIP6rn^?=59(_F7-Rk|Hkt(Vw>LICEF6b^q z4W;W=Wrfoh>|>se0b)3z!(@{2!TXlBTr*eBoUG>)-M8EH2^y?*+hF znG}jH3uDE}p3XH_Cl0tpEq&y`roAfqIJ5~ir%{DFwQoAzJ#2p&rmUD$;bs~M(|GZa zZ=gcy{?*f;$3cq^l>#*Y{)uw`oKxw;KlXLsHRh8$uX^k%ST&X3MohKGeg4|R`lV&0 z(&zbG#sAPXAut^d)#OZpx(izDl7`@YYeTcd40#W8iUF`hPmCH#Ji|a4q^7>%F=W64 zhb|}9aF>X3f-N}1%i^<*D_(qQEa3ZvV{5zPMvQVZ(Qy24y5W9{36R+Ps-vx)L5^UT zo;+lv@|$d8q)Lnwr~lFpe?#|%GS#{7KP1xuQ+nKOdQFC8FF{8@9C7nh@b;AVmda?3 zcDOGUV}X!N*`k7KRwpj&F(v2lgtREdOaci&0BSrh11XZW+c-`xI1yw4UmcLr2zPiF z-ACSzf{H`D93kJ5ucKM?8>&-?`uraQHY=%C0Ekd!t6=-2>Mf^sb4JO)d7?Htg1Mqw zRyv;6GSw$D*bS$A-{b#=*AuBpusa*Rl^La4Jwo+HdrTfDhY{YLly;wwDoi7CV-_R> zP%xKI7>X>UUTVmZdTroi-cxsyPrgQZKdd=75)Qi++58?dLM^9iwqcR!ybCe{sq0v?y?UBw=f3>lH`!=)X5p zG^LGY2TFyyjLQY8D}V>}bC*K?`>(TE2ERyQ?Uhbx?PXkPl9g&SKW;(TzYU^3H9vnW z65faE2sD-6|C&93$_M^*OJ6!69ziZK>s;VI8cWxy(0XwuaLe{SgMgh)p}wdvwGpSD z4+^jp8ORt&muDvZHS?=g>^^(Sqxb=NzADM#S^5*tHcd<%BPwiWbWS_~5L^gg4QRVo zj!z&4l6BU#9uD^x+mcZGElE)=s{Y*+nFSIZ9f)ZAMC8d4+>WA3Z z<%;enqrC2ZM{Q;csJkiFo7G~Up3P4qz|Yc*#HJDFQ;*a`!a~lkO$WHzE02|Y8*U9r zC{$H_m*0VAyPGM?nZNwn<}c7#lBr{_P;4-VXb_Fa);s{1R$ZQB#XwbIWQh~g4BnrV z_#Fkz#mF+^v;X5Am^qMq6gglwCIw1f-7;rr1Rxl^n@I(2_bndrgxk)jjIbST;+PW6 zgpJh>Ub&3jnSRF6dyH2@JsVdCl#it|rH+RwpEi5ka%y|o8&DHs5yO=Iy*H0Dmzim) zVY#7b#+U>PCe@#LiP!f+fFJYlBpg}C9lTXZ@hIQL8Nh0BQuW;N@>YsbTc!%+^%<~< z#qS#24W_o0kzZz|FjR<3=KO49u(D*WjPaWghNO$?D3o24109JyotmAAIm5gN*M!Dn z^Tvi*G}{{Zq?0qeOPfJzpIZ`cVGP`~buO&<$h|7n4$klnv2HIJV|-@i4Kl`IJh2XI zG)uQ!SvY+Q(XR*Q$BR?KEJOme-26)G^8W7v{m;rvWC3$=2rz;=u9O!%{C_l^2TW6c zyv0j_Qc8g;tL&mOWR|TUP_{D5Mr0K%vO$&tGF$dm_K>}&0xCNIY26;G14yaAzrxHoZ=-Pp-Uj!q&3_s9LNCDplRnI@#H{v zu;Wo!l$L70+EH8g-5#xB9ourxA2DF@^vVKOny)!tY%{Pzhu2D!y50dVB+lg1#)G}f z4OC-iY1ol~eK(bP?w|f#t1%mAxSU%RkAkHetR!>)&9%qK=D0!~?0iwxnKE90p`Lwm z_WLX5&MU!rr`3W>M*8_jXSXj$dUa!EH9xxmH%)ep@Nw7e`)Yh|V3$(i)$vA1VE# zN@KxeTjJ7_NIb^C4hk;B3T+aIm~`*K6oqxZ4#f&ZnFyt4ybLoL1WeX@k1*(VU2@bJ z0u1%Bp_Yx=~%Wuc5|x~8tk zbT!VD_7&#`(FxJwe^waB(Ow1e=f6Au{q+PCtV_ybBemk3(VPI~MpsIJ{6Wldl!9x# zO@GIPl)@l)`OY-a=IKC4@E>MMhpQk8|KsoLTs7^m0=+9~QU*<_p@Q#HaLGKLjTPbO z#QXfQD2(Tl1tsAwgHs2#q zi2jH=`8B8$kn^o}J&Obx_%S50-Qo{VN%9x?$nd1%W&eQxwcro>{Yr0&#cVuA5g!5f z)$uB0y+D|l$dNcg5cv!jmJ~M5k2xW6h$%=fVhWR9W|oF}4*1Y3+?lzKdFNl0VY>38 zkO>|vglsj10zOQi$M3YMe%k<6%UhNSaTL%zI1!c%(gEAI2c;}`-W8+yNc&c8TE^15 zl1mqfmhyD8eSBpV4MXD}7$ebY!mowJIGD*gBG`awZ8XkeN*>kPY*(>{ZeL=8sPu6J z|Mrd)K;=r0SK4}p8kR93sxrUWC@+`1*K4ik@3oR;`W7hXXvi%P1yU|Ig(+z9{@gUa zZbQGRzeTNS__sq71ZRas`98+hzhRvg6jPmSXnUhwe$2hT!u^*MCeE1dNd$$1iIqi& zbTphf|1Q4ao51&5-%xTnB7$oPzb%Zm$`cvSUILao@-?8vLQo6Mwc(PlQ~u;hnZb*8 zW34yh9Q%!+D%QyZJ9Vwt@QRBM36*B`FG<~tQ)!Kk6Ij78t^ZChE$xbimEoPV-(QKP zS#qoKI%%`^3a7Ua};elCtG2Q40~$P?BEsacKpBv!b|&G$Ef zgud)i+2s0CrO!#fRQ7F)ZYT1b)^ZX_>ajK@0=#4BS^xQ5^ia`I%WdHFHFt7m8IJ@! zsuCOt>ieua<+y$6GQ4n%nz&nvmL&2N}C+u2&+@p*@R*t z0?%i8Y28wXEP%c5F^*FOXZLlOmPlmZ324nXhq9g6!XDb4(nBJ0NMIv;YRj$1ZtDzNF{xof3#bKgjGdRE7~R;rh-S>ctU9$MtzSf16I4+*VqGXy4a8_%^z_ z8)AoQ|K>MM$L0%2-$G6THMZMI$faCGy|=jnCYneS?UTR=Y;`yUS_lFz5vvX+YB4cJ z01F&rSb5TidmcR}gJ~s^#y7>|Jm)9X;Zbo;e@dwBVBd!Cz5?N#Z?$tMmQz9~ z=}bVNAds?tRk$*F1V>hT?z(R2hpapPU+=j^m2HEGOAl32MXPLof4=)lMa!i1S@m*4 zaZoTsKXS_PA4BC=IdhVsY^z-zp50Pg1F!)Ry_uO;skSm97d!Sj`R%T|EaA zvPg*);bf8BppI9MSOKD*^%ING;Zl=3w9hO|ES*)VleB9WBdZNUJ_gYMyNkl-Ry-aQ^a`_M<3WWv8+2YYjH6uN?NB}wfUHGH1hhyFqb99e z_sF?Xo<6csC1H9$*I`28FV1fLi?P6ZMxFPO72}zVS=P|S z+)I^}=A!X#4LI?cFhM7}_@UAO&qYV+XPQ;vE`2LBWIS2)f6S^Bl(XKwm}c>xM( zWeHlmIh-li1i2ZN!tRi@F;agCan^D=5$fQ$Z-%WH6A#U_V^l8{vQzGr}<>PT%VV2+KsRo%U4D= z6;#ycsgVUqH>*@^;6Q37+5%W}k)o?w_NO~A@O59nH=!%mBiG8)0q%JU=@c|>bY>z` z!JtxmETAvIZ1p>oX(>9qlrcq+s)`5AhVR6K`mBtT9y3V;3oG{`Ig@Fi$u|&TDsyEf z3Y*$1Z&C#SE&eh&NNg!VBa*)kWzh5&A5x6%vwwas^z?5W#D?(y&MM{qEv5hx9GNO} zJ@1VhKM4Of8-N6d8tc&9IZZXX5!#0Cg%0J0-{Wi4EzERKx$qJ?dQ~1C5iaO*)z#Rn z(eT>bJ-{9=vYQrBoB66q#x!-Ujd2XV3Te5@WYr*`T|?-Sa8(Q#uz> zrkL*U3nnOFCYtb4G1$uYy(}<<()`?tBXbrJW2|<6@7#d8FCV`Ej0pLe0OiM1ujc(* z4E9nPP2~J@_@T#nDi8Ehkb}`e`a+3*?H!W!Pd4oXeiV%qURYfBKR0Le{qx4D-9x5c zZ1u48nc|mF8E4d&Zl&D3JHNiVboLCq@89RKjM!=qT9KFkksDqARCAy6UtJisH2(SY zl^tV)rC=4to)=r^6g3U^bRe!vFD3xg)K=;YpG5wYQ^fv}FVB^j#!vqm-@(NS#S=Br@Wf-|mJROR)hd&*OjDO-sl!@8S`;C15Ych0=E zSCJG@(HA7F00B%GVxF4hrMbmC*%RS?Q;h!w$94iELJkSfy9tAG!inv_d? zE33+tPQ2v2L;XEwm-gk!b3M0nQj8DV;-a#u{JEpu??A^NHGV$7`pSKZw_sN1r*KL! z7Q?*(qsfB53oSuDha`TV_30eaL5dZrw_9`jyn~$;nlaS^008G@`6UpEcBr5F1Npy{ zHMxGPMfo+A0V}U_Zby~#w^C(6a6+Igeqxiokr7@uRI-GnoP9W{S>3o*Y?4JH8)yU0 zQ7QL4Bq`p1+F!UDshnuW{CMvK-utDFQt|AFGqUSjLd6Lq`LF%J=+TGcPofqlB;y(# z7b#>FB*#?iMUKX+k3)rZu3u(v$(T|1KDS8kky7=o>a=z1`T(*q8_q@H$uOt6EXx`zmK^v
    wp}iNS=I_<9}}*0j|({!tENg+O&d@}85MY@hxLTfg(+7MK`l;~$elB? zqXLMWlVuW|ZALopgZQ}aPQvs!d^w}LSkB#9DYsa4bimhADyU#VwlIV6t6#dcTI!xa zLN5{)C~;S6XruF{hujEjj-C=4Iq{hCF|Q^lq7nv8DkpZMeV%8G-KsdL(a##n9eady zRpn*LzQXw~N=tF`+mYZq!P}uOYhM`8cAAZMzVM|z-;uFHQ2;a+ty3$|RfD9AtSn7c z$dh7w8*#+s4M9=1A=Irjl|p}G!#goNo}gYE55bn6uuY{hsp|0_{jCKpqn#~bS4L}?Gm!xGb)KI8*d&n+S=4NbUMF78T9E5a5UGDSX-s_p;Io(Q427KG9i18zjP|8!AP`qS|% zSd_r5L)veob1F%g&af8QFEwXt9<1>Q>$YIVW0h^|{Fq04`F2{B(+CDBy6PUGSEzhpK?PW#e?4~F|S8fa4isX^`@Ad>os;Lr5lbHI`& zH2Q}|uZ_<_g|zQ9EMfxVm^iQrJO13)$7U=mt{iV?3n4TakcuG`rZi*yUwzqO#aB)3 z$F;F;e9p#9l35Ll0=DQvt#`^DPHJKb)YYbVP|YCPk*tSeCbq~F+|}^9BtCLVquMmF zg18TWZs)B_fiYE}#m;1A0K(xhxc+DrN7Oh#dlKT-=7cci2!g7F28n;yez%v+EzdT zfGRN|{%^%m>mfxepQAl%AV!?NkzNvE4%NBgN}*x+L1Mwl7^y{u18#(F^T}oXo5UX5 zqfW*wYhsm%?Jc)yFcH@+))V-tbV?&mxWt^%6q+LF{DO<9&a9eMq_X6tA~1dQTiFCS zYlyn{(f&=lnMp0fN>|JVb%Q}C2o2+=Q64Z+IocD;Hu2OeZ#kdcim)3Hq$^G~_jlza z_B!&w@jn&9J%8V9p#APbFC;-%OzHO*7k&AI!`i0rn?!J)v`$x!|B9dDF9WXpue)Oh z{`Hh;y<1UciToiND~rc&4=fIR(%OCrv>b>%7qtLKAPirVcqrf!-%ZeN{57@wH6J9N zWS@24wLdfTB~FZNlSSep8p1KxFb%IMp}I;cfWIl($G}PzX$ob9K6bsTYH;8%QW-=w zj>gfU^8%Qg@Nb3e{ja+MQ&LHtz4Axb=NJI80xdPRnx!D5jOs>XrX> zTat?5pB~Z(-2TX~&oHLQ3LTp`%5>bXZ zIPg^1Rc*EtUIe29h zss?*#F{w|>5$VEont6pzK|_pP+Mx1&st!f?YMN;tY6`>-uZC;YOn zU@&RWm(%SQhZAs!pVc3>LCUnm(B5q}1pkp%x%j{Qw&TR4s^!oBez&YV7~SW%Qo>72 zR?(H{D8+!3ldTyQCbdCM;BeAaR0LqU3#b_oJz5rm-DN3_zG2(1Vi0!Y#{JI2nz7Bs zM~`v~UIq?!bSiyz`8^MybzV|S{ye_pqA*r~QpL$FeYEwr|EI$iD6-*kIb9kQ9bma# zPBnY7{Us_mtF8L`7?p*F5IxyeJDl(=2iNc?I%5kNk6$q8-~ViUiq|Y+SgQC_Eo$66 zrrVUDWF!wRx@!7ts~862;oj`34&Di&CC7Plfy?5D&6eH)%#Tv599GM~)0=5w!mG!yF0%1<4Nekh zM`~O>_qbj#->lP}GFVZ}J#fbR=}cf@*SNOm+a$xOleS+lv8DT4#V;N_Gk!Cx%KIBX zuFAeRRYB%f;qi!D6&HHu*?Pp*>CF#@Vh*_t5Gl9)8?sHyado&W*UF@ceR%Z@rbr7c*7*eBZ$tS^ zjHq>4qYR3%7UzpacPwu3M|Z;+-)}&x^|6gaP!C@M6C&GHg*c3 zJFactGGG14|5fUY4yoMOV`NJ;f_Or0R6z=7%9j4a82GNwsmU@|Bkx<60DjQPC%GZc zi*2_ytE>^N7XwyVm#PA6!D>Ak{a3LoDw+2}u}DEZ@w8$xq_(+s!j=^u+<|pyYb)kz z242{xE&<=vTj9i6`ypt}Z^EwJit|ENMCflDDVO;Nyyt40O7ur+R?GI1c60f7SZOPW z=-XT}k6kPQ>aST7)%0t~RH%Oc78UUW3YzCCuko*3r$20(pY64heOURC){UDHinlTHc#Tzm*zz zd~q*9-`0BXk5Wvb4*t^OtAy5}D`pNeM$hJpHZ@ayfa(}=K%xHM3sB0uunB3Y$x;dH zjP{#2!+En7(|y=EGN6ItBe9wWTYeLf3r&GfaeNMQla`7qtWqWZoN zvxVLs_s#bouXPGsXX?0{+_>^rdbenTi$#|w-k94ZT>1Q!=da9a;(a>M?vPj~PEz)nU&gqC1ZDScS9;~`(B z<-RkhBVatKJ;GTc)1V3-#EjgK(9oM!g(j;qT8dM}Mp4Y145p**;W$GC`i9^tN}K2V z4#D?*eIUl-UOj*YY2m~C{?g47Of?wbMxTg%pM<%1SN& z(Zs}V(AIm(dD2|CaKJq-derv;7B41&w7r;i8AB{JH%{Q$LuHqM=)yg+)TVe9o?$xx zpe2ok@IQhgz#uaTS274$q!4S5DLR=9k-;9JFR1Eav`UF0%2i;5dnHoui#pr1F0b5? z8Ip^v^64-Ry?^;0{zE45y0qw$+=iC{eOl2wpF1Eig_^$!V-3wO9Okr?tGm`HX8hRP zuZ$$0GbhpPOZ3%WUkd+N`YjFC^0a-SKDn^Lwg%kOKEY$rmnNGX=4l+woCv=u!0`#2 zSzJI@K*i+wxdEa3D7nqaHq@Q1>qjOx2irr`Lo`w1)*VYM6BEc`@a%%a_YTJ4m%uPD z#AzWJp}X--=ebIbPqKzhFLq8^jdStLX?#X;;an<&Z?8BU#3M%U&$@-oR*aB?GG%*k zAI7!ltZ&v|8&oH=DCDow(L4JkKwuJp z2Zpw7Df90J3S$^pi}t^bZ@J7IleJPTcSvGLVHu*XYX^&i^_%3}Y3`f9BQC82p4FOJ z+{)97lz^xtnN?80% zJS%5e(Pf)RZ+-I^d+d5ERuDgq!DZ+S(?~EnRPZin6w+CzR9dLxgV7aX z$v8wKf%W}E*t_R9nG>`#3(w7(V>QTC&Tp%4Ff4SBW3q$VfZgT zyOc9A#Re%*5;J)%rFj2Rn*9gQ#?wWUUH3d3Z6 zRmnZzFA!Eu$Vltmhxk=!O}bV@q1d${JU@-%tVSLNWAO;P;PDX;J_)F5`^!%rcm1+% z#ka2ZOhwqZKCwPpZ+*kjoAqa-Rb%gHf(_^a`__eZkXadBUp&QsMeh)4#sij*WfXq_ zBpqHkuOcK}ah>eb&g0-)-{;ho{Qc;Euz15FB^Gc^ugM6u3blyri|&uM0WM2)MBiS_ zoPY{vyo?gkowfE+zi!_`uDUK4Py9pSh=#&iE5<=vVFxJF9SCwKfE+9h&wf2dr{TgP zjU%1(#9Z{m6J_KZ)N@YHMRto=$a_A1vxY-yqrcL;ChMeEjiO8Q(?<>>rO~fV7!fBf zY0Bhboexn5+UTdRYPwe@`OcEUl^HECWPx+;sj5sjyV1~ZNFb`d#737LC1GBx>yy`a zZ|;Fw?R@~fSYsiId3RN$XejO-^VFZxh$hD7lF)SKjj7i~Di&yu^ggwR5no_XasAA- zne`NWj*dXI^`M40$l+l3jiKWGH$#6Mk<&8^LqNoNbY2l~w;r|$qIM0*TdQf_^S~oO zDwY&Kko_U{`g8GnTft`;}Kjo3HEjs1oS?q9cV< z*brkVwQBl$!3yaatJKNWNSZwLP%O)Te-ave>n~m2DTztWfA!v(-^!(r-GCcuy{&qy zarU6%r1ZYe_pBJ7y?q1Hget*l<#Kl7Wm_PSR4C?rYo)&EzN@x~;D7ZCM%Mjy77ed+ z8bD|2*4MfY%%odeW$B7Z!olCI&9g_)86s5$5(ERpv3anJLVI$do3)D^$p;JE=vPhm z)bFIdV>OqbILK)oFK)R{x|o!)e3n}z95(m}L^K@|Fz%6Q@;68a6*{wy6rFG4Z=!Ou z?y;9UOfKBZYJ%*nmiSoQPWho>9KD9N3iVtk`p`zgmQA5u5mF!VFewp-TNcAu0T_FM z&Z-EU;LQ4Z)zIXwV7t|90)$S|Sa-a(T0>;o_MP!(Rl|+j-~A62VRX9U;|V4rCE$p5 z`Y!C?dv~&0Q@PsR?erc;+pG00p*G%Rsmfie6`o`;G6D>$3j3)+bR2Cc=vrw~h7-vz zq|ypKKO;&xR5)|5V~~?>Mexw;scg4GZmc+b%%vY679YHxj%Ac|k|Uoi`Edz@0qdqC z`f=Jz6(8S6N>=lqH4pgDwiatIT0j(BBxix|Ax0O!VY@|4{ajTPj1nBCoc012uNh2& zqtYkp;31-=Z-Q0}tClW2fL+}yL*#MCYN<=$d4-d=7``Ns;tYO6{f)_2#mqY5D_pbAn)1Vy)Qu5>e9WuVZ z-!{c(+q0TX8||7eLrcetljxffjq!Am)Az2o`;hR#zm-VXZ8G}ZK4c|OB^Osq$y6A$q>da;=RLHU;+-;-=uq1iuucBmxC@y(?RQ%_ta z@yK7rD8;QfCG0Q-#{Ic)Yu;X9kNi$u8zL&gB|V$*ze^@U5y>J$4>7kokDtk##N%z* zrqqlv(%R99B9ugQCK;oQThTB+d+1JKxT3U?BS_p@{`rS_2k1ASVYQm!D|`dRaJbBK z8N)2zX_4X)pTLTr+~p3`GeKnv#x3!08ZsWU;X$rAZ#K8O2kQOCWw@Z29IQ7%E?DJ@ zhM1XK@#}WW4JdE0O1~b4wcUA)v191 z;%OwJDH|z~Rv8Vl9Jr4;=WV&s2=lv{P=_4b z8(G&MIsmGbE~9qLy+^%Xte+U{vlb@v?hBW_L~M#)v1jdf)ZziAR8xG_95ro3XZ7f_ z84C^0R>Plwf)-~XT3khMVxf_CWBWukYp^4<5Z-e|Y>KYzOYF~3uI$^4Q==80Rfup=>?NP=e#lcz990ASw)~#t`#>eLr&_X*5kMPQRY5C_C;!Xe7a81Ycvs1s?>dWYVZRss~><*&mVwO8guXprf zPGktH4`kH$X4bKkjoYQ`T1&tmDU9rHKaPK5UuWT;27Le#_xpa~h2YcV&;C=CN)3Gdi%((penYM7!{ai(1^Eu*H(@bDiFp#eU71{p_+0e|VlOrG^&pJ0`FLJ{6XrfBKg zJ6CS0(KwmB%Bgz)kvYnsDZw;o81v4G%#z%0)?U4roHx($h z&i$(^taylW881`Rt?CBLWNo;#jHMGqjY0nQTqPdWrbDtw$sfQ^S>ENuFMj*S`x^LthieDnDeA%RnpZta<2~ndQpo`_4lXLg_?_wuVqrj1$hL;6|F5bb68P2(Nnd>`|0!X9r$VF zVCJ6xj2v6}qDGovwCP02tx`zjHvy@O``R6KGu_PT-SMNG@h%mO(6mqS*__k;&;Ji3LN<)8 z%hlipYo}IDhtuMp+o5WB^on~>vFh&N9085TiP#SkdSog%)_y6gh{u_}j0e$K4y~~- zJ^g)-A67LOzA}V%W3x-y(td1F<3wx-`8ap-O6!}<*$3~oRnV1)`E92gsOh0XuzFu7y>`)py@`Uit^i$2f9gJ1QeQm1 z6)z*y7>fPkW7`-jOC~Bmh-;ejrBr&uP=AoK@w5N@t8RPZF*~*_6dm<8>89#;iq6yZ zlk1G~o9W%V<>rHA00mhAqEoX;L`Xbkn?rm1HO%$}Ye&0kNfHOasIge#bTy`Z{( zy)@)ZjGVZ`Lf&Po0C=B4&98LGi?3=l0o#P0ic`V@mT%Nuz}|&5!5C`tw*ZW3O8k(C zIYX8rWE`-rJwtS6P310iyZj)i00o>4C53hb#zC9|9{)+qoX`E57Z3)2P(IJ>w*1=; zW6m&cCG7R}?Xy=oHcQS2D^8!D^IpA6zX!NPbeq(4Arcd|;}2>70`*JMg9Vjw{n{5I zXh#W(>q{!Mh-?{yHf4CIXKy6!>pBO>?mBsF zn!6hm8IMJ*3@a?uS-}~M8&h8|)WH$jumi{8iZw>kZAJu)0$|-yIF!4XV8s?K1cBMs zONn$91Gt`5xB(f!14AZ+nVZqRY;!^Vq(+gZq7{SLJ_D;1+X>BCz%{?&Hs-z;?e%!= z`g`-G5tfLy)aS2`4Y+k#zp_Y^i9D-51^-xGJpL2m$eIVF2S1twR1rsm0yBfpc2v*y z8+YNv-{Z$oHbuV`19J6#zE65T*P4>p*_az^Gg5qgO#cxo7sIU}7kjj<6z#VhBtni8 zTlj!E`5Rg7ICLh&>-tv&IPAD<*4H@#`3v28VSA)nTtyeV-8Dw|wQJzRcYSK8YelpQ zO`w_VU)eL+f8{!*IYVg6P+aftexLnddsoxS=gd|!0B6K+0J5<~JPUrzPDzX-Bisi^ zByHj+?BiZL9)t@UFmU6L6bMBW3+H(1!?N{FNV}DkklUG76SO!jU!SYNvhhHRPcM6QcxT8Nnzp z+{sg7p(zr9uAl+2G=+NdG4_zbT`i{~DIWSE7B}r~U%TN}c;E$w6UnRrCMFyP8Z=C- zEbu1#ZU53 zdBr6DfCoQT>Rr)W)Z{p6$7yWE=zz8e5;j2pcyhD8x!|>x?uqwu_2@+>{MaCiXF1e}vcT-;@(H+4GV)M_acz+X?ZwI(`pm`R z9&PG;7+T`pa^08t1pH5kq^G;AAkPN$F>T}(&SEtU72J1mptLEawkk!dELX_Pd-!T> z3;c^l4jS=+2E>-u5Hre4aYKd@@j=$Kwh#i#sdyKYF82b>YtV1l#E6V%nl)h1pjU5j zQoB&|DmHhi!%9%IJC&kEzX(>PFSvdv1L%_Re(Vv2I#ZdDtFjZ*+59!YR2YHt5Nuto zs)HD{aCSOY)mBaS2z$bXl;K5mY|RaN_ztC+BHM-a(*L8I7u;W)m)Mo6G7rxRpI1Q^ zn};?aev(0Mz755G-Rly#ZOhz1gVZpO%!0U*13ei6j#e_`7n*lS=Ss*A&B=x-x zEw{5T_7By_1q#BP)>|PLW1-bLox;F73TcnO$zsOwctAN(!|0WP$m1RbDzVQdker#T zW(8kv#i!qe6vpNX`1x(RbqwKVVHsSHk-l{6ZnrNi?fq}RGHyBR`sK@|1aVhVUmv`r zqAPy;=Pa+iJ?X7d&ky}S;xEm5i|U>P%l(|wSb6uPXDpJbF{UZIr75eY z4`4RWo1JH_KE3V#rvziu&?`7!y(=aRLA@$Uw27m43o>5`ml@a>1 zFr3e_aC_@`x9N7&g1p;7u;cDCiTdWI7G)Us28|o zAz4CF&b{N&k&@2gj|C6PN~RWaB-D8RkTt@9C+s}2M?(Ar6|DU<-# z8v1baDFcfA(V`h_k7atGR|55;8ZKbRt~4O{qh*p(ZvPHAAEX_0hcc$yIkchxO%f7B zuKRs|lWcfpfbv8-3r2mTNaT%Uya6>J;&?!@-CLmb1lZ)YNL9)Ru zAx*S<;!Ttk6q`wyQ+$?-pr(SUpytg)hy=^dHz5>!F94Hzw~Mb}Z$lZLO_*{TO-3z! zT%9j}ktByd-x}q$7F-(2Pas^du3atNW1x&k1F4Gk1jOVBb~c`nIcTuxy=acApqZ24b*dB)xIg)p9B15&x8Dr?d{ zvPq)rj68m~ym{!x)!INVSePO6JwPBK46&P~$ekZ0e|CClG_;#?Oyiva!beT1C$POO zXulUj`u6#u;1Z`kDeHyavxS5WJz8-R87#+4@r*B~Ue$Oqkz8kcJ zk?e|b|Cr2ibf#Tg0Rq*uex>ToxWKcDjOMK=)^wo-Z zht%s%b54wyImX%&QxegS(e2>|G~tyF5>Crl#i2qm0eA$OV!%)wx)_f4Y|~@Hj60x> z<{LiazdM_jUmQl|guwVfKm!tyDK9bEODtAF$DGQL+}S*qRN zEF;dXnt`quAOJr5^7!K9-XL!J_KV-MDGYiSk4^u0aVk;$b$s&Y+bRoWU(JL;xMs0T0azg?`pXT#HHpnt z@wm^w%8xsE>t3@gSoH|vAwIa8Ep7UKb!P_PVX#ur!bPXh(T>!S-FO+mwaUCMR?=@s zQ-Ko8U}h06@oy|QnjJO6YK*JzQcx(siCmOnWfHEGCqu@FxtAHclG0Fzry_uVb?#L{ zRDdNe6k8ceXo*CV$S5eGf#+&G9CNB~(9hT( zx}jxsqXj+U!Dl~uj!1`VPok?t$4{pQDt`{Mz={1nM>z!2)NJ6^@V=YR*;Wo|w|kQn z%3Un>7Rw*b0g@zvw?;pC+AZUfNH(6~ugeeUyv}+iS_R%X}cGh;l15t*!_P3a{J0BF*C%sDpL?c5CAh3}HENvA)As01VtyOMm#I zIE^zW13EG3CbC}}WY8$!oQ1QszuV?tkmNvnG-Vm7)>ULk{)*zu&90#laa$y$Q{8-{ zVvz>Umysgq^`k6?PS-P6Lpr7}+u+0AkG6~o=yEFh5oZ!Jh%{^JUH(1Zq8 z!OdPt$Hgh0Yl@oUFZ?sQ_pB8E9Y220CD+NcLc#=eXf%kx&$70 z+S%?d){^V)JoB2hUv}-E(V%Gkh zn+JOWBtp9TQHe_QymB!eAD=jakKZ7!kIzn&@Wuec^M~pM310Xv(K!NL86)vhSrm6b zk)|myqjo!?Y%8nBbYG^J^_$d!dF=z9!>?#Id&(^EB12{eYI$s5U$DzAt?^!k}ceY2%wZv=n=X}-vao{zd1T^)MAOLSdO zhF*B;K@Q&UbIp|A92L9|2(5wHZ)$i|ZBgHQGGV(mQ4q-i>!Vt@W9{>nT9LDN;dzYPJ|866$(SP$=rV6S> z2E>a1+B|+xrupWIdv}udS`bJ3l2zGt{uA9*S#n^ndSoYH^z~;Elghh4q;I~#lKt;} zkt?#X84bR9eMu=FsTDV#Ewdcedm>FR=0DrhW`BRZ{JnW@{9Wx8L&%re!K9XDh07Fs z{XAsT^dRqpD2Y{D zN!1`?U+L(ma^B^>jw5*@eap*Yo#3DbP5S0OH+eX)mhG=MW69yJar!LA*2Rjvcu=?( z0w!*p?#qF69a$;&)Qtd4WHc`Zs4;CakGYE$&Wl1fKiI}K>F zinmX9Hfgv!LL+LTSELQBX{(thiu(O6<0=|3VW`yZ@b=TxPERf-z*S1KIac;}_K>Hu zEe&LolN@J3wbbt8;+q^dyJ(k1h974nzagg1np#?QBmn8Bt6iGz=*Xzst_e%-_VCm< z=?ze2+8gx3JgNV3yjjQ9`d(gjg{?lkH0dY=_qOci409S5a@>z>1BJ!nxMol%*gA0Y`G!Qz$fuG(hes260FkKf zz90;@7^En;ST4F+t++P((erMUD`NXwXnXE{$(lm~;zpuaiME&nRG&U%W0P zI$>Km3d8!65LHgn6iHbzTXK4=V5|7F_p%6K*Gc(I-t2RW*R)rdBAs&~C9$1bDGJ1c z@*>XjW4zT9NK-%86od65$CQ;@-_ww*yKvWLe=FwpYn!2mbGKE*{?kpl$npBrSu5x| z@CO-EmiWkE-I|J=XXTh|R*!`M(X_iV^J+ILJjnfN7SWf4{m!I3Vbhi z7*UXF2;mEQEUbAup~$33FkdK1a7{449XXM;-1J0SEZg^bFzC)#s-r`W3#12H~pw%$cAI2|{C>{k3X5vfo`-K!>K za!&6QtP8^=frB|84gAdV({z=;IqStgBlR~AHHLVBb=lo$Dcm8JdLk?0hj>#G8$;*E z|KaH@!KZK10+T1?oO4KZlt@UL`e|@q~kpQ zb6w}W*^B4eyJ!2w_rCAXJ)pql_fv6{ry#OLD&>7&P&8HK-x<{bHKF=ogl1!`J(}h< zxd}+H+^H_i?h!skI!iFZY@EWRU!YupMhFgD8^q}@W-UPQW~$j56oji1_6kt#Kft>v zrx^i5!be~0Z^4avu982fyUYLLB}$q639|Oq?#gv^0VtE0+On8z=1QmJq)%SF6>_{5 zT_ddKlWz~lrWqx@1teR!D&ZsR{zMS$WGua49y~Cm12?uG7>$T#XLZxWDX=x90eNEs zX*0z1J2~T5F;=DrUDBvr0eUGNUd@7$XMKn@&w8l0?xz3^A-z7JU0|+-?za_z96dp4 zK3ih24b5<3Iv>bQeZIucPe#mN z|K+dQ4h`5pIxeWzX{9qa{E<3xuC=*2wsn0pFt|Oymoykjwtc00SJQ}g_6Bp)7N`9db?w=YDqZyDGCrxtth}B1 z#$0JR`j7~o?)CNB_STm|Pm3dhUqq}|Kxv#>HKWv-Db_A`NyYM&KB6s{X^j+L2V&*J z*s&}x<@YbY8WIcw{q3`ikiC(>hmVYnHT+;b;wqL3nji@jZbr}H`P)*)Mn@+U**y{- zj!tUpJ9WWUNr-&64O+*kZol|J93tHb@0=I`4)?980=Dp@S6wIGRud#>YQcDZIIK!z zCK&Yuf`i9wF|o>N??PTh2s#i%d&4LUpyHt!BK$l2(A9i>S!DJQsnDl~4n{SJbJ`=s zoKPVebcHaa8U-`0768zFT#0Uw$1H|eplBj|yc9|*0mzn~js*iH6>olD7zB;qjDrSH zvx+C|E?uT&-L0myg6@dRmprf?e}MF3PwuI^AFo#>2)8Z)j&m;?1R7}|@_XJQ&Jno+ z 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%0D%y8@)+Wmu->sPAq`6t;6@LNM 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%0DK{-4o_8s~Srp#qjk^5r)Trv>|D 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

    5Bv-(9tmmh0Nnmbi61des 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/&$U7NNWBx?YHP;K2>`;M~3aHSuIlr1FyIT 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 Date: Sun, 15 Jan 2023 22:52:17 -0500 Subject: [PATCH 4203/6505] Delete node-red-themes.png --- misc/images/node-red-themes.png | Bin 31933 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/node-red-themes.png diff --git a/misc/images/node-red-themes.png b/misc/images/node-red-themes.png deleted file mode 100644 index f7a7bdb8a2aa3ef4af5496a4e964c4d9c4344a1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31933 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 From d04d83bf4ba96110132e1eecc0eb89ea7884bccb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:52:39 -0500 Subject: [PATCH 4204/6505] Delete play_prism.png --- misc/images/play_prism.png | Bin 3691 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/play_prism.png diff --git a/misc/images/play_prism.png b/misc/images/play_prism.png deleted file mode 100644 index d97c16253300e640067c3c7f0a5924d9e363690d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3691 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 JPDHLkV1n56wjBTf From 6ed44e7d4435ee7921533b1e67d652af8348914c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:53:02 -0500 Subject: [PATCH 4205/6505] Delete pms-copy-data.png --- misc/images/pms-copy-data.png | Bin 25396 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/pms-copy-data.png diff --git a/misc/images/pms-copy-data.png b/misc/images/pms-copy-data.png deleted file mode 100644 index 073f90d7c0263475f5ab74298062edae12ce5f3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25396 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 z 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 apW{%lmJ+6mYHVKte`?CwcRnh@pZ^>7DU%lf From 9ad5a37e27eb21c0078992c3c08e37ac715efdf0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:53:17 -0500 Subject: [PATCH 4206/6505] Delete update-menu.png --- misc/images/update-menu.png | Bin 41752 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/update-menu.png diff --git a/misc/images/update-menu.png b/misc/images/update-menu.png deleted file mode 100644 index 42e65b98fe8e4dc539c13caa6d24c2e119c0afd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41752 zcmdqJ^l?5>kRPbc1wv4-GQJ&_joG4&5-% zsOR~;yzcwDuRq}ViP!5mhCS=pd+l|6)>`j9p(;wUxY%Ua_wL=pm3t%o?%q8VvwQdM zb7G<+ubk1L-y#3pcYY@;d9QScV(Z?$XZPf!CDc6(cT+JyAeqVFbUdDqSObk&Mz01A zwY0PXOtia;i>x&V8ehCpf7HEOijwt{OhpULx##11G~%lK49w?Y39&|jiTiiZYqZ9^ zyr$M|V^Z{H*P*oTt?fcRWexWhA9%@?33=^2>nCDbBh-kGk2z6Zw_%d{)5|}b%#y(& zG*fWFE_VLw*2hq8J+xmRx&P;)1uE)W5O07SC*gno8F?pbVDjIgetnMY{(VBTNF#y) z)W1d|A~JJcAK>EtYcNg}+&68~IuAN(OaB^8CE{ZYV|cg8!ZlA~N1b_K8HW`m%#yh` zO_FbIMh~*i2-Kf-EYVW(3+E#z&bJ8KlwTw~#;2KwjQ)>49vH4CP z^|{RSQ9lQCr>u3T+Hy?bV(F7LCXcOQUb?Rk;tJNP?RR^6`7@lOe!H-Ul>7agNH2p% zmrUUKezo0vl0En`_w=w-`=~k{E9)o*@*iO(98STn+}kp9*wIhJKkMx z01=u6#l@@JMP=)sX}=gn@=h)x@2>k}P-Q5mi>Yg92+pp|D1k&vDPMEBq~gHtyQ zJh_u?D&-<`#}VJ*+_YRRClcrwHrdKFZO zvhUR+jnBl9if?e(>JK^&V<~;}{A>P5N*CO^tfi-$1TeRByl)cKKZUr2`gvK)h`;QK zc-m>#w6~5`nf*m5j3LdVBL}PO3y#!APjS{CFTJtEBqBCDvhX>ZHcwL#yt`P@F%BZO z3avzbZwT^xLrV>s*iYyzc&-n7sYREwRpOdej$WlYbYS7^{7|c%)U~cSUjPaNpXu*5 zY-WWw^SLkjoRbkIkiR46GC@uEyA#Yyae{P!sl7I7ls%{%+U^gX)mN_|t(12*-sC1> z_i1n#vfrp*`La^k&wkwezV-Gj`MffG@VC>IH6LNyHy^%^JiS>&+{G*M&yN#YbW8SJ z+QNb|!+rjB$2eOQ85tcJneGmUG!ea{*Q-DX9hkjgm7v-&NG7vAJ4$Q@$Nb4`7ZIKh z;`Uq=p1AXR!z3#3TQlHDh0Cb zmF@S`&j5T|yn|g+!*ARS1UA5VGT~1QEv~=EDE-{ZOJ^5M>E?yI)-as=9NjQ=vDw2- zqeRzRzSk5WCa(-Fb7J4*jVX<3uuJ8=F8TIn>RFFbpF2aOGZGk+1stZM87)v`G zqWCH#1B%R{Y5E?^LA&Lhc-}{S46Z2p15`B(`1(;)q9Xn|VssFqq}_=kSO=KMYj?6_ zwj)vtQBs~<^y(pbm{spYniCC?iFSO$=j}Sujk)taDYqXqA?3&&23oBX*l1xtTaEIG z)zDlHq4v#C%Tp?@8WJ*G$QJ2Z^h1b3#StO|>BsAX;gXs=t|Y-`{8sk=1T?d6ZO=n1 zouQ(zeq1#Rr@4AZ3a`yfL#4!KyrR-Zt4Kv5swg1VnR$w1a9t?U(#D}z;kGW=b9pQa z17(!Rj6REa$|Is$+887+H2|C{3m5I~p$g*;0z1njibO*M)zhYs7Vn1H8MiPZZMFE1 zt#L?OxkEWZV`7xWre~{z@hG=bwbcyc39h7!$BT7%pvUEVwX;sc5*UZbd0;0PHX%dH{ehe-o5@o8+CGJH~Kx4#CNp29@~5Y8AWhx1vXNgo5$iWB`ZN+e>(;C^RUbv z{ra;!FVz6a4$aU*q3)}Gj@EH2A;`LuO#wbo{*>V`{~*WL=*{<#wJt*C6QyH_+Bz9{ zV2>fpxZzZPNaskPmi<^i7BKxy4pBKg^?^)BC6x)1WgiirbQK13-9 zBNzNjg*Kq{VfK2~oEZf@BWQr5Vzj||Lw8Q!7SC1}dC7%)ou5)z1%#XIpp_AQxCL=h#bWxDXwfL~!d`sRW~ZNX|Eab9;F3C#RUb;$d+T_wu4^KGk?9|m;YWp{wA?R_k4IkckLLI#6yhEt zg@QtG)2Y>8T7(R#Fs1|k?Bib_ig-o)%qXk)@!NpJza$ItA8XP7QVqkHmf|K~$_oftJ6!_S-zr4)gY|z298Q$Tj~_!TUvpx82>8oVq)BA| zzcon_)NK;o2g)^bjZo%7spYe=otnv4T!P*-l()c;>M#H`MOsG&abMk4wCp>l9`nwe z2cgDBded&CwN5Grd3?#lbHJ*?+Br1cLv+^H2DxI!DBUtTV;|_6Tp2`{H3(AA=yIDGCo!D zy*G-MXQ!Vml6}H;rjCL4!$2i}shKO-M!!}wJ_nvIzU=j7?rU+tgjeg>9@~od%3H9_&2K%r(wG!_Nw}T18d>C%}`1Q%bk3T1##h#0f63TE1Q9ug4{is*olsF&?Eps-c7Orb_Q?NoH-Dsf#(1OI{U7nni4vZS^sR2ishNKQ)bBn00O`wk(ZykZ zx!V(dM+?LhLA z=XOICsJrgg^fAtoAX9hB@@7PI@`QA1yFEi~77J;tDH_IbR=)Q?Fr6mAi9(ZyoY z?5gJ|7W$$bt{CgF-nGUB`lAdphZ#!w0!-V7vzqU>^?uy{yTkRazRP=< zG041preHkj?r^9WwCM5HT)=@}0L*`L27DTcp%F7^H1>(0xJDxd5^HoPaQQ^-A#jS+=}0zCmW~u~Q=Z zYc|^|B{II}u})UfAD&UlRa?ti?P`y%^nOh|HH-Y(G#)BhBgr#W$d=;7`O+4J2h7Y4 zVP;uc_Ul~9Hac)tWrO(|BuDWLobQ*c*HQBn&k6Oo8GQ5R;~SJ!&V^VHx06@u&XNkJ ze0@K4sWFXd&IQ+hTsGQ)d)z8mSn-7lT)9_ZDqfnBy2rHasK*Ggb6+_=2jgYgJZ^R; zFgyNWmT>eoOq)RSMj@gkO8#j6`%Cy8hk4}MnJOfE^QY}N#I*o+&$_r7|LX*DEC0$V zqhDL{h=9TvW+wCSUu0tUTAC5Jky%g>Z*J+mX{cSVmtPUu(;AVLdz~c zSEh(`&r6f_VThtvvD<~yjwxaF4DYgioZ!z77cw{(rf!p?r|wZzzP+gZCD=H=LG}yE zJeQ%xTHS<{p`^~{xjKI5sG-;wXP;gYV&uI+Q|ixm+;L?9nhZBerJM@WS=3_Rh+%*| z=)3c1N6kF1vILrDXyKDjLKw82iv)-VmtfS~Z=WXp+^MU2B_$^AmwISJ0=HjKIBxG` z8pW}SVWNld&9Nx$;9(_|qPE_mrbj7o`KWuE#xstQT`jd2-SQhP z!|ewKS8e0aY~8ZUtDy~g%SwV~Pg&kpU$yHNJ<8OKK6$Q%hb`{}1FS-LVs5yEr)*54 z^G_BRE8Nj|43#DzOyLa1^9Da{+};E%lbChJGhqe2QY&t9PGS4<=3pODczGD}P*JaI zYQGEh7(8^aKQBfU`elMY^7!)N<(O=)wr?aUSx8qXLmWkTxM;~t@AU2xs{MlDV3Zn9 zakE4OCG-uqtw)$;=iGH+`{is0295siw8x?V8zRZ5V^HIU3uE$HZ;sHCmZRWjRQioS z(3>wDxcoyIIkNE}sc>52`>TASbP=uDb(5^Owk*}RJ+>1Am#m%gJ3Uid19a&R6}U_z zuBS-CDns5`L?Ab5MQ4FrZsZ#-pZCK`4}})h+qLZTM3ra8jhQ&QSRM;*IQu!)fAOiQ zbp(6Vtj}DmHV};&o?Kh~;9ajLDoOeiz=@tMfi@STSM{ZJM9@vq+g;r|amqmE^G-$W ze7*EKt}CRi-Zkt~grk$6ouirp{f z^aXdcox<+1Bu@zU>wsQ@ZuR9r#NgFSs(~<>^XB(7SK;n zdx8mn_*9wG_dq4g1+PQ2wDh3a_@{2_$^`R|+O8>_(#XrF3r|;}#!_V!`8CF6e_oDA zaiEaHIHp2$JDQu;uq_%@tU4)F)AfnjQQVyVvh8G!5{j3gS*+kf)2q+pYtkR&9us}KwJTV< z#ju{KS}1koI1xOFDBg6;F^s4xVjR2X7i4TNB=0HE#-_yX6O8A-Gs#wp( zlA`N=(qb6Y=y=rYt7<;;Z_)@6 z(4$U$uMS63N8kYgfWA#JoT(Zh8i#?JOcM@^hmR32rI+Txji+zw+~}h$Rsn`TZbfpDV9)P0#49|2&B+?XZQ64m3GzBbLQm(Cd*tkfiyd@VYIQIwvN21!2%_ zFaCZpFC`tXh1p|kn|a;$t1+CMSp+%_+3EFQW4Ht?4?HG;oh5*X%p``i3l7%s)wp>( zf-Y&9UDl*hWpqHI@${F=D@kXJMEMSI1+B)Q1AReYR&k&xfl;b`!2#aOz_cz6zOV}G zs4(5M$|ohC4(yh?K%ez}s&m{ueAh+#ZXm!#bofNH*q58RUEm`vUa`MEj2jXNc*8Ku;yF(of zIeup|hrPf3fZ-%q*?M7E)yZvz7*bY{adjTyt~^n;Xl7CC^f0y1rqU#WD_)Bx>c?Uu zy=ATLfI=axPk4=ZOL_si_}=681t4J)q^AwqEF%mXlf6zZaevPJ2&2fJ%5=k-If1i0 z3;;eNyxf5HAMCi_HPOr0-k1l}!OsY9T``TD2$A78J}3ltTMZ;Lo&ElN5MSY-XU{jm zZ6eZS*THKPr@~jToo%}1$p)O~rL}5uRS&fp)DTgybRBi`Xc61Gd+MYOmEc26+MB~m z?M13X)uCjiV&-Lo&^zJu-DJc8;-Tq1)CX^ zS|Oo6WwkLh{D(w(HaKNnDvMmryptamQ3qkFU-V+*hs&NT>u{;&!VG$;=pkfYk<(hm zf8ybITg8r<3d=ANOyUPVue4Zo9q?Kd2lmU`J(L7LD9CP9Ob}R2Rb0#8=i% zEn+l1-kKHB5?1f$6Z+y@>;bhcQ%Nb=OP0o#nO=zR+aF!esY}Sj%!NZL`M$J*t&A5E zox*CxUbN55cDD@A!mEsr2q(Oc?f5usJ4L-mNDL)tfMQe04kDo*C*K_juj1 zja1+0-O=uaN+h?eR9mHISUO+$uzT|fZH#BE2stko=VtBdI2V!XQG7kI87YvS?<(67 zA_|TzpUe#3Q$qXK-L4#r8$Ez#l7j)LU#`eaDvQndh}Jhp;b4RQ?Fn#yJ;EI z5MLmmHGbXH;EF8vb9!gaExnv>@eY70x$h#r_wFRo&wd&TFxxN)VgB&s5VY08Zt8A8 zj@!^f5&v0(=Z}^WL5Y+E#qzK;ik#6HPze(RivWg%OG^LB7|1yMbCf`R3U04Lmbetm zJUGbULPX8wh(f;}0az^I@LS9`s zBw%SFK$5K7)|zyRu<&%pd!w&7i5>Ajcd!dE1CzXZZ z%O?|5@nENoN-+VBNWLZq-EpDQ7Cz)fVCz5bmHNt2b+Y-J*77=iB5f#QDqbNBbKiepAsM$(_I9w^=5rkvUX?``53gtz`ZMda@V?!1ttd6`@wglbaM>|e!yTRG-k;V?gc zaC%<8g+6>uVk1Yk5$ZvarePcxG2bp+1d8lMgEg)Bgy?@1pz)(FC^ zNoEY4lxTOECW85K>6;r*8~Cy=rgr|gQn?2f2oLarfUfEM8PArKiS6vW`BuOl%Zb6Z zbi{JySf&t~)?#7_f}X4uWA{`g(%7rsG%d>9_U(Bt_oY{5^|eN3#F-1}Os z_O|ovqmwMfl?C`Pq4!_uqshGDR5Fzie>Zd(mSmg0Ioy~OoUuDo5yVVihbFxFlDwq$0`oZE#}q!1h+ z=U&mEqb9KNX7Re=#tA$HzGfml&c%tfp(II$84yy{7Z~t3S0$11s&vo0R z9u-=hcmM}lwd$S6;{K!F`>k6LXyBTNjbz9_^zj!aLXlrZQtU%uj(-P%)=eKc(UW1VCaJR`bIgl zl9E5f-0%pkUn56$x7Fz5MU(^U5G!B&U_-2Y&KXv$lvex0H<{n|OuM!hVvZA+YV z9Nx3jPHcX;Cvua8unQ`tcj@*za+$Iat>33u6fR`o%demEzPT$uXU~vzy5;P(KTpYC zN+;>4YtOFA+Qr>aMb@hab@6HKj?vPa{f;Jw(lCyTmR6uQhWfiBDR!+`BK+X>l!fcJ zXL7{24Sf0+{}x8In^98;Zb{0pYV^eI#09(n0+&t+m$rK_`p-QNkEEhGn%||l`sq-z zZ~p}LjGxWM7>|=5+z|mX`gmxJo%A`TtVuRqD>=Tre)|!l>=>}lF<`6^Q7wEYXRk?9zy;Op4-1cDF z4Jw2(V~ZhcxSB>1pRAS}*QH6tkCld|;X6xqod8<~r*NLAUUw|IA6|w~jWQ-nDRgoI z#^gzT$@O2hoeMQSAxWN?q=iXUy*PkU9ax9v$%88MHdBT|`tAFVEPvE2L;AL#{*Kda zKWT>Zr4#wMJe7!szMZe`MTOyCCEh=1J3dfZa%Ccck`=Y#C3mvVww2DdRdHM|GpunK zEaILC;j)Vk;!o#{9i#(qBJTjOb_}&0S&*Fmm-=}U=IvJP5p?#)!^gQck&Q1r;t2#Q z%~vVGqEZ0JS&bjYrXz}rNS|mRlmBrai9@ex24SIf89D<6CJP(Bx#0>9Pox0~GoW|~ za1WT4b_)bCswHTI@Du4yO5hD@g%kVO0|aRX7?aK7A<@=LsZp75pCI#r?zDVC0|M*p zIcW4hC4B!Y`e6%cofvF!cdKky39P*_>okUZ-tA2O&L#7zOinGz_o{aS^k4szpRvvRo3f%C#vd!rYmBhtO?k@!m;c~B^nzK+#b^+hJg zK1wM*&4*|=mKK!dK>~q(dj{NpQh%ZeU}buk-$|^z?nyP_#vHpxBM+Kin1#-&H7(xU zBbFoeF|SQ$)a!&9*x<=bmurQGI2-Ja=yLGpDVW&SJ5_r98xt{KVyosVo``Qq#mLuR zyiOpet0y6^&VAz2%#csxxcQpgt!RC1&Mx5h-upkb2%jkLI+{vrj`5VFvRr30s3k?oP z+I8tsX92%xLXE7T{j3d&0Xv%yH!ti_3#$# z9iR1HL}TZq1jll$B4ug6U6SPxP{G|sGW=i#>SL3Cs_k=5Z}F1Vfk zOX8VRV>Lcmi72v86H!xA^+4fr-z2X);y)qux`wgWKcSDb&b~f%N4TsM!;MZgZlViN zJF((lX+TJfvFk)d=9D`$eP<<_IyV6AXt&;9Gn=Y9!tLN-3PVziDD=K9$f-OAma4EV z7Qf4>sIB}0pe87t^v*1rg@Gel8XD`~(L~+JJa{YZM_(Kgf~(KxpoOk_wppF;^uufZ zXNYCp0%_@0JoPB6?7a|}!X{@xvo#gUtWg3T*>+|EJCZjpwJDL!?-j1$< zjKK49>FJyC$b(5b@s#?783{&b+6#F0!T9D;;P**2rsQntL__zAUNa?fFWdT3nt!vs z@Q`1Vfo;iD9Sb0mSFh(>Mif4vcYhRG;D(hrq{}2Jn$S z686R0)pReA#dvoub0gLFN&>HqU=HQeGSwf0JkC1LRnOkM@_g>X4|uj+y+xP}!6#Gz zZN1D1TZi|0a#|)K^{07NWgJy)o?pGmpoY;IRE)%c^IA^{1xX?Z+dtT#T*FylO2353 zQ#6zB&JJxP_;F^FGH4~os%Z|W<<=VPI;M^V>yxwZ^ltwVi)}w?hZ&`H1UqBu6qY3o z5;^JMCeuzc6^(ysPK&pwaYCvuI1&k{d|qxo3M1 zcU(~??n$FwQ879NGru%7-Usbi^cP0Q3vF#B!oN$g1awPu5auiVjKUpHdTQ^@cMMi3 zGaoyeTCqhLD*q4t3e!^QFlU|2=|<(eKTH_C&oSDTWml|quaWCJ@Ze!z<5c2xnoLb^ z4niM%+CH5FedkJ+EXux80QYp?8vA#~zR{}agLrLUSL(Ts5*pHvSSr8Ee*I|Ck)iPV zH0bi!C){9L;EUpUfakeJ3A(diaQs5REOp3%=O<&HUY9d!(*0EM&3wgSiWSQ}bCkW0 z8Xu<{ogdZ{=d-s8Doas4^u|QhikYyGG1;~>g33HnKW+G3t4;{MXM0*tXT*L0rg}x? z;NW6y5dhOrFaXPOfTBDVIY^eM~hv%OOCB*`rfVy>S=@!7Wp>BI` zA}JNTZUnfitPC^Z?-(Gyq6fNlGdmy7@$=fz*)q?WI8V$FN6@*ff5a=c`1*^&vLciU z2l@=*xBM8@mj&du!>Weg=U@iSwg?P;d>6=Lvmg=YoEgY`O6TFkM3WZvnKakr4uM2E z%K5#Wdm;Dz(1y?qq1GAWQ{jWM<05ObjKJLcbq|Q!(A#9%tY4+4K!Vom<}M+7!W4QH zmsa_n?uk7A)<_lN{)f`^1Xyx0N2!an435pydYFzNjZ;uQw!g%uwg%01RirL+&IkDU zUh-dwqs)culFGDelp5AdYOeOrOGpJPb>$c`LBINEU?MO|M|O$+;2I59xQk7heB4}I*{|ky=8&cgAL|9%Kr$Dfb7ty zN&`M~kk0rFLYH=i({7=eEjs;NXBzyOo%}Z@A}c`ucd5a z_TN;}`d4TWgsS{g}^zeRLtG~~EQT)4muOzjKiSOn~ADM>Ehn#+9 zeihX=PAhZ0;lgT2AVc76Df>whxLQLLqWEzqKoG|d$D)+}GkrPTHBv^veQ#WpeViG~AD-^g?#9{)qPxHQ9QqI+`)&(Wvof!UvCYD-;~&Q^#PA{+nMz?Tfhuv+pOTc?6scfQlbLt-CViw+P`Lk8_ znb)f2RY8Pjyy&)C+9=%t$T$P@^1vQ;(`=iqbc4qCorc0t5II&-w529iq(NoWh z7A1I3@QxtmD6a4gsE<&KRlSJtJF_ka03)qQ>l0##*eqwAg~$w75MG*6oc5>Q!77NN zpbwIZ7WJSM5hSDXmj%R<`4z=NW%WZW_4`9wmr6)5}FGEpZo5m&*xN;SXm4~*CX{%9YK2j zJXRZk+)a`-mWV+(K^QmvS;$Y8I{Y9dVzzi$UZRns1SYMw&j&R?1%5#sZ8{h1{b* z3c=dMzU*tFRZd=L)qUia{8XDPm~c&E^hJpjdSjM^-0HINrz;|}-x9JXU!_1vSw4bE z5b#r;iVj9#7@Db8iha4|Qg9WQ@$N1yOu7`0XEVBU%81>iZE3!FtU~?*RxrIKL0PlL zj3))`WZ_!99dBmxo<|#&Q%XgjXfadGdRx}|X!Ra*^Ry6Y6rPlYC=*P@tzke*3fi>O ztRwoTy{_$qN*2VZ@M5X{*0?OyxF**4OrP|cZ|;`prW7^1+37D`IsBoRg$<#W7Pt6VNOvDSc%A)QwcJbLK|;e{iw zk`-9*U(f6It@ajOy43H`LUBkJU!8f0!ejxbmks&&z^qBBp&b@`Qq%b3ZxOBFqy_-d zg$jSUs96HoLW8zvqFE!tfaA^4%ttHVq(;)#-6yt0XLd+uL;2qT3ThFi;T)yJd@aMi zR?^x+vO7;>TVuDk=7`L--t*u^7X|CYoKAYVq_Vs`5y?X4&YOmVy%0+=FJ_rjdo#W# zsx1|v+>y6=$~@i&MrSmy^(bSE)=o{EU2>?-=RNv^f!)(L<#cLkid<`nb0M5;=*gzT zg$60pV>|=bm3HJh|3NO;G?&XpkdL~&@jPaze2JvlmHV`t$T>G&{O+neFGWZ3rT;v# zO>lh3lnYkTljg4$U7G?kx*GIOtiv63Ym_lxejT3%<|$NXPJY_BUtsKCh{ zx^>xpYj!l_n5Y^4PFkfZr*@rpoKE%SKyvIM-`W3(L)ceA{T5U!z+vNhtXTsSxhS=9 zY>=#GoQAUaLh^|(ofK}(tbO+49rAvmTu0vucWDWa7I!-G)Ki_BW$0&gN^B!2hu(1S z-V_$|)JB6HE3{0DqrmbGXJRA(vxF8 zK{3Zkc*4P?jBeEG50;^`z?6Pi<}}r@IH6aLHjq6%oWNDTmsq)jN=u8==Pk0M{-phQ z=RmOL7bL_==0CdJFCFmyoa+4xpEt#}dWF~LMLt1b1xi_RWdugGKH&?$ZD1#MC^xUG zjk$mghrq?nk^Kn=-P>A0vG%Z?E>ibMINK-(oDEO8d|lI#IjOx&{CxuV%WjxG42dB7 zx%=^G+i7SYuy`N)CiN-57qz?0Dt1D<&^yQWy?Qy=b?tM%eqIjiCo$JTBil~F=puol zNwa4WqHa%FF}gGu(Aw{D+x_$46lf{tEg-|}pxgM&jlhh{VxDH`ijv@^9-43Z13>e) zpJR_L?VU$nm#=-511G2CPLw)|`M!{msUjucf4Y$zYPrzB!eX;FKf1o)LVvNxaN(^V zwv~P324TW(uip83!Z$z9QFaj65tTk}^Pbl8ft%uRb&xm-4?qFfAskbMAv0l_>FcF= zam9chL&ZV?j<7OE(k5wamo(kWBy3Aj(|11%CKJ|uko1tLQZTNYLbOHL`O0$3^*bC< zDkMH$&R)&uCc+|DrE%Dj|CB!&nK(af3Li8~CEdNH1~|O+0oN`$RLI(bbdO7GSzFOv z8VkQYCgCtjrM!U$Lx_#ni!2wY3B1|$ublE%UY1gHuCeL0sv*gXxC@CDA(dYRh&B`2 z|404U6j?vkFJ5%j6IgpBuwn&>rc{>%ZGkH#d@>ZM5ju%$prB-^6w?V#<)s&wn*eWL z^<$>osFT)l{sn%e{?-=>4$j1W1OBIXPtK*2q}!>zo;)hwA9Ab}c;4QGI7X8kd%{&K z%+=mp#?uU}L!hOwKu$OZQlZLTdo8XZt$hXcpSdS=e8vQj>$E=hl_?G&+VjQyh3GQZ zrQ^AZ;r^7=2R%vy9`ETwpOis7rGxdoi5mglP6&C|)L{hOSnzdgrPeefk_u2f>Z@Y9 zOV|j9arESgR+KBiutk;+W1u!jdaKz{kJnkOzkIZj%T0)G30IAwS*(qBT=m6O@ znoa+f;U)IAnL~J=w>F|;4@=H)Pj3(kFcWxOLamWiws6NW95R_+346 zc`m()2+XYQS?mF59B0~XH-dKQI3z&*o_&+5?KkD_n;Pv3S{lRy^v)FwR)bA5S*K%{ zx!7PY;XTi#JUj(1g!vnekAmsf)E@Cji|Qj-V0J!G*ZS`P6w$I78f;ngier*M{}w`DI9ygJ=62vodIJ zCOd$HLwgA;0m+A~<`flOcxndUqH7)W(JpYpqV?J1>`%)d`z9>n`e8bP}2u7Cy? z*LK$5*(0;@Hdn8Jpo1BK>nCV0ZSjBxT75qZk-c>cfu%F~9sppCJ~Ui8i(8XLJ@F6l zVjEZYVU{rFVQWU%HX7L60=~oIf$%4)S~%#+==9}X zGSjumZHgq56wdpxq~->C7hmP2?1S5(9i6U^%r2?!+g4wn6rFU0VT)EbF>YaT+@8b5 zuOwd?X7I!FlNqnC=3n-gd~yE-8$I1g>Up2+3WTy_gK-koCrSMbJg&QB?irkRioG({Q>r6Pd zpRE|IIwSN=zhv5yJYMZ+7@kr2Y#8974MST9eM|D|MPb|9ZHL@UiA&u$+w2hR+ct>7 z@!IMudC*{r$_0@{1+_EpRn`GMSn^D|q(U<5EzJa{VrNjKe&$fW!&mIh*$6F3_!mf13xd}QeHEk@nqB{mXwf=Gr+MH9=m!zJ^sjy zrHtAfBpE9~8APNt`@Ok{^|?%9kE_l%YOzv5_O+ps#)?I)A3qb3B;r5R&i4~1z8d{t z`EQz=@A6F6d@%d1$a`D#Mb@mDU{!Y0knL@Vt(+e!{IOU0_kx&nUAH{K(=#` z*8bgpa?j`ftjz?b7Lem$UOmCr$v%WH0SrA;EQQTob1ipj?dQ~&G@pql!z#A?v6Lg; zA_0^Q(_4<0wt;$gJnggY*P(ZcngM%CZ;yKQp9Ci#DFe2vf3C~Yd0fsg`(8r$T{}g8 zR*ODsXSprB+`E3bv-cBmlrBoECIu>~QJgy#@evan#4ftVS{#!lxs);N=}GoePIPi1 zdg8Nkh7|X4#{ZH*6WjfB8lalFzD3r>OF$TsO$8d(lzdS-8XJF^F0xU}WK$lJ&T?iF z#mp_J#AUEw_$as3ez-t|l2Ln^gKL3WfA9uy&{2qRclt&xK6o%f=u6s{^F@h2SSIvN z$W_Rv+P=sg!n-p0WxEXQ8IcMtFzR?USmXET{ay3JR&*MTc;0npNY+)@jmo{{SW+SB zXI!(5rUAVCQHNH3ew4_5us*=ly+X&exw+1eIHIL7%rl5R(lsGGpBHWwzAY2V{re^8 zFjNDi$wN*qi+?e)%P=f}^-^B-$vTMAQ*}86lcI^5q7s8*rsjr)YXkC$+73j?KxmdU0=0B}fz?0Wa6-?VcqUJDJkJ7aL+&Mbxu0e4=m8kvp` zk)B>;&o|09MqJl3f${^3}fCWh#E6%#E!zhVV1%5=MDKv!Yl zzFhx-X*IG3r7`hijLCjsJNZKJD}Pca5@)j@uEV_C&sBi(1Mb%Xd(87V3NE%kC0wbY}h( z-bh#yUtaIazHPe8&Ifcg0c($wvAH-F6Q+OWh1=j{(A_4|i3}sJ*8Q;f=F) z_lTc82;Y;Ba9SVRCi4$|G0Z5V!-V-?%+lg;ecW5W%kwz4r!2)<*>c-{b(Wn3=EscXj_9)!acb4@FB@9TF1EDD&59Rjk!`pl$@}X~JZ04`(qo*Z!3^=idi`*nTlms{a=w)i|gjdnb<+DyN)F=-atetTiv zZuAZNnLEQhTTg~hHZCUqF9+4hC(0U z{I60-dG%vPc1RK*?R1Io7FOA}&1!}MRoc(+dcuj@s}Aq^?^wte_%o+*F^8VVH50Eg zap4I=4oi0JTm6faWY8if=-O~@Y#GOCYeQ>WZ+d&GavMW>{G#EwaGW)Elp+3gD&d|@ zgjErZAxS!Zu0-o~Rf~axhz&Rs5g63tz4x7+Qta5F-acPEJ-q6T$|ljl_btx7@W#{e zXzOgTD{OJ$f|mo=-2euuv`=#BaliBV8^b-yUkxY!9>xFpT*N=L6s8ga16iSF-_)vF zzhTx^(Kxnm%-c1dSL4G*7blr;+Jn_pY%<+*7u^ElY3e=wvPiueB>dfa@UFw$K|Yj- zkQQghBYtFZ-@Zw4IjPDxy{fW|xUg>clh*e#{W8h@Dv4vDOGN`wjgzzvQ?e9P7d(&F zOXbB*GGgip*Ekr&FPBgd$dX+S56WIwu*uq%ZlOAgEZk`3qqqd=l9c+$ltgY-E!~+f za};$-G_`-xYeVDjNT#0jHXj#qL9S2gQS1HPe;!mJ!{vhe>$B+=j6^wV0_(5Q1fBn~ z0JCx1cehq>7k1a@Jsiq!!(*4e>B-~7A554EcNzoR+c)C>%`lKD-Jdt-mGDkWea!S?fDopM9m&(EtTeF%=lH}lcZr@*OXE62^A+V zeqg*;-9XtajI8>5i<74TpHis;+Q&Xm{slFa&He*5@%ImOujl7%K8IAR##QQ&?_c(| zCC7M+eM$>lOZHD2KY%njbnoeW)uZOKeoHV>cN*Yli213^pNb#ZtcOw9j(Zolsi!JV zh6r;E4$ZfP;Dm5w&p7Ik4<>a8%672pbsqJ%!xlT|mD>~et5zCs-X@5WfYTp@?A`Z* zl2f<2p10ZiGfd}{<-2CWa7rR~hJtD|ahmg=wjvmRNhah8-4B0Se%eWx|MRH`Q*W*i zA=Ou<0)(3SLnJ(UwTEa!$1Atw*F`uYuiyNKu;P~bvfMN3SI!YPsgE`!hCNe^BYS=# zYKEi=Ekh*Al8yf*oJen)5p?%sQ|kiK7&-+J!O+$t{uiEIR1|SOZyKAuu6MD`Zyw-n z#hrfNqS?vpeUmvghW}~d!Ey_eZ^A*6^HQcUSoS%Q9g=?HUpa*xiUw9~_=|*Mw-nY- zQSjn7ke6Kq=3G1ScE+pn+1GF(>r)6InQzLD{U{Xt(B2#K7Wk1t-mh3Z*(^_bX{M+% z=r$Aj^x)dNet&a+~wYEj8{=@%>wlkHGXkvBQp>GN;Mcb{0*YXATq7clh6_KU^Db{NGb8 zK!3%tfB$r6KRoijlo90NaPGpX_M+Z*PE+5J9)S7~-er5L7VRUgv@E%Nt za4z}p3Jm?mtQw$q-m6{~lc;yo4}94U=pG^O2%aRVhqDw`*B6) z+g_7YCqc#&-fcXATX}JkBCt*An~s><<(_uVBUg)7(G#Jkcp~_8A2oi@7`s$tQ8c5o zErXTq>Jh9pS+nC{b}8%r0R*U{T5D-7aP@PStocmeZ!Uf@u4b~P?49-Z=seaNf0r3z zPQeTR48D$XQ<~({#v)PGz4~Iye;iWx7Z#+6sTu!ix$TRC%2%m$=);c~X(1totoSv2 zaRofa!-RJ|4i|>LQ%*xrU*Q?l*K_;!A1|L<-Jwh!yCC35%xdO_&wyGi1>IgTShcLP z7;ZJAW_A3vp28F32Mg~>&hGUY{GO=N$1e+FdLdd_F-{Ry4@|z014@ro)lC zKzrD*pbKVH10ekg{FMXp9#P1)bO;8!%i8qJKR`4-SxDdRneP7JY3-GYf*~Klde74& zt?}{IJO=HH3%2@!cm+xl)pg{LT5zfgT#rlnzz?zeFEg*6uv{5Va0W6dCw6&3lPlx4 z?E88B!=3M*AdeAmNM_mWL@vjLFRzMmt~raNQkzwUBj*>H-~6|^*=$5xQ!?-(+jWy) zezg8ibBgt`TPN_!q%JjWa>)E}DBxxkHWgV8IzXPdg82=doVZuQ(LWXx` zoon{;D+qEN^ESc#pD}iL{T^_&cVANK zZsSM|VhtO3p}zOnh0q>6mA^$u&V_Po>el8VJM;Wd7MH5{^T-+(6oaM`WlIT7hb zg_Jj^RfI`!vmsxwd1KPZkch*t=28R1dK|29HlIraeSrUwaCtb7%RzVl2W>UK4z`d9*EYurE73V$+1B??gs1IRWiu zR>vOH@@;wNnkB7cr?*y$i^Un_-OuAD%4(DD{z05(Eh;=5;yH?cwNGRRXDJd!4 zjYD@g36I{m9lX9^!GJud!Y5CgnxY z8irrMP+(D-D0$yAe(xM+Bj>A50F;N@_9;C&S!ret#_#FK=^(ma!~9@6e>18hR*D{I zu#~b6{Qzw~WK^4HkKVZ7hz?MF)fJ%yzc;I(mnjI3!c02aM+SDE0^eppSI(cFXXcOl zC*kdrz26*OU`2S^(^Mmu$LpSwUl8uwD_w$(%G(ZdPf(Wb-lcT-e8q^N=Z!krw$tW* z#>z(hN@VX!{p&tGQld9UGQxCAk|KM#_1^CjJnK_hkWXTq?u3?Nj~1fr=8Szj>97MO z5BKz0vnuzb!>J`EF#07z*lO_r)%~3eRFKZGL|vxSK;gJS1o0V!qY2C-2k3N{)oPeU z^}Z^TGPLWkOIvW>IY4~foXR(l*q=uCQ;$a{5TXf*zwH{nEsCnGJms`oRBZd2agyvi z*xk|G(ROg>d@)Y2?M~1=w-BfKvJrNF2c%`F+J`tVyf9u>GcEvNa!r~5kCZ+~g5$);__~`F%Dt5^kLm$# zXD)WEEQu^8O$g*Lg!1te*ml?eyn7^tiP|5hk#O)jyJ9oD-anC+E&|^f%uTXXP&@6R z;^d3fs$HGm4N_ScKi6-^C>U*3a36dNBhV-Lv8J*8i&WUn8@>Jeuvwc0{^7*atVX6|Bq(iZkcwN$@x`pPMC(X;eG<~^)T~zx_&+Xw*GF4cH|Bk(yy0k zZ37DkuWkw9YH}~&yPS7!^$;GQb3bR|J}gJ%FLYW}!7&@ae4v0#4GEyh>KpPMb^fY2 zNDcHeY{W*T{rvc*62t>q0Qv6abYNSH4F<|wp0nyR-51DvpVwmAy~?ET+JpncP2ONt zazg?@`vw9Jh$YC|n(I4hL%YUIFM|)dXPwf+a;8*7U@|9lZ|`Ev!cFJg&)cZ zd(QNm=~qI_9+}FKZgf+zijg$*0OjrHKhBZkPC5g*A+=oiIh;qfaOIHq?!>Md!-2*s z=>=1|w+`v$4!87OBT!JVrzu2LhDZt%1aAq853>d=4lOagZyZnCEW4e5dv+O`d2k9$ zLy{jiD=)J;nKH_%)hv={ZRQA~N!8h;C_Z}o_OvDx6&`; zUm^b>QRVwuMJF*dj7FI(7~yfO=T3JyE0$)IeY|$(3|XY~WPjnMn?)q79!3uyMWXAT zf`O{=#{dr{%q5Ij`&!L&+|8I^+54S7v&(=ZlHR+;QD&nMU}nV zFc8QaZqW;9OMq{JYlfqLCh~w`pn{QP3HLE(b2;PvmyhH&A>Z`_Jf2ju$vYner(rBD zUwHXv4+z_^xQdpd_YKo`L|@Tn`|sU`U@$OmT$53s^OYjpD=2awv1TGvNDOh8!JI8W zbN>u(JL7V%>8ymXUvXy+k1Yk%mb;ws{hEdO*6-Cg5ZK?a8&=)lqW$E0N|1xg6#!Vz zx{>#ff9;@ZN|W_C`@qJ2hL^_p)Fy1(?89aZ`o|{(>(-w$2a;S9&0l{SlzbU@u>FsW zmUQE;vd5v1i4fVM-uT8fb_ebiY#Mrjdq^ldFcI25@=se$1kHM7`_aTU%rPS`ISK%DOv=Uy-O3Tx1m&{eXqOi!=>6cMieANA!jLer$R;Q0&|w65|ZZ(-(%#fuh5%YPBV`kXbf|o5M4p5mOU9% zJUHmDkSi7?Hqrb(_=FAVBN-ULB#-cbRg-0l69PCMYeE-K3Zscd9>qj?ZnRNvo=#s< zMD{Tjeh!M9p*vKMs(xC|=7JtH?80E?4Rk8Hy&?E<+1cmE$)u#gm1V`w&BzuS!A;C# zOWz&#lU((1ilOh8%fA=85!dJFq&^ZS^4=DPYx5l=` zcF-`SP5@ELZvG5}n&rq)Ub(AL@prOHSxGaTL0F-P--y0N^>xoWY&jYZaKP&vA$lZ-3$ys!8QWz-&XKMUk;7S9ixSK3cd zZ=JMFl+;0&cRvbHf*eBHO8QnVSdb@q*&}T;)3h@bz=$X%HnNJ*ak zLenNW@iezgZflbNFyL8=d@>`g;@c>ZGKH9=pLq<5dFYZnV!X(igNzI)s29&%F!)U& zIk)r`M44YpT5upQyl}o=t_m3FEW-}qf528c=zjrdM$)Tjg~xhp`x$!#T0-)gry%w^ zo+F>vpWiGyRKL{Sg-W^5SfI}_BH)u0>2>K$ns+S@%PY}I=uoI@a)SF3wKbmp8A|C1 zi&y@Uc4ZWhpC7tnjiF6cWuu^2GIw8b?y!-@4MKiuKOO)jjGn5@S+$^HK)umX@k87M z*MHrGUoE(T*KlQz`Y-oLeFJ6W0~bCrrEzhdnGoDD@arHcCiup%`m${}e-#{OUaFw! zx*WsC1?0->OUFsc_7UfxQ!-%dqLfO>27ap|3798=25oVY*dRl{siMVJ0>ui8^iueS&-W*9 zp5nE_1`1GQej^u$x^$3*foKx-l;F+F>`94j+CP`-bG9w1Xv3`|MDt0K7Ai6|^rWQ< zQ9~b3iI`s2Dx3bskT|QNT1J|#km+w}3lR2%dbUUr_^e=ibz|@hpytHp!)KDZDs#$t zM;qJk?GAL0jDBIU1UL2#4%591RaR>5OuP?>5Fwr$dA*gZ0~G)uH6aWZS8PxV*9?RG z8&=#%8S+|d*f+nLL)kVQ<AMR?R#YimpUt3Uj=wyaq8fEq@%eCAw;&_1b zIc>q-7sTqgj8y77v+4^&1Nq3%)r~&wh*ss!NG5;sQ|4KfBXeC}+#*L+GT+_+ptqI4yxJlco+8bZ2*;i$im4R$v$6(%tZ?;Ww&!4(R@snuhd1+ z!3alhvEb!@&8(H=h!40?1b$G^Zgd6gtbY?pniY;${|=8pyq)uT#Q6ne9Ej?UAMdIW2@2Vz53Sal^0M&mJ1xAUbFZqIbh1!G zQvLLCd{%*vDdfBee}mRBIm|I&EG8deQDTFgj#_q)^DNFBeaCsDOiBY1P^i#)!mBHu zyziXMoapXKsP66HlI;1^H-oAqq4Vo(h6^q@+^2TanQy#==J3rh+hBI!elcvMlKd7& zY@oV?m|<47aw6F?a_l!BgIBl$KdgHzxJl{};RQyViR%`mVXvF+aJaLck#1=0BsO!( zSTE;dSD(%?yoFF9#!-=Z5XUu;=>f>2{5#8eYcgY)AygE2i{nAm(O6KQaT)fF^Nq?k zl;-XBBLz|(rzlY8u1}4e8``jrDC&}YPWN9O>=`*C}U4jlR>HO=lCbh*Jc}hsakqzM9 zji#1!9Qvk8p{`}FjPq>`+1nBcxyIJN@uF2%v{b?8-8;o%8=Jttv9C~my?;)KE3~0V zM@8l^u@vSG`4shp0h;@t>QFI*^@%740%C=8pgOjjv-`ei6Tb@;+Vev>JMZcV=p=Tg z;)@@cZ|Irj6M5&a&5 zu~A!V^wgnTRb&4ZBT$E?^2-JOIHy9|aM<-}QNmwl0)W{a ze_IlrDV~}Z-iVRKPyh5ePuzI!Q(9TBLCk>IzuTJ`YG~VHRM|PTyLDn;sEo-^T#)Kf zF`lBa`8>`OILC(Bg=qHY6k#GDsW{a$GGW!JQ)v|TMBZ++^Ix|p%=eJexI*_+&wn>4 z44oCHw+`N!#=6Z`KL(r0Z;R-oy06<1iG2UVkm%+{uST;bA+4b=@Y$Gi#L2Z4t%l(4X0lg$Y4CD~XZv@3z zYaSE0CcREU@UE!x`a$@tJZD&HJ9bhrn|nKvKIQ{xs6Id*b~djwr%-qO@pfJr&Om{( zLIaI@y32g`MAmQfMdv>gukOywgD^=41XZBK8+J*HPk3TkNm&j6{j?7KGPL^IP%4i< z)d<4A!H-*nanYTr+RR;@Z<=%oSeTUa9!MsM^YXe)|YwMs!EXux$)8eXOPllS{L^E(kc*_>Xj;;Fv_ob@8 z=1ew2=*PB&?lTz`K8(}(<0`85du00iH$6XOimIYifB4$s?tOKI?Lpn5uws{v;^>-1 zwl0ind&RB&Pl%WX|1;@eW}N3S3!Yz-&&Vt5tP6iFm0#f9FgZhN?hkzfptIO(%s`>e z;swW9?mG5Yb@;Emo~B^%u}O-pv5gbU@WOXn{q&tT1YeiS{8z?NQ_zdqZK&_^ASKfr z6>9z)@M1g&X_b93ID0ew`O>4Ug4pLL+(XjAWvm&T_N#9OgQcq~?*jCFf3N_|Ld%zi zeqHpJ!={%Ned_8))i4d_-gA{z_#24i74;SB$r*!sYX7I4CNDwkU~SUm_2xcvtplR1 zHB%*(cVU$)-|X9xlQz?vtMnM~hnQSsRO+FoKWI2nqWTfkPkDDGCD)D1p}$LAB#(MN zR^1s@*K06p90(=b51>qE|LpX`__Nck4l+kJs|sy@G36^8rIgEGGSMi%jvb*Xx0Qdh zc)MjXzte>M4;f5gibUQGG{f$VJL22&W~820<*W3jaw`S0?NOw>-IX{%TwwNER$P4{ zr?zG`jnt{Lad=xzs1rxYWj%K)Y20$eTv76=W>EZOMCDkrlptY(Q4fK>eQ6~i-1_5( z6N@Dap9fyBLvd%MDOEBj|6pSIt@EmshHD~sDoKpNmH5mNKw5--1eN%ZIDbPQN4B9c zRA}?cTjslz&Ry0P212SY)DU*Hd+?6_;Y|-T@@VrBZ3ls6%dwptD!{W$EaS8o7Ux(7 zF>BXGRnK%hUua1YR6xxgI@%GCtq5cmpk^-&M!T^WC4=4~g)xajilDu+rE z4r}{R=bM%LC;tt#2zMi^TV-sO;oy)GKD2NfNK2 zan5t;aR$G`mN*8_o-BiuJ))wMPWr)RX{CQ>A_U>&LmtA)Z)X`@d5~vqk*M{w z_z~zy16Tu=o0?Yw)gje3PyRR14;9s*Lm>#u&d=RIy{gE>x5?)wDTUyw=kvq|jK{d9 zR%AluMb5nq_!nMJ@ioJYHUVPEVtuGveCu%t#6JHr%w?RP?b|yCZmAMGOW{q3fBU4M zrY|l#G}zc*%I0d~VJJUi11+li^>csU( z^Z6EU*bafRWljpdETF*qF4P32+S7GBd37~A z!tHCtlP&oGgX+<>M*^8jW0UqCB*> zp2EatPtP7rEwIa|2n+uVTMvJx_`U_3inhbgsDT0!g#|DDHH?bY80HxQLWk4)4j2>) z9;p|wSPHAy2~;uf`}kIT+kWk&Cod%Lq%6R?B#sTQwSrV!GfvgyF1fbSir8Wr&^}z% zwwm50&30p}|AJ%5F%9fDGcmk-Ko{KCTLC}+^^DYkyA>_@q1Yi9n7!fLa0-_7eyjW4 z@cPGi1@2pA2PDp$ip{WXgnju-C311W$GZ*5lbX!erQ=$X9sO{D4@4uI-dvMjI~+Os z7mB+Q3$j`AJ87XZ5Y23>6CBg8^)E(@46scuc>-{d{N^Oy8vdLse9MkEM8~Nwk9Fb8 zG~gwO_l;d`{Aja&;cf9kKLfGqjZAJtD2;M!q_S^eIC>~sGZXu9 z{rL~q-^(blq||t+NGR4h7IMilrn@YAxQ!)k7fX_WZ<0@P+|6$czWwt`M=0mb| z@tAYkjSRp_!EeU~on8=EF^{b+Hv)QXBCq*yeyC;dcT>Ym#t8^JO2ix3Ko` zWG9gNc>GkX`W9LI7-jwe^I_3Eq)@`U#Ed8`cTBS1$oXwzq=D|(XcjqE=nZdK6PLqH z3|z_itxX9jF)p{uF0;~itKMO?LA9DS2*ITi$>+%I@LCn-COd-wAqH z1~jceB04IMj0{Wu`Wc(#Yi+0rY!PO&6h`odvyMGp8r~QYhU6AjyHkDJ?)%sGPG-Vj ze2oBj2Eu(-ae_dt10?j4yYaAgwd(=1kAoLXucR*w$5i&ZheKcx%10_pN|5rS?9I`a zXC-yG8@i*;aROFqRwp>d4_A9eR|>f=^2yv$ExGUO$$H_oo30AZE~AAG-rhn-n9nK->!!>{Lw znq#$=g{s@OdCVkY$tb4Osr?+)7Pls6vVlTWG(FwA$(^#_Oa@U@cbMZj(-zFg7|ymz z#!4Maec1M%*>@K9gBbr(hwgyj*Yjf(5$! z+|j%Z7Or`B3Tq+QVl|s;GPJV5HqKoqwoK|=8GV=4QGyi?fc&MyDnkb9Q_Xw^ z%}{?W6-y3n*5OZ(G4bLfCb-Oj5ROXxDXHHJeKZBVEqf~>(O)>S>3&Vuv%?}4a^elawT zn1rF@HpAVxCUn+mEXsB>l2qs#jc6<_TqE8uDm-$=CU6BYb!R~D9qDu!Jz`7Rl5)~B zCidVOE}r9i75bFC!tuV%D~Nov{9tcid%I_Kfrl;)jjyIJ9sEL7ayuDoICj!-m(cU) z3){Va@r4O;vKdh9iFuX41pHaU)8c6IzFZsgTStK37*O|{>MV_cQ?p<1FSwL(gisx{ zSG*_#cZ640o* z5jzWboK#Up^!1dhdgyCWj5B5Vn8Va(tTxx%`P%38LQlr`la9z=tB?v5u-%I3S=?b+Oq8x>bn>m>rf5^)!_#-2 zHnuYyJJgv@G?$gor(EqRWwIG0p5{6$64gaY=Esye_0;~G)+T~`HWqJ1}&O@!QaIp^IH}U{>rmXVOo{k^n!|p-_BT!3wy|2$-@VWC+|*j;Mx3CypaIw)IJQ@ z8*B{=T77y({bHnOqJu@~V+Ka*%pRINiP|9#o}$a3aZqC{=-AsQ&e|%exZ4rmU+Aq{ z>4C3-wabt$GE=)2l5#hn&qbCnEBfNsv)pK;hFwzl#EJ2hA*5GA%e_6cdi&QL1q>?p zbW0+V$r6YsdT43f&#d$bzFhEx#JzYIaoao)F_4Ik86?YGoRwuH11}Tgwk%US8UY~M z*_21VW`dO`1vcJe)vH$_U|pv@5OX_sMLBTUcY7KvX=OCF7jjiBribd&c{O0U2Q1oD z&s_^yw)Z8qsZ<8%^RY76(T$Gs&1sJz=`OIO@NxcNXBSOnH1B;h` ze2=WJU2D}(ct3e~zx4xo^{9Jy6Y-f`j(0i>KLg(c@L!omkzI$uIrBAFxaSSamd{Xp znR}z!JT^-(_Y!%L9pz{2i)vLd!oW|*MZ7Ky7l!>-%qX~13YSuew765=maS>@b>oU< zg}{uZ^W|whA;`NC#oSWEUx(&XajF)%IqT<$32lj?%91d@9HpW;n{DajNl-%hsN3C0 zFJp8rvXCU}uI-QGiFO5cI`ek)z7K@86?&N2HlDziF3NSLF!O(SZpDRH$R)!yu2@NKz$kK+4USn1w|ewCx13@jy_^T4#Pzt!7h>yH)pmbuyflcz#l zpgZ;p{L-#Wg5FrFUnn4JFlEYsA>Li__z|Ne+@mAY+OYxG{M(nT`^0VVK?M`XK zxZd(6l$aKkGK`JdQ-zSza}ZtPXuFuYlL^1*>H4YuUVoMJYwa&pNVW(BjGo8v2B#RA zBD8)x{X1cPAKyy4*qZZ|mcyPD=GN&- zn(4gp2;QW~v{4?sBhBpa3x>znKYH)#`B#Wt`OXvR$nX?jj(y`M;B@bcfG76WI2B(f ztofg=d56+3>aA94_?%?(CJ1Z|RQo6%nIPwmNpK6#Lavy-AEEMU(S-KP2M)j#zlE@C za64!w;av2;(eebPG#$zGi7pqEQ60154=((H!i7X>SHn}78I&su7T1iQLzg{#NdalQ zqyYFRw2U9_cJ8zXWS6{WPSiva7m_Ef*&Ufh``CG+X#a%`1~+Dp+CBP2S%MWHd6MR3 zic&G5z%?lcAuyNb<9e;gYEiY|bB&9>T7 zVvfo0mPh4_P|bh%3$~W`v46bGwwkqD9_w3y+Y@30-fF|vJNMB*lG@Vvh}?|PSd68- z{OD?bcDy6A>>%i-RTBrJ>n@mNo%IP1;!-kPGySY^N}33g1Pd~y@uM-2VF{e8ox;Lj zhXtYL(C_V;*n6vuCdvX2^bgr{-q#7#@)4QD4ap-YIpNY48)GQP!=@&8=J=xORa)8H zWux9s-Bw-{3yX=vr?f+Dai8eDrC=v-yt&k(&{5K4=*$`_^ZAUw4|J4Ecc#Ij7g7duJ3EqjGq1rqhe zt>P{s$wn$MciQSl8~}q6vs+*ghp_;+H`)(vgoBQlgDvg7}I}*GJ5l2bY@A^3^%VauC@o(zg=wHLMA7vXnM_0Aw5;m-J z$;O`(rLdCsvA3?A#U#?WE}TmH03s~nm}|D9nF*FtoTi>7 zIb%5V`CKxxC+}l^5t|b<)y|mX+hKGK-XCz-g##@>23zc-5$j1UfH*2V5(fOKI!uNa zX43o3uLH%GZ$9>uLCWwCQ7SqK+novpLUM)JMSYh!vg z<`zFk(6CChfXmf_Z&{*2W|9wgfX~~lR(R9YNT1M1)pM08&>|o4NI;{g%r!X2xnw#- zG!g5kFR3YVQk6nf)-(kOl^t5tK5y*RvG6w+$iu2fGI?KgrCJseStW&fZ0 z6`>JMYH6mgr7OCjjjp4kB)ThQFf2_rDTl^%-r;1~o$4HCW0vHS!H;5`@q($oyz7#lTi!#v0UubviBq!+pyg*}i zH1Y0mo7Di!X_=ZYH@DWVC(moV84TJE0jaYGs4b1bxt%d(cH<0njO?#knuyI%y24>D zScE+I{o;xjn(Dm0YTjQ>p8lu9!e;{}MYENDlG;Wm2Ahq*EMA|kXxF@WSXhzSF0QeM z^U^k6PQLZy5=5M|fwgIaU6!etn*)V9ub4WfS3QR|0T?VUMPu>oKJtn^x-dPma5RWv zc$IpS;hhUJ=-jbH{M3w9*yJ%L?bD(;vWk?7EuZ3$4fuZ+Yg`n3{h}T>bJ;Kbj`kfd z-T^P2PvC3}p`wdD?DDF=aHB75xihRsE2`BJ{GB)2)op_~bD3amjty&e$zwUNTa}KrT87xqpoL_$^+$|=& zvTqfIsvg>lb-ndXT%H<0Z8`rtU`?P+FRowy#JcNSD2zOAQ1|0`DdLTn7ET z+<}00cz7XL`DYZd_oPTC4dC0L#{?nFqt1#V;^=f6boV%f{Z zuogFbG7U+Dr-0^Re)OU6`Rvhc>*qyr2!gwq{C5-;=8_|76M}D|m>ywm3J`FAVD8V@ ziqCE`V(RrDzYh{92(>^w|q=2F7a0i~+(N&Y^e!X+B-iz>))(CWQRb6A#WTolP zEY#o-osk6ZNx9v|J)|Cwa4PmO4L*F#)O9sDd`~}kBgU7xWM?oTk?G;Se9i>A+5tWK zz@U*_-H;dzu^C)lWgZSMVvd)i&oA|3r^{b(AJ+=0V*zm0r&M6`n5x9K+nEr8_%XdW zc^U%zLurcjaklS~M>gaPZZm{Kj6i$CF#7VCdAX{09u*O9K#iOWkpeI|Mf<6N^lRm` zVQ(NRw{eQ95)QOUn6D~tg0hd>9<{uOa>hs|ISmAm;Awr~WE+=eku_RrX+EiXsT&r| zUjF6cs)S&3MINgUdh(g!>A7GIy$Nv*hFzbf=wr^$^W@NsaTqL`87%jLYPyd#@wJpC z6eX~FzD(V&1t_vf6mH(bd6CADwzlKh^`nCVy#0vc{Z^PYqMP`oChI;%wLP<1Kp!AP z;6FyGaG^hHp913f!ib7e_tU+LSKT%1FkMj!0d$H<%c$Q%C zJ$zdjVkK;5h|0}4skO^&^le>?B{U;#(opNlj7B86!4Wq zd(EF69JntFh5c;J({~e!YVTI^_DWLN+OD*ONE#ze{zCp$u#93t%NU)TturOalik{V zootV{Wve6_M!#+c(Xb)kHePP~y5{aAP0Ftd5|l|aqK_CWi|?_^7Pd5r&NhkoJS`?lEuIR%-6^6jE>Ai9y(Q9e81}4%y{I1 zMZ0>WI~Fd}!Nbp7=PLSs;z&v0B!(Lhm4I5Jbjj#^5aqg%4lR7Ygzjh<=Y zzTAxk%3fj!Q@u;!d_@p1AIF+5-9dC1Lr^CWZ2^7maoJX%gk)6C$zboCL7`Sd_djl$ z86h-OLf@WwvGYx{mml{c_(!whEge)Fv#K0;no~dfOC8p|0CdIqn9P1zoRl3{!C@2m zbmQ>LY&n88I&ttzpn!Ll(B7nn5DGsV%=9aoJ5sRFVa;fc3ohNb-~|5FRykaI8GKOS zcYr3dTC;S+w3QqBk&UTg=aI2bLM@QIcj-7*{X6!AvbM`{KPG9T*&nQrFE`Gv(U>3j#1 z{e?lGHnFy|$?+GqJh)^N24W5Dfa=#!==#&QM6<2P`(~kevK7f2Bd%#)8ZcP^<8{Pw zw4hVG^rNx+9K;U&xOWniJb91PuW$i$ZN)7AzlzY2_h0p^9z5BE<;>IQKE8YWfTZt` zw&0>(-^CPymEvzPHLr#3U(JsB2!D50952CVPX|H0b6*~Y2Ym#lRB@!1yi>nbn;a!d z#H~u`O5&z=fW$K!42>GAL{yWGkyS#=-y|(=WXEMWuPNa}wtjVj7Kio)8{R!Bd`yg= z54lYA(NY8MXI;~T3|}9DhB98e9^(nmjbS7m_vG3K{6MLduoBG>S>39O(48KHb}fGf zCq{1Sc8$5ITKJ>G*@VRPUS9s2&h5C}=sGv6CY=3lW6IDfWN(OO-1h&n*2_xR< z#oJ6(_RT2O7%HaBquitm^vJAPb zkK$(4Djw^I&Y}RTff~XlKok7p zN7=K6aft3V(=j*{l=#M z;PvB>3qq>SRQscuN=GI7zL#)8B=SBj5H|Y%>li4Nu7C~rMJ^gWd(imfmIQ&Nutt$Q z#RqHVY-`#R<7A1_nz^gCKIjs$2@_7uR;AJSGw086J2v?hmnp#&f98p(c;gn7(lHJx z(EVEb4i7hFv=5JNSVn5V)~l;G^?xOX7f8TuXd5Wl&~)i%yMs+2mkQ=HeR{1+Ok}u(#&H87rS(_O*)PrJcAN+aZ(Z)1 z?x>}9w9uXuOadAuHL$-rzkGi0y?geZ(Ib>neyy*#yiRVg$Io0Bc$Ps=rf`k{|HfkX zLlZLhJ?7CC3fZLZVW7~lP50n?`F~v%yHZ{}!}C@{V*+#{5TCE0SJ=zWc0RA?-tnCB zNsUW@K?o?vy0qI^`C)(tk}^@PHsibHXt3dtDX+SG9qgAV0f(ygc?oElY#)1Qy9HyM z&$}S7wq+m2mcK3YV@pvy8O#x?I%%hCil65yhmPo;E$*3?EzbJ2ixHyo3lCi1a2IOi zI+N<8<6Lftvg5sX*HBXwL}!hDC%70E=blhec3J@x$#p8Z8Gx$L_cTfpqUrKXR;h>J z8>!?kT0KG~>u7&Vi1m4wygm`4j(|sJ`vs<1JUy8GlU>i7Gu2scr_S{(&^LH!vm@M3 zT#EN|OcElvk7{?=G1ATD$&Vb@2Di<|VtiEeZ(M&5g?&@}CZH|Y$ivfAEFw9ii;|O- zsONfa@IbKz1Z4&tpIV!;U+rtAWGJ{}%ji=2MDBjYzgX=wJw=#?G80tfg-QY-BK+aWYPb5L!rSomEWTusyi}aIaIyq1gp=*- zA@=e*mO-x(bKSs6ptD$@w$s?JmOvnTFECx`w!*#&|3Mf=X`+0ZlECaCh!`o>+mO~U zv?4p+X~2UV?+A7fsVTY&6t-^Ov2D7+i5RLjUh(P6XUICwKg)G1{h>(am0t-6m$i9Oi4wLZAQ9 zFqC@Nzv(XCovxe?W~^?dQP2@xpw`Vh(zqJ->n;>c(8YCCU(C#zO-D4jK*?inHTADmW+6dV4>gNzxa~? zi8HB-p-TokcO_ZDV;ZVE6JkQt$?}z6A+6&o-Cwn{kvdal+m~r@HE4QAoRBN_+f7?7 ztjn>CUt1Jxd1Mu5(znJ7dF}iyu9VArsCu^}f-5u=xKg_#+kvmx8UU#~E zD9U;18G?Ll;sSS-0Dn=eNjf5dl<=OR)D^&u?xO5@Py-EwW-`w?LPvSBp&hk3@%HPh z7ve1@fvL1tP6K3_q|dWyj8mBJ?Va+OOY`>g66c}k3`Lnm@@7_)=}l`(I0O*w6^uhb z{!>c!H)c)`@;*H0I?*RYM0ZmWZvvF;4UE64SJDyLY;X2-0t>lYCZg`T{bn(n6l!9E zj6H$y#9q^_ox!4g_MfrR!=wMv#f6bS0fmRK0k*K+VKClg2zvL(+#YCd&BS(&rpscV z{eAMp+pn+)geV0?in19#lA}X^^A?2^CHf!6UH%W_&aCwE8724mH+%APF}sU5W4>v^ z3N44mF_0w_C3J?<>b=W6e`4Ly$b)Wo1=f1Ux!+PN#ND4ZL}~2)^#UXc zF$}5~)<*g#BB0!JWDY_d6xX9+Bw_wO@lA?IW6{dI+B+go%0LrT8E{+$J@_H>Rx;1G zF@#k)5D}d@822r!yqboRFf*=iY$dp%np%z+Bl;Zvb%jaVcwF}-di3NUtY*iFypF8c zQ-D8~SRRGA$$)BPwg9s|N@{lfX}ziPA7I`^3(;!ZlQ?T=(^D#USYZ?IW*tA(E|ufM0yoicI5PKXK> zjf2hn`l-VM^0C8n=KKDKZx9%V5?WMb;g>&yL#sy7omASX*Y?Ldb2)I!i&jR9op70o zlYM^amXg9cRV7z5rnZ0k9G~G)v9}ez)34b&lvK^y$K7hcxbQ);^nz(%$F)b=9P(F9 zU*^aDft4NZwRnhNHG_agNc??bOEJ@oJoA>15cQsReKQhqkpO-`1Dk9mue<^3*}$}H zLzYmmaD6vW5S5PdorYeCGpTHiB&pMQc0i9e`xu7ayYZqJdDvX(VWqIF zqx2peA+SJ52{l^ z!GZhn7(Rt(uM$ysVph2jGQ4$8X>OrKE?8(XNNifhM3fYYgA@SG50)0qX|rK)F`U|HlwkeRC}c1_g-9en0<`6MWY%%G8)6|c=Pf% z_l>J;fDmSB!g@W~*g@!{YQqjP8>qq}bxbg6d^_n(dj*Ah+AVmveh4yV1s=_?DAlz% zt<$8~hV**6qW4TT3?$z|jeT#T>nlto<|C0tfecpV_nAQG!y62FmUgUB-HI9<<30V3 z!}yGW2nx}Aq!47sn22{evIc!{OEXuRsC726ahnsgE?2(?_^X>~uulez_4>60`dO0M zuPnb5n*4}{B1zq@a#JcRx^U(U#>KpNSdl!YOL6x_QIT&MSrA@(uyK>WskDi~@4dW@ zF0TkGvPNHT`~YrA^mhi*UB+_$D{?DOQ-UG@!o-3aW^C8(^G-q9sHI zb$78wt;42K>62rp`g(*8uU(~NOAC;;BfZpTa*D=W$BZ@`TaPRpJ>bDM>#|9<43Z$@ zls!%{H|F_kVM()vn-Ph7Lj;E(MKauNYzn{TBYQScx;K+;b&Y(U9AVmv-B|Q5fcupg zd0kquhi1k)0&b3>8|zJIzNmOyx2Vi4$`hac`=s*E9Mb4S+Tc*k;T1GFJU>m4gPOeD_d)ros#^}6dv`Uj#IV2L3iC_e>7ETRGrNBGyHh6C16QvQ7I^6nn2h8A1DlC-Xz3@y4Yi zBSgm?w#-JT)pK30KmBfVi!Q9UNJp|(j>2lQ6~Zy0SXT*a)7)hpUpI7WG?%u_3n=rN z^sm!lXWGdIHJQ_UnPl7yXPKyNP#pYuoXee*Fa8%4?d}Cd(Hf|m@D^%_q}HhGgYe() zk`?0$Ybp=H&XBiu=~X=+ZJh``(Ofk|l=w*&C_3;e+!+eN zPM5*~P>L?zR8qW?S0r8Jlt?v-FFpAD1gULK2~5RkY!ve>*sY@sWT02kS*cUt0>0GS z*WT*QRpn4Iw@l(g`#ymB3#3pG7pa=zZnv6ACJr$x80!NtZTIUEuK(=@?ArcE2)%I( zh0tz1?lcu!Ff1MvBPSA;skvv-Z1J2~^*bX(W>auxa~uzN_mt0Zewn+Aa=A`#PHbpz z(~SKPUJL``1p6JJwoXH~Wre+xvIj<>zu5$JUyRDV?`Hh!ld&9lC=1d;-!#?f7Fv1( z>Z1fjcI#OsNvhp)|b;4<1 zV;!6@qleo9-D;_Ir+Ir*>&O5*LA*t^92H*Qk&t5VH#cYgjaYZZbJ6SdRwrdAe!XL< zhQ<@`;Eeasa+goiZOmpPfrcO?V9j&Q7<*~^FP3?-eLfjW921A;HGhg} zZcnJpZWFQCzGFEuHke(#vXUyM%}M$RV_QV_TMOR8E^ULF@Rn5UJ zxB&G9V*{hk7Ic{;x~ENXh>yFn60qL?jw6(6haYN z^#nk@xsph8Gz>ov;>yGP^Cummab0J)Zm(~;p>`wrhez$hf6(X<uL6bF@1s+YQybBc6B#s*qp2fKIij@ox6Y(E_RhHJ zoqwhla@)T))67yLB07gUGbVHF8Jw|~%>G?6$zusBEvnZvcQ;DDeW&ob3t~dV+46{qP^j97 z-2x61yGNa6A>Oqjbft6`TNW&JN92N)?e{+loxGg1yRj9D%$FhTfy-pORq7_qGegzO zG91*vlqXxOq5#!KHQ3pOk?m0JIc|7^vRLIe1C~Qq;|nFQ zPGHB;DCgJ~?zW{UuRsnJYs=Te;zXORaVUIEJKWsgf&ZWqV71s2YPK(j&n^G5Zy5C+ zG`a)}eIKZAk03S_6WWUNnlvd!ks=bB2vVgfEf|V`Ktd4^1(YVigaA^c333cQbO{}#2o?wk(n1rFYM}=a z2t5!=c(>=g=e&2^aeu(QW88enhpeo%_u9`|^I3B~bMDnl-YoNEF~Gf&dOv-w#_Y;Z za^$h#iq)xv%7$wkISf2+{d9F&xn%&}_os6Cq(N*+tz#tYDNw-%P)8WQm-npyOC5pe zseq7D+5DCWlMG{qlYv&9Th4q>!Ra*Ov;Hl6B%x(svyVb zjz1t;fVin9E3U3e<9Qohkbv@DpS0P1)aCM*!dvUu$7{cDPkG7m9;wZ_!*^|Ttoe;d z5-d^wZzKb@U%8UWr{Eu50wcV1!_dY{<}W_>XS1WfiI(@k=u}XM*9z#qlEL9$66wEG zZRccSMHp~x>4{bY?MpZmelNcmg&YI?r2 z8}p39{bOq`5=yM0OIo7uB)T)e6%_SJ+jmU*gXGn|H0DMxbrcJj5td!&k)qUcy*&~G zolO(%*GUSv_6Ri-eL`C_gDZ+(a?mh2{KqS~IF=KWnVKR*J@%;yA)*>K-fQsH*@g}B z+&{zm4gzDI=^xt5WX18`(5$_3Fp>45D@ z)V~8sz{~=)2he=nxE`JM&qMuR(oA%O>yu*d!1bnyl~FS0$|?9GB3g?A{RdiiqC@)U z!(PY^`U{QOr@GkSBD6axeXhkFgP9(CL1$_B8`$}c+e`14zC2hEIX~7_huSkB@~&|j z*`Xb?m6Lr6c35R${u(nk-y(2&=J;G_+!JQ@>7N7ngsXGG3F=fnjoqL5J7|TYS!+#) z2Vh=%KaTM_&x~@!s>&&s7UNqSwlXQ~g{IlGBMzO<&lcI# zTv(s$e%ksJoR6WcD`WRjuF$~Y{@6AfBCnfJ@E1YM!PW?Ql=3OJH4uHF7<05=Bp2^J zzj4V+UZ)H6io01BbQtRsTC;3b!Ryj=Koz_7BE9RbJ4ldI))5RiPE~OoP@YG#!sYho5owO8bQ*VQlhYX2!c}C@mL=hwOY~&^x{yVnMrnND&`R2O znem!2`gV^-H$*RF>5mQ6VBiQNN>FR?6#VppK(5&G+K+QM+p@)?-2$iB5~Ng+KzT3o zS<-1JBF-%<@WL|laEax`{nb{mgl(O4-Gd3?_6x}piv#&buLe-!IK>PdI^u;~6+M4` z%5`OmKbr4pJOx}jO9UHF%W%1^oI^7R1I(M_wgYKl;JQc~kCk00psRCO8m;;{(WI#+ zYqn~r_KZWGJj-VS>BF25d` zPC;S~j9%A3C$Jd_O_RCzOd*&;Q{w_cec(*{v!Yw&>9ovJ>nh03w!8~zlD@Zcr2}5& z)V4b2mJOg5IbPL1YI5a!`1VBb#F7X$fNy~uP=?;7q{_Rnjn_Y@#Q!pzDqC+9T`R+y z&a8DWAf#r}uyT!V+Mx2@FamW zdUGKlNv?7o1E>ia2oX63URLwQ)Px=G;AmQ219=gW$95i;-OOcl?M;tJK|Gc$zqPQ|A#&y5 ze0?@{w<}KebHK2C<665QK~l=IuK<9+wTTQxcPHxgqLoVGZVA7MrMd;CUd6n}?9B@W z{&g|kToQ4TJtjzRn7fGzMaDSq^<%u}`m-k#J%>sxcL2cu7U_?_I5r`9C#__5hn&C> z4;IF}8g+UBO?K{xPt$~zSXFw(^RsCaQC4Nvxr$h?hBf_-j+Tp+4NscryWRVUp#8Ou zR5|BJ6@*Sisd-cJ!&@}O`Dt{?uM|?FMY}IhQ!tN+l;)WN=h=F_WfoNOkPSXgq>kSw z2b{}Fuhw0I^9xD=nT#8-8Q^7==|yP!lOYd8H3r;{yy0qg28|z4E^_k7G2skR0=)y> z6@rArBKOlq2%q+#AxWTnAO{!el|zFw+wV>^n}Z&+n8hc7jXh ztc6*}d4n$KpK_7HwmCljLf{RTnCXs9lpsLwe<^Y#hS;ope&>IGZc}XWk;JS-&r%qi zO+y*gdn4DGsK)R8_JI1e7rCLvcVhC$GY&A(4ib@PxiY5+LS?G>l2Zr5@4CxqysUgr zxoS~<`*QgSJxE0J5wMyA{VM>NUS8x#h5g|8&F2G^hDlPA^(raE7bbW4G|iB@8<|d! ztj<_AksqZtHLh>gNf!qpd3QQ-$RsJt&u`3d@LGGHF0uH;?Ah5nac5NI!z9dKi<>od zEUK!QeJ`OYRsZOS|ho{)ztn&VLQ~ zC1bh*Ff`-@v7y%J8qzj|W5PT}9`N>23gol6#7LZ52h%ly)TJ>Loi;z%u9{!codQiT z!imLz4}1iGCp7JkZ*L%3`|lz~`?qwz#ZncSnxi<|IQ7iHpl-|KCL@vXDhkLe#>||` z1H#%$<}A&qfSxht8C*{4>J(s}?KnFUcuMOcXglIt23C%7)aV0Le;g7m|D&a=(m03o zkOb_1AsKL5OD{dZZnn!W&%~DWTt1!=Ox&>w%v1+itiB=qX}R z>hPU(au%Ax5Nj2<>e7u2#hjI~ss6}qVyx;hR^7I5w}pUZ_D8XKx<2;U{5b&6*f?vl z$Inm;Y;z08$6I+XS8`oFx0QHZSdN)tF&dR+E?BK>MI5wAB0gNVcQH8Xb89Vg+v(*W zEj>gT^MJVL<1^RiB2JAbCIS_{s2_g?@Jx8xTIlizGr?b}Z+$W6|44}G<+kUB?mPO^ z=29{^yz~WW^3ytH@O*viHxF|MMI_NrvbqWuZM(RW1KFqX)yr7wm219fe$ok?MyMS z(lCyMk25x>#Q~EdliAYqVRfo?Fp_DJCGE#89+#4SV;&74Ph$&FClRYe&di#qlQ93& zq|~W%Uo9&v;g5PQcd1C=HQQE~0S;~~$9bLMjtG8h^wN{mn6{V^$F-ZNp*ny4yC>|_ zu+b9c{F!~8eeWdpwnmU2Z182`$4o58g9#w#FH6zlSvR<@VG>tI(2wECM2U0`ar$~K zaumobZFhW~)3`C;-%-=Ak#V+BK!C^hF-=xaF@R#Hw*Af5eZ-ONjbm%%=#WT1rk?_i;anE!yrj~#NuhGIo`0_oRO(oy%Oo)FFz9CU@1gh)XQKyI^#BTHzAu3EFm3?t9>6&}m93+qDX@+an)90+iL$C0A3# zi`&h3?-O*qD=%m$iq(y&njS3)8z0NLc0_@>2X_I(q0G+XGrI(;=NTR*>BY#w%BR)VMP}X%TmtPLL9sSt zKq)N0rm#n3FFX|DX;StlAvnV#=w+b7hqE78*{JtoVc0Q34dIzmRs1F4U=$WOrChYC zP`qESo$~S6vM<_Y^HbjHr+%A+cH~91RL<#O>0wt?(C3#1WTRn(Mkv?OohL7MrgY-L zyr=6oKDevmpDN(UwgfDw5%%7i- zd(fwNI-ft_yMIa=om{3*u|mEYWCKqHP~xBc!%>wsjsi)#8|2>J*UkEI ze2&SY4_o>?>%WuvGGEg!{Mu`)mCP2~=V%Gj^h>)u364D6pVuT&i`23KPIVRLtTTu3 zm{BBKwwDZUw-EJjt+c%gS6^HmJk`o4H*?!L4k2VNr~E1M;!KT387nBjp_q-pzwEBX ztp$#dcKIMCXT5)@cV_!lMs?010%UhPtR=xzG-kQ@+#etiW3qwnH47t(Sl+J@M$j;x z8h2E0K}xS_sm7KOWut2|b)3T#eW}8Dvjz`g;xrWXTMsuZzped1hWFpu;b*Rij$9}C z=t83s-)4nGRohLpP3QdfgNb%C>Ec}YbM3T_DRV_B3Qf?Y-T%&y;AG%%;Wc{@TlpW~ zLY-K%z}Vf(l)8a3bPvTv7M}94vu?Ic_P;oLX0?C2BpeH4jQ;btzH@-*Vty;lTKb>! h|Nl4pKR+R>hu)W3-=@n{)PR7GfgVh^LfhfVzW`43mhAul From 394195904b7b58ec5783a1ed12ab19ac7e3ba643 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:53:31 -0500 Subject: [PATCH 4207/6505] Delete social.png --- misc/images/social.png | Bin 19402 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/social.png diff --git a/misc/images/social.png b/misc/images/social.png deleted file mode 100644 index 396c884827d732554048eca39ba558119e61924d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19402 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 V* Date: Sun, 15 Jan 2023 22:53:58 -0500 Subject: [PATCH 4208/6505] Delete proxcord.png --- misc/images/proxcord.png | Bin 109791 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/proxcord.png diff --git a/misc/images/proxcord.png b/misc/images/proxcord.png deleted file mode 100644 index 619f32bd963eb07595000623adf5a61f5d2915c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109791 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%0Aj8Ao80ccb!|y*xCb@*TRWu!$Ut5R7O2( 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

    #u)m)t2wf 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 Kyjs*K=zjocysa4k From a2034067c5e501634c4ce2d401f6aa9da83587a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Jan 2023 22:55:40 -0500 Subject: [PATCH 4209/6505] Delete motioneye-256x256.png --- misc/images/motioneye-256x256.png | Bin 5256 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/motioneye-256x256.png diff --git a/misc/images/motioneye-256x256.png b/misc/images/motioneye-256x256.png deleted file mode 100644 index 2f0fbaf37a0401dcbd764c13e5d11c59b27f599d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5256 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 QQw5} Date: Sun, 15 Jan 2023 22:56:21 -0500 Subject: [PATCH 4210/6505] Delete github-icon.png --- misc/images/github-icon.png | Bin 604 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/github-icon.png diff --git a/misc/images/github-icon.png b/misc/images/github-icon.png deleted file mode 100644 index cb9a01d02698d509569c02df327273f464ca8e8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 604 zcmV-i0;BzjP)Px%7D+@wR9Hvtm%nbpFc8MSzycdcEU>Y*V=HC`W=s}XBf(?v4v2{fiIEMAgcuoE z+p&FvsslwZ@<-sx5k_Ea$AMJs(2U9X?ss>eFSdhUew<&9kI(@1dY$d}dpM4R^?L2| zClU!T#t@Ik(d~9a`Ls6nJdZ7xORIvV(`od2JuBaVMqvWWbT%MH073|}N;$xYQmT!k z{SZ}f!KQ;y0z@6$1aSpWtJRoLcNFD6_mNB{(eL*!VqO8Lvfu4?7>~!kuS%s7$Tb`e zPd2i>+=>eTUFpvq21b_*RKVvDe+Qt^Xt4Qwu1s*TSYS4rg-u@DvP>p(nwX~wn3NxN z3pkl*Lm)stpGT|Jx+#0H$fScnfP1q42Z*Es*=!b_PUq(};JPk591hAr_voNdC?J>1 zUHFZ~Vi*htzW)BsAmTJp&w_Hf44$q0Xh$)C2SUi3SRhI-_VH@9LbKUKsZ=s*qF5{< zl}agXD5Z}8-o;1b-;ir!G#V*Ks!A8r=@jjD+X!d;8y;8Y2q7QB%Vx8|WHLduTE%v| z^%IXfo%|u)4mlJ60000 Date: Mon, 16 Jan 2023 11:02:06 -0500 Subject: [PATCH 4211/6505] Update kernel-clean.sh add pve-kernel-6.1 check --- misc/kernel-clean.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 5b072c18..824d708a 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -51,18 +51,23 @@ function check_root() { exit 1 else header_info - edge_kernel + other_kernel kernel_info kernel_clean fi } -function edge_kernel() { +function other_kernel() { if [[ "$current_kernel" == *"edge"* ]]; then echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" echo -e "\nAn Active PVE Kernel is required to use Kernel Clean\n" exit 1 fi + if [[ "$current_kernel" == *"6.1"* ]]; then + echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" + echo -e "\nAs 5.15 is the current default kernel in PVE 7.3 the package management directly depends on it, it's not possible to use this script while running 6.1 kernels. (the script tries to remove ALL old kernels) \n" + exit 1 + fi } function kernel_info() { From 5cc5358e3e15962e019073ee5f100483d3551111 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 16 Jan 2023 12:14:20 -0500 Subject: [PATCH 4212/6505] Delete file-manager.png --- misc/images/file-manager.png | Bin 160849 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/file-manager.png diff --git a/misc/images/file-manager.png b/misc/images/file-manager.png deleted file mode 100644 index 4acbe6df48995fcdf9b2fdf1d44cb00fbe799be0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160849 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

    86;iZw_s&S%ieB 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�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 Date: Mon, 16 Jan 2023 12:14:35 -0500 Subject: [PATCH 4213/6505] Delete prome.png --- misc/images/prome.png | Bin 44686 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/prome.png diff --git a/misc/images/prome.png b/misc/images/prome.png deleted file mode 100644 index 0f6f3de4d29d5d914b93c7690ec229feb4f84f28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44686 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 z 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 From 30c820fd2a20d14790a9a4068bd9693856623973 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 16 Jan 2023 12:14:48 -0500 Subject: [PATCH 4214/6505] Delete omv.png --- misc/images/omv.png | Bin 2795 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/omv.png diff --git a/misc/images/omv.png b/misc/images/omv.png deleted file mode 100644 index b8de99c57387f34f2dcaa52fdf4cf9753d08b70f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2795 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 GM)GfN<%gdD From c4d2e1908e45f53d58cc235ed910cf4bd17561c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 16 Jan 2023 19:07:50 -0500 Subject: [PATCH 4215/6505] Update changedetection-v5-install.sh add dnspython --- install/changedetection-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index c2835894..313d35cc 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -89,6 +89,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Change Detection" mkdir /opt/changedetection $STD pip3 install changedetection.io +$STD python3 -m pip install dnspython==2.2.1 msg_ok "Installed Change Detection" msg_info "Creating Service" From 05c1661b6fc26849b5c4aa3838c30cb2e2476283 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 Jan 2023 05:23:21 -0500 Subject: [PATCH 4216/6505] Update deluge-v5-install.sh add dependency --- install/deluge-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 0ec88f4e..43c0214f 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -91,6 +91,7 @@ msg_ok "Installed pip3" msg_info "Installing Deluge" $STD pip install deluge[all] +$STD pip install lbry-libtorrent msg_ok "Installed Deluge" msg_info "Creating Service" From fcadc60cda766daa8f099c682722e16a1c5e2d56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 Jan 2023 05:38:38 -0500 Subject: [PATCH 4217/6505] Create homer-v5.sh --- ct/homer-v5.sh | 394 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 ct/homer-v5.sh diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh new file mode 100644 index 00000000..9f74ad24 --- /dev/null +++ b/ct/homer-v5.sh @@ -0,0 +1,394 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ + / / / /___ ____ ___v5___ _____ + / /_/ / __ \/ __ `__ \/ _ \/ ___/ + / __ / /_/ / / / / / / __/ / +/_/ /_/\____/_/ /_/ /_/\___/_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Homer" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Stopping ${APP}" +systemctl stop homer +msg_ok "Stopped ${APP}" + +msg_info "Backing up conf.yml" +cd ~ +cp -R /opt/homer/assets/conf.yml conf.yml +msg_ok "Backed up conf.yml" + +msg_info "Updating ${APP}" +rm -rf /opt/homer/* +cd /opt/homer +wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip +unzip homer.zip &>/dev/null +msg_ok "Updated ${APP}" +msg_info "Restoring conf.yml" +cd ~ +cp -R conf.yml /opt/homer/assets +msg_ok "Restored conf.yml" + +msg_info "Cleaning" +rm -rf conf.yml /opt/homer/homer.zip +msg_ok "Cleaned" + +msg_info "Starting ${APP}" +systemctl start homer +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8010${CL} \n" From 8265e5eddddf899ae5e80c329ee0c19bf6a321c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 Jan 2023 05:39:51 -0500 Subject: [PATCH 4218/6505] Create homer-v5-install.sh --- install/homer-v5-install.sh | 138 ++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 install/homer-v5-install.sh diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh new file mode 100644 index 00000000..d6c42232 --- /dev/null +++ b/install/homer-v5-install.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y unzip +$STD apt-get install -y pip +msg_ok "Installed Dependencies" + +msg_info "Installing Homer" +mkdir -p /opt/homer +cd /opt/homer +wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip +$STD unzip homer.zip +rm -rf homer.zip +cp assets/config.yml.dist assets/config.yml +msg_ok "Installed Homer" + +msg_info "Creating Service" +cat </etc/systemd/system/homer.service +[Unit] +Description=Homer Dashboard +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/opt/homer +ExecStart=python3 -m http.server 8010 +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now homer +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 1e2f8fb059fda88b9a81e4a43251638e17e5e55d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 Jan 2023 05:47:22 -0500 Subject: [PATCH 4219/6505] Update homer-v5.sh --- ct/homer-v5.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 9f74ad24..4e117f5f 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -327,7 +327,7 @@ msg_ok "Stopped ${APP}" msg_info "Backing up conf.yml" cd ~ -cp -R /opt/homer/assets/conf.yml conf.yml +cp -R /opt/homer/assets/config.yml config.yml msg_ok "Backed up conf.yml" msg_info "Updating ${APP}" @@ -338,11 +338,11 @@ unzip homer.zip &>/dev/null msg_ok "Updated ${APP}" msg_info "Restoring conf.yml" cd ~ -cp -R conf.yml /opt/homer/assets +cp -R config.yml /opt/homer/assets msg_ok "Restored conf.yml" msg_info "Cleaning" -rm -rf conf.yml /opt/homer/homer.zip +rm -rf config.yml /opt/homer/homer.zip msg_ok "Cleaned" msg_info "Starting ${APP}" From 68ceabf85a3efb607d3c0ccd4d9c37eaa2b73b29 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 Jan 2023 05:48:38 -0500 Subject: [PATCH 4220/6505] Update homer-v5.sh --- ct/homer-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 4e117f5f..bc702f38 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -325,10 +325,10 @@ msg_info "Stopping ${APP}" systemctl stop homer msg_ok "Stopped ${APP}" -msg_info "Backing up conf.yml" +msg_info "Backing up config.yml" cd ~ cp -R /opt/homer/assets/config.yml config.yml -msg_ok "Backed up conf.yml" +msg_ok "Backed up config.yml" msg_info "Updating ${APP}" rm -rf /opt/homer/* From 5fd5078f60afe1293848b7cb8fd64b7ff4bb74f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 Jan 2023 05:50:34 -0500 Subject: [PATCH 4221/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 60905879..6555643e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-17 + +### Changed + +- **Homer LXC** + - NEW Script + ## 2023-01-14 ### Changed From f2a02a29142a42cfcf927c18d3d97bfc0d897eb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 Jan 2023 13:04:17 -0500 Subject: [PATCH 4222/6505] Update jellyfin-v5-install.sh install beignet-opencl-icd only on 20.04 --- install/jellyfin-v5-install.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 7038cd18..d67f35d7 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -92,9 +92,8 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install \ va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd - + ocl-icd-libopencl1 + if [[ ${PCT_OSVERSION} == "20.04" ]]; then $STD apt-get -y install beignet-opencl-icd; fi /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* @@ -104,9 +103,7 @@ fi msg_info "Setting Up Jellyfin Repository" $STD add-apt-repository universe -y $STD apt-key add <(curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key) -cat </etc/apt/sources.list.d/jellyfin.list -deb [arch=amd64] https://repo.jellyfin.org/ubuntu focal main -EOF +sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://repo.jellyfin.org/ubuntu $(lsb_release -c -s) main" > /etc/apt/sources.list.d/jellyfin.list' msg_ok "Set Up Jellyfin Repository" msg_info "Installing Jellyfin" From 220c436e575db63bcab396abfd66c40323374970 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 Jan 2023 13:08:22 -0500 Subject: [PATCH 4223/6505] Update emby-v5-install.sh install beignet-opencl-icd only on 20.04 --- install/emby-v5-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 8caf588b..8982246c 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -90,8 +90,8 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install \ va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd + ocl-icd-libopencl1 + if [[ ${PCT_OSVERSION} == "20.04" ]]; then $STD apt-get -y install beignet-opencl-icd; fi /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri From c12d58630f7f7499fffda1c2fc9ca75a375e5f22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 18 Jan 2023 13:15:21 -0500 Subject: [PATCH 4224/6505] Update plex-v5-install.sh install beignet-opencl-icd only on 20.04 --- install/plex-v5-install.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 2a5cb5c2..4796b4fb 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -91,8 +91,8 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install \ va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd + ocl-icd-libopencl1 + if [[ ${PCT_OSVERSION} == "20.04" ]]; then $STD apt-get -y install beignet-opencl-icd; fi /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri @@ -102,9 +102,7 @@ fi msg_info "Setting Up Plex Media Server Repository" $STD apt-key add <(curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key) -cat </etc/apt/sources.list.d/plexmediaserver.list -deb [arch=amd64] https://downloads.plex.tv/repo/deb/ public main -EOF +sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" > /etc/apt/sources.list.d/plexmediaserver.list' msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" From ce5443f288a8a499d213c5353a81ea5e3ba41aa4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 Jan 2023 17:06:46 -0500 Subject: [PATCH 4225/6505] Create sabnzbd-v5.sh --- ct/sabnzbd-v5.sh | 370 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 ct/sabnzbd-v5.sh diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh new file mode 100644 index 00000000..fcba12e2 --- /dev/null +++ b/ct/sabnzbd-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + _____ ___ ____ __ __ + / ___// | / __ )____v5____ / /_ ____/ / + \__ \/ /| | / __ / __ \/_ / / __ \/ __ / + ___/ / ___ |/ /_/ / / / / / /_/ /_/ / /_/ / +/____/_/ |_/_____/_/ /_/ /___/_.___/\__,_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="SABnzbd" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:7777${CL} \n" From 85aeec53ba7b65eb463ea3e6c73a5ce8c88bb4a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 Jan 2023 17:08:05 -0500 Subject: [PATCH 4226/6505] Create sabnzbd-v5-install.sh --- install/sabnzbd-v5-install.sh | 141 ++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 install/sabnzbd-v5-install.sh diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh new file mode 100644 index 00000000..848ac026 --- /dev/null +++ b/install/sabnzbd-v5-install.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing pip3" +$STD apt-get install -y par2 \ + python3-setuptools \ + python3-pip +msg_ok "Installed pip3" + +msg_info "Installing SABnzbd" +RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +$STD tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) +mv SABnzbd-${RELEASE} /opt/sabnzbd +cd /opt/sabnzbd +$STD python3 -m pip install -r requirements.txt +msg_ok "Installed SABnzbd" + +msg_info "Creating Service" +service_path="/etc/systemd/system/sabnzbd.service" +echo "[Unit] +Description=SABnzbd +After=network.target +[Service] +WorkingDirectory=/opt/sabnzbd +ExecStart=python3 SABnzbd.py -s 0.0.0.0:7777 +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q sabnzbd.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From bc6ecfd8b7ab28a96d0b3b33f5c81ec51327fb74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 Jan 2023 17:13:01 -0500 Subject: [PATCH 4227/6505] Update sabnzbd-v5.sh --- ct/sabnzbd-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index fcba12e2..2c3b0a1f 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -367,4 +367,4 @@ pct set $CTID -description "# ${APP} LXC " msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}https://${IP}:7777${CL} \n" + ${BL}http://${IP}:7777${CL} \n" From a9c03fcc7b4a781929c908f2890761b51d99c339 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 Jan 2023 17:36:53 -0500 Subject: [PATCH 4228/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6555643e..a7e201f3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-19 + +### Changed + +- **SABnzbd LXC** + - NEW Script + ## 2023-01-17 ### Changed From c16ed2a80f6f26525caa87e18ff8ed450d56681e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Jan 2023 07:40:45 -0500 Subject: [PATCH 4229/6505] Update and rename mikrotik-routeros-v4.sh to mikrotik-routeros-v5.sh --- ...routeros-v4.sh => mikrotik-routeros-v5.sh} | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) rename vm/{mikrotik-routeros-v4.sh => mikrotik-routeros-v5.sh} (90%) diff --git a/vm/mikrotik-routeros-v4.sh b/vm/mikrotik-routeros-v5.sh similarity index 90% rename from vm/mikrotik-routeros-v4.sh rename to vm/mikrotik-routeros-v5.sh index 848a505c..f2a0cd30 100644 --- a/vm/mikrotik-routeros-v4.sh +++ b/vm/mikrotik-routeros-v5.sh @@ -1,4 +1,16 @@ #!/usr/bin/env bash +function header_info { +cat <<"EOF" + __ ____ __ __ _ __ ____ __ ____ _____ + / |/ (_) /___________ / /_(_) /__ / __ \____v5__ __/ /____ _____/ __ \/ ___/ + / /|_/ / / //_/ ___/ __ \/ __/ / //_/ / /_/ / __ \/ / / / __/ _ \/ ___/ / / /\__ \ + / / / / / < / / / /_/ / /_/ / < / _ _/ /_/ / /_/ / /_/ __/ / / /_/ /___/ / +/_/ /_/_/_/|_/_/ \____/\__/_/_/|_| /_/ |_|\____/\__,_/\__/\___/_/ \____//____/ + +EOF +} +clear +header_info echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) @@ -58,15 +70,7 @@ else echo -e "⚠ User exited script \n" exit fi -function header_info { -echo -e "${RD} - __ ____ __ __ _ __ ____ __ ____ _____ - / |/ (_) /___________ / /_(_) /__ / __ \____ __ __/ /____ _____/ __ \/ ___/ - / /|_/ / / //_/ ___/ __ \/ __/ / //_/ / /_/ / __ \/ / / / __/ _ \/ ___/ / / /\__ \ - / / / / / < / / / /_/ / /_/ / < v4 / _ _/ /_/ / /_/ / /_/ __/ / / /_/ /___/ / -/_/ /_/_/_/|_/_/ \____/\__/_/_/|_| /_/ |_|\____/\__,_/\__/\___/_/ \____//____/ -${CL}" -} + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -90,6 +94,8 @@ function default_settings() { MAC=$GEN_MAC echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" echo -e "${BL}Creating a Mikrotik RouterOS VM using the above default settings${CL}" @@ -149,6 +155,17 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi +MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi +fi if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS VM when completed?" 10 58); then echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}yes${CL}" START_VM="yes" @@ -241,17 +258,17 @@ for i in {0,1}; do done msg_ok "Extracted Mikrotik RouterOS Disk Image" msg_info "Creating Mikrotik RouterOS VM" -qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ +qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=2G >/dev/null -qm set $VMID \ -boot order=scsi0 >/dev/null -qm set $VMID -description "# Mikrotik RouterOS -### https://github.com/tteck/Proxmox" >/dev/null + -description "# Home Assistant OS +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Mikrotik RouterOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Mikrotik RouterOS VM" From 0323395dec810724cb5cb71f6347bad00a2ed1cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Jan 2023 07:49:47 -0500 Subject: [PATCH 4230/6505] Update mikrotik-routeros-v5.sh --- vm/mikrotik-routeros-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros-v5.sh b/vm/mikrotik-routeros-v5.sh index f2a0cd30..32eaffa7 100644 --- a/vm/mikrotik-routeros-v5.sh +++ b/vm/mikrotik-routeros-v5.sh @@ -266,7 +266,7 @@ qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=2G >/dev/null -boot order=scsi0 >/dev/null - -description "# Home Assistant OS + -description "# Mikrotik RouterOS VM ### https://github.com/tteck/Proxmox [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Mikrotik RouterOS VM ${CL}${BL}(${HN})" From 85216cabc35203ef87803637f8c1608537536aa6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Jan 2023 08:22:09 -0500 Subject: [PATCH 4231/6505] Update sabnzbd-v5-install.sh add unzip unrar --- install/sabnzbd-v5-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 848ac026..1790be9a 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -83,12 +83,14 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y unzip +$STD apt-get install -y par2 +$STD apt-get install -y unrar-free msg_ok "Installed Dependencies" msg_info "Installing pip3" -$STD apt-get install -y par2 \ - python3-setuptools \ - python3-pip +$STD apt-get install -y python3-setuptools +$STD apt-get install -y python3-pip msg_ok "Installed pip3" msg_info "Installing SABnzbd" From 419f750487ff9453355d1eb6bffa06a70607c0cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Jan 2023 10:36:19 -0500 Subject: [PATCH 4232/6505] Update mikrotik-routeros-v5.sh fix redirect --- vm/mikrotik-routeros-v5.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/mikrotik-routeros-v5.sh b/vm/mikrotik-routeros-v5.sh index 32eaffa7..789d2e75 100644 --- a/vm/mikrotik-routeros-v5.sh +++ b/vm/mikrotik-routeros-v5.sh @@ -264,8 +264,8 @@ pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ - -scsi0 ${DISK1_REF},size=2G >/dev/null - -boot order=scsi0 >/dev/null + -scsi0 ${DISK1_REF},size=2G \ + -boot order=scsi0 \ -description "# Mikrotik RouterOS VM ### https://github.com/tteck/Proxmox [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null From 0a2896d81fb8bb543c4d71c947f006f928af65c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Jan 2023 11:18:32 -0500 Subject: [PATCH 4233/6505] Update mikrotik-routeros-v5.sh update to 7.7 --- vm/mikrotik-routeros-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros-v5.sh b/vm/mikrotik-routeros-v5.sh index 789d2e75..0c13b8dc 100644 --- a/vm/mikrotik-routeros-v5.sh +++ b/vm/mikrotik-routeros-v5.sh @@ -227,7 +227,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Mikrotik RouterOS Disk Image" -URL=https://download.mikrotik.com/routeros/7.4.1/install-image-7.4.1.zip +URL=https://download.mikrotik.com/routeros/7.7/install-image-7.7.zip sleep 2 msg_ok "${CL}${BL}${URL}${CL}" From 78d07cd3a543539bb7ba3a9cfccf9894e0fddb33 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Jan 2023 14:01:43 -0500 Subject: [PATCH 4234/6505] Update casaos-v5.sh If the LXC is created Privileged, the script will automatically set up USB passthrough --- ct/casaos-v5.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 740930aa..809f3d74 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -377,6 +377,17 @@ cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$CT_TYPE" == "0" ]; then +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From c64ef30a9d566b2755e6c10a377c155fc3584bfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Jan 2023 14:03:52 -0500 Subject: [PATCH 4235/6505] Update umbrel-v5.sh If the LXC is created Privileged, the script will automatically set up USB passthrough --- ct/umbrel-v5.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 9a2b7b0e..135b4218 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -375,6 +375,17 @@ cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: EOF +if [ "$CT_TYPE" == "0" ]; then +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" From b8a0390d410a3c8b93c934037dcad4ba2ab98b6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Jan 2023 16:25:53 -0500 Subject: [PATCH 4236/6505] Create kavita-v5.sh --- ct/kavita-v5.sh | 373 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 ct/kavita-v5.sh diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh new file mode 100644 index 00000000..7b2dd5a6 --- /dev/null +++ b/ct/kavita-v5.sh @@ -0,0 +1,373 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + __ __ _ __ + / //_/___ __ v5__(_) /_____ _ + / ,< / __ `/ | / / / __/ __ `/ + / /| / /_/ /| |/ / / /_/ /_/ / +/_/ |_\__,_/ |___/_/\__/\__,_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Kavita" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /opt/Kavita ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From 99edae4bcd1bb1f2fe16cf02ffa89400f84ff7f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Jan 2023 16:27:23 -0500 Subject: [PATCH 4237/6505] Create kavita-v5-install.sh --- install/kavita-v5-install.sh | 132 +++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 install/kavita-v5-install.sh diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh new file mode 100644 index 00000000..6ef9c43d --- /dev/null +++ b/install/kavita-v5-install.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" + +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing Kavita" +cd /opt +RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) && +msg_ok "Installed Kavita" + +msg_info "Creating Service" +service_path="/etc/systemd/system/kavita.service" +echo "[Unit] +Description=Kavita Server +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/Kavita +ExecStart=/opt/Kavita/Kavita +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +chmod +x /opt/Kavita/* && chown root /opt/Kavita/* +systemctl enable --now -q kavita.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 2138e2b0174914e2785a9ff0c74efedb51fdf3b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Jan 2023 16:37:32 -0500 Subject: [PATCH 4238/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a7e201f3..f8a3eb80 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-21 + +### Changed + +- **Kavita LXC** + - NEW Script + ## 2023-01-19 ### Changed From d899003066be8b0ad4a0d0d7ac91ea8ccbd3dc6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 22 Jan 2023 10:50:46 -0500 Subject: [PATCH 4239/6505] Update jellyfin-v5-install.sh now installs jellyfin-ffmpeg5 --- install/jellyfin-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index d67f35d7..667b3ace 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -109,7 +109,7 @@ msg_ok "Set Up Jellyfin Repository" msg_info "Installing Jellyfin" $STD apt-get update $STD apt install jellyfin-server -y -$STD apt install jellyfin-ffmpeg -y +$STD apt install jellyfin-ffmpeg5 -y msg_ok "Installed Jellyfin" msg_info "Creating Service" From f7d1889b22caf398c5d29af5775617d2b58b5841 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 22 Jan 2023 17:19:08 -0500 Subject: [PATCH 4240/6505] Create autobrr-v5-install.sh --- install/autobrr-v5-install.sh | 141 ++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 install/autobrr-v5-install.sh diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh new file mode 100644 index 00000000..406e63e5 --- /dev/null +++ b/install/autobrr-v5-install.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +msg_ok "Installed Dependencies" + +msg_info "Installing Autobrr" +wget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\" -f4) +tar -C /usr/local/bin -xzf autobrr*.tar.gz +rm -rf autobrr*.tar.gz +mkdir -p /root/.config/autobrr +cat <>/root/.config/autobrr/config.toml +# https://autobrr.com/configuration/autobrr +host = "0.0.0.0" +port = 7474 +logLevel = "DEBUG" +sessionSecret = "$(openssl rand -base64 24)" +EOF +msg_ok "Installed Autobrr" + +msg_info "Creating Service" +service_path="/etc/systemd/system/autobrr.service" +echo "[Unit] +Description=autobrr service +After=syslog.target network-online.target +[Service] +Type=simple +User=root +Group=root +ExecStart=/usr/local/bin/autobrr --config=/root/.config/autobrr/ +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q autobrr.service +msg_ok "Created Service" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 50cc6e7287a19e7c156076a49379aa2ff31c279b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 22 Jan 2023 17:20:45 -0500 Subject: [PATCH 4241/6505] Create autobrr-v5.sh --- ct/autobrr-v5.sh | 384 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 ct/autobrr-v5.sh diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh new file mode 100644 index 00000000..26e18c8c --- /dev/null +++ b/ct/autobrr-v5.sh @@ -0,0 +1,384 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ___ __ __ + / | __ __/ /_____ / /_v5__________ + / /| |/ / / / __/ __ \/ __ \/ ___/ ___/ + / ___ / /_/ / /_/ /_/ / /_/ / / / / +/_/ |_\__,_/\__/\____/_.___/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Autobrr" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /root/.config/autobrr ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Stopping ${APP} LXC" +systemctl stop autobrr.service +msg_ok "Stopped ${APP} LXC" + +msg_info "Updating ${APP} LXC" +rm -rf /usr/local/bin/* +wget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\" -f4) +tar -C /usr/local/bin -xzf autobrr*.tar.gz +rm -rf autobrr*.tar.gz +msg_ok "Updated ${APP} LXC" + +msg_info "Starting ${APP} LXC" +systemctl start autobrr.service +msg_ok "Started ${APP} LXC" +msg_ok "Update Successfull" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7474${CL} \n" From d35f1eac89df25589daa4c96411062ee6c57568f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 22 Jan 2023 17:26:07 -0500 Subject: [PATCH 4242/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f8a3eb80..f5212b19 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-22 + +### Changed + +- **Autobrr LXC** + - NEW Script + ## 2023-01-21 ### Changed From 9a7d8fdc78bd55b7c58f003147ac94eb15278648 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 23 Jan 2023 10:42:50 -0500 Subject: [PATCH 4243/6505] add midnight commander (mc) (#974) --- install/adguard-install.sh | 1 + install/adguard-v5-install.sh | 2 ++ install/autobrr-v5-install.sh | 2 ++ install/blocky-install.sh | 1 + install/blocky-v5-install.sh | 2 ++ install/casaos-install.sh | 1 + install/casaos-v5-install.sh | 2 ++ install/changedetection-install.sh | 1 + install/changedetection-v5-install.sh | 2 ++ install/cronicle-v5-install.sh | 2 ++ install/daemonsync-install.sh | 1 + install/daemonsync-v5-install.sh | 2 ++ install/dashy-install.sh | 1 + install/dashy-v5-install.sh | 2 ++ install/debian-install.sh | 1 + install/debian-v5-install.sh | 2 ++ install/deconz-install.sh | 1 + install/deconz-v5-install.sh | 2 ++ install/deluge-v5-install.sh | 2 ++ install/docker-install.sh | 1 + install/docker-v5-install.sh | 2 ++ install/emby-install.sh | 1 + install/emby-v5-install.sh | 2 ++ install/emqx-install.sh | 1 + install/emqx-v5-install.sh | 2 ++ install/esphome-install.sh | 1 + install/esphome-v5-install.sh | 2 ++ install/grafana-install.sh | 1 + install/grafana-v5-install.sh | 2 ++ install/grocy-install.sh | 1 + install/grocy-v5-install.sh | 2 ++ install/heimdalldashboard-install.sh | 1 + install/heimdalldashboard-v5-install.sh | 2 ++ install/homeassistant-core-install.sh | 1 + install/homeassistant-core-v5-install.sh | 2 ++ install/homeassistant-install.sh | 1 + install/homeassistant-v5-install.sh | 2 ++ install/homebridge-install.sh | 1 + install/homebridge-v5-install.sh | 2 ++ install/homepage-install.sh | 1 + install/homepage-v5-install.sh | 2 ++ install/homer-v5-install.sh | 2 ++ install/hyperion-install.sh | 1 + install/hyperion-v5-install.sh | 2 ++ install/influxdb-install.sh | 1 + install/influxdb-v5-install.sh | 2 ++ install/iobroker-install.sh | 1 + install/iobroker-v5-install.sh | 2 ++ install/jellyfin-install.sh | 1 + install/jellyfin-v5-install.sh | 2 ++ install/k0s-v5-install.sh | 2 ++ install/kavita-v5-install.sh | 2 ++ install/keycloak-install.sh | 1 + install/keycloak-v5-install.sh | 2 ++ install/lidarr-v5-install.sh | 2 ++ install/magicmirror-install.sh | 1 + install/magicmirror-v5-install.sh | 2 ++ install/mariadb-install.sh | 1 + install/mariadb-v5-install.sh | 2 ++ install/meshcentral-install.sh | 1 + install/meshcentral-v5-install.sh | 2 ++ install/motioneye-install.sh | 1 + install/motioneye-v5-install.sh | 2 ++ install/mqtt-install.sh | 1 + install/mqtt-v5-install.sh | 2 ++ install/n8n-install.sh | 1 + install/n8n-v5-install.sh | 2 ++ install/navidrome-install.sh | 1 + install/navidrome-v5-install.sh | 2 ++ install/nextcloudpi-install.sh | 1 + install/nextcloudpi-v5-install.sh | 2 ++ install/nginx-proxy-manager-install.sh | 1 + install/nginxproxymanager-v5-install.sh | 2 ++ install/nocodb-install.sh | 1 + install/nocodb-v5-install.sh | 2 ++ install/node-red-install.sh | 1 + install/node-red-v5-install.sh | 2 ++ install/omada-install.sh | 1 + install/omada-v5-install.sh | 12 +++++++----- install/omv-install.sh | 1 + install/omv-v5-install.sh | 2 ++ install/openhab-install.sh | 1 + install/openhab-v5-install.sh | 2 ++ install/paperless-ngx-install.sh | 1 + install/paperless-ngx-v5-install.sh | 4 +++- install/photoprism-install.sh | 1 + install/photoprism-v5-install.sh | 2 ++ install/pihole-install.sh | 1 + install/pihole-v5-install.sh | 2 ++ install/plex-install.sh | 1 + install/plex-v5-install.sh | 2 ++ install/podman-homeassistant-install.sh | 1 + install/podman-homeassistant-v5-install.sh | 2 ++ install/podman-v5-install.sh | 2 ++ install/postgresql-install.sh | 1 + install/postgresql-v5-install.sh | 2 ++ install/prometheus-install.sh | 1 + install/prometheus-v5-install.sh | 2 ++ install/prowlarr-v5-install.sh | 2 ++ install/radarr-v5-install.sh | 2 ++ install/readarr-v5-install.sh | 2 ++ install/sabnzbd-v5-install.sh | 2 ++ install/scrypted-install.sh | 1 + install/scrypted-v5-install.sh | 4 +++- install/shinobi-install.sh | 1 + install/shinobi-v5-install.sh | 3 ++- install/sonarr-v5-install.sh | 2 ++ install/syncthing-install.sh | 1 + install/syncthing-v5-install.sh | 2 ++ install/tdarr-v5-install.sh | 2 ++ install/technitiumdns-install.sh | 1 + install/technitiumdns-v5-install.sh | 2 ++ install/trilium-install.sh | 1 + install/trilium-v5-install.sh | 2 ++ install/ubuntu-install.sh | 1 + install/ubuntu-v5-install.sh | 2 ++ install/umbrel-install.sh | 1 + install/umbrel-v5-install.sh | 2 ++ install/unifi-install.sh | 1 + install/unifi-v5-install.sh | 2 ++ install/uptimekuma-install.sh | 1 + install/uptimekuma-v5-install.sh | 2 ++ install/vaultwarden-install.sh | 1 + install/vaultwarden-v5-install.sh | 4 +++- install/whisparr-v5-install.sh | 2 ++ install/whoogle-install.sh | 1 + install/whoogle-v5-install.sh | 2 ++ install/wikijs-install.sh | 1 + install/wikijs-v5-install.sh | 2 ++ install/wireguard-install.sh | 1 + install/wireguard-v5-install.sh | 2 ++ install/yunohost-v5-install.sh | 2 ++ install/zigbee2mqtt-install.sh | 1 + install/zigbee2mqtt-v5-install.sh | 2 ++ install/zwave-js-ui-install.sh | 1 + install/zwave-js-ui-v5-install.sh | 2 ++ 136 files changed, 220 insertions(+), 9 deletions(-) diff --git a/install/adguard-install.sh b/install/adguard-install.sh index ec37c2c9..fbe4d973 100644 --- a/install/adguard-install.sh +++ b/install/adguard-install.sh @@ -91,6 +91,7 @@ curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scrip msg_ok "Installed AdGuard Home" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 637375f6..c0cb9130 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" @@ -93,6 +94,7 @@ rm install.sh msg_ok "Installed AdGuard Home" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 406e63e5..08b1490d 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Autobrr" @@ -115,6 +116,7 @@ systemctl enable --now -q autobrr.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/blocky-install.sh b/install/blocky-install.sh index ff3ad10c..4422902e 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -348,6 +348,7 @@ systemctl enable --now blocky msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index dbb72503..3a09d1b8 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Blocky" @@ -348,6 +349,7 @@ $STD systemctl enable --now blocky msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/casaos-install.sh b/install/casaos-install.sh index 35e88e14..141058cd 100644 --- a/install/casaos-install.sh +++ b/install/casaos-install.sh @@ -107,6 +107,7 @@ wget -qO- https://get.casaos.io | bash &>/dev/null msg_ok "Installed CasaOS" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 7ff88b3b..9f076d43 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y unzip msg_ok "Installed Dependencies" @@ -104,6 +105,7 @@ $STD bash <(curl -fsSL https://get.casaos.io) msg_ok "Installed CasaOS" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 8fe7d7fd..e8c2fdd3 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -107,6 +107,7 @@ systemctl enable --now changedetection &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index 313d35cc..ae77b3a0 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y pip msg_ok "Installed Dependencies" @@ -108,6 +109,7 @@ $STD systemctl enable --now changedetection msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index ebd00e41..0bee1960 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git $STD apt-get install -y make $STD apt-get install -y g++ @@ -114,6 +115,7 @@ $STD update-rc.d cronicled defaults msg_ok "Installed Cronicle Primary Server" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/daemonsync-install.sh b/install/daemonsync-install.sh index 3936e378..9f68ed71 100644 --- a/install/daemonsync-install.sh +++ b/install/daemonsync-install.sh @@ -93,6 +93,7 @@ sudo dpkg -i daemonsync_2.2.0.0059_amd64.deb &>/dev/null msg_ok "Installed Daemon Sync Server" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 557f6505..670d3c2e 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y g++-multilib msg_ok "Installed Dependencies" @@ -93,6 +94,7 @@ $STD dpkg -i daemonsync_2.2.0.0059_amd64.deb msg_ok "Installed Daemon Sync Server" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 72155a18..680a95cc 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -124,6 +124,7 @@ sudo systemctl enable dashy &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 3e6391e8..205163bf 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -124,6 +125,7 @@ systemctl start dashy msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/debian-install.sh b/install/debian-install.sh index dca29c9b..0029b4e4 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -86,6 +86,7 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 13ff3d34..ffb9f70b 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -83,9 +83,11 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/deconz-install.sh b/install/deconz-install.sh index cef9767d..18395883 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -118,6 +118,7 @@ systemctl enable deconz &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 691f8f65..fa12d272 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -117,6 +118,7 @@ $STD systemctl enable --now deconz msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 43c0214f..cb4bebc7 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing pip3" @@ -131,6 +132,7 @@ systemctl enable --now -q deluge-web.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/docker-install.sh b/install/docker-install.sh index de2a015f..df358aba 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -148,6 +148,7 @@ if [[ $DOCKER_COMPOSE == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 82cd8d7f..c0edccb1 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" get_latest_release() { @@ -148,6 +149,7 @@ if [[ $DOCKER_COMPOSE == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/emby-install.sh b/install/emby-install.sh index fcd7396c..3ce66a06 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -107,6 +107,7 @@ dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null msg_ok "Installed Emby" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 8982246c..a13941c0 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then @@ -107,6 +108,7 @@ $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb msg_ok "Installed Emby" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/emqx-install.sh b/install/emqx-install.sh index e40bed9c..49adfa50 100644 --- a/install/emqx-install.sh +++ b/install/emqx-install.sh @@ -92,6 +92,7 @@ systemctl enable --now emqx msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index cc8f968f..718f0089 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing EMQX" @@ -92,6 +93,7 @@ $STD systemctl enable --now emqx msg_ok "Installed EMQX" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/esphome-install.sh b/install/esphome-install.sh index d624ad84..8a1b73d5 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -113,6 +113,7 @@ systemctl start esphomeDashboard msg_ok "Installed ESPHome Dashboard" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index 22f1a6f2..bddd0035 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -113,6 +114,7 @@ systemctl start esphomeDashboard msg_ok "Installed ESPHome Dashboard" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/grafana-install.sh b/install/grafana-install.sh index 4235bd26..efc51a98 100644 --- a/install/grafana-install.sh +++ b/install/grafana-install.sh @@ -100,6 +100,7 @@ apt-get install -y grafana &>/dev/null msg_ok "Installed Grafana" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 23fc0f5b..189cbae3 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg $STD apt-get install -y apt-transport-https $STD apt-get install -y software-properties-common @@ -100,6 +101,7 @@ $STD apt-get install -y grafana msg_ok "Installed Grafana" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/grocy-install.sh b/install/grocy-install.sh index fcc019e7..1d7acc0a 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -130,6 +130,7 @@ systemctl reload apache2 msg_ok "Installed grocy" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index 85ee376c..1e4c784b 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y apache2 $STD apt-get install -y unzip $STD apt-get install -y apt-transport-https @@ -130,6 +131,7 @@ systemctl reload apache2 msg_ok "Installed grocy" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index c9ef0bd7..cf19a76c 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -124,6 +124,7 @@ sudo systemctl enable --now heimdall.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index 41185b39..33e8ef13 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing PHP" @@ -124,6 +125,7 @@ $STD sudo systemctl enable --now heimdall.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index e997f268..a9fb4de6 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -180,6 +180,7 @@ systemctl enable homeassistant &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 37131755..6070a81a 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -97,6 +97,7 @@ $STD apt-get install -y \ git \ curl \ sudo \ + mc \ llvm \ libncursesw5-dev \ xz-utils \ @@ -166,6 +167,7 @@ $STD systemctl enable --now homeassistant msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 7ad489d5..19998207 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -332,6 +332,7 @@ sudo chmod +x /root/update-containers.sh msg_ok "Created Update Menu Script" mkdir /root/hass_config PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index cb1fa779..603028b3 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing runlike" @@ -151,6 +152,7 @@ $STD docker run -d \ msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh index 1841a555..3fdc5a6b 100644 --- a/install/homebridge-install.sh +++ b/install/homebridge-install.sh @@ -103,6 +103,7 @@ sudo hb-service install --user homebridge &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index af5fdd30..bd218d9e 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" @@ -103,6 +104,7 @@ $STD hb-service install --user homebridge msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/homepage-install.sh b/install/homepage-install.sh index c48b139b..b69d538c 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -122,6 +122,7 @@ systemctl enable --now homepage &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index b477f518..bf0b8e4b 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -122,6 +123,7 @@ $STD systemctl enable --now homepage msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index d6c42232..c9e8172e 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y unzip $STD apt-get install -y pip msg_ok "Installed Dependencies" @@ -112,6 +113,7 @@ $STD systemctl enable --now homer msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh index ee8a3c9f..29644340 100644 --- a/install/hyperion-install.sh +++ b/install/hyperion-install.sh @@ -97,6 +97,7 @@ systemctl enable --now hyperion@root.service &>/dev/null msg_ok "Installed Hyperion" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index fca9b2d9..13263722 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y lsb-release $STD apt-get install -y gpg $STD apt-get install -y apt-transport-https @@ -99,6 +100,7 @@ $STD systemctl enable --now hyperion@root.service msg_ok "Installed Hyperion" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh index 3c57b2c8..1d11d97f 100644 --- a/install/influxdb-install.sh +++ b/install/influxdb-install.sh @@ -125,6 +125,7 @@ if [[ $TELEGRAF == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index dcd61d3d..27e263e9 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y lsb-base $STD apt-get install -y lsb-release $STD apt-get install -y gnupg2 @@ -127,6 +128,7 @@ if [[ $TELEGRAF == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/iobroker-install.sh b/install/iobroker-install.sh index 3bcb2570..813e9c46 100644 --- a/install/iobroker-install.sh +++ b/install/iobroker-install.sh @@ -91,6 +91,7 @@ curl -sLf https://iobroker.net/install.sh | bash - &>/dev/null msg_ok "Installed ioBroker" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index c25ff672..b592dced 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing ioBroker (Patience)" @@ -91,6 +92,7 @@ $STD bash <(curl -fsSL https://iobroker.net/install.sh) msg_ok "Installed ioBroker" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index d70f29ce..94c8ad5f 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -132,6 +132,7 @@ ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 667b3ace..2f0f1126 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y apt-transport-https $STD apt-get install -y software-properties-common msg_ok "Installed Dependencies" @@ -131,6 +132,7 @@ ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index 785160c7..24b67810 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -107,6 +108,7 @@ $STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/ msg_ok "Installed Helm" fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 6ef9c43d..316ecaf1 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -77,6 +77,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Kavita" @@ -106,6 +107,7 @@ systemctl enable --now -q kavita.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh index 00128983..92488072 100644 --- a/install/keycloak-install.sh +++ b/install/keycloak-install.sh @@ -113,6 +113,7 @@ systemctl enable --now keycloak.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 032c6a6b..797046df 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies (Patience)" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y openjdk-11-jdk msg_ok "Installed Dependencies" @@ -110,6 +111,7 @@ $STD systemctl enable --now keycloak.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index 53d35fcc..061fbd31 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y sqlite3 $STD apt-get install -y libchromaprint-tools $STD apt-get install -y mediainfo @@ -117,6 +118,7 @@ systemctl enable --now -q lidarr msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/magicmirror-install.sh b/install/magicmirror-install.sh index 71bd489a..37ada095 100644 --- a/install/magicmirror-install.sh +++ b/install/magicmirror-install.sh @@ -215,6 +215,7 @@ systemctl enable --now magicmirror &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 3405239b..1902ced3 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -215,6 +216,7 @@ $STD systemctl enable --now magicmirror msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index 12eeba97..cd499979 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -108,6 +108,7 @@ if [[ $ADMINER == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 83f6d689..8985b950 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing MariaDB" @@ -108,6 +109,7 @@ if [[ $ADMINER == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh index 77233afc..af40b17d 100644 --- a/install/meshcentral-install.sh +++ b/install/meshcentral-install.sh @@ -102,6 +102,7 @@ node node_modules/meshcentral --install &>/dev/null msg_ok "Installed MeshCentral" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index ebc598f8..0559a932 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" @@ -102,6 +103,7 @@ $STD node node_modules/meshcentral --install msg_ok "Installed MeshCentral" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index 2d116c01..7d819d66 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -121,6 +121,7 @@ systemctl start motioneye msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index f6a1e5e4..57a103de 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y cifs-utils msg_ok "Installed Dependencies" @@ -121,6 +122,7 @@ systemctl start motioneye msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 70f9efeb..c9e90259 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -98,6 +98,7 @@ apt-get -y install mosquitto-clients &>/dev/null msg_ok "Installed Mosquitto MQTT Broker" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 8ab82ce6..dfd7fd03 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -98,6 +99,7 @@ $STD apt-get -y install mosquitto-clients msg_ok "Installed Mosquitto MQTT Broker" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 1cca4611..c700bdb0 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -114,6 +114,7 @@ sudo systemctl enable n8n &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 64f241d5..03a27b72 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" @@ -113,6 +114,7 @@ $STD systemctl enable --now n8n msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh index 763d5353..e746cf32 100644 --- a/install/navidrome-install.sh +++ b/install/navidrome-install.sh @@ -141,6 +141,7 @@ systemctl enable --now navidrome.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index a6230259..f0c9e767 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies (patience)" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y ffmpeg msg_ok "Installed Dependencies" @@ -141,6 +142,7 @@ $STD systemctl enable --now navidrome.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh index ec0729d7..5ea6ffa3 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-install.sh @@ -92,6 +92,7 @@ sudo service apache2 restart msg_ok "Installed NextCloudPi" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 356f2a8c..2fbce9fc 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" @@ -93,6 +94,7 @@ service apache2 restart msg_ok "Installed NextCloudPi" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/nginx-proxy-manager-install.sh b/install/nginx-proxy-manager-install.sh index 88c11cdd..c2dba3e7 100644 --- a/install/nginx-proxy-manager-install.sh +++ b/install/nginx-proxy-manager-install.sh @@ -246,6 +246,7 @@ EOF msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 25de6ad9..3b752773 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -85,6 +85,7 @@ msg_info "Installing Dependencies" $STD apt-get update $STD apt-get -y install \ sudo \ + mc \ curl \ gnupg \ make \ @@ -247,6 +248,7 @@ EOF msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh index 0099b7bd..491eb153 100644 --- a/install/nocodb-install.sh +++ b/install/nocodb-install.sh @@ -120,6 +120,7 @@ systemctl enable --now nocodb.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index 967a506e..bcf5d676 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -120,6 +121,7 @@ systemctl enable --now nocodb.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/node-red-install.sh b/install/node-red-install.sh index 2169624a..85df743b 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -122,6 +122,7 @@ systemctl enable --now nodered.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index a6613d6e..a554c35b 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -123,6 +124,7 @@ $STD systemctl enable --now nodered.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/omada-install.sh b/install/omada-install.sh index 0daab6a0..bec67474 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -97,6 +97,7 @@ sudo dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb &>/dev/null msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 898c75a4..dd1e986b 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -82,11 +82,12 @@ $STD apt-get -y upgrade msg_ok "Updated Container OS" msg_info "Installing Dependencies" -$STD apt-get -y install curl -$STD apt-get -y install sudo -$STD apt-get -y install gnupg -$STD apt-get -y install openjdk-8-jre-headless -$STD apt-get -y install jsvc +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +$STD apt-get install -y openjdk-8-jre-headless +$STD apt-get install -y jsvc wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed Dependencies" @@ -97,6 +98,7 @@ $STD dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb msg_ok "Installed Omada Controller" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/omv-install.sh b/install/omv-install.sh index 415e428b..0a98be6f 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -109,6 +109,7 @@ omv-confdbadm populate msg_ok "Installed OpenMediaVault" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index c3a10912..89bc3116 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -109,6 +110,7 @@ omv-confdbadm populate msg_ok "Installed OpenMediaVault" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/openhab-install.sh b/install/openhab-install.sh index 5736c2b0..ef7dc48f 100644 --- a/install/openhab-install.sh +++ b/install/openhab-install.sh @@ -109,6 +109,7 @@ systemctl start openhab.service msg_ok "Installed openHAB" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index f5df107e..ced8d90d 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg $STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" @@ -108,6 +109,7 @@ $STD systemctl enable --now openhab.service msg_ok "Installed openHAB" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index a994c2f3..87d509eb 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -263,6 +263,7 @@ systemctl enable --now paperless-consumer paperless-webserver paperless-schedule msg_ok "Finished installing Paperless-ngx" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index d9bf955e..8040e113 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -96,7 +96,8 @@ $STD apt-get install -y --no-install-recommends \ libzbar0 \ poppler-utils \ default-libmysqlclient-dev \ - sudo + sudo \ + mc msg_ok "Installed Paperless-ngx Dependencies" msg_info "Installing OCR Dependencies" @@ -265,6 +266,7 @@ $STD systemctl enable --now paperless-consumer paperless-webserver paperless-sch msg_ok "Created Services" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 6b6ec3f7..523bdf41 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -181,6 +181,7 @@ WantedBy=multi-user.target" >$service_path msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 352d6096..661ab7d9 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -85,6 +85,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies (Patience)" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gcc $STD apt-get install -y g++ $STD apt-get install -y git @@ -181,6 +182,7 @@ WantedBy=multi-user.target" >$service_path msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/pihole-install.sh b/install/pihole-install.sh index 8e3783ac..3b7de2a2 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -111,6 +111,7 @@ curl -sSL https://install.pi-hole.net | bash /dev/stdin --unattended &>/dev/null msg_ok "Installed Pi-hole" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 300ed2d8..87bc2d69 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -85,6 +85,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y ufw $STD apt-get install -y ntp msg_ok "Installed Dependencies" @@ -111,6 +112,7 @@ $STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended msg_ok "Installed Pi-hole" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/plex-install.sh b/install/plex-install.sh index 93527256..dc5ba5e2 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -111,6 +111,7 @@ apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver &>/dev/n msg_ok "Installed Plex Media Server" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 4796b4fb..b048ada9 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -111,6 +112,7 @@ $STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver msg_ok "Installed Plex Media Server" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/podman-homeassistant-install.sh b/install/podman-homeassistant-install.sh index 7fb81641..3cd1679d 100644 --- a/install/podman-homeassistant-install.sh +++ b/install/podman-homeassistant-install.sh @@ -144,6 +144,7 @@ systemctl enable homeassistant &>/dev/null msg_ok "Installed Home Assistant" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 5f302e48..7ed0482b 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Podman" @@ -113,6 +114,7 @@ $STD systemctl enable --now homeassistant msg_ok "Installed Home Assistant" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 82432ae6..48038cba 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Podman" @@ -92,6 +93,7 @@ echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registr msg_ok "Installed Podman" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/postgresql-install.sh b/install/postgresql-install.sh index 88cd544d..4e0c8849 100644 --- a/install/postgresql-install.sh +++ b/install/postgresql-install.sh @@ -216,6 +216,7 @@ if [[ $ADMINER == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 7ab0e05f..a092835d 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -215,6 +216,7 @@ if [[ $ADMINER == "Y" ]]; then fi PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/prometheus-install.sh b/install/prometheus-install.sh index c0493b2f..fd38a1b9 100644 --- a/install/prometheus-install.sh +++ b/install/prometheus-install.sh @@ -121,6 +121,7 @@ sudo systemctl enable --now prometheus &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index f46343fa..b5f37958 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Prometheus" @@ -122,6 +123,7 @@ $STD sudo systemctl enable --now prometheus msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 71fcd5fb..f7f9edd8 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y sqlite3 msg_ok "Installed Dependencies" @@ -115,6 +116,7 @@ systemctl enable --now -q prowlarr msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 63536c41..a0a84993 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y sqlite3 msg_ok "Installed Dependencies" @@ -115,6 +116,7 @@ systemctl enable --now -q radarr msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index 4ab6fd6c..8c90fcc2 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y sqlite3 msg_ok "Installed Dependencies" @@ -115,6 +116,7 @@ systemctl enable --now -q readarr msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 1790be9a..cd231485 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y unzip $STD apt-get install -y par2 $STD apt-get install -y unrar-free @@ -117,6 +118,7 @@ systemctl enable --now -q sabnzbd.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 2347d59a..96380318 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -180,6 +180,7 @@ WantedBy=multi-user.target" >$service_path systemctl enable --now scrypted.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 27ae70da..40f4d6ac 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -98,7 +98,8 @@ $STD apt-get -y install \ librsvg2-dev \ pkg-config \ curl \ - sudo + sudo \ + mc msg_ok "Installed Dependencies" msg_info "Installing GStreamer" @@ -182,6 +183,7 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now scrypted.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index ba6fa2af..0c8510fa 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -150,6 +150,7 @@ pm2 list &>/dev/null msg_ok "Installed Shinobi" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 73e5eadb..6ea98787 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -91,7 +91,7 @@ if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then fi msg_info "Installing Dependencies" -$STD apt-get install -y curl sudo git +$STD apt-get install -y curl sudo git mc $STD apt-get install -y make zip net-tools $STD apt-get install -y gcc g++ cmake msg_ok "Installed Dependencies" @@ -150,6 +150,7 @@ $STD pm2 list msg_ok "Installed Shinobi" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 9d8a6585..f942d8ef 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg $STD apt-get install -y ca-certificates msg_ok "Installed Dependencies" @@ -96,6 +97,7 @@ $STD apt-get -o Dpkg::Options::="--force-confold" install -y sonarr msg_ok "Installed Sonarr" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh index f4f9d2ec..a6a09abd 100644 --- a/install/syncthing-install.sh +++ b/install/syncthing-install.sh @@ -99,6 +99,7 @@ systemctl restart syncthing@root.service msg_ok "Installed Syncthing" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 42f34a10..4845c1ec 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -101,6 +102,7 @@ systemctl restart syncthing@root.service msg_ok "Installed Syncthing" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 0bce29cd..43fc93cb 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y unzip msg_ok "Installed Dependencies" @@ -142,6 +143,7 @@ systemctl enable --now -q tdarr-node.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index dbd8ecd1..038275c2 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -91,6 +91,7 @@ curl -sSL https://download.technitium.com/dns/install.sh | sudo bash &>/dev/null msg_ok "Installed Technitium DNS" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index e3645c7c..a75fbc97 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Technitium DNS" @@ -91,6 +92,7 @@ $STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) msg_ok "Installed Technitium DNS" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/trilium-install.sh b/install/trilium-install.sh index c7f97023..d18a33c2 100644 --- a/install/trilium-install.sh +++ b/install/trilium-install.sh @@ -116,6 +116,7 @@ systemctl enable --now -q trilium msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 936eb6c6..5a6d2a36 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | @@ -116,6 +117,7 @@ systemctl enable --now -q trilium msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/ubuntu-install.sh b/install/ubuntu-install.sh index b090d307..0b1564d0 100644 --- a/install/ubuntu-install.sh +++ b/install/ubuntu-install.sh @@ -87,6 +87,7 @@ apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 03415a4b..a0e2f7c1 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -84,9 +84,11 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/umbrel-install.sh b/install/umbrel-install.sh index 95c1c376..d63ff40a 100644 --- a/install/umbrel-install.sh +++ b/install/umbrel-install.sh @@ -108,6 +108,7 @@ systemctl enable --now umbrel-startup.service &>/dev/null msg_ok "Installed Umbrel" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 0de53375..7468dfb3 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Umbrel (Patience)" @@ -105,6 +106,7 @@ $STD systemctl enable --now umbrel-startup.service msg_ok "Installed Umbrel" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 6dcd2e00..da6e91fd 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -99,6 +99,7 @@ wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && b msg_ok "Installed UniFi Network Application" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 6b8f7bfd..e86bdeb8 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -85,6 +85,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" read -r -p "Local Controller? " prompt @@ -100,6 +101,7 @@ $STD bash unifi-latest.sh --skip --add-repository $LOCAL msg_ok "Installed UniFi Network Application" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh index c542bba5..d314ad3c 100644 --- a/install/uptimekuma-install.sh +++ b/install/uptimekuma-install.sh @@ -120,6 +120,7 @@ systemctl enable --now uptime-kuma.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 87e80bc2..659c9685 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -120,6 +121,7 @@ $STD systemctl enable --now uptime-kuma.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/vaultwarden-install.sh b/install/vaultwarden-install.sh index 72a03a9e..0710c1ef 100644 --- a/install/vaultwarden-install.sh +++ b/install/vaultwarden-install.sh @@ -176,6 +176,7 @@ systemctl enable --now vaultwarden.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 510d78c1..e23a1d84 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -91,7 +91,8 @@ $STD apt-get -qqy install \ libmariadb-dev-compat \ libpq-dev \ curl \ - sudo + sudo \ + mc msg_ok "Installed Dependencies" WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | @@ -177,6 +178,7 @@ $STD systemctl enable --now vaultwarden.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index f05cf265..3e10887c 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y sqlite3 msg_ok "Installed Dependencies" @@ -115,6 +116,7 @@ systemctl enable --now -q whisparr msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index dc3efde8..f41c34d3 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -109,6 +109,7 @@ systemctl enable --now whoogle.service &>/dev/null msg_ok "Installed Whoogle" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index c8cb5ed3..0408a740 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing pip3" @@ -109,6 +110,7 @@ $STD systemctl enable --now whoogle.service msg_ok "Installed Whoogle" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index 8194d606..947ddbab 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -137,6 +137,7 @@ systemctl enable --now wikijs &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 4806102b..28ae5236 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" @@ -137,6 +138,7 @@ $STD systemctl enable --now wikijs msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh index 96e11ce9..92f6f77d 100644 --- a/install/wireguard-install.sh +++ b/install/wireguard-install.sh @@ -150,6 +150,7 @@ sudo systemctl start wg-dashboard.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 10da01e4..6c30ed01 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -101,6 +101,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gunicorn msg_ok "Installed Dependencies" @@ -109,6 +110,7 @@ $STD bash <(curl -fsSL https://install.pivpn.io) --unattended options.conf msg_ok "Installed WireGuard" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 19eeec06..e149ee21 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -83,6 +83,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg $STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' $STD apt-get install -y apt-transport-https @@ -96,6 +97,7 @@ $STD bash <(curl -fsSL https://install.yunohost.org) -a msg_ok "Installed YunoHost" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" chmod -x /etc/update-motd.d/* diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 1d488c49..38f70952 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -136,6 +136,7 @@ systemctl enable zigbee2mqtt.service &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 81452490..c703e95b 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y git $STD apt-get install -y make $STD apt-get install -y g++ @@ -136,6 +137,7 @@ $STD systemctl enable zigbee2mqtt.service msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh index b67f28d5..a101ffe6 100644 --- a/install/zwave-js-ui-install.sh +++ b/install/zwave-js-ui-install.sh @@ -112,6 +112,7 @@ systemctl enable zwave-js-ui &>/dev/null msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 601d9082..e1dace8a 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -84,6 +84,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y unzip msg_ok "Installed Dependencies" @@ -112,6 +113,7 @@ $STD systemctl enable zwave-js-ui msg_ok "Created Service" PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc if [[ $PASS != $ ]]; then msg_info "Customizing Container" rm /etc/motd From 2791098177694c740de88c8a961d95969e42b1cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 23 Jan 2023 10:46:38 -0500 Subject: [PATCH 4244/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f5212b19..8dbd128e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-23 + +### Changed + +- **ALL LXC's** + - Add [Midnight Commander (mc)](https://www.linuxcommand.org/lc3_adv_mc.php) + ## 2023-01-22 ### Changed From f99e8e198bd087ebcd4a2000f0ed5edbd9a851f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 23 Jan 2023 10:56:13 -0500 Subject: [PATCH 4245/6505] Update esphome-v5.sh fix typo --- ct/esphome-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index 647a05ca..e42069b0 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -333,7 +333,7 @@ pip3 install esphome --upgrade &>/dev/null msg_ok "Updated ESPHome" msg_info "Starting ESPHome" -systemctl stop esphomeDashboard +systemctl start esphomeDashboard msg_ok "Started ESPHome" msg_ok "Update Successfull" exit From d4af8afb3d31d982837a6364c6258acd0c522c55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 23 Jan 2023 16:51:29 -0500 Subject: [PATCH 4246/6505] Update homepage-v5-install.sh fix install --- install/homepage-v5-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index bf0b8e4b..c37009ba 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -93,13 +93,14 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" $STD apt-get install -y nodejs -$STD npm install -g pnpm +$STD npm install -g npm@9.3.1 msg_ok "Installed Node.js" msg_info "Installing Homepage" $STD git clone https://github.com/benphelps/homepage.git /opt/homepage cd /opt/homepage mkdir -p config +cp /opt/homepage/src/skeleton/* /opt/homepage/config $STD pnpm install $STD pnpm build msg_ok "Installed Homepage" From bfe427535e53baf60b31e7d8a4ebf9bf17a4327d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 23 Jan 2023 17:01:41 -0500 Subject: [PATCH 4247/6505] Update homepage-v5-install.sh --- install/homepage-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index c37009ba..f1da0ee9 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -93,7 +93,7 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" $STD apt-get install -y nodejs -$STD npm install -g npm@9.3.1 +$STD npm install -g pnpm msg_ok "Installed Node.js" msg_info "Installing Homepage" From 976ab3e597c165f7e76486066815fcabb1a5fc3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 23 Jan 2023 17:07:29 -0500 Subject: [PATCH 4248/6505] Update homepage-v5-install.sh --- install/homepage-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index f1da0ee9..7069e0ee 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -96,7 +96,7 @@ $STD apt-get install -y nodejs $STD npm install -g pnpm msg_ok "Installed Node.js" -msg_info "Installing Homepage" +msg_info "Installing Homepage (Patience)" $STD git clone https://github.com/benphelps/homepage.git /opt/homepage cd /opt/homepage mkdir -p config From 4828b02c9f2b77a60bd79501c25fe035052e0fd9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 24 Jan 2023 18:37:06 -0500 Subject: [PATCH 4249/6505] Create transmission-v5-install.sh --- install/transmission-v5-install.sh | 122 +++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 install/transmission-v5-install.sh diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh new file mode 100644 index 00000000..ceb6ddbd --- /dev/null +++ b/install/transmission-v5-install.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +silent() { "$@" > /dev/null 2>&1; } +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + + +msg_info "Installing Transmission" +$STD apt-get install -y transmission-daemon +systemctl stop transmission-daemon +sed -i '{s/"rpc-whitelist-enabled": true/"rpc-whitelist-enabled": false/g; s/"rpc-host-whitelist-enabled": true,/"rpc-host-whitelist-enabled": false,/g}' /etc/transmission-daemon/settings.json +systemctl start transmission-daemon +msg_ok "Installed Transmission" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From c5d30ac3b0377acc3d6315f3d1a6d05b81a8aadc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 24 Jan 2023 18:40:59 -0500 Subject: [PATCH 4250/6505] Create transmission-v5.sh --- ct/transmission-v5.sh | 370 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 ct/transmission-v5.sh diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh new file mode 100644 index 00000000..7b991ea3 --- /dev/null +++ b/ct/transmission-v5.sh @@ -0,0 +1,370 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ______ _ _ + /_ __/________ _____v5_________ ___ (_)_________(_)___ ____ + / / / ___/ __ `/ __ \/ ___/ __ `__ \/ / ___/ ___/ / __ \/ __ \ + / / / / / /_/ / / / (__ ) / / / / / (__ |__ ) / /_/ / / / / +/_/ /_/ \__,_/_/ /_/____/_/ /_/ /_/_/____/____/_/\____/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Transmission" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} +clear +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9091/transmission${CL} \n" From b048583513f16e35d7f1e7b90677d33ff83aeef5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 24 Jan 2023 18:51:10 -0500 Subject: [PATCH 4251/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 8dbd128e..ebb1ef9f 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-24 + +### Changed + +- **Transmission LXC** + - NEW Script + ## 2023-01-23 ### Changed From 263c59944a371d329fd489d050deb9aeff6ca160 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 24 Jan 2023 23:22:11 -0500 Subject: [PATCH 4252/6505] Update sabnzbd-v5-install.sh add 7zip --- install/sabnzbd-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index cd231485..e793adf4 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -87,6 +87,7 @@ $STD apt-get install -y mc $STD apt-get install -y unzip $STD apt-get install -y par2 $STD apt-get install -y unrar-free +$STD apt-get install -y p7zip-full msg_ok "Installed Dependencies" msg_info "Installing pip3" From e392cf9811db00509bfe872d1808b9d373f91334 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 08:14:42 -0500 Subject: [PATCH 4253/6505] add arch check (#981) --- ct/adguard-v4.sh | 9 +++++++++ ct/adguard-v5.sh | 10 ++++++++++ ct/alpine-v5.sh | 10 ++++++++++ ct/archlinux-v5.sh | 10 ++++++++++ ct/autobrr-v5.sh | 10 ++++++++++ ct/blocky-v4.sh | 9 +++++++++ ct/blocky-v5.sh | 10 ++++++++++ ct/casaos-v4.sh | 9 +++++++++ ct/casaos-v5.sh | 10 ++++++++++ ct/changedetection-v4.sh | 9 +++++++++ ct/changedetection-v5.sh | 10 ++++++++++ ct/cronicle-v5.sh | 10 ++++++++++ ct/daemonsync-v4.sh | 9 +++++++++ ct/daemonsync-v5.sh | 10 ++++++++++ ct/dashy-v4.sh | 9 +++++++++ ct/dashy-v5.sh | 10 ++++++++++ ct/debian-v4.sh | 9 +++++++++ ct/debian-v5.sh | 10 ++++++++++ ct/deconz-v4.sh | 9 +++++++++ ct/deconz-v5.sh | 10 ++++++++++ ct/deluge-v5.sh | 10 ++++++++++ ct/docker-v4.sh | 9 +++++++++ ct/docker-v5.sh | 10 ++++++++++ ct/emby-v4.sh | 9 +++++++++ ct/emby-v5.sh | 10 ++++++++++ ct/emqx-v4.sh | 9 +++++++++ ct/emqx-v5.sh | 10 ++++++++++ ct/esphome-v4.sh | 9 +++++++++ ct/esphome-v5.sh | 10 ++++++++++ ct/grafana-v4.sh | 9 +++++++++ ct/grafana-v5.sh | 10 ++++++++++ ct/grocy-v4.sh | 9 +++++++++ ct/grocy-v5.sh | 10 ++++++++++ ct/heimdalldashboard-v4.sh | 9 +++++++++ ct/heimdalldashboard-v5.sh | 10 ++++++++++ ct/homeassistant-core-v4.sh | 9 +++++++++ ct/homeassistant-core-v5.sh | 1 + ct/homeassistant-v4.sh | 9 +++++++++ ct/homeassistant-v5.sh | 10 ++++++++++ ct/homebridge-v4.sh | 9 +++++++++ ct/homebridge-v5.sh | 10 ++++++++++ ct/homepage-v4.sh | 9 +++++++++ ct/homepage-v5.sh | 10 ++++++++++ ct/homer-v5.sh | 10 ++++++++++ ct/hyperion-v4.sh | 9 +++++++++ ct/hyperion-v5.sh | 10 ++++++++++ ct/influxdb-v4.sh | 9 +++++++++ ct/influxdb-v5.sh | 10 ++++++++++ ct/iobroker-v4.sh | 9 +++++++++ ct/iobroker-v5.sh | 10 ++++++++++ ct/jellyfin-v4.sh | 9 +++++++++ ct/jellyfin-v5.sh | 10 ++++++++++ ct/k0s-v5.sh | 10 ++++++++++ ct/kavita-v5.sh | 10 ++++++++++ ct/keycloak-v4.sh | 9 +++++++++ ct/keycloak-v5.sh | 10 ++++++++++ ct/lidarr-v5.sh | 10 ++++++++++ ct/magicmirror-v4.sh | 9 +++++++++ ct/magicmirror-v5.sh | 10 ++++++++++ ct/mariadb-v4.sh | 9 +++++++++ ct/mariadb-v5.sh | 10 ++++++++++ ct/meshcentral-v4.sh | 9 +++++++++ ct/meshcentral-v5.sh | 10 ++++++++++ ct/motioneye-v4.sh | 9 +++++++++ ct/motioneye-v5.sh | 10 ++++++++++ ct/mqtt-v5.sh | 10 ++++++++++ ct/n8n-v4.sh | 9 +++++++++ ct/n8n-v5.sh | 10 ++++++++++ ct/navidrome-v4.sh | 9 +++++++++ ct/navidrome-v5.sh | 10 ++++++++++ ct/nextcloudpi-v4.sh | 9 +++++++++ ct/nextcloudpi-v5.sh | 10 ++++++++++ ct/nginx-proxy-manager-v4.sh | 9 +++++++++ ct/nginxproxymanager-v5.sh | 10 ++++++++++ ct/nocodb-v4.sh | 9 +++++++++ ct/nocodb-v5.sh | 10 ++++++++++ ct/node-red-v4.sh | 9 +++++++++ ct/node-red-v5.sh | 10 ++++++++++ ct/omada-v4.sh | 9 +++++++++ ct/omada-v5.sh | 10 ++++++++++ ct/omv-v4.sh | 9 +++++++++ ct/omv-v5.sh | 10 ++++++++++ ct/openhab-v4.sh | 9 +++++++++ ct/openhab-v5.sh | 10 ++++++++++ ct/paperless-ngx-v4.sh | 9 +++++++++ ct/paperless-ngx-v5.sh | 10 ++++++++++ ct/photoprism-v4.sh | 9 +++++++++ ct/photoprism-v5.sh | 10 ++++++++++ ct/pihole-v4.sh | 9 +++++++++ ct/pihole-v5.sh | 10 ++++++++++ ct/plex-v4.sh | 9 +++++++++ ct/plex-v5.sh | 10 ++++++++++ ct/podman-homeassistant-v4.sh | 9 +++++++++ ct/podman-homeassistant-v5.sh | 10 ++++++++++ ct/podman-v5.sh | 10 ++++++++++ ct/postgresql-v4.sh | 9 +++++++++ ct/postgresql-v5.sh | 10 ++++++++++ ct/prometheus-v4.sh | 9 +++++++++ ct/prometheus-v5.sh | 10 ++++++++++ ct/prowlarr-v5.sh | 10 ++++++++++ ct/radarr-v5.sh | 10 ++++++++++ ct/readarr-v5.sh | 10 ++++++++++ ct/sabnzbd-v5.sh | 10 ++++++++++ ct/scrypted-v4.sh | 9 +++++++++ ct/scrypted-v5.sh | 10 ++++++++++ ct/shinobi-v4.sh | 9 +++++++++ ct/shinobi-v5.sh | 10 ++++++++++ ct/sonarr-v5.sh | 10 ++++++++++ ct/syncthing-v4.sh | 9 +++++++++ ct/syncthing-v5.sh | 10 ++++++++++ ct/tdarr-v5.sh | 10 ++++++++++ ct/technitiumdns-v4.sh | 9 +++++++++ ct/technitiumdns-v5.sh | 10 ++++++++++ ct/transmission-v5.sh | 10 ++++++++++ ct/trilium-v4.sh | 9 +++++++++ ct/trilium-v5.sh | 10 ++++++++++ ct/ubuntu-v4.sh | 9 +++++++++ ct/ubuntu-v5.sh | 10 ++++++++++ ct/umbrel-v4.sh | 9 +++++++++ ct/umbrel-v5.sh | 10 ++++++++++ ct/unifi-v4.sh | 9 +++++++++ ct/unifi-v5.sh | 10 ++++++++++ ct/uptimekuma-v4.sh | 9 +++++++++ ct/uptimekuma-v5.sh | 10 ++++++++++ ct/vaultwarden-v4.sh | 9 +++++++++ ct/vaultwarden-v5.sh | 10 ++++++++++ ct/whisparr-v5.sh | 10 ++++++++++ ct/whoogle-v4.sh | 9 +++++++++ ct/whoogle-v5.sh | 10 ++++++++++ ct/wikijs-v4.sh | 9 +++++++++ ct/wikijs-v5.sh | 10 ++++++++++ ct/wireguard-v4.sh | 9 +++++++++ ct/wireguard-v5.sh | 10 ++++++++++ ct/yunohost-v5.sh | 10 ++++++++++ ct/zigbee2mqtt-v4.sh | 9 +++++++++ ct/zigbee2mqtt-v5.sh | 10 ++++++++++ ct/zwave-js-ui-v4.sh | 9 +++++++++ ct/zwave-js-ui-v5.sh | 10 ++++++++++ 138 files changed, 1312 insertions(+) diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh index c430c632..c7f12804 100644 --- a/ct/adguard-v4.sh +++ b/ct/adguard-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index da147dfc..56035b9d 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then NEXTID=$(pvesh get /cluster/nextid) @@ -350,6 +359,7 @@ exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index db759dd5..5ef6197c 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -329,6 +338,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index da561a1f..015661f0 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 26e18c8c..0bf2ba40 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -342,6 +351,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh index 7c681676..507d2f71 100644 --- a/ct/blocky-v4.sh +++ b/ct/blocky-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index 59d2c74d..d82c7a93 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh index 59da684a..b3ae3583 100644 --- a/ct/casaos-v4.sh +++ b/ct/casaos-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 809f3d74..f41c1c96 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -342,6 +351,7 @@ exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/changedetection-v4.sh b/ct/changedetection-v4.sh index 61bec458..95108992 100644 --- a/ct/changedetection-v4.sh +++ b/ct/changedetection-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 88aa8595..d0d7b890 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -332,6 +341,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index f10caccb..41f618b4 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} Master LXC. Proceed?" 10 58); then @@ -379,6 +388,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh index d8d5fca0..faaf9a81 100644 --- a/ct/daemonsync-v4.sh +++ b/ct/daemonsync-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 39305f4a..c21c5de6 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh index d824ab70..f128a191 100644 --- a/ct/dashy-v4.sh +++ b/ct/dashy-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index eb18f3a7..98ed2189 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -359,6 +368,7 @@ exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh index 7f6c9410..441ebe05 100644 --- a/ct/debian-v4.sh +++ b/ct/debian-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index f4a14602..25af81a5 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh index 7740e731..87a41090 100644 --- a/ct/deconz-v4.sh +++ b/ct/deconz-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 4a50fe38..7b733470 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index d77b8d36..8450b457 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -329,6 +338,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh index 6e18ded5..d3a6ee55 100644 --- a/ct/docker-v4.sh +++ b/ct/docker-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index c90ee4b0..8b29ccd8 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then NEXTID=$(pvesh get /cluster/nextid) @@ -339,6 +348,7 @@ msg_ok "Updated ${APP} LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh index 0c381a19..4935a5c9 100644 --- a/ct/emby-v4.sh +++ b/ct/emby-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 1c8f4031..e5637ede 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -352,6 +361,7 @@ exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh index 64779851..032b2ec9 100644 --- a/ct/emqx-v4.sh +++ b/ct/emqx-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 053de5a0..45471134 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -332,6 +341,7 @@ msg_ok "Updated ${APP} LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh index e6f44de4..dc4fe5bf 100644 --- a/ct/esphome-v4.sh +++ b/ct/esphome-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index e42069b0..a3c650a5 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -339,6 +348,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh index f6de91c3..f89a2857 100644 --- a/ct/grafana-v4.sh +++ b/ct/grafana-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 71c801d9..291af104 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh index 90e9cd22..e355e177 100644 --- a/ct/grocy-v4.sh +++ b/ct/grocy-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 1f45f898..7b404d1f 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -332,6 +341,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh index af75b933..f39c042f 100644 --- a/ct/heimdalldashboard-v4.sh +++ b/ct/heimdalldashboard-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 466269e5..62bf3c8e 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -412,6 +421,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh index 93a64643..ae1cd2c7 100644 --- a/ct/homeassistant-core-v4.sh +++ b/ct/homeassistant-core-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 46bf2b5f..8dfdc3cd 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -409,6 +409,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh index 80218197..1407f92c 100644 --- a/ct/homeassistant-v4.sh +++ b/ct/homeassistant-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 043eebb4..a9320d6c 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -407,6 +416,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh index 2c3eaa77..5aa8300e 100644 --- a/ct/homebridge-v4.sh +++ b/ct/homebridge-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index f635f3d6..d0ed805b 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh index 5b7430fe..07eea829 100644 --- a/ct/homepage-v4.sh +++ b/ct/homepage-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 5e293376..0ddcf04f 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -339,6 +348,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index bc702f38..281ffdb5 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -352,6 +361,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/hyperion-v4.sh b/ct/hyperion-v4.sh index d9125d52..2b0fc124 100644 --- a/ct/hyperion-v4.sh +++ b/ct/hyperion-v4.sh @@ -70,6 +70,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index f2b83c82..ac0a241d 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -334,6 +343,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh index b1ca3aa8..6ee8e824 100644 --- a/ct/influxdb-v4.sh +++ b/ct/influxdb-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 18e5e1ef..e7dae7cf 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh index 4b54689b..b4515677 100644 --- a/ct/iobroker-v4.sh +++ b/ct/iobroker-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index e5863828..09ca2662 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh index aab2b0a2..774a3738 100644 --- a/ct/jellyfin-v4.sh +++ b/ct/jellyfin-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 91b007ef..77d93abe 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -342,6 +351,7 @@ msg_ok "Updated ${APP} LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 7a578549..84f72199 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index 7b2dd5a6..2b80642e 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -331,6 +340,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh index 3266c386..5237a3ed 100644 --- a/ct/keycloak-v4.sh +++ b/ct/keycloak-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index f23f1c32..ab061363 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -334,6 +343,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index aa63a68d..11929ba5 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh index 6c172502..2342d731 100644 --- a/ct/magicmirror-v4.sh +++ b/ct/magicmirror-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 199ded64..1b523e7a 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -335,6 +344,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh index cf31225e..5281c61d 100644 --- a/ct/mariadb-v4.sh +++ b/ct/mariadb-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 82f7c71a..716e925f 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh index 54c21a91..b1a2b983 100644 --- a/ct/meshcentral-v4.sh +++ b/ct/meshcentral-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index ac9500ff..75444ab2 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh index 41ead7e5..f2101198 100644 --- a/ct/motioneye-v4.sh +++ b/ct/motioneye-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 7d4fe34c..a267063a 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -332,6 +341,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 707624b8..ade50ece 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then NEXTID=$(pvesh get /cluster/nextid) @@ -333,6 +342,7 @@ exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh index 8cff0d8d..58af3ddb 100644 --- a/ct/n8n-v4.sh +++ b/ct/n8n-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 69437e2a..87888de4 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh index 893f9311..3f188aa6 100644 --- a/ct/navidrome-v4.sh +++ b/ct/navidrome-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index beab0978..3754dfa3 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -344,6 +353,7 @@ exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh index e0a70b50..c1ff886d 100644 --- a/ct/nextcloudpi-v4.sh +++ b/ct/nextcloudpi-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index a993d3bc..c57934f8 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh index a6ab98ad..23e60e9c 100644 --- a/ct/nginx-proxy-manager-v4.sh +++ b/ct/nginx-proxy-manager-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 94954f7f..88dba9c9 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -442,6 +451,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh index 2406fd20..80776771 100644 --- a/ct/nocodb-v4.sh +++ b/ct/nocodb-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 1fd54974..c7db9a0a 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -336,6 +345,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh index fec6b066..24568629 100644 --- a/ct/node-red-v4.sh +++ b/ct/node-red-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 3743a71a..9928b776 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -369,6 +378,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh index f4db3280..70fbbe6a 100644 --- a/ct/omada-v4.sh +++ b/ct/omada-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index e6aa93bd..23689d0e 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -331,6 +340,7 @@ function install_script() { fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh index e279912a..573745c9 100644 --- a/ct/omv-v4.sh +++ b/ct/omv-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index e7ed0d62..5adcf838 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -334,6 +343,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh index 2c1e1541..2d014284 100644 --- a/ct/openhab-v4.sh +++ b/ct/openhab-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 401b85b7..3e7fab93 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -334,6 +343,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh index 6ed7022c..1630ed49 100644 --- a/ct/paperless-ngx-v4.sh +++ b/ct/paperless-ngx-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 411463c0..25a0b51f 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -401,6 +410,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh index e645f8f2..1574037c 100644 --- a/ct/photoprism-v4.sh +++ b/ct/photoprism-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 4691eb67..c458183a 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -354,6 +363,7 @@ msg_ok "Update Successful" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh index 492692bc..891d272e 100644 --- a/ct/pihole-v4.sh +++ b/ct/pihole-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index a6e3e22f..3b46de9a 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh index 9f12ecb5..ba26e011 100644 --- a/ct/plex-v4.sh +++ b/ct/plex-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 537f8bf5..5274f9b7 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -352,6 +361,7 @@ exit fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh index 36a5fef9..5887d22a 100644 --- a/ct/podman-homeassistant-v4.sh +++ b/ct/podman-homeassistant-v4.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 995ca428..9a19d4b9 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -76,6 +76,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -383,6 +392,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 32670543..0deea5d2 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh index 771d0568..d1013485 100644 --- a/ct/postgresql-v4.sh +++ b/ct/postgresql-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index 73bf41f5..7cc1fd6f 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh index 474cc21e..a4106946 100644 --- a/ct/prometheus-v4.sh +++ b/ct/prometheus-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 8b46ddcf..a3c2a7b6 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index dbf5a5e8..589a1ff7 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index ad68253e..0f1b8a79 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index a8e596d0..b87aace9 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 2c3b0a1f..a6c859cc 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh index e8d364c9..3dd86f9b 100644 --- a/ct/scrypted-v4.sh +++ b/ct/scrypted-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 1070f901..12510995 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -334,6 +343,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/shinobi-v4.sh b/ct/shinobi-v4.sh index 427e7e7a..e52e3565 100644 --- a/ct/shinobi-v4.sh +++ b/ct/shinobi-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 4e3f1107..61dc52bf 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -343,6 +352,7 @@ msg_ok "Updated Shinobi LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 2207fb65..2fb46009 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh index c66e96e1..f6f928c1 100644 --- a/ct/syncthing-v4.sh +++ b/ct/syncthing-v4.sh @@ -70,6 +70,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 4825b5ab..0d7743d4 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -334,6 +343,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 0de99210..7b6f59f8 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh index d726ba0c..ca581f21 100644 --- a/ct/technitiumdns-v4.sh +++ b/ct/technitiumdns-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 9e55abd1..fac927a2 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -395,6 +404,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index 7b991ea3..e415d8f7 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated ${APP} LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh index 3a9ebe38..8fd5f853 100644 --- a/ct/trilium-v4.sh +++ b/ct/trilium-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 88cdc017..b8e733a7 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -352,6 +361,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh index 4c47da6d..803ce681 100644 --- a/ct/ubuntu-v4.sh +++ b/ct/ubuntu-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 6fb92d13..343b95f9 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -336,6 +345,7 @@ msg_ok "Updated ${APP} LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh index 2d663fca..9b557c03 100644 --- a/ct/umbrel-v4.sh +++ b/ct/umbrel-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 135b4218..b908617d 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -340,6 +349,7 @@ msg_ok "Updated ${APP} LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh index bf24121e..38229ab0 100644 --- a/ct/unifi-v4.sh +++ b/ct/unifi-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index d8f71fe2..b2267304 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -333,6 +342,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh index 630b2b04..289694da 100644 --- a/ct/uptimekuma-v4.sh +++ b/ct/uptimekuma-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 81f77d75..60c22a50 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -350,6 +359,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh index f4ec98da..be5fe841 100644 --- a/ct/vaultwarden-v4.sh +++ b/ct/vaultwarden-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 65002322..deed5797 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then NEXTID=$(pvesh get /cluster/nextid) @@ -401,6 +410,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index ed21646d..c00bcec0 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -329,6 +338,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh index 41cc947e..7d3a7f6c 100644 --- a/ct/whoogle-v4.sh +++ b/ct/whoogle-v4.sh @@ -68,6 +68,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index a92970eb..e6b6ef7d 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -332,6 +341,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh index bb5ad6b3..6fc2487f 100644 --- a/ct/wikijs-v4.sh +++ b/ct/wikijs-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index a8785853..1857c2fd 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -346,6 +355,7 @@ msg_ok "Update Successfull" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh index dd3b594f..532847ad 100644 --- a/ct/wireguard-v4.sh +++ b/ct/wireguard-v4.sh @@ -70,6 +70,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 333635b5..722884a6 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -388,6 +397,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 9a44f24e..973f62b8 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -328,6 +337,7 @@ msg_ok "Updated Debian LXC" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh index 46a81164..986309c5 100644 --- a/ct/zigbee2mqtt-v4.sh +++ b/ct/zigbee2mqtt-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 1d4d9cc1..10df801e 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -73,6 +73,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -363,6 +372,7 @@ msg_ok "Update Successful" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh index 317f5841..1125bd07 100644 --- a/ct/zwave-js-ui-v4.sh +++ b/ct/zwave-js-ui-v4.sh @@ -69,6 +69,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 3b7394df..9aff96ea 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -72,6 +72,15 @@ function PVE_CHECK() { exit fi } +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then @@ -346,6 +355,7 @@ msg_ok "Updated Successfully!\n" exit } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From c56f833f21ab37599c8f4096f3c2390652c86092 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 10:32:11 -0500 Subject: [PATCH 4254/6505] Update sabnzbd-v5-install.sh add unrar_6.0.3-1 --- install/sabnzbd-v5-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index e793adf4..6cd98a5c 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -86,14 +86,16 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y unzip $STD apt-get install -y par2 -$STD apt-get install -y unrar-free $STD apt-get install -y p7zip-full +wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_6.0.3-1+deb11u1_amd64.deb +$STD dpkg -i unrar_6.0.3-1+deb11u1_amd64.deb +rm unrar_6.0.3-1+deb11u1_amd64.deb msg_ok "Installed Dependencies" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" $STD apt-get install -y python3-setuptools $STD apt-get install -y python3-pip -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing SABnzbd" RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From 58db0a3be9f4866b3bd6dfe658cf8f1b1d32d47b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 10:42:35 -0500 Subject: [PATCH 4255/6505] Update Home Assistant VM's (#983) --- vm/{haos-vm-v4.sh => haos-vm-v5.sh} | 65 +++-- vm/haos.sh.gpg | Bin 3852 -> 0 bytes vm/haos_vm.sh | 272 ------------------ ...imox-haos-vm-v4.sh => pimox-haos-vm-v5.sh} | 77 ++++- 4 files changed, 112 insertions(+), 302 deletions(-) rename vm/{haos-vm-v4.sh => haos-vm-v5.sh} (87%) delete mode 100644 vm/haos.sh.gpg delete mode 100644 vm/haos_vm.sh rename vm/{pimox-haos-vm-v4.sh => pimox-haos-vm-v5.sh} (78%) diff --git a/vm/haos-vm-v4.sh b/vm/haos-vm-v5.sh similarity index 87% rename from vm/haos-vm-v4.sh rename to vm/haos-vm-v5.sh index 8dbf2889..2f41df72 100644 --- a/vm/haos-vm-v4.sh +++ b/vm/haos-vm-v5.sh @@ -2,7 +2,7 @@ function header_info { cat <<"EOF" __ __ ___ _ __ __ ____ _____ - / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____v5/ /_ / __ \/ ___/ / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / /_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ @@ -13,6 +13,7 @@ clear header_info echo -e "\n Loading..." GEN_MAC=$(echo 'AE 1A 60'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +USEDID=$(pvesh get /cluster/resources --type vm --output-format yaml | egrep -i 'vmid' | awk '{print substr($2, 1, length($2)-0) }') NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') @@ -62,13 +63,6 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7.2\|7.3" | wc -l` -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: =>7.2" - echo "Exiting..." - sleep 3 - exit -fi if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then echo "User selected Yes" else @@ -76,7 +70,6 @@ else echo -e "⚠ User exited script \n" exit fi - function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -89,7 +82,24 @@ function msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } - +function PVE_CHECK() { +if [ `pveversion | grep "pve-manager/7.2\|7.3" | wc -l` -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: =>7.2" + echo "Exiting..." + sleep 2 + exit +fi +} +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} function default_settings() { echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" BRANCH=${STABLE} @@ -110,6 +120,8 @@ function default_settings() { MAC=$GEN_MAC echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" @@ -126,8 +138,16 @@ if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${C VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; + else + if echo "$USEDID" | egrep -q "$VMID" + then + echo -e "\n🚨 ${RD}ID $VMID is already in use${CL} \n" + echo -e "Exiting Script \n" + sleep 2; + exit + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; + fi fi MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "i440fx" "Machine i440fx" ON \ @@ -183,6 +203,17 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi +MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi +fi if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" @@ -199,7 +230,7 @@ else advanced_settings fi } -function start_script() { +function START_SCRIPT() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then clear header_info @@ -212,7 +243,9 @@ else advanced_settings fi } -start_script +ARCH_CHECK +PVE_CHECK +START_SCRIPT msg_info "Validating Storage" while read -r line; do TAG=$(echo $line | awk '{print $1}') @@ -278,8 +311,8 @@ for i in {0,1}; do done msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE \ + -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ diff --git a/vm/haos.sh.gpg b/vm/haos.sh.gpg deleted file mode 100644 index c887542bcb808d9e1094be86e8b595681a0ba1a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3852 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 OV|9-rFHVs{mGX|rqg5RM diff --git a/vm/haos_vm.sh b/vm/haos_vm.sh deleted file mode 100644 index 5f204f69..00000000 --- a/vm/haos_vm.sh +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') -NEXTID=$(pvesh get /cluster/nextid) -STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -BETA=$(curl -sX GET "https://api.github.com/repos/home-assistant/operating-system/releases" | awk '/tag_name/{print $4;exit}' FS='[""]') -DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -HA=`echo "\033[1;34m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT -} -function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID - fi -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7" | wc -l` -eq 1 ]; then - echo -e "\n🚨 ${RD} This script is for Proxmox Virtual Environment 6.xx${CL}\n" - echo "Exiting..." - sleep 3 - exit -fi -if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { -echo -e "${HA} - __ _____ ____ _____ - / / / / | / __ \/ ___/ - / /_/ / /| |/ / / /\__ \ - / __ / ___ / /_/ /___/ / -/_/ /_/_/v4|_\____//____/ - Home Assistant OS -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function default_settings() { - echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" - HN=haos${STABLE} - echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" - CORE_COUNT="2" - echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" - echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" -} -function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" 10 58 3 \ -"$STABLE" "Stable" ON \ -"$BETA" "Beta" OFF \ -"$DEV" "Dev" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" -else - exit -fi -VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" -else - exit -fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - HN=$(echo ${VM_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" -else - exit -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" -else - exit -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" -else - exit -fi -MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - MAC="$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - exit -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" -else - echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" - START_VM="no" -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" 10 58); then - echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} -function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} -start_script -msg_info "Validating Storage" -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi -STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) -done < <(pvesm status -content images | awk 'NR>1') -VALID=$(pvesm status -content images | awk 'NR>1') -if [ -z "$VALID" ]; then - echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" - echo -e "Exiting..." - exit -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the HAOS VM?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" -if [ "$BRANCH" == "$DEV" ]; then -URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -else -URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -fi -sleep 2 -msg_ok "${CL}${BL}${URL}${CL}" -wget -q --show-progress $URL -echo -en "\e[1A\e[0K" -FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" -msg_info "Extracting KVM Disk Image" -unxz $FILE -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DISK_IMPORT="-format qcow2" -esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done -msg_ok "Extracted KVM Disk Image" -msg_info "Creating HAOS VM" -qm create $VMID -agent 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF},size=128K \ - -scsi0 ${DISK1_REF},size=32G >/dev/null -qm set $VMID \ - -boot order=scsi0 >/dev/null -qm set $VMID -description "# Home Assistant OS -### https://github.com/tteck/Proxmox" >/dev/null -msg_ok "Created HAOS VM ${CL}${BL}(${HN})" -if [ "$START_VM" == "yes" ]; then -msg_info "Starting Home Assistant OS VM" -qm start $VMID -msg_ok "Started Home Assistant OS VM" -fi -msg_ok "Completed Successfully!\n" diff --git a/vm/pimox-haos-vm-v4.sh b/vm/pimox-haos-vm-v5.sh similarity index 78% rename from vm/pimox-haos-vm-v4.sh rename to vm/pimox-haos-vm-v5.sh index 97dc8369..cebce5e2 100644 --- a/vm/pimox-haos-vm-v4.sh +++ b/vm/pimox-haos-vm-v5.sh @@ -1,6 +1,23 @@ #!/usr/bin/env bash +function header_info { +cat <<"EOF" + ____ _ __ ___ + / __ \(_) |/ /___ _ __ + / /_/ / / /|_/ / __ \| |/_/ + / ____/ / / / / /_/ /> < + __ __ /_/_ /_/_/ /_/\____/_/|_| __ ____ _____ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____v5/ /_ / __ \/ ___/ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ + +EOF +} +clear +header_info echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +USEDID=$(pvesh get /cluster/resources --type vm --output-format yaml | egrep -i 'vmid' | awk '{print substr($2, 1, length($2)-0) }') NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') @@ -55,14 +72,23 @@ else echo -e "⚠ User exited script \n" exit fi -function header_info { -echo -e "${RD} - ____ _ __ ___ __ _____ ____ _____ - / __ \(_) / |/ /___ _ __ / / / / | / __ \/ ___/ - / /_/ / /v4_/ /|_/ / __ \| |/_/ / /_/ / /| |/ / / /\__ \ - / ____/ /___/ / / / /_/ /> < / __ / ___ / /_/ /___/ / -/_/ /_/ /_/ /_/\____/_/|_| /_/ /_/_/ |_\____//____/ -${CL}" +function PVE_CHECK() { +if [ `pveversion | grep "pve-manager/7.2\|7.3" | wc -l` -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: =>7.2" + echo "Exiting..." + sleep 2 + exit +fi +} +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" == "amd64" ]]; then + echo -e "\n ❌ This script only works with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi } function msg_info() { local msg="$1" @@ -94,6 +120,8 @@ function default_settings() { MAC=$GEN_MAC echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" VLAN="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" @@ -109,8 +137,16 @@ if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${C VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; + else + if echo "$USEDID" | egrep -q "$VMID" + then + echo -e "\n🚨 ${RD}ID $VMID is already in use${CL} \n" + echo -e "Exiting Script \n" + sleep 2; + exit + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; + fi fi VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? @@ -152,6 +188,17 @@ else echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi +MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) +exitstatus=$? +if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi +fi if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" @@ -168,7 +215,7 @@ else advanced_settings fi } -function start_script() { +function START_SCRIPT() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then clear header_info @@ -181,7 +228,9 @@ else advanced_settings fi } -start_script +ARCH_CHECK +PVE_CHECK +START_SCRIPT while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') @@ -232,8 +281,8 @@ for i in {0,1}; do done msg_ok "Extracted Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN \ - -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \ + -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 64M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ From 332f089110d6ab5476fcc150bbc3f30b6c60ea03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 11:00:21 -0500 Subject: [PATCH 4256/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ebb1ef9f..1fe9be84 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,24 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-25 + +### Changed + +- **Home Assistant OS VM** + - switch to v5 + - add an option to set MTU size (Advanced) + - add arch check (no ARM64) + - add check to insure VMID isn't already used before VM creation (Advanced) + - code refactoring +- **PiMox Home Assistant OS VM** + - switch to v5 + - add an option to set MTU size (Advanced) + - add arch check (no AMD64) + - add pve check (=>7.2) + - add check to insure VMID isn't already used before VM creation (Advanced) + - code refactoring + ## 2023-01-24 ### Changed From b5c89a34f2070b0c0fb2bfab8a634308fcea448e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 11:07:53 -0500 Subject: [PATCH 4257/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1fe9be84..035a5cc7 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -10,8 +10,8 @@ All notable changes to this project will be documented in this file. - **Home Assistant OS VM** - switch to v5 - add an option to set MTU size (Advanced) - - add arch check (no ARM64) - - add check to insure VMID isn't already used before VM creation (Advanced) + - add arch check (no ARM64) (issue from community.home-assistant.io) + - add check to insure VMID isn't already used before VM creation (Advanced) (issue from forum.proxmox.com) - code refactoring - **PiMox Home Assistant OS VM** - switch to v5 @@ -20,6 +20,8 @@ All notable changes to this project will be documented in this file. - add pve check (=>7.2) - add check to insure VMID isn't already used before VM creation (Advanced) - code refactoring +- **All LXC's** + - add arch check (no ARM64) (issue from forum.proxmox.com) ## 2023-01-24 From d385d7e9d23287c80a35a5ef654fa967788dafcb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 13:51:39 -0500 Subject: [PATCH 4258/6505] copy-data --- .../hacontainer-copy-data-hacontainer.sh} | 0 .../hacontainer-copy-data-hacore.sh} | 0 .../hacontainer-copy-data-podman.sh} | 0 .../hacore-copy-data-hacontainer.sh} | 0 .../hacore-copy-data-hacore.sh} | 0 misc/{pms-copy-data.sh => copy-data/plex-copy-data-plex.sh} | 0 .../podman-copy-data-hacontainer.sh} | 0 misc/{z2m-copy-data.sh => copy-data/z2m-copy-data-z2m.sh} | 0 .../zwavejs2mqtt-copy-data-zwavejsui.sh} | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename misc/{ha-copy-data.sh => copy-data/hacontainer-copy-data-hacontainer.sh} (100%) rename misc/{hacontainer2hacore-data.sh => copy-data/hacontainer-copy-data-hacore.sh} (100%) rename misc/{ha-copy-data-podman.sh => copy-data/hacontainer-copy-data-podman.sh} (100%) rename misc/{hacore2hacontainer-data.sh => copy-data/hacore-copy-data-hacontainer.sh} (100%) rename misc/{hacore2hacore-data.sh => copy-data/hacore-copy-data-hacore.sh} (100%) rename misc/{pms-copy-data.sh => copy-data/plex-copy-data-plex.sh} (100%) rename misc/{podman-copy-data-docker.sh => copy-data/podman-copy-data-hacontainer.sh} (100%) rename misc/{z2m-copy-data.sh => copy-data/z2m-copy-data-z2m.sh} (100%) rename misc/{zwave-copy-data.sh => copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh} (100%) diff --git a/misc/ha-copy-data.sh b/misc/copy-data/hacontainer-copy-data-hacontainer.sh similarity index 100% rename from misc/ha-copy-data.sh rename to misc/copy-data/hacontainer-copy-data-hacontainer.sh diff --git a/misc/hacontainer2hacore-data.sh b/misc/copy-data/hacontainer-copy-data-hacore.sh similarity index 100% rename from misc/hacontainer2hacore-data.sh rename to misc/copy-data/hacontainer-copy-data-hacore.sh diff --git a/misc/ha-copy-data-podman.sh b/misc/copy-data/hacontainer-copy-data-podman.sh similarity index 100% rename from misc/ha-copy-data-podman.sh rename to misc/copy-data/hacontainer-copy-data-podman.sh diff --git a/misc/hacore2hacontainer-data.sh b/misc/copy-data/hacore-copy-data-hacontainer.sh similarity index 100% rename from misc/hacore2hacontainer-data.sh rename to misc/copy-data/hacore-copy-data-hacontainer.sh diff --git a/misc/hacore2hacore-data.sh b/misc/copy-data/hacore-copy-data-hacore.sh similarity index 100% rename from misc/hacore2hacore-data.sh rename to misc/copy-data/hacore-copy-data-hacore.sh diff --git a/misc/pms-copy-data.sh b/misc/copy-data/plex-copy-data-plex.sh similarity index 100% rename from misc/pms-copy-data.sh rename to misc/copy-data/plex-copy-data-plex.sh diff --git a/misc/podman-copy-data-docker.sh b/misc/copy-data/podman-copy-data-hacontainer.sh similarity index 100% rename from misc/podman-copy-data-docker.sh rename to misc/copy-data/podman-copy-data-hacontainer.sh diff --git a/misc/z2m-copy-data.sh b/misc/copy-data/z2m-copy-data-z2m.sh similarity index 100% rename from misc/z2m-copy-data.sh rename to misc/copy-data/z2m-copy-data-z2m.sh diff --git a/misc/zwave-copy-data.sh b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh similarity index 100% rename from misc/zwave-copy-data.sh rename to misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh From 08fab50acd7ab8b97ab5fa61586f5a647f62b52f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 14:39:50 -0500 Subject: [PATCH 4259/6505] copy-data --- misc/copy-data/README.md | 46 +++++++++++++++++++ ...ner-copy-data-home-assistant-container.sh} | 1 - ...ontainer-copy-data-home-assistant-core.sh} | 0 ...tainer-copy-data-podman-home-assistant.sh} | 1 - ...ore-copy-data-home-assistant-container.sh} | 0 ...ant-core-copy-data-home-assistant-core.sh} | 0 misc/copy-data/plex-copy-data-plex.sh | 3 +- ...ant-copy-data-home-assistant-container.sh} | 3 +- misc/copy-data/z2m-copy-data-z2m.sh | 3 +- .../zwavejs2mqtt-copy-data-zwavejsui.sh | 3 +- 10 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 misc/copy-data/README.md rename misc/copy-data/{hacontainer-copy-data-hacontainer.sh => home-assistant-container-copy-data-home-assistant-container.sh} (97%) rename misc/copy-data/{hacontainer-copy-data-hacore.sh => home-assistant-container-copy-data-home-assistant-core.sh} (100%) rename misc/copy-data/{hacontainer-copy-data-podman.sh => home-assistant-container-copy-data-podman-home-assistant.sh} (97%) rename misc/copy-data/{hacore-copy-data-hacontainer.sh => home-assistant-core-copy-data-home-assistant-container.sh} (100%) rename misc/copy-data/{hacore-copy-data-hacore.sh => home-assistant-core-copy-data-home-assistant-core.sh} (100%) rename misc/copy-data/{podman-copy-data-hacontainer.sh => podman-home-assistant-copy-data-home-assistant-container.sh} (97%) diff --git a/misc/copy-data/README.md b/misc/copy-data/README.md new file mode 100644 index 00000000..519540dc --- /dev/null +++ b/misc/copy-data/README.md @@ -0,0 +1,46 @@ +

    Copy data to another LXC

    +
    To copy data from Home Assistant Container to Home Assistant Container
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)" +``` +
    To copy data from Home Assistant Container to Home Assistant Core
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)" +``` +
    To copy data from Home Assistant Container to Podman Home Assistant
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)" +``` +
    To copy data from Podman Home Assistant to Home Assistant Container
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)" +``` +
    To copy data from Home Assistant Core to Home Assistant Container
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)" +``` +
    To copy data from Home Assistant Core to Home Assistant Core
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)" +``` +
    To copy data from Plex to Plex
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/plex-copy-data-plex.sh)" +``` +
    To copy data from Zigbee2MQTT to Zigbee2MQTT
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/z2m-copy-data-z2m.sh)" +``` +
    To copy data from Zwavejs2MQTT to Zwave JS UI
    + +``` +bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)" +``` diff --git a/misc/copy-data/hacontainer-copy-data-hacontainer.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh similarity index 97% rename from misc/copy-data/hacontainer-copy-data-hacontainer.sh rename to misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh index 698c1cfb..f9410471 100644 --- a/misc/copy-data/hacontainer-copy-data-hacontainer.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash # Use to copy all data from one Home Assistant LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" clear if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do diff --git a/misc/copy-data/hacontainer-copy-data-hacore.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh similarity index 100% rename from misc/copy-data/hacontainer-copy-data-hacore.sh rename to misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh diff --git a/misc/copy-data/hacontainer-copy-data-podman.sh b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh similarity index 97% rename from misc/copy-data/hacontainer-copy-data-podman.sh rename to misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh index 2b8abc13..2442a576 100644 --- a/misc/copy-data/hacontainer-copy-data-podman.sh +++ b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" clear if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do diff --git a/misc/copy-data/hacore-copy-data-hacontainer.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh similarity index 100% rename from misc/copy-data/hacore-copy-data-hacontainer.sh rename to misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh diff --git a/misc/copy-data/hacore-copy-data-hacore.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh similarity index 100% rename from misc/copy-data/hacore-copy-data-hacore.sh rename to misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh diff --git a/misc/copy-data/plex-copy-data-plex.sh b/misc/copy-data/plex-copy-data-plex.sh index 60812f67..399ddcb0 100644 --- a/misc/copy-data/plex-copy-data-plex.sh +++ b/misc/copy-data/plex-copy-data-plex.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # Use to copy all data from one Plex Media Server LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from one Plex Media Server LXC to another. Proceed(y/n)?" yn case $yn in diff --git a/misc/copy-data/podman-copy-data-hacontainer.sh b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh similarity index 97% rename from misc/copy-data/podman-copy-data-hacontainer.sh rename to misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh index 5b5bea9e..d9c1d9dd 100644 --- a/misc/copy-data/podman-copy-data-hacontainer.sh +++ b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman-copy-data-docker.sh)" +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. Proceed(y/n)?" yn case $yn in diff --git a/misc/copy-data/z2m-copy-data-z2m.sh b/misc/copy-data/z2m-copy-data-z2m.sh index ad29d1c2..0cdd7651 100644 --- a/misc/copy-data/z2m-copy-data-z2m.sh +++ b/misc/copy-data/z2m-copy-data-z2m.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # Use to copy all data from one Zigbee2MQTT LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?" yn case $yn in diff --git a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh index 193a027e..c45ececc 100644 --- a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh +++ b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/zwave-copy-data.sh)" +clear +if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do read -p "Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC. Proceed(y/n)?" yn case $yn in From 61df2ea119f504d9effa032c911a7dfc4d486b7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 25 Jan 2023 14:49:07 -0500 Subject: [PATCH 4260/6505] Update README.md add instruction --- misc/copy-data/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/copy-data/README.md b/misc/copy-data/README.md index 519540dc..e24677c3 100644 --- a/misc/copy-data/README.md +++ b/misc/copy-data/README.md @@ -1,4 +1,4 @@ -

    Copy data to another LXC

    +

    Copy data to another LXC (run in the Proxmox Shell)

    To copy data from Home Assistant Container to Home Assistant Container
    ``` From 6964f82b4d702ab1f056146f931f6cebbbde5d75 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 03:55:42 -0500 Subject: [PATCH 4261/6505] Option to disable IPv6 (#986) --- ct/adguard-v5.sh | 10 ++++++++++ ct/alpine-v5.sh | 10 ++++++++++ ct/archlinux-v5.sh | 10 ++++++++++ ct/autobrr-v5.sh | 10 ++++++++++ ct/blocky-v5.sh | 10 ++++++++++ ct/casaos-v5.sh | 10 ++++++++++ ct/changedetection-v5.sh | 10 ++++++++++ ct/cronicle-v5.sh | 10 ++++++++++ ct/daemonsync-v5.sh | 10 ++++++++++ ct/dashy-v5.sh | 10 ++++++++++ ct/debian-v5.sh | 22 ++++++++++++++++------ ct/deconz-v5.sh | 10 ++++++++++ ct/deluge-v5.sh | 10 ++++++++++ ct/docker-v5.sh | 10 ++++++++++ ct/emby-v5.sh | 10 ++++++++++ ct/emqx-v5.sh | 10 ++++++++++ ct/esphome-v5.sh | 10 ++++++++++ ct/grafana-v5.sh | 10 ++++++++++ ct/grocy-v5.sh | 10 ++++++++++ ct/heimdalldashboard-v5.sh | 10 ++++++++++ ct/homeassistant-core-v5.sh | 10 ++++++++++ ct/homeassistant-v5.sh | 10 ++++++++++ ct/homebridge-v5.sh | 10 ++++++++++ ct/homepage-v5.sh | 10 ++++++++++ ct/homer-v5.sh | 10 ++++++++++ ct/hyperion-v5.sh | 10 ++++++++++ ct/influxdb-v5.sh | 10 ++++++++++ ct/iobroker-v5.sh | 10 ++++++++++ ct/jellyfin-v5.sh | 10 ++++++++++ ct/k0s-v5.sh | 10 ++++++++++ ct/kavita-v5.sh | 10 ++++++++++ ct/keycloak-v5.sh | 10 ++++++++++ ct/lidarr-v5.sh | 10 ++++++++++ ct/magicmirror-v5.sh | 10 ++++++++++ ct/mariadb-v5.sh | 10 ++++++++++ ct/meshcentral-v5.sh | 10 ++++++++++ ct/motioneye-v5.sh | 10 ++++++++++ ct/mqtt-v5.sh | 10 ++++++++++ ct/n8n-v5.sh | 10 ++++++++++ ct/navidrome-v5.sh | 10 ++++++++++ ct/nextcloudpi-v5.sh | 10 ++++++++++ ct/nginxproxymanager-v5.sh | 10 ++++++++++ ct/nocodb-v5.sh | 10 ++++++++++ ct/node-red-v5.sh | 10 ++++++++++ ct/omada-v5.sh | 10 ++++++++++ ct/omv-v5.sh | 10 ++++++++++ ct/openhab-v5.sh | 10 ++++++++++ ct/paperless-ngx-v5.sh | 10 ++++++++++ ct/photoprism-v5.sh | 10 ++++++++++ ct/pihole-v5.sh | 10 ++++++++++ ct/plex-v5.sh | 10 ++++++++++ ct/podman-homeassistant-v5.sh | 10 ++++++++++ ct/podman-v5.sh | 10 ++++++++++ ct/postgresql-v5.sh | 10 ++++++++++ ct/prometheus-v5.sh | 10 ++++++++++ ct/prowlarr-v5.sh | 10 ++++++++++ ct/radarr-v5.sh | 10 ++++++++++ ct/readarr-v5.sh | 10 ++++++++++ ct/sabnzbd-v5.sh | 10 ++++++++++ ct/scrypted-v5.sh | 10 ++++++++++ ct/shinobi-v5.sh | 10 ++++++++++ ct/sonarr-v5.sh | 10 ++++++++++ ct/syncthing-v5.sh | 10 ++++++++++ ct/tdarr-v5.sh | 10 ++++++++++ ct/technitiumdns-v5.sh | 10 ++++++++++ ct/transmission-v5.sh | 10 ++++++++++ ct/trilium-v5.sh | 10 ++++++++++ ct/ubuntu-v5.sh | 10 ++++++++++ ct/umbrel-v5.sh | 10 ++++++++++ ct/unifi-v5.sh | 10 ++++++++++ ct/uptimekuma-v5.sh | 10 ++++++++++ ct/vaultwarden-v5.sh | 10 ++++++++++ ct/whisparr-v5.sh | 10 ++++++++++ ct/whoogle-v5.sh | 10 ++++++++++ ct/wikijs-v5.sh | 10 ++++++++++ ct/wireguard-v5.sh | 14 ++++++++++++-- ct/yunohost-v5.sh | 10 ++++++++++ ct/zigbee2mqtt-v5.sh | 10 ++++++++++ ct/zwave-js-ui-v5.sh | 10 ++++++++++ install/adguard-v5-install.sh | 1 + install/autobrr-v5-install.sh | 1 + install/blocky-v5-install.sh | 1 + install/casaos-v5-install.sh | 1 + install/changedetection-v5-install.sh | 1 + install/cronicle-v5-install.sh | 1 + install/daemonsync-v5-install.sh | 1 + install/dashy-v5-install.sh | 1 + install/debian-v5-install.sh | 1 + install/deconz-v5-install.sh | 1 + install/deluge-v5-install.sh | 5 +++-- install/docker-v5-install.sh | 1 + install/emby-v5-install.sh | 1 + install/emqx-v5-install.sh | 1 + install/esphome-install.sh | 4 ++-- install/esphome-v5-install.sh | 5 +++-- install/grafana-v5-install.sh | 1 + install/grocy-v5-install.sh | 1 + install/heimdalldashboard-v5-install.sh | 1 + install/homeassistant-core-v5-install.sh | 1 + install/homeassistant-install.sh | 4 ++-- install/homeassistant-v5-install.sh | 1 + install/homebridge-v5-install.sh | 1 + install/homepage-v5-install.sh | 1 + install/homer-v5-install.sh | 1 + install/hyperion-v5-install.sh | 1 + install/influxdb-v5-install.sh | 1 + install/iobroker-v5-install.sh | 1 + install/jellyfin-v5-install.sh | 1 + install/k0s-v5-install.sh | 1 + install/kavita-v5-install.sh | 1 + install/keycloak-v5-install.sh | 1 + install/lidarr-v5-install.sh | 1 + install/magicmirror-v5-install.sh | 1 + install/mariadb-v5-install.sh | 1 + install/meshcentral-v5-install.sh | 1 + install/motioneye-v5-install.sh | 1 + install/mqtt-v5-install.sh | 1 + install/n8n-v5-install.sh | 1 + install/navidrome-v5-install.sh | 1 + install/nextcloudpi-v5-install.sh | 1 + install/nginxproxymanager-v5-install.sh | 1 + install/nocodb-v5-install.sh | 1 + install/node-red-v5-install.sh | 1 + install/omada-v5-install.sh | 1 + install/omv-v5-install.sh | 1 + install/openhab-v5-install.sh | 1 + install/paperless-ngx-v5-install.sh | 1 + install/photoprism-v5-install.sh | 1 + install/pihole-v5-install.sh | 1 + install/plex-v5-install.sh | 1 + install/podman-homeassistant-v5-install.sh | 1 + install/podman-v5-install.sh | 1 + install/postgresql-v5-install.sh | 1 + install/prometheus-v5-install.sh | 1 + install/prowlarr-v5-install.sh | 1 + install/radarr-v5-install.sh | 1 + install/readarr-v5-install.sh | 1 + install/sabnzbd-v5-install.sh | 1 + install/scrypted-v5-install.sh | 1 + install/shinobi-v5-install.sh | 1 + install/sonarr-v5-install.sh | 1 + install/syncthing-v5-install.sh | 1 + install/tdarr-v5-install.sh | 1 + install/technitiumdns-v5-install.sh | 1 + install/transmission-v5-install.sh | 1 + install/trilium-v5-install.sh | 1 + install/ubuntu-v5-install.sh | 1 + install/umbrel-v5-install.sh | 1 + install/unifi-v5-install.sh | 1 + install/uptimekuma-v5-install.sh | 1 + install/vaultwarden-v5-install.sh | 1 + install/whisparr-v5-install.sh | 1 + install/whoogle-install.sh | 4 ++-- install/whoogle-v5-install.sh | 5 +++-- install/wikijs-v5-install.sh | 1 + install/wireguard-install.sh | 4 ++-- install/wireguard-v5-install.sh | 1 + install/yunohost-v5-install.sh | 1 + install/zigbee2mqtt-v5-install.sh | 1 + install/zwave-js-ui-v5-install.sh | 1 + 160 files changed, 889 insertions(+), 22 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 56035b9d..817bb5fd 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -125,6 +125,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -236,6 +238,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -369,6 +378,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 5ef6197c..7f9c7d03 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -234,6 +236,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -348,6 +357,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index 015661f0..afef7c5a 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 0bf2ba40..5f3589ba 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -125,6 +125,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -236,6 +238,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -361,6 +370,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index d82c7a93..7291b0be 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index f41c1c96..2a7e1c93 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -239,6 +241,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -362,6 +371,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index d0d7b890..e50e3fda 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -351,6 +360,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 41f618b4..e1e831cc 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -124,6 +124,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -235,6 +237,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -399,6 +408,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export SERV=$SERVER +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index c21c5de6..c79e3cac 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 98ed2189..d3ed0919 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -378,6 +387,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 25af81a5..9f007fb1 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash function header_info { cat <<"EOF" - ____ __________ _______ _ __ - / __ \/ ____/ __ )/ _/ | / | / / - / / / / __/ / __ |/ // /| | / |/ / - / /_/ / /_v5/ /_/ // // ___ |/ /| / -/_____/_____/_____/___/_/ |_/_/ |_/ - + ____ __ _ + / __ \___v5/ /_ (_)___ _____ + / / / / _ \/ __ \/ / __ `/ __ \ + / /_/ / __/ /_/ / / /_/ / / / / +/_____/\___/_.___/_/\__,_/_/ /_/ + EOF } clear @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 7b733470..f99fffb4 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index 8450b457..f6124413 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -123,6 +123,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -234,6 +236,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -348,6 +357,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 8b29ccd8..d2e3c0a7 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -125,6 +125,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -359,6 +368,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index e5637ede..7392ac61 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -246,6 +248,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -371,6 +380,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 45471134..26360cbc 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -351,6 +360,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index a3c650a5..6ec4e410 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -358,6 +367,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 291af104..85e1b111 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 7b404d1f..62441b72 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -351,6 +360,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 62bf3c8e..00dddee1 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -431,6 +440,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 8dfdc3cd..0cc1acb4 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -120,6 +120,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -232,6 +234,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -419,6 +428,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index a9320d6c..afaa19eb 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -241,6 +243,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -427,6 +436,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index d0ed805b..d036f6ed 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 0ddcf04f..413bcb9a 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -358,6 +367,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 281ffdb5..fcb920b0 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -371,6 +380,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index ac0a241d..51353a73 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -353,6 +362,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index e7dae7cf..03681cb6 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 09ca2662..257ae0bd 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 77d93abe..127dcd25 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -129,6 +129,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -248,6 +250,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -361,6 +370,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 84f72199..bcf5f0ee 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index 2b80642e..d0d21213 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -125,6 +125,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -236,6 +238,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -350,6 +359,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index ab061363..2d9e16fe 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -353,6 +362,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 11929ba5..07586f05 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 1b523e7a..9a738bcf 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -354,6 +363,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 716e925f..96fdb8e1 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 75444ab2..37d26f3f 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index a267063a..f5b6186d 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -351,6 +360,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index ade50ece..8cc7274e 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -124,6 +124,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -235,6 +237,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 87888de4..c4a371af 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 3754dfa3..06f2a828 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -363,6 +372,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index c57934f8..af9a035b 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 88dba9c9..41cf41a8 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -461,6 +470,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index c7db9a0a..d552dd84 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -355,6 +364,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 9928b776..d6239acc 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -388,6 +397,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 23689d0e..c200d3fd 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -246,6 +248,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -350,6 +359,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 5adcf838..8591a72e 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -353,6 +362,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 3e7fab93..837f815c 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -353,6 +362,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 25a0b51f..b4de9ab6 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -420,6 +429,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index c458183a..ccab7aad 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -125,6 +125,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -236,6 +238,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -373,6 +382,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 3b46de9a..299c53d0 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 5274f9b7..30894617 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -128,6 +128,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -247,6 +249,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -371,6 +380,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 9a19d4b9..55f0f9c5 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -130,6 +130,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -241,6 +243,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -402,6 +411,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 0deea5d2..c4475f01 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index 7cc1fd6f..e1247142 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index a3c2a7b6..2de01b11 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index 589a1ff7..ed741da7 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 0f1b8a79..3ae34a9c 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index b87aace9..d8e03dfb 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index a6c859cc..c5480465 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 12510995..3b4c7eda 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -353,6 +362,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 61dc52bf..0a3ca6cf 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -246,6 +248,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -362,6 +371,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 2fb46009..bf291d82 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 0d7743d4..fc983f24 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -353,6 +362,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 7b6f59f8..882fa1d7 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index fac927a2..ec98b23c 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -414,6 +423,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index e415d8f7..53bf082a 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index b8e733a7..9facb7ca 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -371,6 +380,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 343b95f9..0cdab57f 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -123,6 +123,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -242,6 +244,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -355,6 +364,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index b908617d..684b4fc2 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -239,6 +241,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -360,6 +369,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index b2267304..5f07d29a 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,6 +361,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 60c22a50..c29a3832 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -369,6 +378,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index deed5797..fda70c39 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -125,6 +125,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -420,6 +429,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index c00bcec0..27636526 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -123,6 +123,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -234,6 +236,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -348,6 +357,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index e6b6ef7d..b8600076 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -351,6 +360,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 1857c2fd..1ed0b3b8 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -365,6 +374,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 722884a6..376ff186 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -352,13 +361,13 @@ if [ "$UPD" == "2" ]; then exit fi IP=$(hostname -I | awk '{print $1}') -msg_info "Installing pip3" +msg_info "Installing Python3-pip" apt-get install -y python3-pip &>/dev/null pip install flask &>/dev/null pip install ifcfg &>/dev/null pip install flask_qrcode &>/dev/null pip install icmplib &>/dev/null -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing WGDashboard" WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest | @@ -407,6 +416,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 973f62b8..e9d630c4 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -122,6 +122,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -233,6 +235,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -347,6 +356,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 10df801e..e006440e 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -127,6 +127,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -238,6 +240,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -382,6 +391,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 9aff96ea..3018177d 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -126,6 +126,8 @@ function default_settings() { NET=dhcp echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -237,6 +239,13 @@ function advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" fi fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -365,6 +374,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB export STD=$VERB2 export SSH_ROOT=${SSH} diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index c0cb9130..562c14ab 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 08b1490d..c66c362c 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index 3a09d1b8..f4f9d698 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 9f076d43..98e7ae77 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index ae77b3a0..da5891f1 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 0bee1960..dc0dbd07 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 670d3c2e..f5f9408b 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 205163bf..4e4a084f 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index ffb9f70b..f89c2ffb 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index fa12d272..5b689847 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index cb4bebc7..963dbe93 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -86,9 +87,9 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" $STD apt-get install -y python3-pip -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing Deluge" $STD pip install deluge[all] diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index c0edccb1..5d4d19bb 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index a13941c0..29d38f1b 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 718f0089..26b8daa5 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 8a1b73d5..fbd8570a 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -87,9 +87,9 @@ apt-get install -y sudo &>/dev/null apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" apt-get install -y python3-pip &>/dev/null -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing ESPHome" pip3 install esphome &>/dev/null diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index bddd0035..e4fbcc58 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -88,9 +89,9 @@ $STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" $STD apt-get install -y python3-pip -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing ESPHome" $STD pip3 install esphome diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 189cbae3..d9dbcdfc 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index 1e4c784b..c56342c7 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index 33e8ef13..a1fc064b 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 6070a81a..2b3a3333 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 19998207..52c3c427 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -86,9 +86,9 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" apt-get install -y python3-pip &>/dev/null -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" get_latest_release() { curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index 603028b3..cb5c9ccf 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index bd218d9e..3aedb557 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 7069e0ee..b2d8ada4 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index c9e8172e..9f2db9fa 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 13263722..05558e6b 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 27e263e9..5affc2de 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index b592dced..a59032a8 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 2f0f1126..17683b67 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index 24b67810..ab239220 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 316ecaf1..bbf7bc1a 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 797046df..53e03b5c 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index 061fbd31..f541f553 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 1902ced3..9f47644a 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 8985b950..a705ad23 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index 0559a932..c5e5ed15 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 57a103de..6dd05e2e 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index dfd7fd03..b75ccd39 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 03a27b72..677f21b5 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index f0c9e767..8ef3f859 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 2fbce9fc..e6092393 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 3b752773..7fb0efa9 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index bcf5d676..15b515bc 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index a554c35b..de324a32 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index dd1e986b..30191935 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 89bc3116..9a1801a6 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index ced8d90d..1649094c 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 8040e113..496ae80a 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 661ab7d9..d8831deb 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 87bc2d69..091351f5 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index b048ada9..64d33251 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 7ed0482b..20d9c70c 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 48038cba..9fdad038 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index a092835d..48d20364 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index b5f37958..de31eb50 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index f7f9edd8..f22ccc1a 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index a0a84993..4f262889 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index 8c90fcc2..a776b2cf 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 6cd98a5c..fd8b2d51 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 40f4d6ac..f0694686 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 6ea98787..838718b8 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index f942d8ef..fbbac3ac 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 4845c1ec..dd5d92f7 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 43fc93cb..8594d8a0 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index a75fbc97..add94e24 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index ceb6ddbd..d6ead82b 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 5a6d2a36..617ec96d 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index a0e2f7c1..d5371ab6 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 7468dfb3..841be405 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index e86bdeb8..ec68eaad 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 659c9685..5d088390 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index e23a1d84..9d107133 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 3e10887c..7f005241 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index f41c34d3..758ae265 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -86,9 +86,9 @@ apt-get install -y curl &>/dev/null apt-get install -y sudo &>/dev/null msg_ok "Installed Dependencies" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" apt-get install python3-pip -y &>/dev/null -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing Whoogle" pip install brotli &>/dev/null diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 0408a740..5fdd8338 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -87,9 +88,9 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" $STD apt-get install -y python3-pip -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing Whoogle" $STD pip install brotli diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 28ae5236..b138e039 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh index 92f6f77d..b71dad3b 100644 --- a/install/wireguard-install.sh +++ b/install/wireguard-install.sh @@ -110,13 +110,13 @@ chmod +x install.sh ./install.sh --unattended options.conf &>/dev/null msg_ok "Installed WireGuard" -msg_info "Installing pip3" +msg_info "Installing Python3-pip" apt-get install python3-pip -y &>/dev/null pip install flask &>/dev/null pip install ifcfg &>/dev/null pip install flask_qrcode &>/dev/null pip install icmplib &>/dev/null -msg_ok "Installed pip3" +msg_ok "Installed Python3-pip" msg_info "Installing WGDashboard" WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest | diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 6c30ed01..c92487b2 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index e149ee21..1f79c4a3 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index c703e95b..a37264cc 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index e1dace8a..b115a202 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") From 8e2248c83c4be7a9b9852a21ed75cc41e115a562 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 04:00:11 -0500 Subject: [PATCH 4262/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 035a5cc7..bb623259 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-26 + +### Changed + +- **ALL LXC's** + - Add an option to disable IPv6 (Advanced) + ## 2023-01-25 ### Changed From 2dede961bda88e7e91b38f04fbde5b50cbb0056c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 12:59:02 -0500 Subject: [PATCH 4263/6505] Update adguard-v5-install.sh free port 53 --- install/adguard-v5-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 562c14ab..583b6df8 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -89,6 +89,8 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" +echo "DNSStubListener=no" >>/etc/systemd/resolved.conf +ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh $STD bash install.sh rm install.sh From f416b876d041e66bc5997fdfd8c09daa4591c429 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 13:06:39 -0500 Subject: [PATCH 4264/6505] Update adguard-v5-install.sh --- install/adguard-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 583b6df8..e2b5d69c 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -91,6 +91,7 @@ msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" echo "DNSStubListener=no" >>/etc/systemd/resolved.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf +systemctl restart systemd-resolved wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh $STD bash install.sh rm install.sh From b16e58b370ebf6aca2674fbc2a1910bb509b342e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 13:09:02 -0500 Subject: [PATCH 4265/6505] Update adguard-v5-install.sh --- install/adguard-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index e2b5d69c..39d61741 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -91,7 +91,7 @@ msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" echo "DNSStubListener=no" >>/etc/systemd/resolved.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -systemctl restart systemd-resolved +#systemctl restart systemd-resolved wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh $STD bash install.sh rm install.sh From 2c5190855785c13367097a9908f7e0234ac9ca64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 14:13:49 -0500 Subject: [PATCH 4266/6505] Update adguard-v5-install.sh free port 53 without reboot --- install/adguard-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 39d61741..7b3711ab 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -89,9 +89,9 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" +systemctl stop systemd-resolved echo "DNSStubListener=no" >>/etc/systemd/resolved.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -#systemctl restart systemd-resolved wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh $STD bash install.sh rm install.sh From 030c4927e7e912a9cbbc69fee3552016a51565bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 17:51:02 -0500 Subject: [PATCH 4267/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 0cc1acb4..8db47e6b 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -325,6 +325,7 @@ function advanced_settings() { } function install_script() { + ARCH_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -418,7 +419,6 @@ fi } clear -ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From 2a33c86cfb4151a1c19ca6516ba7c9af29952f91 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 17:57:32 -0500 Subject: [PATCH 4268/6505] Update homeassistant-core-v5.sh add arch check --- ct/homeassistant-core-v5.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 8db47e6b..33862ce0 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -75,7 +75,14 @@ function PVE_CHECK() { exit fi } - +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then NEXTID=$(pvesh get /cluster/nextid) @@ -325,7 +332,6 @@ function advanced_settings() { } function install_script() { - ARCH_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -419,6 +425,7 @@ fi } clear +ARCH_CHECK if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From ed1e623a287b002b6d5476a3365e4d82bcc2dbc8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 18:00:56 -0500 Subject: [PATCH 4269/6505] Update homeassistant-core-v5.sh --- ct/homeassistant-core-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 33862ce0..1d67e929 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -83,6 +83,7 @@ function ARCH_CHECK() { sleep 2 exit fi + } if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then NEXTID=$(pvesh get /cluster/nextid) From bc6ac71bc648c8b3800b78171fd81e58ab441b82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Jan 2023 20:19:10 -0500 Subject: [PATCH 4270/6505] Update adguard-v5.sh --- ct/adguard-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 817bb5fd..daf5027a 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -137,7 +137,7 @@ function default_settings() { MAC="" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" From 8307bbe86c6e81a753ab021dc3a40b64661b2675 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 01:33:16 -0500 Subject: [PATCH 4271/6505] Update influxdb-v5-install.sh fix sources --- install/influxdb-v5-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 5affc2de..0ab4978d 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -93,9 +93,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up InfluxDB Repository" $STD apt-key add <(curl -fsSL https://repos.influxdata.com/influxdb.key) -cat </etc/apt/sources.list.d/influxdb.list -deb https://repos.influxdata.com/debian bullseye stable -EOF +sh -c 'echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" > sudo tee /etc/apt/sources.list.d/influxdb.list' msg_ok "Set up InfluxDB Repository" read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt From 40ad663997f4865a13a737f474a4c10f18f51e96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 02:01:45 -0500 Subject: [PATCH 4272/6505] update sources --- install/hyperion-v5-install.sh | 4 +--- install/nginxproxymanager-v5-install.sh | 4 +--- install/scrypted-v5-install.sh | 4 +--- install/syncthing-v5-install.sh | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 05558e6b..b3eed082 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -92,9 +92,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Hyperion" wget -qO- https://apt.hyperion-project.org/hyperion.pub.key | gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg -cat </etc/apt/sources.list.d/hyperion.list -deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ bullseye main -EOF +sh -c 'echo "deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/hyperion.list' $STD apt-get update $STD apt-get install -y hyperion $STD systemctl enable --now hyperion@root.service diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 7fb0efa9..e97c311e 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -114,9 +114,7 @@ msg_ok "Installed Python" msg_info "Installing Openresty" $STD apt-key add <(curl -fsSL https://openresty.org/package/pubkey.gpg) -cat </etc/apt/sources.list.d/openresty.list -deb http://openresty.org/package/debian bullseye openresty -EOF +sh -c 'echo "deb http://openresty.org/package/debian $(lsb_release -cs) openresty" > /etc/apt/sources.list.d/openresty.list' $STD apt-get -y update $STD apt-get -y install --no-install-recommends openresty msg_ok "Installed Openresty" diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index f0694686..4118fab3 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -153,9 +153,7 @@ fi if [[ $CORAL == "Y" ]]; then msg_info "Adding Coral Edge TPU Support" $STD apt-key add <(curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg) -cat </etc/apt/sources.list.d/coral-edgetpu.list -deb https://packages.cloud.google.com/apt coral-edgetpu-stable main -EOF +sh -c 'echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list' $STD apt-get -y update $STD apt-get -y install libedgetpu1-std msg_ok "Coral Edge TPU Support Added" diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index dd5d92f7..f8370423 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -90,9 +90,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Syncthing" curl -s -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg -cat </etc/apt/sources.list.d/syncthing.list -deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable -EOF +sh -c 'echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" > /etc/apt/sources.list.d/syncthing.list' $STD apt-get update $STD apt-get install -y syncthing $STD systemctl enable syncthing@root.service From 454f8d696edf958f87dd55848187b18b2760dfe7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 02:40:33 -0500 Subject: [PATCH 4273/6505] Update influxdb-v5-install.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As of 2023-01-26, InfluxData’s Linux packaging signing key has been rotated. --- install/influxdb-v5-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 0ab4978d..e3f506c3 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -92,8 +92,9 @@ $STD apt-get install -y gnupg2 msg_ok "Installed Dependencies" msg_info "Setting up InfluxDB Repository" -$STD apt-key add <(curl -fsSL https://repos.influxdata.com/influxdb.key) -sh -c 'echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" > sudo tee /etc/apt/sources.list.d/influxdb.list' +wget -q https://repos.influxdata.com/influxdata-archive_compat.key +$STD gpg --with-fingerprint --show-keys ./influxdata-archive_compat.key +sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' msg_ok "Set up InfluxDB Repository" read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt From 076789ca79261111a92de95623c0a1d758ef8d42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 02:46:08 -0500 Subject: [PATCH 4274/6505] Update influxdb-v5-install.sh --- install/influxdb-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index e3f506c3..ed09402b 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -94,6 +94,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up InfluxDB Repository" wget -q https://repos.influxdata.com/influxdata-archive_compat.key $STD gpg --with-fingerprint --show-keys ./influxdata-archive_compat.key +$STD cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' msg_ok "Set up InfluxDB Repository" From f3727c347ac8ba2f12e7940c812ac5ac8d5aa08f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 02:50:05 -0500 Subject: [PATCH 4275/6505] Update influxdb-v5-install.sh --- install/influxdb-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index ed09402b..8fcdca35 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -94,7 +94,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up InfluxDB Repository" wget -q https://repos.influxdata.com/influxdata-archive_compat.key $STD gpg --with-fingerprint --show-keys ./influxdata-archive_compat.key -$STD cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg +cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' msg_ok "Set up InfluxDB Repository" From db0a396df56d189d30c5c6cb0a3e95e8bc00d9c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 02:58:08 -0500 Subject: [PATCH 4276/6505] Update influxdb-v5-install.sh --- install/influxdb-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 8fcdca35..68e31c7d 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -93,7 +93,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up InfluxDB Repository" wget -q https://repos.influxdata.com/influxdata-archive_compat.key -$STD gpg --with-fingerprint --show-keys ./influxdata-archive_compat.key +gpg --with-fingerprint --show-keys ./influxdata-archive_compat.key cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' msg_ok "Set up InfluxDB Repository" From f750bb61593c795ddd51e1168081ce48e859a3aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 04:11:05 -0500 Subject: [PATCH 4277/6505] Update influxdb-v5-install.sh final fix for signing key rotation --- install/influxdb-v5-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 68e31c7d..7efc4406 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -93,8 +93,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up InfluxDB Repository" wget -q https://repos.influxdata.com/influxdata-archive_compat.key -gpg --with-fingerprint --show-keys ./influxdata-archive_compat.key -cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null +cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' msg_ok "Set up InfluxDB Repository" From c360a680f8e8dab8e9c34a8e2463470e798c905f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 09:53:43 -0500 Subject: [PATCH 4278/6505] Create clean-lxcs.sh --- misc/clean-lxcs.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 misc/clean-lxcs.sh diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh new file mode 100644 index 00000000..bc7ce5c0 --- /dev/null +++ b/misc/clean-lxcs.sh @@ -0,0 +1,70 @@ +#!/bin/bash +function header_info { + cat <<"EOF" + ________ __ _ ________ + / ____/ /__ ____ _____ / / | |/ / ____/ + / / / / _ \/ __ `/ __ \ / / | / / +/ /___/ / __/ /_/ / / / / / /___/ / /___ +\____/_/\___/\__,_/_/ /_/ /_____/_/|_\____/ + +EOF +} +set -e +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +CM='\xE2\x9C\x94\033' +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +clear +header_info +while true; do + read -p "This Will Clean logs, cache and update apt lists on all LXC Containers. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +clear +containers=$(pct list | tail -n +2 | cut -f1 -d' ') + +function clean_container() { + container=$1 + clear + header_info + echo -e "${BL}[Info]${GN} Cleaning${BL} $container${CL} \n" + pct exec $container -- bash -c "apt-get -y autoremove && apt-get -y autoclean && rm -rf /var/{cache,log}/* /var/lib/apt/lists/* && apt-get update" +} +read -p "Skip stopped containers? " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + skip=no +else + skip=yes +fi + +for container in $containers; do + status=$(pct status $container) + if [ "$skip" == "no" ]; then + if [ "$status" == "status: stopped" ]; then + echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" + pct start $container + echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" + sleep 5 + clean_container $container + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + clean_container $container + fi + fi + if [ "$skip" == "yes" ]; then + if [ "$status" == "status: running" ]; then + clean_container $container + fi + fi +done +wait + +echo -e "${GN} Finished, All Containers Cleaned. ${CL} \n" From 4cc322d240a51af48648522740f3b6d159a00e74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 10:00:29 -0500 Subject: [PATCH 4279/6505] Update clean-lxcs.sh --- misc/clean-lxcs.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index bc7ce5c0..3c7c2aa3 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -66,5 +66,6 @@ for container in $containers; do fi done wait - +clear +header_info echo -e "${GN} Finished, All Containers Cleaned. ${CL} \n" From 1c327f96a5324c6b117cfc061422652aad313c37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 10:56:20 -0500 Subject: [PATCH 4280/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bb623259..7ae1401d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-27 + +### Changed + +- **LXC Cleaner** + - NEW Script + ## 2023-01-26 ### Changed From 24d94e089d6e1bfab4217208804b5babc950f043 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 20:58:38 -0500 Subject: [PATCH 4281/6505] Update debian-v5.sh --- ct/debian-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 9f007fb1..3aa0fb10 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -380,7 +380,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ From 1a8a13423cb21ad37fd4a9fc17e274e7377add35 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 21:15:50 -0500 Subject: [PATCH 4282/6505] immediately enforce disable IPv6 (#993) --- install/adguard-v5-install.sh | 5 +++-- install/autobrr-v5-install.sh | 5 +++-- install/blocky-v5-install.sh | 5 +++-- install/casaos-v5-install.sh | 5 +++-- install/changedetection-v5-install.sh | 5 +++-- install/cronicle-v5-install.sh | 5 +++-- install/daemonsync-v5-install.sh | 5 +++-- install/dashy-v5-install.sh | 5 +++-- install/debian-v5-install.sh | 5 +++-- install/deconz-v5-install.sh | 5 +++-- install/deluge-v5-install.sh | 5 +++-- install/docker-v5-install.sh | 5 +++-- install/emby-v5-install.sh | 5 +++-- install/emqx-v5-install.sh | 5 +++-- install/esphome-v5-install.sh | 5 +++-- install/grafana-v5-install.sh | 5 +++-- install/grocy-v5-install.sh | 5 +++-- install/heimdalldashboard-v5-install.sh | 5 +++-- install/homeassistant-core-v5-install.sh | 5 +++-- install/homeassistant-v5-install.sh | 5 +++-- install/homebridge-v5-install.sh | 5 +++-- install/homepage-v5-install.sh | 5 +++-- install/homer-v5-install.sh | 5 +++-- install/hyperion-v5-install.sh | 5 +++-- install/influxdb-v5-install.sh | 5 +++-- install/iobroker-v5-install.sh | 5 +++-- install/jellyfin-v5-install.sh | 5 +++-- install/k0s-v5-install.sh | 5 +++-- install/kavita-v5-install.sh | 5 +++-- install/keycloak-v5-install.sh | 5 +++-- install/lidarr-v5-install.sh | 5 +++-- install/magicmirror-v5-install.sh | 5 +++-- install/mariadb-v5-install.sh | 5 +++-- install/meshcentral-v5-install.sh | 5 +++-- install/motioneye-v5-install.sh | 5 +++-- install/mqtt-v5-install.sh | 5 +++-- install/n8n-v5-install.sh | 5 +++-- install/navidrome-v5-install.sh | 5 +++-- install/nextcloudpi-v5-install.sh | 5 +++-- install/nginxproxymanager-v5-install.sh | 5 +++-- install/nocodb-v5-install.sh | 5 +++-- install/node-red-v5-install.sh | 5 +++-- install/omada-v5-install.sh | 5 +++-- install/omv-v5-install.sh | 5 +++-- install/openhab-v5-install.sh | 5 +++-- install/paperless-ngx-v5-install.sh | 5 +++-- install/photoprism-v5-install.sh | 5 +++-- install/pihole-v5-install.sh | 5 +++-- install/plex-v5-install.sh | 5 +++-- install/podman-homeassistant-v5-install.sh | 5 +++-- install/podman-v5-install.sh | 5 +++-- install/postgresql-v5-install.sh | 5 +++-- install/prometheus-v5-install.sh | 5 +++-- install/prowlarr-v5-install.sh | 5 +++-- install/radarr-v5-install.sh | 5 +++-- install/readarr-v5-install.sh | 5 +++-- install/sabnzbd-v5-install.sh | 5 +++-- install/scrypted-v5-install.sh | 5 +++-- install/shinobi-v5-install.sh | 5 +++-- install/sonarr-v5-install.sh | 5 +++-- install/syncthing-v5-install.sh | 5 +++-- install/tdarr-v5-install.sh | 5 +++-- install/technitiumdns-v5-install.sh | 5 +++-- install/transmission-v5-install.sh | 5 +++-- install/trilium-v5-install.sh | 5 +++-- install/ubuntu-v5-install.sh | 5 +++-- install/umbrel-v5-install.sh | 5 +++-- install/unifi-v5-install.sh | 5 +++-- install/uptimekuma-v5-install.sh | 5 +++-- install/vaultwarden-v5-install.sh | 5 +++-- install/whisparr-v5-install.sh | 5 +++-- install/whoogle-v5-install.sh | 5 +++-- install/wikijs-v5-install.sh | 5 +++-- install/wireguard-v5-install.sh | 5 +++-- install/yunohost-v5-install.sh | 5 +++-- install/zigbee2mqtt-v5-install.sh | 5 +++-- install/zwave-js-ui-v5-install.sh | 5 +++-- 77 files changed, 231 insertions(+), 154 deletions(-) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 7b3711ab..497b3a81 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index c66c362c..9c54ff2a 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index f4f9d698..b1b80f4b 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 98e7ae77..1a2358fc 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index da5891f1..bf528d16 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index dc0dbd07..85be2f0a 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index f5f9408b..4281260e 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 4e4a084f..14f76bef 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index f89c2ffb..3a525e6b 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 5b689847..0235e7de 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 963dbe93..19f9449d 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 5d4d19bb..762327dd 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 29d38f1b..ffe06b70 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 26b8daa5..c8fadb4b 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index e4fbcc58..0504c6c9 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index d9dbcdfc..29e171c9 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index c56342c7..d847d5a6 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index a1fc064b..a94d230d 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 2b3a3333..c4663502 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index cb5c9ccf..eaed502e 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 3aedb557..6526111b 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index b2d8ada4..eca56674 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 9f2db9fa..e4f564d5 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index b3eed082..62dd33fc 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 7efc4406..f5becf2e 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index a59032a8..96db7e0b 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 17683b67..99df1d57 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index ab239220..a87798ad 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index bbf7bc1a..b76e7979 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -14,7 +15,7 @@ CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 53e03b5c..4370ce4d 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index f541f553..653c2d7e 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 9f47644a..f347ba92 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index a705ad23..7e5b2265 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index c5e5ed15..e4085bed 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 6dd05e2e..77a8f558 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index b75ccd39..7b2893bb 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 677f21b5..e03de40c 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 8ef3f859..c035e760 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index e6092393..e0cb1628 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index e97c311e..eacab824 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index 15b515bc..1700c038 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index de324a32..20359660 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 30191935..9dabc392 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 9a1801a6..19e6c069 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -21,7 +22,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index 1649094c..4ef6fe28 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 496ae80a..2d3864e0 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index d8831deb..ca60b3df 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -21,7 +22,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 091351f5..e8776260 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -21,7 +22,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 64d33251..93bb66d3 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 20d9c70c..e7831240 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 9fdad038..f893c4d0 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 48d20364..16a24da2 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index de31eb50..5eaad18a 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index f22ccc1a..ace1fe80 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 4f262889..57434a87 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index a776b2cf..b621cb7a 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index fd8b2d51..964f2de7 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 4118fab3..53c2e62d 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 838718b8..b78a3eb2 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index fbbac3ac..d70ec352 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -21,7 +22,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index f8370423..3a78362e 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 8594d8a0..0121ef51 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index add94e24..28de985b 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index d6ead82b..436f527a 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 617ec96d..b4fe4f89 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index d5371ab6..abb5e42f 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 841be405..448920c3 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index ec68eaad..80b4562d 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -21,7 +22,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 5d088390..29af2997 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 9d107133..4ad15ac4 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 7f005241..9cd11da7 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 5fdd8338..659b2d36 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index b138e039..b90beae5 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index c92487b2..06d3cc3f 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 1f79c4a3..02ec6fc8 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index a37264cc..8eae1c36 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index b115a202..3ce383d8 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } if [ "$VERBOSE" == "yes" ]; then set -x; fi -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -20,7 +21,7 @@ set -o pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR -silent() { "$@" > /dev/null 2>&1; } + function error_exit() { trap - ERR local reason="Unknown failure occurred." From 13ece7ef08a236123e72d1b2eb8a3f0608b497ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 21:18:24 -0500 Subject: [PATCH 4283/6505] Update debian-v5.sh switch branch --- ct/debian-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 3aa0fb10..9f007fb1 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -380,7 +380,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/install/$var_install.sh)" || exit +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ From e075b4954a9f87ed4e73144806bcca272f7cc7ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 22:09:23 -0500 Subject: [PATCH 4284/6505] Update pihole-v5-install.sh free port 53 --- install/pihole-v5-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index e8776260..2133980b 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -93,6 +93,9 @@ $STD apt-get install -y ntp msg_ok "Installed Dependencies" msg_info "Installing Pi-hole" +systemctl stop systemd-resolved +echo "DNSStubListener=no" >>/etc/systemd/resolved.conf +ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf mkdir -p /etc/pihole/ cat </etc/pihole/setupVars.conf PIHOLE_INTERFACE=eth0 From 32c38611ae72224957454842e2ad4a892bd4a5a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Jan 2023 22:10:14 -0500 Subject: [PATCH 4285/6505] Update technitiumdns-v5-install.sh free port 53 --- install/technitiumdns-v5-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 28de985b..76abf611 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -90,6 +90,9 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Technitium DNS" +systemctl stop systemd-resolved +echo "DNSStubListener=no" >>/etc/systemd/resolved.conf +ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf $STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) msg_ok "Installed Technitium DNS" From 5328b66cdf7e46c7a3825385bd8262bdfc3173bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Jan 2023 10:31:11 -0500 Subject: [PATCH 4286/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7ae1401d..e0713191 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-01-28 + +### Changed + +- **LXC Cleaner** + - Pulled due to Issues with some Apps + ## 2023-01-27 ### Changed From 24eb8ad256162aa4d7e9b48eac3bd0952cadcca9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Jan 2023 16:16:55 -0500 Subject: [PATCH 4287/6505] Update clean-lxcs.sh code refactoring --- misc/clean-lxcs.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 3c7c2aa3..21d4f892 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -18,6 +18,7 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") clear header_info +echo -e "\n ${RD} USE AT YOUR OWN RISK. Deleting logs/cache may result in some apps/services broken!${CL} \n" while true; do read -p "This Will Clean logs, cache and update apt lists on all LXC Containers. Proceed(y/n)?" yn case $yn in @@ -28,13 +29,13 @@ while true; do done clear containers=$(pct list | tail -n +2 | cut -f1 -d' ') - function clean_container() { container=$1 clear header_info - echo -e "${BL}[Info]${GN} Cleaning${BL} $container${CL} \n" - pct exec $container -- bash -c "apt-get -y autoremove && apt-get -y autoclean && rm -rf /var/{cache,log}/* /var/lib/apt/lists/* && apt-get update" + name=`pct exec $container hostname` + echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" + pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/dev/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" } read -p "Skip stopped containers? " -n 1 -r echo @@ -68,4 +69,4 @@ done wait clear header_info -echo -e "${GN} Finished, All Containers Cleaned. ${CL} \n" +echo -e "${GN} Finished, Containers Cleaned. ${CL} \n" From 118a7d705478e26e3358d0b46ee45de1e7210b17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Jan 2023 16:17:46 -0500 Subject: [PATCH 4288/6505] Create clean.sh --- misc/clean.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 misc/clean.sh diff --git a/misc/clean.sh b/misc/clean.sh new file mode 100644 index 00000000..331bbbe3 --- /dev/null +++ b/misc/clean.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ________ __ _ ________ + / ____/ /__ ____ _____ / / | |/ / ____/ + / / / / _ \/ __ `/ __ \ / / | / / +/ /___/ / __/ /_/ / / / / / /___/ / /___ +\____/_/\___/\__,_/_/ /_/ /_____/_/|_\____/ + +EOF +} +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +name=$(hostname) +clear +header_info +echo -e "${BL}[Info]${GN} Cleaning $name${CL}" +cache=$(find /var/cache/ -type f) + if [[ -z "$cache" ]]; then + echo -e "It appears there are no cached files on your system. \n" + sleep 2 + else + echo -e "$cache \n" + echo -e "${GN}Cache in $name${CL}" + read -p "Would you like to remove the selected cache listed above? [y/n] " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Removing cache" + find /var/cache -type f -delete + echo "Successfully Removed cache" + sleep 2 + fi + fi +clear +header_info +echo -e "${BL}[Info]${GN} Cleaning $name${CL}" +logs=$(find /var/log/ -type f) + if [[ -z "$logs" ]]; then + echo -e "It appears there are no logs on your system. \n" + sleep 2 + else + echo -e "$logs \n" + echo -e "${GN}Logs in $name${CL}" + read -p "Would you like to remove the selected logs listed above? [y/n]" -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Removing logs" + find /var/log -type f -delete + echo "Successfully Removed logs" + sleep 2 + fi + fi + clear + header_info + echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" + echo -e "${GN}Populating apt lists${CL} \n" From 73582a907e09f1e56bab74fe0f04f82c5cd0b78e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Jan 2023 16:46:40 -0500 Subject: [PATCH 4289/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index e0713191..08530649 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **LXC Cleaner** - - Pulled due to Issues with some Apps + - Code refactoring to let the user decide if cache or logs gets deleted for each app/service. ## 2023-01-27 From 6d341109c58d97686273c3faad3308465f60ef7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Jan 2023 16:56:58 -0500 Subject: [PATCH 4290/6505] Update clean-lxcs.sh tweak --- misc/clean-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 21d4f892..f94141e7 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -37,7 +37,7 @@ function clean_container() { echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/dev/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" } -read -p "Skip stopped containers? " -n 1 -r +read -p "Skip stopped containers? [y/N]" -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then skip=no From fcdd5a460ff7dd56de196ce3ea98a89c8fd6b24a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Jan 2023 18:45:40 -0500 Subject: [PATCH 4291/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 08530649..dd704742 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - **LXC Cleaner** - Code refactoring to let the user decide if cache or logs gets deleted for each app/service. + - Leaves directory structure intact ## 2023-01-27 From ecd56591b699f7f8d561a072a937fdedea9acd17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 02:41:12 -0500 Subject: [PATCH 4292/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 80bd78cc..a47b3f08 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -51,7 +51,7 @@ function update_container() { fi } header_info -read -p "Skip stopped containers? " -n 1 -r +read -p "Skip stopped containers? [y/N]" -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then skip=no From 92f11b76609645acaa10532080e1c5e4d0af5327 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 10:04:48 -0500 Subject: [PATCH 4293/6505] Update clean-lxcs.sh fix curl path --- misc/clean-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index f94141e7..4bda3c1a 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -35,7 +35,7 @@ function clean_container() { header_info name=`pct exec $container hostname` echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" - pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/dev/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" + pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" } read -p "Skip stopped containers? [y/N]" -n 1 -r echo From c9e3b72dfa60d0375ea44d7e66c9d732c8552871 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 11:01:07 -0500 Subject: [PATCH 4294/6505] Update clean.sh tweak --- misc/clean.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/clean.sh b/misc/clean.sh index 331bbbe3..8d80649e 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -15,7 +15,7 @@ CL=$(echo "\033[m") name=$(hostname) clear header_info -echo -e "${BL}[Info]${GN} Cleaning $name${CL}" +echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" cache=$(find /var/cache/ -type f) if [[ -z "$cache" ]]; then echo -e "It appears there are no cached files on your system. \n" @@ -34,7 +34,7 @@ cache=$(find /var/cache/ -type f) fi clear header_info -echo -e "${BL}[Info]${GN} Cleaning $name${CL}" +echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" logs=$(find /var/log/ -type f) if [[ -z "$logs" ]]; then echo -e "It appears there are no logs on your system. \n" From 6b3d7a7bf81273cd8c923180f217d7d4886f0a30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 15:20:01 -0500 Subject: [PATCH 4295/6505] Update clean.sh tweak --- misc/clean.sh | 75 ++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/misc/clean.sh b/misc/clean.sh index 8d80649e..00856aa2 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash -function header_info { + +function header_info() { cat <<"EOF" ________ __ _ ________ / ____/ /__ ____ _____ / / | |/ / ____/ @@ -9,49 +10,57 @@ function header_info { EOF } + BL=$(echo "\033[36m") GN=$(echo "\033[1;92m") CL=$(echo "\033[m") name=$(hostname) + clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" + +# Clean cache cache=$(find /var/cache/ -type f) - if [[ -z "$cache" ]]; then - echo -e "It appears there are no cached files on your system. \n" +if [[ -z "$cache" ]]; then + echo -e "It appears there are no cached files on your system. \n" + sleep 2 +else + echo -e "$cache \n" + echo -e "${GN}Cache in $name${CL}" + read -p "Would you like to remove the selected cache listed above? [y/n] " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Removing cache" + find /var/cache -type f -delete + echo "Successfully Removed cache" sleep 2 - else - echo -e "$cache \n" - echo -e "${GN}Cache in $name${CL}" - read -p "Would you like to remove the selected cache listed above? [y/n] " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Removing cache" - find /var/cache -type f -delete - echo "Successfully Removed cache" - sleep 2 - fi - fi + fi +fi + +# Clean logs clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" logs=$(find /var/log/ -type f) - if [[ -z "$logs" ]]; then - echo -e "It appears there are no logs on your system. \n" +if [[ -z "$logs" ]]; then + echo -e "It appears there are no logs on your system. \n" + sleep 2 +else + echo -e "$logs \n" + echo -e "${GN}Logs in $name${CL}" + read -p "Would you like to remove the selected logs listed above? [y/n]" -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Removing logs" + find /var/log -type f -delete + echo "Successfully Removed logs" sleep 2 - else - echo -e "$logs \n" - echo -e "${GN}Logs in $name${CL}" - read -p "Would you like to remove the selected logs listed above? [y/n]" -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Removing logs" - find /var/log -type f -delete - echo "Successfully Removed logs" - sleep 2 - fi - fi - clear - header_info - echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" - echo -e "${GN}Populating apt lists${CL} \n" + fi +fi + +# Populate apt lists +clear +header_info +echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" +echo -e "${GN}Populating apt lists${CL} \n" From f067bc6e86d10f470263d1b026f31c6ba3128de3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 15:38:57 -0500 Subject: [PATCH 4296/6505] Update clean.sh --- misc/clean.sh | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/misc/clean.sh b/misc/clean.sh index 00856aa2..eaa83cd1 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash - function header_info() { cat <<"EOF" ________ __ _ ________ @@ -10,17 +9,13 @@ function header_info() { EOF } - BL=$(echo "\033[36m") GN=$(echo "\033[1;92m") CL=$(echo "\033[m") name=$(hostname) - clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" - -# Clean cache cache=$(find /var/cache/ -type f) if [[ -z "$cache" ]]; then echo -e "It appears there are no cached files on your system. \n" @@ -37,8 +32,6 @@ else sleep 2 fi fi - -# Clean logs clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" @@ -49,7 +42,7 @@ if [[ -z "$logs" ]]; then else echo -e "$logs \n" echo -e "${GN}Logs in $name${CL}" - read -p "Would you like to remove the selected logs listed above? [y/n]" -n 1 -r + read -p "Would you like to remove the selected logs listed above? [y/n] " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Removing logs" @@ -58,8 +51,6 @@ else sleep 2 fi fi - -# Populate apt lists clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" From 04bc43f06f83f2c6e9dc357f7c547ad3b6e1168f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 16:36:03 -0500 Subject: [PATCH 4297/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5334d58e..6e495fb8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ +These script's creates a Linux container in an interactive manner, with Default settings available for a straightforward LXC creation.
    If the user selects Advanced, they are presented with additional options, such as choosing the type of container (privileged or unprivileged), setting the root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects the user's input, validates it, and applies the appropriate values. The final configuration of the container is then generated based on the user's input.
    +

    Proxmox Helper Scripts

    -
    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.
    +
    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.
    From 1b78baa78f6a3ceb4edd87b21c3a843b66f7a938 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 16:39:23 -0500 Subject: [PATCH 4298/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6e495fb8..b04213e4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -These script's creates a Linux container in an interactive manner, with Default settings available for a straightforward LXC creation.
    If the user selects Advanced, they are presented with additional options, such as choosing the type of container (privileged or unprivileged), setting the root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects the user's input, validates it, and applies the appropriate values. The final configuration of the container is then generated based on the user's input.
    +These script's creates a Linux container or virtual machine in an interactive manner, with Default settings available for a straightforward LXC/VM creation.
    If the user selects Advanced, they are presented with additional options, such as choosing the type of container (privileged or unprivileged), setting the root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects the user's input, validates it, and applies the appropriate values. The final configuration of the container or virtual machine is then generated based on the user's input.

    Proxmox Helper Scripts

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.
    From 308ffc8dda80e2ca43471c7c6fb8a4500fbee6a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Jan 2023 16:43:29 -0500 Subject: [PATCH 4299/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b04213e4..d548402a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -These script's creates a Linux container or virtual machine in an interactive manner, with Default settings available for a straightforward LXC/VM creation.
    If the user selects Advanced, they are presented with additional options, such as choosing the type of container (privileged or unprivileged), setting the root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects the user's input, validates it, and applies the appropriate values. The final configuration of the container or virtual machine is then generated based on the user's input.
    +These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup provides additional options such as container type, root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine.

    Proxmox Helper Scripts

    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.
    From 616dd24616b2b66277e93a979c81cda0bbb95f0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 31 Jan 2023 03:40:43 -0500 Subject: [PATCH 4300/6505] Update code-server.sh pve check --- misc/code-server.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/code-server.sh b/misc/code-server.sh index cb55416b..03285dcb 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -40,6 +40,7 @@ function error_exit() { } clear header_info +if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in From 55077eba6c53853052e65174027c4736b0e9e015 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 31 Jan 2023 04:28:36 -0500 Subject: [PATCH 4301/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index dd704742..f4cf8cf6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changed - **LXC Cleaner** - - Code refactoring to let the user decide if cache or logs gets deleted for each app/service. + - Code refactoring to give the user the option to choose whether cache or logs will be deleted for each app/service. - Leaves directory structure intact ## 2023-01-27 From 536ff87b5ff7ef1aaa94fa4e067902dad7650766 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 31 Jan 2023 14:58:55 -0500 Subject: [PATCH 4302/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d548402a..acdc8c2d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup provides additional options such as container type, root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine.

    Proxmox Helper Scripts

    -
    Always remember to use due diligence when sourcing scripts and automation tasks from third-party sites.
    +
    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    From c2593306446c8157a3c00955cec706e90cf0e3ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 31 Jan 2023 22:14:37 -0500 Subject: [PATCH 4303/6505] Update haos-vm-v5.sh full random mac --- vm/haos-vm-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index 2f41df72..0f2cb0b6 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -12,7 +12,7 @@ EOF clear header_info echo -e "\n Loading..." -GEN_MAC=$(echo 'AE 1A 60'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +GEN_MAC=$(openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//' | tr '[:lower:]' '[:upper:]') USEDID=$(pvesh get /cluster/resources --type vm --output-format yaml | egrep -i 'vmid' | awk '{print substr($2, 1, length($2)-0) }') NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') From 4da7e6be7ce685f4acb46c2ecb787d8e5aaf4d4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Feb 2023 10:31:05 -0500 Subject: [PATCH 4304/6505] Update haos-vm-v5.sh revert --- vm/haos-vm-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index 0f2cb0b6..2f41df72 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -12,7 +12,7 @@ EOF clear header_info echo -e "\n Loading..." -GEN_MAC=$(openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//' | tr '[:lower:]' '[:upper:]') +GEN_MAC=$(echo 'AE 1A 60'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') USEDID=$(pvesh get /cluster/resources --type vm --output-format yaml | egrep -i 'vmid' | awk '{print substr($2, 1, length($2)-0) }') NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') From b2b065d77d0eca501f82bb8b382ae33fce63cf8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Feb 2023 11:06:59 -0500 Subject: [PATCH 4305/6505] Update haos-vm-v5.sh ensure unicast random mac address --- vm/haos-vm-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index 2f41df72..445f7f90 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -12,7 +12,7 @@ EOF clear header_info echo -e "\n Loading..." -GEN_MAC=$(echo 'AE 1A 60'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +GEN_MAC=02:$(openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | tr '[:lower:]' '[:upper:]') USEDID=$(pvesh get /cluster/resources --type vm --output-format yaml | egrep -i 'vmid' | awk '{print substr($2, 1, length($2)-0) }') NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') From bc651fc074a80721506860b1171dbd6e083cbd31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Feb 2023 20:46:19 -0500 Subject: [PATCH 4306/6505] Create audiobookshelf-v5-install.sh --- install/audiobookshelf-v5-install.sh | 124 +++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 install/audiobookshelf-v5-install.sh diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh new file mode 100644 index 00000000..13e8a432 --- /dev/null +++ b/install/audiobookshelf-v5-install.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +silent() { "$@" > /dev/null 2>&1; } +if [ "$VERBOSE" == "yes" ]; then set -x; fi +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +NUM=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +while [ "$(hostname -I)" = "" ]; do + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + ((NUM--)) + if [ $NUM -eq 0 ]; then + echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + exit 1 + fi +done +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +alias die='' +if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +alias die='EXIT=$? LINE=$LINENO error_exit' +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing audiobookshelf" +$STD apt-key add <(curl -s --compressed "https://advplyr.github.io/audiobookshelf-ppa/KEY.gpg") +sh -c 'echo "deb https://advplyr.github.io/audiobookshelf-ppa ./" > /etc/apt/sources.list.d/audiobookshelf.list' +$STD apt-get update +$STD apt install audiobookshelf +msg_ok "Installed audiobookshelf" + +PASS=$(grep -w "root" /etc/shadow | cut -b6) +echo "export TERM='xterm-256color'" >>/root/.bashrc +if [[ $PASS != $ ]]; then + msg_info "Customizing Container" + chmod -x /etc/update-motd.d/* + touch ~/.hushlogin + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd +fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 5f4c8b967ab31eab2d55e4a0a4ddb270c7dbe5cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Feb 2023 20:47:50 -0500 Subject: [PATCH 4307/6505] Create audiobookshelf-v5.sh --- ct/audiobookshelf-v5.sh | 390 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 ct/audiobookshelf-v5.sh diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh new file mode 100644 index 00000000..ad90c03c --- /dev/null +++ b/ct/audiobookshelf-v5.sh @@ -0,0 +1,390 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ___ __ __ __ ______ + ____ ___ ______/ (_)___v5/ /_ ____ ____ / /_______/ /_ ___ / / __/ + / __ `/ / / / __ / / __ \/ __ \/ __ \/ __ \/ //_/ ___/ __ \/ _ \/ / /_ +/ /_/ / /_/ / /_/ / / /_/ / /_/ / /_/ / /_/ / ,< (__ ) / / / __/ / __/ +\__,_/\__,_/\__,_/_/\____/_.___/\____/\____/_/|_/____/_/ /_/\___/_/_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="audiobookshelf" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +ARCH_CHECK +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:13378${CL} \n" From eec85f39e734427dd499ffc1c2a4bf1d12f2dc9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Feb 2023 21:12:25 -0500 Subject: [PATCH 4308/6505] Create rockylinux-v5.sh --- ct/rockylinux-v5.sh | 393 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 ct/rockylinux-v5.sh diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh new file mode 100644 index 00000000..8cf707f2 --- /dev/null +++ b/ct/rockylinux-v5.sh @@ -0,0 +1,393 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ __ __ _ + / __ \____ _____/ /____ __ / / (_)___v5__ ___ __ + / /_/ / __ \/ ___/ //_/ / / / / / / / __ \/ / / / |/_/ + / _, _/ /_/ / /__/ ,< / /_/ / / /___/ / / / / /_/ /> < +/_/ |_|\____/\___/_/|_|\__, / /_____/_/_/ /_/\__,_/_/|_| + /____/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Rocky Linux" +var_disk="1" +var_cpu="1" +var_ram="512" +var_os="rockylinux" +var_version="9" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/pacman.d ]]; then + msg_error "No ${APP} Installation Found!"; + exit + fi + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}archlinux${CL}" + PW="-password rockylinux" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="rockylinux" PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + VERB2="" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + VERB2="silent" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating ${APP} LXC" +pacman-key --init +pacman-key --populate archlinux +pacman -Sy archlinux-keyring && pacman -Su +msg_ok "Update Successfull" +exit +} +clear +ARCH_CHECK +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export VERBOSE=$VERB +export STD=$VERB2 +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 108f3ffe5f14c8b248ee62a3603d0e24f3706d2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Feb 2023 10:35:31 -0500 Subject: [PATCH 4309/6505] Update update-lxcs.sh add rocky -centos-alma --- misc/update-lxcs.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index a47b3f08..e4542e09 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash function header_info { cat <<"EOF" __ __ __ __ __ _ ________ @@ -41,9 +41,9 @@ function update_container() { if [ "$os" == "alpine" ]; then pct exec $container -- ash -c "apk update && apk upgrade" elif [ "$os" == "ubuntu" ] || [ "$os" == "debian" ] || [ "$os" == "devuan" ]; then - pct exec $container -- bash -c "apt-get update && apt-get upgrade -y && apt-get clean && apt-get --purge autoremove -y" - elif [ "$os" == "fedora" ]; then - pct exec $container -- bash -c "dnf -y update && dnf -y upgrade && dnf -y --purge autoremove" + pct exec $container -- bash -c "apt-get update && apt-get -y upgrade" + elif [ "$os" == "fedora" ] || [ "$os" == "rocky" ] || [ "$os" == "centos" ] || [ "$os" == "alma" ]; then + pct exec $container -- bash -c "dnf -y update && dnf -y upgrade" elif [ "$os" == "archlinux" ]; then pct exec $container -- bash -c "pacman -Syyu --noconfirm" else From 7cbbb1b38a27986a59f79babd1249e47db4ff952 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Feb 2023 11:21:37 -0500 Subject: [PATCH 4310/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f4cf8cf6..1bbf3c61 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,15 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-02-02 + +### Changed + +- **Audiobookshelf LXC** + - NEW Script +- **Rocky Linux LXC** + - NEW Script + ## 2023-01-28 ### Changed From c8aa5a029decffb2d1b8f33b91bb7f50126eaab5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 07:15:15 -0500 Subject: [PATCH 4311/6505] more pruning & code refactoring (#1011) * improve error handling to show more details * improve the way it checks for root password * consistant getty_override * streamline verbose mode * remove v4 scripts * small tweaks --- ct/adguard-v4.sh | 329 ------------------ ct/adguard-v5.sh | 25 +- ct/alpine-v5.sh | 25 +- ct/archlinux-v5.sh | 25 +- ct/audiobookshelf-v5.sh | 25 +- ct/autobrr-v5.sh | 25 +- ct/blocky-v4.sh | 327 ------------------ ct/blocky-v5.sh | 25 +- ct/casaos-v4.sh | 344 ------------------- ct/casaos-v5.sh | 25 +- ct/changedetection-v4.sh | 329 ------------------ ct/changedetection-v5.sh | 25 +- ct/create_lxc.sh | 23 +- ct/cronicle-v5.sh | 25 +- ct/daemonsync-v4.sh | 329 ------------------ ct/daemonsync-v5.sh | 25 +- ct/dashy-v4.sh | 329 ------------------ ct/dashy-v5.sh | 25 +- ct/debian-v4.sh | 326 ------------------ ct/debian-v5.sh | 25 +- ct/deconz-v4.sh | 343 ------------------- ct/deconz-v5.sh | 24 +- ct/deluge-v5.sh | 25 +- ct/docker-v4.sh | 353 ------------------- ct/docker-v5.sh | 25 +- ct/emby-v4.sh | 350 ------------------- ct/emby-v5.sh | 25 +- ct/emqx-v4.sh | 329 ------------------ ct/emqx-v5.sh | 25 +- ct/esphome-v4.sh | 328 ------------------ ct/esphome-v5.sh | 25 +- ct/grafana-v4.sh | 328 ------------------ ct/grafana-v5.sh | 25 +- ct/grocy-v4.sh | 328 ------------------ ct/grocy-v5.sh | 25 +- ct/heimdalldashboard-v4.sh | 328 ------------------ ct/heimdalldashboard-v5.sh | 25 +- ct/homeassistant-core-v4.sh | 343 ------------------- ct/homeassistant-core-v5.sh | 26 +- ct/homeassistant-v4.sh | 357 -------------------- ct/homeassistant-v5.sh | 25 +- ct/homebridge-v4.sh | 328 ------------------ ct/homebridge-v5.sh | 25 +- ct/homepage-v4.sh | 329 ------------------ ct/homepage-v5.sh | 25 +- ct/homer-v5.sh | 25 +- ct/hyperion-v4.sh | 344 ------------------- ct/hyperion-v5.sh | 25 +- ct/influxdb-v4.sh | 326 ------------------ ct/influxdb-v5.sh | 25 +- ct/iobroker-v4.sh | 328 ------------------ ct/iobroker-v5.sh | 25 +- ct/jellyfin-v4.sh | 350 ------------------- ct/jellyfin-v5.sh | 25 +- ct/k0s-v5.sh | 25 +- ct/kavita-v5.sh | 25 +- ct/keycloak-v4.sh | 329 ------------------ ct/keycloak-v5.sh | 25 +- ct/lidarr-v5.sh | 25 +- ct/magicmirror-v4.sh | 329 ------------------ ct/magicmirror-v5.sh | 25 +- ct/mariadb-v4.sh | 326 ------------------ ct/mariadb-v5.sh | 25 +- ct/meshcentral-v4.sh | 328 ------------------ ct/meshcentral-v5.sh | 25 +- ct/motioneye-v4.sh | 328 ------------------ ct/motioneye-v5.sh | 25 +- ct/mqtt-v4.sh | 293 ---------------- ct/mqtt-v5.sh | 25 +- ct/n8n-v4.sh | 329 ------------------ ct/n8n-v5.sh | 25 +- ct/navidrome-v4.sh | 328 ------------------ ct/navidrome-v5.sh | 25 +- ct/nextcloudpi-v4.sh | 329 ------------------ ct/nextcloudpi-v5.sh | 25 +- ct/nginx-proxy-manager-v4.sh | 329 ------------------ ct/nginxproxymanager-v5.sh | 25 +- ct/nocodb-v4.sh | 328 ------------------ ct/nocodb-v5.sh | 25 +- ct/node-red-v4.sh | 328 ------------------ ct/node-red-v5.sh | 25 +- ct/omada-v4.sh | 337 ------------------ ct/omada-v5.sh | 25 +- ct/omv-v4.sh | 339 ------------------- ct/omv-v5.sh | 25 +- ct/openhab-v4.sh | 329 ------------------ ct/openhab-v5.sh | 25 +- ct/paperless-ngx-v4.sh | 329 ------------------ ct/paperless-ngx-v5.sh | 25 +- ct/photoprism-v4.sh | 331 ------------------ ct/photoprism-v5.sh | 25 +- ct/pihole-v4.sh | 328 ------------------ ct/pihole-v5.sh | 25 +- ct/plex-v4.sh | 350 ------------------- ct/plex-v5.sh | 25 +- ct/podman-homeassistant-v4.sh | 354 ------------------- ct/podman-homeassistant-v5.sh | 25 +- ct/podman-v5.sh | 25 +- ct/postgresql-v4.sh | 327 ------------------ ct/postgresql-v5.sh | 25 +- ct/prometheus-v4.sh | 328 ------------------ ct/prometheus-v5.sh | 25 +- ct/prowlarr-v5.sh | 25 +- ct/radarr-v5.sh | 25 +- ct/readarr-v5.sh | 25 +- ct/rockylinux-v5.sh | 25 +- ct/sabnzbd-v5.sh | 25 +- ct/scrypted-v4.sh | 343 ------------------- ct/scrypted-v5.sh | 25 +- ct/shinobi-v4.sh | 338 ------------------- ct/shinobi-v5.sh | 25 +- ct/sonarr-v5.sh | 25 +- ct/syncthing-v4.sh | 330 ------------------ ct/syncthing-v5.sh | 25 +- ct/tdarr-v5.sh | 25 +- ct/technitiumdns-v4.sh | 328 ------------------ ct/technitiumdns-v5.sh | 25 +- ct/transmission-v5.sh | 25 +- ct/trilium-v4.sh | 329 ------------------ ct/trilium-v5.sh | 25 +- ct/ubuntu-v4.sh | 335 ------------------ ct/ubuntu-v5.sh | 25 +- ct/umbrel-v4.sh | 344 ------------------- ct/umbrel-v5.sh | 25 +- ct/unifi-v4.sh | 328 ------------------ ct/unifi-v5.sh | 25 +- ct/uptimekuma-v4.sh | 329 ------------------ ct/uptimekuma-v5.sh | 25 +- ct/vaultwarden-v4.sh | 332 ------------------ ct/vaultwarden-v5.sh | 25 +- ct/whisparr-v5.sh | 25 +- ct/whoogle-v4.sh | 328 ------------------ ct/whoogle-v5.sh | 25 +- ct/wikijs-v4.sh | 329 ------------------ ct/wikijs-v5.sh | 25 +- ct/wireguard-v4.sh | 330 ------------------ ct/wireguard-v5.sh | 25 +- ct/yunohost-v5.sh | 25 +- ct/zigbee2mqtt-v4.sh | 341 ------------------- ct/zigbee2mqtt-v5.sh | 25 +- ct/zwave-js-ui-v4.sh | 343 ------------------- ct/zwave-js-ui-v5.sh | 25 +- install/adguard-install.sh | 119 ------- install/adguard-v5-install.sh | 56 ++- install/audiobookshelf-v5-install.sh | 55 ++- install/autobrr-v5-install.sh | 55 ++- install/blocky-install.sh | 375 --------------------- install/blocky-v5-install.sh | 55 ++- install/casaos-install.sh | 135 -------- install/casaos-v5-install.sh | 56 ++- install/changedetection-install.sh | 134 -------- install/changedetection-v5-install.sh | 55 ++- install/cronicle-v5-install.sh | 55 ++- install/daemonsync-install.sh | 121 ------- install/daemonsync-v5-install.sh | 56 ++- install/dashy-install.sh | 152 --------- install/dashy-v5-install.sh | 56 ++- install/debian-install.sh | 113 ------- install/debian-v5-install.sh | 55 ++- install/deconz-install.sh | 145 -------- install/deconz-v5-install.sh | 55 ++- install/deluge-v5-install.sh | 55 ++- install/docker-install.sh | 176 ---------- install/docker-v5-install.sh | 56 ++- install/emby-install.sh | 135 -------- install/emby-v5-install.sh | 55 ++- install/emqx-install.sh | 119 ------- install/emqx-v5-install.sh | 55 ++- install/esphome-install.sh | 141 -------- install/esphome-v5-install.sh | 56 ++- install/grafana-install.sh | 130 ------- install/grafana-v5-install.sh | 56 ++- install/grocy-install.sh | 158 --------- install/grocy-v5-install.sh | 55 ++- install/heimdalldashboard-install.sh | 152 --------- install/heimdalldashboard-v5-install.sh | 56 ++- install/homeassistant-core-install.sh | 207 ------------ install/homeassistant-core-v5-install.sh | 55 ++- install/homeassistant-install.sh | 360 -------------------- install/homeassistant-v5-install.sh | 56 ++- install/homebridge-install.sh | 131 ------- install/homebridge-v5-install.sh | 56 ++- install/homepage-install.sh | 149 -------- install/homepage-v5-install.sh | 55 ++- install/homer-v5-install.sh | 55 ++- install/hyperion-install.sh | 124 ------- install/hyperion-v5-install.sh | 55 ++- install/influxdb-install.sh | 153 --------- install/influxdb-v5-install.sh | 56 ++- install/iobroker-install.sh | 119 ------- install/iobroker-v5-install.sh | 56 ++- install/jellyfin-install.sh | 159 --------- install/jellyfin-v5-install.sh | 55 ++- install/k0s-v5-install.sh | 55 ++- install/kavita-v5-install.sh | 32 +- install/keycloak-install.sh | 140 -------- install/keycloak-v5-install.sh | 55 ++- install/lidarr-v5-install.sh | 55 ++- install/magicmirror-install.sh | 242 ------------- install/magicmirror-v5-install.sh | 17 +- install/mariadb-install.sh | 136 -------- install/mariadb-v5-install.sh | 56 ++- install/meshcentral-install.sh | 130 ------- install/meshcentral-v5-install.sh | 56 ++- install/motioneye-install.sh | 149 -------- install/motioneye-v5-install.sh | 56 ++- install/mqtt-install.sh | 126 ------- install/mqtt-v5-install.sh | 56 ++- install/n8n-install.sh | 142 -------- install/n8n-v5-install.sh | 56 ++- install/navidrome-install.sh | 169 ---------- install/navidrome-v5-install.sh | 55 ++- install/nextcloudpi-install.sh | 119 ------- install/nextcloudpi-v5-install.sh | 55 ++- install/nginx-proxy-manager-install.sh | 280 --------------- install/nginxproxymanager-v5-install.sh | 56 ++- install/nocodb-install.sh | 148 -------- install/nocodb-v5-install.sh | 56 ++- install/node-red-install.sh | 150 --------- install/node-red-v5-install.sh | 56 ++- install/omada-install.sh | 124 ------- install/omada-v5-install.sh | 55 ++- install/omv-install.sh | 136 -------- install/omv-v5-install.sh | 55 ++- install/openhab-install.sh | 136 -------- install/openhab-v5-install.sh | 55 ++- install/paperless-ngx-install.sh | 287 ---------------- install/paperless-ngx-v5-install.sh | 14 +- install/photoprism-install.sh | 218 ------------ install/photoprism-v5-install.sh | 56 ++- install/pihole-install.sh | 139 -------- install/pihole-v5-install.sh | 56 ++- install/plex-install.sh | 138 -------- install/plex-v5-install.sh | 55 ++- install/podman-homeassistant-install.sh | 172 ---------- install/podman-homeassistant-v5-install.sh | 56 ++- install/podman-v5-install.sh | 55 ++- install/postgresql-install.sh | 243 ------------- install/postgresql-v5-install.sh | 55 ++- install/prometheus-install.sh | 149 -------- install/prometheus-v5-install.sh | 55 ++- install/prowlarr-v5-install.sh | 55 ++- install/radarr-v5-install.sh | 55 ++- install/readarr-v5-install.sh | 55 ++- install/sabnzbd-v5-install.sh | 55 ++- install/scrypted-install.sh | 207 ------------ install/scrypted-v5-install.sh | 55 ++- install/shinobi-install.sh | 177 ---------- install/shinobi-v5-install.sh | 55 ++- install/sonarr-v5-install.sh | 55 ++- install/syncthing-install.sh | 126 ------- install/syncthing-v5-install.sh | 55 ++- install/tdarr-v5-install.sh | 55 ++- install/technitiumdns-install.sh | 119 ------- install/technitiumdns-v5-install.sh | 56 ++- install/transmission-v5-install.sh | 55 ++- install/trilium-install.sh | 144 -------- install/trilium-v5-install.sh | 55 ++- install/ubuntu-install.sh | 114 ------- install/ubuntu-v5-install.sh | 55 ++- install/umbrel-install.sh | 135 -------- install/umbrel-v5-install.sh | 56 ++- install/unifi-install.sh | 127 ------- install/unifi-v5-install.sh | 56 ++- install/uptimekuma-install.sh | 148 -------- install/uptimekuma-v5-install.sh | 56 ++- install/vaultwarden-install.sh | 204 ----------- install/vaultwarden-v5-install.sh | 56 ++- install/whisparr-v5-install.sh | 55 ++- install/whoogle-install.sh | 136 -------- install/whoogle-v5-install.sh | 55 ++- install/wikijs-install.sh | 164 --------- install/wikijs-v5-install.sh | 55 ++- install/wireguard-install.sh | 178 ---------- install/wireguard-v5-install.sh | 56 ++- install/yunohost-v5-install.sh | 55 ++- install/zigbee2mqtt-install.sh | 164 --------- install/zigbee2mqtt-v5-install.sh | 56 ++- install/zwave-js-ui-install.sh | 141 -------- install/zwave-js-ui-v5-install.sh | 56 ++- 280 files changed, 2486 insertions(+), 33413 deletions(-) delete mode 100644 ct/adguard-v4.sh delete mode 100644 ct/blocky-v4.sh delete mode 100644 ct/casaos-v4.sh delete mode 100644 ct/changedetection-v4.sh delete mode 100644 ct/daemonsync-v4.sh delete mode 100644 ct/dashy-v4.sh delete mode 100644 ct/debian-v4.sh delete mode 100644 ct/deconz-v4.sh delete mode 100644 ct/docker-v4.sh delete mode 100644 ct/emby-v4.sh delete mode 100644 ct/emqx-v4.sh delete mode 100644 ct/esphome-v4.sh delete mode 100644 ct/grafana-v4.sh delete mode 100644 ct/grocy-v4.sh delete mode 100644 ct/heimdalldashboard-v4.sh delete mode 100644 ct/homeassistant-core-v4.sh delete mode 100644 ct/homeassistant-v4.sh delete mode 100644 ct/homebridge-v4.sh delete mode 100644 ct/homepage-v4.sh delete mode 100644 ct/hyperion-v4.sh delete mode 100644 ct/influxdb-v4.sh delete mode 100644 ct/iobroker-v4.sh delete mode 100644 ct/jellyfin-v4.sh delete mode 100644 ct/keycloak-v4.sh delete mode 100644 ct/magicmirror-v4.sh delete mode 100644 ct/mariadb-v4.sh delete mode 100644 ct/meshcentral-v4.sh delete mode 100644 ct/motioneye-v4.sh delete mode 100644 ct/mqtt-v4.sh delete mode 100644 ct/n8n-v4.sh delete mode 100644 ct/navidrome-v4.sh delete mode 100644 ct/nextcloudpi-v4.sh delete mode 100644 ct/nginx-proxy-manager-v4.sh delete mode 100644 ct/nocodb-v4.sh delete mode 100644 ct/node-red-v4.sh delete mode 100644 ct/omada-v4.sh delete mode 100644 ct/omv-v4.sh delete mode 100644 ct/openhab-v4.sh delete mode 100644 ct/paperless-ngx-v4.sh delete mode 100644 ct/photoprism-v4.sh delete mode 100644 ct/pihole-v4.sh delete mode 100644 ct/plex-v4.sh delete mode 100644 ct/podman-homeassistant-v4.sh delete mode 100644 ct/postgresql-v4.sh delete mode 100644 ct/prometheus-v4.sh delete mode 100644 ct/scrypted-v4.sh delete mode 100644 ct/shinobi-v4.sh delete mode 100644 ct/syncthing-v4.sh delete mode 100644 ct/technitiumdns-v4.sh delete mode 100644 ct/trilium-v4.sh delete mode 100644 ct/ubuntu-v4.sh delete mode 100644 ct/umbrel-v4.sh delete mode 100644 ct/unifi-v4.sh delete mode 100644 ct/uptimekuma-v4.sh delete mode 100644 ct/vaultwarden-v4.sh delete mode 100644 ct/whoogle-v4.sh delete mode 100644 ct/wikijs-v4.sh delete mode 100644 ct/wireguard-v4.sh delete mode 100644 ct/zigbee2mqtt-v4.sh delete mode 100644 ct/zwave-js-ui-v4.sh delete mode 100644 install/adguard-install.sh delete mode 100644 install/blocky-install.sh delete mode 100644 install/casaos-install.sh delete mode 100644 install/changedetection-install.sh delete mode 100644 install/daemonsync-install.sh delete mode 100644 install/dashy-install.sh delete mode 100644 install/debian-install.sh delete mode 100644 install/deconz-install.sh delete mode 100644 install/docker-install.sh delete mode 100644 install/emby-install.sh delete mode 100644 install/emqx-install.sh delete mode 100644 install/esphome-install.sh delete mode 100644 install/grafana-install.sh delete mode 100644 install/grocy-install.sh delete mode 100644 install/heimdalldashboard-install.sh delete mode 100644 install/homeassistant-core-install.sh delete mode 100644 install/homeassistant-install.sh delete mode 100644 install/homebridge-install.sh delete mode 100644 install/homepage-install.sh delete mode 100644 install/hyperion-install.sh delete mode 100644 install/influxdb-install.sh delete mode 100644 install/iobroker-install.sh delete mode 100644 install/jellyfin-install.sh delete mode 100644 install/keycloak-install.sh delete mode 100644 install/magicmirror-install.sh delete mode 100644 install/mariadb-install.sh delete mode 100644 install/meshcentral-install.sh delete mode 100644 install/motioneye-install.sh delete mode 100644 install/mqtt-install.sh delete mode 100644 install/n8n-install.sh delete mode 100644 install/navidrome-install.sh delete mode 100644 install/nextcloudpi-install.sh delete mode 100644 install/nginx-proxy-manager-install.sh delete mode 100644 install/nocodb-install.sh delete mode 100644 install/node-red-install.sh delete mode 100644 install/omada-install.sh delete mode 100644 install/omv-install.sh delete mode 100644 install/openhab-install.sh delete mode 100644 install/paperless-ngx-install.sh delete mode 100644 install/photoprism-install.sh delete mode 100644 install/pihole-install.sh delete mode 100644 install/plex-install.sh delete mode 100644 install/podman-homeassistant-install.sh delete mode 100644 install/postgresql-install.sh delete mode 100644 install/prometheus-install.sh delete mode 100644 install/scrypted-install.sh delete mode 100644 install/shinobi-install.sh delete mode 100644 install/syncthing-install.sh delete mode 100644 install/technitiumdns-install.sh delete mode 100644 install/trilium-install.sh delete mode 100644 install/ubuntu-install.sh delete mode 100644 install/umbrel-install.sh delete mode 100644 install/unifi-install.sh delete mode 100644 install/uptimekuma-install.sh delete mode 100644 install/vaultwarden-install.sh delete mode 100644 install/whoogle-install.sh delete mode 100644 install/wikijs-install.sh delete mode 100644 install/wireguard-install.sh delete mode 100644 install/zigbee2mqtt-install.sh delete mode 100644 install/zwave-js-ui-install.sh diff --git a/ct/adguard-v4.sh b/ct/adguard-v4.sh deleted file mode 100644 index c7f12804..00000000 --- a/ct/adguard-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Adguard" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${GN} - ___ __ __ - / | ____/ /___ ___ ______ __________/ / - / /| |/ __ / __ / / / / __ / ___/ __ / - / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / -/_/v4|_\__,_/\__, /\__,_/\__,_/_/ \__,_/ - /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index daf5027a..9cec3c16 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -141,7 +135,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -316,7 +309,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -380,7 +372,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 7f9c7d03..38ffc8c7 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -314,7 +307,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -359,7 +351,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index afef7c5a..8e424a66 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index ad90c03c..86199f22 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 5f3589ba..fa31ef71 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -141,7 +135,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -316,7 +309,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -372,7 +364,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/blocky-v4.sh b/ct/blocky-v4.sh deleted file mode 100644 index 507d2f71..00000000 --- a/ct/blocky-v4.sh +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Blocky" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ____ __ __ - / __ )/ /___v4_____/ /____ __ - / __ / / __ \/ ___/ //_/ / / / - / /_/ / / /_/ / /__/ ,< / /_/ / -/_____/_/\____/\___/_/|_|\__, / - /____/ -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index 7291b0be..efe66ff7 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/casaos-v4.sh b/ct/casaos-v4.sh deleted file mode 100644 index b3ae3583..00000000 --- a/ct/casaos-v4.sh +++ /dev/null @@ -1,344 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="CasaOS" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ______ ____ _____ - / ____/___ __v4______ _/ __ \/ ___/ - / / / __ `/ ___/ __ `/ / / /\__ \ -/ /___/ /_/ (__ ) /_/ / /_/ /___/ / -\____/\__,_/____/\__,_/\____//____/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export ST=$FUSE -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP} ${CL} \n" diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 2a7e1c93..bb901bca 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -144,7 +138,6 @@ function default_settings() { FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -326,7 +319,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -373,7 +365,6 @@ pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/changedetection-v4.sh b/ct/changedetection-v4.sh deleted file mode 100644 index 95108992..00000000 --- a/ct/changedetection-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Change Detection" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ________ ____ __ __ _ - / ____/ /_v4____ _____ ____ ____ / __ \___ / /____ _____/ /_(_)___ ____ - / / / __ \/ __ `/ __ \/ __ `/ _ \ / / / / _ \/ __/ _ \/ ___/ __/ / __ \/ __ \ -/ /___/ / / / /_/ / / / / /_/ / __/ / /_/ / __/ /_/ __/ /__/ /_/ / /_/ / / / / -\____/_/ /_/\__,_/_/ /_/\__, /\___/ /_____/\___/\__/\___/\___/\__/_/\____/_/ /_/ - /____/ -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index e50e3fda..13afb78e 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -362,7 +354,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index c0af30d9..f6071c13 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -36,21 +36,14 @@ if [ -z "$VALIDTMP" ]; then exit 1 fi -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function select_storage() { diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index e1e831cc..bf0495e1 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -33,20 +33,14 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" hostname="$(hostname)" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -140,7 +134,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -315,7 +308,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -410,7 +402,6 @@ pushd $TEMP_DIR >/dev/null export SERV=$SERVER export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/daemonsync-v4.sh b/ct/daemonsync-v4.sh deleted file mode 100644 index faaf9a81..00000000 --- a/ct/daemonsync-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Daemon Sync" -var_disk="8" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - ____ _____ - / __ \____ ____ ____ ___ ____ ____ / ___/__ ______ _____ - / / / / __ / _ \/ __ __ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/ - / /_/ / /_/ / __/ / / / / / /_/ / / / / ___/ / /_/ / / / / /__ -/_____/\__,_/\___/_/ /_/ /_/\____/_/ /_/ v4/____/\__, /_/ /_/\___/ - /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index c79e3cac..401086bb 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/dashy-v4.sh b/ct/dashy-v4.sh deleted file mode 100644 index f128a191..00000000 --- a/ct/dashy-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Dashy" -var_disk="3" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - ____ __ - / __ \____ ______/ /_ __ __ - / / / / __ / ___/ __ \/ / / / - / /_/ / /_/ (__ ) / / / /_/ / -/_____/\__,_/____/_/ /_/\__, / - v4 /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index d3ed0919..069b8ee1 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -389,7 +381,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/debian-v4.sh b/ct/debian-v4.sh deleted file mode 100644 index 441ebe05..00000000 --- a/ct/debian-v4.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Debian" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - ____ __________ _______ _ __ - / __ \/ ____/ __ )/ _/ | / | / / - / / / / __/ / __ |/ // /| | / |/ / - / /_/ / /_v4/ /_/ // // ___ |/ /| / -/_____/_____/_____/___/_/ |_/_/ |_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 9f007fb1..9fae150f 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/deconz-v4.sh b/ct/deconz-v4.sh deleted file mode 100644 index 87a41090..00000000 --- a/ct/deconz-v4.sh +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="deCONZ" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - __ __________ _ _______ - ____/ /v4 / ____/ __ \/ | / /__ / - / __ / _ \/ / / / / / |/ / / / -/ /_/ / __/ /___/ /_/ / /| / / /__ -\__,_/\___/\____/\____/_/ |_/ /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL}\n" diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index f99fffb4..8368ce39 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -317,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index f6124413..93fde875 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -139,7 +133,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -314,7 +307,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -359,7 +351,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/docker-v4.sh b/ct/docker-v4.sh deleted file mode 100644 index d3a6ee55..00000000 --- a/ct/docker-v4.sh +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Docker" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - ____ __ - / __ \____ _____/ /_v4__ _____ - / / / / __ \/ ___/ //_/ _ \/ ___/ - / /_/ / /_/ / /__/ ,< / __/ / -/_____/\____/\___/_/|_|\___/_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export ST=$FUSE -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$CT_TYPE" == "0" ]; then -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index d2e3c0a7..5d4b2eb2 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -325,7 +318,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -370,7 +362,6 @@ pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/emby-v4.sh b/ct/emby-v4.sh deleted file mode 100644 index 4935a5c9..00000000 --- a/ct/emby-v4.sh +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Emby" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${DGN} - ______ __ - / ____/___ v4_ / /_ __ __ - / __/ / __ __ \/ __ \/ / / / - / /___/ / / / / / /_/ / /_/ / -/_____/_/ /_/ /_/_.___/\__, / - /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 7392ac61..fb1392ac 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -326,7 +319,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -382,7 +374,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/emqx-v4.sh b/ct/emqx-v4.sh deleted file mode 100644 index 032b2ec9..00000000 --- a/ct/emqx-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="EMQX" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ________ _______v4 _ __ - / ____/ |/ / __ \ | |/ / - / __/ / /|_/ / / / / | / - / /___/ / / / /_/ / / | -/_____/_/ /_/\___\_\/_/|_| - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:18083${CL} \n" diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 26360cbc..5f0aaa9a 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -362,7 +354,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/esphome-v4.sh b/ct/esphome-v4.sh deleted file mode 100644 index dc4fe5bf..00000000 --- a/ct/esphome-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="ESPHome" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${CL} - ___________ ____ __ ______ __ _________ - / ____/ ___// __ \/ / / / __ \/ |/ / ____/ - / __/ \__ \/ /_/ / /_/ / / / / /|_/ / __/ - / /___ ___/ / ____/ __ / /_/ / / / / /_v4 -/_____//____/_/ /_/ /_/\____/_/ /_/_____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index 6ec4e410..b0a51c9c 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -369,7 +361,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/grafana-v4.sh b/ct/grafana-v4.sh deleted file mode 100644 index f89a2857..00000000 --- a/ct/grafana-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Grafana" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - ______ ____ - / ____/________ _/ __/___ _____ ____ _ - / / __/ ___/ __ / /_/ __ / __ \/ __ / -/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / -\____/_/ v4\__,_/_/ \__,_/_/ /_/\__,_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 85e1b111..38514eed 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/grocy-v4.sh b/ct/grocy-v4.sh deleted file mode 100644 index e355e177..00000000 --- a/ct/grocy-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="grocy" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - ____ __________ _______ __ - / __ / ___/ __ \/ ___/ / / / - / /_/ / / / /_/ / /__/ /_/ / - \__, /_/ \____/\___/\__, / -/____/ v4 /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 62441b72..64a58fe6 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -362,7 +354,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/heimdalldashboard-v4.sh b/ct/heimdalldashboard-v4.sh deleted file mode 100644 index f39c042f..00000000 --- a/ct/heimdalldashboard-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Heimdall Dashboard" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - __ __ _ __ ____ ____ __ __ __ - / / / /__ (_)___ ___ ____/ /_v4 _/ / / / __ \____ ______/ /_ / /_ ____ ____ __________/ / - / /_/ / _ \/ / __ __ \/ __ / __ / / / / / / / __ / ___/ __ \/ __ \/ __ \/ __ / ___/ __ / - / __ / __/ / / / / / / /_/ / /_/ / / / / /_/ / /_/ (__ ) / / / /_/ / /_/ / /_/ / / / /_/ / -/_/ /_/\___/_/_/ /_/ /_/\__,_/\__,_/_/_/ /_____/\__,_/____/_/ /_/_.___/\____/\__,_/_/ \__,_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 00dddee1..4dcc78d0 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -442,7 +434,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homeassistant-core-v4.sh b/ct/homeassistant-core-v4.sh deleted file mode 100644 index ae1cd2c7..00000000 --- a/ct/homeassistant-core-v4.sh +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Home Assistant-Core" -var_disk="8" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - _ _ _ _ ___ - /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___v4_ __ ___ - / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ -/ __ / (_) | | | | | | __/ / _ \__ \__ \ \__ \ || (_| | | | | |_ / /__| (_) | | | __/ -\/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable (after it's initialized) by going to the following URL. - ${BL}http://${IP}:8123${CL}" diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 1d67e929..769a6f1a 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -34,21 +34,14 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -144,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } @@ -320,7 +312,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -438,7 +429,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homeassistant-v4.sh b/ct/homeassistant-v4.sh deleted file mode 100644 index 1407f92c..00000000 --- a/ct/homeassistant-v4.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Home Assistant" -var_disk="16" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - __ __ ___ _ __ __ - / / / /___ ____ ___ ___ v4 / | __________(_)____/ /_____ _____ / /_ - / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export ST=$FUSE -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$CT_TYPE" == "0" ]; then -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} -Portainer should be reachable by going to the following URL. - ${BL}http://${IP}:9000${CL}\n" diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index afaa19eb..49de18fd 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -145,7 +139,6 @@ function default_settings() { FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } @@ -328,7 +321,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -438,7 +430,6 @@ pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homebridge-v4.sh b/ct/homebridge-v4.sh deleted file mode 100644 index 5aa8300e..00000000 --- a/ct/homebridge-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Homebridge" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - __ ______ __ _____________ ____ ________ ____________ - / / / / __ \/ |/ / ____/ __ )/ __ \/ _/ __ \/ ____/ ____/ - / /_/ / / / / /|_/ / __/ / __ / /_/ // // / / / / __/ __/ - / __ / /_/ / / / / /___/ /_/ / _, _// // /_/ / /_/ / /___ -/_/ /_/\____/_/v4/_/_____/_____/_/ |_/___/_____/\____/_____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index d036f6ed..95297599 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homepage-v4.sh b/ct/homepage-v4.sh deleted file mode 100644 index 07eea829..00000000 --- a/ct/homepage-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Homepage" -var_disk="3" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - __ __ - / / / /___ ____ ___ ___ ____ ____ _____ ____ - / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ - / __ / /_/ / / / / / / __/ /_/ / /_/ / /_/ / __/ -/_/ /_/\____/_/ /_/ /_/\___/ .___/\__,_/\__, /\___/ - /_/ v4 /____/ -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 413bcb9a..555343bc 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -369,7 +361,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index fcb920b0..494b0b7c 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -382,7 +374,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/hyperion-v4.sh b/ct/hyperion-v4.sh deleted file mode 100644 index 2b0fc124..00000000 --- a/ct/hyperion-v4.sh +++ /dev/null @@ -1,344 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Hyperion" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { -cat <<"EOF" - __ __ _ - / / / /_ ______v4___ _____(_)___ ____ - / /_/ / / / / __ \/ _ \/ ___/ / __ \/ __ \ - / __ / /_/ / /_/ / __/ / / / /_/ / / / / -/_/ /_/\__, / .___/\___/_/ /_/\____/_/ /_/ - /____/_/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8090${CL} \n" diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 51353a73..2ae540da 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -364,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/influxdb-v4.sh b/ct/influxdb-v4.sh deleted file mode 100644 index 6ee8e824..00000000 --- a/ct/influxdb-v4.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="InfluxDB" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - ____ ______ ____ ____ - / _/_v4 / __/ /_ ___ __/ __ \/ __ ) - / // __ \/ /_/ / / / / |/_/ / / / __ | - _/ // / / / __/ / /_/ /> &1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 03681cb6..053feb3e 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/iobroker-v4.sh b/ct/iobroker-v4.sh deleted file mode 100644 index b4515677..00000000 --- a/ct/iobroker-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="ioBroker" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - _ ____ __ - (_)___ / __ )_________ / /_____ _____ - / / __ \/ __ / ___/ __ \/ //_/ _ \/ ___/ - / / /_/ / /_/ / / / /_/ / ,< / __/ / -/_/\____/_____/_/ v4\____/_/|_|\___/_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8081${CL} \n" diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 257ae0bd..6d022ee3 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/jellyfin-v4.sh b/ct/jellyfin-v4.sh deleted file mode 100644 index 774a3738..00000000 --- a/ct/jellyfin-v4.sh +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Jellyfin" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${DGN} - __________ ____ _____________ __ - / / ____/ / / /\ \/ / ____/ _/ | / / - __ / / __/ / / / / \ / /_ / // |/ / -/ /_/ / /___/ /___/ /_v4/ / __/ _/ // /| / -\____/_____/_____/_____/_/_/ /___/_/ |_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 127dcd25..ec315a7c 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -145,7 +139,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -328,7 +321,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -372,7 +364,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index bcf5f0ee..6a4281a7 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index d0d21213..0267f0a9 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -141,7 +135,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -316,7 +309,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -361,7 +353,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/keycloak-v4.sh b/ct/keycloak-v4.sh deleted file mode 100644 index 5237a3ed..00000000 --- a/ct/keycloak-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Keycloak" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - __ __ __ __ - / //_/__ __ _______/ /___ ____ _/ /__ - / ,< / _ \/ / / / ___/ / __ \/ __ / //_/ - / /| / __/ /_/ / /__/ / /_/ / /_/ / ,< -/_/ |_\___/\__, /\___/_/\____/\__,_/_/|_| - v4 /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 2d9e16fe..85b170e2 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -364,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 07586f05..1a11e0d7 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/magicmirror-v4.sh b/ct/magicmirror-v4.sh deleted file mode 100644 index 2342d731..00000000 --- a/ct/magicmirror-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="MagicMirror" -var_disk="3" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - __ ___ _ __ ____ - / |/ /___ _____ _(_)____/ |/ (_)_____________ _____ - / /|_/ / __ / __ / / ___/ /|_/ / / ___/ ___/ __ \/ ___/ - / / / / /_/ / /_/ / / /__/ / / / / / / / / /_/ / / -/_/ /_/\__,_/\__, /_/\___/_/ /_/_/_/ /_/ \____/_/ - /____/ v4 -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 9a738bcf..8fb8eef7 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -365,7 +357,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/mariadb-v4.sh b/ct/mariadb-v4.sh deleted file mode 100644 index 5281c61d..00000000 --- a/ct/mariadb-v4.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="MariaDB" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - __ ___ _ ____ ____ - / |/ /___ ______(_)___ _/ __ \/ __ ) - / /|_/ / __ / ___/ / __ / / / / __ | - / / / / /_/ / / / / /_/ / /_/ / /_/ / -/_/ /_/\__,_/_/v4/_/\__,_/_____/_____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 96fdb8e1..3ad4ae5a 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/meshcentral-v4.sh b/ct/meshcentral-v4.sh deleted file mode 100644 index b1a2b983..00000000 --- a/ct/meshcentral-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="MeshCentral" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - __ ___ __ ______ __ __ - / |/ /__ _____/ /_ / ____/__ ____ / /__________ _/ / - / /|_/ / _ \/ ___/ __ \/ / / _ \/ __ \/ __/ ___/ __ / / - / / / / __(__ ) / / / /___/ __/ / / / /_/ / / /_/ / / -/_/ /_/\___/____/_/ /_/\____/\___/_/ /_/\__/_/ v4\__,_/_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 37d26f3f..825c5a55 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/motioneye-v4.sh b/ct/motioneye-v4.sh deleted file mode 100644 index f2101198..00000000 --- a/ct/motioneye-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Motioneye" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - __ ___ __ _ ________ ________ - / |/ /___ / /_(_)___ ____ / ____/\ \/ / ____/ - / /|_/ / __ \/ __/ / __ \/ __ \/ __/ \ / __/ - / / / / /_/ / /_/ / /_/ / / / / /___v4 / / /___ -/_/ /_/\____/\__/_/\____/_/ /_/_____/ /_/_____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index f5b6186d..4d8d82a2 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -362,7 +354,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/mqtt-v4.sh b/ct/mqtt-v4.sh deleted file mode 100644 index 16d80e43..00000000 --- a/ct/mqtt-v4.sh +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="MQTT" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { -echo -e "${GN} - __ _______ ____________ - / |/ / __ \/_ __/_ __/ - / /|_/ / / / / / / / / - / / / / /_/ / / / / / -/_/ /_/\___\_\/_/ v4/_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) -if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit -fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { -CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ -"1" "Unprivileged" ON \ -"0" "Privileged" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -fi -PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi -fi -CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; -fi -CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; - if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; -fi -GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then GATE1="Default" GATE=""; - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi -fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi -MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then MAC1="Default" MAC=""; - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} -function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 8cc7274e..5a4e9351 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -140,7 +134,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -315,7 +308,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/n8n-v4.sh b/ct/n8n-v4.sh deleted file mode 100644 index 58af3ddb..00000000 --- a/ct/n8n-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="n8n" -var_disk="3" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - ___ - / _ \ - _ __ | (_) |_v4_ - | _ \ > _ <| _ \ - | | | | (_) | | | | - |_| |_|\___/|_| |_| -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5678${CL} \n" diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index c4a371af..a1fa02ad 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/navidrome-v4.sh b/ct/navidrome-v4.sh deleted file mode 100644 index 3f188aa6..00000000 --- a/ct/navidrome-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Navidrome" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - _ __ _ __ - / | / /___ __ v4__(_)___/ /________ ____ ___ ___ - / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ - / /| / /_/ /| |/ / / /_/ / / / /_/ / / / / / / __/ -/_/ |_/\__,_/ |___/_/\__,_/_/ \____/_/ /_/ /_/\___/ -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:4533${CL} \n" diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 06f2a828..1f38d743 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -374,7 +366,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/nextcloudpi-v4.sh b/ct/nextcloudpi-v4.sh deleted file mode 100644 index c1ff886d..00000000 --- a/ct/nextcloudpi-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="NextCloudPi" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - _ __ __ ________ ______ _ - / | / /__ _ __/ /_/ ____/ /___ __v4______/ / __ \(_) - / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / /_/ / / - / /| / __/> &1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}https://${IP}/${CL} \n" diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index af9a035b..e77c3b4a 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/nginx-proxy-manager-v4.sh b/ct/nginx-proxy-manager-v4.sh deleted file mode 100644 index 23e60e9c..00000000 --- a/ct/nginx-proxy-manager-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Nginx Proxy Manager" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - _ __ _ ____ __ ___ - / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____ - / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ - / /| / /_/ / / / / /> < / ____/ / / /_/ /> &1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/nginx-proxy-manager-install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 41cf41a8..237ee263 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -472,7 +464,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/nocodb-v4.sh b/ct/nocodb-v4.sh deleted file mode 100644 index 80776771..00000000 --- a/ct/nocodb-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="NocoDB" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - _ __ ____ ____ - / | / /___ ____v4___ / __ \/ __ ) - / |/ / __ \/ ___/ __ \/ / / / __ | - / /| / /_/ / /__/ /_/ / /_/ / /_/ / -/_/ |_/\____/\___/\____/_____/_____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080/dashboard${CL} \n" diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index d552dd84..e06cdc12 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -366,7 +358,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/node-red-v4.sh b/ct/node-red-v4.sh deleted file mode 100644 index 24568629..00000000 --- a/ct/node-red-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Node-Red" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - _ __ __ ____ __ - / | / /___ ____/ /__ v4 / __ \___ ____/ / - / |/ / __ \/ __ / _ \ / /_/ / _ \/ __ / - / /| / /_/ / /_/ / __/ / _, _/ __/ /_/ / -/_/ |_/\____/\__,_/\___/ /_/ |_|\___/\__,_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index d6239acc..cc5720ed 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -399,7 +391,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/omada-v4.sh b/ct/omada-v4.sh deleted file mode 100644 index 70fbbe6a..00000000 --- a/ct/omada-v4.sh +++ /dev/null @@ -1,337 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Omada" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - ____ __ - / __ \____ ___v4____ _____/ /___ _ - / / / / __ __ \/ __ / __ / __ / -/ /_/ / / / / / / /_/ / /_/ / /_/ / -\____/_/ /_/ /_/\__,_/\__,_/\__,_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}https://${IP}:8043${CL} \n" diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index c200d3fd..35861b21 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -326,7 +319,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -361,7 +353,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/omv-v4.sh b/ct/omv-v4.sh deleted file mode 100644 index 573745c9..00000000 --- a/ct/omv-v4.sh +++ /dev/null @@ -1,339 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="OMV" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ____ __ ___ ___ _ __ ____ - / __ \____v4___ ____ / |/ /__ ____/ (_)___ | | / /___ ___ __/ / /_ - / / / / __ \/ _ \/ __ \/ /|_/ / _ \/ __ / / __ `/ | / / __ `/ / / / / __/ -/ /_/ / /_/ / __/ / / / / / / __/ /_/ / / /_/ /| |/ / /_/ / /_/ / / /_ -\____/ .___/\___/_/ /_/_/ /_/\___/\__,_/_/\__,_/ |___/\__,_/\__,_/_/\__/ - /_/ -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 8591a72e..8406e00a 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -364,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/openhab-v4.sh b/ct/openhab-v4.sh deleted file mode 100644 index 2d014284..00000000 --- a/ct/openhab-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="openHAB" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - __ _____ ____ - ____v4____ ___ ____ / / / / | / __ ) - / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __ | -/ /_/ / /_/ / __/ / / / __ / ___ |/ /_/ / -\____/ .___/\___/_/ /_/_/ /_/_/ |_/_____/ - /_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 837f815c..a1d4a601 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -364,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/paperless-ngx-v4.sh b/ct/paperless-ngx-v4.sh deleted file mode 100644 index 1630ed49..00000000 --- a/ct/paperless-ngx-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Paperless-ngx" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ____ __ - / __ \____ _____ ___ _____/ /__v4__________ ____ ____ __ __ - / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ - / ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> < -/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| - /_/ /____/ -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index b4de9ab6..d014671b 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -431,7 +423,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/photoprism-v4.sh b/ct/photoprism-v4.sh deleted file mode 100644 index 1574037c..00000000 --- a/ct/photoprism-v4.sh +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="PhotoPrism" -var_disk="8" -var_cpu="2" -var_ram="3072" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - ____ __ ______ __________ ____ ____ _________ __ ___ - / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / - / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / - / ____/ __ / /_/ / / / / /_/ / ____/ _, _// / v4_/ / / / / -/_/ /_/ /_/\____/ /_/ \____/_/ /_/ |_/___//____/_/ /_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 2048 -msg_ok "Set Container to Normal Resources" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index ccab7aad..2c7042d6 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -141,7 +135,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -316,7 +309,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -384,7 +376,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/pihole-v4.sh b/ct/pihole-v4.sh deleted file mode 100644 index 891d272e..00000000 --- a/ct/pihole-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Pihole" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - ____ ____ __ ______ __ ______ - / __ \/ _/ / / / / __ \/ / / ____/ - / /_/ // /___/ /_/ / / / / / / __/ - / ____// /___/ __ / /_/ / /v4_/ /___ -/_/ /___/ /_/ /_/\____/_____/_____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}/admin${CL} \n" diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 299c53d0..989bd0de 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/plex-v4.sh b/ct/plex-v4.sh deleted file mode 100644 index ba26e011..00000000 --- a/ct/plex-v4.sh +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Plex" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - ____ __ - / __ \/ /__ _ __ - / /_/ / / _ \| |/_/ - / ____/ / __/> < -/_/v4 /_/\___/_/|_| -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:32400/web${CL}\n" diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 30894617..f7dc89a0 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -144,7 +138,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -327,7 +320,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -382,7 +374,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/podman-homeassistant-v4.sh b/ct/podman-homeassistant-v4.sh deleted file mode 100644 index 5887d22a..00000000 --- a/ct/podman-homeassistant-v4.sh +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Podman-Home Assistant" -var_disk="16" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - ____ __ - / __ \____ ____/ /___ ___ ____ _____ - v4 / /_/ / __ \/ __ / __ __ \/ __ / __ \ - / ____/ /_/ / /_/ / / / / / / /_/ / / / / - __ __ /_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/__ __ - / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ - / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -if [ "$CT_TYPE" == "0" ]; then -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -else - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} -Yacht should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL}\n" diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 55f0f9c5..711ae8f8 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -36,20 +36,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -146,7 +140,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -321,7 +314,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -413,7 +405,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index c4475f01..325d7268 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/postgresql-v4.sh b/ct/postgresql-v4.sh deleted file mode 100644 index d1013485..00000000 --- a/ct/postgresql-v4.sh +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="PostgreSQL" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - ____ __ _____ ____ __ - / __ \____ _____/ /_____ _________ / ___// __ \ / / - / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / - / ____/ /_/ (__ ) /_/ /_/ / / / __/__/ / /_/ / / /___ -/_/ \____/____/\__/\__, /_/v4 \___/____/\___\_\/_____/ - /____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index e1247142..3a00762f 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/prometheus-v4.sh b/ct/prometheus-v4.sh deleted file mode 100644 index a4106946..00000000 --- a/ct/prometheus-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Prometheus" -var_disk="4" -var_cpu="1" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - ____ __ __ - / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ - / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ - / ____/ / / /_/ / / / / / / __/ /_/ / / / __/ /_/ (__ ) -/_/ v4/_/ \____/_/ /_/ /_/\___/\__/_/ /_/\___/\__,_/____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:9090${CL} \n" diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 2de01b11..a11c6e8e 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index ed741da7..5d73e435 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 3ae34a9c..e453cd1a 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index d8e03dfb..39092a64 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index 8cf707f2..992902d1 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -364,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index c5480465..6edfd424 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/scrypted-v4.sh b/ct/scrypted-v4.sh deleted file mode 100644 index 3dd86f9b..00000000 --- a/ct/scrypted-v4.sh +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Scrypted" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - _____ __ __ - / ___/____________v4______ / /____ ____/ / - \__ \/ ___/ ___/ / / / __ \/ __/ _ \/ __ / - ___/ / /__/ / / /_/ / /_/ / /_/ __/ /_/ / -/____/\___/_/ \__, / .___/\__/\___/\__,_/ - /____/_/ -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}https://${IP}:10443${CL} \n" diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 3b4c7eda..97f0bedf 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -364,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/shinobi-v4.sh b/ct/shinobi-v4.sh deleted file mode 100644 index e52e3565..00000000 --- a/ct/shinobi-v4.sh +++ /dev/null @@ -1,338 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Shinobi" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="22.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - _____ __ _ __ _ - / ___// /_ (_)___v4____ / /_ (_) - \__ \/ __ \/ / __ \/ __ \/ __ \/ / - ___/ / / / / / / / / /_/ / /_/ / / -/____/_/ /_/_/_/ /_/\____/_.___/_/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" OFF \ - "22.04" "Jammy" ON \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:8080/super${CL} \n" diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 0a3ca6cf..9e9943b7 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -326,7 +319,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -373,7 +365,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index bf291d82..f0ddd2bc 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/syncthing-v4.sh b/ct/syncthing-v4.sh deleted file mode 100644 index f6f928c1..00000000 --- a/ct/syncthing-v4.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Syncthing" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - _____ __ __ _ - / ___/__ ______v4_____/ /_/ /_ (_)___ ____ _ - \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ - ___/ / /_/ / / / / /__/ /_/ / / / / / / / /_/ / -/____/\__, /_/ /_/\___/\__/_/ /_/_/_/ /_/\__, / - /____/ /____/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8384 ${CL} (after initial start) \n" diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index fc983f24..cc8c498e 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -364,7 +356,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 882fa1d7..16fee7d4 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/technitiumdns-v4.sh b/ct/technitiumdns-v4.sh deleted file mode 100644 index ca581f21..00000000 --- a/ct/technitiumdns-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Technitium DNS" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - ______ __ _ __ _ ____ _ _______ - /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ v4 / __ \/ | / / ___/ - / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ - / / / __/ /__/ / / / / / / / /_/ / /_/ / / / / / / / /_/ / /| /___/ / -/_/ \___/\___/_/ /_/_/ /_/_/\__/_/\__,_/_/ /_/ /_/ /_____/_/ |_//____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index ec98b23c..d9f0cc23 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -425,7 +417,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index 53bf082a..9c040e3e 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/trilium-v4.sh b/ct/trilium-v4.sh deleted file mode 100644 index 8fd5f853..00000000 --- a/ct/trilium-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Trilium" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - ______ _ ___ - /_ __/_v4_(_) (_)_ ______ ___ - / / / ___/ / / / / / / __ `__ \ - / / / / / / / / /_/ / / / / / / -/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 9facb7ca..09e8bf47 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -382,7 +374,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/ubuntu-v4.sh b/ct/ubuntu-v4.sh deleted file mode 100644 index 803ce681..00000000 --- a/ct/ubuntu-v4.sh +++ /dev/null @@ -1,335 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Ubuntu" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="ubuntu" -var_version="22.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - __ ____ __ - / / / / /_v4__ ______ / /___ __ - / / / / __ \/ / / / __ \/ __/ / / / -/ /_/ / /_/ / /_/ / / / / /_/ /_/ / -\____/_.___/\__,_/_/ /_/\__/\__,_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" OFF \ - "22.04" "Jammy" ON \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 0cdab57f..938f771a 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -139,7 +133,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -322,7 +315,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -366,7 +358,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/umbrel-v4.sh b/ct/umbrel-v4.sh deleted file mode 100644 index 9b557c03..00000000 --- a/ct/umbrel-v4.sh +++ /dev/null @@ -1,344 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Umbrel" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - __ __ __ __ - / / / /___ ___v4/ /_ ________ / / - / / / / __ `__ \/ __ \/ ___/ _ \/ / -/ /_/ / / / / / / /_/ / / / __/ / -\____/_/ /_/ /_/_.___/_/ \___/_/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export ST=$FUSE -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL (reboot is required before app installs). - ${BL}http://${IP} ${CL} \n" diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 684b4fc2..6d421a09 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -144,7 +138,6 @@ function default_settings() { FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -326,7 +319,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -371,7 +363,6 @@ pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/unifi-v4.sh b/ct/unifi-v4.sh deleted file mode 100644 index 38229ab0..00000000 --- a/ct/unifi-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Unifi" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - __ __ _ _____ - / / / /_v4 (_) __(_) - / / / / __ \/ / /_/ / -/ /_/ / / / / / __/ / -\____/_/ /_/_/_/ /_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP}${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:8443${CL} \n" diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 5f07d29a..87ec5d1f 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -363,7 +355,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/uptimekuma-v4.sh b/ct/uptimekuma-v4.sh deleted file mode 100644 index 289694da..00000000 --- a/ct/uptimekuma-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Uptime Kuma" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${DGN} - __ __ __ _ __ __ - / / / /___ / /_(_)___ ___ ___ v4 / //_/_ ______ ___ ____ _ - / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / -/ /_/ / /_/ / /_/ / / / / / / __/ / /| / /_/ / / / / / / /_/ / -\____/ .___/\__/_/_/ /_/ /_/\___/ /_/ |_\__,_/_/ /_/ /_/\__,_/ - /_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3001${CL} \n" diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index c29a3832..b08413ed 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -380,7 +372,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/vaultwarden-v4.sh b/ct/vaultwarden-v4.sh deleted file mode 100644 index be5fe841..00000000 --- a/ct/vaultwarden-v4.sh +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Vaultwarden" -var_disk="6" -var_cpu="2" -var_ram="3072" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${CL} - _ _____ __ ____ _______ _____ ____ ____ _______ __ -| | / / | / / / / / /_ __/ | / / | / __ \/ __ \/ ____/ | / / -| | / / /| |/ / / / / / / | | /| / / /| | / /_/ / / / / __/ / |/ / -| |/ / ___ / /_/ / /___/ / | |/ |/ / ___ |/ _, _/ /_/ / /___/ /| / -|___/_/ |_\____/_____/_/ v4 |__/|__/_/ |_/_/ |_/_____/_____/_/ |_/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 512 -pct set $CTID -cores 1 -msg_ok "Set Container to Normal Resources" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index fda70c39..87ebde7d 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -141,7 +135,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -431,7 +423,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 27636526..eb983253 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -139,7 +133,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -314,7 +307,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -359,7 +351,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/whoogle-v4.sh b/ct/whoogle-v4.sh deleted file mode 100644 index 7d3a7f6c..00000000 --- a/ct/whoogle-v4.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Whoogle" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${GN} - _ ____ ______ ____ ________ ______ -| | v4 / / / / / __ \/ __ \/ ____/ / / ____/ -| | /| / / /_/ / / / / / / / / __/ / / __/ -| |/ |/ / __ / /_/ / /_/ / /_/ / /___/ /___ -|__/|__/_/ /_/\____/\____/\____/_____/_____/ -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index b8600076..e39ecff8 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -362,7 +354,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/wikijs-v4.sh b/ct/wikijs-v4.sh deleted file mode 100644 index 6fc2487f..00000000 --- a/ct/wikijs-v4.sh +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Wikijs" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${BL} - _ ___ __ _ _ -| | / (_) /__(_) (_)____ -| | /| / / / //_/ / / / ___/ -| |/ |/ / / ,< / / / (__ ) -|__/|__/_/_/|_/_(_)_/ /____/ - /___/ v4 -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 1ed0b3b8..db50b8e9 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -376,7 +368,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/wireguard-v4.sh b/ct/wireguard-v4.sh deleted file mode 100644 index 532847ad..00000000 --- a/ct/wireguard-v4.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Wireguard" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${RD} - __ ___ _____ _ - \ \ / (_) / ____| | | - \ \ /\ / / _ _ __ ___| | __ _ _ __ _ _ __ __| | - \ \/ \/ / | | __/ _ \ | |_ | | | |/ _ | __/ _ | - \ /\ / | | | | __/ |__| | |_| | (_| | | | (_| | - \/ \/ v4|_|_| \___|\_____|\__,_|\__,_|_| \__,_| - ${YW}With WGDashboard -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "WGDashboard should be reachable by going to the following URL. - ${BL}http://${IP}:10086${CL} \n" diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 376ff186..78d35fa2 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -418,7 +410,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index e9d630c4..f60795d2 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -138,7 +132,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -313,7 +306,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -358,7 +350,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/zigbee2mqtt-v4.sh b/ct/zigbee2mqtt-v4.sh deleted file mode 100644 index 986309c5..00000000 --- a/ct/zigbee2mqtt-v4.sh +++ /dev/null @@ -1,341 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Zigbee2MQTT" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - echo -e "${YW} - _____ _ __ ___ __ _______ ____________ -/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ - / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / - / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / -/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ - v4 /____/ 🐝 -${CL}" -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index e006440e..ad1d2455 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -33,20 +33,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -143,7 +137,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -318,7 +311,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -393,7 +385,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/ct/zwave-js-ui-v4.sh b/ct/zwave-js-ui-v4.sh deleted file mode 100644 index 1125bd07..00000000 --- a/ct/zwave-js-ui-v4.sh +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env bash -echo -e "Loading..." -APP="Zwave-JS-UI" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-install" -NEXTID=$(pvesh get /cluster/nextid) -INTEGER='^[0-9]+$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" -else - clear - echo -e "⚠ User exited script \n" - exit -fi -function header_info { - cat <<"EOF" - _____ _______ __ ______ -/__ /_ ______ __v4 _____ / / ___/ / / / / _/ - / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / - / /_| |/ |/ / /_/ /| |/ / __/ / /_/ /___/ / / /_/ // / -/____/__/|__/\__,_/ |___/\___/ \____//____/ \____/___/ - -EOF -} -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} -clear -start_script -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8091${CL} \n" diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 3018177d..da1e45c8 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -32,20 +32,14 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -142,7 +136,6 @@ function default_settings() { SSH="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } function advanced_settings() { @@ -317,7 +310,6 @@ function advanced_settings() { else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" - VERB2="silent" fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" @@ -376,7 +368,6 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 export VERBOSE=$VERB -export STD=$VERB2 export SSH_ROOT=${SSH} export CTID=$CT_ID export PCT_OSTYPE=$var_os diff --git a/install/adguard-install.sh b/install/adguard-install.sh deleted file mode 100644 index fbe4d973..00000000 --- a/install/adguard-install.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing AdGuard Home" -curl -sSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh &>/dev/null -msg_ok "Installed AdGuard Home" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 497b3a81..533c988a 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -98,12 +94,11 @@ $STD bash install.sh rm install.sh msg_ok "Installed AdGuard Home" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -116,10 +111,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index 13e8a432..e9086b57 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -96,11 +92,11 @@ $STD apt-get update $STD apt install audiobookshelf msg_ok "Installed audiobookshelf" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -113,10 +109,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 9c54ff2a..03a1d05c 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -117,11 +113,11 @@ WantedBy=multi-user.target" >$service_path systemctl enable --now -q autobrr.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -134,10 +130,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/blocky-install.sh b/install/blocky-install.sh deleted file mode 100644 index 4422902e..00000000 --- a/install/blocky-install.sh +++ /dev/null @@ -1,375 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Blocky" -systemctl stop systemd-resolved &>/dev/null -systemctl disable systemd-resolved.service &>/dev/null -RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz &>/dev/null -mkdir -p /opt/blocky -tar -xf blocky_${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky -rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz -cat </opt/blocky/config.yml -upstream: - # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query - # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) - # this configuration is mandatory, please define at least one external DNS resolver - default: - # example for tcp+udp IPv4 server (https://digitalcourage.de/) - #- 5.9.164.112 - # Cloudflare - - 1.1.1.1 - # example for DNS-over-TLS server (DoT) - #- tcp-tls:fdns1.dismail.de:853 - # example for DNS-over-HTTPS (DoH) - #- https://dns.digitale-gesellschaft.ch/dns-query - # optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range) - # or single ip address / client subnet as CIDR notation - #laptop*: - #- 123.123.123.123 - -# optional: timeout to query the upstream resolver. Default: 2s -#upstreamTimeout: 2s - -# optional: If true, blocky will fail to start unless at least one upstream server per group is reachable. Default: false -#startVerifyUpstream: true - -# optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists. -# accepted: dual, v4, v6 -# default: dual -#connectIPVersion: dual - -# optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma -# example: query "printer.lan" or "my.printer.lan" will return 192.168.178.3 -#customDNS: - #customTTL: 1h - # optional: if true (default), return empty result for unmapped query types (for example TXT, MX or AAAA if only IPv4 address is defined). - # if false, queries with unmapped types will be forwarded to the upstream resolver - #filterUnmappedTypes: true - # optional: replace domain in the query with other domain before resolver lookup in the mapping - #rewrite: - #example.com: printer.lan - #mapping: - #printer.lan: 192.168.178.3,2001:0db8:85a3:08d3:1319:8a2e:0370:7344 - -# optional: definition, which DNS resolver(s) should be used for queries to the domain (with all sub-domains). Multiple resolvers must be separated by a comma -# Example: Query client.fritz.box will ask DNS server 192.168.178.1. This is necessary for local network, to resolve clients by host name -#conditional: - # optional: if false (default), return empty result if after rewrite, the mapped resolver returned an empty answer. If true, the original query will be sent to the upstream resolver - # Example: The query "blog.example.com" will be rewritten to "blog.fritz.box" and also redirected to the resolver at 192.168.178.1. If not found and if was set to , the original query "blog.example.com" will be sent upstream. - # Usage: One usecase when having split DNS for internal and external (internet facing) users, but not all subdomains are listed in the internal domain. - #fallbackUpstream: false - # optional: replace domain in the query with other domain before resolver lookup in the mapping - #rewrite: - #example.com: fritz.box - #mapping: - #fritz.box: 192.168.178.1 - #lan.net: 192.168.178.1,192.168.178.2 - -# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.) -blocking: - # definition of blacklist groups. Can be external link (http/https) or local file - blackLists: - ads: - - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt - - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts - - http://sysctl.org/cameleon/hosts - - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt - - | - # inline definition with YAML literal block scalar style - # hosts format - someadsdomain.com - special: - - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts - # definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked - whiteLists: - ads: - - whitelist.txt - - | - # inline definition with YAML literal block scalar style - # hosts format - whitelistdomain.com - # this is a regex - /^banners?[_.-]/ - # definition: which groups should be applied for which client - clientGroupsBlock: - # default will be used, if no special definition for a client name exists - default: - - ads - - special - # use client name (with wildcard support: * - sequence of any characters, [0-9] - range) - # or single ip address / client subnet as CIDR notation - #laptop*: - #- ads - #192.168.178.1/24: - #- special - # which response will be sent, if query is blocked: - # zeroIp: 0.0.0.0 will be returned (default) - # nxDomain: return NXDOMAIN as return code - # comma separated list of destination IP addresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. - blockType: zeroIp - # optional: TTL for answers to blocked domains - # default: 6h - blockTTL: 1m - # optional: automatically list refresh period (in duration format). Default: 4h. - # Negative value -> deactivate automatically refresh. - # 0 value -> use default - refreshPeriod: 4h - # optional: timeout for list download (each url). Default: 60s. Use large values for big lists or slow internet connections - downloadTimeout: 4m - # optional: Download attempt timeout. Default: 60s - downloadAttempts: 5 - # optional: Time between the download attempts. Default: 1s - downloadCooldown: 10s - # optional: if failOnError, application startup will fail if at least one list can't be downloaded / opened. Default: blocking - #startStrategy: failOnError - -# optional: configuration for caching of DNS responses -caching: - # duration how long a response must be cached (min value). - # If <=0, use response's TTL, if >0 use this value, if TTL is smaller - # Default: 0 - minTime: 5m - # duration how long a response must be cached (max value). - # If <0, do not cache responses - # If 0, use TTL - # If > 0, use this value, if TTL is greater - # Default: 0 - maxTime: 30m - # Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM. - # Default (0): unlimited - maxItemsCount: 0 - # if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2-hour time window) - # this improves the response time for often used queries, but significantly increases external traffic - # default: false - prefetching: true - # prefetch track time window (in duration format) - # default: 120 - prefetchExpires: 2h - # name queries threshold for prefetch - # default: 5 - prefetchThreshold: 5 - # Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM. - # Default (0): unlimited - #prefetchMaxItemsCount: 0 - -# optional: configuration of client name resolution -clientLookup: - # optional: this DNS resolver will be used to perform reverse DNS lookup (typically local router) - #upstream: 192.168.178.1 - # optional: some routers return multiple names for client (host name and user defined name). Define which single name should be used. - # Example: take second name if present, if not take first name - #singleNameOrder: - #- 2 - #- 1 - # optional: custom mapping of client name to IP addresses. Useful if reverse DNS does not work properly or just to have custom client names. - #clients: - #laptop: - #- 192.168.178.29 -# optional: configuration for prometheus metrics endpoint -prometheus: - # enabled if true - #enable: true - # url path, optional (default '/metrics') - #path: /metrics - -# optional: write query information (question, answer, client, duration etc.) to daily csv file -queryLog: - # optional one of: mysql, postgresql, csv, csv-client. If empty, log to console - #type: mysql - # directory (should be mounted as volume in docker) for csv, db connection string for mysql/postgresql - #target: db_user:db_password@tcp(db_host_or_ip:3306)/db_name?charset=utf8mb4&parseTime=True&loc=Local - #postgresql target: postgres://user:password@db_host_or_ip:5432/db_name - # if > 0, deletes log files which are older than ... days - #logRetentionDays: 7 - # optional: Max attempts to create specific query log writer, default: 3 - #creationAttempts: 1 - # optional: Time between the creation attempts, default: 2s - #creationCooldown: 2s - -# optional: Blocky can synchronize its cache and blocking state between multiple instances through redis. -redis: - # Server address and port - #address: redis:6379 - # Password if necessary - #password: passwd - # Database, default: 0 - #database: 2 - # Connection is required for blocky to start. Default: false - #required: true - # Max connection attempts, default: 3 - #connectionAttempts: 10 - # Time between the connection attempts, default: 1s - #connectionCooldown: 3s - -# optional: DNS listener port(s) and bind ip address(es), default 53 (UDP and TCP). Example: 53, :53, "127.0.0.1:5353,[::1]:5353" -port: 553 -# optional: Port(s) and bind ip address(es) for DoT (DNS-over-TLS) listener. Example: 853, 127.0.0.1:853 -#tlsPort: 853 -# optional: HTTPS listener port(s) and bind ip address(es), default empty = no http listener. If > 0, will be used for prometheus metrics, pprof, REST API, DoH... Example: 443, :443, 127.0.0.1:443 -#httpPort: 4000 -#httpsPort: 443 -# optional: Mininal TLS version that the DoH and DoT server will use -#minTlsServeVersion: 1.3 -# if https port > 0: path to cert and key file for SSL encryption. if not set, self-signed certificate will be generated -#certFile: server.crt -#keyFile: server.key -# optional: use this DNS server to resolve blacklist urls and upstream DNS servers. Useful if no DNS resolver is configured and blocky needs to resolve a host name. Format net:IP:port, net must be udp or tcp -#bootstrapDns: tcp+udp:1.1.1.1 - -filtering: -# optional: drop all queries with following query types. Default: empty - #queryTypes: - #- AAAA - -# optional: if path defined, use this file for query resolution (A, AAAA and rDNS). Default: empty -hostsFile: - # optional: Path to hosts file (e.g. /etc/hosts on Linux) - #filePath: /etc/hosts - # optional: TTL, default: 1h - #hostsTTL: 60m - # optional: Time between hosts file refresh, default: 1h - #refreshPeriod: 30m - # optional: Whether loopback hosts addresses (127.0.0.0/8 and ::1) should be filtered or not, default: false - #filterLoopback: true -# optional: Log level (one from debug, info, warn, error). Default: info -#logLevel: info -# optional: Log format (text or json). Default: text -#logFormat: text -# optional: log timestamps. Default: true -#logTimestamp: true -# optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false -#logPrivacy: false - -# optional: add EDE error codes to dns response -#ede: - # enabled if true, Default: false - #enable: true -EOF -msg_ok "Installed Blocky" - -msg_info "Creating Service" -cat </etc/systemd/system/blocky.service -[Unit] -Description=Blocky -After=network.target -[Service] -User=root -WorkingDirectory=/opt/blocky -ExecStart=/opt/blocky/./blocky --config config.yml -[Install] -WantedBy=multi-user.target -EOF -systemctl enable --now blocky -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index b1b80f4b..b68882b1 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -350,11 +346,11 @@ EOF $STD systemctl enable --now blocky msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -367,10 +363,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/casaos-install.sh b/install/casaos-install.sh deleted file mode 100644 index 141058cd..00000000 --- a/install/casaos-install.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y unzip &>/dev/null -msg_ok "Installed Dependencies" - -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -msg_info "Installing CasaOS (Patience)" -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -fi -wget -qO- https://get.casaos.io | bash &>/dev/null -msg_ok "Installed CasaOS" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 1a2358fc..013a9a46 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -106,12 +102,11 @@ fi $STD bash <(curl -fsSL https://get.casaos.io) msg_ok "Installed CasaOS" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -124,10 +119,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh deleted file mode 100644 index e8c2fdd3..00000000 --- a/install/changedetection-install.sh +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y pip &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Change Detection" -mkdir /opt/changedetection -pip3 install changedetection.io &>/dev/null -msg_ok "Installed Change Detection" - -msg_info "Creating Service" -cat </etc/systemd/system/changedetection.service -[Unit] -Description=Change Detection -After=network-online.target -[Service] -Type=simple -WorkingDirectory=/opt/changedetection -ExecStart=changedetection.io -d /opt/changedetection -p 5000 -[Install] -WantedBy=multi-user.target -EOF -systemctl enable --now changedetection &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index bf528d16..f8b24983 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -110,11 +106,11 @@ EOF $STD systemctl enable --now changedetection msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -127,10 +123,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 85be2f0a..d9c2aca7 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -116,11 +112,11 @@ chmod 775 /etc/init.d/cronicled $STD update-rc.d cronicled defaults msg_ok "Installed Cronicle Primary Server" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -133,10 +129,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/daemonsync-install.sh b/install/daemonsync-install.sh deleted file mode 100644 index 9f68ed71..00000000 --- a/install/daemonsync-install.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y g++-multilib &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Daemon Sync Server" -wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_amd64.deb &>/dev/null -sudo dpkg -i daemonsync_2.2.0.0059_amd64.deb &>/dev/null -msg_ok "Installed Daemon Sync Server" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 4281260e..04229094 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -95,12 +91,11 @@ wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_am $STD dpkg -i daemonsync_2.2.0.0059_amd64.deb msg_ok "Installed Daemon Sync Server" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -113,10 +108,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf daemonsync_2.2.0.0059_amd64.deb diff --git a/install/dashy-install.sh b/install/dashy-install.sh deleted file mode 100644 index 680a95cc..00000000 --- a/install/dashy-install.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Yarn" -npm install --global yarn &>/dev/null -msg_ok "Installed Yarn" - -msg_info "Installing Dashy (Patience)" -git clone https://github.com/Lissy93/dashy.git &>/dev/null -cd /dashy -yarn &>/dev/null -export NODE_OPTIONS=--max-old-space-size=1000 &>/dev/null -yarn build &>/dev/null -msg_ok "Installed Dashy" - -msg_info "Creating Service" -cat </etc/systemd/system/dashy.service -[Unit] -Description=dashy - -[Service] -Type=simple -WorkingDirectory=/dashy -ExecStart=/usr/bin/yarn start -[Install] -WantedBy=multi-user.target -EOF -sudo systemctl start dashy &>/dev/null -sudo systemctl enable dashy &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 14f76bef..84bc8eaa 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -126,12 +122,11 @@ $STD systemctl enable dashy systemctl start dashy msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -144,10 +139,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/debian-install.sh b/install/debian-install.sh deleted file mode 100644 index 0029b4e4..00000000 --- a/install/debian-install.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 3a525e6b..428fe812 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -88,11 +84,11 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -105,10 +101,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/deconz-install.sh b/install/deconz-install.sh deleted file mode 100644 index 18395883..00000000 --- a/install/deconz-install.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting Phoscon Repository" -wget -q http://phoscon.de/apt/deconz.pub.key -O - | sudo apt-key add - &>/dev/null -sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" &>/dev/null -msg_ok "Setup Phoscon Repository" - -msg_info "Installing deConz" -apt-get update &>/dev/null -apt-get install -y deconz &>/dev/null -msg_ok "Installed deConz" - -msg_info "Creating Service" -service_path="/lib/systemd/system/deconz.service" -echo "[Unit] -Description=deCONZ: ZigBee gateway -- REST API -Wants=deconz-init.service deconz-update.service -StartLimitIntervalSec=0 - -[Service] -User=root -ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80 -Restart=on-failure -RestartSec=30 -AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl start deconz -systemctl enable deconz &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 0235e7de..1b4a59b3 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -119,11 +115,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now deconz msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -136,10 +132,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 19f9449d..4d2c8e21 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -133,11 +129,11 @@ systemctl enable --now -q deluged.service systemctl enable --now -q deluge-web.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -150,10 +146,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/docker-install.sh b/install/docker-install.sh deleted file mode 100644 index df358aba..00000000 --- a/install/docker-install.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} - -DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") -PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") -DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") - -msg_info "Installing Docker $DOCKER_LATEST_VERSION" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi -sh <(curl -sSL https://get.docker.com) &>/dev/null -msg_ok "Installed Docker $DOCKER_LATEST_VERSION" - -read -r -p "Would you like to add Portainer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - PORTAINER="Y" -else - PORTAINER="N" -fi - -if [[ $PORTAINER == "Y" ]]; then - msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" - docker volume create portainer_data >/dev/null - docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null - msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" -fi - -read -r -p "Would you like to add Docker Compose? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - DOCKER_COMPOSE="Y" -else - DOCKER_COMPOSE="N" -fi - -if [[ $DOCKER_COMPOSE == "Y" ]]; then - msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" - DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} - mkdir -p $DOCKER_CONFIG/cli-plugins - curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose - chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose - msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" -fi - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 762327dd..fa8b1495 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -150,12 +146,11 @@ if [[ $DOCKER_COMPOSE == "Y" ]]; then msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -168,10 +163,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/emby-install.sh b/install/emby-install.sh deleted file mode 100644 index 3ce66a06..00000000 --- a/install/emby-install.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then - msg_info "Setting Up Hardware Acceleration" - apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* - msg_ok "Set Up Hardware Acceleration" -fi - -LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) - -msg_info "Installing Emby" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null -dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null -msg_ok "Installed Emby" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm emby-server-deb_${LATEST}_amd64.deb -msg_ok "Cleaned" diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index ffe06b70..18d832f1 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -109,11 +105,11 @@ wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb msg_ok "Installed Emby" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -126,10 +122,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/emqx-install.sh b/install/emqx-install.sh deleted file mode 100644 index 49adfa50..00000000 --- a/install/emqx-install.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing EMQX" -curl -s https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh | bash &>/dev/null -sudo apt-get install -y emqx >/dev/null -systemctl enable --now emqx -msg_ok "Installed EMQX" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index c8fadb4b..bcbae979 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -94,11 +90,11 @@ $STD apt-get install -y emqx $STD systemctl enable --now emqx msg_ok "Installed EMQX" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -111,10 +107,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/install/esphome-install.sh b/install/esphome-install.sh deleted file mode 100644 index fbd8570a..00000000 --- a/install/esphome-install.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Python3-pip" -apt-get install -y python3-pip &>/dev/null -msg_ok "Installed Python3-pip" - -msg_info "Installing ESPHome" -pip3 install esphome &>/dev/null -msg_ok "Installed ESPHome" - -msg_info "Installing ESPHome Dashboard" -pip3 install tornado esptool &>/dev/null - -service_path="/etc/systemd/system/esphomeDashboard.service" -echo "[Unit] -Description=ESPHome Dashboard -After=network.target -[Service] -ExecStart=/usr/local/bin/esphome /root/config/ dashboard -Restart=always -User=root -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable esphomeDashboard.service &>/dev/null -systemctl start esphomeDashboard -msg_ok "Installed ESPHome Dashboard" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index 0504c6c9..433d8487 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -115,12 +111,11 @@ $STD systemctl enable esphomeDashboard.service systemctl start esphomeDashboard msg_ok "Installed ESPHome Dashboard" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -133,10 +128,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/grafana-install.sh b/install/grafana-install.sh deleted file mode 100644 index efc51a98..00000000 --- a/install/grafana-install.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -apt-get install -y apt-transport-https &>/dev/null -apt-get install -y software-properties-common &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Grafana Repository" -wget -qO- https://packages.grafana.com/gpg.key | sudo apt-key add - &>/dev/null -echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list &>/dev/null -msg_ok "Set up Grafana Repository" - -msg_info "Installing Grafana" -apt-get update &>/dev/null -apt-get install -y grafana &>/dev/null -msg_ok "Installed Grafana" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi -systemctl start grafana-server -systemctl enable grafana-server.service &>/dev/null - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 29e171c9..b695df32 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -102,12 +98,11 @@ $STD apt-get update $STD apt-get install -y grafana msg_ok "Installed Grafana" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -120,10 +115,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi systemctl start grafana-server $STD systemctl enable grafana-server.service diff --git a/install/grocy-install.sh b/install/grocy-install.sh deleted file mode 100644 index 1d7acc0a..00000000 --- a/install/grocy-install.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y apache2 &>/dev/null -apt-get install -y unzip &>/dev/null -apt-get install -y apt-transport-https &>/dev/null -apt-get install -y lsb-release &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing PHP 8.1" -curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg -sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' -apt-get update &>/dev/null -apt-get install -y php8.1 &>/dev/null -apt-get install -y libapache2-mod-php8.1 &>/dev/null -apt-get install -y php8.1-sqlite3 &>/dev/null -apt-get install -y php8.1-gd &>/dev/null -apt-get install -y php8.1-intl &>/dev/null -apt-get install -y php8.1-mbstring &>/dev/null -msg_ok "Installed PHP 8.1" - -msg_info "Installing grocy" -wget https://releases.grocy.info/latest &>/dev/null -unzip latest -d /var/www/html &>/dev/null -chown -R www-data:www-data /var/www/html -cp /var/www/html/config-dist.php /var/www/html/data/config.php -chmod +x /var/www/html/update.sh - -cat </etc/apache2/sites-available/grocy.conf - - ServerAdmin webmaster@localhost - DocumentRoot /var/www/html/public - ErrorLog /var/log/apache2/error.log - - Options Indexes FollowSymLinks MultiViews - AllowOverride All - Order allow,deny - allow from all - - -EOF - -a2dissite 000-default.conf &>/dev/null -a2ensite grocy.conf &>/dev/null -a2enmod rewrite &>/dev/null -systemctl reload apache2 -msg_ok "Installed grocy" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /root/latest -msg_ok "Cleaned" diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index d847d5a6..34073ba0 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -132,11 +128,11 @@ $STD a2enmod rewrite systemctl reload apache2 msg_ok "Installed grocy" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -149,10 +145,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh deleted file mode 100644 index cf19a76c..00000000 --- a/install/heimdalldashboard-install.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing PHP" -apt-get install -y php &>/dev/null -apt-get install -y php-sqlite3 &>/dev/null -apt-get install -y php-zip &>/dev/null -msg_ok "Installed PHP" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -msg_info "Installing Heimdall Dashboard ${RELEASE}" -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') -rm -rf ${RELEASE}.tar.gz -mv Heimdall-${VER} /opt/Heimdall -msg_ok "Installed Heimdall Dashboard ${RELEASE}" - -msg_info "Creating Service" -service_path="/etc/systemd/system/heimdall.service" -echo "[Unit] -Description=Heimdall -After=network.target - -[Service] -Restart=always -RestartSec=5 -Type=simple -User=root -WorkingDirectory=/opt/Heimdall -ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 -TimeoutStopSec=30 - -[Install] -WantedBy=multi-user.target" >$service_path -sudo systemctl enable --now heimdall.service &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index a94d230d..ce1b5f75 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -126,12 +122,11 @@ WantedBy=multi-user.target" >$service_path $STD sudo systemctl enable --now heimdall.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -144,10 +139,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh deleted file mode 100644 index a9fb4de6..00000000 --- a/install/homeassistant-core-install.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (Patience)" -apt-get install -y \ - make \ - build-essential \ - libjpeg-dev \ - libpcap-dev \ - libssl-dev \ - zlib1g-dev \ - libbz2-dev \ - libreadline-dev \ - libsqlite3-dev \ - libmariadb-dev-compat \ - autoconf \ - git \ - curl \ - sudo \ - llvm \ - libncursesw5-dev \ - xz-utils \ - tzdata \ - bluez \ - tk-dev \ - libxml2-dev \ - libxmlsec1-dev \ - libffi-dev \ - libopenjp2-7 \ - libtiff5 \ - libturbojpeg0-dev \ - liblzma-dev &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Linux D-Bus Message Broker" -cat <>/etc/apt/sources.list -deb http://deb.debian.org/debian bullseye-backports main contrib non-free -deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free -EOF -apt-get update &>/dev/null -apt-get -t bullseye-backports install -y dbus-broker &>/dev/null -systemctl enable --now dbus-broker.service &>/dev/null -msg_ok "Installed Linux D-Bus Message Broker" - -msg_info "Installing pyenv" -git clone https://github.com/pyenv/pyenv.git ~/.pyenv &>/dev/null -set +e -echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc -echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc -echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc -msg_ok "Installed pyenv" -. ~/.bashrc -set -e -msg_info "Installing Python 3.10.8" -pyenv install 3.10.8 &>/dev/null -pyenv global 3.10.8 -msg_ok "Installed Python 3.10.8" - -read -r -p " Use the Beta Branch? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - BR="--pre " -else - BR="" -fi - -msg_info "Installing Home Assistant-Core" -mkdir /srv/homeassistant -cd /srv/homeassistant -python3 -m venv . -source bin/activate -pip install --upgrade pip &>/dev/null -python3 -m pip install wheel &>/dev/null -pip install mysqlclient &>/dev/null -pip install psycopg2-binary &>/dev/null -pip install ${BR}homeassistant &>/dev/null -msg_ok "Installed Home Assistant-Core" - -# fix for inconsistent versions, hopefully the HA team will get this fixed -if [ "${BR}" == "--pre " ]; then -sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i '{s/dbus-fast==1.82.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -else -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/package_constraints.txt -sed -i '{s/dbus-fast==1.75.0/dbus-fast==1.83.1/g; s/bleak==0.19.2/bleak==0.19.5/g}' /srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/bluetooth/manifest.json -fi - -msg_info "Creating Service" -cat </etc/systemd/system/homeassistant.service -[Unit] -Description=Home Assistant -After=network-online.target -[Service] -Type=simple -WorkingDirectory=/root/.homeassistant -ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" -RestartForceExitStatus=100 -[Install] -WantedBy=multi-user.target -EOF -systemctl enable homeassistant &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index c4663502..1ca60ef6 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -168,11 +164,11 @@ EOF $STD systemctl enable --now homeassistant msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -185,10 +181,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh deleted file mode 100644 index 52c3c427..00000000 --- a/install/homeassistant-install.sh +++ /dev/null @@ -1,360 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Python3-pip" -apt-get install -y python3-pip &>/dev/null -msg_ok "Installed Python3-pip" - -get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} - -DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") -CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") -PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") - -msg_info "Installing Docker $DOCKER_LATEST_VERSION" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi -sh <(curl -sSL https://get.docker.com) &>/dev/null -msg_ok "Installed Docker $DOCKER_LATEST_VERSION" - -msg_info "Pulling Portainer $PORTAINER_LATEST_VERSION Image" -docker pull portainer/portainer-ce:latest &>/dev/null -msg_ok "Pulled Portainer $PORTAINER_LATEST_VERSION Image" - -msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" -docker volume create portainer_data >/dev/null -docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest &>/dev/null -msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" - -msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" -docker pull homeassistant/home-assistant:stable &>/dev/null -msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" - -msg_info "Installing Home Assistant $CORE_LATEST_VERSION" -docker volume create hass_config >/dev/null -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null -msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" - -msg_info "Creating Update Menu Script" -pip3 install runlike &>/dev/null -UPDATE_PATH='/root/update' -UPDATE_CONTAINERS_PATH='/root/update-containers.sh' -cat >$UPDATE_PATH <<'EOF' -#!/bin/sh -set -o errexit -show_menu(){ - normal=`echo "\033[m"` - safe=`echo "\033[32m"` - menu=`echo "\033[36m"` - number=`echo "\033[33m"` - bgred=`echo "\033[41m"` - fgred=`echo "\033[31m"` - hostname -I - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${safe} Switch to Stable Branch ${normal}\n" - printf "${menu}**${number} 2)${number} Switch to Beta Branch ${normal}\n" - printf "${menu}**${number} 3)${fgred} Switch to Dev Branch ${normal}\n" - printf "${menu}**${number} 4)${safe} Backup Home Assistant Data (to root) ${normal}\n" - printf "${menu}**${number} 5)${number} Restore Home Assistant Data ${normal}\n" - printf "${menu}**${number} 6)${fgred} Edit Home Assistant Configuration ${normal}\n" - printf "${menu}**${number} 7)${safe} Restart Home Assistant ${normal}\n" - printf "${menu}**${number} 8)${safe} Just Update Containers ${normal}\n" - printf "${menu}**${number} 9)${number} Remove Unused Images ${normal}\n" - printf "${menu}**${number} 10)${safe} Update Host OS ${normal}\n" - printf "${menu}**${number} 11)${safe} Reboot Host OS ${normal}\n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu and enter or ${fgred}x to exit. ${normal}" - read opt -} -option_picked(){ - msgcolor=`echo "\033[01;31m"` - normal=`echo "\033[00;00m"` - message=${@:-"${normal}Error: No message passed"} - printf "${msgcolor}${message}${normal}\n" -} -clear -show_menu -while [ $opt != '' ] - do - if [ $opt = '' ]; then - exit; - else - case $opt in - 1) clear; - option_picked "Switching to Stable Branch"; - TAG=stable - break; - ;; - 2) clear; - option_picked "Switching to Beta Branch"; - TAG=beta - break; - ;; - 3) while true; do - read -p "Are you sure you want to Switch to Dev Branch? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Switching to Dev Branch"; - TAG=dev - break; - ;; - 4) clear; - option_picked "Backing up Home Assistant Data to root (hass_config)"; - rm -r hass_config; - cp -pR /var/lib/docker/volumes/hass_config/ /root/; - sleep 2; - clear; - show_menu; - ;; - 5) while true; do - read -p "Are you sure you want to Restore Home Assistant Data? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Restoring Home Assistant Data from root (hass_config)"; - rm -r /var/lib/docker/volumes/hass_config/_data; - cp -pR /root/hass_config/_data /var/lib/docker/volumes/hass_config/; - sleep 2; - clear; - show_menu; - ;; - 6) while true; do - read -p "Are you sure you want to Edit Home Assistant Configuration? Proceed(y/n)?" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac - done - clear; - option_picked "Editing Home Assistant Configuration"; - nano /var/lib/docker/volumes/hass_config/_data/configuration.yaml; - clear; - show_menu; - ;; - 7) clear; - option_picked "Restarting Home Assistant"; - docker restart homeassistant; - exit; - ;; - 8) clear; - option_picked "Just Updating Containers"; - ./update-containers.sh; - sleep 2; - clear; - show_menu; - ;; - 9) clear; - option_picked "Removing Unused Images"; - docker image prune -af; - sleep 2; - clear; - show_menu; - ;; - 10) clear; - option_picked "Updating Host OS"; - apt update && apt upgrade -y; - sleep 2; - clear; - show_menu; - ;; - 11) clear; - option_picked "Reboot Host OS"; - reboot; - exit; - ;; - x)exit; - ;; - \n)exit; - ;; - *)clear; - option_picked "Please choose an option from the menu"; - show_menu; - ;; - esac - fi - done -docker pull homeassistant/home-assistant:$TAG -docker rm --force homeassistant -docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:$TAG -EOF -sudo chmod +x /root/update -cat >$UPDATE_CONTAINERS_PATH <<'EOF' -#!/bin/bash -set -o errexit -CONTAINER_LIST="${1:-$(docker ps -q)}" -for container in ${CONTAINER_LIST}; do - CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" - RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" - docker pull "${CONTAINER_IMAGE}" - LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" - if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then - echo "Updating ${container} image ${CONTAINER_IMAGE}" - DOCKER_COMMAND="$(runlike "${container}")" - docker rm --force "${container}" - eval ${DOCKER_COMMAND} - fi -done -EOF -sudo chmod +x /root/update-containers.sh -msg_ok "Created Update Menu Script" -mkdir /root/hass_config -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index eaed502e..b6c63719 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -153,12 +149,11 @@ $STD docker run -d \ mkdir /root/hass_config msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -171,10 +166,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh deleted file mode 100644 index 3fdc5a6b..00000000 --- a/install/homebridge-install.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -sudo apt-get install -y nodejs gcc g++ make python net-tools &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Homebridge" -sudo npm install -g --unsafe-perm homebridge homebridge-config-ui-x &>/dev/null -msg_info "Installed Homebridge" - -msg_info "Creating Service" -sudo hb-service install --user homebridge &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 6526111b..1bf8da31 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -105,12 +101,11 @@ msg_info "Creating Service" $STD hb-service install --user homebridge msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -123,10 +118,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homepage-install.sh b/install/homepage-install.sh deleted file mode 100644 index b69d538c..00000000 --- a/install/homepage-install.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_14.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -npm install -g pnpm &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Homepage" -git clone https://github.com/benphelps/homepage.git /opt/homepage &>/dev/null -cd /opt/homepage -mkdir -p config -pnpm install &>/dev/null -pnpm build &>/dev/null -msg_ok "Installed Homepage" - -msg_info "Creating Service" -service_path="/etc/systemd/system/homepage.service" -echo "[Unit] -Description=Homepage -After=network.target -StartLimitIntervalSec=0 -[Service] -Type=simple -Restart=always -RestartSec=1 -User=root -WorkingDirectory=/opt/homepage/ -ExecStart=pnpm start -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now homepage &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index eca56674..81bc069e 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -125,11 +121,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now homepage msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -142,10 +138,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index e4f564d5..b7bbed3a 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -114,11 +110,11 @@ EOF $STD systemctl enable --now homer msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -131,10 +127,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh deleted file mode 100644 index 29644340..00000000 --- a/install/hyperion-install.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y lsb-release &>/dev/null -apt-get install -y gpg &>/dev/null -apt-get install -y apt-transport-https &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Hyperion" -wget -qO- https://apt.hyperion-project.org/hyperion.pub.key | sudo gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg &>/dev/null -echo "deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hyperion.list &>/dev/null -apt-get update &>/dev/null -apt-get install -y hyperion &>/dev/null -systemctl enable --now hyperion@root.service &>/dev/null -msg_ok "Installed Hyperion" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 62dd33fc..82bf8084 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -99,11 +95,11 @@ $STD apt-get install -y hyperion $STD systemctl enable --now hyperion@root.service msg_ok "Installed Hyperion" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -116,10 +112,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove >/dev/null diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh deleted file mode 100644 index 1d11d97f..00000000 --- a/install/influxdb-install.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y lsb-base &>/dev/null -apt-get install -y lsb-release &>/dev/null -apt-get install -y gnupg2 &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up InfluxDB Repository" -wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add - &>/dev/null -echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list &>/dev/null -msg_ok "Set up InfluxDB Repository" - -read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt -if [[ $prompt == "2" ]]; then - INFLUX="2" -else - INFLUX="1" -fi - -msg_info "Installing InfluxDB" -apt-get update &>/dev/null -if [[ $INFLUX == "2" ]]; then - apt-get install -y influxdb2 &>/dev/null -else - apt-get install -y influxdb &>/dev/null -fi -systemctl enable --now influxdb &>/dev/null -msg_ok "Installed InfluxDB" - -read -r -p "Would you like to add Telegraf? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - TELEGRAF="Y" -else - TELEGRAF="N" -fi - -if [[ $TELEGRAF == "Y" ]]; then - msg_info "Installing Telegraf" - apt-get install -y telegraf &>/dev/null - msg_ok "Installed Telegraf" -fi - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index f5becf2e..6c16f851 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -128,12 +124,11 @@ if [[ $TELEGRAF == "Y" ]]; then msg_ok "Installed Telegraf" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -146,10 +141,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/iobroker-install.sh b/install/iobroker-install.sh deleted file mode 100644 index 813e9c46..00000000 --- a/install/iobroker-install.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing ioBroker (10 min)" -curl -sLf https://iobroker.net/install.sh | bash - &>/dev/null -msg_ok "Installed ioBroker" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 96db7e0b..9baddbb6 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -93,12 +89,11 @@ msg_info "Installing ioBroker (Patience)" $STD bash <(curl -fsSL https://iobroker.net/install.sh) msg_ok "Installed ioBroker" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -111,10 +106,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh deleted file mode 100644 index 94c8ad5f..00000000 --- a/install/jellyfin-install.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y apt-transport-https &>/dev/null -apt-get install -y software-properties-common &>/dev/null -msg_ok "Installed Dependencies" - -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then - msg_info "Setting Up Hardware Acceleration" - apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* - msg_ok "Set Up Hardware Acceleration" -fi - -msg_info "Setting Up Jellyfin Repository" -sudo add-apt-repository universe -y &>/dev/null -wget -q -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add - &>/dev/null -echo "deb [arch=$(dpkg --print-architecture)] https://repo.jellyfin.org/ubuntu $(lsb_release -c -s) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list &>/dev/null -msg_ok "Set Up Jellyfin Repository" - -msg_info "Installing Jellyfin" -apt-get update &>/dev/null -sudo apt install jellyfin-server -y &>/dev/null -apt install jellyfin-ffmpeg -y &>/dev/null -msg_ok "Installed Jellyfin" - -msg_info "Creating Service" -cat <<'EOF' >/lib/systemd/system/jellyfin.service -[Unit] -Description = Jellyfin Media Server -After = network.target -[Service] -Type = simple -EnvironmentFile = /etc/default/jellyfin -User = root -ExecStart = /usr/bin/jellyfin -Restart = on-failure -TimeoutSec = 15 -[Install] -WantedBy = multi-user.target -EOF -ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 99df1d57..9b06ea4c 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -133,11 +129,11 @@ EOF ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -150,10 +146,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index a87798ad..8a8553ae 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -109,11 +105,11 @@ msg_info "Installing Helm" $STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) msg_ok "Installed Helm" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -126,10 +122,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index b76e7979..e7f41d47 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,7 +10,6 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" @@ -42,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -67,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -108,11 +111,11 @@ chmod +x /opt/Kavita/* && chown root /opt/Kavita/* systemctl enable --now -q kavita.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -125,10 +128,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh deleted file mode 100644 index 92488072..00000000 --- a/install/keycloak-install.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (Patience)" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y openjdk-11-jdk &>/dev/null -msg_ok "Installed Dependencies" - -RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -msg_info "Installing Keycloak v$RELEASE" -cd /opt -wget https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz &>/dev/null -tar -xvf keycloak-$RELEASE.tar.gz &>/dev/null -mv keycloak-$RELEASE keycloak -msg_ok "Installed Keycloak" - -msg_info "Creating Service" -service_path="/etc/systemd/system/keycloak.service" -echo "[Unit] -Description=Keycloak -After=network-online.target -[Service] -User=root -WorkingDirectory=/opt/keycloak -ExecStart=/opt/keycloak/bin/kc.sh start-dev -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now keycloak.service &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 4370ce4d..6fdf6051 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -112,11 +108,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now keycloak.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -129,10 +125,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index 653c2d7e..d32cf2af 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -119,11 +115,11 @@ systemctl -q daemon-reload systemctl enable --now -q lidarr msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -136,10 +132,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf Lidarr.master.*.tar.gz diff --git a/install/magicmirror-install.sh b/install/magicmirror-install.sh deleted file mode 100644 index 37ada095..00000000 --- a/install/magicmirror-install.sh +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Setting up MagicMirror Repository" -git clone https://github.com/MichMich/MagicMirror /opt/magicmirror &>/dev/null -msg_ok "Set up MagicMirror Repository" - -msg_info "Installing MagicMirror" -cd /opt/magicmirror &>/dev/null -npm install --only=prod --omit=dev &>/dev/null - -cat </opt/magicmirror/config/config.js -let config = { - address: "0.0.0.0", - port: 8080, - basePath: "/", - ipWhitelist: [], - useHttps: false, - httpsPrivateKey: "", - httpsCertificate: "", - language: "en", - locale: "en-US", - logLevel: ["INFO", "LOG", "WARN", "ERROR"], - timeFormat: 24, - units: "metric", - serverOnly: true, - modules: [ - { - module: "alert", - }, - { - module: "updatenotification", - position: "top_bar" - }, - { - module: "clock", - position: "top_left" - }, - { - module: "calendar", - header: "US Holidays", - position: "top_left", - config: { - calendars: [ - { - symbol: "calendar-check", - url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" - } - ] - } - }, - { - module: "compliments", - position: "lower_third" - }, - { - module: "weather", - position: "top_right", - config: { - weatherProvider: "openweathermap", - type: "current", - location: "New York", - locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city - apiKey: "YOUR_OPENWEATHER_API_KEY" - } - }, - { - module: "weather", - position: "top_right", - header: "Weather Forecast", - config: { - weatherProvider: "openweathermap", - type: "forecast", - location: "New York", - locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city - apiKey: "YOUR_OPENWEATHER_API_KEY" - } - }, - { - module: "newsfeed", - position: "bottom_bar", - config: { - feeds: [ - { - title: "New York Times", - url: "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" - } - ], - showSourceTitle: true, - showPublishDate: true, - broadcastNewsFeeds: true, - broadcastNewsUpdates: true - } - }, - ] -}; - -/*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} -EOF -msg_ok "Installed MagicMirror" - -msg_info "Creating Service" -service_path="/etc/systemd/system/magicmirror.service" -echo "[Unit] -Description=Magic Mirror -After=network.target -StartLimitIntervalSec=0 - -[Service] -Type=simple -Restart=always -RestartSec=1 -User=root -WorkingDirectory=/opt/magicmirror/ -ExecStart=/usr/bin/node serveronly - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now magicmirror &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index f347ba92..94db7430 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,7 +10,6 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" @@ -74,7 +74,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -217,11 +217,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now magicmirror msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -234,10 +234,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh deleted file mode 100644 index cd499979..00000000 --- a/install/mariadb-install.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing MariaDB" -curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash &>/dev/null -apt-get update >/dev/null -apt-get install -y mariadb-server &>/dev/null -msg_ok "Installed MariaDB" - -read -r -p "Would you like to add Adminer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - ADMINER="Y" -else - ADMINER="N" -fi - -if [[ $ADMINER == "Y" ]]; then - msg_info "Installing Adminer" - sudo apt install adminer -y &>/dev/null - sudo a2enconf adminer &>/dev/null - sudo systemctl reload apache2 &>/dev/null - msg_ok "Installed Adminer" -fi - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 7e5b2265..35d38926 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -110,12 +106,11 @@ if [[ $ADMINER == "Y" ]]; then msg_ok "Installed Adminer" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -128,10 +123,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh deleted file mode 100644 index af40b17d..00000000 --- a/install/meshcentral-install.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing MeshCentral" -mkdir /opt/meshcentral -cd /opt/meshcentral -npm install meshcentral &>/dev/null -node node_modules/meshcentral --install &>/dev/null -msg_ok "Installed MeshCentral" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index e4085bed..825aaa00 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -104,12 +100,11 @@ $STD npm install meshcentral $STD node node_modules/meshcentral --install msg_ok "Installed MeshCentral" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -122,10 +117,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh deleted file mode 100644 index 7d819d66..00000000 --- a/install/motioneye-install.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y cifs-utils &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Motion" -apt-get install motion -y &>/dev/null -systemctl stop motion &>/dev/null -systemctl disable motion &>/dev/null -msg_ok "Installed Motion" - -msg_info "Installing FFmpeg" -apt-get install ffmpeg v4l-utils -y &>/dev/null -msg_ok "Installed FFmpeg" - -msg_info "Installing Python" -apt-get update &>/dev/null -apt-get install python2 -y &>/dev/null -curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py &>/dev/null -python2 get-pip.py &>/dev/null -apt-get install libffi-dev libzbar-dev libzbar0 -y &>/dev/null -apt-get install python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -y &>/dev/null -msg_ok "Installed Python" - -msg_info "Installing MotionEye" -apt-get update &>/dev/null -sudo pip install motioneye &>/dev/null -mkdir -p /etc/motioneye -cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf -mkdir -p /var/lib/motioneye -msg_ok "Installed MotionEye" - -msg_info "Creating Service" -cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service &>/dev/null -systemctl enable motioneye &>/dev/null -systemctl start motioneye -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 77a8f558..772149a2 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -123,12 +119,11 @@ $STD systemctl enable motioneye systemctl start motioneye msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -141,10 +136,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh deleted file mode 100644 index c9e90259..00000000 --- a/install/mqtt-install.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Mosquitto MQTT Broker" -wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key &>/dev/null -apt-key add mosquitto-repo.gpg.key &>/dev/null -cd /etc/apt/sources.list.d/ -wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list &>/dev/null -apt-get update >/dev/null -apt-get -y install mosquitto &>/dev/null -apt-get -y install mosquitto-clients &>/dev/null -msg_ok "Installed Mosquitto MQTT Broker" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 7b2893bb..867fb2bb 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -100,12 +96,11 @@ $STD apt-get -y install mosquitto $STD apt-get -y install mosquitto-clients msg_ok "Installed Mosquitto MQTT Broker" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -118,10 +113,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/n8n-install.sh b/install/n8n-install.sh deleted file mode 100644 index c700bdb0..00000000 --- a/install/n8n-install.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -sL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing n8n (Patience)" -npm install --global n8n &>/dev/null -msg_ok "Installed n8n" - -msg_info "Creating Service" -cat </etc/systemd/system/n8n.service -[Unit] -Description=n8n - -[Service] -Type=simple -ExecStart=n8n start -[Install] -WantedBy=multi-user.target -EOF -sudo systemctl start n8n &>/dev/null -sudo systemctl enable n8n &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index e03de40c..d72a9c2d 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -115,12 +111,11 @@ EOF $STD systemctl enable --now n8n msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -133,10 +128,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh deleted file mode 100644 index e746cf32..00000000 --- a/install/navidrome-install.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (patience)" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y ffmpeg &>/dev/null -msg_ok "Installed Dependencies" - -RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -msg_info "Installing Navidrome" -sudo install -d -o root -g root /opt/navidrome -sudo install -d -o root -g root /var/lib/navidrome -wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null -sudo tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null -sudo chown -R root:root /opt/navidrome -mkdir -p /music -cat </var/lib/navidrome/navidrome.toml -MusicFolder = '/music' -EOF -msg_ok "Installed Navidrome" - -msg_info "Creating Service" -service_path="/etc/systemd/system/navidrome.service" - -echo "[Unit] -Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic -After=remote-fs.target network.target -AssertPathExists=/var/lib/navidrome - -[Service] -User=root -Group=root -Type=simple -ExecStart=/opt/navidrome/navidrome --configfile '/var/lib/navidrome/navidrome.toml' -WorkingDirectory=/var/lib/navidrome -TimeoutStopSec=20 -KillMode=process -Restart=on-failure -DevicePolicy=closed -NoNewPrivileges=yes -PrivateTmp=yes -PrivateUsers=yes -ProtectControlGroups=yes -ProtectKernelModules=yes -ProtectKernelTunables=yes -RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 -RestrictNamespaces=yes -RestrictRealtime=yes -SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap -ReadWritePaths=/var/lib/navidrome -ProtectSystem=full - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl daemon-reload -systemctl enable --now navidrome.service &>/dev/null - -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /root/Navidrome.tar.gz -msg_ok "Cleaned" diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index c035e760..519177bd 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -143,11 +139,11 @@ $STD systemctl enable --now navidrome.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -160,10 +156,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh deleted file mode 100644 index 5ea6ffa3..00000000 --- a/install/nextcloudpi-install.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing NextCloudPi (Patience)" -curl -sSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh | bash &>/dev/null -sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php -sudo service apache2 restart -msg_ok "Installed NextCloudPi" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index e0cb1628..fc3f7c74 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -95,11 +91,11 @@ sed -i '{s|root:/usr/sbin/nologin|root:/bin/bash|g}' /etc/passwd service apache2 restart msg_ok "Installed NextCloudPi" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -112,10 +108,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/nginx-proxy-manager-install.sh b/install/nginx-proxy-manager-install.sh deleted file mode 100644 index c2dba3e7..00000000 --- a/install/nginx-proxy-manager-install.sh +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get update &>/dev/null -apt-get -y install \ - sudo \ - curl \ - gnupg \ - make \ - g++ \ - gcc \ - ca-certificates \ - apache2-utils \ - logrotate \ - build-essential \ - python3-dev \ - git \ - lsb-release &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Python" -apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv &>/dev/null -pip3 install --upgrade setuptools &>/dev/null -pip3 install --upgrade pip &>/dev/null -python3 -m venv /opt/certbot/ &>/dev/null -if [ "$(getconf LONG_BIT)" = "32" ]; then - python3 -m pip install --no-cache-dir -U cryptography==3.3.2 &>/dev/null -fi -python3 -m pip install --no-cache-dir cffi certbot &>/dev/null -msg_ok "Installed Python" - -msg_info "Installing Openresty" -wget -q -O - https://openresty.org/package/pubkey.gpg | apt-key add - &>/dev/null -codename=$(grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release) &>/dev/null -echo "deb http://openresty.org/package/debian $codename openresty" | tee /etc/apt/sources.list.d/openresty.list &>/dev/null -apt-get -y update &>/dev/null -apt-get -y install --no-install-recommends openresty &>/dev/null -msg_ok "Installed Openresty" - -msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Yarn" -npm install --global yarn &>/dev/null -msg_ok "Installed Yarn" - -RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -msg_info "Downloading Nginx Proxy Manager v${RELEASE}" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null -cd ./nginx-proxy-manager-${RELEASE} -msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" - -msg_info "Setting up Enviroment" -ln -sf /usr/bin/python3 /usr/bin/python -ln -sf /usr/bin/certbot /opt/certbot/bin/certbot -ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx -ln -sf /usr/local/openresty/nginx/ /etc/nginx - -sed -i "s+0.0.0+${RELEASE}+g" backend/package.json -sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json - -sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf -NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") -for NGINX_CONF in $NGINX_CONFS; do - sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" -done - -mkdir -p /var/www/html /etc/nginx/logs -cp -r docker/rootfs/var/www/html/* /var/www/html/ -cp -r docker/rootfs/etc/nginx/* /etc/nginx/ -cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini -cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager -ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf -rm -f /etc/nginx/conf.d/dev.conf - -mkdir -p /tmp/nginx/body \ - /run/nginx \ - /data/nginx \ - /data/custom_ssl \ - /data/logs \ - /data/access \ - /data/nginx/default_host \ - /data/nginx/default_www \ - /data/nginx/proxy_host \ - /data/nginx/redirection_host \ - /data/nginx/stream \ - /data/nginx/dead_host \ - /data/nginx/temp \ - /var/lib/nginx/cache/public \ - /var/lib/nginx/cache/private \ - /var/cache/nginx/proxy_temp - -chmod -R 777 /var/cache/nginx -chown root /tmp/nginx - -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf - -if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -en "${GN} Generating dummy SSL Certificate... " - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null -fi - -mkdir -p /app/global /app/frontend/images -cp -r backend/* /app -cp -r global/* /app/global -msg_ok "Set up Enviroment" - -msg_info "Building Frontend" -cd ./frontend -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -yarn build &>/dev/null -cp -r dist/* /app/frontend -cp -r app-images/* /app/frontend/images -msg_ok "Built Frontend" - -msg_info "Initializing Backend" -rm -rf /app/config/default.json &>/dev/null -if [ ! -f /app/config/production.json ]; then - cat <<'EOF' >/app/config/production.json -{ - "database": { - "engine": "knex-native", - "knex": { - "client": "sqlite3", - "connection": { - "filename": "/data/database.sqlite" - } - } - } -} -EOF -fi -cd /app -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -msg_ok "Initialized Backend" - -msg_info "Creating Service" -cat <<'EOF' >/lib/systemd/system/npm.service -[Unit] -Description=Nginx Proxy Manager -After=network.target -Wants=openresty.service - -[Service] -Type=simple -Environment=NODE_ENV=production -ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge -ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 -WorkingDirectory=/app -Restart=on-failure - -[Install] -WantedBy=multi-user.target -EOF -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Starting Services" -systemctl enable npm &>/dev/null -systemctl start openresty -systemctl start npm -msg_ok "Started Services" - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index eacab824..ae45c980 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -247,12 +243,11 @@ WantedBy=multi-user.target EOF msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -265,10 +260,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Starting Services" $STD systemctl enable --now openresty diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh deleted file mode 100644 index 491eb153..00000000 --- a/install/nocodb-install.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -sudo apt-get install -y nodejs git make g++ gcc &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing NocoDB" -git clone https://github.com/nocodb/nocodb-seed &>/dev/null -mv nocodb-seed /opt/nocodb -cd /opt/nocodb -npm install &>/dev/null -msg_ok "Installed NocoDB" - -msg_info "Creating Service" -service_path="/etc/systemd/system/nocodb.service" -echo "[Unit] -Description=nocodb - -[Service] -Type=simple -Restart=always -User=root -WorkingDirectory=/opt/nocodb -ExecStart=/usr/bin/npm start - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now nocodb.service &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index 1700c038..340863f9 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -122,12 +118,11 @@ WantedBy=multi-user.target" >$service_path systemctl enable --now nocodb.service &>/dev/null msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -140,10 +135,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/node-red-install.sh b/install/node-red-install.sh deleted file mode 100644 index 85df743b..00000000 --- a/install/node-red-install.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Node-Red" -npm install -g --unsafe-perm node-red &>/dev/null -msg_ok "Installed Node-Red" - -msg_info "Creating Service" -service_path="/etc/systemd/system/nodered.service" -echo "[Unit] -Description=Node-RED -After=syslog.target network.target - -[Service] -ExecStart=/usr/bin/node-red --max-old-space-size=128 -v -Restart=on-failure -KillSignal=SIGINT - -SyslogIdentifier=node-red -StandardOutput=syslog - -WorkingDirectory=/root/ -User=root -Group=root - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now nodered.service &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index 20359660..b9cb9bc9 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -125,12 +121,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now nodered.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -143,10 +138,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/omada-install.sh b/install/omada-install.sh deleted file mode 100644 index bec67474..00000000 --- a/install/omada-install.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get -y install curl &>/dev/null -apt-get -y install sudo &>/dev/null -apt-get -y install gnupg &>/dev/null -apt-get -y install openjdk-8-jre-headless &>/dev/null -apt-get -y install jsvc &>/dev/null -wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb -sudo dpkg -i mongodb-org-server_3.6.23_amd64.deb &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Omada Controller v5.6.3" -wget -qL https://static.tp-link.com/upload/software/2022/202211/20221121/Omada_SDN_Controller_v5.7.4_Linux_x64.deb -sudo dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb &>/dev/null -msg_ok "Installed Omada Controller" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 9dabc392..79fd4e5f 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -99,11 +95,11 @@ wget -qL https://static.tp-link.com/upload/software/2022/202211/20221121/Omada_S $STD dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb msg_ok "Installed Omada Controller" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -116,10 +112,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf Omada_SDN_Controller_v5.7.4_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb diff --git a/install/omv-install.sh b/install/omv-install.sh deleted file mode 100644 index 0a98be6f..00000000 --- a/install/omv-install.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -export DEBIAN_FRONTEND=noninteractive -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing OpenMediaVault (Patience)" -wget -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key &>/dev/null -apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" &>/dev/null - -cat <>/etc/apt/sources.list.d/openmediavault.list -deb https://packages.openmediavault.org/public shaitan main -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main -## Uncomment the following line to add software from the proposed repository. -# deb https://packages.openmediavault.org/public shaitan-proposed main -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan-proposed main -## This software is not part of OpenMediaVault, but is offered by third-party -## developers as a service to OpenMediaVault users. -# deb https://packages.openmediavault.org/public shaitan partner -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner -EOF -apt-get update &>/dev/null -apt-get -y install openmediavault-keyring &>/dev/null -apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends install openmediavault &>/dev/null -omv-confdbadm populate -msg_ok "Installed OpenMediaVault" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 19e6c069..90623f7c 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") @@ -10,26 +11,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -111,11 +107,11 @@ $STD apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-chan omv-confdbadm populate msg_ok "Installed OpenMediaVault" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -128,10 +124,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/openhab-install.sh b/install/openhab-install.sh deleted file mode 100644 index ef7dc48f..00000000 --- a/install/openhab-install.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -apt-get install -y apt-transport-https &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Azul Zulu" -apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 &>/dev/null -curl -O https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb &>/dev/null -apt-get install ./zulu-repo_1.0.0-3_all.deb &>/dev/null -apt-get update &>/dev/null -apt-get -y install zulu11-jdk &>/dev/null -msg_ok "Installed Azul Zulu" - -msg_info "Installing openHAB" -curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor >openhab.gpg -mv openhab.gpg /usr/share/keyrings -chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg -echo 'deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main' | tee /etc/apt/sources.list.d/openhab.list &>/dev/null -apt update &>/dev/null -apt-get -y install openhab &>/dev/null -systemctl daemon-reload -systemctl enable openhab.service &>/dev/null -systemctl start openhab.service -msg_ok "Installed openHAB" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index 4ef6fe28..ca7a23d9 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -110,11 +106,11 @@ systemctl daemon-reload $STD systemctl enable --now openhab.service msg_ok "Installed openHAB" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -127,10 +123,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh deleted file mode 100644 index 87d509eb..00000000 --- a/install/paperless-ngx-install.sh +++ /dev/null @@ -1,287 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Paperless-ngx Dependencies" -apt-get install -y --no-install-recommends \ - python3 \ - python3-pip \ - python3-dev \ - imagemagick \ - fonts-liberation \ - optipng \ - gnupg \ - libpq-dev \ - libmagic-dev \ - mime-support \ - libzbar0 \ - poppler-utils \ - default-libmysqlclient-dev \ - sudo &>/dev/null -msg_ok "Installed Paperless-ngx Dependencies" - -msg_info "Installing OCR Dependencies" -apt-get install -y --no-install-recommends \ - unpaper \ - ghostscript \ - icc-profiles-free \ - qpdf \ - liblept5 \ - libxml2 \ - pngquant \ - zlib1g \ - tesseract-ocr \ - tesseract-ocr-eng &>/dev/null -msg_ok "Installed OCR Dependencies" - -msg_info "Installing Extra Dependencies" -apt-get install -y --no-install-recommends \ - redis \ - postgresql \ - build-essential \ - python3-setuptools \ - python3-wheel &>/dev/null -msg_ok "Installed Extra Dependencies" - -msg_info "Installing JBIG2" -apt-get install -y --no-install-recommends \ - automake \ - libtool \ - pkg-config \ - git \ - curl \ - libtiff-dev \ - libpng-dev \ - libleptonica-dev &>/dev/null - -git clone https://github.com/agl/jbig2enc /opt/jbig2enc &>/dev/null -cd /opt/jbig2enc -/bin/bash -c "./autogen.sh" &>/dev/null && - /bin/bash -c "./configure && make" &>/dev/null && - /bin/bash -c "make install" &>/dev/null -rm -rf /opt/jbig2enc -msg_ok "Installed JBIG2" - -msg_info "Downloading Paperless-ngx" -Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) -cd /opt && - wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz &>/dev/null && - tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ &>/dev/null && - mv paperless-ngx paperless && - rm paperless-ngx-$Paperlessngx.tar.xz -cd /opt/paperless - -## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file -sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt - -/usr/bin/python3 -m pip install --upgrade pip &>/dev/null -/usr/bin/python3 -m pip install -r requirements.txt &>/dev/null -msg_ok "Downloaded Paperless-ngx" - -msg_info "Setting up database" -DB_USER=paperless -DB_PASS="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" -DB_NAME=paperlessdb - -sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" &>/dev/null -sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" &>/dev/null - -echo "Paperless-ngx Database User" >>~/paperless.creds -echo $DB_USER >>~/paperless.creds -echo "Paperless-ngx Database Password" >>~/paperless.creds -echo $DB_PASS >>~/paperless.creds -echo "Paperless-ngx Database Name" >>~/paperless.creds -echo $DB_NAME >>~/paperless.creds - -/bin/bash -c "mkdir -p {consume,media}" - -sed -i -e 's|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=paperlessdb|' /opt/paperless/paperless.conf -sed -i -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" /opt/paperless/paperless.conf -SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" -sed -i -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" /opt/paperless/paperless.conf - -cd /opt/paperless/src -/usr/bin/python3 manage.py migrate &>/dev/null -msg_ok "Set up database" - -msg_info "Setting up admin Paperless-ngx User & Password" -## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations -cat <>~/paperless.creds -echo "Paperless-ngx WebUI User" >>~/paperless.creds -echo admin >>~/paperless.creds -echo "Paperless-ngx WebUI Password" >>~/paperless.creds -echo $DB_PASS >>~/paperless.creds -msg_ok "Set up admin Paperless-ngx User & Password" - -cat </etc/systemd/system/paperless-scheduler.service -[Unit] -Description=Paperless Celery beat -Requires=redis.service - -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless beat --loglevel INFO - -[Install] -WantedBy=multi-user.target -EOF - -cat </etc/systemd/system/paperless-task-queue.service -[Unit] -Description=Paperless Celery Workers -Requires=redis.service - -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless worker --loglevel INFO - -[Install] -WantedBy=multi-user.target -EOF - -cat </etc/systemd/system/paperless-consumer.service -[Unit] -Description=Paperless consumer -Requires=redis.service - -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=python3 manage.py document_consumer - -[Install] -WantedBy=multi-user.target -EOF - -cat </etc/systemd/system/paperless-webserver.service -[Unit] -Description=Paperless webserver -After=network.target -Wants=network.target -Requires=redis.service - -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=/usr/local/bin/gunicorn -c /opt/paperless/gunicorn.conf.py paperless.asgi:application - -[Install] -WantedBy=multi-user.target -EOF - -sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml - -systemctl daemon-reload -systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service &>/dev/null - -msg_ok "Finished installing Paperless-ngx" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 2d3864e0..3eb5cb42 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,7 +10,6 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" @@ -74,7 +74,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -267,12 +267,11 @@ $STD systemctl enable --now paperless-consumer paperless-webserver paperless-sch msg_ok "Created Services" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -285,6 +284,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh deleted file mode 100644 index 523bdf41..00000000 --- a/install/photoprism-install.sh +++ /dev/null @@ -1,218 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (Patience)" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gcc &>/dev/null -apt-get install -y g++ &>/dev/null -apt-get install -y git &>/dev/null -apt-get install -y gnupg &>/dev/null -apt-get install -y make &>/dev/null -apt-get install -y zip &>/dev/null -apt-get install -y unzip &>/dev/null -apt-get install -y exiftool &>/dev/null -apt-get install -y ffmpeg &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -sL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Golang (Patience)" -wget https://golang.org/dl/go1.19.3.linux-amd64.tar.gz &>/dev/null -tar -xzf go1.19.3.linux-amd64.tar.gz -C /usr/local &>/dev/null -ln -s /usr/local/go/bin/go /usr/local/bin/go &>/dev/null -go install github.com/tianon/gosu@latest &>/dev/null -go install golang.org/x/tools/cmd/goimports@latest &>/dev/null -go install github.com/psampaz/go-mod-outdated@latest &>/dev/null -go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest &>/dev/null -go install github.com/mikefarah/yq/v4@latest &>/dev/null -go install github.com/kyoh86/richgo@latest &>/dev/null -cp /root/go/bin/* /usr/local/go/bin/ -cp /usr/local/go/bin/richgo /usr/local/bin/richgo -cp /usr/local/go/bin/gosu /usr/local/sbin/gosu -chown root:root /usr/local/sbin/gosu -chmod 755 /usr/local/sbin/gosu -msg_ok "Installed Golang" - -msg_info "Installing Tensorflow" -if [[ "$AVX" =~ avx2 ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz &>/dev/null -elif [[ "$AVX" =~ avx ]]; then - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz &>/dev/null -else - wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null - tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz &>/dev/null -fi -ldconfig &>/dev/null -msg_ok "Installed Tensorflow" - -msg_info "Cloning PhotoPrism" -mkdir -p /opt/photoprism/bin -mkdir -p /var/lib/photoprism/storage -git clone https://github.com/photoprism/photoprism.git &>/dev/null -cd photoprism -git checkout release &>/dev/null -msg_ok "Cloned PhotoPrism" - -msg_info "Building PhotoPrism (Patience)" -NODE_OPTIONS=--max_old_space_size=2048 make all &>/dev/null -./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null -cp -r assets/ /opt/photoprism/ &>/dev/null -msg_ok "Built PhotoPrism" - -env_path="/var/lib/photoprism/.env" -echo " -PHOTOPRISM_AUTH_MODE='password' -PHOTOPRISM_ADMIN_PASSWORD='changeme' -PHOTOPRISM_HTTP_HOST='0.0.0.0' -PHOTOPRISM_HTTP_PORT='2342' -PHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/' -PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' -PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' -PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -" >$env_path - -msg_info "Creating Service" -service_path="/etc/systemd/system/photoprism.service" - -echo "[Unit] -Description=PhotoPrism service -After=network.target - -[Service] -Type=forking -User=root -WorkingDirectory=/opt/photoprism -EnvironmentFile=/var/lib/photoprism/.env -ExecStart=/opt/photoprism/bin/photoprism up -d -ExecStop=/opt/photoprism/bin/photoprism down - -[Install] -WantedBy=multi-user.target" >$service_path -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /var/{cache,log}/* \ - /photoprism \ - /go1.19.3.linux-amd64.tar.gz \ - /libtensorflow-linux-avx2-1.15.2.tar.gz \ - /libtensorflow-linux-avx-1.15.2.tar.gz \ - /libtensorflow-linux-cpu-1.15.2.tar.gz -msg_ok "Cleaned" - -msg_info "Starting PhotoPrism" -systemctl enable --now photoprism &>/dev/null diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index ca60b3df..48584dcb 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) YW=$(echo "\033[33m") @@ -10,26 +11,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -50,15 +43,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -75,7 +71,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -183,12 +179,11 @@ ExecStop=/opt/photoprism/bin/photoprism down WantedBy=multi-user.target" >$service_path msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -201,10 +196,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/pihole-install.sh b/install/pihole-install.sh deleted file mode 100644 index 3b7de2a2..00000000 --- a/install/pihole-install.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -export DEBIAN_FRONTEND=noninteractive -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y ufw &>/dev/null -apt-get install -y ntp &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Pi-hole" -mkdir -p /etc/pihole/ -cat </etc/pihole/setupVars.conf -PIHOLE_INTERFACE=eth0 -PIHOLE_DNS_1=8.8.8.8 -PIHOLE_DNS_2=8.8.4.4 -QUERY_LOGGING=true -INSTALL_WEB_SERVER=true -INSTALL_WEB_INTERFACE=true -LIGHTTPD_ENABLED=true -CACHE_SIZE=10000 -DNS_FQDN_REQUIRED=true -DNS_BOGUS_PRIV=true -DNSMASQ_LISTENING=local -WEBPASSWORD=$(openssl rand -base64 48) -BLOCKING_ENABLED=true -EOF - -curl -sSL https://install.pi-hole.net | bash /dev/stdin --unattended &>/dev/null -msg_ok "Installed Pi-hole" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 2133980b..c1d93dd4 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi export DEBIAN_FRONTEND=noninteractive YW=$(echo "\033[33m") @@ -10,26 +11,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -50,15 +43,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -75,7 +71,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -116,12 +112,11 @@ EOF $STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended msg_ok "Installed Pi-hole" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -134,10 +129,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/plex-install.sh b/install/plex-install.sh deleted file mode 100644 index dc5ba5e2..00000000 --- a/install/plex-install.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -msg_ok "Installed Dependencies" - -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then - msg_info "Setting Up Hardware Acceleration" - apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - beignet-opencl-icd &>/dev/null - - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* - msg_ok "Set Up Hardware Acceleration" -fi - -msg_info "Setting Up Plex Media Server Repository" -wget -q https://downloads.plex.tv/plex-keys/PlexSign.key -O - | sudo apt-key add - &>/dev/null -echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" | tee /etc/apt/sources.list.d/plexmediaserver.list &>/dev/null -msg_ok "Set Up Plex Media Server Repository" - -msg_info "Installing Plex Media Server" -apt-get update &>/dev/null -apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver &>/dev/null -msg_ok "Installed Plex Media Server" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 93bb66d3..b9a46f66 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -113,11 +109,11 @@ $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver msg_ok "Installed Plex Media Server" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -130,10 +126,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/podman-homeassistant-install.sh b/install/podman-homeassistant-install.sh deleted file mode 100644 index 3cd1679d..00000000 --- a/install/podman-homeassistant-install.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Podman" -apt-get -y install podman &>/dev/null -systemctl enable --now podman.socket &>/dev/null -msg_ok "Installed Podman" - -read -r -p "Would you like to add Yacht (Semifunctional)? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - YACHT="Y" -else - YACHT="N" -fi - -if [[ $YACHT == "Y" ]]; then - msg_info "Pulling Yacht Image" - podman pull docker.io/selfhostedpro/yacht:latest &>/dev/null - msg_ok "Pulled Yacht Image" - - msg_info "Installing Yacht" - podman volume create yacht >/dev/null - podman run -d \ - --privileged \ - --name yacht \ - --restart always \ - -v /var/run/podman/podman.sock:/var/run/docker.sock \ - -v yacht:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - -p 8000:8000 \ - selfhostedpro/yacht:latest &>/dev/null - podman generate systemd \ - --new --name yacht \ - >/etc/systemd/system/yacht.service - systemctl enable yacht &>/dev/null - msg_ok "Installed Yacht" -fi -msg_info "Pulling Home Assistant Image" -podman pull docker.io/homeassistant/home-assistant:stable &>/dev/null -msg_ok "Pulled Home Assistant Image" - -msg_info "Installing Home Assistant" -podman volume create hass_config >/dev/null -podman run -d \ - --privileged \ - --name homeassistant \ - --restart unless-stopped \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:stable &>/dev/null -podman generate systemd \ - --new --name homeassistant \ - >/etc/systemd/system/homeassistant.service -systemctl enable homeassistant &>/dev/null -msg_ok "Installed Home Assistant" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index e7831240..277afab7 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -115,12 +111,11 @@ podman generate systemd \ $STD systemctl enable --now homeassistant msg_ok "Installed Home Assistant" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -133,10 +128,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index f893c4d0..98928d14 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -94,11 +90,11 @@ $STD systemctl enable --now podman.socket echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registries.conf msg_ok "Installed Podman" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -111,10 +107,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/postgresql-install.sh b/install/postgresql-install.sh deleted file mode 100644 index 4e0c8849..00000000 --- a/install/postgresql-install.sh +++ /dev/null @@ -1,243 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg2 &>/dev/null -apt-get install -y lsb-release &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up PostgreSQL Repository" -sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' &>/dev/null -wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - &>/dev/null -msg_ok "Setup PostgreSQL Repository" - -msg_info "Installing PostgreSQL" -apt-get update &>/dev/null -apt-get install -y postgresql &>/dev/null - -cat </etc/postgresql/15/main/pg_hba.conf -# PostgreSQL Client Authentication Configuration File -local all postgres peer -# TYPE DATABASE USER ADDRESS METHOD -# "local" is for Unix domain socket connections only -local all all peer -# IPv4 local connections: -host all all 127.0.0.1/32 scram-sha-256 -host all all 0.0.0.0/24 md5 -# IPv6 local connections: -host all all ::1/128 scram-sha-256 -host all all 0.0.0.0/0 md5 -# Allow replication connections from localhost, by a user with the -# replication privilege. -local replication all peer -host replication all 127.0.0.1/32 scram-sha-256 -host replication all ::1/128 scram-sha-256 -EOF - -cat </etc/postgresql/15/main/postgresql.conf -# ----------------------------- -# PostgreSQL configuration file -# ----------------------------- - -#------------------------------------------------------------------------------ -# FILE LOCATIONS -#------------------------------------------------------------------------------ - -data_directory = '/var/lib/postgresql/15/main' -hba_file = '/etc/postgresql/15/main/pg_hba.conf' -ident_file = '/etc/postgresql/15/main/pg_ident.conf' -external_pid_file = '/var/run/postgresql/15-main.pid' - -#------------------------------------------------------------------------------ -# CONNECTIONS AND AUTHENTICATION -#------------------------------------------------------------------------------ - -# - Connection Settings - - -listen_addresses = '*' -port = 5432 -max_connections = 100 -unix_socket_directories = '/var/run/postgresql' - -# - SSL - - -ssl = on -ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' -ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' - -#------------------------------------------------------------------------------ -# RESOURCE USAGE (except WAL) -#------------------------------------------------------------------------------ - -shared_buffers = 128MB -dynamic_shared_memory_type = posix - -#------------------------------------------------------------------------------ -# WRITE-AHEAD LOG -#------------------------------------------------------------------------------ - -max_wal_size = 1GB -min_wal_size = 80MB - -#------------------------------------------------------------------------------ -# REPORTING AND LOGGING -#------------------------------------------------------------------------------ - -# - What to Log - - -log_line_prefix = '%m [%p] %q%u@%d ' -log_timezone = 'Etc/UTC' - -#------------------------------------------------------------------------------ -# PROCESS TITLE -#------------------------------------------------------------------------------ - -cluster_name = '15/main' - -#------------------------------------------------------------------------------ -# CLIENT CONNECTION DEFAULTS -#------------------------------------------------------------------------------ - -# - Locale and Formatting - - -datestyle = 'iso, mdy' -timezone = 'Etc/UTC' -lc_messages = 'C' -lc_monetary = 'C' -lc_numeric = 'C' -lc_time = 'C' -default_text_search_config = 'pg_catalog.english' - -#------------------------------------------------------------------------------ -# CONFIG FILE INCLUDES -#------------------------------------------------------------------------------ - -include_dir = 'conf.d' -EOF - -sudo systemctl restart postgresql -msg_ok "Installed PostgreSQL" - -read -r -p "Would you like to add Adminer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - ADMINER="Y" -else - ADMINER="N" -fi - -if [[ $ADMINER == "Y" ]]; then - msg_info "Installing Adminer" - sudo apt install adminer -y &>/dev/null - sudo a2enconf adminer &>/dev/null - sudo systemctl reload apache2 &>/dev/null - msg_ok "Installed Adminer" -fi - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 16a24da2..bc14a5dc 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -217,11 +213,11 @@ if [[ $ADMINER == "Y" ]]; then msg_ok "Installed Adminer" fi -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -234,10 +230,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/prometheus-install.sh b/install/prometheus-install.sh deleted file mode 100644 index fd38a1b9..00000000 --- a/install/prometheus-install.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Prometheus" -mkdir -p /etc/prometheus -mkdir -p /var/lib/prometheus -wget https://github.com/prometheus/prometheus/releases/download/v2.36.2/prometheus-2.36.2.linux-amd64.tar.gz &>/dev/null -tar -xvf prometheus-2.36.2.linux-amd64.tar.gz &>/dev/null -cd prometheus-2.36.2.linux-amd64 -mv prometheus promtool /usr/local/bin/ -mv consoles/ console_libraries/ /etc/prometheus/ -mv prometheus.yml /etc/prometheus/prometheus.yml -msg_ok "Installed Prometheus" - -msg_info "Creating Service" -service_path="/etc/systemd/system/prometheus.service" -echo "[Unit] -Description=Prometheus -Wants=network-online.target -After=network-online.target - -[Service] -User=root -Restart=always -Type=simple -ExecStart=/usr/local/bin/prometheus \ - --config.file=/etc/prometheus/prometheus.yml \ - --storage.tsdb.path=/var/lib/prometheus/ \ - --web.console.templates=/etc/prometheus/consoles \ - --web.console.libraries=/etc/prometheus/console_libraries \ - --web.listen-address=0.0.0.0:9090 - -[Install] -WantedBy=multi-user.target" >$service_path -sudo systemctl enable --now prometheus &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /root/prometheus-2.36.2.linux-amd64 /root/prometheus-2.36.2.linux-amd64.tar.gz -msg_ok "Cleaned" diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 5eaad18a..faf3d67a 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -124,11 +120,11 @@ WantedBy=multi-user.target" >$service_path $STD sudo systemctl enable --now prometheus msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -141,10 +137,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index ace1fe80..7fa6898b 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -117,11 +113,11 @@ systemctl -q daemon-reload systemctl enable --now -q prowlarr msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -134,10 +130,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf Prowlarr.master.*.tar.gz diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 57434a87..58f9c4a6 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -117,11 +113,11 @@ systemctl -q daemon-reload systemctl enable --now -q radarr msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -134,10 +130,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf Radarr.master.*.tar.gz diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index b621cb7a..d4586f0d 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -117,11 +113,11 @@ systemctl -q daemon-reload systemctl enable --now -q readarr msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -134,10 +130,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf Readarr.develop.*.tar.gz diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 964f2de7..ccdf4923 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -122,11 +118,11 @@ WantedBy=multi-user.target" >$service_path systemctl enable --now -q sabnzbd.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -139,10 +135,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh deleted file mode 100644 index 96380318..00000000 --- a/install/scrypted-install.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get -y install software-properties-common apt-utils &>/dev/null -apt-get -y update &>/dev/null -apt-get -y upgrade &>/dev/null -apt-get -y install \ - build-essential \ - gcc \ - gir1.2-gtk-3.0 \ - libcairo2-dev \ - libgirepository1.0-dev \ - libglib2.0-dev \ - libjpeg-dev \ - libgif-dev \ - libopenjp2-7 \ - libpango1.0-dev \ - librsvg2-dev \ - pkg-config \ - curl \ - sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing GStreamer" -apt-get -y install \ - gstreamer1.0-tools \ - libgstreamer1.0-dev \ - libgstreamer-plugins-base1.0-dev \ - libgstreamer-plugins-bad1.0-dev \ - gstreamer1.0-plugins-base \ - gstreamer1.0-plugins-good \ - gstreamer1.0-plugins-bad \ - gstreamer1.0-plugins-ugly \ - gstreamer1.0-libav \ - gstreamer1.0-alsa &>/dev/null -msg_ok "Installed GStreamer" - -msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Python3" -apt-get -y install \ - python3 \ - python3-dev \ - python3-gi \ - python3-gst-1.0 \ - python3-matplotlib \ - python3-numpy \ - python3-opencv \ - python3-pil \ - python3-pip \ - python3-setuptools \ - python3-skimage \ - python3-wheel &>/dev/null -python3 -m pip install --upgrade pip &>/dev/null -python3 -m pip install aiofiles debugpy typing_extensions typing &>/dev/null -msg_ok "Installed Python3" - -read -r -p "Would you like to add Coral Edge TPU support? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - CORAL="Y" -else - CORAL="N" -fi - -if [[ $CORAL == "Y" ]]; then -msg_info "Adding Coral Edge TPU Support" -echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | tee /etc/apt/sources.list.d/coral-edgetpu.list &>/dev/null -curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - &>/dev/null -apt-get -y update &>/dev/null -apt-get -y install libedgetpu1-std &>/dev/null -msg_ok "Coral Edge TPU Support Added" -fi - -msg_info "Installing Scrypted" -sudo -u root npx -y scrypted@latest install-server &>/dev/null -msg_info "Installed Scrypted" - -msg_info "Creating Service" -service_path="/etc/systemd/system/scrypted.service" -echo "[Unit] -Description=Scrypted service -After=network.target - -[Service] -User=root -Group=root -Type=simple -ExecStart=/usr/bin/npx -y scrypted serve -Restart=on-failure -RestartSec=3 - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now scrypted.service &>/dev/null -msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 53c2e62d..c55bfba2 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -182,11 +178,11 @@ RestartSec=3 WantedBy=multi-user.target" >$service_path $STD systemctl enable --now scrypted.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -199,10 +195,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh deleted file mode 100644 index 0c8510fa..00000000 --- a/install/shinobi-install.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update --fix-missing &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -ubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) -if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then - apt install sudo wget -y - sudo apt install -y software-properties-common - sudo add-apt-repository universe -y - apt update -y - apt update --fix-missing -y -fi - -msg_info "Installing Dependencies" -apt-get install -y curl sudo git &>/dev/null -apt-get install -y make zip net-tools &>/dev/null -apt-get install -y gcc g++ cmake &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing FFMPEG" -apt-get install -y ffmpeg &>/dev/null -msg_ok "Installed FFMPEG" - -msg_info "Clonning Shinobi" -cd /opt -git clone https://gitlab.com/Shinobi-Systems/Shinobi.git -b master Shinobi &>/dev/null -cd Shinobi -gitVersionNumber=$(git rev-parse HEAD) -theDateRightNow=$(date) -touch version.json -chmod 777 version.json -echo '{"Product" : "'"Shinobi"'" , "Branch" : "'"master"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"https://gitlab.com/Shinobi-Systems/Shinobi.git"'"}' > version.json -msg_ok "Cloned Shinobi" - -msg_info "Installing Database" -sqlpass="" -echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections -echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections -apt-get install -y mariadb-server &>/dev/null -service mysql start -sqluser="root" -mysql -e "source sql/user.sql" || true -mysql -e "source sql/framework.sql" || true -msg_ok "Installed Database" -cp conf.sample.json conf.json -cronKey=$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)}') -sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json -cp super.sample.json super.json - -msg_info "Installing Shinobi" -npm i npm -g &>/dev/null -npm install --unsafe-perm &>/dev/null -npm install pm2@latest -g &>/dev/null -chmod -R 755 . -touch INSTALL/installed.txt -ln -s /opt/Shinobi/INSTALL/shinobi /usr/bin/shinobi -node /opt/Shinobi/tools/modifyConfiguration.js addToConfig="{\"cron\":{\"key\":\"$(head -c 64 < /dev/urandom | sha256sum | awk '{print substr($1,1,60)}')\"}}" &>/dev/null -pm2 start camera.js &>/dev/null -pm2 start cron.js &>/dev/null -pm2 startup &>/dev/null -pm2 save &>/dev/null -pm2 list &>/dev/null -msg_ok "Installed Shinobi" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index b78a3eb2..6a6c6d47 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -151,11 +147,11 @@ $STD pm2 save $STD pm2 list msg_ok "Installed Shinobi" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -168,10 +164,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index d70ec352..4d397510 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -10,26 +11,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -98,11 +94,11 @@ $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" install -y sonarr msg_ok "Installed Sonarr" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -115,10 +111,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh deleted file mode 100644 index a6a09abd..00000000 --- a/install/syncthing-install.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gnupg &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Syncthing" -curl -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg &>/dev/null -echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list &>/dev/null -apt-get update &>/dev/null -apt-get install -y syncthing &>/dev/null -systemctl enable syncthing@root.service &>/dev/null -systemctl start syncthing@root.service -sleep 5 -sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.config/syncthing/config.xml -systemctl restart syncthing@root.service -msg_ok "Installed Syncthing" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 3a78362e..770fdc90 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -101,11 +97,11 @@ sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.config/syncthing/config.xml systemctl restart syncthing@root.service msg_ok "Installed Syncthing" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -118,10 +114,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 0121ef51..35167dfc 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -144,11 +140,11 @@ systemctl enable --now -q tdarr-server.service systemctl enable --now -q tdarr-node.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -161,10 +157,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf Tdarr_Updater.zip diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh deleted file mode 100644 index 038275c2..00000000 --- a/install/technitiumdns-install.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Technitium DNS" -curl -sSL https://download.technitium.com/dns/install.sh | sudo bash &>/dev/null -msg_ok "Installed Technitium DNS" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 76abf611..a410e6cc 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -96,12 +92,11 @@ ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf $STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) msg_ok "Installed Technitium DNS" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -114,10 +109,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index 436f527a..db579d21 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -96,11 +92,11 @@ sed -i '{s/"rpc-whitelist-enabled": true/"rpc-whitelist-enabled": false/g; s/"rp systemctl start transmission-daemon msg_ok "Installed Transmission" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -113,10 +109,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/trilium-install.sh b/install/trilium-install.sh deleted file mode 100644 index d18a33c2..00000000 --- a/install/trilium-install.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -msg_info "Installing Trilium" -wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz -tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null -mv trilium-linux-x64-server /opt/trilium -msg_ok "Installed Trilium" - -msg_info "Creating Service" -service_path="/etc/systemd/system/trilium.service" - -echo "[Unit] -Description=Trilium Daemon -After=syslog.target network.target - -[Service] -User=root -Type=simple -ExecStart=/opt/trilium/trilium.sh -WorkingDirectory=/opt/trilium/ -TimeoutStopSec=20 -Restart=always - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q trilium -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -rm -rf /root/trilium-linux-x64-server-$RELEASE.tar.xz -msg_ok "Cleaned" diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index b4fe4f89..4b266ec1 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -118,11 +114,11 @@ WantedBy=multi-user.target" >$service_path systemctl enable --now -q trilium msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -135,10 +131,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/ubuntu-install.sh b/install/ubuntu-install.sh deleted file mode 100644 index 0b1564d0..00000000 --- a/install/ubuntu-install.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index abb5e42f..ec35eb7f 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -89,11 +85,11 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -106,10 +102,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/umbrel-install.sh b/install/umbrel-install.sh deleted file mode 100644 index d63ff40a..00000000 --- a/install/umbrel-install.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -cat >$DOCKER_CONFIG_PATH <<'EOF' -{ - "log-driver": "journald" -} -EOF - -msg_info "Installing Umbrel (Patience)" -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -fi -curl -sL https://umbrel.sh | bash &>/dev/null -systemctl daemon-reload -systemctl enable --now umbrel-startup.service &>/dev/null -msg_ok "Installed Umbrel" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 448920c3..3c0e217b 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -107,12 +103,11 @@ systemctl daemon-reload $STD systemctl enable --now umbrel-startup.service msg_ok "Installed Umbrel" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -125,10 +120,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean diff --git a/install/unifi-install.sh b/install/unifi-install.sh deleted file mode 100644 index da6e91fd..00000000 --- a/install/unifi-install.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -#https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -read -r -p "Local Controller? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - LOCAL="--local-controller" -else - LOCAL="" -fi - -msg_info "Installing UniFi Network Application (Patience)" -wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh --skip --add-repository $LOCAL &>/dev/null -msg_ok "Installed UniFi Network Application" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 80b4562d..afc4930a 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 YW=$(echo "\033[33m") @@ -10,26 +11,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -50,15 +43,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -75,7 +71,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -102,12 +98,11 @@ wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh $STD bash unifi-latest.sh --skip --add-repository $LOCAL msg_ok "Installed UniFi Network Application" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -120,10 +115,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh deleted file mode 100644 index d314ad3c..00000000 --- a/install/uptimekuma-install.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -sudo apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Uptime Kuma" -git clone https://github.com/louislam/uptime-kuma.git &>/dev/null -mv uptime-kuma /opt/uptime-kuma -cd /opt/uptime-kuma -npm run setup &>/dev/null -msg_ok "Installed Uptime Kuma" - -msg_info "Creating Service" -service_path="/etc/systemd/system/uptime-kuma.service" -echo "[Unit] -Description=uptime-kuma - -[Service] -Type=simple -Restart=always -User=root -WorkingDirectory=/opt/uptime-kuma -ExecStart=/usr/bin/npm start - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now uptime-kuma.service &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 29af2997..69baf541 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -122,12 +118,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now uptime-kuma.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -140,10 +135,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/vaultwarden-install.sh b/install/vaultwarden-install.sh deleted file mode 100644 index 0710c1ef..00000000 --- a/install/vaultwarden-install.sh +++ /dev/null @@ -1,204 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get update &>/dev/null -apt-get -qqy install \ - git \ - build-essential \ - pkgconf \ - libssl-dev \ - libmariadb-dev-compat \ - libpq-dev \ - curl \ - sudo &>/dev/null -msg_ok "Installed Dependencies" - -WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -msg_info "Installing Rust" -curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal &>/dev/null -echo 'export PATH=~/.cargo/bin:$PATH' >>~/.bashrc &>/dev/null -export PATH=~/.cargo/bin:$PATH &>/dev/null -which rustc &>/dev/null -msg_ok "Installed Rust" - -msg_info "Building Vaultwarden ${VAULT} (Patience)" -git clone https://github.com/dani-garcia/vaultwarden &>/dev/null -cd vaultwarden -cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null -msg_ok "Built Vaultwarden ${VAULT}" - -addgroup --system vaultwarden &>/dev/null -adduser --system --home /opt/vaultwarden --shell /usr/sbin/nologin --no-create-home --gecos 'vaultwarden' --ingroup vaultwarden --disabled-login --disabled-password vaultwarden &>/dev/null -mkdir -p /opt/vaultwarden/bin -mkdir -p /opt/vaultwarden/data -cp target/release/vaultwarden /opt/vaultwarden/bin/ - -msg_info "Downloading Web-Vault ${WEBVAULT}" -curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz &>/dev/null -tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ &>/dev/null -msg_ok "Downloaded Web-Vault ${WEBVAULT}" - -cat </opt/vaultwarden/.env -ADMIN_TOKEN=$(openssl rand -base64 48) -ROCKET_ADDRESS=0.0.0.0 -DATA_FOLDER=/opt/vaultwarden/data -DATABASE_MAX_CONNS=10 -WEB_VAULT_FOLDER=/opt/vaultwarden/web-vault -WEB_VAULT_ENABLED=true -EOF - -msg_info "Creating Service" -chown -R vaultwarden:vaultwarden /opt/vaultwarden/ -chown root:root /opt/vaultwarden/bin/vaultwarden -chmod +x /opt/vaultwarden/bin/vaultwarden -chown -R root:root /opt/vaultwarden/web-vault/ -chmod +r /opt/vaultwarden/.env -service_path="/etc/systemd/system/vaultwarden.service" &>/dev/null - -echo "[Unit] -Description=Bitwarden Server (Powered by Vaultwarden) -Documentation=https://github.com/dani-garcia/vaultwarden -After=network.target -[Service] -User=vaultwarden -Group=vaultwarden -EnvironmentFile=-/opt/vaultwarden/.env -ExecStart=/opt/vaultwarden/bin/vaultwarden -LimitNOFILE=65535 -LimitNPROC=4096 -PrivateTmp=true -PrivateDevices=true -ProtectHome=true -ProtectSystem=strict -DevicePolicy=closed -ProtectControlGroups=yes -ProtectKernelModules=yes -ProtectKernelTunables=yes -RestrictNamespaces=yes -RestrictRealtime=yes -MemoryDenyWriteExecute=yes -LockPersonality=yes -WorkingDirectory=/opt/vaultwarden -ReadWriteDirectories=/opt/vaultwarden/data -AmbientCapabilities=CAP_NET_BIND_SERVICE -[Install] -WantedBy=multi-user.target" >$service_path -systemctl daemon-reload -systemctl enable --now vaultwarden.service &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 4ad15ac4..aeaab763 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -179,12 +175,11 @@ systemctl daemon-reload $STD systemctl enable --now vaultwarden.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -197,10 +192,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 9cd11da7..1c037d5c 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -117,11 +113,11 @@ systemctl -q daemon-reload systemctl enable --now -q whisparr msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -134,10 +130,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm -rf Whisparr.develop.*.tar.gz diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh deleted file mode 100644 index 758ae265..00000000 --- a/install/whoogle-install.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Python3-pip" -apt-get install python3-pip -y &>/dev/null -msg_ok "Installed Python3-pip" - -msg_info "Installing Whoogle" -pip install brotli &>/dev/null -pip install whoogle-search &>/dev/null - -service_path="/etc/systemd/system/whoogle.service" -echo "[Unit] -Description=Whoogle-Search -After=network.target -[Service] -ExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0 -Restart=always -User=root -[Install] -WantedBy=multi-user.target" >$service_path - -systemctl enable --now whoogle.service &>/dev/null -msg_ok "Installed Whoogle" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 659b2d36..891c28c1 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -111,11 +107,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now whoogle.service msg_ok "Installed Whoogle" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -128,10 +124,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh deleted file mode 100644 index 947ddbab..00000000 --- a/install/wikijs-install.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -sL https://deb.nodesource.com/setup_16.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Wiki.js" -mkdir -p /opt/wikijs -cd /opt/wikijs -wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz &>/dev/null -tar xzf wiki-js.tar.gz -rm wiki-js.tar.gz - -cat </opt/wikijs/config.yml -bindIP: 0.0.0.0 -port: 3000 -db: - type: sqlite - storage: /opt/wikijs/db.sqlite -logLevel: info -logFormat: default -dataPath: /opt/wikijs/data -bodyParserLimit: 5mb -EOF -npm rebuild sqlite3 &>/dev/null -msg_ok "Installed Wiki.js" - -msg_info "Creating Service" -service_path="/etc/systemd/system/wikijs.service" - -echo "[Unit] -Description=Wiki.js -After=network.target - -[Service] -Type=simple -ExecStart=/usr/bin/node server -Restart=always -User=root -Environment=NODE_ENV=production -WorkingDirectory=/opt/wikijs - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now wikijs &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index b90beae5..5cbaeb91 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -139,11 +135,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now wikijs msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -156,10 +152,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh deleted file mode 100644 index b71dad3b..00000000 --- a/install/wireguard-install.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -OPTIONS_PATH='/options.conf' -cat >$OPTIONS_PATH <<'EOF' -IPv4dev=eth0 -install_user=root -VPN=wireguard -pivpnNET=10.6.0.0 -subnetClass=24 -ALLOWED_IPS="0.0.0.0/0, ::0/0" -pivpnMTU=1420 -pivpnPORT=51820 -pivpnDNS1=1.1.1.1 -pivpnDNS2=8.8.8.8 -pivpnHOST= -pivpnPERSISTENTKEEPALIVE=25 -UNATTUPG=1 -EOF - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y gunicorn &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing WireGuard (using pivpn.io)" -curl -s -L https://install.pivpn.io >install.sh -chmod +x install.sh -./install.sh --unattended options.conf &>/dev/null -msg_ok "Installed WireGuard" - -msg_info "Installing Python3-pip" -apt-get install python3-pip -y &>/dev/null -pip install flask &>/dev/null -pip install ifcfg &>/dev/null -pip install flask_qrcode &>/dev/null -pip install icmplib &>/dev/null -msg_ok "Installed Python3-pip" - -msg_info "Installing WGDashboard" -WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null -cd /etc/wgdashboard/src -sudo chmod u+x wgd.sh -sudo ./wgd.sh install &>/dev/null -sudo chmod -R 755 /etc/wireguard -msg_ok "Installed WGDashboard" - -msg_info "Creating Service" -service_path="/etc/systemd/system/wg-dashboard.service" -echo "[Unit] -After=netword.service - -[Service] -WorkingDirectory=/etc/wgdashboard/src -ExecStart=/usr/bin/python3 /etc/wgdashboard/src/dashboard.py -Restart=always - - -[Install] -WantedBy=default.target" >$service_path -sudo chmod 664 /etc/systemd/system/wg-dashboard.service -sudo systemctl daemon-reload -sudo systemctl enable wg-dashboard.service &>/dev/null -sudo systemctl start wg-dashboard.service -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 06d3cc3f..b7647b7b 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -111,12 +107,11 @@ msg_info "Installing WireGuard (using pivpn.io)" $STD bash <(curl -fsSL https://install.pivpn.io) --unattended options.conf msg_ok "Installed WireGuard" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -129,10 +124,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 02ec6fc8..2510ebc1 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -48,15 +41,18 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -73,7 +69,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -98,11 +94,11 @@ wget -q -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg $STD bash <(curl -fsSL https://install.yunohost.org) -a msg_ok "Installed YunoHost" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - chmod -x /etc/update-motd.d/* + OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -115,10 +111,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh deleted file mode 100644 index 38f70952..00000000 --- a/install/zigbee2mqtt-install.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y git &>/dev/null -apt-get install -y make &>/dev/null -apt-get install -y g++ &>/dev/null -apt-get install -y gcc &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -curl -fsSL https://deb.nodesource.com/setup_18.x | bash - &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Setting up Zigbee2MQTT Repository" -git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt &>/dev/null -msg_ok "Set up Zigbee2MQTT Repository" - -read -r -p "Switch to Edge/dev branch? (y/N) " prompt -if [[ $prompt == "y" ]]; then - DEV="y" -else - DEV="n" -fi - -msg_info "Installing Zigbee2MQTT" -cd /opt/zigbee2mqtt &>/dev/null -if [[ $DEV == "y" ]]; then - git checkout dev &>/dev/null -fi -npm ci &>/dev/null -msg_ok "Installed Zigbee2MQTT" - -msg_info "Creating Service" -service_path="/etc/systemd/system/zigbee2mqtt.service" -echo "[Unit] -Description=zigbee2mqtt -After=network.target -[Service] -Environment=NODE_ENV=production -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zigbee2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable zigbee2mqtt.service &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 8eae1c36..dfe49bdd 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -138,12 +134,11 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable zigbee2mqtt.service msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -156,10 +151,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh deleted file mode 100644 index a101ffe6..00000000 --- a/install/zwave-js-ui-install.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -NUM=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi -done -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -alias die='' -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' -set -e - -msg_info "Updating Container OS" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null -apt-get install -y unzip &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Installing Z-Wave JS UI" -mkdir /opt/zwave-js-ui -cd /opt/zwave-js-ui -RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -msg_ok "Installed Z-Wave JS UI" - -msg_info "Creating Service" -service_path="/etc/systemd/system/zwave-js-ui.service" -echo "[Unit] -Description=zwave-js-ui -Wants=network-online.target -After=network-online.target -[Service] -User=root -WorkingDirectory=/opt/zwave-js-ui -ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux -[Install] -WantedBy=multi-user.target" >$service_path -systemctl start zwave-js-ui -systemctl enable zwave-js-ui &>/dev/null -msg_ok "Created Service" - -PASS=$(grep -w "root" /etc/shadow | cut -b6) -echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then - msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi - -msg_info "Cleaning up" -rm zwave-js-ui-${RELEASE}-linux.zip -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 3ce383d8..63125469 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi +if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$VERBOSE" == "yes" ]; then set -x; fi if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -9,26 +10,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 -NUM=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { @@ -49,15 +42,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi echo 1>&2 -en "${CROSS}${RD} No Network! " sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" @@ -74,7 +70,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi alias die='EXIT=$? LINE=$LINENO error_exit' set -e @@ -114,12 +110,11 @@ systemctl start zwave-js-ui $STD systemctl enable zwave-js-ui msg_ok "Created Service" -PASS=$(grep -w "root" /etc/shadow | cut -b6) echo "export TERM='xterm-256color'" >>/root/.bashrc -if [[ $PASS != $ ]]; then +if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - rm /etc/motd - rm /etc/update-motd.d/10-uname +OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) +if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -132,10 +127,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -if [[ "${SSH_ROOT}" == "yes" ]]; then - sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd -fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" rm zwave-js-ui-${RELEASE}-linux.zip From 811ff7fd968af472341fcbf35b3e4cde9a416ea0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 08:40:46 -0500 Subject: [PATCH 4312/6505] remove residual error_exit (#1012) --- install/adguard-v5-install.sh | 2 -- install/audiobookshelf-v5-install.sh | 2 -- install/autobrr-v5-install.sh | 2 -- install/blocky-v5-install.sh | 2 -- install/casaos-v5-install.sh | 2 -- install/changedetection-v5-install.sh | 2 -- install/cronicle-v5-install.sh | 2 -- install/daemonsync-v5-install.sh | 2 -- install/dashy-v5-install.sh | 2 -- install/debian-v5-install.sh | 2 -- install/deconz-v5-install.sh | 2 -- install/deluge-v5-install.sh | 2 -- install/docker-v5-install.sh | 2 -- install/emby-v5-install.sh | 2 -- install/emqx-v5-install.sh | 2 -- install/esphome-v5-install.sh | 2 -- install/grafana-v5-install.sh | 2 -- install/grocy-v5-install.sh | 2 -- install/heimdalldashboard-v5-install.sh | 2 -- install/homeassistant-core-v5-install.sh | 2 -- install/homeassistant-v5-install.sh | 2 -- install/homebridge-v5-install.sh | 2 -- install/homepage-v5-install.sh | 2 -- install/homer-v5-install.sh | 2 -- install/hyperion-v5-install.sh | 2 -- install/influxdb-v5-install.sh | 2 -- install/iobroker-v5-install.sh | 2 -- install/jellyfin-v5-install.sh | 2 -- install/k0s-v5-install.sh | 2 -- install/kavita-v5-install.sh | 2 -- install/keycloak-v5-install.sh | 2 -- install/lidarr-v5-install.sh | 2 -- install/magicmirror-v5-install.sh | 2 -- install/mariadb-v5-install.sh | 2 -- install/meshcentral-v5-install.sh | 2 -- install/motioneye-v5-install.sh | 2 -- install/mqtt-v5-install.sh | 2 -- install/n8n-v5-install.sh | 2 -- install/navidrome-v5-install.sh | 2 -- install/nextcloudpi-v5-install.sh | 2 -- install/nginxproxymanager-v5-install.sh | 2 -- install/nocodb-v5-install.sh | 2 -- install/node-red-v5-install.sh | 2 -- install/omada-v5-install.sh | 2 -- install/omv-v5-install.sh | 2 -- install/openhab-v5-install.sh | 2 -- install/paperless-ngx-v5-install.sh | 2 -- install/photoprism-v5-install.sh | 2 -- install/pihole-v5-install.sh | 2 -- install/plex-v5-install.sh | 2 -- install/podman-homeassistant-v5-install.sh | 2 -- install/podman-v5-install.sh | 2 -- install/postgresql-v5-install.sh | 2 -- install/prometheus-v5-install.sh | 2 -- install/prowlarr-v5-install.sh | 2 -- install/radarr-v5-install.sh | 2 -- install/readarr-v5-install.sh | 2 -- install/sabnzbd-v5-install.sh | 2 -- install/scrypted-v5-install.sh | 2 -- install/shinobi-v5-install.sh | 2 -- install/sonarr-v5-install.sh | 2 -- install/syncthing-v5-install.sh | 2 -- install/tdarr-v5-install.sh | 2 -- install/technitiumdns-v5-install.sh | 2 -- install/transmission-v5-install.sh | 2 -- install/trilium-v5-install.sh | 2 -- install/ubuntu-v5-install.sh | 2 -- install/umbrel-v5-install.sh | 2 -- install/unifi-v5-install.sh | 2 -- install/uptimekuma-v5-install.sh | 2 -- install/vaultwarden-v5-install.sh | 2 -- install/whisparr-v5-install.sh | 2 -- install/whoogle-v5-install.sh | 2 -- install/wikijs-v5-install.sh | 2 -- install/wireguard-v5-install.sh | 2 -- install/yunohost-v5-install.sh | 2 -- install/zigbee2mqtt-v5-install.sh | 2 -- install/zwave-js-ui-v5-install.sh | 2 -- 78 files changed, 156 deletions(-) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 533c988a..e6fafaa3 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index e9086b57..fe7913ef 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 03a1d05c..478b01f8 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index b68882b1..dbabbbe7 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 013a9a46..6e0fea4c 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index f8b24983..da0f9854 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index d9c2aca7..4a9d95a1 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 04229094..82267d9a 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 84bc8eaa..bfec6f59 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 428fe812..df4d2093 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 1b4a59b3..e5794400 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 4d2c8e21..a6477102 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index fa8b1495..8ed83542 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 18d832f1..6d8a58fa 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index bcbae979..59245e2b 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index 433d8487..c3a74cd8 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index b695df32..b9386b4c 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index 34073ba0..d2f9ed40 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index ce1b5f75..39a569a6 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 1ca60ef6..6a8d6913 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index b6c63719..4a72aa7b 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 1bf8da31..3917de67 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 81bc069e..80dfab19 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index b7bbed3a..2f3bd736 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 82bf8084..e3af572d 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 6c16f851..de01f69f 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 9baddbb6..2905243b 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 9b06ea4c..dd56b60e 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index 8a8553ae..5b58883b 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index e7f41d47..2f5fec18 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 6fdf6051..44addad1 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index d32cf2af..aa4651aa 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 94db7430..5acc38b6 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -62,7 +62,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,7 +74,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 35d38926..441dc6e5 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index 825aaa00..b2c0027b 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 772149a2..298e719c 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 867fb2bb..ea8d8928 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index d72a9c2d..d3a6f6d4 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 519177bd..1fec13d1 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index fc3f7c74..ef24f03c 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index ae45c980..2bab1ba7 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index 340863f9..f282e40c 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index b9cb9bc9..b4568343 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 79fd4e5f..14cbcbe9 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 90623f7c..cfdd0173 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index ca7a23d9..e8174928 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 3eb5cb42..2d7f28fb 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -62,7 +62,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,7 +74,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 48584dcb..4a74f1e2 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -59,7 +59,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -72,7 +71,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index c1d93dd4..a9926604 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -59,7 +59,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -72,7 +71,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index b9a46f66..dbf48fdf 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 277afab7..f14550f6 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 98928d14..d1017251 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index bc14a5dc..13933399 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index faf3d67a..82e1c7d7 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 7fa6898b..8690a803 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 58f9c4a6..cca78868 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index d4586f0d..70fae8db 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index ccdf4923..2684a461 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index c55bfba2..00c6c76b 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 6a6c6d47..9f128f6d 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 4d397510..1e1ee7a3 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 770fdc90..ddfc4e9a 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 35167dfc..2ee6e6c5 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index a410e6cc..01679c67 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index db579d21..8616965a 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 4b266ec1..2fc7f477 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index ec35eb7f..71d85b05 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 3c0e217b..43bc7343 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index afc4930a..5691b0d1 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -59,7 +59,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -72,7 +71,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 69baf541..8121c67b 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index aeaab763..8ae80763 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 1c037d5c..351d1d60 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 891c28c1..8e1b6d48 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 5cbaeb91..de85bdf0 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index b7647b7b..c3860c5b 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e OPTIONS_PATH='/options.conf' diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 2510ebc1..d97a204a 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -57,7 +57,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -70,7 +69,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index dfe49bdd..131e0654 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 63125469..293d484c 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -58,7 +58,6 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -alias die='' if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -71,7 +70,6 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else fi RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -alias die='EXIT=$? LINE=$LINENO error_exit' set -e msg_info "Updating Container OS" From d8c2d6e257f6112473fc51933c18d6fed8c27e72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 10:16:51 -0500 Subject: [PATCH 4313/6505] remove old code --- ct/adguard-v5.sh | 1 - ct/alpine-v5.sh | 1 - ct/archlinux-v5.sh | 1 - ct/audiobookshelf-v5.sh | 1 - ct/autobrr-v5.sh | 1 - ct/blocky-v5.sh | 1 - ct/casaos-v5.sh | 1 - ct/changedetection-v5.sh | 1 - ct/cronicle-v5.sh | 1 - ct/daemonsync-v5.sh | 1 - ct/dashy-v5.sh | 1 - ct/debian-v5.sh | 1 - ct/deconz-v5.sh | 1 - ct/deluge-v5.sh | 1 - ct/docker-v5.sh | 1 - ct/emby-v5.sh | 1 - ct/emqx-v5.sh | 1 - ct/esphome-v5.sh | 1 - ct/grafana-v5.sh | 1 - ct/grocy-v5.sh | 1 - ct/heimdalldashboard-v5.sh | 1 - ct/homeassistant-core-v5.sh | 1 - ct/homeassistant-v5.sh | 1 - ct/homebridge-v5.sh | 1 - ct/homepage-v5.sh | 1 - ct/homer-v5.sh | 1 - ct/hyperion-v5.sh | 1 - ct/influxdb-v5.sh | 1 - ct/iobroker-v5.sh | 1 - ct/jellyfin-v5.sh | 1 - ct/k0s-v5.sh | 1 - ct/kavita-v5.sh | 1 - ct/keycloak-v5.sh | 1 - ct/lidarr-v5.sh | 1 - ct/magicmirror-v5.sh | 1 - ct/mariadb-v5.sh | 1 - ct/meshcentral-v5.sh | 1 - ct/motioneye-v5.sh | 1 - ct/mqtt-v5.sh | 1 - ct/n8n-v5.sh | 1 - ct/navidrome-v5.sh | 1 - ct/nextcloudpi-v5.sh | 1 - ct/nginxproxymanager-v5.sh | 1 - ct/nocodb-v5.sh | 1 - ct/node-red-v5.sh | 1 - ct/omada-v5.sh | 1 - ct/omv-v5.sh | 1 - ct/openhab-v5.sh | 1 - ct/paperless-ngx-v5.sh | 1 - ct/photoprism-v5.sh | 1 - ct/pihole-v5.sh | 1 - ct/plex-v5.sh | 1 - ct/podman-homeassistant-v5.sh | 1 - ct/podman-v5.sh | 1 - ct/postgresql-v5.sh | 1 - ct/prometheus-v5.sh | 1 - ct/prowlarr-v5.sh | 1 - ct/radarr-v5.sh | 1 - ct/readarr-v5.sh | 1 - ct/rockylinux-v5.sh | 1 - ct/sabnzbd-v5.sh | 1 - ct/scrypted-v5.sh | 1 - ct/shinobi-v5.sh | 1 - ct/sonarr-v5.sh | 1 - ct/syncthing-v5.sh | 1 - ct/tdarr-v5.sh | 1 - ct/technitiumdns-v5.sh | 1 - ct/transmission-v5.sh | 1 - ct/trilium-v5.sh | 1 - ct/ubuntu-v5.sh | 1 - ct/umbrel-v5.sh | 1 - ct/unifi-v5.sh | 1 - ct/uptimekuma-v5.sh | 1 - ct/vaultwarden-v5.sh | 1 - ct/whisparr-v5.sh | 1 - ct/whoogle-v5.sh | 1 - ct/wikijs-v5.sh | 1 - ct/wireguard-v5.sh | 1 - ct/yunohost-v5.sh | 1 - ct/zigbee2mqtt-v5.sh | 1 - ct/zwave-js-ui-v5.sh | 1 - 81 files changed, 81 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 9cec3c16..6e424c6a 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -305,7 +305,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 38ffc8c7..d94a9c33 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -303,7 +303,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index 8e424a66..a59e2a5a 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 86199f22..bac2131c 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index fa31ef71..942565ac 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -305,7 +305,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index efe66ff7..a18faaef 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index bb901bca..c40fcac5 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -315,7 +315,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 13afb78e..632c8c9f 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index bf0495e1..6d5b478c 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -304,7 +304,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 401086bb..f170a688 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 069b8ee1..7f168215 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 9fae150f..8abd935b 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 8368ce39..24296217 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index 93fde875..22b90ad3 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -303,7 +303,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 5d4b2eb2..dd21a81e 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -314,7 +314,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index fb1392ac..6808f1ff 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -315,7 +315,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 5f0aaa9a..3313c436 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index b0a51c9c..f4b4f117 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 38514eed..0c349d10 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 64a58fe6..49a71f40 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 4dcc78d0..0aac7e41 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 769a6f1a..8f588766 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -308,7 +308,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 49de18fd..35a5c1c7 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -317,7 +317,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 95297599..8b6028ba 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 555343bc..4eee8fd5 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 494b0b7c..05700b71 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 2ae540da..c419e8b4 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 053feb3e..08687ce2 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 6d022ee3..ce7d81cb 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index ec315a7c..682cf962 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -317,7 +317,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 6a4281a7..90734371 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index 0267f0a9..2ffed10a 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -305,7 +305,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 85b170e2..149cf054 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 1a11e0d7..5f2bea43 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 8fb8eef7..748e92dd 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 3ad4ae5a..60febdd9 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 825c5a55..bc150f17 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 4d8d82a2..bd05d8d3 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 5a4e9351..d6586750 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -304,7 +304,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index a1fa02ad..06519242 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 1f38d743..d440e7e5 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index e77c3b4a..da10e525 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 237ee263..34effe2b 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index e06cdc12..2bbdc9ba 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index cc5720ed..47d50c74 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 35861b21..72768f0e 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -315,7 +315,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 8406e00a..3c82ce9f 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index a1d4a601..bd75f853 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index d014671b..ac926ebb 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 2c7042d6..46acf01c 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -305,7 +305,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 989bd0de..dfcfd8af 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index f7dc89a0..32e66dd6 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -316,7 +316,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 711ae8f8..702a2d74 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -310,7 +310,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 325d7268..e61101f8 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index 3a00762f..aa1b8325 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index a11c6e8e..05122e98 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index 5d73e435..8e3bd733 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index e453cd1a..8a9ab6fc 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 39092a64..63cf74e1 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index 992902d1..ec0975b8 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 6edfd424..65399620 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 97f0bedf..33a22311 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 9e9943b7..190d3df6 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -315,7 +315,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index f0ddd2bc..7925af27 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index cc8c498e..9007943a 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 16fee7d4..9ff7e671 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index d9f0cc23..5e395c27 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index 9c040e3e..622406d8 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 09e8bf47..b71cb766 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 938f771a..7b62d7cd 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -311,7 +311,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 6d421a09..80375583 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -315,7 +315,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 87ec5d1f..8a7aa4f1 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index b08413ed..4e852dd0 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 87ebde7d..ab1d0fb6 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index eb983253..900cc60e 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -303,7 +303,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index e39ecff8..c858ecb8 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index db50b8e9..b151cd13 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 78d35fa2..52ed54a5 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index f60795d2..2ba9a1aa 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -302,7 +302,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index ad1d2455..23badce2 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -307,7 +307,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index da1e45c8..75152cca 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -306,7 +306,6 @@ function advanced_settings() { if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" VERB="yes" - VERB2="" else echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" From 5238dd8b24a404f56c644408ab41ea6260154572 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 10:49:24 -0500 Subject: [PATCH 4314/6505] Update create_lxc.sh --- ct/create_lxc.sh | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index f6071c13..0eadaf9c 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -59,7 +59,7 @@ function select_storage() { CONTENT='vztmpl' CONTENT_LABEL='Container template' ;; - *) false || die "Invalid storage class." ;; + *) false;; esac local -a MENU @@ -83,21 +83,20 @@ function select_storage() { STORAGE=$(whiptail --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "${MENU[@]}" 3>&1 1>&2 2>&3)" done printf $STORAGE fi } -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." -[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." +[[ "${CTID:-}" ]] +[[ "${PCT_OSTYPE:-}" ]] -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." +[ "$CTID" -ge "100" ] if pct status $CTID &>/dev/null; then echo -e "ID '$CTID' is already in use." unset CTID - die "Cannot use ID that is already in use." fi TEMPLATE_STORAGE=$(select_storage template) || exit @@ -112,13 +111,12 @@ msg_ok "Updated LXC Template List" TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +[ ${#TEMPLATES[@]} -gt 0 ] TEMPLATE="${TEMPLATES[-1]}" if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_info "Downloading LXC Template" - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null msg_ok "Downloaded LXC Template" fi @@ -129,6 +127,5 @@ PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) [[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) msg_info "Creating LXC Container" -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created." From c0ab2d5e0a823fb91d5041e8b574a9e6e839c08c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 10:53:08 -0500 Subject: [PATCH 4315/6505] Update create_lxc.sh --- ct/create_lxc.sh | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 0eadaf9c..c0af30d9 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -36,14 +36,21 @@ if [ -z "$VALIDTMP" ]; then exit 1 fi -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + exit $EXIT } function select_storage() { @@ -59,7 +66,7 @@ function select_storage() { CONTENT='vztmpl' CONTENT_LABEL='Container template' ;; - *) false;; + *) false || die "Invalid storage class." ;; esac local -a MENU @@ -83,20 +90,21 @@ function select_storage() { STORAGE=$(whiptail --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3)" + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi } -[[ "${CTID:-}" ]] -[[ "${PCT_OSTYPE:-}" ]] +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." +[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." -[ "$CTID" -ge "100" ] +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." if pct status $CTID &>/dev/null; then echo -e "ID '$CTID' is already in use." unset CTID + die "Cannot use ID that is already in use." fi TEMPLATE_STORAGE=$(select_storage template) || exit @@ -111,12 +119,13 @@ msg_ok "Updated LXC Template List" TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." TEMPLATE="${TEMPLATES[-1]}" if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_info "Downloading LXC Template" - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." msg_ok "Downloaded LXC Template" fi @@ -127,5 +136,6 @@ PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) [[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) msg_info "Creating LXC Container" -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created." From ca7ee8519e53bfd1d8af55ad42eb85398097cc8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 11:41:12 -0500 Subject: [PATCH 4316/6505] Update create_lxc.sh add new error_handler --- ct/create_lxc.sh | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index c0af30d9..ecb62d96 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -9,7 +9,15 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" - +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -36,23 +44,6 @@ if [ -z "$VALIDTMP" ]; then exit 1 fi -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - function select_storage() { local CLASS=$1 local CONTENT @@ -66,7 +57,7 @@ function select_storage() { CONTENT='vztmpl' CONTENT_LABEL='Container template' ;; - *) false || die "Invalid storage class." ;; + *) false || exit "Invalid storage class." ;; esac local -a MENU @@ -90,21 +81,21 @@ function select_storage() { STORAGE=$(whiptail --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "${MENU[@]}" 3>&1 1>&2 2>&3) || exit "Menu aborted." done printf $STORAGE fi } -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." -[[ "${PCT_OSTYPE:-}" ]] || die "You need to set 'PCT_OSTYPE' variable." +[[ "${CTID:-}" ]] || exit "You need to set 'CTID' variable." +[[ "${PCT_OSTYPE:-}" ]] || exit "You need to set 'PCT_OSTYPE' variable." -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." +[ "$CTID" -ge "100" ] || exit "ID cannot be less than 100." if pct status $CTID &>/dev/null; then echo -e "ID '$CTID' is already in use." unset CTID - die "Cannot use ID that is already in use." + exit "Cannot use ID that is already in use." fi TEMPLATE_STORAGE=$(select_storage template) || exit @@ -119,13 +110,13 @@ msg_ok "Updated LXC Template List" TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +[ ${#TEMPLATES[@]} -gt 0 ] || exit "Unable to find a template when searching for '$TEMPLATE_SEARCH'." TEMPLATE="${TEMPLATES[-1]}" if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_info "Downloading LXC Template" pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." + exit "A problem occured while downloading the LXC template." msg_ok "Downloaded LXC Template" fi @@ -137,5 +128,5 @@ PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) msg_info "Creating LXC Container" pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." + exit "A problem occured while trying to create container." msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created." From bb63e91f32fe7bdb339b2d39b867bd44c7b69d1c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 11:47:41 -0500 Subject: [PATCH 4317/6505] Update magicmirror-v5-install.sh add error_handler --- install/magicmirror-v5-install.sh | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 5acc38b6..7fad5c70 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -14,21 +14,14 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { From 08efe3585028a3bc6897ee043b31968342f0d1ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 11:49:04 -0500 Subject: [PATCH 4318/6505] Update paperless-ngx-v5-install.sh add error_handler --- install/paperless-ngx-v5-install.sh | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 2d7f28fb..c32d5362 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -14,21 +14,14 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" } function msg_info() { From b2da4b0cd215ec9fb04eaa4b551ca988d789e534 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 17:39:18 -0500 Subject: [PATCH 4319/6505] Update zigbee2mqtt-v5.sh - Revise the update process so that if the `git pull` fails, it will execute `git stash` followed by `git pull`. - Keep the update process verbose. --- ct/zigbee2mqtt-v5.sh | 69 +++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 23badce2..d1e2b82c 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -335,40 +335,57 @@ function update_script() { clear header_info cd /opt/zigbee2mqtt -msg_info "Checking for Backup Directory" +#!/bin/bash + +stop_zigbee2mqtt() { + if which systemctl 2> /dev/null > /dev/null; then + echo "Shutting down Zigbee2MQTT..." + sudo systemctl stop zigbee2mqtt + else + echo "Skipped stopping Zigbee2MQTT, no systemctl found" + fi +} + +start_zigbee2mqtt() { + if which systemctl 2> /dev/null > /dev/null; then + echo "Starting Zigbee2MQTT..." + sudo systemctl start zigbee2mqtt + else + echo "Skipped starting Zigbee2MQTT, no systemctl found" + fi +} + +set -e + if [ -d data-backup ]; then - echo "ERROR: Backup directory exists. May be previous restoring was failed?" - echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later." - echo "2. Manually delete 'data-backup' dir and try again." - exit 1 + echo "ERROR: Backup directory exists. May be previous restoring was failed?" + echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later." + echo "2. Manually delete 'data-backup' dir and try again." + exit 1 fi -msg_ok "No Backup Directory Exists" -msg_info "Stopping Zigbee2MQTT" -systemctl stop zigbee2mqtt -msg_ok "Stopped Zigbee2MQTT" +stop_zigbee2mqtt -msg_info "Creating Backup of Configuration" -cp -R data data-backup -msg_ok "Created Backup of Configuration" +echo "Creating backup of configuration..." +cp -R data data-backup || { echo "Failed to create backup."; exit 1; } -msg_info "Updating Zigbee2MQTT" -git pull &>/dev/null -msg_ok "Updated Zigbee2MQTT" +echo "Initiating update" +if ! git pull; then + echo "Update failed, temporarily storing changes and trying again." + git stash && git pull || (echo "Update failed even after storing changes. Aborting."; exit 1) +fi -msg_info "Installing Dependencies" -npm ci &>/dev/null -msg_ok "Installed Dependencies" +echo "Acquiring necessary components..." +npm ci || { echo "Failed to install necessary components."; exit 1; } -msg_info "Restoring Configuration" -cp -R data-backup/* data -rm -rf data-backup -msg_ok "Restored Configuration" +echo "Restoring configuration..." +cp -R data-backup/* data || { echo "Failed to restore configuration."; exit 1; } -msg_info "Starting Zigbee2MQTT" -systemctl start zigbee2mqtt -msg_ok "Started Zigbee2MQTT" -msg_ok "Update Successful" +rm -rf data-backup || { echo "Failed to remove backup directory."; exit 1; } + +start_zigbee2mqtt + +echo "Done!" exit } clear From 9494cffd986f25dc6423fb01e1360736cc7fe21b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 17:41:45 -0500 Subject: [PATCH 4320/6505] Update zigbee2mqtt-v5.sh --- ct/zigbee2mqtt-v5.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index d1e2b82c..5c2e943c 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -335,7 +335,6 @@ function update_script() { clear header_info cd /opt/zigbee2mqtt -#!/bin/bash stop_zigbee2mqtt() { if which systemctl 2> /dev/null > /dev/null; then From a5b50d9d451edf48fd0535230e84e5c1fe497d93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Feb 2023 17:53:17 -0500 Subject: [PATCH 4321/6505] Update zigbee2mqtt-v5.sh --- ct/zigbee2mqtt-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 5c2e943c..dbde6937 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -365,7 +365,7 @@ fi stop_zigbee2mqtt -echo "Creating backup of configuration..." +echo "Generating a backup of the configuration..." cp -R data data-backup || { echo "Failed to create backup."; exit 1; } echo "Initiating update" From 351161bc835e9f96b38508acf054d977e02af944 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 Feb 2023 09:40:27 -0500 Subject: [PATCH 4322/6505] add rm options --- install/adguard-v5-install.sh | 2 +- install/audiobookshelf-v5-install.sh | 2 +- install/autobrr-v5-install.sh | 2 +- install/blocky-v5-install.sh | 2 +- install/casaos-v5-install.sh | 2 +- install/changedetection-v5-install.sh | 2 +- install/cronicle-v5-install.sh | 2 +- install/daemonsync-v5-install.sh | 2 +- install/dashy-v5-install.sh | 2 +- install/debian-v5-install.sh | 2 +- install/deconz-v5-install.sh | 2 +- install/deluge-v5-install.sh | 2 +- install/docker-v5-install.sh | 2 +- install/emby-v5-install.sh | 2 +- install/emqx-v5-install.sh | 2 +- install/esphome-v5-install.sh | 2 +- install/grafana-v5-install.sh | 2 +- install/grocy-v5-install.sh | 2 +- install/heimdalldashboard-v5-install.sh | 2 +- install/homeassistant-core-v5-install.sh | 2 +- install/homeassistant-v5-install.sh | 2 +- install/homebridge-v5-install.sh | 2 +- install/homepage-v5-install.sh | 2 +- install/homer-v5-install.sh | 2 +- install/hyperion-v5-install.sh | 2 +- install/influxdb-v5-install.sh | 2 +- install/iobroker-v5-install.sh | 2 +- install/jellyfin-v5-install.sh | 2 +- install/k0s-v5-install.sh | 2 +- install/kavita-v5-install.sh | 2 +- install/keycloak-v5-install.sh | 2 +- install/lidarr-v5-install.sh | 2 +- install/magicmirror-v5-install.sh | 2 +- install/mariadb-v5-install.sh | 2 +- install/meshcentral-v5-install.sh | 2 +- install/motioneye-v5-install.sh | 2 +- install/mqtt-v5-install.sh | 2 +- install/n8n-v5-install.sh | 2 +- install/navidrome-v5-install.sh | 2 +- install/nextcloudpi-v5-install.sh | 2 +- install/nginxproxymanager-v5-install.sh | 2 +- install/nocodb-v5-install.sh | 2 +- install/node-red-v5-install.sh | 2 +- install/omada-v5-install.sh | 2 +- install/omv-v5-install.sh | 2 +- install/openhab-v5-install.sh | 2 +- install/paperless-ngx-v5-install.sh | 2 +- install/photoprism-v5-install.sh | 2 +- install/pihole-v5-install.sh | 2 +- install/plex-v5-install.sh | 2 +- install/podman-homeassistant-v5-install.sh | 2 +- install/podman-v5-install.sh | 2 +- install/postgresql-v5-install.sh | 2 +- install/prometheus-v5-install.sh | 2 +- install/prowlarr-v5-install.sh | 2 +- install/radarr-v5-install.sh | 2 +- install/readarr-v5-install.sh | 2 +- install/sabnzbd-v5-install.sh | 2 +- install/scrypted-v5-install.sh | 2 +- install/shinobi-v5-install.sh | 2 +- install/sonarr-v5-install.sh | 2 +- install/syncthing-v5-install.sh | 2 +- install/tdarr-v5-install.sh | 2 +- install/technitiumdns-v5-install.sh | 2 +- install/transmission-v5-install.sh | 2 +- install/trilium-v5-install.sh | 2 +- install/ubuntu-v5-install.sh | 2 +- install/umbrel-v5-install.sh | 2 +- install/unifi-v5-install.sh | 2 +- install/uptimekuma-v5-install.sh | 2 +- install/vaultwarden-v5-install.sh | 2 +- install/whisparr-v5-install.sh | 2 +- install/whoogle-v5-install.sh | 2 +- install/wikijs-v5-install.sh | 2 +- install/wireguard-v5-install.sh | 2 +- install/yunohost-v5-install.sh | 2 +- install/zigbee2mqtt-v5-install.sh | 2 +- install/zwave-js-ui-v5-install.sh | 2 +- 78 files changed, 78 insertions(+), 78 deletions(-) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index e6fafaa3..73cb6aba 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -96,7 +96,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index fe7913ef..3fbd4fc5 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -94,7 +94,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 478b01f8..98e9e22f 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -115,7 +115,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index dbabbbe7..2f2fe7f0 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -348,7 +348,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 6e0fea4c..1b68b8b7 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -104,7 +104,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index da0f9854..219298ac 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -108,7 +108,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 4a9d95a1..69a5d798 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -114,7 +114,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 82267d9a..a7ee8c29 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -93,7 +93,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index bfec6f59..dd2eee90 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -124,7 +124,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index df4d2093..176fe03b 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -86,7 +86,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index e5794400..4a4cfe2b 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -117,7 +117,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index a6477102..618c18ad 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -131,7 +131,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 8ed83542..1a79204c 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -148,7 +148,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 6d8a58fa..caed417c 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -107,7 +107,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 59245e2b..5067c515 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -92,7 +92,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index c3a74cd8..e899e86a 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -113,7 +113,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index b9386b4c..87f02d1b 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -100,7 +100,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index d2f9ed40..b0945f6f 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -130,7 +130,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index 39a569a6..04bde39e 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -124,7 +124,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 6a8d6913..c4d90f2b 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -166,7 +166,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index 4a72aa7b..47e8a5f1 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -151,7 +151,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 3917de67..3ca4c619 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -103,7 +103,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 80dfab19..e7564d29 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -123,7 +123,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 2f3bd736..1bea0313 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -112,7 +112,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index e3af572d..5acf9f93 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -97,7 +97,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index de01f69f..85a9ec8d 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -126,7 +126,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 2905243b..c4539140 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -91,7 +91,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index dd56b60e..6da83f15 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -131,7 +131,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index 5b58883b..315983d1 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -107,7 +107,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 2f5fec18..f197b02b 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -113,7 +113,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 44addad1..3f57e98c 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -110,7 +110,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index aa4651aa..d6808aff 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -117,7 +117,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 7fad5c70..62e0377c 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -212,7 +212,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 441dc6e5..f00046a7 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -108,7 +108,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index b2c0027b..458c458e 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -102,7 +102,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 298e719c..e93a6a46 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -121,7 +121,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index ea8d8928..08cd9055 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -98,7 +98,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index d3a6f6d4..84207276 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -113,7 +113,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 1fec13d1..5f0b0f45 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -141,7 +141,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index ef24f03c..47ce3060 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -93,7 +93,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 2bab1ba7..a128a729 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -245,7 +245,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index f282e40c..6f92515c 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -120,7 +120,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index b4568343..f114216b 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -123,7 +123,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 14cbcbe9..347eec82 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -97,7 +97,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index cfdd0173..3a72d385 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -109,7 +109,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index e8174928..cf21a733 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -108,7 +108,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index c32d5362..e60e617a 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -262,7 +262,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 4a74f1e2..c61d4dec 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -181,7 +181,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index a9926604..21637402 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -114,7 +114,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index dbf48fdf..2fa7638d 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -111,7 +111,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index f14550f6..b54fdd82 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -113,7 +113,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index d1017251..952fa9c3 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -92,7 +92,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 13933399..897fb1c1 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -215,7 +215,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 82e1c7d7..c3ebcdff 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -122,7 +122,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 8690a803..dc9fd918 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -115,7 +115,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index cca78868..3e2b2c51 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -115,7 +115,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index 70fae8db..5df38948 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -115,7 +115,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 2684a461..15384772 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -120,7 +120,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 00c6c76b..b557a38f 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -180,7 +180,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 9f128f6d..f36b68c5 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -149,7 +149,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 1e1ee7a3..697514d7 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -96,7 +96,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index ddfc4e9a..b7f63b24 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -99,7 +99,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 2ee6e6c5..8e6f50f0 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -142,7 +142,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 01679c67..fb052087 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -94,7 +94,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index 8616965a..2e73fc17 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -94,7 +94,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 2fc7f477..3d6f2598 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -116,7 +116,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 71d85b05..b48ba885 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -87,7 +87,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 43bc7343..b447635c 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -105,7 +105,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 5691b0d1..b75f3bba 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -100,7 +100,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 8121c67b..9148e80e 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -120,7 +120,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 8ae80763..6cc0f029 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -177,7 +177,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 351d1d60..2ffa248d 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -115,7 +115,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 8e1b6d48..e9d8f72d 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -109,7 +109,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index de85bdf0..5defd0dd 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -137,7 +137,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index c3860c5b..6e5d8464 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -109,7 +109,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index d97a204a..769e07be 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -96,7 +96,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 131e0654..7f778003 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -136,7 +136,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 293d484c..973ef4c2 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -112,7 +112,7 @@ echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) From d54683396e89902a8ccf41b54f30aeb4403d855d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 Feb 2023 12:47:47 -0500 Subject: [PATCH 4323/6505] use PCT_OSTYPE instead of redefining OS (#1018) --- install/adguard-v5-install.sh | 3 +-- install/audiobookshelf-v5-install.sh | 3 +-- install/autobrr-v5-install.sh | 3 +-- install/blocky-v5-install.sh | 3 +-- install/casaos-v5-install.sh | 3 +-- install/changedetection-v5-install.sh | 3 +-- install/cronicle-v5-install.sh | 3 +-- install/daemonsync-v5-install.sh | 3 +-- install/dashy-v5-install.sh | 3 +-- install/debian-v5-install.sh | 3 +-- install/deconz-v5-install.sh | 3 +-- install/deluge-v5-install.sh | 3 +-- install/docker-v5-install.sh | 3 +-- install/emby-v5-install.sh | 3 +-- install/emqx-v5-install.sh | 3 +-- install/esphome-v5-install.sh | 3 +-- install/grafana-v5-install.sh | 3 +-- install/grocy-v5-install.sh | 3 +-- install/heimdalldashboard-v5-install.sh | 3 +-- install/homeassistant-core-v5-install.sh | 3 +-- install/homeassistant-v5-install.sh | 3 +-- install/homebridge-v5-install.sh | 3 +-- install/homepage-v5-install.sh | 3 +-- install/homer-v5-install.sh | 3 +-- install/hyperion-v5-install.sh | 3 +-- install/influxdb-v5-install.sh | 3 +-- install/iobroker-v5-install.sh | 3 +-- install/jellyfin-v5-install.sh | 3 +-- install/k0s-v5-install.sh | 3 +-- install/kavita-v5-install.sh | 3 +-- install/keycloak-v5-install.sh | 3 +-- install/lidarr-v5-install.sh | 3 +-- install/magicmirror-v5-install.sh | 5 ++--- install/mariadb-v5-install.sh | 3 +-- install/meshcentral-v5-install.sh | 3 +-- install/motioneye-v5-install.sh | 3 +-- install/mqtt-v5-install.sh | 3 +-- install/n8n-v5-install.sh | 3 +-- install/navidrome-v5-install.sh | 3 +-- install/nextcloudpi-v5-install.sh | 3 +-- install/nginxproxymanager-v5-install.sh | 3 +-- install/nocodb-v5-install.sh | 3 +-- install/node-red-v5-install.sh | 3 +-- install/omada-v5-install.sh | 3 +-- install/omv-v5-install.sh | 3 +-- install/openhab-v5-install.sh | 3 +-- install/paperless-ngx-v5-install.sh | 5 ++--- install/photoprism-v5-install.sh | 3 +-- install/pihole-v5-install.sh | 3 +-- install/plex-v5-install.sh | 3 +-- install/podman-homeassistant-v5-install.sh | 3 +-- install/podman-v5-install.sh | 3 +-- install/postgresql-v5-install.sh | 3 +-- install/prometheus-v5-install.sh | 3 +-- install/prowlarr-v5-install.sh | 3 +-- install/radarr-v5-install.sh | 3 +-- install/readarr-v5-install.sh | 3 +-- install/sabnzbd-v5-install.sh | 3 +-- install/scrypted-v5-install.sh | 3 +-- install/shinobi-v5-install.sh | 3 +-- install/sonarr-v5-install.sh | 3 +-- install/syncthing-v5-install.sh | 3 +-- install/tdarr-v5-install.sh | 3 +-- install/technitiumdns-v5-install.sh | 3 +-- install/transmission-v5-install.sh | 3 +-- install/trilium-v5-install.sh | 3 +-- install/ubuntu-v5-install.sh | 3 +-- install/umbrel-v5-install.sh | 3 +-- install/unifi-v5-install.sh | 3 +-- install/uptimekuma-v5-install.sh | 3 +-- install/vaultwarden-v5-install.sh | 3 +-- install/whisparr-v5-install.sh | 3 +-- install/whoogle-v5-install.sh | 3 +-- install/wikijs-v5-install.sh | 3 +-- install/wireguard-v5-install.sh | 3 +-- install/yunohost-v5-install.sh | 3 +-- install/zigbee2mqtt-v5-install.sh | 3 +-- install/zwave-js-ui-v5-install.sh | 3 +-- misc/update-lxcs.sh | 2 +- 79 files changed, 81 insertions(+), 159 deletions(-) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 73cb6aba..927412d4 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -95,8 +95,7 @@ msg_ok "Installed AdGuard Home" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index 3fbd4fc5..c5ea736a 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -93,8 +93,7 @@ msg_ok "Installed audiobookshelf" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 98e9e22f..61b2eb45 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -114,8 +114,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index 2f2fe7f0..51f1e601 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -347,8 +347,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 1b68b8b7..4825c26f 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -103,8 +103,7 @@ msg_ok "Installed CasaOS" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index 219298ac..fbe2e18d 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -107,8 +107,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 69a5d798..fb845084 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -113,8 +113,7 @@ msg_ok "Installed Cronicle Primary Server" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index a7ee8c29..ea43bc98 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -92,8 +92,7 @@ msg_ok "Installed Daemon Sync Server" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index dd2eee90..e876c39f 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -123,8 +123,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 176fe03b..d15f4d0c 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -85,8 +85,7 @@ msg_ok "Installed Dependencies" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 4a4cfe2b..3e9973df 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -116,8 +116,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 618c18ad..1dc55656 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -130,8 +130,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 1a79204c..5eed9309 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -147,8 +147,7 @@ fi echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index caed417c..c23deef0 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -106,8 +106,7 @@ msg_ok "Installed Emby" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 5067c515..5a4cab70 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -91,8 +91,7 @@ msg_ok "Installed EMQX" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index e899e86a..00366388 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -112,8 +112,7 @@ msg_ok "Installed ESPHome Dashboard" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 87f02d1b..3827d1b0 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -99,8 +99,7 @@ msg_ok "Installed Grafana" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index b0945f6f..344ea7ce 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -129,8 +129,7 @@ msg_ok "Installed grocy" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index 04bde39e..351df94b 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -123,8 +123,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index c4d90f2b..14c6d0e6 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -165,8 +165,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index 47e8a5f1..e1213501 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -150,8 +150,7 @@ msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 3ca4c619..a966c54b 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -102,8 +102,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index e7564d29..2cd61caa 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -122,8 +122,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 1bea0313..5c0358ce 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -111,8 +111,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 5acf9f93..589297a0 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -96,8 +96,7 @@ msg_ok "Installed Hyperion" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 85a9ec8d..f623b20d 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -125,8 +125,7 @@ fi echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index c4539140..0c9499cf 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -90,8 +90,7 @@ msg_ok "Installed ioBroker" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 6da83f15..e8f0f73b 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -130,8 +130,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index 315983d1..c9adae82 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -106,8 +106,7 @@ fi echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index f197b02b..0b5b6711 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -112,8 +112,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 3f57e98c..19407187 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -109,8 +109,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index d6808aff..4eaaa2e8 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -116,8 +116,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 62e0377c..fa57fd6e 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -210,9 +210,8 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi + msg_info "Customizing Container" +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index f00046a7..37829a43 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -107,8 +107,7 @@ fi echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index 458c458e..d172d37e 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -101,8 +101,7 @@ msg_ok "Installed MeshCentral" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index e93a6a46..f0d91b0e 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -120,8 +120,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 08cd9055..4b2c7047 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -97,8 +97,7 @@ msg_ok "Installed Mosquitto MQTT Broker" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 84207276..e11671e6 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -112,8 +112,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 5f0b0f45..5f3804f0 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -140,8 +140,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 47ce3060..0d01c01e 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -92,8 +92,7 @@ msg_ok "Installed NextCloudPi" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index a128a729..d585a660 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -244,8 +244,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index 6f92515c..f56b68c5 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -119,8 +119,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index f114216b..02686163 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -122,8 +122,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 347eec82..26428b02 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -96,8 +96,7 @@ msg_ok "Installed Omada Controller" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 3a72d385..d5b06587 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -108,8 +108,7 @@ msg_ok "Installed OpenMediaVault" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index cf21a733..b57f9edf 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -107,8 +107,7 @@ msg_ok "Installed openHAB" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index e60e617a..1d09ae89 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -260,9 +260,8 @@ msg_ok "Created Services" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi + msg_info "Customizing Container" +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index c61d4dec..66b62c0b 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -180,8 +180,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 21637402..848d9cb1 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -113,8 +113,7 @@ msg_ok "Installed Pi-hole" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 2fa7638d..bbd76a96 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -110,8 +110,7 @@ msg_ok "Installed Plex Media Server" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index b54fdd82..5a93e042 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -112,8 +112,7 @@ msg_ok "Installed Home Assistant" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 952fa9c3..7e75b6f9 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -91,8 +91,7 @@ msg_ok "Installed Podman" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 897fb1c1..8877f2e4 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -214,8 +214,7 @@ fi echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index c3ebcdff..357a2229 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -121,8 +121,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index dc9fd918..7ca5434b 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -114,8 +114,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 3e2b2c51..85a47c29 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -114,8 +114,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index 5df38948..6554d377 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -114,8 +114,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 15384772..ccf74909 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -119,8 +119,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index b557a38f..fd84cc49 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -179,8 +179,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index f36b68c5..76d2b9b0 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -148,8 +148,7 @@ msg_ok "Installed Shinobi" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 697514d7..96dca52d 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -95,8 +95,7 @@ msg_ok "Installed Sonarr" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index b7f63b24..8e6812b7 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -98,8 +98,7 @@ msg_ok "Installed Syncthing" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 8e6f50f0..e13a2f94 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -141,8 +141,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index fb052087..0ad64b31 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -93,8 +93,7 @@ msg_ok "Installed Technitium DNS" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index 2e73fc17..f56dff91 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -93,8 +93,7 @@ msg_ok "Installed Transmission" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 3d6f2598..e93f13f1 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -115,8 +115,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index b48ba885..539076f0 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -86,8 +86,7 @@ msg_ok "Installed Dependencies" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index b447635c..ee5469cf 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -104,8 +104,7 @@ msg_ok "Installed Umbrel" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index b75f3bba..3f105891 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -99,8 +99,7 @@ msg_ok "Installed UniFi Network Application" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 9148e80e..92f6b6ba 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -119,8 +119,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 6cc0f029..ee7181ca 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -176,8 +176,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 2ffa248d..ac18b9b6 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -114,8 +114,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index e9d8f72d..a4db211d 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -108,8 +108,7 @@ msg_ok "Installed Whoogle" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 5defd0dd..916a57b3 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -136,8 +136,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 6e5d8464..9c94cdc4 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -108,8 +108,7 @@ msg_ok "Installed WireGuard" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 769e07be..803a1fa0 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -95,8 +95,7 @@ msg_ok "Installed YunoHost" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" - OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 7f778003..9161fbb4 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -135,8 +135,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 973ef4c2..eb90430d 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -111,8 +111,7 @@ msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -OS=$(grep "^ID=" /etc/os-release | cut -d'=' -f2) -if [ "$OS" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi +if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index e4542e09..0c19f0ca 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -40,7 +40,7 @@ function update_container() { os=`awk '/^ostype/' temp | cut -d' ' -f2` if [ "$os" == "alpine" ]; then pct exec $container -- ash -c "apk update && apk upgrade" - elif [ "$os" == "ubuntu" ] || [ "$os" == "debian" ] || [ "$os" == "devuan" ]; then + elif [ "$os" == "ubuntu" ] || [ "$PCT_OSTYPE" == "debian" ] || [ "$os" == "devuan" ]; then pct exec $container -- bash -c "apt-get update && apt-get -y upgrade" elif [ "$os" == "fedora" ] || [ "$os" == "rocky" ] || [ "$os" == "centos" ] || [ "$os" == "alma" ]; then pct exec $container -- bash -c "dnf -y update && dnf -y upgrade" From b7e073b1c8a39b9f51e4c215ea33095cd20355e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 Feb 2023 12:56:22 -0500 Subject: [PATCH 4324/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 0c19f0ca..e4542e09 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -40,7 +40,7 @@ function update_container() { os=`awk '/^ostype/' temp | cut -d' ' -f2` if [ "$os" == "alpine" ]; then pct exec $container -- ash -c "apk update && apk upgrade" - elif [ "$os" == "ubuntu" ] || [ "$PCT_OSTYPE" == "debian" ] || [ "$os" == "devuan" ]; then + elif [ "$os" == "ubuntu" ] || [ "$os" == "debian" ] || [ "$os" == "devuan" ]; then pct exec $container -- bash -c "apt-get update && apt-get -y upgrade" elif [ "$os" == "fedora" ] || [ "$os" == "rocky" ] || [ "$os" == "centos" ] || [ "$os" == "alma" ]; then pct exec $container -- bash -c "dnf -y update && dnf -y upgrade" From 1be65d04cc5d159000eaddabaa311c97788ac4c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 Feb 2023 16:45:47 -0500 Subject: [PATCH 4325/6505] code refactoring --- misc/update-lxcs.sh | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index e4542e09..eb9d14cd 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash function header_info { - cat <<"EOF" +clear +cat <<"EOF" __ __ __ __ __ _ ________ / / / /___ ____/ /___ _/ /____ / / | |/ / ____/ / / / / __ \/ __ / __ `/ __/ _ \ / / | / / @@ -17,7 +18,6 @@ RD=$(echo "\033[01;31m") CM='\xE2\x9C\x94\033' GN=$(echo "\033[1;92m") CL=$(echo "\033[m") -clear header_info while true; do read -p "This Will Update All LXC Containers. Proceed(y/n)?" yn @@ -29,26 +29,19 @@ while true; do done clear containers=$(pct list | tail -n +2 | cut -f1 -d' ') - function update_container() { container=$1 clear header_info - name=`pct exec $container hostname` + name=$(pct exec "$container" hostname) echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} \n" - pct config $container > temp - os=`awk '/^ostype/' temp | cut -d' ' -f2` - if [ "$os" == "alpine" ]; then - pct exec $container -- ash -c "apk update && apk upgrade" - elif [ "$os" == "ubuntu" ] || [ "$os" == "debian" ] || [ "$os" == "devuan" ]; then - pct exec $container -- bash -c "apt-get update && apt-get -y upgrade" - elif [ "$os" == "fedora" ] || [ "$os" == "rocky" ] || [ "$os" == "centos" ] || [ "$os" == "alma" ]; then - pct exec $container -- bash -c "dnf -y update && dnf -y upgrade" - elif [ "$os" == "archlinux" ]; then - pct exec $container -- bash -c "pacman -Syyu --noconfirm" - else - pct exec $container -- bash -c "yum -y update" - fi + os=$(pct config "$container" | awk '/^ostype/ {print $2}') + case "$os" in + alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; + archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm";; + fedora|rocky|centos|alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; + ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update && apt-get -y upgrade" ;; + esac } header_info read -p "Skip stopped containers? [y/N]" -n 1 -r @@ -58,11 +51,9 @@ if [[ ! $REPLY =~ ^[Yy]$ ]]; then else skip=yes fi - for container in $containers; do status=$(pct status $container) - if [ "$skip" == "no" ]; then - if [ "$status" == "status: stopped" ]; then + if [ "$skip" == "no" ] && [ "$status" == "status: stopped" ]; then echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" @@ -72,16 +63,9 @@ for container in $containers; do pct shutdown $container & elif [ "$status" == "status: running" ]; then update_container $container - fi - fi - if [ "$skip" == "yes" ]; then - if [ "$status" == "status: running" ]; then - update_container $container - fi fi done wait rm -rf temp -clear header_info echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From 94a5b030cadc6cba56833855c4b18da58da4fd52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 Feb 2023 18:28:08 -0500 Subject: [PATCH 4326/6505] add nltk stopwords --- install/paperless-ngx-v5-install.sh | 52 ++++++++++++----------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 1d09ae89..bdf8ba88 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -74,12 +74,21 @@ $STD apt-get update $STD apt-get -y upgrade msg_ok "Updated Container OS" -msg_info "Installing Paperless-ngx Dependencies" +msg_info "Installing Python3" $STD apt-get install -y --no-install-recommends \ python3 \ python3-pip \ python3-dev \ - imagemagick \ + python3-setuptools \ + python3-wheel +msg_ok "Installed Python3" + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y --no-install-recommends \ + redis \ + postgresql \ + build-essential \ + imagemagick \ fonts-liberation \ optipng \ gnupg \ @@ -89,11 +98,19 @@ $STD apt-get install -y --no-install-recommends \ libzbar0 \ poppler-utils \ default-libmysqlclient-dev \ + automake \ + libtool \ + pkg-config \ + git \ + curl \ + libtiff-dev \ + libpng-dev \ + libleptonica-dev \ sudo \ mc -msg_ok "Installed Paperless-ngx Dependencies" +msg_ok "Installed Dependencies" -msg_info "Installing OCR Dependencies" +msg_info "Installing OCR Dependencies (Patience)" $STD apt-get install -y --no-install-recommends \ unpaper \ ghostscript \ @@ -107,26 +124,7 @@ $STD apt-get install -y --no-install-recommends \ tesseract-ocr-eng msg_ok "Installed OCR Dependencies" -msg_info "Installing Extra Dependencies" -$STD apt-get install -y --no-install-recommends \ - redis \ - postgresql \ - build-essential \ - python3-setuptools \ - python3-wheel -msg_ok "Installed Extra Dependencies" - msg_info "Installing JBIG2" -$STD apt-get install -y --no-install-recommends \ - automake \ - libtool \ - pkg-config \ - git \ - curl \ - libtiff-dev \ - libpng-dev \ - libleptonica-dev - $STD git clone https://github.com/agl/jbig2enc /opt/jbig2enc cd /opt/jbig2enc $STD bash ./autogen.sh @@ -144,36 +142,30 @@ $STD tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ mv paperless-ngx paperless rm paperless-ngx-$Paperlessngx.tar.xz cd /opt/paperless - ## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt - $STD pip install --upgrade pip $STD pip install -r requirements.txt +$STD python3 -m nltk.downloader -d /usr/share/nltk_data stopwords msg_ok "Installed Paperless-ngx" msg_info "Setting up database" DB_USER=paperless DB_PASS="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" DB_NAME=paperlessdb - $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" - echo "Paperless-ngx Database User" >>~/paperless.creds echo $DB_USER >>~/paperless.creds echo "Paperless-ngx Database Password" >>~/paperless.creds echo $DB_PASS >>~/paperless.creds echo "Paperless-ngx Database Name" >>~/paperless.creds echo $DB_NAME >>~/paperless.creds - mkdir -p {consume,media} - sed -i -e 's|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=paperlessdb|' /opt/paperless/paperless.conf sed -i -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" /opt/paperless/paperless.conf SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" sed -i -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" /opt/paperless/paperless.conf - cd /opt/paperless/src $STD python3 manage.py migrate msg_ok "Set up database" From 3c4772541243ce6c2c35b772bf1b9b86c33e3949 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 Feb 2023 22:40:38 -0500 Subject: [PATCH 4327/6505] code optimization (#1020) --- ct/adguard-v5.sh | 2 +- ct/alpine-v5.sh | 2 +- ct/archlinux-v5.sh | 2 +- ct/audiobookshelf-v5.sh | 2 +- ct/autobrr-v5.sh | 2 +- ct/blocky-v5.sh | 2 +- ct/casaos-v5.sh | 2 +- ct/changedetection-v5.sh | 2 +- ct/cronicle-v5.sh | 2 +- ct/daemonsync-v5.sh | 2 +- ct/dashy-v5.sh | 2 +- ct/debian-v5.sh | 2 +- ct/deconz-v5.sh | 2 +- ct/deluge-v5.sh | 2 +- ct/docker-v5.sh | 2 +- ct/emby-v5.sh | 2 +- ct/emqx-v5.sh | 2 +- ct/esphome-v5.sh | 2 +- ct/grafana-v5.sh | 2 +- ct/grocy-v5.sh | 2 +- ct/heimdalldashboard-v5.sh | 2 +- ct/homeassistant-core-v5.sh | 2 +- ct/homeassistant-v5.sh | 2 +- ct/homebridge-v5.sh | 2 +- ct/homepage-v5.sh | 2 +- ct/homer-v5.sh | 2 +- ct/hyperion-v5.sh | 2 +- ct/influxdb-v5.sh | 2 +- ct/iobroker-v5.sh | 2 +- ct/jellyfin-v5.sh | 2 +- ct/k0s-v5.sh | 2 +- ct/kavita-v5.sh | 2 +- ct/keycloak-v5.sh | 2 +- ct/lidarr-v5.sh | 2 +- ct/magicmirror-v5.sh | 2 +- ct/mariadb-v5.sh | 2 +- ct/meshcentral-v5.sh | 2 +- ct/motioneye-v5.sh | 2 +- ct/mqtt-v5.sh | 2 +- ct/n8n-v5.sh | 2 +- ct/navidrome-v5.sh | 2 +- ct/nextcloudpi-v5.sh | 2 +- ct/nginxproxymanager-v5.sh | 2 +- ct/nocodb-v5.sh | 2 +- ct/node-red-v5.sh | 2 +- ct/omada-v5.sh | 2 +- ct/omv-v5.sh | 2 +- ct/openhab-v5.sh | 2 +- ct/paperless-ngx-v5.sh | 2 +- ct/photoprism-v5.sh | 2 +- ct/pihole-v5.sh | 2 +- ct/plex-v5.sh | 2 +- ct/podman-homeassistant-v5.sh | 2 +- ct/podman-v5.sh | 2 +- ct/postgresql-v5.sh | 2 +- ct/prometheus-v5.sh | 2 +- ct/prowlarr-v5.sh | 2 +- ct/radarr-v5.sh | 2 +- ct/readarr-v5.sh | 2 +- ct/rockylinux-v5.sh | 2 +- ct/sabnzbd-v5.sh | 2 +- ct/scrypted-v5.sh | 2 +- ct/shinobi-v5.sh | 2 +- ct/sonarr-v5.sh | 2 +- ct/syncthing-v5.sh | 2 +- ct/tdarr-v5.sh | 2 +- ct/technitiumdns-v5.sh | 2 +- ct/transmission-v5.sh | 2 +- ct/trilium-v5.sh | 2 +- ct/ubuntu-v5.sh | 2 +- ct/umbrel-v5.sh | 2 +- ct/unifi-v5.sh | 2 +- ct/uptimekuma-v5.sh | 2 +- ct/vaultwarden-v5.sh | 2 +- ct/whisparr-v5.sh | 2 +- ct/whoogle-v5.sh | 2 +- ct/wikijs-v5.sh | 2 +- ct/wireguard-v5.sh | 2 +- ct/yunohost-v5.sh | 2 +- ct/zigbee2mqtt-v5.sh | 2 +- ct/zwave-js-ui-v5.sh | 2 +- install/adguard-v5-install.sh | 7 +++---- install/audiobookshelf-v5-install.sh | 7 +++---- install/autobrr-v5-install.sh | 7 +++---- install/blocky-v5-install.sh | 7 +++---- install/casaos-v5-install.sh | 7 +++---- install/changedetection-v5-install.sh | 7 +++---- install/cronicle-v5-install.sh | 7 +++---- install/daemonsync-v5-install.sh | 7 +++---- install/dashy-v5-install.sh | 7 +++---- install/debian-v5-install.sh | 7 +++---- install/deconz-v5-install.sh | 7 +++---- install/deluge-v5-install.sh | 7 +++---- install/docker-v5-install.sh | 7 +++---- install/emby-v5-install.sh | 7 +++---- install/emqx-v5-install.sh | 7 +++---- install/esphome-v5-install.sh | 7 +++---- install/grafana-v5-install.sh | 7 +++---- install/grocy-v5-install.sh | 7 +++---- install/heimdalldashboard-v5-install.sh | 7 +++---- install/homeassistant-core-v5-install.sh | 7 +++---- install/homeassistant-v5-install.sh | 7 +++---- install/homebridge-v5-install.sh | 7 +++---- install/homepage-v5-install.sh | 7 +++---- install/homer-v5-install.sh | 7 +++---- install/hyperion-v5-install.sh | 7 +++---- install/influxdb-v5-install.sh | 7 +++---- install/iobroker-v5-install.sh | 7 +++---- install/jellyfin-v5-install.sh | 7 +++---- install/k0s-v5-install.sh | 7 +++---- install/kavita-v5-install.sh | 7 +++---- install/keycloak-v5-install.sh | 7 +++---- install/lidarr-v5-install.sh | 7 +++---- install/magicmirror-v5-install.sh | 7 +++---- install/mariadb-v5-install.sh | 7 +++---- install/meshcentral-v5-install.sh | 7 +++---- install/motioneye-v5-install.sh | 7 +++---- install/mqtt-v5-install.sh | 7 +++---- install/n8n-v5-install.sh | 7 +++---- install/navidrome-v5-install.sh | 7 +++---- install/nextcloudpi-v5-install.sh | 7 +++---- install/nginxproxymanager-v5-install.sh | 7 +++---- install/nocodb-v5-install.sh | 7 +++---- install/node-red-v5-install.sh | 7 +++---- install/omada-v5-install.sh | 7 +++---- install/omv-v5-install.sh | 7 +++---- install/openhab-v5-install.sh | 7 +++---- install/paperless-ngx-v5-install.sh | 7 +++---- install/photoprism-v5-install.sh | 7 +++---- install/pihole-v5-install.sh | 7 +++---- install/plex-v5-install.sh | 7 +++---- install/podman-homeassistant-v5-install.sh | 7 +++---- install/podman-v5-install.sh | 7 +++---- install/postgresql-v5-install.sh | 7 +++---- install/prometheus-v5-install.sh | 7 +++---- install/prowlarr-v5-install.sh | 7 +++---- install/radarr-v5-install.sh | 7 +++---- install/readarr-v5-install.sh | 7 +++---- install/sabnzbd-v5-install.sh | 7 +++---- install/scrypted-v5-install.sh | 7 +++---- install/shinobi-v5-install.sh | 7 +++---- install/sonarr-v5-install.sh | 7 +++---- install/syncthing-v5-install.sh | 7 +++---- install/tdarr-v5-install.sh | 7 +++---- install/technitiumdns-v5-install.sh | 7 +++---- install/transmission-v5-install.sh | 7 +++---- install/trilium-v5-install.sh | 7 +++---- install/ubuntu-v5-install.sh | 7 +++---- install/umbrel-v5-install.sh | 7 +++---- install/unifi-v5-install.sh | 7 +++---- install/uptimekuma-v5-install.sh | 7 +++---- install/vaultwarden-v5-install.sh | 7 +++---- install/whisparr-v5-install.sh | 7 +++---- install/whoogle-v5-install.sh | 7 +++---- install/wikijs-v5-install.sh | 7 +++---- install/wireguard-v5-install.sh | 7 +++---- install/yunohost-v5-install.sh | 7 +++---- install/zigbee2mqtt-v5-install.sh | 7 +++---- install/zwave-js-ui-v5-install.sh | 7 +++---- 159 files changed, 315 insertions(+), 393 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 6e424c6a..43255816 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -393,7 +393,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index d94a9c33..a3aed622 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -371,7 +371,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index a59e2a5a..d16eb6a1 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -375,7 +375,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index bac2131c..6c63c6c2 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 942565ac..88c5ba1c 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -385,7 +385,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index a18faaef..764e832b 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index c40fcac5..70af50ab 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -402,7 +402,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 632c8c9f..9e856f71 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -375,7 +375,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 6d5b478c..6e039f32 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -423,7 +423,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index f170a688..ec7e6c7f 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 7f168215..c284725b 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -402,7 +402,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 8abd935b..a167d1a9 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 24296217..fbaf1bd1 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -391,7 +391,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index 22b90ad3..be3a784c 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -372,7 +372,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index dd21a81e..9a55c770 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -400,7 +400,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 6808f1ff..78b3623c 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -407,7 +407,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 3313c436..740f13ff 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -375,7 +375,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index f4b4f117..1f65a742 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -382,7 +382,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 0c349d10..0723b384 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 49a71f40..8dd7be84 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -375,7 +375,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 0aac7e41..2e687d41 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -455,7 +455,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 8f588766..9a5247af 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -464,7 +464,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 35a5c1c7..80f7c040 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -468,7 +468,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 8b6028ba..f0de87a9 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 4eee8fd5..092838f9 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -382,7 +382,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 05700b71..d7a94ab4 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -395,7 +395,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index c419e8b4..b26fa92b 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -391,7 +391,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 08687ce2..7865ff37 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index ce7d81cb..aec33a36 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 682cf962..44743db4 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -397,7 +397,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 90734371..566323c8 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index 2ffed10a..00bde20e 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -374,7 +374,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 149cf054..5c646690 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -377,7 +377,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 5f2bea43..1b210bf8 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 748e92dd..d0b6d70c 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -378,7 +378,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 60febdd9..a7e10c6f 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index bc150f17..42a7a903 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index bd05d8d3..d6438774 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -375,7 +375,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index d6586750..4a47c646 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 06519242..15ed0944 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index d440e7e5..9aca8a7d 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -387,7 +387,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index da10e525..67fbc1be 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 34effe2b..0bc50e2e 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -485,7 +485,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 2bbdc9ba..8dd52282 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -379,7 +379,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 47d50c74..23e2b5c6 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -412,7 +412,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 72768f0e..7923b522 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -374,7 +374,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 3c82ce9f..1a2577df 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -387,7 +387,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index bd75f853..28041e77 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -377,7 +377,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index ac926ebb..cfd7653d 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -444,7 +444,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 46acf01c..0787d490 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -397,7 +397,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index dfcfd8af..c2a79326 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 32e66dd6..39766d02 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -407,7 +407,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 702a2d74..e9301f95 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -446,7 +446,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index e61101f8..ceaaabc6 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index aa1b8325..09ded8b2 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 05122e98..e2b60b9a 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index 8e3bd733..23fe82cc 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 8a9ab6fc..cd1a1fd1 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 63cf74e1..d78e79bf 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index ec0975b8..0888b791 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -376,7 +376,7 @@ bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/c msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 65399620..f9422730 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 33a22311..0c2e1f0d 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -391,7 +391,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 190d3df6..8b4f1d67 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -386,7 +386,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 7925af27..27ff2b07 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 9007943a..3638e391 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -377,7 +377,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 9ff7e671..ec70c7bc 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 5e395c27..75603db3 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -438,7 +438,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index 622406d8..db1881b8 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index b71cb766..ee1d71d6 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -395,7 +395,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 7b62d7cd..aa85b85f 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -379,7 +379,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} ${var_version} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 80375583..a7e63c93 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -400,7 +400,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 8a7aa4f1..82c6edfd 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -376,7 +376,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 4e852dd0..e638b68c 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -393,7 +393,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index ab1d0fb6..e89d3872 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -444,7 +444,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 900cc60e..4877261f 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -372,7 +372,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index c858ecb8..4a5e2296 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -375,7 +375,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index b151cd13..12aaa524 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -389,7 +389,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 52ed54a5..8c773e57 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -431,7 +431,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 2ba9a1aa..1a79f7dd 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -371,7 +371,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index dbde6937..4e8055dc 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -436,7 +436,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 75152cca..5beec0f9 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -403,7 +403,7 @@ msg_info "Starting LXC Container" pct start $CTID msg_ok "Started LXC Container" lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 927412d4..309588d0 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index c5ea736a..140b4239 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 61b2eb45..2aa9ed6a 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index 51f1e601..d8c20d98 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 4825c26f..13ca9596 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index fbe2e18d..54356608 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index fb845084..fe04107d 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index ea43bc98..2bc5536a 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index e876c39f..5d5dd79c 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index d15f4d0c..0a5e83a5 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 3e9973df..189d4ded 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 1dc55656..ab026534 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 5eed9309..a50a80e9 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index c23deef0..753c541d 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 5a4cab70..07e6b630 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index 00366388..42e810b0 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 3827d1b0..6e4b218e 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index 344ea7ce..3210baa2 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index 351df94b..a920d9ea 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 14c6d0e6..c51a67f6 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index e1213501..3e6d6023 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index a966c54b..f1a75d97 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 2cd61caa..9c093dfe 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 5c0358ce..f9012735 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 589297a0..017efb42 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index f623b20d..c7db11a5 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 0c9499cf..f17f3978 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index e8f0f73b..56fc9c6d 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index c9adae82..a7906488 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 0b5b6711..41ebc755 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 19407187..b05cc0cf 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index 4eaaa2e8..00bf3b60 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index fa57fd6e..8aafd3e5 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -55,7 +54,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -65,7 +64,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 37829a43..5cefe546 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index d172d37e..31031d10 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index f0d91b0e..c573d84d 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 4b2c7047..a7401efe 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index e11671e6..9c421c55 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 5f3804f0..c23cfa96 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 0d01c01e..f702367f 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index d585a660..193aa3f7 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index f56b68c5..e09afe29 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index 02686163..6ed1c729 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 26428b02..2f007ebf 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index d5b06587..dc355c56 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi export DEBIAN_FRONTEND=noninteractive @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index b57f9edf..89481331 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index bdf8ba88..cbc85eea 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -55,7 +54,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -65,7 +64,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 66b62c0b..a18106b9 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) @@ -59,7 +58,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -69,7 +68,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 848d9cb1..2ef307c8 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi export DEBIAN_FRONTEND=noninteractive @@ -59,7 +58,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -69,7 +68,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index bbd76a96..1afcc401 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 5a93e042..18828d37 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 7e75b6f9..c8e375a0 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 8877f2e4..08357047 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 357a2229..33a090bb 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 7ca5434b..6157280e 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 85a47c29..32c540e0 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index 6554d377..ae2b5416 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index ccf74909..3e700eb3 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index fd84cc49..d4753e21 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 76d2b9b0..8738ea13 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 96dca52d..2152a929 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 8e6812b7..4fb4f35b 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index e13a2f94..0604dd72 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 0ad64b31..cb536f2e 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index f56dff91..44f1c40a 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index e93f13f1..936eac73 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 539076f0..051e6554 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index ee5469cf..e07e745a 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 3f105891..fa1c90ea 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi #https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 @@ -59,7 +58,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -69,7 +68,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 92f6b6ba..d53bacc8 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index ee7181ca..1421be40 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index ac18b9b6..c07df625 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index a4db211d..2d3e996d 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 916a57b3..36f48110 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 9c94cdc4..95598151 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 803a1fa0..912136e7 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -57,7 +56,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -67,7 +66,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 9161fbb4..c24062c9 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index eb90430d..02e5b65e 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -if [ "$VERBOSE" == "yes" ]; then set -x; STD=""; fi -if [ "$VERBOSE" != "yes" ]; then STD="silent"; fi +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi YW=$(echo "\033[33m") @@ -58,7 +57,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e -if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then @@ -68,7 +67,7 @@ if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else exit 1 fi fi -RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e From a4c1b0e464e0679a1ef46e44ced60d744a693434 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 12:36:42 -0500 Subject: [PATCH 4328/6505] Update clean-lxcs.sh code optimization --- misc/clean-lxcs.sh | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 4bda3c1a..8c35219a 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -1,6 +1,7 @@ #!/bin/bash function header_info { - cat <<"EOF" +clear +cat <<"EOF" ________ __ _ ________ / ____/ /__ ____ _____ / / | |/ / ____/ / / / / _ \/ __ `/ __ \ / / | / / @@ -16,7 +17,6 @@ RD=$(echo "\033[01;31m") CM='\xE2\x9C\x94\033' GN=$(echo "\033[1;92m") CL=$(echo "\033[m") -clear header_info echo -e "\n ${RD} USE AT YOUR OWN RISK. Deleting logs/cache may result in some apps/services broken!${CL} \n" while true; do @@ -31,9 +31,8 @@ clear containers=$(pct list | tail -n +2 | cut -f1 -d' ') function clean_container() { container=$1 - clear header_info - name=`pct exec $container hostname` + name=$(pct exec "$container" hostname) echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" } @@ -47,8 +46,7 @@ fi for container in $containers; do status=$(pct status $container) - if [ "$skip" == "no" ]; then - if [ "$status" == "status: stopped" ]; then + if [ "$skip" == "no" ] && [ "$status" == "status: stopped" ]; then echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" @@ -58,15 +56,8 @@ for container in $containers; do pct shutdown $container & elif [ "$status" == "status: running" ]; then clean_container $container - fi - fi - if [ "$skip" == "yes" ]; then - if [ "$status" == "status: running" ]; then - clean_container $container - fi fi done wait -clear header_info echo -e "${GN} Finished, Containers Cleaned. ${CL} \n" From 0213205b29d96e2f914b1d0418258e5a210b5264 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 12:38:25 -0500 Subject: [PATCH 4329/6505] Update clean.sh tweak --- misc/clean.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/misc/clean.sh b/misc/clean.sh index eaa83cd1..8146ff52 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash function header_info() { - cat <<"EOF" +clear +cat <<"EOF" ________ __ _ ________ / ____/ /__ ____ _____ / / | |/ / ____/ / / / / _ \/ __ `/ __ \ / / | / / @@ -13,7 +14,6 @@ BL=$(echo "\033[36m") GN=$(echo "\033[1;92m") CL=$(echo "\033[m") name=$(hostname) -clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" cache=$(find /var/cache/ -type f) @@ -32,7 +32,6 @@ else sleep 2 fi fi -clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" logs=$(find /var/log/ -type f) @@ -51,7 +50,6 @@ else sleep 2 fi fi -clear header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" echo -e "${GN}Populating apt lists${CL} \n" From c89e9ac9c569283ef422abbde1757f9843162387 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 13:52:05 -0500 Subject: [PATCH 4330/6505] Update audiobookshelf-v5.sh set default privileged --- ct/audiobookshelf-v5.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 6c63c6c2..54e5d69a 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -96,8 +96,8 @@ if ! command -v pveversion >/dev/null 2>&1; then fi function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" PW="" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -136,8 +136,8 @@ function default_settings() { } function advanced_settings() { CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then From 1fd36bc6c3a908153b69735aa0794914bfec4f26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 17:10:04 -0500 Subject: [PATCH 4331/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index eb9d14cd..51ccb214 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -66,6 +66,5 @@ for container in $containers; do fi done wait -rm -rf temp header_info echo -e "${GN} Finished, All Containers Updated. ${CL} \n" From 907a29b7a3b899c3876d7931174155abd6956385 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 17:27:58 -0500 Subject: [PATCH 4332/6505] Update update-lxcs.sh change to dist-upgrade --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 51ccb214..80586942 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -40,7 +40,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm";; fedora|rocky|centos|alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update && apt-get -y upgrade" ;; + ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update && apt-get -y dist-upgrade" ;; esac } header_info From 38d1a82c71643b0bbb962fcdedd1ac21413c56a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 18:36:19 -0500 Subject: [PATCH 4333/6505] Create devuan-v5-install.sh --- install/devuan-v5-install.sh | 88 ++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 install/devuan-v5-install.sh diff --git a/install/devuan-v5-install.sh b/install/devuan-v5-install.sh new file mode 100644 index 00000000..52cdbb48 --- /dev/null +++ b/install/devuan-v5-install.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY +done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +echo "export TERM='xterm-256color'" >>/root/.bashrc +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From fa715ef26b8b9ae7d167aa5e4ca7068820593339 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 18:38:19 -0500 Subject: [PATCH 4334/6505] Create devuan-v5.sh --- ct/devuan-v5.sh | 378 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 ct/devuan-v5.sh diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh new file mode 100644 index 00000000..fb23bcf7 --- /dev/null +++ b/ct/devuan-v5.sh @@ -0,0 +1,378 @@ +#!/usr/bin/env bash +function header_info { + cat <<"EOF" + ____ + / __ \___ _ ____ ______v5____ + / / / / _ \ | / / / / / __ `/ __ \ + / /_/ / __/ |/ / /_/ / /_/ / / / / +/_____/\___/|___/\__,_/\__,_/_/ /_/ + +EOF +} +clear +header_info +echo -e "Loading..." +APP="Devuan" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="devuan" +var_version="4.0" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { + PVE=$(pveversion | grep "pve-manager/7" | wc -l) + if [[ $PVE != 1 ]]; then + echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" + echo -e "Exiting..." + sleep 2 + exit + fi +} +function ARCH_CHECK() { + ARCH=$(dpkg --print-architecture) + if [[ "$ARCH" != "amd64" ]]; then + echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +if command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + NEXTID=$(pvesh get /cluster/nextid) + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi +if ! command -v pveversion >/dev/null 2>&1; then + if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + echo "User selected Update" + else + clear + echo -e "⚠ User exited script \n" + exit + fi +fi + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}devuan${CL}" + PW="-password devuan" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD (leave blank for devuan)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="devuan" PW="-password devuan" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +clear +header_info +msg_info "Updating Debian LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Debian LXC" +exit +} +clear +ARCH_CHECK +if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} ${var_version} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 7d5019068fefe688c9d3e16391818b879c7218ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Feb 2023 19:05:38 -0500 Subject: [PATCH 4335/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1bbf3c61..65b956ed 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-02-05 + +### Changed + +- **Devuan LXC** + - NEW Script + ## 2023-02-02 ### Changed From 474903d5af95289ee7bd040826564d77e2721264 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Feb 2023 05:56:25 -0500 Subject: [PATCH 4336/6505] Update devuan-v5.sh tweak --- ct/devuan-v5.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index fb23bcf7..82d40c70 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -98,8 +98,8 @@ fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}devuan${CL}" - PW="-password devuan" + echo -e "${DGN}Using Root Password: ${BGN}$NSAPP${CL}" + PW="-password $NSAPP" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" CT_ID=$NEXTID echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" @@ -143,11 +143,11 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD (leave blank for devuan)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + PW1=$(whiptail --inputbox "Set Root Password" 8 58 $NSAPP --title "ROOT PASSWORD" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $PW1 ]; then - PW1="devuan" PW="-password devuan" + PW1="$NSAPP" PW="-password $NSAPP" echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" else PW="-password $PW1" From eeced862dafb61dc76b7592e23620cd90d652aea Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Feb 2023 09:36:01 -0500 Subject: [PATCH 4337/6505] code optimization (#1025) - remove mc from Ubuntu - change archive mirrors for Ubuntu - small tweaks --- ct/adguard-v5.sh | 1 + ct/alpine-v5.sh | 1 + ct/archlinux-v5.sh | 1 + ct/audiobookshelf-v5.sh | 1 + ct/autobrr-v5.sh | 1 + ct/blocky-v5.sh | 1 + ct/casaos-v5.sh | 1 + ct/changedetection-v5.sh | 1 + ct/cronicle-v5.sh | 1 + ct/daemonsync-v5.sh | 1 + ct/dashy-v5.sh | 1 + ct/debian-v5.sh | 1 + ct/deconz-v5.sh | 1 + ct/deluge-v5.sh | 1 + ct/devuan-v5.sh | 1 + ct/docker-v5.sh | 1 + ct/emby-v5.sh | 1 + ct/emqx-v5.sh | 1 + ct/esphome-v5.sh | 1 + ct/grafana-v5.sh | 1 + ct/grocy-v5.sh | 1 + ct/heimdalldashboard-v5.sh | 1 + ct/homeassistant-core-v5.sh | 1 + ct/homeassistant-v5.sh | 1 + ct/homebridge-v5.sh | 1 + ct/homepage-v5.sh | 1 + ct/homer-v5.sh | 1 + ct/hyperion-v5.sh | 1 + ct/influxdb-v5.sh | 1 + ct/iobroker-v5.sh | 1 + ct/jellyfin-v5.sh | 1 + ct/k0s-v5.sh | 1 + ct/kavita-v5.sh | 1 + ct/keycloak-v5.sh | 1 + ct/lidarr-v5.sh | 1 + ct/magicmirror-v5.sh | 1 + ct/mariadb-v5.sh | 1 + ct/meshcentral-v5.sh | 1 + ct/motioneye-v5.sh | 1 + ct/mqtt-v5.sh | 1 + ct/n8n-v5.sh | 1 + ct/navidrome-v5.sh | 1 + ct/nextcloudpi-v5.sh | 1 + ct/nginxproxymanager-v5.sh | 1 + ct/nocodb-v5.sh | 1 + ct/node-red-v5.sh | 1 + ct/omada-v5.sh | 1 + ct/omv-v5.sh | 1 + ct/openhab-v5.sh | 1 + ct/paperless-ngx-v5.sh | 1 + ct/photoprism-v5.sh | 1 + ct/pihole-v5.sh | 1 + ct/plex-v5.sh | 1 + ct/podman-homeassistant-v5.sh | 1 + ct/podman-v5.sh | 1 + ct/postgresql-v5.sh | 1 + ct/prometheus-v5.sh | 1 + ct/prowlarr-v5.sh | 1 + ct/radarr-v5.sh | 1 + ct/readarr-v5.sh | 1 + ct/rockylinux-v5.sh | 1 + ct/sabnzbd-v5.sh | 1 + ct/scrypted-v5.sh | 1 + ct/shinobi-v5.sh | 1 + ct/sonarr-v5.sh | 1 + ct/syncthing-v5.sh | 1 + ct/tdarr-v5.sh | 1 + ct/technitiumdns-v5.sh | 1 + ct/transmission-v5.sh | 1 + ct/trilium-v5.sh | 1 + ct/ubuntu-v5.sh | 1 + ct/umbrel-v5.sh | 1 + ct/unifi-v5.sh | 1 + ct/uptimekuma-v5.sh | 1 + ct/vaultwarden-v5.sh | 1 + ct/whisparr-v5.sh | 1 + ct/whoogle-v5.sh | 1 + ct/wikijs-v5.sh | 1 + ct/wireguard-v5.sh | 1 + ct/yunohost-v5.sh | 1 + ct/zigbee2mqtt-v5.sh | 1 + ct/zwave-js-ui-v5.sh | 1 + install/adguard-v5-install.sh | 4 ++-- install/audiobookshelf-v5-install.sh | 4 ++-- install/autobrr-v5-install.sh | 4 ++-- install/blocky-v5-install.sh | 4 ++-- install/casaos-v5-install.sh | 4 ++-- install/changedetection-v5-install.sh | 4 ++-- install/cronicle-v5-install.sh | 4 ++-- install/daemonsync-v5-install.sh | 4 ++-- install/dashy-v5-install.sh | 4 ++-- install/debian-v5-install.sh | 4 ++-- install/deconz-v5-install.sh | 11 ++++++++--- install/deluge-v5-install.sh | 4 ++-- install/devuan-v5-install.sh | 2 ++ install/docker-v5-install.sh | 4 ++-- install/emby-v5-install.sh | 11 ++++++++--- install/emqx-v5-install.sh | 4 ++-- install/esphome-v5-install.sh | 4 ++-- install/grafana-v5-install.sh | 4 ++-- install/grocy-v5-install.sh | 4 ++-- install/heimdalldashboard-v5-install.sh | 4 ++-- install/homeassistant-core-v5-install.sh | 4 ++-- install/homeassistant-v5-install.sh | 4 ++-- install/homebridge-v5-install.sh | 4 ++-- install/homepage-v5-install.sh | 4 ++-- install/homer-v5-install.sh | 4 ++-- install/hyperion-v5-install.sh | 4 ++-- install/influxdb-v5-install.sh | 4 ++-- install/iobroker-v5-install.sh | 4 ++-- install/jellyfin-v5-install.sh | 11 ++++++++--- install/k0s-v5-install.sh | 4 ++-- install/kavita-v5-install.sh | 4 ++-- install/keycloak-v5-install.sh | 4 ++-- install/lidarr-v5-install.sh | 4 ++-- install/magicmirror-v5-install.sh | 16 ++++++++-------- install/mariadb-v5-install.sh | 4 ++-- install/meshcentral-v5-install.sh | 4 ++-- install/motioneye-v5-install.sh | 4 ++-- install/mqtt-v5-install.sh | 4 ++-- install/n8n-v5-install.sh | 4 ++-- install/navidrome-v5-install.sh | 4 ++-- install/nextcloudpi-v5-install.sh | 4 ++-- install/nginxproxymanager-v5-install.sh | 4 ++-- install/nocodb-v5-install.sh | 4 ++-- install/node-red-v5-install.sh | 4 ++-- install/omada-v5-install.sh | 11 ++++++++--- install/omv-v5-install.sh | 4 ++-- install/openhab-v5-install.sh | 4 ++-- install/paperless-ngx-v5-install.sh | 16 ++++++++-------- install/photoprism-v5-install.sh | 4 ++-- install/pihole-v5-install.sh | 4 ++-- install/plex-v5-install.sh | 11 ++++++++--- install/podman-homeassistant-v5-install.sh | 4 ++-- install/podman-v5-install.sh | 4 ++-- install/postgresql-v5-install.sh | 4 ++-- install/prometheus-v5-install.sh | 4 ++-- install/prowlarr-v5-install.sh | 4 ++-- install/radarr-v5-install.sh | 4 ++-- install/readarr-v5-install.sh | 4 ++-- install/sabnzbd-v5-install.sh | 4 ++-- install/scrypted-v5-install.sh | 4 ++-- install/shinobi-v5-install.sh | 12 +++++++++--- install/sonarr-v5-install.sh | 4 ++-- install/syncthing-v5-install.sh | 4 ++-- install/tdarr-v5-install.sh | 4 ++-- install/technitiumdns-v5-install.sh | 4 ++-- install/transmission-v5-install.sh | 4 ++-- install/trilium-v5-install.sh | 4 ++-- install/ubuntu-v5-install.sh | 11 ++++++++--- install/umbrel-v5-install.sh | 4 ++-- install/unifi-v5-install.sh | 4 ++-- install/uptimekuma-v5-install.sh | 4 ++-- install/vaultwarden-v5-install.sh | 4 ++-- install/whisparr-v5-install.sh | 4 ++-- install/whoogle-v5-install.sh | 4 ++-- install/wikijs-v5-install.sh | 4 ++-- install/wireguard-v5-install.sh | 4 ++-- install/yunohost-v5-install.sh | 4 ++-- install/zigbee2mqtt-v5-install.sh | 4 ++-- install/zwave-js-ui-v5-install.sh | 4 ++-- 161 files changed, 295 insertions(+), 175 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 43255816..d27ffa28 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -370,6 +370,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index a3aed622..4b29ba88 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -349,6 +349,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index d16eb6a1..d3c3009e 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 54e5d69a..55e121d0 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 88c5ba1c..ba683924 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -362,6 +362,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index 764e832b..321a6932 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 70af50ab..994be9a2 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -363,6 +363,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 9e856f71..2e9939ff 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -352,6 +352,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 6e039f32..8097937e 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -400,6 +400,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export SERV=$SERVER export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index ec7e6c7f..bc351a7d 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index c284725b..7a5f9354 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -379,6 +379,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index a167d1a9..1f0cb49c 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index fbaf1bd1..85f27fe0 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index be3a784c..ba79ee1c 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -349,6 +349,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index 82d40c70..79871ef6 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 9a55c770..ae6085f4 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -360,6 +360,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 78b3623c..57c35026 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -372,6 +372,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 740f13ff..b0e091ca 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -352,6 +352,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index 1f65a742..bf580607 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -359,6 +359,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 0723b384..20947e81 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 8dd7be84..f715b57e 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -352,6 +352,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 2e687d41..396e5825 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -432,6 +432,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 9a5247af..83b04839 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -427,6 +427,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 80f7c040..04f7f93a 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -428,6 +428,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index f0de87a9..851b72bc 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 092838f9..a93adf81 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -359,6 +359,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index d7a94ab4..458bbd87 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -372,6 +372,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index b26fa92b..bd2f7106 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 7865ff37..9f3889e8 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index aec33a36..2099aa8e 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 44743db4..a81b354e 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -362,6 +362,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 566323c8..1e5f3e92 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index 00bde20e..acf18be2 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -351,6 +351,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 5c646690..e3e8eac0 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 1b210bf8..636e4e0a 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index d0b6d70c..50432f13 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -355,6 +355,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index a7e10c6f..d37c0186 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 42a7a903..68285c3b 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index d6438774..eb08e9b1 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -352,6 +352,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 4a47c646..f7995b7f 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 15ed0944..beb58747 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 9aca8a7d..c382844a 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -364,6 +364,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 67fbc1be..20909da5 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 0bc50e2e..a1f96474 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -462,6 +462,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 8dd52282..be844bf6 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -356,6 +356,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 23e2b5c6..2784b41f 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -389,6 +389,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 7923b522..0af724ce 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -351,6 +351,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 1a2577df..839b8b69 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 28041e77..46720606 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index cfd7653d..5b5d8a6f 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -421,6 +421,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 0787d490..33a810db 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -374,6 +374,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index c2a79326..4ecb5d26 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 39766d02..c973e8a0 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -372,6 +372,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index e9301f95..8f88bf64 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -403,6 +403,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index ceaaabc6..048c6a50 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index 09ded8b2..ff6dcbf0 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index e2b60b9a..898b61b0 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index 23fe82cc..3ff3a087 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index cd1a1fd1..a71f5265 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index d78e79bf..71dde5fe 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index 0888b791..421a5eab 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index f9422730..885619eb 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 0c2e1f0d..9e0c1244 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 8b4f1d67..54abd42f 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -363,6 +363,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 27ff2b07..7e5f472e 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 3638e391..d11d2c2d 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -354,6 +354,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index ec70c7bc..679b1258 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 75603db3..9fd8c7f3 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -415,6 +415,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index db1881b8..ff634702 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index ee1d71d6..7a6648e4 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -372,6 +372,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index aa85b85f..ece6935e 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -356,6 +356,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index a7e63c93..fbf3e650 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -361,6 +361,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 82c6edfd..7c395c9e 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -353,6 +353,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index e638b68c..af07651f 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -370,6 +370,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index e89d3872..1eff8d4e 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -421,6 +421,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 4877261f..3549ade0 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -349,6 +349,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 4a5e2296..2027bf44 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -352,6 +352,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 12aaa524..80f0cd42 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -366,6 +366,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 8c773e57..642ff613 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -408,6 +408,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 1a79f7dd..ca1efda9 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -348,6 +348,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 4e8055dc..c5c789a1 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -399,6 +399,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 5beec0f9..6d3f63cc 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -366,6 +366,7 @@ fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP export VERBOSE=$VERB export SSH_ROOT=${SSH} export CTID=$CT_ID diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 309588d0..f4c92d4c 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -92,10 +92,10 @@ rm install.sh msg_ok "Installed AdGuard Home" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index 140b4239..51d38430 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -90,10 +90,10 @@ $STD apt install audiobookshelf msg_ok "Installed audiobookshelf" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 2aa9ed6a..4414672e 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -111,10 +111,10 @@ systemctl enable --now -q autobrr.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index d8c20d98..5c4bef55 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -344,10 +344,10 @@ $STD systemctl enable --now blocky msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index 13ca9596..fa81060c 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -100,10 +100,10 @@ $STD bash <(curl -fsSL https://get.casaos.io) msg_ok "Installed CasaOS" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index 54356608..2827bfc7 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -104,10 +104,10 @@ $STD systemctl enable --now changedetection msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index fe04107d..8f7d152c 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -110,10 +110,10 @@ $STD update-rc.d cronicled defaults msg_ok "Installed Cronicle Primary Server" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 2bc5536a..16f410c1 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -89,10 +89,10 @@ $STD dpkg -i daemonsync_2.2.0.0059_amd64.deb msg_ok "Installed Daemon Sync Server" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 5d5dd79c..f6421b9a 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -120,10 +120,10 @@ systemctl start dashy msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 0a5e83a5..e910d9e5 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -82,10 +82,10 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 189d4ded..6a7f82a7 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -71,6 +71,12 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') +cat </etc/apt/sources.list +deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +EOF + msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade @@ -79,7 +85,6 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo -$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -113,10 +118,10 @@ $STD systemctl enable --now deconz msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index ab026534..776814e7 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -127,10 +127,10 @@ systemctl enable --now -q deluge-web.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/devuan-v5-install.sh b/install/devuan-v5-install.sh index 52cdbb48..9da236b1 100644 --- a/install/devuan-v5-install.sh +++ b/install/devuan-v5-install.sh @@ -80,6 +80,8 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index a50a80e9..091dfdec 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -144,10 +144,10 @@ if [[ $DOCKER_COMPOSE == "Y" ]]; then fi echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 753c541d..fff7abed 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -71,6 +71,12 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') +cat </etc/apt/sources.list +deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +EOF + msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade @@ -79,7 +85,6 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo -$STD apt-get install -y mc msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then @@ -103,10 +108,10 @@ $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb msg_ok "Installed Emby" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 07e6b630..23df928a 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -88,10 +88,10 @@ $STD systemctl enable --now emqx msg_ok "Installed EMQX" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index 42e810b0..b2af525e 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -109,10 +109,10 @@ systemctl start esphomeDashboard msg_ok "Installed ESPHome Dashboard" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 6e4b218e..2abf3dff 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -96,10 +96,10 @@ $STD apt-get install -y grafana msg_ok "Installed Grafana" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index 3210baa2..d23ff417 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -126,10 +126,10 @@ systemctl reload apache2 msg_ok "Installed grocy" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index a920d9ea..fac55718 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -120,10 +120,10 @@ $STD sudo systemctl enable --now heimdall.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index c51a67f6..83695041 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -162,10 +162,10 @@ $STD systemctl enable --now homeassistant msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index 3e6d6023..f86f089e 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -147,10 +147,10 @@ $STD docker run -d \ msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index f1a75d97..4e1e4c92 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -99,10 +99,10 @@ $STD hb-service install --user homebridge msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 9c093dfe..3ef04b4b 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -119,10 +119,10 @@ $STD systemctl enable --now homepage msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index f9012735..70d9ee17 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -108,10 +108,10 @@ $STD systemctl enable --now homer msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 017efb42..2eba6ef7 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -93,10 +93,10 @@ $STD systemctl enable --now hyperion@root.service msg_ok "Installed Hyperion" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index c7db11a5..dc918a9a 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -122,10 +122,10 @@ if [[ $TELEGRAF == "Y" ]]; then fi echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index f17f3978..6db17570 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -87,10 +87,10 @@ $STD bash <(curl -fsSL https://iobroker.net/install.sh) msg_ok "Installed ioBroker" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 56fc9c6d..e7633690 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -71,6 +71,12 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') +cat </etc/apt/sources.list +deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +EOF + msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade @@ -79,7 +85,6 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo -$STD apt-get install -y mc $STD apt-get install -y apt-transport-https $STD apt-get install -y software-properties-common msg_ok "Installed Dependencies" @@ -127,10 +132,10 @@ ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index a7906488..dcb6de05 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -103,10 +103,10 @@ $STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/ msg_ok "Installed Helm" fi echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 41ebc755..21245848 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -109,10 +109,10 @@ systemctl enable --now -q kavita.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index b05cc0cf..d64ef3a1 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -106,10 +106,10 @@ $STD systemctl enable --now keycloak.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index 00bf3b60..d3e8b945 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -113,10 +113,10 @@ systemctl enable --now -q lidarr msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 8aafd3e5..f53c1689 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -208,20 +208,20 @@ $STD systemctl enable --now magicmirror msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 5cefe546..72cf2410 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -104,10 +104,10 @@ if [[ $ADMINER == "Y" ]]; then fi echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index 31031d10..67cc6747 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -98,10 +98,10 @@ $STD node node_modules/meshcentral --install msg_ok "Installed MeshCentral" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index c573d84d..1575f17f 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -117,10 +117,10 @@ systemctl start motioneye msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index a7401efe..53b39b32 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -94,10 +94,10 @@ $STD apt-get -y install mosquitto-clients msg_ok "Installed Mosquitto MQTT Broker" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 9c421c55..be76bfa3 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -109,10 +109,10 @@ $STD systemctl enable --now n8n msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index c23cfa96..33ae8d3e 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -137,10 +137,10 @@ $STD systemctl enable --now navidrome.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index f702367f..4396c90c 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -89,10 +89,10 @@ service apache2 restart msg_ok "Installed NextCloudPi" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 193aa3f7..99b09e8a 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -241,10 +241,10 @@ EOF msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index e09afe29..d22f7308 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -116,10 +116,10 @@ systemctl enable --now nocodb.service &>/dev/null msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index 6ed1c729..a127c44d 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -119,10 +119,10 @@ $STD systemctl enable --now nodered.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 2f007ebf..b56d4564 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -71,6 +71,12 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') +cat </etc/apt/sources.list +deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +EOF + msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade @@ -79,7 +85,6 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo -$STD apt-get install -y mc $STD apt-get install -y gnupg $STD apt-get install -y openjdk-8-jre-headless $STD apt-get install -y jsvc @@ -93,10 +98,10 @@ $STD dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb msg_ok "Installed Omada Controller" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index dc355c56..32151fa7 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -105,10 +105,10 @@ omv-confdbadm populate msg_ok "Installed OpenMediaVault" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index 89481331..54b87c0a 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -104,10 +104,10 @@ $STD systemctl enable --now openhab.service msg_ok "Installed openHAB" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index cbc85eea..5c076deb 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -250,20 +250,20 @@ $STD systemctl enable --now paperless-consumer paperless-webserver paperless-sch msg_ok "Created Services" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" fi if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index a18106b9..f167d361 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -177,10 +177,10 @@ WantedBy=multi-user.target" >$service_path msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 2ef307c8..fb175b07 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -110,10 +110,10 @@ $STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended msg_ok "Installed Pi-hole" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 1afcc401..660fa292 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -71,6 +71,12 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') +cat </etc/apt/sources.list +deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +EOF + msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade @@ -79,7 +85,6 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo -$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" @@ -107,10 +112,10 @@ $STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver msg_ok "Installed Plex Media Server" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 18828d37..56853cf3 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -109,10 +109,10 @@ $STD systemctl enable --now homeassistant msg_ok "Installed Home Assistant" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index c8e375a0..91d1e340 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -88,10 +88,10 @@ echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registr msg_ok "Installed Podman" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 08357047..0fa74a59 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -211,10 +211,10 @@ if [[ $ADMINER == "Y" ]]; then fi echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 33a090bb..7ee69706 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -118,10 +118,10 @@ $STD sudo systemctl enable --now prometheus msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 6157280e..5e9bf052 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -111,10 +111,10 @@ systemctl enable --now -q prowlarr msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 32c540e0..b2829bf8 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -111,10 +111,10 @@ systemctl enable --now -q radarr msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index ae2b5416..66ad0e93 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -111,10 +111,10 @@ systemctl enable --now -q readarr msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 3e700eb3..bae07f8a 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -116,10 +116,10 @@ systemctl enable --now -q sabnzbd.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index d4753e21..e67b5a15 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -176,10 +176,10 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now scrypted.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 8738ea13..29af4e26 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -71,6 +71,12 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') +cat </etc/apt/sources.list +deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +EOF + msg_info "Updating Container OS" $STD apt-get update --fix-missing $STD apt-get -y upgrade @@ -86,7 +92,7 @@ if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then fi msg_info "Installing Dependencies" -$STD apt-get install -y curl sudo git mc +$STD apt-get install -y curl sudo git $STD apt-get install -y make zip net-tools $STD apt-get install -y gcc g++ cmake msg_ok "Installed Dependencies" @@ -145,10 +151,10 @@ $STD pm2 list msg_ok "Installed Shinobi" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 2152a929..9eb09159 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -92,10 +92,10 @@ $STD apt-get -o Dpkg::Options::="--force-confold" install -y sonarr msg_ok "Installed Sonarr" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 4fb4f35b..f362c31e 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -95,10 +95,10 @@ systemctl restart syncthing@root.service msg_ok "Installed Syncthing" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 0604dd72..13bfa0a3 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -138,10 +138,10 @@ systemctl enable --now -q tdarr-node.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index cb536f2e..079875b9 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -90,10 +90,10 @@ $STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) msg_ok "Installed Technitium DNS" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index 44f1c40a..29e86c90 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -90,10 +90,10 @@ systemctl start transmission-daemon msg_ok "Installed Transmission" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 936eac73..a2fa2f92 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -112,10 +112,10 @@ systemctl enable --now -q trilium msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 051e6554..6547ca36 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -71,6 +71,12 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') +cat </etc/apt/sources.list +deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main +EOF + msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade @@ -79,14 +85,13 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo -$STD apt-get install -y mc msg_ok "Installed Dependencies" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index e07e745a..2d6cab06 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -101,10 +101,10 @@ $STD systemctl enable --now umbrel-startup.service msg_ok "Installed Umbrel" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index fa1c90ea..3b30be60 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -96,10 +96,10 @@ $STD bash unifi-latest.sh --skip --add-repository $LOCAL msg_ok "Installed UniFi Network Application" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index d53bacc8..eb4debfa 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -116,10 +116,10 @@ $STD systemctl enable --now uptime-kuma.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 1421be40..91de64ff 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -173,10 +173,10 @@ $STD systemctl enable --now vaultwarden.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index c07df625..90ff1a86 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -111,10 +111,10 @@ systemctl enable --now -q whisparr msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 2d3e996d..8b04e690 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -105,10 +105,10 @@ $STD systemctl enable --now whoogle.service msg_ok "Installed Whoogle" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 36f48110..6207a120 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -133,10 +133,10 @@ $STD systemctl enable --now wikijs msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 95598151..57a2405e 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -105,10 +105,10 @@ $STD bash <(curl -fsSL https://install.pivpn.io) --unattended options.conf msg_ok "Installed WireGuard" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 912136e7..784492db 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -92,10 +92,10 @@ $STD bash <(curl -fsSL https://install.yunohost.org) -a msg_ok "Installed YunoHost" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index c24062c9..1b229424 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -132,10 +132,10 @@ $STD systemctl enable zigbee2mqtt.service msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 02e5b65e..0d2e7530 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -108,10 +108,10 @@ $STD systemctl enable zwave-js-ui msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* if ! getent shadow root | grep -q "^root:[^\!*]"; then msg_info "Customizing Container" -if [ "$PCT_OSTYPE" == "debian" ]; then rm -rf /etc/motd /etc/update-motd.d/10-uname; else chmod -x /etc/update-motd.d/*; fi - touch ~/.hushlogin GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) cat <$GETTY_OVERRIDE From 8e736f16800377179781e65bc7c64d7c26bf70ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Feb 2023 13:04:17 -0500 Subject: [PATCH 4338/6505] Update haos-vm-v5.sh tweak --- vm/haos-vm-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index 445f7f90..ef7970a0 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -274,7 +274,7 @@ else fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Home Assistant ${BRANCH} Disk Image" +msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image" if [ "$BRANCH" == "$DEV" ]; then URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz else From a79ecedb80fa92f4d27c5dd78f858b8ce287f64d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Feb 2023 15:14:43 -0500 Subject: [PATCH 4339/6505] revert change archive mirrors for Ubuntu (#1028) * revert change archive mirrors for Ubuntu --- install/deconz-v5-install.sh | 6 ------ install/emby-v5-install.sh | 6 ------ install/jellyfin-v5-install.sh | 6 ------ install/omada-v5-install.sh | 6 ------ install/plex-v5-install.sh | 6 ------ install/shinobi-v5-install.sh | 6 ------ install/ubuntu-v5-install.sh | 6 ------ 7 files changed, 42 deletions(-) diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 6a7f82a7..6b90e28a 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -71,12 +71,6 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e -CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') -cat </etc/apt/sources.list -deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -EOF - msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index fff7abed..56778328 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -71,12 +71,6 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e -CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') -cat </etc/apt/sources.list -deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -EOF - msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index e7633690..07fba79a 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -71,12 +71,6 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e -CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') -cat </etc/apt/sources.list -deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -EOF - msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index b56d4564..52c3eaad 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -71,12 +71,6 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e -CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') -cat </etc/apt/sources.list -deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -EOF - msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 660fa292..c9aa4532 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -71,12 +71,6 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e -CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') -cat </etc/apt/sources.list -deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -EOF - msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 29af4e26..58687086 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -71,12 +71,6 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e -CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') -cat </etc/apt/sources.list -deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -EOF - msg_info "Updating Container OS" $STD apt-get update --fix-missing $STD apt-get -y upgrade diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 6547ca36..ad0773de 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -71,12 +71,6 @@ RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e -CODENAME=$(cat /etc/*release | grep "UBUNTU_CODENAME" | awk '{print substr($1, 17, length($1)) }') -cat </etc/apt/sources.list -deb http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -deb-src http://mirror.genesisadaptive.com/ubuntu/ $CODENAME main -EOF - msg_info "Updating Container OS" $STD apt-get update $STD apt-get -y upgrade From d3bceff8ae42f6eb576748b3aa0a39b1a40a5e97 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Feb 2023 00:00:13 -0500 Subject: [PATCH 4340/6505] Misc updates (#1030) * add back mc in ubuntu * omada 5.8.4 --- install/deconz-v5-install.sh | 1 + install/emby-v5-install.sh | 1 + install/jellyfin-v5-install.sh | 1 + install/omada-v5-install.sh | 9 +++++---- install/plex-v5-install.sh | 1 + install/shinobi-v5-install.sh | 2 +- install/ubuntu-v5-install.sh | 1 + 7 files changed, 11 insertions(+), 5 deletions(-) diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 6b90e28a..b2292b3c 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -79,6 +79,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 56778328..b2a4deb5 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -79,6 +79,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 07fba79a..92c16950 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -79,6 +79,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y apt-transport-https $STD apt-get install -y software-properties-common msg_ok "Installed Dependencies" diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 52c3eaad..e498ee12 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -79,6 +79,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg $STD apt-get install -y openjdk-8-jre-headless $STD apt-get install -y jsvc @@ -86,9 +87,9 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed Dependencies" -msg_info "Installing Omada Controller v5.7.4" -wget -qL https://static.tp-link.com/upload/software/2022/202211/20221121/Omada_SDN_Controller_v5.7.4_Linux_x64.deb -$STD dpkg -i Omada_SDN_Controller_v5.7.4_Linux_x64.deb +msg_info "Installing Omada Controller v5.8.4" +wget -qL https://static.tp-link.com/upload/software/2023/202301/20230130/Omada_SDN_Controller_v5.8.4_Linux_x64.tar.gz +$STD dpkg -i Omada_SDN_Controller_v5.8.4_Linux_x64.deb msg_ok "Installed Omada Controller" echo "export TERM='xterm-256color'" >>/root/.bashrc @@ -110,7 +111,7 @@ fi if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_v5.7.4_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb +rm -rf Omada_SDN_Controller_v5.8.4_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index c9aa4532..4fc4bfe4 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -79,6 +79,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc $STD apt-get install -y gnupg msg_ok "Installed Dependencies" diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 58687086..c83579f1 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -86,7 +86,7 @@ if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then fi msg_info "Installing Dependencies" -$STD apt-get install -y curl sudo git +$STD apt-get install -y curl sudo git mc $STD apt-get install -y make zip net-tools $STD apt-get install -y gcc g++ cmake msg_ok "Installed Dependencies" diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index ad0773de..0cb3c135 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -79,6 +79,7 @@ msg_ok "Updated Container OS" msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y mc msg_ok "Installed Dependencies" echo "export TERM='xterm-256color'" >>/root/.bashrc From 6368c9f72fcdf5706e6a54fff8ba2928782c28a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Feb 2023 05:16:14 -0500 Subject: [PATCH 4341/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 80586942..937dcb5c 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -31,7 +31,6 @@ clear containers=$(pct list | tail -n +2 | cut -f1 -d' ') function update_container() { container=$1 - clear header_info name=$(pct exec "$container" hostname) echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} \n" From 1a3e3fb4ab71beb4067aeb6491dea7971497e167 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Feb 2023 11:33:32 -0500 Subject: [PATCH 4342/6505] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index b3b9c59c..733d43ad 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 tteck +Copyright (c) 2021-2023 tteck Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 44c614f65dc849b4331920926b1f15e55b1de2bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Feb 2023 12:15:22 -0500 Subject: [PATCH 4343/6505] include information (#1032) --- ct/adguard-v5.sh | 6 ++++++ ct/alpine-v5.sh | 6 ++++++ ct/archlinux-v5.sh | 6 ++++++ ct/audiobookshelf-v5.sh | 6 ++++++ ct/autobrr-v5.sh | 6 ++++++ ct/blocky-v5.sh | 6 ++++++ ct/casaos-v5.sh | 6 ++++++ ct/changedetection-v5.sh | 6 ++++++ ct/create_lxc.sh | 6 ++++++ ct/cronicle-v5.sh | 6 ++++++ ct/daemonsync-v5.sh | 6 ++++++ ct/dashy-v5.sh | 6 ++++++ ct/debian-v5.sh | 6 ++++++ ct/deconz-v5.sh | 6 ++++++ ct/deluge-v5.sh | 6 ++++++ ct/devuan-v5.sh | 6 ++++++ ct/docker-v5.sh | 6 ++++++ ct/emby-v5.sh | 6 ++++++ ct/emqx-v5.sh | 6 ++++++ ct/esphome-v5.sh | 6 ++++++ ct/grafana-v5.sh | 6 ++++++ ct/grocy-v5.sh | 6 ++++++ ct/heimdalldashboard-v5.sh | 6 ++++++ ct/homeassistant-core-v5.sh | 6 ++++++ ct/homeassistant-v5.sh | 6 ++++++ ct/homebridge-v5.sh | 6 ++++++ ct/homepage-v5.sh | 6 ++++++ ct/homer-v5.sh | 6 ++++++ ct/hyperion-v5.sh | 6 ++++++ ct/influxdb-v5.sh | 6 ++++++ ct/iobroker-v5.sh | 6 ++++++ ct/jellyfin-v5.sh | 6 ++++++ ct/k0s-v5.sh | 6 ++++++ ct/kavita-v5.sh | 6 ++++++ ct/keycloak-v5.sh | 6 ++++++ ct/lidarr-v5.sh | 6 ++++++ ct/magicmirror-v5.sh | 6 ++++++ ct/mariadb-v5.sh | 6 ++++++ ct/meshcentral-v5.sh | 6 ++++++ ct/motioneye-v5.sh | 6 ++++++ ct/mqtt-v5.sh | 6 ++++++ ct/n8n-v5.sh | 6 ++++++ ct/navidrome-v5.sh | 6 ++++++ ct/nextcloudpi-v5.sh | 6 ++++++ ct/nginxproxymanager-v5.sh | 6 ++++++ ct/nocodb-v5.sh | 6 ++++++ ct/node-red-v5.sh | 6 ++++++ ct/omada-v5.sh | 6 ++++++ ct/omv-v5.sh | 6 ++++++ ct/openhab-v5.sh | 6 ++++++ ct/paperless-ngx-v5.sh | 6 ++++++ ct/photoprism-v5.sh | 6 ++++++ ct/pihole-v5.sh | 6 ++++++ ct/plex-v5.sh | 6 ++++++ ct/podman-homeassistant-v5.sh | 6 ++++++ ct/podman-v5.sh | 6 ++++++ ct/postgresql-v5.sh | 6 ++++++ ct/prometheus-v5.sh | 6 ++++++ ct/prowlarr-v5.sh | 6 ++++++ ct/radarr-v5.sh | 6 ++++++ ct/readarr-v5.sh | 6 ++++++ ct/rockylinux-v5.sh | 6 ++++++ ct/sabnzbd-v5.sh | 6 ++++++ ct/scrypted-v5.sh | 6 ++++++ ct/shinobi-v5.sh | 6 ++++++ ct/sonarr-v5.sh | 6 ++++++ ct/syncthing-v5.sh | 6 ++++++ ct/tdarr-v5.sh | 6 ++++++ ct/technitiumdns-v5.sh | 6 ++++++ ct/transmission-v5.sh | 6 ++++++ ct/trilium-v5.sh | 6 ++++++ ct/ubuntu-v5.sh | 6 ++++++ ct/umbrel-v5.sh | 6 ++++++ ct/unifi-v5.sh | 6 ++++++ ct/uptimekuma-v5.sh | 6 ++++++ ct/vaultwarden-v5.sh | 6 ++++++ ct/whisparr-v5.sh | 6 ++++++ ct/whoogle-v5.sh | 6 ++++++ ct/wikijs-v5.sh | 6 ++++++ ct/wireguard-v5.sh | 6 ++++++ ct/yunohost-v5.sh | 6 ++++++ ct/zigbee2mqtt-v5.sh | 6 ++++++ ct/zwave-js-ui-v5.sh | 6 ++++++ install/adguard-v5-install.sh | 6 ++++++ install/audiobookshelf-v5-install.sh | 6 ++++++ install/autobrr-v5-install.sh | 6 ++++++ install/blocky-v5-install.sh | 6 ++++++ install/casaos-v5-install.sh | 6 ++++++ install/changedetection-v5-install.sh | 6 ++++++ install/cronicle-v5-install.sh | 6 ++++++ install/daemonsync-v5-install.sh | 6 ++++++ install/dashy-v5-install.sh | 6 ++++++ install/debian-v5-install.sh | 6 ++++++ install/deconz-v5-install.sh | 6 ++++++ install/deluge-v5-install.sh | 6 ++++++ install/devuan-v5-install.sh | 6 ++++++ install/docker-v5-install.sh | 6 ++++++ install/emby-v5-install.sh | 6 ++++++ install/emqx-v5-install.sh | 6 ++++++ install/esphome-v5-install.sh | 6 ++++++ install/grafana-v5-install.sh | 6 ++++++ install/grocy-v5-install.sh | 6 ++++++ install/heimdalldashboard-v5-install.sh | 6 ++++++ install/homeassistant-core-v5-install.sh | 6 ++++++ install/homeassistant-v5-install.sh | 6 ++++++ install/homebridge-v5-install.sh | 6 ++++++ install/homepage-v5-install.sh | 6 ++++++ install/homer-v5-install.sh | 6 ++++++ install/hyperion-v5-install.sh | 6 ++++++ install/influxdb-v5-install.sh | 6 ++++++ install/iobroker-v5-install.sh | 6 ++++++ install/jellyfin-v5-install.sh | 6 ++++++ install/k0s-v5-install.sh | 6 ++++++ install/kavita-v5-install.sh | 6 ++++++ install/keycloak-v5-install.sh | 6 ++++++ install/lidarr-v5-install.sh | 6 ++++++ install/magicmirror-v5-install.sh | 6 ++++++ install/mariadb-v5-install.sh | 6 ++++++ install/meshcentral-v5-install.sh | 6 ++++++ install/motioneye-v5-install.sh | 6 ++++++ install/mqtt-v5-install.sh | 6 ++++++ install/n8n-v5-install.sh | 6 ++++++ install/navidrome-v5-install.sh | 6 ++++++ install/nextcloudpi-v5-install.sh | 6 ++++++ install/nginxproxymanager-v5-install.sh | 6 ++++++ install/nocodb-v5-install.sh | 6 ++++++ install/node-red-v5-install.sh | 6 ++++++ install/omada-v5-install.sh | 6 ++++++ install/omv-v5-install.sh | 6 ++++++ install/openhab-v5-install.sh | 6 ++++++ install/paperless-ngx-v5-install.sh | 6 ++++++ install/photoprism-v5-install.sh | 6 ++++++ install/pihole-v5-install.sh | 6 ++++++ install/plex-v5-install.sh | 6 ++++++ install/podman-homeassistant-v5-install.sh | 6 ++++++ install/podman-v5-install.sh | 6 ++++++ install/postgresql-v5-install.sh | 6 ++++++ install/prometheus-v5-install.sh | 6 ++++++ install/prowlarr-v5-install.sh | 6 ++++++ install/radarr-v5-install.sh | 6 ++++++ install/readarr-v5-install.sh | 6 ++++++ install/sabnzbd-v5-install.sh | 6 ++++++ install/scrypted-v5-install.sh | 6 ++++++ install/shinobi-v5-install.sh | 6 ++++++ install/sonarr-v5-install.sh | 6 ++++++ install/syncthing-v5-install.sh | 6 ++++++ install/tdarr-v5-install.sh | 6 ++++++ install/technitiumdns-v5-install.sh | 6 ++++++ install/transmission-v5-install.sh | 6 ++++++ install/trilium-v5-install.sh | 6 ++++++ install/ubuntu-v5-install.sh | 6 ++++++ install/umbrel-v5-install.sh | 6 ++++++ install/unifi-v5-install.sh | 6 ++++++ install/uptimekuma-v5-install.sh | 6 ++++++ install/vaultwarden-v5-install.sh | 6 ++++++ install/whisparr-v5-install.sh | 6 ++++++ install/whoogle-v5-install.sh | 6 ++++++ install/wikijs-v5-install.sh | 6 ++++++ install/wireguard-v5-install.sh | 6 ++++++ install/yunohost-v5-install.sh | 6 ++++++ install/zigbee2mqtt-v5-install.sh | 6 ++++++ install/zwave-js-ui-v5-install.sh | 6 ++++++ misc/add-tailscale-lxc.sh | 6 ++++++ misc/bluetooth.sh | 6 ++++++ misc/clean-lxcs.sh | 8 +++++++- misc/clean.sh | 6 ++++++ misc/code-server.sh | 6 ++++++ misc/container-restore-from-backup.sh | 6 ++++++ ...container-copy-data-home-assistant-container.sh | 6 ++++++ ...tant-container-copy-data-home-assistant-core.sh | 6 ++++++ ...nt-container-copy-data-podman-home-assistant.sh | 6 ++++++ ...tant-core-copy-data-home-assistant-container.sh | 6 ++++++ ...assistant-core-copy-data-home-assistant-core.sh | 6 ++++++ misc/copy-data/plex-copy-data-plex.sh | 6 ++++++ ...assistant-copy-data-home-assistant-container.sh | 6 ++++++ misc/copy-data/z2m-copy-data-z2m.sh | 6 ++++++ misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh | 6 ++++++ misc/core-restore-from-backup.sh | 6 ++++++ misc/crowdsec.sh | 6 ++++++ misc/edge-kernel.sh | 6 ++++++ misc/filebrowser.sh | 6 ++++++ misc/frigate-support.sh | 6 ++++++ misc/kernel-clean.sh | 8 +++++++- misc/post-pbs-install.sh | 8 +++++++- misc/post-pve-install.sh | 8 +++++++- misc/pyenv.sh | 14 +++++++++++++- misc/scaling-governor.sh | 6 ++++++ misc/update-lxcs.sh | 6 ++++++ misc/usb-passthrough.sh | 6 ++++++ misc/webmin.sh | 5 +++++ vm/haos-vm-v5.sh | 6 ++++++ vm/mikrotik-routeros-v5.sh | 6 ++++++ vm/pimox-haos-vm-v5.sh | 6 ++++++ 193 files changed, 1168 insertions(+), 5 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index d27ffa28..2022e1f7 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ___ __ __ diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 4b29ba88..f48475c6 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ___ v5 __ _ diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index d3c3009e..5349d521 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ___ __ __ _ diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 55e121d0..c55385f7 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ___ __ __ __ ______ diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index ba683924..e5fdb60f 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ___ __ __ diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index 321a6932..ccf94f66 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ __ diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 994be9a2..416743d9 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ ____ _____ diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 2e9939ff..7ef66909 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ________ ____ __ __ _ diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index ecb62d96..f8326f55 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" == "yes" ]; then set -x; fi YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 8097937e..a8ce108b 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ _ __ diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index bc351a7d..49e06d6c 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ _____ diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 7a5f9354..7f51ba45 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 1f0cb49c..2b3bd1c5 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ _ diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 85f27fe0..f26890fb 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __________ _ _______ diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index ba79ee1c..f2f62f56 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index 79871ef6..cc5e9253 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index ae6085f4..25b390a2 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 57c35026..6d9d2fac 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ __ diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index b0e091ca..3ea8ff96 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ________ _______v5 _ __ diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index bf580607..fb44c748 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ___________ ____ __ __ diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 20947e81..6ac359a5 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ ____ diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index f715b57e..c1bb4dbd 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __________ _______ __ diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 396e5825..8d890a1f 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ _ _ _ ___ _ _ _ diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 83b04839..f7c432c5 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ _ _ _ ___ diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 04f7f93a..df6808f6 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ ___ _ __ __ diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 851b72bc..5442b1b1 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ______ __ _____________ ____ ________ ____________ diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index a93adf81..620dee04 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 458bbd87..f9b75c3d 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index bd2f7106..81e30620 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ _ diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 9f3889e8..eaf8ada3 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ ______ ____ ____ diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 2099aa8e..55e1d493 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ ____ __ diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index a81b354e..e5b677be 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ____ _____ diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 1e5f3e92..04c0e1f1 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ____ __ __ __ __ diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index acf18be2..e8dd83d4 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ _ __ diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index e3e8eac0..e4a3aad0 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ __ __ diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 636e4e0a..aff50b74 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ _ __ diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 50432f13..5862a8e6 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ___ _ __ ____ diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index d37c0186..6ea66777 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ___ _ ____ ____ diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 68285c3b..79609b9d 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ___ __ ______ __ __ diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index eb08e9b1..f50a8cf5 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ___ __ _ diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index f7995b7f..f5de113d 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ___ ____ _ ____________ diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index beb58747..2132cdd1 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ___ diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index c382844a..2999950c 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ __ _ __ diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 20909da5..bcc07914 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ __ __ ________ ______ _ diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index a1f96474..94a17159 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ __ _ ____ __ ___ diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index be844bf6..c9e31080 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ __ ____ ____ diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 2784b41f..e4016d4d 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ __ __ ____ __ diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 0af724ce..0160d8f5 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 839b8b69..cda88be9 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ ___ ___ _ __ ____ diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 46720606..c183799f 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ _____ ____ diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 5b5d8a6f..050f77e2 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 33a810db..886008c8 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ ______ __________ ____ ____ _________ __ ___ diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 4ecb5d26..03fa249b 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ ____ __ ______ __ ______ diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index c973e8a0..25555eab 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ __ ___ ___ _____ diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 8f88bf64..f6da09c4 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 048c6a50..75b3170c 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index ff6dcbf0..f6c599f6 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ _____ ____ __ diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 898b61b0..3f61b2c8 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ __ diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index 3ff3a087..b9398fe7 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index a71f5265..e2c9b2f3 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 71dde5fe..1810c403 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index 421a5eab..f548f14b 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ __ __ _ diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 885619eb..01dfcd56 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _____ ___ ____ __ __ diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 9e0c1244..cc759881 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _____ __ __ diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 54abd42f..cad79e5c 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _____ __ _ __ _ diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 7e5f472e..000becd3 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _____ diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index d11d2c2d..2c1c13d1 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _____ __ __ _ diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 679b1258..12be69a4 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ __ diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 9fd8c7f3..729a6c3b 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ __ _ __ _ ____ _ _______ diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index ff634702..f99e4644 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ _ _ diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 7a6648e4..e6b8b540 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ _ ___ diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index ece6935e..3416113c 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ____ __ diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index fbf3e650..24c40e7e 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ __ __ diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 7c395c9e..78b76c0c 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ _ _____ diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index af07651f..2af3e44c 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ __ _ __ __ diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 1eff8d4e..6165882d 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ __ ____ _ __ __ diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 3549ade0..0adfdfed 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ ____ _ diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 2027bf44..d3c6b07c 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ ____ ______ ____ ________ ______ diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 80f0cd42..5e4ecb02 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ ___ __ _ _ diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 642ff613..ea6c3d1a 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _ ___ ______ __ diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index ca1efda9..c4b7f2a5 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ __ __ __ diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index c5c789a1..42767d5d 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _____ _ __ ___ __ _______ ____________ diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 6d3f63cc..293abf26 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _____ _______ __ ______ diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index f4c92d4c..e74135d9 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index 51d38430..0be7f07a 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 4414672e..1485c75b 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index 5c4bef55..f51e98fb 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index fa81060c..ada2bb6b 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index 2827bfc7..7d2bda09 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 8f7d152c..a8bb2b6d 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 16f410c1..9b5e7eea 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index f6421b9a..565690e2 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index e910d9e5..7a4f410e 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index b2292b3c..2d51c7e0 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 776814e7..da12b769 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/devuan-v5-install.sh b/install/devuan-v5-install.sh index 9da236b1..da159dbe 100644 --- a/install/devuan-v5-install.sh +++ b/install/devuan-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 091dfdec..31ceda72 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index b2a4deb5..066dc17d 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 23df928a..9529d961 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index b2af525e..2a8f81f6 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 2abf3dff..159fefe2 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index d23ff417..f8087bbd 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index fac55718..f0eee420 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 83695041..ac3cc58d 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index f86f089e..071ab8af 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 4e1e4c92..f07731d6 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 3ef04b4b..d4a4e801 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 70d9ee17..bf873e80 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 2eba6ef7..cdf9fd91 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index dc918a9a..5f4d9f67 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 6db17570..9316795f 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 92c16950..11451bf2 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index dcb6de05..fc6f6314 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 21245848..b6e0d230 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index d64ef3a1..ae2a6754 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index d3e8b945..d5798b44 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index f53c1689..9b48fc35 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 72cf2410..07c6486b 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index 67cc6747..f37c5614 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 1575f17f..2c177e73 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 53b39b32..980ad410 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index be76bfa3..1881f808 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 33ae8d3e..2dd1b369 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 4396c90c..4b4c4d21 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 99b09e8a..d1b5cd4b 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index d22f7308..c5ecc2fb 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index a127c44d..5b548bf0 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index e498ee12..fffee12b 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 32151fa7..22319f8b 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index 54b87c0a..fc7861d1 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 5c076deb..48ed0e08 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index f167d361..fe1093d3 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index fb175b07..0d3ae506 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 4fc4bfe4..f7b00eee 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 56853cf3..53779ee1 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 91d1e340..7b366a9c 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 0fa74a59..d9dba2eb 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 7ee69706..85009f9a 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 5e9bf052..b4e6a048 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index b2829bf8..822edb0f 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index 66ad0e93..bffb5dc6 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index bae07f8a..9856ec3a 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index e67b5a15..69805c7f 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index c83579f1..69d1e634 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 9eb09159..1980b551 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + export DEBIAN_FRONTEND=noninteractive if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index f362c31e..38c001a1 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 13bfa0a3..35dc88b0 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 079875b9..39c50d12 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index 29e86c90..f11bbdbf 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index a2fa2f92..8a72a790 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 0cb3c135..d7569a6f 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 2d6cab06..8bfaaadb 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 3b30be60..6d9ece10 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index eb4debfa..674bc025 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 91de64ff..b8d5f39e 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 90ff1a86..b97cd37a 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 8b04e690..0897cac6 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 6207a120..fb3aecbd 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 57a2405e..b36f310d 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 784492db..4598cbd8 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 1b229424..89e08b24 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 0d2e7530..6118ef0f 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 73ee67ee..52de7c9f 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ _ __ __ diff --git a/misc/bluetooth.sh b/misc/bluetooth.sh index 69ea28e4..c95a1815 100644 --- a/misc/bluetooth.sh +++ b/misc/bluetooth.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi set -e clear diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 8c35219a..bb445767 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -1,4 +1,10 @@ -#!/bin/bash +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { clear cat <<"EOF" diff --git a/misc/clean.sh b/misc/clean.sh index 8146ff52..8c604b46 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info() { clear cat <<"EOF" diff --git a/misc/code-server.sh b/misc/code-server.sh index 03285dcb..cc32de97 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ______ __ _____ diff --git a/misc/container-restore-from-backup.sh b/misc/container-restore-from-backup.sh index bc0a6b52..efb169d1 100644 --- a/misc/container-restore-from-backup.sh +++ b/misc/container-restore-from-backup.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + clear if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi YW=$(echo "\033[33m") diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh index f9410471..0ff1828e 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + # Use to copy all data from one Home Assistant LXC to another # run from the Proxmox Shell clear diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh index 29728e47..f278911a 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + clear if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do diff --git a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh index 2442a576..62f9ed8b 100644 --- a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh +++ b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. # run from the Proxmox Shell clear diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh index ab037fc1..3a451f17 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + clear if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh index 28e0997b..5244c284 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + clear if ! command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Run from the Proxmox Shell"; exit; fi while true; do diff --git a/misc/copy-data/plex-copy-data-plex.sh b/misc/copy-data/plex-copy-data-plex.sh index 399ddcb0..35e43bea 100644 --- a/misc/copy-data/plex-copy-data-plex.sh +++ b/misc/copy-data/plex-copy-data-plex.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + # Use to copy all data from one Plex Media Server LXC to another # run from the Proxmox Shell clear diff --git a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh index d9c1d9dd..8db36359 100644 --- a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh +++ b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + # Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. # run from the Proxmox Shell clear diff --git a/misc/copy-data/z2m-copy-data-z2m.sh b/misc/copy-data/z2m-copy-data-z2m.sh index 0cdd7651..69a3573a 100644 --- a/misc/copy-data/z2m-copy-data-z2m.sh +++ b/misc/copy-data/z2m-copy-data-z2m.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + # Use to copy all data from one Zigbee2MQTT LXC to another # run from the Proxmox Shell clear diff --git a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh index c45ececc..9f58fc5b 100644 --- a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh +++ b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + # Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC # run from the Proxmox Shell clear diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh index 6f65801b..0f41adfc 100644 --- a/misc/core-restore-from-backup.sh +++ b/misc/core-restore-from-backup.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + clear if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi YW=$(echo "\033[33m") diff --git a/misc/crowdsec.sh b/misc/crowdsec.sh index 7f509ba8..712e0b19 100644 --- a/misc/crowdsec.sh +++ b/misc/crowdsec.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 7214595d..876f5cab 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" function header_info { cat <<"EOF" diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index 893c834b..02545b48 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" _______ __ ____ diff --git a/misc/frigate-support.sh b/misc/frigate-support.sh index 0341c2cd..21b641d5 100644 --- a/misc/frigate-support.sh +++ b/misc/frigate-support.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + echo -e "\e[1;33m This script will Prepare a LXC Container for Frigate \e[0m" while true; do read -p "Did you replace 106 with your LXC ID? Proceed (y/n)?" yn diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 824d708a..053215af 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -1,4 +1,10 @@ -#!/usr/bin/env bash -ex +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ __ ________ diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index 7b29e5f4..2a6ff6f0 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -1,4 +1,10 @@ -#!/usr/bin/env bash -ex +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + set -euo pipefail shopt -s inherit_errexit nullglob YW=$(echo "\033[33m") diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 2c3031fd..0cd732f6 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -1,4 +1,10 @@ -#!/usr/bin/env bash -ex +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ _ _____________ ____ __ ____ __ ____ diff --git a/misc/pyenv.sh b/misc/pyenv.sh index 51120c62..5fb41779 100644 --- a/misc/pyenv.sh +++ b/misc/pyenv.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + set -e YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") @@ -108,7 +114,13 @@ python3 -m pip install wheel &>/dev/null pip3 install --upgrade pip &>/dev/null pip3 install --pre esphome &>/dev/null cat </srv/esphome/start.sh -#!/bin/bash +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + source /srv/esphome/bin/activate esphome dashboard /srv/esphome/ EOF diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index e7eea1d2..edecd2c4 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __________ __ __ diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 937dcb5c..38031eb2 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { clear cat <<"EOF" diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index b8623d3b..8274d96b 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + echo -e "\e[1;33m This script will allow USB passthrough to a PRIVILEGED LXC Container ONLY\e[0m" while true; do read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn diff --git a/misc/webmin.sh b/misc/webmin.sh index b997df5f..0095a911 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -1,5 +1,10 @@ #!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index ef7970a0..f4e7e4dd 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ __ ___ _ __ __ ____ _____ diff --git a/vm/mikrotik-routeros-v5.sh b/vm/mikrotik-routeros-v5.sh index 0c13b8dc..7e0bcdda 100644 --- a/vm/mikrotik-routeros-v5.sh +++ b/vm/mikrotik-routeros-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" __ ____ __ __ _ __ ____ __ ____ _____ diff --git a/vm/pimox-haos-vm-v5.sh b/vm/pimox-haos-vm-v5.sh index cebce5e2..c116c84a 100644 --- a/vm/pimox-haos-vm-v5.sh +++ b/vm/pimox-haos-vm-v5.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + function header_info { cat <<"EOF" ____ _ __ ___ From e1ae1c7c19d180356ecf4bf5b33e47e64ed00fcf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Feb 2023 15:43:49 -0500 Subject: [PATCH 4344/6505] Update omada-v5-install.sh correct file extension --- install/omada-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index fffee12b..0271ba38 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -94,7 +94,7 @@ $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed Dependencies" msg_info "Installing Omada Controller v5.8.4" -wget -qL https://static.tp-link.com/upload/software/2023/202301/20230130/Omada_SDN_Controller_v5.8.4_Linux_x64.tar.gz +wget -qL https://static.tp-link.com/upload/software/2023/202301/20230130/Omada_SDN_Controller_v5.8.4_Linux_x64.deb $STD dpkg -i Omada_SDN_Controller_v5.8.4_Linux_x64.deb msg_ok "Installed Omada Controller" From 91772f8c730844587db7a21e9962cbe954ba6dc7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Feb 2023 17:11:02 -0500 Subject: [PATCH 4345/6505] tweak (#1034) --- ct/audiobookshelf-v5.sh | 4 ++-- ct/debian-v5.sh | 4 ++-- ct/deluge-v5.sh | 4 ++-- ct/devuan-v5.sh | 4 ++-- ct/kavita-v5.sh | 4 ++-- ct/lidarr-v5.sh | 4 ++-- ct/prowlarr-v5.sh | 4 ++-- ct/radarr-v5.sh | 4 ++-- ct/readarr-v5.sh | 4 ++-- ct/sabnzbd-v5.sh | 4 ++-- ct/sonarr-v5.sh | 4 ++-- ct/tdarr-v5.sh | 4 ++-- ct/whisparr-v5.sh | 4 ++-- ct/yunohost-v5.sh | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index c55385f7..981f227d 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 2b3bd1c5..02e30838 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index f2f62f56..e69cd92a 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -337,10 +337,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index cc5e9253..fe55f367 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index e8dd83d4..c5338e4d 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -339,10 +339,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index aff50b74..931ca190 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index b9398fe7..5a6e998d 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index e2c9b2f3..20ed874d 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 1810c403..0dffef6a 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 01dfcd56..40bffdbf 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 000becd3..7ca8a5d7 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 12be69a4..3319a7e3 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 0adfdfed..87043a9b 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -337,10 +337,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index c4b7f2a5..cabde660 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -336,10 +336,10 @@ function install_script() { function update_script() { clear header_info -msg_info "Updating Debian LXC" +msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Debian LXC" +msg_ok "Updated $APP LXC" exit } clear From 4d8285a48425cbee31dc59142230d77f66d999ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Feb 2023 17:50:50 -0500 Subject: [PATCH 4346/6505] Update podman-homeassistant-v5.sh fix ending fi --- ct/podman-homeassistant-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index f6da09c4..b1581dff 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -356,6 +356,7 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit +fi if [ "$UPD" == "2" ]; then msg_info "Installing Home Assistant Comunity Store (HACS)" apt update &>/dev/null From 15c6c046aba1c1a94f8686410c55d3fc4e476ccc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Feb 2023 03:59:42 -0500 Subject: [PATCH 4347/6505] Update paperless-ngx-v5-install.sh correct missing network retries --- install/paperless-ngx-v5-install.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 48ed0e08..10a752ce 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -47,15 +47,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" From 85895bffa7aa947f3ca27c51b0a58320dd65344f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Feb 2023 04:05:21 -0500 Subject: [PATCH 4348/6505] Update magicmirror-v5-install.sh correct missing network retries --- install/magicmirror-v5-install.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 9b48fc35..9f141744 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -47,15 +47,18 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -while [ "$(hostname -I)" = "" ]; do - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - ((NUM--)) - if [ $NUM -eq 0 ]; then - echo 1>&2 -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - exit 1 - fi +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" From d671df97c91d14b35df144adddb26de1de7bf76c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Feb 2023 12:00:17 -0500 Subject: [PATCH 4349/6505] Update haos-vm-v5.sh code optimization --- vm/haos-vm-v5.sh | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index f4e7e4dd..6a5f5c6c 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -19,12 +19,11 @@ clear header_info echo -e "\n Loading..." GEN_MAC=02:$(openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | tr '[:lower:]' '[:upper:]') -USEDID=$(pvesh get /cluster/resources --type vm --output-format yaml | egrep -i 'vmid' | awk '{print substr($2, 1, length($2)-0) }') NEXTID=$(pvesh get /cluster/nextid) -STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -LATEST=$(curl -s https://api.github.com/repos/home-assistant/operating-system/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | cut -d '"' -f 4) +BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | cut -d '"' -f 4) +DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | cut -d '"' -f 4) +LATEST=$(curl -s https://api.github.com/repos/home-assistant/operating-system/releases/latest | grep "tag_name" | cut -d '"' -f 4) YW=`echo "\033[33m"` BL=`echo "\033[36m"` HA=`echo "\033[1;34m"` @@ -69,13 +68,12 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if (whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58); then - echo "User selected Yes" +if whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then + : else - clear - echo -e "⚠ User exited script \n" - exit + clear && echo -e "⚠ User exited script \n" && exit fi + function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -100,7 +98,7 @@ fi function ARCH_CHECK() { ARCH=$(dpkg --print-architecture) if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -141,20 +139,24 @@ BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-b 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi -VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; +while true; do + VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z "$VMID" ]; then + VMID="$NEXTID" + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break else - if echo "$USEDID" | egrep -q "$VMID" - then - echo -e "\n🚨 ${RD}ID $VMID is already in use${CL} \n" - echo -e "Exiting Script \n" - sleep 2; - exit - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue fi -fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + fi +done + MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "i440fx" "Machine i440fx" ON \ "q35" "Machine q35" OFF \ From 4d83642522fbf83e877e6269e01733163a2f95a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Feb 2023 11:44:07 -0500 Subject: [PATCH 4350/6505] Update nextcloudpi-v5.sh check path to update host --- ct/nextcloudpi-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index bcc07914..a8b21172 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -92,7 +92,7 @@ if command -v pveversion >/dev/null 2>&1; then fi fi if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then + if [[ ! -f /lib/systemd/system/nextcloud-domain.service ]]; then msg_error "No ${APP} Installation Found!"; exit fi From ae335b115528b80f0536bff6cb3caadd8a092d8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Feb 2023 20:15:09 -0500 Subject: [PATCH 4351/6505] Update haos-vm-v5.sh more code optimization --- vm/haos-vm-v5.sh | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index 6a5f5c6c..d30107d1 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -6,6 +6,7 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { +clear cat <<"EOF" __ __ ___ _ __ __ ____ _____ / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____v5/ /_ / __ \/ ___/ @@ -15,7 +16,6 @@ cat <<"EOF" EOF } -clear header_info echo -e "\n Loading..." GEN_MAC=02:$(openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | tr '[:lower:]' '[:upper:]') @@ -55,11 +55,9 @@ function error_exit() { exit $EXIT } function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null fi } function cleanup() { @@ -71,7 +69,7 @@ pushd $TEMP_DIR >/dev/null if whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then : else - clear && echo -e "⚠ User exited script \n" && exit + header_info && echo -e "⚠ User exited script \n" && exit fi function msg_info() { @@ -87,17 +85,16 @@ function msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { -if [ `pveversion | grep "pve-manager/7.2\|7.3" | wc -l` -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: =>7.2" - echo "Exiting..." - sleep 2 - exit +if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then + if [ "$(dpkg --print-architecture)" != "amd64" ]; then echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 @@ -232,7 +229,6 @@ fi if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" else - clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings @@ -240,12 +236,10 @@ fi } function START_SCRIPT() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - clear header_info echo -e "${BL}Using Default Settings${CL}" default_settings else - clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings From 992182d74d54ae040233ba0c6a07d741456a413c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 13:39:23 -0500 Subject: [PATCH 4352/6505] Update haos-vm-v5.sh Code refactoring --- vm/haos-vm-v5.sh | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index d30107d1..22f2a45e 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -20,10 +20,10 @@ header_info echo -e "\n Loading..." GEN_MAC=02:$(openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) -STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | cut -d '"' -f 4) -BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | cut -d '"' -f 4) -DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | cut -d '"' -f 4) -LATEST=$(curl -s https://api.github.com/repos/home-assistant/operating-system/releases/latest | grep "tag_name" | cut -d '"' -f 4) +VERSIONS=( stable beta dev ) +for version in "${VERSIONS[@]}"; do + eval "$version=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/$version.json | grep "ova" | cut -d '"' -f 4)" +done YW=`echo "\033[33m"` BL=`echo "\033[36m"` HA=`echo "\033[1;34m"` @@ -102,15 +102,15 @@ function ARCH_CHECK() { fi } function default_settings() { - echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} + echo -e "${DGN}Using HAOS Version: ${BGN}${stable}${CL}" + BRANCH=${stable} echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" VMID=$NEXTID echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" FORMAT=",efitype=4m" MACHINE="" - echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" - HN=haos${STABLE} + echo -e "${DGN}Using Hostname: ${BGN}haos${stable}${CL}" + HN=haos${stable} echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" CORE_COUNT="2" echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" @@ -128,11 +128,10 @@ function default_settings() { echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 4 \ -"$STABLE" "Stable" ON \ -"$BETA" "Beta" OFF \ -"$DEV" "Dev" OFF \ -"$LATEST" "Latest" OFF \ +BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ +"$stable" "Stable " ON \ +"$beta" "Beta " OFF \ +"$dev" "Dev " OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi @@ -277,7 +276,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image" -if [ "$BRANCH" == "$DEV" ]; then +if [ "$BRANCH" == "$dev" ]; then URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz else URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz From f1be33211eaa5b2f2a33cce4355c8302a4b237dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 14:02:16 -0500 Subject: [PATCH 4353/6505] Update haos-vm-v5.sh `awk` is more efficient than using `tr` as it doesn't need to create a new process --- vm/haos-vm-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index 22f2a45e..f721d285 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -18,7 +18,7 @@ EOF } header_info echo -e "\n Loading..." -GEN_MAC=02:$(openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | tr '[:lower:]' '[:upper:]') +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') NEXTID=$(pvesh get /cluster/nextid) VERSIONS=( stable beta dev ) for version in "${VERSIONS[@]}"; do From 9e2a0e18f24cb8bcb10f3fbf9e90a615cd5f4e5e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 14:43:58 -0500 Subject: [PATCH 4354/6505] Update haos-vm-v5.sh default settings more readable in code --- vm/haos-vm-v5.sh | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index f721d285..31728e62 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -102,30 +102,30 @@ function ARCH_CHECK() { fi } function default_settings() { - echo -e "${DGN}Using HAOS Version: ${BGN}${stable}${CL}" - BRANCH=${stable} - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" - FORMAT=",efitype=4m" - MACHINE="" - echo -e "${DGN}Using Hostname: ${BGN}haos${stable}${CL}" - HN=haos${stable} - echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" - CORE_COUNT="2" - echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" - echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" + BRANCH="$stable" + VMID="$NEXTID" + FORMAT=",efitype=4m" + MACHINE="" + HN="haos$stable" + CORE_COUNT="2" + RAM_SIZE="4096" + BRG="vmbr0" + MAC="$GEN_MAC" + VLAN="" + MTU="" + START_VM="yes" + echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ From 7b464da33c754763f9ae7747f03bf5ed15cc07f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 14:54:51 -0500 Subject: [PATCH 4355/6505] Update paperless-ngx-v5-install.sh nltk download all --- install/paperless-ngx-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 10a752ce..6df1d813 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -154,7 +154,7 @@ cd /opt/paperless sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt $STD pip install --upgrade pip $STD pip install -r requirements.txt -$STD python3 -m nltk.downloader -d /usr/share/nltk_data stopwords +$STD python3 -m nltk.downloader -d /usr/share/nltk_data all msg_ok "Installed Paperless-ngx" msg_info "Setting up database" From 57b4c2773ba7d188c81376cc99f0f49f3f1d666e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 16:11:12 -0500 Subject: [PATCH 4356/6505] Update paperless-ngx-v5.sh increase disk to 8GB --- ct/paperless-ngx-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 050f77e2..4e8ff9c3 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -20,7 +20,7 @@ clear header_info echo -e "Loading..." APP="Paperless-ngx" -var_disk="4" +var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" From 959cd5800e00f43a675f8f834a2c33468dec29a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 16:44:35 -0500 Subject: [PATCH 4357/6505] Update paperless-ngx-v5-install.sh tweak --- install/paperless-ngx-v5-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 6df1d813..0470345b 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -154,9 +154,12 @@ cd /opt/paperless sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt $STD pip install --upgrade pip $STD pip install -r requirements.txt -$STD python3 -m nltk.downloader -d /usr/share/nltk_data all msg_ok "Installed Paperless-ngx" +msg_info "Installing Natural Language Toolkit (Patience)" +$STD python3 -m nltk.downloader -d /usr/share/nltk_data all +msg_ok "Installed Natural Language Toolkit" + msg_info "Setting up database" DB_USER=paperless DB_PASS="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" From 0432ea1558b297c8ec4949b8af572c705e55c2f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 20:51:53 -0500 Subject: [PATCH 4358/6505] Update haos-vm-v5.sh add new error_handler --- vm/haos-vm-v5.sh | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index 31728e62..e89c1951 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -37,22 +37,16 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" THIN="discard=on,ssd=1," -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid } function cleanup_vmid() { if qm status $VMID &>/dev/null; then From 06831d61284aa0cd244cf2b07d84d298f438b946 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Feb 2023 21:17:50 -0500 Subject: [PATCH 4359/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 65b956ed..eb556ee4 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-02-10 + +### Changed + +- **Home Assistant OS VM** + - Code Refactoring + ## 2023-02-05 ### Changed From 0ddf5e210118046c9ee20f18e1389188c676cadb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Feb 2023 20:36:39 -0500 Subject: [PATCH 4360/6505] update pve & arch checks (#1044) * update ARCH_CHECK & PVE_CHECK * header_info * PVE 7 required --- ct/adguard-v5.sh | 28 ++++++++++++++-------------- ct/alpine-v5.sh | 28 ++++++++++++++-------------- ct/archlinux-v5.sh | 28 ++++++++++++++-------------- ct/audiobookshelf-v5.sh | 28 ++++++++++++++-------------- ct/autobrr-v5.sh | 28 ++++++++++++++-------------- ct/blocky-v5.sh | 28 ++++++++++++++-------------- ct/casaos-v5.sh | 28 ++++++++++++++-------------- ct/changedetection-v5.sh | 28 ++++++++++++++-------------- ct/cronicle-v5.sh | 28 ++++++++++++++-------------- ct/daemonsync-v5.sh | 28 ++++++++++++++-------------- ct/dashy-v5.sh | 28 ++++++++++++++-------------- ct/debian-v5.sh | 28 ++++++++++++++-------------- ct/deconz-v5.sh | 28 ++++++++++++++-------------- ct/deluge-v5.sh | 28 ++++++++++++++-------------- ct/devuan-v5.sh | 28 ++++++++++++++-------------- ct/docker-v5.sh | 28 ++++++++++++++-------------- ct/emby-v5.sh | 28 ++++++++++++++-------------- ct/emqx-v5.sh | 28 ++++++++++++++-------------- ct/esphome-v5.sh | 28 ++++++++++++++-------------- ct/grafana-v5.sh | 28 ++++++++++++++-------------- ct/grocy-v5.sh | 28 ++++++++++++++-------------- ct/heimdalldashboard-v5.sh | 28 ++++++++++++++-------------- ct/homeassistant-core-v5.sh | 32 ++++++++++++++++---------------- ct/homeassistant-v5.sh | 28 ++++++++++++++-------------- ct/homebridge-v5.sh | 28 ++++++++++++++-------------- ct/homepage-v5.sh | 28 ++++++++++++++-------------- ct/homer-v5.sh | 28 ++++++++++++++-------------- ct/hyperion-v5.sh | 25 ++++++++++++------------- ct/influxdb-v5.sh | 28 ++++++++++++++-------------- ct/iobroker-v5.sh | 28 ++++++++++++++-------------- ct/jellyfin-v5.sh | 28 ++++++++++++++-------------- ct/k0s-v5.sh | 28 ++++++++++++++-------------- ct/kavita-v5.sh | 28 ++++++++++++++-------------- ct/keycloak-v5.sh | 28 ++++++++++++++-------------- ct/lidarr-v5.sh | 28 ++++++++++++++-------------- ct/magicmirror-v5.sh | 28 ++++++++++++++-------------- ct/mariadb-v5.sh | 28 ++++++++++++++-------------- ct/meshcentral-v5.sh | 28 ++++++++++++++-------------- ct/motioneye-v5.sh | 28 ++++++++++++++-------------- ct/mqtt-v5.sh | 25 ++++++++++++------------- ct/n8n-v5.sh | 28 ++++++++++++++-------------- ct/navidrome-v5.sh | 28 ++++++++++++++-------------- ct/nextcloudpi-v5.sh | 28 ++++++++++++++-------------- ct/nginxproxymanager-v5.sh | 28 ++++++++++++++-------------- ct/nocodb-v5.sh | 28 ++++++++++++++-------------- ct/node-red-v5.sh | 29 ++++++++++++++--------------- ct/omada-v5.sh | 27 ++++++++++++++------------- ct/omv-v5.sh | 28 ++++++++++++++-------------- ct/openhab-v5.sh | 28 ++++++++++++++-------------- ct/paperless-ngx-v5.sh | 28 ++++++++++++++-------------- ct/photoprism-v5.sh | 28 ++++++++++++++-------------- ct/pihole-v5.sh | 28 ++++++++++++++-------------- ct/plex-v5.sh | 28 ++++++++++++++-------------- ct/podman-homeassistant-v5.sh | 28 ++++++++++++++-------------- ct/podman-v5.sh | 28 ++++++++++++++-------------- ct/postgresql-v5.sh | 28 ++++++++++++++-------------- ct/prometheus-v5.sh | 28 ++++++++++++++-------------- ct/prowlarr-v5.sh | 28 ++++++++++++++-------------- ct/radarr-v5.sh | 28 ++++++++++++++-------------- ct/readarr-v5.sh | 28 ++++++++++++++-------------- ct/rockylinux-v5.sh | 28 ++++++++++++++-------------- ct/sabnzbd-v5.sh | 28 ++++++++++++++-------------- ct/scrypted-v5.sh | 28 ++++++++++++++-------------- ct/shinobi-v5.sh | 28 ++++++++++++++-------------- ct/sonarr-v5.sh | 28 ++++++++++++++-------------- ct/syncthing-v5.sh | 28 ++++++++++++++-------------- ct/tdarr-v5.sh | 28 ++++++++++++++-------------- ct/technitiumdns-v5.sh | 28 ++++++++++++++-------------- ct/transmission-v5.sh | 28 ++++++++++++++-------------- ct/trilium-v5.sh | 28 ++++++++++++++-------------- ct/ubuntu-v5.sh | 28 ++++++++++++++-------------- ct/umbrel-v5.sh | 28 ++++++++++++++-------------- ct/unifi-v5.sh | 28 ++++++++++++++-------------- ct/uptimekuma-v5.sh | 28 ++++++++++++++-------------- ct/vaultwarden-v5.sh | 28 ++++++++++++++-------------- ct/whisparr-v5.sh | 28 ++++++++++++++-------------- ct/whoogle-v5.sh | 28 ++++++++++++++-------------- ct/wikijs-v5.sh | 28 ++++++++++++++-------------- ct/wireguard-v5.sh | 28 ++++++++++++++-------------- ct/yunohost-v5.sh | 28 ++++++++++++++-------------- ct/zigbee2mqtt-v5.sh | 28 ++++++++++++++-------------- ct/zwave-js-ui-v5.sh | 28 ++++++++++++++-------------- 82 files changed, 1146 insertions(+), 1148 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 2022e1f7..fa35e0c0 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ___ __ __ / | ____/ /___ ___v5______ __________/ / / /| |/ __ / __ / / / / __ / ___/ __ / @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Adguard" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Stopping AdguardHome" systemctl stop AdGuardHome @@ -364,8 +363,9 @@ msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index f48475c6..a7d31ece 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ___ v5 __ _ / | / /___ (_)___ ___ / /| | / / __ \/ / __ \/ _ \ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Alpine" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -335,7 +335,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apk update &>/dev/null @@ -343,8 +342,9 @@ apk upgrade &>/dev/null msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index 5349d521..c1e68f70 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ___ __ __ _ / | __________/ /_ v5 / / (_)___ __ ___ __ / /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Arch Linux" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" pacman-key --init @@ -347,8 +346,9 @@ pacman -Sy archlinux-keyring && pacman -Su msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 981f227d..05dda529 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ___ __ __ __ ______ ____ ___ ______/ (_)___v5/ /_ ____ ____ / /_______/ /_ ___ / / __/ / __ `/ / / / __ / / __ \/ __ \/ __ \/ __ \/ //_/ ___/ __ \/ _ \/ / /_ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="audiobookshelf" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index e5fdb60f..1fed6b3b 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ___ __ __ / | __ __/ /_____ / /_v5__________ / /| |/ / / / __/ __ \/ __ \/ ___/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Autobrr" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -337,7 +337,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Stopping ${APP} LXC" systemctl stop autobrr.service @@ -356,8 +355,9 @@ msg_ok "Started ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index ccf94f66..ab491a6e 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ __ / __ )/ /___v5_____/ /____ __ / __ / / __ \/ ___/ //_/ / / / @@ -15,7 +17,6 @@ function header_info { /____/ EOF } -clear header_info echo -e "Loading..." APP="Blocky" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 416743d9..04683e0d 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ ____ _____ / ____/___ __v5______ _/ __ \/ ___/ / / / __ `/ ___/ __ `/ / / /\__ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="CasaOS" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -346,7 +346,6 @@ function install_script() { fi } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -356,8 +355,9 @@ msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 7ef66909..152f314b 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ________ ____ __ __ _ / ____/ /_v5____ _____ ____ ____ / __ \___ / /____ _____/ /_(_)___ ____ / / / __ \/ __ `/ __ \/ __ `/ _ \ / / / / _ \/ __/ _ \/ ___/ __/ / __ \/ __ \ @@ -15,7 +17,6 @@ function header_info { /____/ EOF } -clear header_info echo -e "Loading..." APP="Change Detection" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" pip3 install changedetection.io --upgrade &>/dev/null @@ -346,8 +345,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index a8ce108b..56c4d075 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ _ __ / ____/________v5____ (_)____/ /__ / / / ___/ __ \/ __ \/ / ___/ / _ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Cronicle" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -341,7 +341,6 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb "2" "Install ${APP} Worker" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then if [[ ! -d /opt/cronicle ]]; then @@ -393,8 +392,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 49e06d6c..ccdd178d 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ _____ / __ \____ ____ ____ ___ ____ ____ / ___/__v5______ _____ / / / / __ / _ \/ __ __ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/ @@ -15,7 +17,6 @@ function header_info { /____/ EOF } -clear header_info echo -e "Loading..." APP="Daemon Sync" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 7f51ba45..79981fb6 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \____ ______/ /_ __ __ / / / / __ / ___/ __ \/ / / / @@ -15,7 +17,6 @@ function header_info { v5 /____/ EOF } -clear header_info echo -e "Loading..." APP="Dashy" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Stopping ${APP}" systemctl stop dashy @@ -373,8 +372,9 @@ msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 02e30838..03bb03ee 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ _ / __ \___v5/ /_ (_)___ _____ / / / / _ \/ __ \/ / __ `/ __ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Debian" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index f26890fb..61e4b0ab 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __________ _ _______ ____/ /v5 / ____/ __ \/ | / /__ / / __ / _ \/ / / / / / |/ / / / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="deCONZ" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -348,8 +347,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index e69cd92a..b3824328 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \___ / /_v5______ ____ / / / / _ \/ / / / / __ `/ _ \ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Deluge" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -335,7 +335,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -343,8 +342,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index fe55f367..3951de1f 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ / __ \___ _ ____ ______v5____ / / / / _ \ | / / / / / __ `/ __ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Devuan" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 25b390a2..98ea5d8c 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \____ _____/ /_v5__ _____ / / / / __ \/ ___/ //_/ _ \/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Docker" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -345,7 +345,6 @@ function install_script() { fi } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -353,8 +352,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 6d9d2fac..9cd4053d 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ __ / ____/___ v5_ / /_ __ __ / __/ / __ __ \/ __ \/ / / / @@ -15,7 +17,6 @@ function header_info { /____/ EOF } -clear header_info echo -e "Loading..." APP="Emby" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -346,7 +346,6 @@ function install_script() { fi } function update_script() { -clear header_info LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Stopping ${APP}" @@ -366,8 +365,9 @@ msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 3ea8ff96..dd98ce38 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ________ _______v5 _ __ / ____/ |/ / __ \ | |/ / / __/ / /|_/ / / / / | / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="EMQX" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -346,8 +345,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index fb44c748..b63a2141 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ___________ ____ __ __ / ____/ ___// __ \/ / / /___v5____ ___ ___ / __/ \__ \/ /_/ / /_/ / __ \/ __ `__ \/ _ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="ESPHome" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -337,7 +337,6 @@ function install_script() { fi } function update_script() { -clear header_info msg_info "Stopping ESPHome" systemctl stop esphomeDashboard @@ -353,8 +352,9 @@ msg_ok "Started ESPHome" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 6ac359a5..ff4b50bb 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ ____ / ____/________ _/ __/___ _____v5____ _ / / __/ ___/ __ / /_/ __ / __ \/ __ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Grafana" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index c1bb4dbd..fccf9569 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __________ _______ __ / __ / ___/ __ \/ ___/ / / / / /_/ / / / /_/ / /__/ /_/ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="grocy" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP}" bash /var/www/html/update.sh @@ -346,8 +345,9 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 8d890a1f..d8ab9f21 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ _ _ _ ___ _ _ _ /\ /\___(_)_ __ ___ __| | __ _| | | / \__ _ ___| |__ | |__ ___ __ _ _ __ __| | / /_/ / _ \ | '_ ` _ \ / _` |/ _` | | | / /\ / _` / __| '_ \| '_ \ / _ \ / _` | '__/ _` | @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Heimdall Dashboard" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Stopping ${APP}" systemctl disable heimdall.service &>/dev/null @@ -426,8 +425,9 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index f7c432c5..0914d90e 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ _ _ _ ___ /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___v5_ __ ___ / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Home Assistant-Core" @@ -66,23 +67,22 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - msg_error "This script requires Proxmox Virtual Environment 7.0 or greater" +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi +} +function ARCH_CHECK() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit fi } -function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi - } if command -v pveversion >/dev/null 2>&1; then if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then NEXTID=$(pvesh get /cluster/nextid) @@ -348,7 +348,6 @@ function update_script() { "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then @@ -421,8 +420,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index df6808f6..f7787bd9 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ ___ _ __ __ / / / /___v5____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Home Assistant" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -354,7 +354,6 @@ function update_script() { "3" "Install HACS" OFF \ "4" "Install FileBrowser" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then msg_info "Updating All Containers" @@ -421,8 +420,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 5442b1b1..78b8e237 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ______ __ _____________ ____ ________ ____________ / / / / __ \/ |/ / ____/ __ )/ __ \/ _/ __ \/ ____/ ____/ / /_/ / / / / /|_/ / __/ / __ / /_/ // // / / / / __/ __/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Homebridge" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 620dee04..97550a20 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ / / / /___ ____ ___ ___ ____ ____ _____ ____ / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ @@ -15,7 +17,6 @@ function header_info { /_/ v5 /____/ EOF } -clear header_info echo -e "Loading..." APP="Homepage" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP}" if ! command -v pnpm >/dev/null 2>&1; then @@ -353,8 +352,9 @@ systemctl start homepage msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index f9b75c3d..58de4b1d 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ / / / /___ ____ ___v5___ _____ / /_/ / __ \/ __ `__ \/ _ \/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Homer" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Stopping ${APP}" systemctl stop homer @@ -366,8 +365,9 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 81e30620..13e00b7b 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -6,6 +6,7 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { +clear cat <<"EOF" __ __ _ / / / /_ ______v5___ _____(_)___ ____ @@ -16,7 +17,6 @@ cat <<"EOF" EOF } -clear header_info echo -e "Loading..." APP="Hyperion" @@ -65,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -348,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index eaf8ada3..4d5e1ca7 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ ______ ____ ____ / _/_v5 / __/ /_ ___ __/ __ \/ __ ) / // __ \/ /_/ / / / / |/_/ / / / __ | @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="InfluxDB" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 55e1d493..97373a1a 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ ____ __ (_)___ / __ )_________ / /_____ _____ / / __ \/ __ / ___/ __ \/ //_/ _ \/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="ioBroker" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index e5b677be..5281665c 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ____ _____ / /__ / / /_v5__/ __(_)___ __ / / _ \/ / / / / / /_/ / __ \ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Jellyfin" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -348,7 +348,6 @@ function install_script() { fi } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -356,8 +355,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 04c0e1f1..ce4e94ad 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ____ __ __ __ __ / /__/ __ \_____ / //_/_ __/ /_ ___v5_________ ___ / /____ _____ / //_/ / / / ___/ / ,< / / / / __ \/ _ \/ ___/ __ \/ _ \/ __/ _ \/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="k0s" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index c5338e4d..afa7a8d2 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ _ __ / //_/___ __ v5__(_) /_____ _ / ,< / __ `/ | / / / __/ __ `/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Kavita" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -337,7 +337,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -345,8 +344,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index e4a3aad0..4adf46cf 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ __ __ / //_/__v5__ _______/ /___ ____ _/ /__ / ,< / _ \/ / / / ___/ / __ \/ __ / //_/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Keycloak" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -348,8 +347,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 931ca190..638c94fb 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ _ __ / / (_)___/ /___v5__________ / / / / __ / __ `/ ___/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Lidarr" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 5862a8e6..ebfa9d20 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ___ _ __ ____ / |/ /___ _____ _(_)____/ |/ (_)_____________ _____ / /|_/ / __ / __ / / ___/ /|_/ / / ___/ ___/ __ \/ ___/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="MagicMirror" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" cd /opt/magicmirror @@ -349,8 +348,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 6ea66777..63dadfd9 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ___ _ ____ ____ / |/ /___ ______(_)___ _/ __ \/ __ ) / /|_/ / __ / ___/ / __ / / / / __ | @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="MariaDB" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 79609b9d..0bf47afb 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ___ __ ______ __ __ / |/ /__ _____/ /_ / ____/__ ____ / /__________ _/ / / /|_/ / _ \/ ___/ __ \/ / / _ \/ __ \/ __/ ___/ __ / / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="MeshCentral" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index f50a8cf5..1b1176bb 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ___ __ _ / |/ /___ / /_(_)___ ____v5___ __ _____ / /|_/ / __ \/ __/ / __ \/ __ \/ _ \/ / / / _ \ @@ -15,7 +17,6 @@ function header_info { /____/ EOF } -clear header_info echo -e "Loading..." APP="Motioneye" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" pip install motioneye --upgrade &>/dev/null @@ -346,8 +345,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index f5de113d..5eab6ee6 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -6,6 +6,7 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { +clear cat <<"EOF" __ ___ ____ _ ____________ / |/ /___v5_____/ __ \__ __(_)_ __/_ __/___ @@ -15,7 +16,6 @@ cat <<"EOF" EOF } -clear header_info echo -e "Loading..." APP="MQTT" @@ -64,18 +64,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -337,7 +336,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +345,9 @@ msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 2132cdd1..85f1d604 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ___ / _ \ _ __ | (_) |_v5_ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="n8n" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" npm update -g n8n &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 2999950c..5499040d 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ __ _ __ / | / /___ __ v5__(_)___/ /________ ____ ___ ___ / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Navidrome" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') msg_info "Stopping ${APP}" @@ -358,8 +357,9 @@ msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index a8b21172..20f09b56 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ __ __ ________ ______ _ / | / /__ _ __/ /_/ ____/ /___ __v5______/ / __ \(_) / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / /_/ / / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="NextCloudPi" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 94a17159..32f9ee26 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ __ _ ____ __ ___ / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____ / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Nginx Proxy Manager" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | grep "tag_name" | @@ -456,8 +455,9 @@ msg_ok "Cleaned" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index c9e31080..e30d090c 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ __ ____ ____ / | / /___ ____v5___ / __ \/ __ ) / |/ / __ \/ ___/ __ \/ / / / __ | @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="NocoDB" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP}" cd /opt/nocodb @@ -350,8 +349,9 @@ msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index e4016d4d..e2c8ebcd 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ __ __ ____ __ / | / /___ ____/ /__ v5 / __ \___ ____/ / / |/ / __ \/ __ / _ \ / /_/ / _ \/ __ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Node-Red" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -341,7 +341,6 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb "1" "Update ${APP}" ON \ "2" "Install Themes" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then msg_info "Stopping ${APP}" @@ -367,7 +366,6 @@ THEME=$(whiptail --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Scri "solarized-dark" "" OFF \ "solarized-light" "" OFF \ 3>&1 1>&2 2>&3) -clear header_info msg_info "Installing ${THEME} Theme" cd /root/.node-red @@ -383,8 +381,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 0160d8f5..1b1c4a8d 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \____ ___v5____ _____/ /___ _ / / / / __ __ \/ __ / __ / __ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Omada" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -345,8 +345,9 @@ function install_script() { advanced_settings fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index cda88be9..75ce494b 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ ___ ___ _ __ ____ / __ \____v5___ ____ / |/ /__ ____/ (_)___ | | / /___ ___ __/ / /_ / / / / __ \/ _ \/ __ \/ /|_/ / _ \/ __ / / __ `/ | / / __ `/ / / / / __/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="OMV" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -348,8 +347,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index c183799f..a43e311e 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ _____ ____ ____v5____ ___ ____ / / / / | / __ ) / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __ | @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="openHAB" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -348,8 +347,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 4e8ff9c3..49be3557 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \____ _____ ___ _____/ /__v5__________ ____ ____ __ __ / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Paperless-ngx" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -345,7 +345,6 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb "1" "Update Paperless-ngx to $RELEASE" ON \ "2" "Paperless-ngx Credentials" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then msg_info "Stopping Paperless-ngx" @@ -415,8 +414,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 886008c8..72f9d070 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ ______ __________ ____ ____ _________ __ ___ / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="PhotoPrism" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -337,7 +337,6 @@ function install_script() { } function update_script() { -clear header_info echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" msg_info "Stopping PhotoPrism" @@ -368,8 +367,9 @@ msg_ok "Started PhotoPrism" msg_ok "Update Successful" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 03fa249b..9df75b50 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ ____ __ ______ __ ______ / __ \/ _/ / / / / __ \/ / / ____/ / /_/ // /___/ /_/ / / / / / / __/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Pihole" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 25555eab..22edee4f 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ __ ___ ___ _____ / __ \/ /__ _ __ / |/ /__v5____/ (_)___ _ / ___/___ ______ _____ _____ / /_/ / / _ \| |/_/ / /|_/ / _ \/ __ / / __ `/ \__ \/ _ \/ ___/ | / / _ \/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Plex" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -352,7 +352,6 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb "2" "Run plexupdate" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" @@ -366,8 +365,9 @@ bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index b1581dff..cef1ac7a 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \____ ____/ /___ ___ ____ _____ / /_/ / __ \/ __ / __ __ \/ __ / __ \ @@ -19,7 +21,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Podman-Home Assistant" @@ -68,18 +69,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -347,7 +347,6 @@ function update_script() { "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" @@ -398,8 +397,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 75b3170c..dcf91be9 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \____v5____/ /___ ___ ____ _____ / /_/ / __ \/ __ / __ `__ \/ __ `/ __ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Podman" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index f6c599f6..e91afbbb 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ _____ ____ __ / __ \____ _____/ /_____ _________ / ___// __ \ / / / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / @@ -15,7 +17,6 @@ function header_info { /____/ EOF } -clear header_info echo -e "Loading..." APP="PostgreSQL" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 3f61b2c8..4a9183d5 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ __ / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Prometheus" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -347,8 +346,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index 5a6e998d..4750837b 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \_________ _ __/ /___v5__________ / /_/ / ___/ __ \ | /| / / / __ `/ ___/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Prowlarr" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 20ed874d..472ba5de 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \____ _____/ /___v5__________ / /_/ / __ `/ __ / __ `/ ___/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Radarr" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 0dffef6a..8ab9a9c7 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ / __ \___ ____ _____/ /___v5__________ / /_/ / _ \/ __ `/ __ / __ `/ ___/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Readarr" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index f548f14b..a5b00f02 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ____ __ __ _ / __ \____ _____/ /____ __ / / (_)___v5__ ___ __ / /_/ / __ \/ ___/ //_/ / / / / / / / __ \/ / / / |/_/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Rocky Linux" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" pacman-key --init @@ -348,8 +347,9 @@ pacman -Sy archlinux-keyring && pacman -Su msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 40bffdbf..9db3ab90 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _____ ___ ____ __ __ / ___// | / __ )____v5____ / /_ ____/ / \__ \/ /| | / __ / __ \/_ / / __ \/ __ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="SABnzbd" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index cc759881..3c3969cf 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _____ __ __ / ___/____________v5______ / /____ ____/ / \__ \/ ___/ ___/ / / / __ \/ __/ _ \/ __ / @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Scrypted" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -348,8 +347,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index cad79e5c..e106c42c 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _____ __ _ __ _ / ___// /_ (_)___v5____ / /_ (_) \__ \/ __ \/ / __ \/ __ \/ __ \/ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Shinobi" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -346,7 +346,6 @@ function install_script() { fi } function update_script() { -clear header_info msg_info "Updating Shinobi LXC" cd /opt/Shinobi @@ -357,8 +356,9 @@ pm2 restart cron msg_ok "Updated Shinobi LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 7ca8a5d7..593394f4 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _____ / ___/____ ____ ____v5__________ \__ \/ __ \/ __ \/ __ `/ ___/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Sonarr" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 2c1c13d1..f8f6d93e 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _____ __ __ _ / ___/__ ______v5_____/ /_/ /_ (_)___ ____ _ \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Syncthing" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -348,8 +347,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 3319a7e3..c72828f8 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ __ /_ __/___/ /___v5__________ / / / __ / __ `/ ___/ ___/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Tdarr" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 729a6c3b..15ac5433 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ __ _ __ _ ____ _ _______ /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ v5 / __ \/ | / / ___/ / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Technitium DNS" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" dotnetDir="/opt/dotnet" @@ -409,8 +408,9 @@ fi msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index f99e4644..064229a1 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ _ _ /_ __/________ _____v5_________ ___ (_)_________(_)___ ____ / / / ___/ __ `/ __ \/ ___/ __ `__ \/ / ___/ ___/ / __ \/ __ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Transmission" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index e6b8b540..f32b8bc1 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + ______ _ ___ /_ __/_v5_(_) (_)_ ______ ___ / / / ___/ / / / / / / __ `__ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Trilium" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | grep "tag_name" | @@ -366,8 +365,9 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 3416113c..eb23aaa5 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ ____ __ / / / / /_v5__ ______ / /___ __ / / / / __ \/ / / / __ \/ __/ / / / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Ubuntu" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -342,7 +342,6 @@ function install_script() { fi } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -350,8 +349,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 24c40e7e..913274a1 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ __ __ / / / /___ ___v5/ /_ ________ / / / / / / __ `__ \/ __ \/ ___/ _ \/ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Umbrel" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -346,7 +346,6 @@ function install_script() { fi } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null @@ -354,8 +353,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 78b76c0c..895a5122 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ _ _____ / / / /_v5 (_) __(_) / / / / __ \/ / /_/ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Unifi" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP}" wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh @@ -347,8 +346,9 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 2af3e44c..8454cb81 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ __ _ __ __ / / / /___ / /_(_)___ ___ ___ v5 / //_/_ ______ ___ ____ _ / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Uptime Kuma" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Stopping ${APP}" @@ -364,8 +363,9 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 6165882d..5c9dbddb 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ __ ____ _ __ __ | | / /___ ___v5__/ / /| | / /___ __________/ /__ ____ | | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Vaultwarden" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -351,7 +351,6 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb "3" "Show Admin Token" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" @@ -415,8 +414,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 87043a9b..63161066 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ ____ _ | | / / /_ (_)________ ____v5__________ | | /| / / __ \/ / ___/ __ \/ __ `/ ___/ ___/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Whisparr" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -335,7 +335,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -343,8 +342,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index d3c6b07c..51acf61b 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ ____ ______ ____ ________ ______ | | v5 / / / / / __ \/ __ \/ ____/ / / ____/ | | /| / / /_/ / / / / / / / / __/ / / __/ @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Whoogle" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating ${APP} LXC" pip3 install whoogle-search --upgrade &>/dev/null @@ -346,8 +345,9 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 5e4ecb02..c9912aef 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ ___ __ _ _ | | v5 / (_) /__(_) (_)____ | | /| / / / //_/ / / / ___/ @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Wikijs" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -339,7 +339,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Stopping ${APP}" systemctl stop wikijs @@ -360,8 +359,9 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index ea6c3d1a..249a8205 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _ ___ ______ __ | | / (_)_______ / ____/_ ______ __________/ / | | /| / / / ___/ _ \/ / __/ / / / __ `/ ___/ __ / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Wireguard" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -342,7 +342,6 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb "1" "Update ${APP} LXC" ON \ "2" "Install WGDashboard" OFF \ 3>&1 1>&2 2>&3) -clear header_info if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" @@ -402,8 +401,9 @@ exit fi } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index cabde660..7ae9a540 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + __ __ __ __ __ \ \/ /_ ______v5____ / / / /___ _____/ /_ \ / / / / __ \/ __ \/ /_/ / __ \/ ___/ __/ @@ -15,7 +17,6 @@ __ __ __ __ __ EOF } -clear header_info echo -e "Loading..." APP="YunoHost" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -334,7 +334,6 @@ function install_script() { } function update_script() { -clear header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null @@ -342,8 +341,9 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 42767d5d..886b8d43 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _____ _ __ ___ __ _______ ____________ /__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / @@ -16,7 +18,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Zigbee2MQTT" @@ -65,18 +66,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -338,7 +338,6 @@ function install_script() { fi } function update_script() { -clear header_info cd /opt/zigbee2mqtt @@ -393,8 +392,9 @@ start_zigbee2mqtt echo "Done!" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 293abf26..d114feda 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -6,7 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" +clear +cat <<"EOF" + _____ _______ __ ______ /__ /_ ______ __v5 _____ / / ___/ / / / / _/ / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / @@ -15,7 +17,6 @@ function header_info { EOF } -clear header_info echo -e "Loading..." APP="Zwave-JS-UI" @@ -64,18 +65,17 @@ function msg_error() { } function PVE_CHECK() { - PVE=$(pveversion | grep "pve-manager/7" | wc -l) - if [[ $PVE != 1 ]]; then - echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi } function ARCH_CHECK() { - ARCH=$(dpkg --print-architecture) - if [[ "$ARCH" != "amd64" ]]; then - echo -e "\n ❌ This script will not work with PiMox! \n" + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -337,7 +337,6 @@ function install_script() { fi } function update_script() { -clear header_info RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') msg_info "Stopping Z-wave JS UI" @@ -360,8 +359,9 @@ msg_ok "Cleaned" msg_ok "Updated Successfully!\n" exit } -clear ARCH_CHECK +PVE_CHECK +header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From 36ca6fa9d2eaa878c1a1ebecb2ca7d3d3bef80af Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Feb 2023 20:58:42 -0500 Subject: [PATCH 4361/6505] move checks to function install_script() (#1045) --- ct/adguard-v5.sh | 4 ++-- ct/alpine-v5.sh | 4 ++-- ct/archlinux-v5.sh | 4 ++-- ct/audiobookshelf-v5.sh | 4 ++-- ct/autobrr-v5.sh | 4 ++-- ct/blocky-v5.sh | 4 ++-- ct/casaos-v5.sh | 4 ++-- ct/changedetection-v5.sh | 4 ++-- ct/cronicle-v5.sh | 4 ++-- ct/daemonsync-v5.sh | 4 ++-- ct/dashy-v5.sh | 4 ++-- ct/debian-v5.sh | 4 ++-- ct/deconz-v5.sh | 4 ++-- ct/deluge-v5.sh | 4 ++-- ct/devuan-v5.sh | 4 ++-- ct/docker-v5.sh | 4 ++-- ct/emby-v5.sh | 4 ++-- ct/emqx-v5.sh | 4 ++-- ct/esphome-v5.sh | 4 ++-- ct/grafana-v5.sh | 4 ++-- ct/grocy-v5.sh | 4 ++-- ct/heimdalldashboard-v5.sh | 4 ++-- ct/homeassistant-core-v5.sh | 4 ++-- ct/homeassistant-v5.sh | 4 ++-- ct/homebridge-v5.sh | 4 ++-- ct/homepage-v5.sh | 4 ++-- ct/homer-v5.sh | 4 ++-- ct/hyperion-v5.sh | 4 ++-- ct/influxdb-v5.sh | 4 ++-- ct/iobroker-v5.sh | 4 ++-- ct/jellyfin-v5.sh | 4 ++-- ct/k0s-v5.sh | 4 ++-- ct/kavita-v5.sh | 4 ++-- ct/keycloak-v5.sh | 4 ++-- ct/lidarr-v5.sh | 4 ++-- ct/magicmirror-v5.sh | 4 ++-- ct/mariadb-v5.sh | 4 ++-- ct/meshcentral-v5.sh | 4 ++-- ct/motioneye-v5.sh | 4 ++-- ct/mqtt-v5.sh | 4 ++-- ct/n8n-v5.sh | 4 ++-- ct/navidrome-v5.sh | 4 ++-- ct/nextcloudpi-v5.sh | 4 ++-- ct/nginxproxymanager-v5.sh | 4 ++-- ct/nocodb-v5.sh | 4 ++-- ct/node-red-v5.sh | 4 ++-- ct/omada-v5.sh | 4 ++-- ct/omv-v5.sh | 4 ++-- ct/openhab-v5.sh | 4 ++-- ct/paperless-ngx-v5.sh | 4 ++-- ct/photoprism-v5.sh | 4 ++-- ct/pihole-v5.sh | 4 ++-- ct/plex-v5.sh | 4 ++-- ct/podman-homeassistant-v5.sh | 4 ++-- ct/podman-v5.sh | 4 ++-- ct/postgresql-v5.sh | 4 ++-- ct/prometheus-v5.sh | 4 ++-- ct/prowlarr-v5.sh | 4 ++-- ct/radarr-v5.sh | 4 ++-- ct/readarr-v5.sh | 4 ++-- ct/rockylinux-v5.sh | 4 ++-- ct/sabnzbd-v5.sh | 4 ++-- ct/scrypted-v5.sh | 4 ++-- ct/shinobi-v5.sh | 4 ++-- ct/sonarr-v5.sh | 4 ++-- ct/syncthing-v5.sh | 4 ++-- ct/tdarr-v5.sh | 4 ++-- ct/technitiumdns-v5.sh | 4 ++-- ct/transmission-v5.sh | 4 ++-- ct/trilium-v5.sh | 4 ++-- ct/ubuntu-v5.sh | 4 ++-- ct/umbrel-v5.sh | 4 ++-- ct/unifi-v5.sh | 4 ++-- ct/uptimekuma-v5.sh | 4 ++-- ct/vaultwarden-v5.sh | 4 ++-- ct/whisparr-v5.sh | 4 ++-- ct/whoogle-v5.sh | 4 ++-- ct/wikijs-v5.sh | 4 ++-- ct/wireguard-v5.sh | 4 ++-- ct/yunohost-v5.sh | 4 ++-- ct/zigbee2mqtt-v5.sh | 4 ++-- ct/zwave-js-ui-v5.sh | 4 ++-- 82 files changed, 164 insertions(+), 164 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index fa35e0c0..74934552 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -363,8 +365,6 @@ msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index a7d31ece..754f2e49 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -323,6 +323,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -342,8 +344,6 @@ apk upgrade &>/dev/null msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index c1e68f70..23e9b352 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ pacman -Sy archlinux-keyring && pacman -Su msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 05dda529..67b9743f 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 1fed6b3b..08754961 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -325,6 +325,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -355,8 +357,6 @@ msg_ok "Started ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index ab491a6e..d197e42a 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 04683e0d..8bc4d337 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -335,6 +335,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -355,8 +357,6 @@ msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 152f314b..c4b00088 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -345,8 +347,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 56c4d075..6d87466f 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -324,6 +324,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -392,8 +394,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index ccdd178d..70ffccbb 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 79981fb6..e81e0be1 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -372,8 +374,6 @@ msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 03bb03ee..a42ebe1f 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 61e4b0ab..c0985471 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,8 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index b3824328..d249c084 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -323,6 +323,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -342,8 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index 3951de1f..c494a805 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 98ea5d8c..35a93d52 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -334,6 +334,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -352,8 +354,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 9cd4053d..022e8a4d 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -335,6 +335,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -365,8 +367,6 @@ msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index dd98ce38..c5cd3d70 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -345,8 +347,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index b63a2141..3dda1671 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -352,8 +354,6 @@ msg_ok "Started ESPHome" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index ff4b50bb..9dc81a58 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index fccf9569..97ec5e40 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -345,8 +347,6 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index d8ab9f21..ebbf5c09 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -425,8 +427,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 0914d90e..f60c6ff5 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -329,6 +329,8 @@ function advanced_settings() { } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -420,8 +422,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index f7787bd9..5887793b 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -337,6 +337,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -420,8 +422,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 78b8e237..caabb1f4 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 97550a20..17d8197b 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -352,8 +354,6 @@ systemctl start homepage msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 58de4b1d..9661e132 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -365,8 +367,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 13e00b7b..4198119d 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 4d5e1ca7..2a8151c3 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 97373a1a..398478a8 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 5281665c..2332180d 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -337,6 +337,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -355,8 +357,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index ce4e94ad..421e517b 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index afa7a8d2..f3c2eebe 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -325,6 +325,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -344,8 +346,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 4adf46cf..2998f12f 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,8 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 638c94fb..3f63d0d4 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index ebfa9d20..d43b49c4 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,8 +350,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 63dadfd9..f8604781 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 0bf47afb..f34b8c82 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 1b1176bb..633c6a00 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -345,8 +347,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 5eab6ee6..312134fa 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -324,6 +324,8 @@ function advanced_settings() { } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -345,8 +347,6 @@ msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 85f1d604..8533e434 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 5499040d..ce73bc4c 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -357,8 +359,6 @@ msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 20f09b56..86d2abdb 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 32f9ee26..0c91b4ff 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -455,8 +457,6 @@ msg_ok "Cleaned" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index e30d090c..1248bb47 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,8 +351,6 @@ msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index e2c8ebcd..0f5dbf28 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -381,8 +383,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 1b1c4a8d..f0fe5e7b 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -335,6 +335,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -345,8 +347,6 @@ function install_script() { advanced_settings fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 75ce494b..fc816afb 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,8 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index a43e311e..936d9cfb 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,8 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 49be3557..7c02f6f2 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -414,8 +416,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 72f9d070..c5421e36 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -325,6 +325,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -367,8 +369,6 @@ msg_ok "Started PhotoPrism" msg_ok "Update Successful" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 9df75b50..e81072e6 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 22edee4f..ad63a59e 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -336,6 +336,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -365,8 +367,6 @@ bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index cef1ac7a..585fb563 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -330,6 +330,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -397,8 +399,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index dcf91be9..3ba54738 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index e91afbbb..bca3cb47 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 4a9183d5..687b8205 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index 4750837b..b0aadbb5 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 472ba5de..17f60707 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 8ab9a9c7..e8a323b0 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index a5b00f02..aeb48aeb 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,8 +349,6 @@ pacman -Sy archlinux-keyring && pacman -Su msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 9db3ab90..863ea945 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 3c3969cf..1c950d52 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,8 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index e106c42c..184f05d1 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -335,6 +335,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -356,8 +358,6 @@ pm2 restart cron msg_ok "Updated Shinobi LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 593394f4..a887509c 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index f8f6d93e..2dd091c6 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,8 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index c72828f8..9d088413 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 15ac5433..80727dc5 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -408,8 +410,6 @@ fi msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index 064229a1..f1f69af9 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index f32b8bc1..a52e0963 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -365,8 +367,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index eb23aaa5..78a1d4bc 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -331,6 +331,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,8 +351,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 913274a1..75bb0d59 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -335,6 +335,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -353,8 +355,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 895a5122..e13aa3a9 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,8 +348,6 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 8454cb81..64c0a2eb 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -363,8 +365,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 5c9dbddb..9eb335e9 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -414,8 +416,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 63161066..912b2df8 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -323,6 +323,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -342,8 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 51acf61b..2713bc4b 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -345,8 +347,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index c9912aef..1ed58c5a 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -359,8 +361,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 249a8205..4738f193 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -401,8 +403,6 @@ exit fi } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 7ae9a540..d73d52c9 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -322,6 +322,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -341,8 +343,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 886b8d43..879efc0a 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -327,6 +327,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -392,8 +394,6 @@ start_zigbee2mqtt echo "Done!" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index d114feda..d5e8b421 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -326,6 +326,8 @@ function advanced_settings() { fi } function install_script() { +ARCH_CHECK +PVE_CHECK if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -359,8 +361,6 @@ msg_ok "Cleaned" msg_ok "Updated Successfully!\n" exit } -ARCH_CHECK -PVE_CHECK header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi From 03ff3750bfbf90d10f74a527347538eaeb52dd22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Feb 2023 21:10:20 -0500 Subject: [PATCH 4362/6505] tweak (#1046) --- ct/adguard-v5.sh | 2 +- ct/alpine-v5.sh | 2 +- ct/archlinux-v5.sh | 2 +- ct/audiobookshelf-v5.sh | 2 +- ct/autobrr-v5.sh | 2 +- ct/blocky-v5.sh | 2 +- ct/casaos-v5.sh | 2 +- ct/changedetection-v5.sh | 2 +- ct/cronicle-v5.sh | 2 +- ct/daemonsync-v5.sh | 2 +- ct/dashy-v5.sh | 2 +- ct/debian-v5.sh | 2 +- ct/deconz-v5.sh | 2 +- ct/deluge-v5.sh | 2 +- ct/devuan-v5.sh | 2 +- ct/docker-v5.sh | 2 +- ct/emby-v5.sh | 2 +- ct/emqx-v5.sh | 2 +- ct/esphome-v5.sh | 2 +- ct/grafana-v5.sh | 2 +- ct/grocy-v5.sh | 2 +- ct/heimdalldashboard-v5.sh | 2 +- ct/homeassistant-core-v5.sh | 2 +- ct/homeassistant-v5.sh | 2 +- ct/homebridge-v5.sh | 2 +- ct/homepage-v5.sh | 2 +- ct/homer-v5.sh | 2 +- ct/hyperion-v5.sh | 2 +- ct/influxdb-v5.sh | 2 +- ct/iobroker-v5.sh | 2 +- ct/jellyfin-v5.sh | 2 +- ct/k0s-v5.sh | 2 +- ct/kavita-v5.sh | 2 +- ct/keycloak-v5.sh | 2 +- ct/lidarr-v5.sh | 2 +- ct/magicmirror-v5.sh | 2 +- ct/mariadb-v5.sh | 2 +- ct/meshcentral-v5.sh | 2 +- ct/motioneye-v5.sh | 2 +- ct/mqtt-v5.sh | 2 +- ct/n8n-v5.sh | 2 +- ct/navidrome-v5.sh | 2 +- ct/nextcloudpi-v5.sh | 2 +- ct/nginxproxymanager-v5.sh | 2 +- ct/nocodb-v5.sh | 2 +- ct/node-red-v5.sh | 2 +- ct/omada-v5.sh | 2 +- ct/omv-v5.sh | 2 +- ct/openhab-v5.sh | 2 +- ct/paperless-ngx-v5.sh | 2 +- ct/photoprism-v5.sh | 2 +- ct/pihole-v5.sh | 2 +- ct/plex-v5.sh | 2 +- ct/podman-homeassistant-v5.sh | 2 +- ct/podman-v5.sh | 2 +- ct/postgresql-v5.sh | 2 +- ct/prometheus-v5.sh | 2 +- ct/prowlarr-v5.sh | 2 +- ct/radarr-v5.sh | 2 +- ct/readarr-v5.sh | 2 +- ct/rockylinux-v5.sh | 2 +- ct/sabnzbd-v5.sh | 2 +- ct/scrypted-v5.sh | 2 +- ct/shinobi-v5.sh | 2 +- ct/sonarr-v5.sh | 2 +- ct/syncthing-v5.sh | 2 +- ct/tdarr-v5.sh | 2 +- ct/technitiumdns-v5.sh | 2 +- ct/transmission-v5.sh | 2 +- ct/trilium-v5.sh | 2 +- ct/ubuntu-v5.sh | 2 +- ct/umbrel-v5.sh | 2 +- ct/unifi-v5.sh | 2 +- ct/uptimekuma-v5.sh | 2 +- ct/vaultwarden-v5.sh | 2 +- ct/whisparr-v5.sh | 2 +- ct/whoogle-v5.sh | 2 +- ct/wikijs-v5.sh | 2 +- ct/wireguard-v5.sh | 2 +- ct/yunohost-v5.sh | 2 +- ct/zigbee2mqtt-v5.sh | 2 +- ct/zwave-js-ui-v5.sh | 2 +- 82 files changed, 82 insertions(+), 82 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 74934552..844fd239 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -365,7 +366,6 @@ msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 754f2e49..01242e04 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -325,6 +325,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -344,7 +345,6 @@ apk upgrade &>/dev/null msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index 23e9b352..f9154d57 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ pacman -Sy archlinux-keyring && pacman -Su msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 67b9743f..51f3fbe5 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 08754961..4f1ed7cd 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -327,6 +327,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -357,7 +358,6 @@ msg_ok "Started ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index d197e42a..bc869719 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 8bc4d337..8657add4 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -337,6 +337,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -357,7 +358,6 @@ msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index c4b00088..4df5b5b3 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,7 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 6d87466f..7b1835c1 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -326,6 +326,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -394,7 +395,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 70ffccbb..339180a7 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index e81e0be1..9449b137 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -374,7 +375,6 @@ msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index a42ebe1f..8819bc73 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index c0985471..0ba3f34f 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,7 +350,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index d249c084..49f23d87 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -325,6 +325,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -344,7 +345,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index c494a805..65b4e0ea 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 35a93d52..cc5e4797 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -336,6 +336,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -354,7 +355,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 022e8a4d..1874ee85 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -337,6 +337,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -367,7 +368,6 @@ msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index c5cd3d70..614b4045 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,7 +348,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index 3dda1671..91dbc0b5 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -354,7 +355,6 @@ msg_ok "Started ESPHome" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 9dc81a58..2662a04d 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 97ec5e40..9563990b 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,7 +348,6 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index ebbf5c09..6596aa0b 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -427,7 +428,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index f60c6ff5..e3ada4d1 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -331,6 +331,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -422,7 +423,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 5887793b..ee46dbe8 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -339,6 +339,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -422,7 +423,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index caabb1f4..80634649 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 17d8197b..fae8323e 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -354,7 +355,6 @@ systemctl start homepage msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 9661e132..36c823ef 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -367,7 +368,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 4198119d..29c990c5 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 2a8151c3..ec9f8b24 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 398478a8..9e37fd2b 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 2332180d..51915187 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -339,6 +339,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -357,7 +358,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 421e517b..e91106f2 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index f3c2eebe..94bd161d 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -327,6 +327,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -346,7 +347,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 2998f12f..b106d2c9 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,7 +350,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 3f63d0d4..fe6acc9a 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index d43b49c4..c6802492 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -350,7 +351,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index f8604781..e56b6b44 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index f34b8c82..1b16dc68 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 633c6a00..0017ab4d 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,7 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 312134fa..efe46ded 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -326,6 +326,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,7 +348,6 @@ msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 8533e434..c6828567 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index ce73bc4c..bc6db67b 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -359,7 +360,6 @@ msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 86d2abdb..2afbaa12 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 0c91b4ff..aa9ca1a9 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -457,7 +458,6 @@ msg_ok "Cleaned" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 1248bb47..929112bd 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -351,7 +352,6 @@ msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 0f5dbf28..f5f1fba1 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -383,7 +384,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index f0fe5e7b..ae6ad8a5 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -337,6 +337,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,7 +348,6 @@ PVE_CHECK advanced_settings fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index fc816afb..13b0bb86 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,7 +350,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 936d9cfb..bb41242f 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,7 +350,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 7c02f6f2..fa744442 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -416,7 +417,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index c5421e36..4953243d 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -327,6 +327,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -369,7 +370,6 @@ msg_ok "Started PhotoPrism" msg_ok "Update Successful" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index e81072e6..b2b7db58 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index ad63a59e..e7188938 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -338,6 +338,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -367,7 +368,6 @@ bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 585fb563..c1ba384f 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -332,6 +332,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -399,7 +400,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 3ba54738..0fa602e5 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index bca3cb47..a8f24ded 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 687b8205..8d6b444f 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index b0aadbb5..dec41aee 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 17f60707..70f6d794 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index e8a323b0..e79a0e14 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index aeb48aeb..56403ea1 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,7 +350,6 @@ pacman -Sy archlinux-keyring && pacman -Su msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 863ea945..d34674ca 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 1c950d52..acf11373 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,7 +350,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 184f05d1..08aca23c 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -337,6 +337,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -358,7 +359,6 @@ pm2 restart cron msg_ok "Updated Shinobi LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index a887509c..47397bdd 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 2dd091c6..e6ad0979 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -349,7 +350,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 9d088413..d078ef54 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 80727dc5..374a8b32 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -410,7 +411,6 @@ fi msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index f1f69af9..1e823bd0 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index a52e0963..1a8818ff 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -367,7 +368,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 78a1d4bc..4c8eeff3 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -333,6 +333,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -351,7 +352,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 75bb0d59..a0964a32 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -337,6 +337,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -355,7 +356,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index e13aa3a9..08fc5a77 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -348,7 +349,6 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 64c0a2eb..fc2b2662 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -365,7 +366,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 9eb335e9..e08c9440 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -416,7 +417,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 912b2df8..64b76ebf 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -325,6 +325,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -344,7 +345,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 2713bc4b..a5e65954 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -347,7 +348,6 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 1ed58c5a..b69e504c 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -361,7 +362,6 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 4738f193..c18bf9f6 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -403,7 +404,6 @@ exit fi } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index d73d52c9..bc234a6c 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -324,6 +324,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -343,7 +344,6 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 879efc0a..71465d15 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -329,6 +329,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -394,7 +395,6 @@ start_zigbee2mqtt echo "Done!" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index d5e8b421..1e4dd191 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -328,6 +328,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -361,7 +362,6 @@ msg_ok "Cleaned" msg_ok "Updated Successfully!\n" exit } -header_info if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From 8e98eb061706586fad3bccbcae5bcb5ee8722704 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 06:05:07 -0500 Subject: [PATCH 4363/6505] code refactoring (#1047) --- ct/adguard-v5.sh | 66 +++++++++++++++-------------- ct/alpine-v5.sh | 62 +++++++++++++--------------- ct/archlinux-v5.sh | 62 +++++++++++++--------------- ct/audiobookshelf-v5.sh | 58 +++++++++++++------------- ct/autobrr-v5.sh | 66 +++++++++++++++-------------- ct/blocky-v5.sh | 67 +++++++++++++++--------------- ct/casaos-v5.sh | 72 ++++++++++++++++---------------- ct/changedetection-v5.sh | 67 +++++++++++++++--------------- ct/cronicle-v5.sh | 63 +++++++++++++--------------- ct/daemonsync-v5.sh | 67 +++++++++++++++--------------- ct/dashy-v5.sh | 66 ++++++++++++++--------------- ct/debian-v5.sh | 58 +++++++++++++------------- ct/deconz-v5.sh | 67 +++++++++++++++--------------- ct/deluge-v5.sh | 65 +++++++++++++++-------------- ct/devuan-v5.sh | 58 +++++++++++++------------- ct/docker-v5.sh | 67 ++++++++++++++---------------- ct/emby-v5.sh | 66 ++++++++++++++--------------- ct/emqx-v5.sh | 62 +++++++++++++--------------- ct/esphome-v5.sh | 67 +++++++++++++++--------------- ct/grafana-v5.sh | 67 +++++++++++++++--------------- ct/grocy-v5.sh | 67 +++++++++++++++--------------- ct/heimdalldashboard-v5.sh | 67 +++++++++++++++--------------- ct/homeassistant-core-v5.sh | 65 +++++++++++++++-------------- ct/homeassistant-v5.sh | 73 ++++++++++++++++---------------- ct/homebridge-v5.sh | 67 +++++++++++++++--------------- ct/homepage-v5.sh | 67 +++++++++++++++--------------- ct/homer-v5.sh | 63 +++++++++++++++------------- ct/hyperion-v5.sh | 67 +++++++++++++++--------------- ct/influxdb-v5.sh | 67 +++++++++++++++--------------- ct/iobroker-v5.sh | 67 +++++++++++++++--------------- ct/jellyfin-v5.sh | 67 +++++++++++++++--------------- ct/k0s-v5.sh | 67 +++++++++++++++--------------- ct/kavita-v5.sh | 66 +++++++++++++++-------------- ct/keycloak-v5.sh | 67 +++++++++++++++--------------- ct/lidarr-v5.sh | 63 +++++++++++++++------------- ct/magicmirror-v5.sh | 67 +++++++++++++++--------------- ct/mariadb-v5.sh | 67 +++++++++++++++--------------- ct/meshcentral-v5.sh | 67 +++++++++++++++--------------- ct/motioneye-v5.sh | 67 +++++++++++++++--------------- ct/mqtt-v5.sh | 66 +++++++++++++++-------------- ct/n8n-v5.sh | 67 +++++++++++++++--------------- ct/navidrome-v5.sh | 66 ++++++++++++++--------------- ct/nextcloudpi-v5.sh | 67 +++++++++++++++--------------- ct/nginxproxymanager-v5.sh | 67 +++++++++++++++--------------- ct/nocodb-v5.sh | 68 +++++++++++++++--------------- ct/node-red-v5.sh | 66 ++++++++++++++--------------- ct/omada-v5.sh | 78 ++++++++++++++++++++--------------- ct/omv-v5.sh | 67 +++++++++++++++--------------- ct/openhab-v5.sh | 67 +++++++++++++++--------------- ct/paperless-ngx-v5.sh | 66 ++++++++++++++--------------- ct/photoprism-v5.sh | 68 +++++++++++++++--------------- ct/pihole-v5.sh | 67 +++++++++++++++--------------- ct/plex-v5.sh | 67 +++++++++++++++--------------- ct/podman-homeassistant-v5.sh | 66 ++++++++++++++--------------- ct/podman-v5.sh | 67 +++++++++++++++--------------- ct/postgresql-v5.sh | 67 +++++++++++++++--------------- ct/prometheus-v5.sh | 67 +++++++++++++++--------------- ct/prowlarr-v5.sh | 63 +++++++++++++++------------- ct/radarr-v5.sh | 63 +++++++++++++++------------- ct/readarr-v5.sh | 63 +++++++++++++++------------- ct/rockylinux-v5.sh | 72 ++++++++++++++++---------------- ct/sabnzbd-v5.sh | 63 +++++++++++++++------------- ct/scrypted-v5.sh | 67 +++++++++++++++--------------- ct/shinobi-v5.sh | 67 +++++++++++++++--------------- ct/sonarr-v5.sh | 63 +++++++++++++++------------- ct/syncthing-v5.sh | 67 +++++++++++++++--------------- ct/tdarr-v5.sh | 63 +++++++++++++++------------- ct/technitiumdns-v5.sh | 67 +++++++++++++++--------------- ct/transmission-v5.sh | 63 +++++++++++++++------------- ct/trilium-v5.sh | 67 +++++++++++++++--------------- ct/ubuntu-v5.sh | 58 +++++++++++++------------- ct/umbrel-v5.sh | 73 ++++++++++++++++---------------- ct/unifi-v5.sh | 67 +++++++++++++++--------------- ct/uptimekuma-v5.sh | 67 +++++++++++++++--------------- ct/vaultwarden-v5.sh | 65 +++++++++++++++-------------- ct/whisparr-v5.sh | 63 +++++++++++++++------------- ct/whoogle-v5.sh | 67 +++++++++++++++--------------- ct/wikijs-v5.sh | 67 +++++++++++++++--------------- ct/wireguard-v5.sh | 66 ++++++++++++++--------------- ct/yunohost-v5.sh | 63 +++++++++++++++------------- ct/zigbee2mqtt-v5.sh | 67 +++++++++++++++--------------- ct/zwave-js-ui-v5.sh | 67 +++++++++++++++--------------- 82 files changed, 2760 insertions(+), 2653 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 844fd239..3ad5b01f 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,39 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/AdGuardHome ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi + function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +307,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -366,7 +346,29 @@ msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/AdGuardHome ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 01242e04..52f86cca 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/alpine-release ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -325,6 +302,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -345,7 +323,25 @@ apk upgrade &>/dev/null msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index f9154d57..a979ffeb 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/pacman.d ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,25 @@ pacman -Sy archlinux-keyring && pacman -Su msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 51f3fbe5..903f34b0 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,25 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 4f1ed7cd..049e4585 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,40 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /root/.config/autobrr ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -327,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -358,7 +337,30 @@ msg_ok "Started ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /root/.config/autobrr/config.toml ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index bc869719..b88f4392 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/blocky/ ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/blocky ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 8657add4..26f8fedb 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/docker ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -140,7 +117,7 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" @@ -312,10 +289,10 @@ function advanced_settings() { SSH="no" fi if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" FUSE="yes" else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then @@ -337,6 +314,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -358,7 +336,29 @@ msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/docker ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then FEATURES="fuse=1,keyctl=1,nesting=1" diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 4df5b5b3..bfc1b6d6 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/changedetection.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -348,7 +326,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/changedetection.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 7b1835c1..614a20c4 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,38 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} Master LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - SERVER="y" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} SUPPORT" --yesno "Options to Update or Install ${APP} Worker on $hostname. Proceed?" 10 58); then - echo "User selected Support" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -326,7 +306,9 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info +SERVER="y" if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -356,10 +338,6 @@ msg_ok "Updated ${APP}" exit fi if [ "$UPD" == "2" ]; then - if [[ -d /opt/cronicle ]]; then - msg_error "${APP} Installation Found!"; - exit - fi LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) IP=$(hostname -I | awk '{print $1}') msg_info "Installing Dependencies" @@ -395,7 +373,24 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 339180a7..96b9b8fb 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/daemonsync ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/daemonsync ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 9449b137..493fd3d1 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/dashy.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -375,7 +353,29 @@ msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/dashy.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 8819bc73..c79f61fa 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,25 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 0ba3f34f..56b55259 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/deconz.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -350,7 +328,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/deconz.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index 49f23d87..e8349ab1 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,37 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -325,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -341,11 +323,34 @@ function update_script() { header_info msg_info "Updating $APP LXC" apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +pip3 install deluge[all] --upgrade msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/deluged.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index 65b4e0ea..4f7d5ea0 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,25 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index cc5e4797..0afd7a11 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,39 +70,17 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/docker ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" @@ -139,7 +117,7 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" @@ -311,10 +289,10 @@ function advanced_settings() { SSH="no" fi if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" FUSE="yes" else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then @@ -336,6 +314,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -355,7 +334,25 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then FEATURES="fuse=1,keyctl=1,nesting=1" diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 1874ee85..2859c147 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/emby-server ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" @@ -337,6 +314,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -368,7 +346,29 @@ msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/emby-server ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 614b4045..01b760c9 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -348,7 +326,25 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index 91dbc0b5..cd8cc028 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /usr/local/bin/esphome ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -355,7 +333,30 @@ msg_ok "Started ESPHome" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /usr/local/bin/esphome ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index 2662a04d..fa798d4a 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/grafana.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/grafana.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 9563990b..c49d1c5a 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -348,7 +326,30 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 6596aa0b..bca0c925 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/Heimdall ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -428,7 +406,30 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/Heimdall ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index e3ada4d1..828d9424 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -62,8 +62,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -72,39 +72,17 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /srv/homeassistant ]]; then - msg_error "No Home Assistant Core Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC" 10 58); then - echo "User selected Support" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" @@ -331,6 +309,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -423,7 +402,29 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /srv/homeassistant ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index ee46dbe8..010dcf7a 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /root/hass_config ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then - echo "User selected support" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -141,7 +118,7 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" @@ -314,10 +291,10 @@ function advanced_settings() { SSH="no" fi if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" FUSE="yes" else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then @@ -339,6 +316,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -423,7 +401,30 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /var/lib/docker/volumes/hass_config/_data + ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then FEATURES="fuse=1,keyctl=1,nesting=1" diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 80634649..8fda38e7 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/emqx_emqx.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/homebridge.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index fae8323e..4246a5f3 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/homepage.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -355,7 +333,30 @@ systemctl start homepage msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/homepage.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index 36c823ef..c18bd377 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -368,7 +350,30 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/homer ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 29c990c5..92cdc544 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/hyperion.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/hyperion.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index ec9f8b24..d7b62cd4 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/influxdb.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/influxdb.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 9e37fd2b..d657eeea 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/iobroker ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/iobroker ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 51915187..d0a8cf82 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /usr/lib/jellyfin ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" @@ -339,6 +316,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -358,7 +336,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /usr/lib/jellyfin ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index e91106f2..143292ca 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/k0s/k0s.yaml ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/k0s/k0s.yaml ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index 94bd161d..77e3889a 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,40 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/Kavita ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -327,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -347,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/Kavita ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index b106d2c9..11f0d9ea 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/keycloak.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -350,7 +328,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/keycloak.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index fe6acc9a..e4877512 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/lidarr/ ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index c6802492..5f8b8704 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/magicmirror ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -351,7 +329,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/magicmirror ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index e56b6b44..7705a589 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/mariadb.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/mariadb.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 1b16dc68..c34c5709 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/meshcentral ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/meshcentral ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 0017ab4d..78a5ff8b 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/motioneye.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -348,7 +326,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/motioneye.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index efe46ded..831ea218 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -59,8 +59,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -69,39 +69,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/mosquitto-bullseye.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi + function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -326,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -348,7 +328,29 @@ msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/mosquitto-bullseye.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index c6828567..4e9ffc1e 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/n8n.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/n8n.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index bc6db67b..8ad6a7d0 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/navidrome ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -360,7 +338,29 @@ msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/navidrome ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 2afbaa12..2832dfd5 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /lib/systemd/system/nextcloud-domain.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /lib/systemd/system/nextcloud-domain.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index aa9ca1a9..35e7df35 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /lib/systemd/system/npm.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -458,7 +436,30 @@ msg_ok "Cleaned" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /lib/systemd/system/npm.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 929112bd..7bce9820 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/nocodb.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,10 +327,32 @@ npm install -s --save nocodb &>/dev/null systemctl restart nocodb.service msg_ok "Updated ${APP}" msg_ok "Update Successfull" - exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/nocodb.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index f5f1fba1..934d59a3 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /root/.node-red ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then - echo "User selected support" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -384,7 +362,29 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /root/.node-red ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index ae6ad8a5..72f16b52 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/tplink ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" @@ -337,6 +314,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -347,8 +325,42 @@ header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings fi + exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +function update_script() { +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/tplink ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 13b0bb86..544f073c 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/openmediavault.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -350,7 +328,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/openmediavault.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index bb41242f..74d31c86 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/openhab.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -350,7 +328,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/openhab.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index fa744442..e11ba30b 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/paperless ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then - echo "User selected support" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -417,7 +395,29 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/paperless ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 4953243d..ecc2399f 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,40 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/photoprism ]]; then - msg_error "No PhotoPrism Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Yes" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi +} + function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -327,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -370,7 +349,30 @@ msg_ok "Started PhotoPrism" msg_ok "Update Successful" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/photoprism ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index b2b7db58..d22efe08 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/pihole ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/pihole ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index e7188938..5f0cae8a 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" @@ -338,6 +315,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -368,7 +346,30 @@ bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index c1ba384f..e03bca6a 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -64,8 +64,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -74,41 +74,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/homeassistant.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -332,6 +309,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -400,7 +378,29 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/homeassistant.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 0fa602e5..93d108b9 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/containers/registries.conf ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/containers/registries.conf ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index a8f24ded..3c052a86 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index 8d6b444f..bf6a2cf6 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/prometheus.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/prometheus.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index dec41aee..d7ffa755 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/prowlarr/ ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 70f6d794..815cc4fd 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/radarr/ ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index e79a0e14..769e1020 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/readarr/ ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index 56403ea1..ea9c9550 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/pacman.d ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,13 +322,35 @@ header_info function update_script() { header_info msg_info "Updating ${APP} LXC" -pacman-key --init -pacman-key --populate archlinux -pacman -Sy archlinux-keyring && pacman -Su +dnf -y update +dnf -y upgrade msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/pacman.d ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index d34674ca..e923ad36 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/sabnzbd ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index acf11373..6b90147f 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/scrypted.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -350,7 +328,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/scrypted.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 08aca23c..14b4850c 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/Shinobi ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" @@ -337,6 +314,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -359,7 +337,30 @@ pm2 restart cron msg_ok "Updated Shinobi LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/Shinobi ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 47397bdd..d948ab5b 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/sonarr.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index e6ad0979..2b0e83a7 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/apt/sources.list.d/syncthing.list ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -350,7 +328,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/syncthing.list ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index d078ef54..5813b5a6 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/tdarr ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 374a8b32..099d6b65 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/dns ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -411,7 +389,30 @@ fi msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/dns ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index 1e823bd0..0ee5d068 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/transmission-daemon/settings.json ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 1a8818ff..3ac54cb0 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/trilium/ ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -368,7 +346,30 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d ! -d /opt/trilium ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 4c8eeff3..f283066b 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" @@ -333,6 +314,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -352,7 +334,25 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index a0964a32..e70695d1 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /root/umbrel ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -140,7 +117,7 @@ function default_settings() { VLAN="" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" SSH="no" - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" VERB="no" @@ -312,10 +289,10 @@ function advanced_settings() { SSH="no" fi if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}Yes${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" FUSE="yes" else - echo -e "${DGN}(ZFS) Enable Fuse Overlayfs: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" FUSE="no" fi if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then @@ -337,6 +314,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -356,7 +334,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /root/umbrel ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$FUSE" == "yes" ]; then FEATURES="fuse=1,keyctl=1,nesting=1" diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 08fc5a77..2e2bce79 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /usr/lib/unifi ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -349,7 +327,30 @@ msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /usr/lib/unifi ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index fc2b2662..a7d24e82 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/uptime-kuma ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -366,7 +344,30 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/uptime-kuma ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index e08c9440..d3fd4f29 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,39 +70,17 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/systemd/system/vaultwarden.service ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then - echo "User selected support" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" @@ -328,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -417,7 +396,29 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/vaultwarden.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 64b76ebf..7a3beee5 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,37 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -325,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -345,7 +327,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/whisparr ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index a5e65954..6d4d9093 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /usr/local/bin/whoogle-search ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -348,7 +326,30 @@ msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /usr/local/bin/whoogle-search ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index b69e504c..6091efaf 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/wikijs ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -362,7 +340,30 @@ msg_ok "Started ${APP}" msg_ok "Update Successfull" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/wikijs ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index c18bf9f6..8bac4026 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/pivpn/wireguard ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC SUPPORT" --yesno "This provides Support for ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -404,7 +382,29 @@ exit fi } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/pivpn/wireguard ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index bc234a6c..c5b72d48 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,37 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" CT_TYPE="1" @@ -324,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -344,7 +326,30 @@ apt-get -y upgrade &>/dev/null msg_ok "Updated $APP LXC" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/trusted.gpg.d/php.gpg ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 71465d15..fc238d95 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -61,8 +61,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -71,41 +71,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/zigbee2mqtt ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" @@ -329,6 +306,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -395,7 +373,30 @@ start_zigbee2mqtt echo "Done!" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/zigbee2mqtt ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 1e4dd191..a56356b4 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -60,8 +60,8 @@ function msg_ok() { } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { @@ -70,41 +70,18 @@ if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." sleep 2 - exit +exit fi } function ARCH_CHECK() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi } -if command -v pveversion >/dev/null 2>&1; then - if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - NEXTID=$(pvesh get /cluster/nextid) - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/zwave-js-ui ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi - if (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - echo "User selected Update" - else - clear - echo -e "⚠ User exited script \n" - exit - fi -fi - function default_settings() { echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" @@ -328,6 +305,7 @@ function advanced_settings() { function install_script() { ARCH_CHECK PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info @@ -362,7 +340,30 @@ msg_ok "Cleaned" msg_ok "Updated Successfully!\n" exit } -if ! command -v pveversion >/dev/null 2>&1; then update_script; else install_script; fi + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/zwave-js-ui ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="nesting=1,keyctl=1" From 8f3e3f524817d18b57acc8ee2e583e7e608f3070 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 10:11:43 -0500 Subject: [PATCH 4364/6505] Create olivetin.sh --- misc/olivetin.sh | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 misc/olivetin.sh diff --git a/misc/olivetin.sh b/misc/olivetin.sh new file mode 100644 index 00000000..0b7fee72 --- /dev/null +++ b/misc/olivetin.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ ___ _______ + / __ \/ (_) _____/_ __(_)___ + / / / / / / | / / _ \/ / / / __ \ +/ /_/ / / /| |/ / __/ / / / / / / +\____/_/_/ |___/\___/_/ /_/_/ /_/ + +EOF +} + +IP=$(hostname -I | awk '{print $1}') +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +APP="OliveTin" +hostname="$(hostname)" +set-e +header_info + +while true; do + read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Installing ${APP}" +RELEASE=$(curl -s https://api.github.com/repos/OliveTin/OliveTin/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q github.com/OliveTin/OliveTin/releases/download/$RELEASE/OliveTin_linux_amd64.deb +dpkg -i OliveTin_linux_amd64.deb &>/dev/null +rm OliveTin_linux_amd64.deb +systemctl enable --now OliveTin &>/dev/null +# configuration file path /etc/OliveTin/config.yaml +msg_ok "Installed ${APP} on $hostname" + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://$IP:1337${CL} \n" From 9e82e8c963bac8b23f9595bc4f116e6e656d9eb4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 10:37:16 -0500 Subject: [PATCH 4365/6505] Update olivetin.sh --- misc/olivetin.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/olivetin.sh b/misc/olivetin.sh index 0b7fee72..69a884b9 100644 --- a/misc/olivetin.sh +++ b/misc/olivetin.sh @@ -53,7 +53,6 @@ msg_info "Installing ${APP}" RELEASE=$(curl -s https://api.github.com/repos/OliveTin/OliveTin/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget -q github.com/OliveTin/OliveTin/releases/download/$RELEASE/OliveTin_linux_amd64.deb dpkg -i OliveTin_linux_amd64.deb &>/dev/null -rm OliveTin_linux_amd64.deb systemctl enable --now OliveTin &>/dev/null # configuration file path /etc/OliveTin/config.yaml msg_ok "Installed ${APP} on $hostname" From fce7ef9a1f53fea312249543071221358948b3e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 10:41:12 -0500 Subject: [PATCH 4366/6505] Update olivetin.sh --- misc/olivetin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/olivetin.sh b/misc/olivetin.sh index 69a884b9..da7f19e5 100644 --- a/misc/olivetin.sh +++ b/misc/olivetin.sh @@ -50,7 +50,7 @@ function msg_ok() { } msg_info "Installing ${APP}" -RELEASE=$(curl -s https://api.github.com/repos/OliveTin/OliveTin/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +RELEASE=$(curl -s https://api.github.com/repos/OliveTin/OliveTin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget -q github.com/OliveTin/OliveTin/releases/download/$RELEASE/OliveTin_linux_amd64.deb dpkg -i OliveTin_linux_amd64.deb &>/dev/null systemctl enable --now OliveTin &>/dev/null From 2d9cf318f0a7e8f72fdf2652c353491948ad5835 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 10:43:40 -0500 Subject: [PATCH 4367/6505] Update olivetin.sh --- misc/olivetin.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/olivetin.sh b/misc/olivetin.sh index da7f19e5..cfef03a7 100644 --- a/misc/olivetin.sh +++ b/misc/olivetin.sh @@ -19,6 +19,7 @@ EOF IP=$(hostname -I | awk '{print $1}') YW=$(echo "\033[33m") +BL=$(echo "\033[36m") GN=$(echo "\033[1;92m") CL=$(echo "\033[m") BFR="\\r\\033[K" @@ -54,6 +55,7 @@ RELEASE=$(curl -s https://api.github.com/repos/OliveTin/OliveTin/releases/latest wget -q github.com/OliveTin/OliveTin/releases/download/$RELEASE/OliveTin_linux_amd64.deb dpkg -i OliveTin_linux_amd64.deb &>/dev/null systemctl enable --now OliveTin &>/dev/null +rm OliveTin_linux_amd64.deb # configuration file path /etc/OliveTin/config.yaml msg_ok "Installed ${APP} on $hostname" From 3fb399d1d22e811b862d6ac1ffd25ad34d3aa24c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 11:00:03 -0500 Subject: [PATCH 4368/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index eb556ee4..a094aa45 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-02-12 + +### Changed + +- **OliveTin** + - NEW Script + ## 2023-02-10 ### Changed From 55f30917b4eb629f8e618d6a1659945af59276ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 17:28:14 -0500 Subject: [PATCH 4369/6505] Update omada-v5.sh fix exit --- ct/omada-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 72f16b52..6fc4e144 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -324,8 +324,8 @@ header_info header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi exit + fi } function update_script() { From d08c1ab3d69284c36e9d38a44122fb2e1bf7f1c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Feb 2023 17:36:08 -0500 Subject: [PATCH 4370/6505] Update omada-v5.sh --- ct/omada-v5.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 6fc4e144..929591ec 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -324,7 +324,6 @@ header_info header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - exit fi } From 0fdd88a5ed7d10f60c2ccede9d4e467a2bb8305b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Feb 2023 04:49:07 -0500 Subject: [PATCH 4371/6505] Update trilium-v5.sh fix syntax error in conditional expression --- ct/trilium-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 3ac54cb0..62a54f47 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -356,7 +356,7 @@ if command -v pveversion >/dev/null 2>&1; then install_script fi -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d ! -d /opt/trilium ]]; then +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/trilium ]]; then msg_error "No ${APP} Installation Found!" exit fi From b2f7ebe759fbecc266af980850840cd7c461174e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Feb 2023 08:23:46 -0500 Subject: [PATCH 4372/6505] Update olivetin.sh tweak --- misc/olivetin.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/misc/olivetin.sh b/misc/olivetin.sh index cfef03a7..c8015572 100644 --- a/misc/olivetin.sh +++ b/misc/olivetin.sh @@ -51,12 +51,10 @@ function msg_ok() { } msg_info "Installing ${APP}" -RELEASE=$(curl -s https://api.github.com/repos/OliveTin/OliveTin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -wget -q github.com/OliveTin/OliveTin/releases/download/$RELEASE/OliveTin_linux_amd64.deb +wget -q https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin_linux_amd64.deb dpkg -i OliveTin_linux_amd64.deb &>/dev/null systemctl enable --now OliveTin &>/dev/null rm OliveTin_linux_amd64.deb -# configuration file path /etc/OliveTin/config.yaml msg_ok "Installed ${APP} on $hostname" msg_ok "Completed Successfully!\n" From 20aabb856ccc820004abd115ac140df0be4a2cf7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Feb 2023 14:02:54 -0500 Subject: [PATCH 4373/6505] Create rstptoweb-v5.sh --- ct/rstptoweb-v5.sh | 386 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 ct/rstptoweb-v5.sh diff --git a/ct/rstptoweb-v5.sh b/ct/rstptoweb-v5.sh new file mode 100644 index 00000000..d067026b --- /dev/null +++ b/ct/rstptoweb-v5.sh @@ -0,0 +1,386 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _______________ __ _ ____________ + / __ \/ ___/_ __/ __ \/ /_____| | v5 / / ____/ __ ) + / /_/ /\__ \ / / / /_/ / __/ __ \ | /| / / __/ / __ | + / _, _/___/ // / / ____/ /_/ /_/ / |/ |/ / /___/ /_/ / +/_/ |_|/____//_/ /_/ \__/\____/|__/|__/_____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="RSTPtoWEB" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +header_info +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8083 ${CL} \n" From 7e83e15ffdbe4f51e956be2ef8b162d3fe8777c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Feb 2023 14:04:11 -0500 Subject: [PATCH 4374/6505] Create rstptoweb-v5-install.sh --- install/rstptoweb-v5-install.sh | 144 ++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 install/rstptoweb-v5-install.sh diff --git a/install/rstptoweb-v5-install.sh b/install/rstptoweb-v5-install.sh new file mode 100644 index 00000000..6a7c1d30 --- /dev/null +++ b/install/rstptoweb-v5-install.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY +done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Golang" +$STD wget https://golang.org/dl/go1.20.1.linux-amd64.tar.gz +$STD tar -xzf go1.20.1.linux-amd64.tar.gz -C /usr/local +$STD ln -s /usr/local/go/bin/go /usr/local/bin/go +rm -rf go1.20.1.linux-amd64.tar.gz +msg_ok "Installed Golang" + +msg_info "Installing RSTPtoWEB" +$STD git clone https://github.com/deepch/RTSPtoWeb /opt/rtsptoweb +cat <>/opt/rtsptoweb/start +#!/bin/bash +cd /opt/rtsptoweb && GO111MODULE=on go run *.go +EOF +chmod +x /opt/rtsptoweb/start +msg_ok "Installed RSTPtoWEB" + +msg_info "Creating Service" +service_path="/etc/systemd/system/rtsptoweb.service" +echo "[Unit] +Description=RTSP to Web Streaming Service +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/opt/rtsptoweb/start + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable -q --now rtsptoweb +msg_ok "Created Service" + +echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* +if ! getent shadow root | grep -q "^root:[^\!*]"; then + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 9827898521d3cd81f81a155d34ccc8402e82e194 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Feb 2023 21:18:17 -0500 Subject: [PATCH 4375/6505] Create go2rtc-v5-install.sh --- install/go2rtc-v5-install.sh | 133 +++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 install/go2rtc-v5-install.sh diff --git a/install/go2rtc-v5-install.sh b/install/go2rtc-v5-install.sh new file mode 100644 index 00000000..ef8044d8 --- /dev/null +++ b/install/go2rtc-v5-install.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY +done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing go2rtc" +mkdir -p /opt/go2rtc +cd /opt/go2rtc +wget -q https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64 +chmod +x go2rtc_linux_amd64 +msg_ok "Installed go2rtc" + +msg_info "Creating Service" +service_path="/etc/systemd/system/go2rtc.service" +echo "[Unit] +Description=go2rtc service +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/opt/go2rtc/go2rtc_linux_amd64 + +[Install] +WantedBy=multi-user.target" >$service_path +msg_ok "Created Service" + +echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* +if ! getent shadow root | grep -q "^root:[^\!*]"; then + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 61f42f8f8f4481cf852b1a80dd8d14224c417d7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Feb 2023 21:19:34 -0500 Subject: [PATCH 4376/6505] Create go2rtc-v5.sh --- ct/go2rtc-v5.sh | 387 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 ct/go2rtc-v5.sh diff --git a/ct/go2rtc-v5.sh b/ct/go2rtc-v5.sh new file mode 100644 index 00000000..2ab170aa --- /dev/null +++ b/ct/go2rtc-v5.sh @@ -0,0 +1,387 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ + ____ _____ |__ \ _____/ /__v5__ + / __ `/ __ \__/ // ___/ __/ ___/ + / /_/ / /_/ / __// / / /_/ /__ + \__, /\____/____/_/ \__/\___/ +/____/ + +EOF +} +header_info +echo -e "Loading..." +APP="go2rtc" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +header_info +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:1984${CL} \n" From c016ea85026d64d746c5e95ae418efd3f965278f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Feb 2023 21:24:00 -0500 Subject: [PATCH 4377/6505] Update go2rtc-v5-install.sh --- install/go2rtc-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/go2rtc-v5-install.sh b/install/go2rtc-v5-install.sh index ef8044d8..532e4a30 100644 --- a/install/go2rtc-v5-install.sh +++ b/install/go2rtc-v5-install.sh @@ -107,6 +107,7 @@ ExecStart=/opt/go2rtc/go2rtc_linux_amd64 [Install] WantedBy=multi-user.target" >$service_path +systemctl enable -q --now go2rtc msg_ok "Created Service" echo "export TERM='xterm-256color'" >>/root/.bashrc From 11aa80c9783e71fab22efbddca17fab4ee8106ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 Feb 2023 05:41:09 -0500 Subject: [PATCH 4378/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index a094aa45..ec418768 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,15 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-02-16 + +### Changed + +- **RSTPtoWEB LXC** + - NEW Script +- **go2rtc LXC** + - NEW Script + ## 2023-02-12 ### Changed From ed2330edc027ed37b6e32c3ac311ffcdf2458d38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 Feb 2023 20:01:15 -0500 Subject: [PATCH 4379/6505] Update wikijs-v5.sh fix update process --- ct/wikijs-v5.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 6091efaf..2baebf4a 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -325,17 +325,26 @@ msg_info "Stopping ${APP}" systemctl stop wikijs msg_ok "Stopped ${APP}" +msg_info "Backing up Data" +mkdir -p data-backup +cp -R /opt/wikijs/{db.sqlite,config.yml,/data} ~/data-backup +msg_ok "Backed up Data" + msg_info "Updating ${APP}" -cp /opt/wikijs/config.yml ~/config.yml.bak rm -rf /opt/wikijs/* cd /opt/wikijs -wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz &>/dev/null +wget -q https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz tar xzf wiki-js.tar.gz -cp ~/config.yml.bak ./config.yml msg_ok "Updated ${APP}" +msg_info "Restoring Data" +cp -R ~/data-backup/* /opt/wikijs +rm -rf ~/data-backup +npm rebuild sqlite3 &>/dev/null +msg_ok "Restored Data" + msg_info "Starting ${APP}" -systemctl stop wikijs +systemctl start wikijs msg_ok "Started ${APP}" msg_ok "Update Successfull" exit From 49db75a8c697a9f46798dafe51abfbb8e6cc73e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 Feb 2023 05:19:46 -0500 Subject: [PATCH 4380/6505] Update paperless-ngx-v5-install.sh fix for v1.13.0 --- install/paperless-ngx-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 0470345b..90d0d518 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -154,6 +154,7 @@ cd /opt/paperless sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt $STD pip install --upgrade pip $STD pip install -r requirements.txt +curl -s -o /opt/paperless/paperless.conf https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/paperless.conf.example msg_ok "Installed Paperless-ngx" msg_info "Installing Natural Language Toolkit (Patience)" From 1acbf02e080f1e6d0f0fd757f1f2712a7d4d955c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 Feb 2023 07:26:58 -0500 Subject: [PATCH 4381/6505] Update dashy-v5.sh set default storage 6GB --- ct/dashy-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 493fd3d1..52a132c6 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -20,7 +20,7 @@ EOF header_info echo -e "Loading..." APP="Dashy" -var_disk="3" +var_disk="6" var_cpu="2" var_ram="2048" var_os="debian" From 0d1131ff6d93a60d88756a1e9be44a7ca08ce0a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 Feb 2023 13:48:02 -0500 Subject: [PATCH 4382/6505] Update photoprism-v5-install.sh update golang to 1.20.1 --- install/photoprism-v5-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index fe1093d3..f674597e 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -107,8 +107,8 @@ $STD apt-get -y install nodejs msg_ok "Installed Node.js" msg_info "Installing Golang (Patience)" -$STD wget https://golang.org/dl/go1.19.3.linux-amd64.tar.gz -$STD tar -xzf go1.19.3.linux-amd64.tar.gz -C /usr/local +$STD wget https://golang.org/dl/go1.20.1.linux-amd64.tar.gz +$STD tar -xzf go1.20.1.linux-amd64.tar.gz -C /usr/local $STD ln -s /usr/local/go/bin/go /usr/local/bin/go $STD go install github.com/tianon/gosu@latest $STD go install golang.org/x/tools/cmd/goimports@latest @@ -205,7 +205,7 @@ $STD apt-get autoremove $STD apt-get autoclean rm -rf /var/{cache,log}/* \ /photoprism \ - /go1.19.3.linux-amd64.tar.gz \ + /go1.20.1.linux-amd64.tar.gz \ /libtensorflow-linux-avx2-1.15.2.tar.gz \ /libtensorflow-linux-avx-1.15.2.tar.gz \ /libtensorflow-linux-cpu-1.15.2.tar.gz From e4b01b02a9f76c6582d67f81fc9f8058cc158b94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 Feb 2023 16:58:54 -0500 Subject: [PATCH 4383/6505] Update photoprism-v5-install.sh code refactoring --- install/photoprism-v5-install.sh | 41 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index f674597e..7946d390 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -8,7 +8,6 @@ if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -AVX=$(grep -o -m1 'avx[^ ]*' /proc/cpuinfo) YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -106,10 +105,15 @@ msg_info "Installing Node.js" $STD apt-get -y install nodejs msg_ok "Installed Node.js" -msg_info "Installing Golang (Patience)" -$STD wget https://golang.org/dl/go1.20.1.linux-amd64.tar.gz -$STD tar -xzf go1.20.1.linux-amd64.tar.gz -C /usr/local +msg_info "Installing Golang" +set +o pipefail +RELEASE=$(curl -s https://go.dev/dl/ | grep -o "go.*\linux-amd64.tar.gz" | head -n 1) +wget -q https://golang.org/dl/$RELEASE +$STD tar -xzf $RELEASE -C /usr/local $STD ln -s /usr/local/go/bin/go /usr/local/bin/go +msg_ok "Installed Golang" + +msg_info "Installing Go Dependencies" $STD go install github.com/tianon/gosu@latest $STD go install golang.org/x/tools/cmd/goimports@latest $STD go install github.com/psampaz/go-mod-outdated@latest @@ -121,20 +125,21 @@ cp /usr/local/go/bin/richgo /usr/local/bin/richgo cp /usr/local/go/bin/gosu /usr/local/sbin/gosu chown root:root /usr/local/sbin/gosu chmod 755 /usr/local/sbin/gosu -msg_ok "Installed Golang" +msg_ok "Installed Go Dependencies" msg_info "Installing Tensorflow" -if [[ "$AVX" =~ avx2 ]]; then - $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz - $STD tar -C /usr/local -xzf libtensorflow-linux-avx2-1.15.2.tar.gz -elif [[ "$AVX" =~ avx ]]; then - $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx-1.15.2.tar.gz - $STD tar -C /usr/local -xzf libtensorflow-linux-avx-1.15.2.tar.gz +if grep -q avx2 /proc/cpuinfo; then + suffix="avx2-" +elif grep -q avx /proc/cpuinfo; then + suffix="avx-" else - $STD wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-cpu-1.15.2.tar.gz - $STD tar -C /usr/local -xzf libtensorflow-linux-cpu-1.15.2.tar.gz + suffix="" fi -$STD ldconfig +version=$(curl -s https://dl.photoprism.org/tensorflow/amd64/ | grep -o "libtensorflow-amd64-$suffix.*\\.tar.gz" | head -n 1) +wget -q https://dl.photoprism.org/tensorflow/amd64/$version +tar -C /usr/local -xzf $version +ldconfig +set -o pipefail msg_ok "Installed Tensorflow" msg_info "Cloning PhotoPrism" @@ -205,12 +210,10 @@ $STD apt-get autoremove $STD apt-get autoclean rm -rf /var/{cache,log}/* \ /photoprism \ - /go1.20.1.linux-amd64.tar.gz \ - /libtensorflow-linux-avx2-1.15.2.tar.gz \ - /libtensorflow-linux-avx-1.15.2.tar.gz \ - /libtensorflow-linux-cpu-1.15.2.tar.gz + /$RELEASE \ + /$version msg_ok "Cleaned" msg_info "Starting PhotoPrism" -$STD systemctl enable --now photoprism +systemctl enable -q --now photoprism msg_ok "Started PhotoPrism" From 652df53f754377c5fe1de6f380d49270b1201715 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Feb 2023 09:36:32 -0500 Subject: [PATCH 4384/6505] Update homepage-v5.sh fix linting error --- ct/homepage-v5.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 4246a5f3..67da0282 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -327,6 +327,8 @@ fi cd /opt/homepage systemctl stop homepage git pull --force &>/dev/null +sed -i 's/prowlarr: dynamic(() => import("\.\/prowlarr\/component")),/\/\/ &/' /opt/homepage/src/widgets/components.js +rm -rf /opt/homepage/src/widgets/prowlarr/component.jsx pnpm install &>/dev/null pnpm build &>/dev/null systemctl start homepage From 65ea70bdffd7cc8c88f8561b0124067c958b408f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Feb 2023 09:37:48 -0500 Subject: [PATCH 4385/6505] Update homepage-v5-install.sh fix linting error --- install/homepage-v5-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index d4a4e801..e9c66cba 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -102,6 +102,8 @@ $STD git clone https://github.com/benphelps/homepage.git /opt/homepage cd /opt/homepage mkdir -p config cp /opt/homepage/src/skeleton/* /opt/homepage/config +sed -i 's/prowlarr: dynamic(() => import("\.\/prowlarr\/component")),/\/\/ &/' /opt/homepage/src/widgets/components.js +rm -rf /opt/homepage/src/widgets/prowlarr/component.jsx $STD pnpm install $STD pnpm build msg_ok "Installed Homepage" From a8ed97f39ecb1b7745aebd8da360cfa6f17d926d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Feb 2023 04:33:48 -0500 Subject: [PATCH 4386/6505] Update nginxproxymanager-v5.sh fix cleanup --- ct/nginxproxymanager-v5.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 35e7df35..3d1be04b 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -10,11 +10,11 @@ clear cat <<"EOF" _ __ _ ____ __ ___ - / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____ + / | / /___ _(_)___ _ __ / __ \_________v5_ ____ __ / |/ /___ _____ ____ _____ ____ _____ / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ / /| / /_/ / / / / /> < / ____/ / / /_/ /> Date: Mon, 20 Feb 2023 04:35:08 -0500 Subject: [PATCH 4387/6505] Update nginxproxymanager-v5-install.sh fix cleanup --- install/nginxproxymanager-v5-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index d1b5cd4b..8e16f101 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -270,6 +270,7 @@ $STD systemctl enable --now npm msg_ok "Started Services" msg_info "Cleaning up" +rm -rf ../nginx-proxy-manager-* $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 565e4349ff5a04757ff8230ba9f0b470f9128d46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Feb 2023 10:53:30 -0500 Subject: [PATCH 4388/6505] Update photoprism-v5-install.sh fix cpu only suffix --- install/photoprism-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 7946d390..084c512e 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -133,7 +133,7 @@ if grep -q avx2 /proc/cpuinfo; then elif grep -q avx /proc/cpuinfo; then suffix="avx-" else - suffix="" + suffix="1" fi version=$(curl -s https://dl.photoprism.org/tensorflow/amd64/ | grep -o "libtensorflow-amd64-$suffix.*\\.tar.gz" | head -n 1) wget -q https://dl.photoprism.org/tensorflow/amd64/$version From 1780cd99c50d0a15d64769a77e81c6c6991b1af2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Feb 2023 15:42:48 -0500 Subject: [PATCH 4389/6505] Update update-lxcs.sh Start the container and perform an update if it is not a template. --- misc/update-lxcs.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 38031eb2..7aa00b17 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -49,16 +49,11 @@ function update_container() { esac } header_info -read -p "Skip stopped containers? [y/N]" -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]]; then - skip=no -else - skip=yes -fi + for container in $containers; do status=$(pct status $container) - if [ "$skip" == "no" ] && [ "$status" == "status: stopped" ]; then + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" From a36d736bf41805d6dc6f7cf3845cd9da732f9837 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Feb 2023 15:57:12 -0500 Subject: [PATCH 4390/6505] Update clean.sh define default action (N) --- misc/clean.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/clean.sh b/misc/clean.sh index 8c604b46..1d32009e 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -29,7 +29,7 @@ if [[ -z "$cache" ]]; then else echo -e "$cache \n" echo -e "${GN}Cache in $name${CL}" - read -p "Would you like to remove the selected cache listed above? [y/n] " -n 1 -r + read -p "Would you like to remove the selected cache listed above? [y/N] " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Removing cache" @@ -47,7 +47,7 @@ if [[ -z "$logs" ]]; then else echo -e "$logs \n" echo -e "${GN}Logs in $name${CL}" - read -p "Would you like to remove the selected logs listed above? [y/n] " -n 1 -r + read -p "Would you like to remove the selected logs listed above? [y/N] " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Removing logs" From 3efdce3526b901aa073f809da3b8f84005ca1cc8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Feb 2023 16:02:51 -0500 Subject: [PATCH 4391/6505] Update clean-lxcs.sh Start the container and prompt to clean if it is not a template. --- misc/clean-lxcs.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index bb445767..0456383d 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -42,17 +42,11 @@ function clean_container() { echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" } -read -p "Skip stopped containers? [y/N]" -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]]; then - skip=no -else - skip=yes -fi for container in $containers; do status=$(pct status $container) - if [ "$skip" == "no" ] && [ "$status" == "status: stopped" ]; then + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" From 6690a31ff79eb17d6177a12f40ffe4d76be7f22f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Feb 2023 05:24:50 -0500 Subject: [PATCH 4392/6505] Update homepage-v5.sh revert linting error fix --- ct/homepage-v5.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 67da0282..4246a5f3 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -327,8 +327,6 @@ fi cd /opt/homepage systemctl stop homepage git pull --force &>/dev/null -sed -i 's/prowlarr: dynamic(() => import("\.\/prowlarr\/component")),/\/\/ &/' /opt/homepage/src/widgets/components.js -rm -rf /opt/homepage/src/widgets/prowlarr/component.jsx pnpm install &>/dev/null pnpm build &>/dev/null systemctl start homepage From b724abc81bdae8e60c3834d138fbf185e5f23872 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Feb 2023 05:25:40 -0500 Subject: [PATCH 4393/6505] Update homepage-v5-install.sh revert linting error fix --- install/homepage-v5-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index e9c66cba..d4a4e801 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -102,8 +102,6 @@ $STD git clone https://github.com/benphelps/homepage.git /opt/homepage cd /opt/homepage mkdir -p config cp /opt/homepage/src/skeleton/* /opt/homepage/config -sed -i 's/prowlarr: dynamic(() => import("\.\/prowlarr\/component")),/\/\/ &/' /opt/homepage/src/widgets/components.js -rm -rf /opt/homepage/src/widgets/prowlarr/component.jsx $STD pnpm install $STD pnpm build msg_ok "Installed Homepage" From 911d19cab6be9bf8cbb7f7abdbd4455438d3d860 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Feb 2023 12:48:16 -0500 Subject: [PATCH 4394/6505] Update update-lxcs.sh add option to exclude an additional container by adding the CTID at the end of the shell command --- misc/update-lxcs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 7aa00b17..b423b508 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -34,7 +34,8 @@ while true; do esac done clear -containers=$(pct list | tail -n +2 | cut -f1 -d' ') +exclude_container="$@" +containers=$(pct list | tail -n +2 | cut -f1 -d' ' | grep -vE "^($exclude_container)$") function update_container() { container=$1 header_info @@ -49,7 +50,6 @@ function update_container() { esac } header_info - for container in $containers; do status=$(pct status $container) template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") From e840f2f26f5358e6d9b38c1223584d6ce3eecf88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Feb 2023 14:29:27 -0500 Subject: [PATCH 4395/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ec418768..67641b69 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -3,6 +3,14 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-02-23 + +### Changed + +- **Proxmox LXC Updater** + - Skip all templates, allowing for the starting, updating, and shutting down of containers to be resumed automatically. + - Exclude an additional container by adding the CTID at the end of the shell command ( -s 103). + ## 2023-02-16 ### Changed From 271f29bc59cc2131a50c968c0cb235294fa6b325 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Feb 2023 01:00:53 -0500 Subject: [PATCH 4396/6505] don't trap Internet/DNS check error (#1098) --- install/adguard-v5-install.sh | 2 ++ install/audiobookshelf-v5-install.sh | 2 ++ install/autobrr-v5-install.sh | 2 ++ install/blocky-v5-install.sh | 2 ++ install/casaos-v5-install.sh | 2 ++ install/changedetection-v5-install.sh | 2 ++ install/cronicle-v5-install.sh | 2 ++ install/daemonsync-v5-install.sh | 2 ++ install/dashy-v5-install.sh | 2 ++ install/debian-v5-install.sh | 2 ++ install/deconz-v5-install.sh | 2 ++ install/deluge-v5-install.sh | 2 ++ install/devuan-v5-install.sh | 2 ++ install/docker-v5-install.sh | 2 ++ install/emby-v5-install.sh | 2 ++ install/emqx-v5-install.sh | 2 ++ install/esphome-v5-install.sh | 2 ++ install/go2rtc-v5-install.sh | 2 ++ install/grafana-v5-install.sh | 2 ++ install/grocy-v5-install.sh | 2 ++ install/heimdalldashboard-v5-install.sh | 2 ++ install/homeassistant-core-v5-install.sh | 2 ++ install/homeassistant-v5-install.sh | 2 ++ install/homebridge-v5-install.sh | 2 ++ install/homepage-v5-install.sh | 2 ++ install/homer-v5-install.sh | 2 ++ install/hyperion-v5-install.sh | 2 ++ install/influxdb-v5-install.sh | 2 ++ install/iobroker-v5-install.sh | 2 ++ install/jellyfin-v5-install.sh | 2 ++ install/k0s-v5-install.sh | 2 ++ install/kavita-v5-install.sh | 2 ++ install/keycloak-v5-install.sh | 2 ++ install/lidarr-v5-install.sh | 2 ++ install/magicmirror-v5-install.sh | 2 ++ install/mariadb-v5-install.sh | 2 ++ install/meshcentral-v5-install.sh | 2 ++ install/motioneye-v5-install.sh | 2 ++ install/mqtt-v5-install.sh | 2 ++ install/n8n-v5-install.sh | 2 ++ install/navidrome-v5-install.sh | 2 ++ install/nextcloudpi-v5-install.sh | 2 ++ install/nginxproxymanager-v5-install.sh | 2 ++ install/nocodb-v5-install.sh | 2 ++ install/node-red-v5-install.sh | 2 ++ install/omada-v5-install.sh | 2 ++ install/omv-v5-install.sh | 2 ++ install/openhab-v5-install.sh | 2 ++ install/paperless-ngx-v5-install.sh | 2 ++ install/photoprism-v5-install.sh | 2 ++ install/pihole-v5-install.sh | 2 ++ install/plex-v5-install.sh | 2 ++ install/podman-homeassistant-v5-install.sh | 2 ++ install/podman-v5-install.sh | 2 ++ install/postgresql-v5-install.sh | 2 ++ install/prometheus-v5-install.sh | 2 ++ install/prowlarr-v5-install.sh | 2 ++ install/radarr-v5-install.sh | 2 ++ install/readarr-v5-install.sh | 2 ++ install/rstptoweb-v5-install.sh | 2 ++ install/sabnzbd-v5-install.sh | 2 ++ install/scrypted-v5-install.sh | 2 ++ install/shinobi-v5-install.sh | 2 ++ install/sonarr-v5-install.sh | 2 ++ install/syncthing-v5-install.sh | 2 ++ install/tdarr-v5-install.sh | 2 ++ install/technitiumdns-v5-install.sh | 2 ++ install/transmission-v5-install.sh | 2 ++ install/trilium-v5-install.sh | 2 ++ install/ubuntu-v5-install.sh | 2 ++ install/umbrel-v5-install.sh | 2 ++ install/unifi-v5-install.sh | 2 ++ install/uptimekuma-v5-install.sh | 2 ++ install/vaultwarden-v5-install.sh | 2 ++ install/whisparr-v5-install.sh | 2 ++ install/whoogle-v5-install.sh | 2 ++ install/wikijs-v5-install.sh | 2 ++ install/wireguard-v5-install.sh | 2 ++ install/yunohost-v5-install.sh | 2 ++ install/zigbee2mqtt-v5-install.sh | 2 ++ install/zwave-js-ui-v5-install.sh | 2 ++ 81 files changed, 162 insertions(+) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index e74135d9..27f82a04 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index 0be7f07a..0f9018d4 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 1485c75b..094d2d9d 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index f51e98fb..565fb004 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index ada2bb6b..e2bec076 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index 7d2bda09..5a582c98 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index a8bb2b6d..785cd1bc 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 9b5e7eea..d4f703ee 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 565690e2..a4aa247f 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 7a4f410e..03b42c31 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 2d51c7e0..7dee64a5 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index da12b769..9164cce2 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/devuan-v5-install.sh b/install/devuan-v5-install.sh index da159dbe..2ab60b40 100644 --- a/install/devuan-v5-install.sh +++ b/install/devuan-v5-install.sh @@ -60,6 +60,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -73,6 +74,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 31ceda72..dbd591e7 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 066dc17d..be0e0a42 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 9529d961..d63e51b7 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index 2a8f81f6..d18f2873 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/go2rtc-v5-install.sh b/install/go2rtc-v5-install.sh index 532e4a30..9cc1f08e 100644 --- a/install/go2rtc-v5-install.sh +++ b/install/go2rtc-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 159fefe2..7229d99b 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index f8087bbd..9bebd2fe 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index f0eee420..9f132699 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index ac3cc58d..9418516a 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index 071ab8af..be302148 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index f07731d6..5d640d5f 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index d4a4e801..e3efeb37 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index bf873e80..48193db5 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index cdf9fd91..5d34310d 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 5f4d9f67..5cafffaa 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 9316795f..1b658cde 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 11451bf2..31bf0c17 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index fc6f6314..c64cc71d 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index b6e0d230..19c4c8b4 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index ae2a6754..f272ec54 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index d5798b44..dfbda183 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 9f141744..85845a72 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 07c6486b..25468b0a 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index f37c5614..c001071e 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 2c177e73..97a8efbb 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 980ad410..9f2960b7 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 1881f808..31446ae5 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 2dd1b369..732a7951 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 4b4c4d21..b845b2f8 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 8e16f101..1973553b 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index c5ecc2fb..33377c85 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index 5b548bf0..9f59d1b8 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 0271ba38..176b67fc 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 22319f8b..8fc871f8 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index fc7861d1..6e181437 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 90d0d518..6279188b 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 084c512e..39373a05 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 0d3ae506..a472ab55 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -64,6 +64,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -77,6 +78,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index f7b00eee..a3ca2992 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 53779ee1..8d768fcb 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 7b366a9c..d0f315ab 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index d9dba2eb..810dca0a 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 85009f9a..71274e88 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index b4e6a048..41c47fa4 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 822edb0f..e7a01987 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index bffb5dc6..4a8d6b22 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/rstptoweb-v5-install.sh b/install/rstptoweb-v5-install.sh index 6a7c1d30..227c0d7a 100644 --- a/install/rstptoweb-v5-install.sh +++ b/install/rstptoweb-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 9856ec3a..ee5a2fb0 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 69805c7f..a5546fe3 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 69d1e634..45a8cc09 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update --fix-missing diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 1980b551..8b1eeda9 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 38c001a1..74911940 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 35dc88b0..e5e9cdb5 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 39c50d12..8c7d1369 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index f11bbdbf..0f8706fe 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 8a72a790..3c3cb8a1 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index d7569a6f..21202a71 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 8bfaaadb..6800d9ed 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 6d9ece10..84f8cdfb 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -64,6 +64,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -77,6 +78,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 674bc025..6ba658ac 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index b8d5f39e..21c3f47d 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index b97cd37a..360d9ab7 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 0897cac6..2aa1607e 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index fb3aecbd..4f5dd643 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index b36f310d..4c5d5c11 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR OPTIONS_PATH='/options.conf' cat >$OPTIONS_PATH <<'EOF' diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 4598cbd8..50cf173a 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -62,6 +62,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -75,6 +76,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 89e08b24..e9bf9173 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 6118ef0f..d63fe7fc 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -63,6 +63,7 @@ msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" set +e +trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt @@ -76,6 +77,7 @@ fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" $STD apt-get update From f0706c924d2777146fe138d6cd22403ba00c8338 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Feb 2023 16:35:41 -0500 Subject: [PATCH 4397/6505] Update technitiumdns-v5-install.sh add ASP.NET Core Runtime --- install/technitiumdns-v5-install.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 8c7d1369..ab510388 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -90,6 +90,14 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" +msg_info "Installing ASP.NET Core Runtime" +wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb +$STD dpkg -i packages-microsoft-prod.deb +rm -rf packages-microsoft-prod.deb +$STD apt-get update +$STD apt-get install -y aspnetcore-runtime-7.0 +msg_ok "Installed ASP.NET Core Runtime" + msg_info "Installing Technitium DNS" systemctl stop systemd-resolved echo "DNSStubListener=no" >>/etc/systemd/resolved.conf From 9aea5320f3cf1b46d24bf13125bfbca3c6aa4250 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Feb 2023 16:54:13 -0500 Subject: [PATCH 4398/6505] Update technitiumdns-v5.sh check for ASP.NET Core Runtime, if not present, install --- ct/technitiumdns-v5.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 099d6b65..f3aa425a 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -335,6 +335,14 @@ echo "===============================" echo "Technitium DNS Server Update" echo "===============================" +if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then + wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb + dpkg -i packages-microsoft-prod.deb + apt-get update + apt-get install -y aspnetcore-runtime-7.0 + rm packages-microsoft-prod.deb +fi + if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then dotnetFound="yes" else From 22a437ee09a1d05fb6491f83b6c8278a635b8f06 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Feb 2023 17:27:00 -0500 Subject: [PATCH 4399/6505] Update technitiumdns-v5.sh tweak update --- ct/technitiumdns-v5.sh | 71 +++--------------------------------------- 1 file changed, 5 insertions(+), 66 deletions(-) diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index f3aa425a..8fc9d666 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -320,20 +320,7 @@ header_info function update_script() { header_info -msg_info "Updating ${APP} LXC" -dotnetDir="/opt/dotnet" -dnsDir="/etc/dns" -dnsTar="/etc/dns/DnsServerPortable.tar.gz" -dnsUrl="https://download.technitium.com/dns/DnsServerPortable.tar.gz" - -mkdir -p $dnsDir -installLog="$dnsDir/install.log" -echo "" >$installLog - -echo "" -echo "===============================" -echo "Technitium DNS Server Update" -echo "===============================" +msg_info "Updating ${APP}" if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb @@ -342,58 +329,10 @@ if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then apt-get install -y aspnetcore-runtime-7.0 rm packages-microsoft-prod.deb fi - -if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then - dotnetFound="yes" -else - dotnetFound="no" -fi - -if [ -d $dotnetDir ]; then - dotnetUpdate="yes" - echo "Updating .NET 7 Runtime..." -fi - -curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 7.0 --runtime dotnet --no-path --install-dir $dotnetDir --verbose >>$installLog 2>&1 - -if [ ! -f "/usr/bin/dotnet" ]; then - ln -s $dotnetDir/dotnet /usr/bin >>$installLog 2>&1 -fi - -if dotnet --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 7.0."; then - if [ "$dotnetUpdate" = "yes" ]; then - echo ".NET 7 Runtime was updated successfully!" - fi -else - echo "Failed to update .NET 7 Runtime. Please try again." - exit 1 -fi - -if curl -o $dnsTar --fail $dnsUrl >>$installLog 2>&1; then - if [ -d $dnsDir ]; then - echo "Updating Technitium DNS Server..." - fi - - tar -zxf $dnsTar -C $dnsDir >>$installLog 2>&1 - - if [ "$(ps --no-headers -o comm 1 | tr -d '\n')" = "systemd" ]; then - if [ -f "/etc/systemd/system/dns.service" ]; then - echo "Restarting systemd service..." - systemctl restart dns.service >>$installLog 2>&1 - fi - - echo "" - echo "Technitium DNS Server was updated successfully!" - else - echo "" - echo "Failed to update Technitium DNS Server: systemd was not detected." - exit 1 - fi -else - echo "" - echo "Failed to download Technitium DNS Server from: $dnsUrl" - exit 1 -fi +wget -q https://download.technitium.com/dns/DnsServerPortable.tar.gz +tar -zxf DnsServerPortable.tar.gz -C /etc/dns/ &>/dev/null +rm -rf DnsServerPortable.tar.gz +systemctl restart dns.service msg_ok "Update Successfull" exit } From 7759485a62fcc812d4694485fad8d34124fb8ae5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Feb 2023 19:52:10 -0500 Subject: [PATCH 4400/6505] qBittorrent & Jackett (#1106) --- ct/jackett-v5.sh | 391 +++++++++++++++++++++++++++++ ct/qbittorrent-v5.sh | 392 ++++++++++++++++++++++++++++++ install/jackett-v5-install.sh | 139 +++++++++++ install/qbittorrent-v5-install.sh | 131 ++++++++++ 4 files changed, 1053 insertions(+) create mode 100644 ct/jackett-v5.sh create mode 100644 ct/qbittorrent-v5.sh create mode 100644 install/jackett-v5-install.sh create mode 100644 install/qbittorrent-v5-install.sh diff --git a/ct/jackett-v5.sh b/ct/jackett-v5.sh new file mode 100644 index 00000000..9ee88af0 --- /dev/null +++ b/ct/jackett-v5.sh @@ -0,0 +1,391 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ __ __ + / /___ ______/ /_____v5/ /_/ /_ + __ / / __ `/ ___/ //_/ _ \/ __/ __/ +/ /_/ / /_/ / /__/ ,< / __/ /_/ /_ +\____/\__,_/\___/_/|_|\___/\__/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="Jackett" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/jackett.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9117${CL}\n" diff --git a/ct/qbittorrent-v5.sh b/ct/qbittorrent-v5.sh new file mode 100644 index 00000000..0af5fe13 --- /dev/null +++ b/ct/qbittorrent-v5.sh @@ -0,0 +1,392 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _ __ __ __ + ____ _/ __ )(_) /_/ /_____ _____________v5____ / /_ + / __ `/ __ / / __/ __/ __ \/ ___/ ___/ _ \/ __ \/ __/ +/ /_/ / /_/ / / /_/ /_/ /_/ / / / / / __/ / / / /_ +\__, /_____/_/\__/\__/\____/_/ /_/ \___/_/ /_/\__/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="qBittorrent" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + PW="" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="Automatic Login" PW=" " + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" + advanced_settings + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/qbittorrent-nox.service ]]; then + msg_error "No ${APP} Installation Found!" + exit +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8090${CL}\n" diff --git a/install/jackett-v5-install.sh b/install/jackett-v5-install.sh new file mode 100644 index 00000000..fd323953 --- /dev/null +++ b/install/jackett-v5-install.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY +done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +trap - ERR +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Jackett" +RELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz +tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt +rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz +msg_ok "Installed Jackett" + +msg_info "Creating Service" +cat </etc/systemd/system/jackett.service +[Unit] +Description=Jackett Daemon +After=network.target +[Service] +SyslogIdentifier=jackett +Restart=always +RestartSec=5 +Type=simple +WorkingDirectory=/opt/Jackett +ExecStart=/bin/sh /opt/Jackett/jackett_launcher.sh +TimeoutStopSec=30 +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now jackett.service +msg_ok "Created Service" + +echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* +if ! getent shadow root | grep -q "^root:[^\!*]"; then + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/qbittorrent-v5-install.sh b/install/qbittorrent-v5-install.sh new file mode 100644 index 00000000..3a7d4edb --- /dev/null +++ b/install/qbittorrent-v5-install.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS" +sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen +locale-gen >/dev/null +for ((i=RETRY_NUM; i>0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY +done +if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(hostname -I)" + +set +e +trap - ERR +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +msg_info "Updating Container OS" +$STD apt-get update +$STD apt-get -y upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing qbittorrent-nox" +$STD apt-get install -y qbittorrent-nox +msg_ok "qbittorrent-nox" + +msg_info "Creating Service" +cat </etc/systemd/system/qbittorrent-nox.service +[Unit] +Description=qBittorrent client +After=network.target +[Service] +ExecStart=/usr/bin/qbittorrent-nox --webui-port=8090 +Restart=always +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now qbittorrent-nox +msg_ok "Created Service" + +echo "export TERM='xterm-256color'" >>/root/.bashrc +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +chmod -x /etc/update-motd.d/* +if ! getent shadow root | grep -q "^root:[^\!*]"; then + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +fi +if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 4d78d5233c3753d718473fbd18fc556cad475166 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Feb 2023 21:21:49 -0500 Subject: [PATCH 4401/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 67641b69..ade68f84 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,8 +1,16 @@ - # Change Log All notable changes to this project will be documented in this file. +## 2023-02-24 + +### Changed + +- **qBittorrent LXC** (Thanks @romka777) + - NEW Script +- **Jackett LXC** (Thanks @romka777) + - NEW Script + ## 2023-02-23 ### Changed From 2c27ff2cfeebf0b86b5fc737ea5b04c3bb402124 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Feb 2023 21:41:25 -0500 Subject: [PATCH 4402/6505] Update wireguard-v5.sh (#1109) (#1110) Fix typo in service file that prevents WGDashboard from starting on boot Co-authored-by: Logan Long --- ct/wireguard-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 8bac4026..23d3d675 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -361,7 +361,7 @@ msg_ok "Installed WGDashboard" msg_info "Creating Service" service_path="/etc/systemd/system/wg-dashboard.service" echo "[Unit] -After=netword.service +After=systemd-networkd.service [Service] WorkingDirectory=/etc/wgdashboard/src From c6648215141906d3c9b9aab77e1746ba645f3e7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Mar 2023 14:15:42 -0500 Subject: [PATCH 4403/6505] Update homeassistant-core-v5-install.sh python 3.11.1 --- install/homeassistant-core-v5-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 9418516a..03b48123 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -135,10 +135,10 @@ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path) msg_ok "Installed pyenv" . ~/.bashrc set -e -msg_info "Installing Python 3.10.8" -$STD pyenv install 3.10.8 -pyenv global 3.10.8 -msg_ok "Installed Python 3.10.8" +msg_info "Installing Python 3.11.1" +$STD pyenv install 3.11.1 +pyenv global 3.11.1 +msg_ok "Installed Python 3.11.1" msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant From 9f322e803c31b180f273c6cddcba91814ba7de78 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Mar 2023 15:04:19 -0500 Subject: [PATCH 4404/6505] Update hyperion-v5.sh fix update --- ct/hyperion-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 92cdc544..77124f48 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -322,7 +322,7 @@ function update_script() { header_info msg_info "Updating ${APP} LXC" apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +apt-get install -y hyperion &>/dev/null msg_ok "Updated ${APP} LXC" msg_ok "Update Successfull" exit From 2be4c2ccc55bc2b8e1d45c57d31fbac420474d16 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Mar 2023 18:48:59 -0500 Subject: [PATCH 4405/6505] Update omada-v5-install.sh v5.9.9 --- install/omada-v5-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index 176b67fc..c7edf4f4 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -95,9 +95,9 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed Dependencies" -msg_info "Installing Omada Controller v5.8.4" -wget -qL https://static.tp-link.com/upload/software/2023/202301/20230130/Omada_SDN_Controller_v5.8.4_Linux_x64.deb -$STD dpkg -i Omada_SDN_Controller_v5.8.4_Linux_x64.deb +msg_info "Installing Omada Controller v5.9.9" +wget -qL https://static.tp-link.com/upload/software/2023/202302/20230227/Omada_SDN_Controller_v5.9.9_Linux_x64.deb +$STD dpkg -i Omada_SDN_Controller_v5.9.9_Linux_x64.deb msg_ok "Installed Omada Controller" echo "export TERM='xterm-256color'" >>/root/.bashrc @@ -119,7 +119,7 @@ fi if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_v5.8.4_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb +rm -rf Omada_SDN_Controller_v5.9.9_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 8488668d1b04147306edf36630bc3674bf774e9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Mar 2023 06:19:08 -0500 Subject: [PATCH 4406/6505] Update jellyfin-v5-install.sh use Intel OpenCL ICD for Ubuntu 22.04 and later --- install/jellyfin-v5-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 31bf0c17..5b386716 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -97,7 +97,11 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then $STD apt-get -y install \ va-driver-all \ ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then $STD apt-get -y install beignet-opencl-icd; fi + if [[ ${PCT_OSVERSION} == "20.04" ]]; then + $STD apt-get install -y beignet-opencl-icd + else + $STD apt-get install -y intel-opencl-icd + fi /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* From 0c4356090812fd4079ffc63ba8b04f30e206617a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Mar 2023 06:43:45 -0500 Subject: [PATCH 4407/6505] Update emby-v5-install.sh use Intel OpenCL ICD for Ubuntu 22.04 and later --- install/emby-v5-install.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index be0e0a42..9129f141 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -95,8 +95,11 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then $STD apt-get -y install \ va-driver-all \ ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then $STD apt-get -y install beignet-opencl-icd; fi - + if [[ ${PCT_OSVERSION} == "20.04" ]]; then + $STD apt-get install -y beignet-opencl-icd + else + $STD apt-get install -y intel-opencl-icd + fi /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* From 1ca55a8d54f8b8366d7ed1882e08be29bf4a8792 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Mar 2023 06:45:45 -0500 Subject: [PATCH 4408/6505] Update plex-v5-install.sh use Intel OpenCL ICD for Ubuntu 22.04 and later --- install/plex-v5-install.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index a3ca2992..41a071c7 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -96,8 +96,11 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then $STD apt-get -y install \ va-driver-all \ ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then $STD apt-get -y install beignet-opencl-icd; fi - + if [[ ${PCT_OSVERSION} == "20.04" ]]; then + $STD apt-get install -y beignet-opencl-icd + else + $STD apt-get install -y intel-opencl-icd + fi /bin/chgrp video /dev/dri /bin/chmod 755 /dev/dri /bin/chmod 660 /dev/dri/* From c159c1add28d6f7986f5a46e255dab0bbc5056c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Mar 2023 07:20:28 -0500 Subject: [PATCH 4409/6505] Update homeassistant-v5.sh fix update --- ct/homeassistant-v5.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 010dcf7a..4d3a1750 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -27,7 +27,6 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -NEXTID=$(pvesh get /cluster/nextid) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") From d883f952760a3571171620e8ec61dd9225e7cb09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 Mar 2023 07:45:47 -0500 Subject: [PATCH 4410/6505] Update homeassistant-v5.sh fix directory check --- ct/homeassistant-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 4d3a1750..69a43f87 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -409,7 +409,7 @@ if command -v pveversion >/dev/null 2>&1; then install_script fi -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /var/lib/docker/volumes/hass_config/_data +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/docker/volumes/hass_config/_data ]]; then msg_error "No ${APP} Installation Found!" exit From 6d1d4a278cae4a04276ce1c10c86523158d1c74e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Mar 2023 14:40:39 -0500 Subject: [PATCH 4411/6505] Update alpine-v5.sh v3.17 --- ct/alpine-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 52f86cca..d88c7153 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -25,7 +25,7 @@ var_disk="0.1" var_cpu="1" var_ram="512" var_os="alpine" -var_version="3.16" +var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" INTEGER='^[0-9]+$' From f79e6fad5ef6ea0c00deb6eb16dcab7dd69fadaf Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Mar 2023 20:53:34 -0500 Subject: [PATCH 4412/6505] Create alpine-vaultwarden-v5-install.sh --- install/alpine-vaultwarden-v5-install.sh | 84 ++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 install/alpine-vaultwarden-v5-install.sh diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh new file mode 100644 index 00000000..97d76c46 --- /dev/null +++ b/install/alpine-vaultwarden-v5-install.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +set +e +trap - ERR + +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +msg_info "Updating Container OS" +$STD apk update +$STD apk upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apk add bash +$STD apk add curl +$STD apk add openssl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing Vaultwarden" +$STD apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing vaultwarden +cat </etc/conf.d/vaultwarden +export DATA_FOLDER=/var/lib/vaultwarden +export WEB_VAULT_ENABLED=true +export ADMIN_TOKEN=$(openssl rand -base64 48) +export ROCKET_ADDRESS=0.0.0.0 +EOF +$STD rc-service vaultwarden start +$STD rc-update add vaultwarden default +msg_ok "Installed Vaultwarden" +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +if [[ "${SSH_ROOT}" == "yes" ]]; then + $STD rc-update add sshd + $STD /etc/init.d/sshd start +fi From abfb9f59f3848ab9b09d9f64ef1276a22b9fddb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Mar 2023 20:55:19 -0500 Subject: [PATCH 4413/6505] Create alpine-vaultwarden-v5.sh --- ct/alpine-vaultwarden-v5.sh | 417 ++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 ct/alpine-vaultwarden-v5.sh diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh new file mode 100644 index 00000000..e438351e --- /dev/null +++ b/ct/alpine-vaultwarden-v5.sh @@ -0,0 +1,417 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ ____ __ +| | / /___ ___ __/ / /__ ______ __________/ /__v5____ +| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ +| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / +|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ + Alpine 3.17 + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Vaultwarden" +var_disk="0.3" +var_cpu="1" +var_ram="512" +var_os="alpine" +var_version="3.17" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +INTEGER='^[0-9]+$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" + PW="-password alpine" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} +function advanced_settings() { + CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi + PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $PW1 ]; then + PW1="alpine" PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + fi + fi + CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_ID ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi + fi + CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CT_NAME ]; then + HN="$NSAPP" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${CT_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $DISK_SIZE ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi + fi + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $GATE1 ]; then + GATE1="Default" GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + fi + fi + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" + DISABLEIP6="yes" + else + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $SD ]; then + SD="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + else + SX=$SD + SD="-searchdomain=$SD" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + fi + fi + NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $NS ]; then + NS="" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + else + NX=$NS + NS="-nameserver=$NS" + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MAC1 ]; then + MAC1="Default" MAC="" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" + SSH="yes" + else + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" + VERB="yes" + else + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { + normal=$(echo "\033[m") + menu=$(echo "\033[36m") + number=$(echo "\033[33m") + fgred=$(echo "\033[31m") + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${normal} Update Vaultwarden \n" + printf "${menu}**${number} 2)${normal} View Admin Token\n" + printf "\n${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." + read opt + +while [ "$opt" != "" ]; do + case $opt in + 1) + clear + echo -e "${fgred}Update Vaultwarden${normal}" + apk update &>/dev/null + apk upgrade --update-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing vaultwarden + + break + ;; + 2) + clear + echo -e "${fgred}View the Admin Token${normal}" + cat /etc/conf.d/vaultwarden | grep "ADMIN_TOKEN" | awk '{print substr($2, 7) }' + + break + ;; + x) + exit + ;; + \n) + exit + ;; + *) + clear + echo -e "Please choose an option from the menu" + update_script + ;; + esac +done +exit +} +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/conf.d/vaultwarden ]]; then + msg_error "No ${APP} Installation Found!" +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ -f /etc/conf.d/vaultwarden ]]; then + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From 3ba88d9b6942f4ef657fb2dae93ed4335dffb060 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 Mar 2023 21:18:52 -0500 Subject: [PATCH 4414/6505] Update alpine-vaultwarden-v5.sh lower ram --- ct/alpine-vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index e438351e..4b0704c1 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -22,7 +22,7 @@ echo -e "Loading..." APP="Alpine-Vaultwarden" var_disk="0.3" var_cpu="1" -var_ram="512" +var_ram="256" var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') From 4ec92846abda8b9c5bb47fccb885e94a5503183b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Mar 2023 07:22:29 -0500 Subject: [PATCH 4415/6505] Update alpine-vaultwarden-v5-install.sh Code refactoring --- install/alpine-vaultwarden-v5-install.sh | 43 +++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 97d76c46..6c1a5d80 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) @@ -7,7 +7,13 @@ if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi +if [ "$DISABLEIPV6" == "yes" ]; then +$STD sysctl net.ipv6.conf.all.disable_ipv6=1 +$STD sysctl net.ipv6.conf.default.disable_ipv6=1 +echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +$STD sysctl -p /etc/sysctl.d/99-sysctl.conf +fi YW=$(echo "\033[33m") RD=$(echo "\033[01;31m") BL=$(echo "\033[36m") @@ -15,17 +21,18 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") RETRY_NUM=10 RETRY_EVERY=3 +i=$RETRY_NUM CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" set -Eeuo pipefail -trap 'error_handler $LINENO' ERR +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR function error_handler() { local exit_code="$?" local line_number="$1" local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" echo -e "\n$error_message\n" } @@ -44,8 +51,36 @@ function msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +msg_info "Setting up Container OS " +while [ $i -gt 0 ]; do + if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + i=$((i-1)) +done + +if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" + set +e trap - ERR +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi From c887a6bea19c9e4180fa4a90519b858c453bfcd8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Mar 2023 08:56:36 -0500 Subject: [PATCH 4416/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ade68f84..ea375c30 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-07 + +### Changed + +- **Alpine-Vaultwarden LXC** + - NEW Script + ## 2023-02-24 ### Changed From 0e1a3ae998a146990bd94ce706d62796b9241ac3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Mar 2023 12:09:28 -0500 Subject: [PATCH 4417/6505] set time zone (#1131) Retrieve the time zone from Proxmox and configure the container to use the same time zone --- ct/adguard-v5.sh | 4 +++- ct/alpine-v5.sh | 4 +++- ct/alpine-vaultwarden-v5.sh | 4 +++- ct/archlinux-v5.sh | 4 +++- ct/audiobookshelf-v5.sh | 4 +++- ct/autobrr-v5.sh | 4 +++- ct/blocky-v5.sh | 4 +++- ct/casaos-v5.sh | 1 + ct/changedetection-v5.sh | 4 +++- ct/cronicle-v5.sh | 1 + ct/daemonsync-v5.sh | 4 +++- ct/dashy-v5.sh | 4 +++- ct/debian-v5.sh | 4 +++- ct/deconz-v5.sh | 4 +++- ct/deluge-v5.sh | 4 +++- ct/devuan-v5.sh | 4 +++- ct/docker-v5.sh | 1 + ct/emby-v5.sh | 4 +++- ct/emqx-v5.sh | 4 +++- ct/esphome-v5.sh | 4 +++- ct/go2rtc-v5.sh | 4 +++- ct/grafana-v5.sh | 4 +++- ct/grocy-v5.sh | 4 +++- ct/heimdalldashboard-v5.sh | 4 +++- ct/homeassistant-core-v5.sh | 4 +++- ct/homeassistant-v5.sh | 1 + ct/homebridge-v5.sh | 4 +++- ct/homepage-v5.sh | 4 +++- ct/homer-v5.sh | 4 +++- ct/hyperion-v5.sh | 4 +++- ct/influxdb-v5.sh | 4 +++- ct/iobroker-v5.sh | 4 +++- ct/jackett-v5.sh | 4 +++- ct/jellyfin-v5.sh | 4 +++- ct/k0s-v5.sh | 4 +++- ct/kavita-v5.sh | 4 +++- ct/keycloak-v5.sh | 4 +++- ct/lidarr-v5.sh | 4 +++- ct/magicmirror-v5.sh | 4 +++- ct/mariadb-v5.sh | 4 +++- ct/meshcentral-v5.sh | 4 +++- ct/motioneye-v5.sh | 4 +++- ct/mqtt-v5.sh | 4 +++- ct/n8n-v5.sh | 4 +++- ct/navidrome-v5.sh | 4 +++- ct/nextcloudpi-v5.sh | 4 +++- ct/nginxproxymanager-v5.sh | 4 +++- ct/nocodb-v5.sh | 4 +++- ct/node-red-v5.sh | 4 +++- ct/omada-v5.sh | 4 +++- ct/omv-v5.sh | 4 +++- ct/openhab-v5.sh | 4 +++- ct/paperless-ngx-v5.sh | 4 +++- ct/photoprism-v5.sh | 4 +++- ct/pihole-v5.sh | 4 +++- ct/plex-v5.sh | 4 +++- ct/podman-homeassistant-v5.sh | 4 +++- ct/podman-v5.sh | 4 +++- ct/postgresql-v5.sh | 4 +++- ct/prometheus-v5.sh | 4 +++- ct/prowlarr-v5.sh | 4 +++- ct/qbittorrent-v5.sh | 4 +++- ct/radarr-v5.sh | 4 +++- ct/readarr-v5.sh | 4 +++- ct/rockylinux-v5.sh | 4 +++- ct/rstptoweb-v5.sh | 4 +++- ct/sabnzbd-v5.sh | 4 +++- ct/scrypted-v5.sh | 4 +++- ct/shinobi-v5.sh | 4 +++- ct/sonarr-v5.sh | 4 +++- ct/syncthing-v5.sh | 4 +++- ct/tdarr-v5.sh | 4 +++- ct/technitiumdns-v5.sh | 4 +++- ct/transmission-v5.sh | 4 +++- ct/trilium-v5.sh | 4 +++- ct/ubuntu-v5.sh | 4 +++- ct/umbrel-v5.sh | 1 + ct/unifi-v5.sh | 4 +++- ct/uptimekuma-v5.sh | 4 +++- ct/vaultwarden-v5.sh | 4 +++- ct/whisparr-v5.sh | 4 +++- ct/whoogle-v5.sh | 4 +++- ct/wikijs-v5.sh | 4 +++- ct/wireguard-v5.sh | 4 +++- ct/yunohost-v5.sh | 4 +++- ct/zigbee2mqtt-v5.sh | 4 +++- ct/zwave-js-ui-v5.sh | 4 +++- install/adguard-v5-install.sh | 1 + install/audiobookshelf-v5-install.sh | 1 + install/autobrr-v5-install.sh | 1 + install/blocky-v5-install.sh | 1 + install/casaos-v5-install.sh | 1 + install/changedetection-v5-install.sh | 1 + install/cronicle-v5-install.sh | 1 + install/daemonsync-v5-install.sh | 1 + install/dashy-v5-install.sh | 1 + install/debian-v5-install.sh | 1 + install/deconz-v5-install.sh | 1 + install/deluge-v5-install.sh | 1 + install/docker-v5-install.sh | 1 + install/emby-v5-install.sh | 1 + install/emqx-v5-install.sh | 1 + install/esphome-v5-install.sh | 1 + install/go2rtc-v5-install.sh | 1 + install/grafana-v5-install.sh | 1 + install/grocy-v5-install.sh | 1 + install/heimdalldashboard-v5-install.sh | 1 + install/homeassistant-core-v5-install.sh | 1 + install/homeassistant-v5-install.sh | 1 + install/homebridge-v5-install.sh | 1 + install/homepage-v5-install.sh | 1 + install/homer-v5-install.sh | 1 + install/hyperion-v5-install.sh | 1 + install/influxdb-v5-install.sh | 1 + install/iobroker-v5-install.sh | 1 + install/jackett-v5-install.sh | 1 + install/jellyfin-v5-install.sh | 1 + install/k0s-v5-install.sh | 1 + install/kavita-v5-install.sh | 1 + install/keycloak-v5-install.sh | 1 + install/lidarr-v5-install.sh | 1 + install/magicmirror-v5-install.sh | 1 + install/mariadb-v5-install.sh | 1 + install/meshcentral-v5-install.sh | 1 + install/motioneye-v5-install.sh | 1 + install/mqtt-v5-install.sh | 1 + install/n8n-v5-install.sh | 1 + install/navidrome-v5-install.sh | 1 + install/nextcloudpi-v5-install.sh | 1 + install/nginxproxymanager-v5-install.sh | 1 + install/nocodb-v5-install.sh | 1 + install/node-red-v5-install.sh | 1 + install/omada-v5-install.sh | 1 + install/omv-v5-install.sh | 1 + install/openhab-v5-install.sh | 1 + install/paperless-ngx-v5-install.sh | 1 + install/photoprism-v5-install.sh | 1 + install/pihole-v5-install.sh | 1 + install/plex-v5-install.sh | 1 + install/podman-homeassistant-v5-install.sh | 1 + install/podman-v5-install.sh | 1 + install/postgresql-v5-install.sh | 1 + install/prometheus-v5-install.sh | 1 + install/prowlarr-v5-install.sh | 1 + install/qbittorrent-v5-install.sh | 1 + install/radarr-v5-install.sh | 1 + install/readarr-v5-install.sh | 1 + install/rstptoweb-v5-install.sh | 1 + install/sabnzbd-v5-install.sh | 1 + install/scrypted-v5-install.sh | 1 + install/shinobi-v5-install.sh | 1 + install/sonarr-v5-install.sh | 1 + install/syncthing-v5-install.sh | 1 + install/tdarr-v5-install.sh | 1 + install/technitiumdns-v5-install.sh | 1 + install/transmission-v5-install.sh | 1 + install/trilium-v5-install.sh | 1 + install/ubuntu-v5-install.sh | 1 + install/umbrel-v5-install.sh | 1 + install/unifi-v5-install.sh | 1 + install/uptimekuma-v5-install.sh | 1 + install/vaultwarden-v5-install.sh | 1 + install/whisparr-v5-install.sh | 1 + install/whoogle-v5-install.sh | 1 + install/wikijs-v5-install.sh | 1 + install/wireguard-v5-install.sh | 1 + install/yunohost-v5-install.sh | 1 + install/zigbee2mqtt-v5-install.sh | 1 + install/zwave-js-ui-v5-install.sh | 1 + 169 files changed, 333 insertions(+), 82 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 3ad5b01f..32b043ef 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -376,7 +377,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index d88c7153..3c42c898 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -28,6 +28,7 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -349,7 +350,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index 4b0704c1..06df8c11 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -27,6 +27,7 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -382,7 +383,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index a979ffeb..99b50c6e 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -27,6 +27,7 @@ var_os="archlinux" var_version="base" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -353,7 +354,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 903f34b0..98128a73 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,7 +353,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 049e4585..bdb2b666 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -368,7 +369,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index b88f4392..573e06b0 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 26f8fedb..dfe1fe4d 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index bfc1b6d6..1ba4ed72 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 614a20c4..ac90461a 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 96b9b8fb..196fe544 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 52a132c6..afd67aae 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -383,7 +384,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index c79f61fa..278f8bb9 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,7 +353,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 56b55259..38df740b 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -27,6 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -359,7 +360,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index e8349ab1..fd515d61 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index 4f7d5ea0..29ee1464 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -27,6 +27,7 @@ var_os="devuan" var_version="4.0" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,7 +353,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index 0afd7a11..f8bada16 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index 2859c147..dd20a0b3 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -27,6 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -376,7 +377,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 01b760c9..4828a5b4 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,7 +353,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index cd8cc028..e9ca6cf2 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -364,7 +365,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/go2rtc-v5.sh b/ct/go2rtc-v5.sh index 2ab170aa..3efc59bf 100644 --- a/ct/go2rtc-v5.sh +++ b/ct/go2rtc-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,7 +353,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index fa798d4a..f94b18e7 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index c49d1c5a..2525cdb2 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index bca0c925..656db61a 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -437,7 +438,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 828d9424..40c2d5d1 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -432,7 +433,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 69a43f87..bc1614ca 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index 8fda38e7..cf330c37 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 4246a5f3..8ef34ca2 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -364,7 +365,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index c18bd377..fcf78f88 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -381,7 +382,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index 77124f48..ada0c0d7 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index d7b62cd4..74d8063e 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index d657eeea..f022bcb4 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/jackett-v5.sh b/ct/jackett-v5.sh index 9ee88af0..554548b5 100644 --- a/ct/jackett-v5.sh +++ b/ct/jackett-v5.sh @@ -26,6 +26,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -356,7 +357,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index d0a8cf82..5af15bc0 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -28,6 +28,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -367,7 +368,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 143292ca..9cf74443 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index 77e3889a..d1869d7b 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 11f0d9ea..8f0ebe5c 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -359,7 +360,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index e4877512..0383aded 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 5f8b8704..606b6b41 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -360,7 +361,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 7705a589..5e1dd9ab 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index c34c5709..336e5d9f 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 78a5ff8b..e000822a 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index 831ea218..a43ce1b9 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -26,6 +26,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 4e9ffc1e..cac60cdc 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 8ad6a7d0..4cb57222 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -368,7 +369,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 2832dfd5..1e663eaa 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 3d1be04b..71d7c8e6 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -467,7 +468,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 7bce9820..af343280 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -360,7 +361,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 934d59a3..7051fbf2 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -392,7 +393,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 929591ec..1f7b2c6d 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -27,6 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -367,7 +368,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 544f073c..f98708b7 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -359,7 +360,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 74d31c86..a21c2b72 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -359,7 +360,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index e11ba30b..1f0d2ce0 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -425,7 +426,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index ecc2399f..21de9379 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -380,7 +381,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index d22efe08..2838c254 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 5f0cae8a..77f384ed 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -27,6 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -377,7 +378,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index e03bca6a..a7beabb3 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -31,6 +31,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -408,7 +409,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 93d108b9..05cd6537 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index 3c052a86..91bf1f6a 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index bf6a2cf6..a55e74cc 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index d7ffa755..c23b23a5 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/qbittorrent-v5.sh b/ct/qbittorrent-v5.sh index 0af5fe13..ef84f26a 100644 --- a/ct/qbittorrent-v5.sh +++ b/ct/qbittorrent-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 815cc4fd..77559143 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 769e1020..7ab40901 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index ea9c9550..ddd6517b 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -28,6 +28,7 @@ var_os="rockylinux" var_version="9" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/rstptoweb-v5.sh b/ct/rstptoweb-v5.sh index d067026b..670fbe2d 100644 --- a/ct/rstptoweb-v5.sh +++ b/ct/rstptoweb-v5.sh @@ -26,6 +26,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -351,7 +352,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index e923ad36..3076ab52 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 6b90147f..aff8cf7b 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -359,7 +360,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 14b4850c..9d854a57 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -27,6 +27,7 @@ var_os="ubuntu" var_version="22.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -368,7 +369,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index d948ab5b..608ce718 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 2b0e83a7..4997662a 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -359,7 +360,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index 5813b5a6..eb311112 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 8fc9d666..e05f3be3 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -367,7 +368,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index 0ee5d068..b1f3aab6 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 62a54f47..28b04449 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -377,7 +378,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index f283066b..7319b8f2 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -27,6 +27,7 @@ var_os="ubuntu" var_version="22.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -360,7 +361,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index e70695d1..d7640ab9 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 2e2bce79..b91ad8c2 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index a7d24e82..7659983d 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -375,7 +376,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index d3fd4f29..135bbe1b 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -426,7 +427,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 7a3beee5..a31ac005 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -358,7 +359,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 6d4d9093..4058cbe1 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 2baebf4a..50da63bd 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -380,7 +381,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 23d3d675..4522791f 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -412,7 +413,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index c5b72d48..bf8f1798 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -357,7 +358,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index fc238d95..460c4980 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -28,6 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -404,7 +405,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index a56356b4..23e88c38 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -27,6 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" +timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -371,7 +372,8 @@ else FEATURES="nesting=1" fi TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null +pushd $TEMP_DIR >/dev/null +export tz=$timezone export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP export VERBOSE=$VERB diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index 27f82a04..ac6bf8fd 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index 0f9018d4..c24e600c 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 094d2d9d..7446e75e 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index 565fb004..275f5e09 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index e2bec076..efda281c 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index 5a582c98..a400759a 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 785cd1bc..daba7eb7 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index d4f703ee..f92e786c 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index a4aa247f..cec3a16f 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 03b42c31..53f5a875 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 7dee64a5..bdef4d6c 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 9164cce2..42325e53 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index dbd591e7..906534e2 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 9129f141..41bedf3d 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index d63e51b7..8c791710 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index d18f2873..d653ee25 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/go2rtc-v5-install.sh b/install/go2rtc-v5-install.sh index 9cc1f08e..51d6831f 100644 --- a/install/go2rtc-v5-install.sh +++ b/install/go2rtc-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 7229d99b..f09c81a7 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index 9bebd2fe..92242165 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index 9f132699..f287b687 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 03b48123..a1190ce0 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index be302148..5f8fe843 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 5d640d5f..b150c163 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index e3efeb37..0b261e03 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 48193db5..23831e78 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 5d34310d..580817b7 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 5cafffaa..4280456a 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 1b658cde..6f9cda96 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/jackett-v5-install.sh b/install/jackett-v5-install.sh index fd323953..9f257f5b 100644 --- a/install/jackett-v5-install.sh +++ b/install/jackett-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 5b386716..8faa5d27 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index c64cc71d..138d51ce 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 19c4c8b4..76fdf021 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index f272ec54..6858e15b 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index dfbda183..aa990c17 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 85845a72..3dbaf0a6 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 25468b0a..db5eb164 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index c001071e..7861a8fd 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 97a8efbb..f112d854 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 9f2960b7..3be1d8a0 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 31446ae5..fbafc2db 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index 732a7951..c6a7f04e 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index b845b2f8..8d25928a 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 1973553b..960bb71f 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index 33377c85..270436a8 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index 9f59d1b8..fcc4c371 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index c7edf4f4..ad68dec6 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 8fc871f8..d9169e75 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index 6e181437..30b9f61d 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 6279188b..c48908f2 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index 39373a05..b9c0782f 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index a472ab55..5976ac9e 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -48,6 +48,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 41a071c7..b15b104c 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 8d768fcb..59918724 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index d0f315ab..89114aba 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 810dca0a..3c98caef 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 71274e88..36ad41fc 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 41c47fa4..0877c3e9 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/qbittorrent-v5-install.sh b/install/qbittorrent-v5-install.sh index 3a7d4edb..7569b0fd 100644 --- a/install/qbittorrent-v5-install.sh +++ b/install/qbittorrent-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index e7a01987..7344a496 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index 4a8d6b22..c1fb8f85 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/rstptoweb-v5-install.sh b/install/rstptoweb-v5-install.sh index 227c0d7a..c0d51ac9 100644 --- a/install/rstptoweb-v5-install.sh +++ b/install/rstptoweb-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index ee5a2fb0..9434927a 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index a5546fe3..42080a83 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index 45a8cc09..d0f77c28 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 8b1eeda9..fb878c3a 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 74911940..bc6edfbc 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index e5e9cdb5..2a3ef8c4 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index ab510388..4513b3db 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index 0f8706fe..e6fa9751 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index 3c3cb8a1..ccb0f1af 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 21202a71..c77cadc8 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 6800d9ed..d6331941 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 84f8cdfb..54d9f90a 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -48,6 +48,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 6ba658ac..6a175b1c 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 21c3f47d..0da9f03c 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 360d9ab7..204074cf 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 2aa1607e..40eec029 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 4f5dd643..09e417c6 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 4c5d5c11..87e9bf33 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 50cf173a..19e7869d 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -46,6 +46,7 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index e9bf9173..a7a38c91 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index d63fe7fc..83e8d30a 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -47,6 +47,7 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +timedatectl set-timezone $tz for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break From 0e10ca682325bf6a0ddb6c7ce8ffba34e61c811c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Mar 2023 12:17:34 -0500 Subject: [PATCH 4418/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ea375c30..adc51ea3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Alpine-Vaultwarden LXC** - NEW Script +- **All LXC Scripts** + - Retrieve the time zone from Proxmox and configure the container to use the same time zone ## 2023-02-24 From ad1d6303022f4b2ce3199cd74be17398d221ac34 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 Mar 2023 15:14:31 -0500 Subject: [PATCH 4419/6505] fix tz unbound varible --- ct/casaos-v5.sh | 1 + ct/docker-v5.sh | 1 + ct/homeassistant-v5.sh | 1 + ct/umbrel-v5.sh | 1 + 4 files changed, 4 insertions(+) diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index dfe1fe4d..1e59b4ae 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -368,6 +368,7 @@ FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export tz=$timezone export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index f8bada16..a5183550 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -362,6 +362,7 @@ FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export tz=$timezone export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index bc1614ca..5537dc7e 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -433,6 +433,7 @@ FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export tz=$timezone export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index d7640ab9..c45af0b5 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -367,6 +367,7 @@ FEATURES="keyctl=1,nesting=1" fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export tz=$timezone export ST=$FUSE export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP From 1f9b959a471b0f47fe5f2ce40726b9e455900883 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 05:28:15 -0500 Subject: [PATCH 4420/6505] modified the code for setting the time zone --- ct/adguard-v5.sh | 2 +- ct/alpine-v5.sh | 2 +- ct/alpine-vaultwarden-v5.sh | 2 +- ct/archlinux-v5.sh | 2 +- ct/audiobookshelf-v5.sh | 2 +- ct/autobrr-v5.sh | 2 +- ct/blocky-v5.sh | 2 +- ct/casaos-v5.sh | 2 +- ct/changedetection-v5.sh | 2 +- ct/cronicle-v5.sh | 2 +- ct/daemonsync-v5.sh | 2 +- ct/dashy-v5.sh | 2 +- ct/debian-v5.sh | 2 +- ct/deconz-v5.sh | 2 +- ct/deluge-v5.sh | 2 +- ct/devuan-v5.sh | 2 +- ct/docker-v5.sh | 2 +- ct/emby-v5.sh | 2 +- ct/emqx-v5.sh | 2 +- ct/esphome-v5.sh | 2 +- ct/go2rtc-v5.sh | 2 +- ct/grafana-v5.sh | 2 +- ct/grocy-v5.sh | 2 +- ct/heimdalldashboard-v5.sh | 2 +- ct/homeassistant-core-v5.sh | 2 +- ct/homeassistant-v5.sh | 2 +- ct/homebridge-v5.sh | 2 +- ct/homepage-v5.sh | 2 +- ct/homer-v5.sh | 2 +- ct/hyperion-v5.sh | 2 +- ct/influxdb-v5.sh | 2 +- ct/iobroker-v5.sh | 2 +- ct/jackett-v5.sh | 2 +- ct/jellyfin-v5.sh | 2 +- ct/k0s-v5.sh | 2 +- ct/kavita-v5.sh | 2 +- ct/keycloak-v5.sh | 2 +- ct/lidarr-v5.sh | 2 +- ct/magicmirror-v5.sh | 2 +- ct/mariadb-v5.sh | 2 +- ct/meshcentral-v5.sh | 2 +- ct/motioneye-v5.sh | 2 +- ct/mqtt-v5.sh | 2 +- ct/n8n-v5.sh | 2 +- ct/navidrome-v5.sh | 2 +- ct/nextcloudpi-v5.sh | 2 +- ct/nginxproxymanager-v5.sh | 2 +- ct/nocodb-v5.sh | 2 +- ct/node-red-v5.sh | 2 +- ct/omada-v5.sh | 2 +- ct/omv-v5.sh | 2 +- ct/openhab-v5.sh | 2 +- ct/paperless-ngx-v5.sh | 2 +- ct/photoprism-v5.sh | 2 +- ct/pihole-v5.sh | 2 +- ct/plex-v5.sh | 2 +- ct/podman-homeassistant-v5.sh | 2 +- ct/podman-v5.sh | 2 +- ct/postgresql-v5.sh | 2 +- ct/prometheus-v5.sh | 2 +- ct/prowlarr-v5.sh | 2 +- ct/qbittorrent-v5.sh | 2 +- ct/radarr-v5.sh | 2 +- ct/readarr-v5.sh | 2 +- ct/rockylinux-v5.sh | 2 +- ct/rstptoweb-v5.sh | 2 +- ct/sabnzbd-v5.sh | 2 +- ct/scrypted-v5.sh | 2 +- ct/shinobi-v5.sh | 2 +- ct/sonarr-v5.sh | 2 +- ct/syncthing-v5.sh | 2 +- ct/tdarr-v5.sh | 2 +- ct/technitiumdns-v5.sh | 2 +- ct/transmission-v5.sh | 2 +- ct/trilium-v5.sh | 2 +- ct/ubuntu-v5.sh | 2 +- ct/umbrel-v5.sh | 2 +- ct/unifi-v5.sh | 2 +- ct/uptimekuma-v5.sh | 2 +- ct/vaultwarden-v5.sh | 2 +- ct/whisparr-v5.sh | 2 +- ct/whoogle-v5.sh | 2 +- ct/wikijs-v5.sh | 2 +- ct/wireguard-v5.sh | 2 +- ct/yunohost-v5.sh | 2 +- ct/zigbee2mqtt-v5.sh | 2 +- ct/zwave-js-ui-v5.sh | 2 +- install/adguard-v5-install.sh | 3 ++- install/audiobookshelf-v5-install.sh | 3 ++- install/autobrr-v5-install.sh | 3 ++- install/blocky-v5-install.sh | 3 ++- install/casaos-v5-install.sh | 3 ++- install/changedetection-v5-install.sh | 3 ++- install/cronicle-v5-install.sh | 3 ++- install/daemonsync-v5-install.sh | 3 ++- install/dashy-v5-install.sh | 3 ++- install/debian-v5-install.sh | 3 ++- install/deconz-v5-install.sh | 3 ++- install/deluge-v5-install.sh | 3 ++- install/docker-v5-install.sh | 3 ++- install/emby-v5-install.sh | 3 ++- install/emqx-v5-install.sh | 3 ++- install/esphome-v5-install.sh | 3 ++- install/go2rtc-v5-install.sh | 3 ++- install/grafana-v5-install.sh | 3 ++- install/grocy-v5-install.sh | 3 ++- install/heimdalldashboard-v5-install.sh | 3 ++- install/homeassistant-core-v5-install.sh | 3 ++- install/homeassistant-v5-install.sh | 3 ++- install/homebridge-v5-install.sh | 3 ++- install/homepage-v5-install.sh | 3 ++- install/homer-v5-install.sh | 3 ++- install/hyperion-v5-install.sh | 3 ++- install/influxdb-v5-install.sh | 3 ++- install/iobroker-v5-install.sh | 3 ++- install/jackett-v5-install.sh | 3 ++- install/jellyfin-v5-install.sh | 3 ++- install/k0s-v5-install.sh | 3 ++- install/kavita-v5-install.sh | 3 ++- install/keycloak-v5-install.sh | 3 ++- install/lidarr-v5-install.sh | 3 ++- install/magicmirror-v5-install.sh | 3 ++- install/mariadb-v5-install.sh | 3 ++- install/meshcentral-v5-install.sh | 3 ++- install/motioneye-v5-install.sh | 3 ++- install/mqtt-v5-install.sh | 3 ++- install/n8n-v5-install.sh | 3 ++- install/navidrome-v5-install.sh | 3 ++- install/nextcloudpi-v5-install.sh | 3 ++- install/nginxproxymanager-v5-install.sh | 3 ++- install/nocodb-v5-install.sh | 3 ++- install/node-red-v5-install.sh | 3 ++- install/omada-v5-install.sh | 3 ++- install/omv-v5-install.sh | 3 ++- install/openhab-v5-install.sh | 3 ++- install/paperless-ngx-v5-install.sh | 3 ++- install/photoprism-v5-install.sh | 3 ++- install/pihole-v5-install.sh | 3 ++- install/plex-v5-install.sh | 3 ++- install/podman-homeassistant-v5-install.sh | 3 ++- install/podman-v5-install.sh | 3 ++- install/postgresql-v5-install.sh | 3 ++- install/prometheus-v5-install.sh | 3 ++- install/prowlarr-v5-install.sh | 3 ++- install/qbittorrent-v5-install.sh | 3 ++- install/radarr-v5-install.sh | 3 ++- install/readarr-v5-install.sh | 3 ++- install/rstptoweb-v5-install.sh | 3 ++- install/sabnzbd-v5-install.sh | 3 ++- install/scrypted-v5-install.sh | 3 ++- install/shinobi-v5-install.sh | 3 ++- install/sonarr-v5-install.sh | 3 ++- install/syncthing-v5-install.sh | 3 ++- install/tdarr-v5-install.sh | 3 ++- install/technitiumdns-v5-install.sh | 3 ++- install/transmission-v5-install.sh | 3 ++- install/trilium-v5-install.sh | 3 ++- install/ubuntu-v5-install.sh | 3 ++- install/umbrel-v5-install.sh | 3 ++- install/unifi-v5-install.sh | 3 ++- install/uptimekuma-v5-install.sh | 3 ++- install/vaultwarden-v5-install.sh | 3 ++- install/whisparr-v5-install.sh | 3 ++- install/whoogle-v5-install.sh | 3 ++- install/wikijs-v5-install.sh | 3 ++- install/wireguard-v5-install.sh | 3 ++- install/yunohost-v5-install.sh | 3 ++- install/zigbee2mqtt-v5-install.sh | 3 ++- install/zwave-js-ui-v5-install.sh | 3 ++- 169 files changed, 251 insertions(+), 169 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index 32b043ef..b642f680 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 3c42c898..349f840f 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -28,7 +28,7 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index 06df8c11..37f11493 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -27,7 +27,7 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index 99b50c6e..69b82639 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -27,7 +27,7 @@ var_os="archlinux" var_version="base" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index 98128a73..a9790f62 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index bdb2b666..36f1d9b2 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index 573e06b0..cbbb49ff 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 1e59b4ae..ee8ab94a 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 1ba4ed72..7283f909 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index ac90461a..06918b55 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index 196fe544..aa53ad77 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index afd67aae..6a8c85b2 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 278f8bb9..54cc5976 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 38df740b..86fda9a6 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -27,7 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index fd515d61..11d82a66 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index 29ee1464..2b124e54 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -27,7 +27,7 @@ var_os="devuan" var_version="4.0" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index a5183550..e0f39952 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index dd20a0b3..ec6c54f5 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -27,7 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 4828a5b4..22f05ffc 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index e9ca6cf2..e75e9f07 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/go2rtc-v5.sh b/ct/go2rtc-v5.sh index 3efc59bf..11af6313 100644 --- a/ct/go2rtc-v5.sh +++ b/ct/go2rtc-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index f94b18e7..ccddc65d 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 2525cdb2..02944358 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index 656db61a..b09170c6 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 40c2d5d1..81ac9bb9 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index 5537dc7e..da4c31ed 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index cf330c37..e77dbc51 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 8ef34ca2..32bc3745 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index fcf78f88..bca46fb8 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index ada0c0d7..f57f81b0 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 74d8063e..7306046c 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index f022bcb4..77e5a5e8 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/jackett-v5.sh b/ct/jackett-v5.sh index 554548b5..485c97cf 100644 --- a/ct/jackett-v5.sh +++ b/ct/jackett-v5.sh @@ -26,7 +26,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index 5af15bc0..d124f71a 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -28,7 +28,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 9cf74443..510c5aba 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index d1869d7b..d2a0aee0 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 8f0ebe5c..65043f38 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index 0383aded..c5973a74 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 606b6b41..8da28b49 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index 5e1dd9ab..ca18035a 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index 336e5d9f..be017202 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index e000822a..907f9182 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index a43ce1b9..e16e0acd 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -26,7 +26,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index cac60cdc..046c20c7 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 4cb57222..99606d17 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 1e663eaa..4087e191 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 71d7c8e6..e2a6f421 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index af343280..7f5cc1b4 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 7051fbf2..6fae8624 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index 1f7b2c6d..e3b04bc1 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -27,7 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index f98708b7..542c9fa3 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index a21c2b72..23f0c177 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 1f0d2ce0..4ffeb59a 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index 21de9379..d182a728 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 2838c254..486e2d28 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 77f384ed..62243b55 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -27,7 +27,7 @@ var_os="ubuntu" var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index a7beabb3..9553f229 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -31,7 +31,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index 05cd6537..a388ea5f 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index 91bf1f6a..d8072ccf 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index a55e74cc..d0977b6c 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index c23b23a5..e73b7249 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/qbittorrent-v5.sh b/ct/qbittorrent-v5.sh index ef84f26a..5eb36c37 100644 --- a/ct/qbittorrent-v5.sh +++ b/ct/qbittorrent-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index 77559143..cf7cf23f 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 7ab40901..4b32964c 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index ddd6517b..96f1f30e 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -28,7 +28,7 @@ var_os="rockylinux" var_version="9" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/rstptoweb-v5.sh b/ct/rstptoweb-v5.sh index 670fbe2d..e0bebee4 100644 --- a/ct/rstptoweb-v5.sh +++ b/ct/rstptoweb-v5.sh @@ -26,7 +26,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index 3076ab52..a3f9457d 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index aff8cf7b..1021fd8c 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index 9d854a57..f2411855 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -27,7 +27,7 @@ var_os="ubuntu" var_version="22.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index 608ce718..f7f6d4b3 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 4997662a..780653b1 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index eb311112..d15c5de0 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index e05f3be3..6927ee63 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index b1f3aab6..a7aad0ce 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 28b04449..688a2a60 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 7319b8f2..3a07a06b 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -27,7 +27,7 @@ var_os="ubuntu" var_version="22.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index c45af0b5..6adff888 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index b91ad8c2..2b299529 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index 7659983d..ad5cc724 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 135bbe1b..055e893d 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index a31ac005..1f51216c 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 4058cbe1..93fc469b 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 50da63bd..685f8783 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index 4522791f..cc16fabd 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index bf8f1798..52629130 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 460c4980..53543482 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -28,7 +28,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 23e88c38..510cb5fc 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -27,7 +27,7 @@ var_os="debian" var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') +timezone=$(cat /etc/timezone) INTEGER='^[0-9]+$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index ac6bf8fd..ddb9f4bc 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index c24e600c..c13f57e8 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 7446e75e..5b7e9d52 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index 275f5e09..70788fde 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index efda281c..f94c4b34 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index a400759a..32823161 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index daba7eb7..63f13711 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index f92e786c..87b1bf68 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index cec3a16f..0835c349 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 53f5a875..8d8c09e0 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index bdef4d6c..391c2857 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index 42325e53..fcfb590d 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 906534e2..4a50c10d 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 41bedf3d..600df6cd 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 8c791710..0f51f30c 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index d653ee25..62d289b7 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/go2rtc-v5-install.sh b/install/go2rtc-v5-install.sh index 51d6831f..d06fe33c 100644 --- a/install/go2rtc-v5-install.sh +++ b/install/go2rtc-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index f09c81a7..5dc1ed99 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index 92242165..adf67d9a 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index f287b687..7f2fa02e 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index a1190ce0..614c3576 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index 5f8fe843..07c8707a 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index b150c163..9fda9f34 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 0b261e03..8f07e05f 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 23831e78..4b5d77fc 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 580817b7..828a5630 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 4280456a..4ef3826e 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index 6f9cda96..b541522f 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/jackett-v5-install.sh b/install/jackett-v5-install.sh index 9f257f5b..711b3804 100644 --- a/install/jackett-v5-install.sh +++ b/install/jackett-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 8faa5d27..7f3667cb 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index 138d51ce..9929af37 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 76fdf021..2bafec40 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 6858e15b..33c4e567 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index aa990c17..fb5c1159 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index 3dbaf0a6..e46fb200 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index db5eb164..58031075 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index 7861a8fd..85084330 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index f112d854..83cbd1c0 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 3be1d8a0..9e35158f 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index fbafc2db..60481d2a 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index c6a7f04e..a1a136fd 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 8d25928a..5382bf00 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 960bb71f..ce7e2cb4 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index 270436a8..b2a77d13 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index fcc4c371..a8437881 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index ad68dec6..e7e38878 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index d9169e75..55aa1f09 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index 30b9f61d..74372081 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index c48908f2..6e7e3e49 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index b9c0782f..a51074eb 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 5976ac9e..6e25aea0 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -48,7 +48,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index b15b104c..701636a2 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 59918724..02878114 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index 89114aba..b551de69 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 3c98caef..6ac71f6e 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 36ad41fc..35434a3a 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 0877c3e9..7d4a80a4 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/qbittorrent-v5-install.sh b/install/qbittorrent-v5-install.sh index 7569b0fd..95512544 100644 --- a/install/qbittorrent-v5-install.sh +++ b/install/qbittorrent-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 7344a496..6b73dfc4 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index c1fb8f85..d6e2dea2 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/rstptoweb-v5-install.sh b/install/rstptoweb-v5-install.sh index c0d51ac9..dbc1d606 100644 --- a/install/rstptoweb-v5-install.sh +++ b/install/rstptoweb-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index 9434927a..e135afb6 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 42080a83..1054b8d1 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index d0f77c28..ff165a74 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index fb878c3a..955d0cc6 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index bc6edfbc..958a63f6 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 2a3ef8c4..79c00018 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 4513b3db..3650c52a 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index e6fa9751..b3708485 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index ccb0f1af..aba37afa 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index c77cadc8..19a880a3 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index d6331941..236d4a10 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 54d9f90a..55a08456 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -48,7 +48,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index 6a175b1c..b0fdb9b4 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 0da9f03c..3c737500 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 204074cf..0ba49544 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 40eec029..6044e6d1 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 09e417c6..2c5433eb 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 87e9bf33..52a617b4 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index 19e7869d..b1baf047 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -46,7 +46,8 @@ function msg_error() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index a7a38c91..3bcde768 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index 83e8d30a..e97b125d 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -47,7 +47,8 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null -timedatectl set-timezone $tz +echo $tz > /etc/timezone +ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do if [ "$(hostname -I)" != "" ]; then break From 259ba993a22197d1bc406f4ee6c309f6a444fbdf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 14:55:40 -0500 Subject: [PATCH 4421/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 0cd732f6..8404bc56 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -66,15 +66,15 @@ function msg_ok() { clear header_info read -r -p "Disable Enterprise Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Disabling Enterprise Repository" sleep 2 - sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list + sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list msg_ok "Disabled Enterprise Repository" fi read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Adding or Correcting PVE7 Sources" cat </etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib @@ -85,8 +85,9 @@ EOF msg_ok "Added or Corrected PVE7 Sources" fi + read -r -p "Enable No-Subscription Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Enabling No-Subscription Repository" cat <>/etc/apt/sources.list deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription @@ -96,7 +97,7 @@ EOF fi read -r -p "Add (Disabled) Beta/Test Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Adding Beta/Test Repository and set disabled" cat <>/etc/apt/sources.list # deb http://download.proxmox.com/debian/pve bullseye pvetest @@ -106,7 +107,7 @@ EOF fi read -r -p "Disable Subscription Nag? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Disabling Subscription Nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null @@ -114,7 +115,7 @@ if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ] fi read -r -p "Update Proxmox VE 7 now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Updating Proxmox VE 7 (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null @@ -122,7 +123,7 @@ if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ] fi read -r -p "Reboot Proxmox VE 7 now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Rebooting Proxmox VE 7" sleep 2 msg_ok "Completed Post Install Routines" From 12d5a78a303acf5423e8b5770c6bc80e30b34a98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 15:03:22 -0500 Subject: [PATCH 4422/6505] match input if it's "y" or "yes" (case-insensitive) --- install/adguard-v5-install.sh | 2 +- install/alpine-vaultwarden-v5-install.sh | 2 +- install/audiobookshelf-v5-install.sh | 2 +- install/autobrr-v5-install.sh | 2 +- install/blocky-v5-install.sh | 2 +- install/casaos-v5-install.sh | 2 +- install/changedetection-v5-install.sh | 2 +- install/cronicle-v5-install.sh | 2 +- install/daemonsync-v5-install.sh | 2 +- install/dashy-v5-install.sh | 2 +- install/debian-v5-install.sh | 2 +- install/deconz-v5-install.sh | 2 +- install/deluge-v5-install.sh | 2 +- install/devuan-v5-install.sh | 2 +- install/docker-v5-install.sh | 6 +++--- install/emby-v5-install.sh | 2 +- install/emqx-v5-install.sh | 2 +- install/esphome-v5-install.sh | 2 +- install/go2rtc-v5-install.sh | 2 +- install/grafana-v5-install.sh | 2 +- install/grocy-v5-install.sh | 2 +- install/heimdalldashboard-v5-install.sh | 2 +- install/homeassistant-core-v5-install.sh | 2 +- install/homeassistant-v5-install.sh | 2 +- install/homebridge-v5-install.sh | 2 +- install/homepage-v5-install.sh | 2 +- install/homer-v5-install.sh | 2 +- install/hyperion-v5-install.sh | 2 +- install/influxdb-v5-install.sh | 4 ++-- install/iobroker-v5-install.sh | 2 +- install/jackett-v5-install.sh | 2 +- install/jellyfin-v5-install.sh | 2 +- install/k0s-v5-install.sh | 4 ++-- install/kavita-v5-install.sh | 2 +- install/keycloak-v5-install.sh | 2 +- install/lidarr-v5-install.sh | 2 +- install/magicmirror-v5-install.sh | 2 +- install/mariadb-v5-install.sh | 4 ++-- install/meshcentral-v5-install.sh | 2 +- install/motioneye-v5-install.sh | 2 +- install/mqtt-v5-install.sh | 2 +- install/n8n-v5-install.sh | 2 +- install/navidrome-v5-install.sh | 2 +- install/nextcloudpi-v5-install.sh | 2 +- install/nginxproxymanager-v5-install.sh | 2 +- install/nocodb-v5-install.sh | 2 +- install/node-red-v5-install.sh | 2 +- install/omada-v5-install.sh | 2 +- install/omv-v5-install.sh | 2 +- install/openhab-v5-install.sh | 2 +- install/paperless-ngx-v5-install.sh | 2 +- install/photoprism-v5-install.sh | 2 +- install/pihole-v5-install.sh | 2 +- install/plex-v5-install.sh | 2 +- install/podman-homeassistant-v5-install.sh | 2 +- install/podman-v5-install.sh | 2 +- install/postgresql-v5-install.sh | 4 ++-- install/prometheus-v5-install.sh | 2 +- install/prowlarr-v5-install.sh | 2 +- install/qbittorrent-v5-install.sh | 2 +- install/radarr-v5-install.sh | 2 +- install/readarr-v5-install.sh | 2 +- install/rstptoweb-v5-install.sh | 2 +- install/sabnzbd-v5-install.sh | 2 +- install/scrypted-v5-install.sh | 4 ++-- install/shinobi-v5-install.sh | 2 +- install/sonarr-v5-install.sh | 2 +- install/syncthing-v5-install.sh | 2 +- install/tdarr-v5-install.sh | 2 +- install/technitiumdns-v5-install.sh | 2 +- install/transmission-v5-install.sh | 2 +- install/trilium-v5-install.sh | 2 +- install/ubuntu-v5-install.sh | 2 +- install/umbrel-v5-install.sh | 2 +- install/unifi-v5-install.sh | 4 ++-- install/uptimekuma-v5-install.sh | 2 +- install/vaultwarden-v5-install.sh | 2 +- install/whisparr-v5-install.sh | 2 +- install/whoogle-v5-install.sh | 2 +- install/wikijs-v5-install.sh | 2 +- install/wireguard-v5-install.sh | 2 +- install/yunohost-v5-install.sh | 2 +- install/zigbee2mqtt-v5-install.sh | 2 +- install/zwave-js-ui-v5-install.sh | 2 +- misc/bluetooth.sh | 4 ++-- misc/post-pbs-install.sh | 14 +++++++------- misc/pyenv.sh | 6 +++--- 87 files changed, 104 insertions(+), 104 deletions(-) diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh index ddb9f4bc..4f8ae86e 100644 --- a/install/adguard-v5-install.sh +++ b/install/adguard-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 6c1a5d80..187fb8c1 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -74,7 +74,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh index c13f57e8..f32761b2 100644 --- a/install/audiobookshelf-v5-install.sh +++ b/install/audiobookshelf-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh index 5b7e9d52..61a9c8c2 100644 --- a/install/autobrr-v5-install.sh +++ b/install/autobrr-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/blocky-v5-install.sh b/install/blocky-v5-install.sh index 70788fde..aa1722b0 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh index f94c4b34..22f05ba7 100644 --- a/install/casaos-v5-install.sh +++ b/install/casaos-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh index 32823161..433ee0f9 100644 --- a/install/changedetection-v5-install.sh +++ b/install/changedetection-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh index 63f13711..d9addbf6 100644 --- a/install/cronicle-v5-install.sh +++ b/install/cronicle-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh index 87b1bf68..abe4dec6 100644 --- a/install/daemonsync-v5-install.sh +++ b/install/daemonsync-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh index 0835c349..1bd8e71d 100644 --- a/install/dashy-v5-install.sh +++ b/install/dashy-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh index 8d8c09e0..ef9e1a6f 100644 --- a/install/debian-v5-install.sh +++ b/install/debian-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh index 391c2857..ad060379 100644 --- a/install/deconz-v5-install.sh +++ b/install/deconz-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh index fcfb590d..dbc85972 100644 --- a/install/deluge-v5-install.sh +++ b/install/deluge-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/devuan-v5-install.sh b/install/devuan-v5-install.sh index 2ab60b40..a8ca650d 100644 --- a/install/devuan-v5-install.sh +++ b/install/devuan-v5-install.sh @@ -64,7 +64,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 4a50c10d..806f7f8b 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" @@ -117,7 +117,7 @@ $STD sh <(curl -sSL https://get.docker.com) msg_ok "Installed Docker $DOCKER_LATEST_VERSION" read -r -p "Would you like to add Portainer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then PORTAINER="Y" else PORTAINER="N" @@ -138,7 +138,7 @@ if [[ $PORTAINER == "Y" ]]; then fi read -r -p "Would you like to add Docker Compose? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then DOCKER_COMPOSE="Y" else DOCKER_COMPOSE="N" diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh index 600df6cd..0a41c2c5 100644 --- a/install/emby-v5-install.sh +++ b/install/emby-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh index 0f51f30c..853a3cdb 100644 --- a/install/emqx-v5-install.sh +++ b/install/emqx-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh index 62d289b7..7bd8b99f 100644 --- a/install/esphome-v5-install.sh +++ b/install/esphome-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/go2rtc-v5-install.sh b/install/go2rtc-v5-install.sh index d06fe33c..57577695 100644 --- a/install/go2rtc-v5-install.sh +++ b/install/go2rtc-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh index 5dc1ed99..9b327c23 100644 --- a/install/grafana-v5-install.sh +++ b/install/grafana-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh index adf67d9a..f5bf1469 100644 --- a/install/grocy-v5-install.sh +++ b/install/grocy-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh index 7f2fa02e..4fcc9888 100644 --- a/install/heimdalldashboard-v5-install.sh +++ b/install/heimdalldashboard-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh index 614c3576..71f3186d 100644 --- a/install/homeassistant-core-v5-install.sh +++ b/install/homeassistant-core-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh index 07c8707a..12a5efbc 100644 --- a/install/homeassistant-v5-install.sh +++ b/install/homeassistant-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh index 9fda9f34..ac0fec01 100644 --- a/install/homebridge-v5-install.sh +++ b/install/homebridge-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh index 8f07e05f..ca0fe0c4 100644 --- a/install/homepage-v5-install.sh +++ b/install/homepage-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh index 4b5d77fc..539c4aed 100644 --- a/install/homer-v5-install.sh +++ b/install/homer-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh index 828a5630..4e2668f2 100644 --- a/install/hyperion-v5-install.sh +++ b/install/hyperion-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 4ef3826e..5e1a28c9 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" @@ -119,7 +119,7 @@ $STD systemctl enable --now influxdb msg_ok "Installed InfluxDB" read -r -p "Would you like to add Telegraf? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then TELEGRAF="Y" else TELEGRAF="N" diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh index b541522f..7c8152b3 100644 --- a/install/iobroker-v5-install.sh +++ b/install/iobroker-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/jackett-v5-install.sh b/install/jackett-v5-install.sh index 711b3804..7baee1b1 100644 --- a/install/jackett-v5-install.sh +++ b/install/jackett-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh index 7f3667cb..821bfe0e 100644 --- a/install/jellyfin-v5-install.sh +++ b/install/jellyfin-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index 9929af37..b7c7db8d 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" @@ -101,7 +101,7 @@ k0s config create > /etc/k0s/k0s.yaml msg_ok "Installed k0s Kubernetes" read -r -p "Would you like to add Helm Package Manager? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then HELM="Y" else HELM="N" diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh index 2bafec40..fb3d3af2 100644 --- a/install/kavita-v5-install.sh +++ b/install/kavita-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh index 33c4e567..65fc382c 100644 --- a/install/keycloak-v5-install.sh +++ b/install/keycloak-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh index fb5c1159..35354173 100644 --- a/install/lidarr-v5-install.sh +++ b/install/lidarr-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-v5-install.sh index e46fb200..3cfc369d 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 58031075..84ae6eca 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" @@ -99,7 +99,7 @@ $STD apt-get install -y mariadb-server msg_ok "Installed MariaDB" read -r -p "Would you like to add Adminer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then ADMINER="Y" else ADMINER="N" diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh index 85084330..f0b22abb 100644 --- a/install/meshcentral-v5-install.sh +++ b/install/meshcentral-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh index 83cbd1c0..14ea8991 100644 --- a/install/motioneye-v5-install.sh +++ b/install/motioneye-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh index 9e35158f..3f13f8a4 100644 --- a/install/mqtt-v5-install.sh +++ b/install/mqtt-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh index 60481d2a..76a45c05 100644 --- a/install/n8n-v5-install.sh +++ b/install/n8n-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh index a1a136fd..67a38067 100644 --- a/install/navidrome-v5-install.sh +++ b/install/navidrome-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh index 5382bf00..6ccada06 100644 --- a/install/nextcloudpi-v5-install.sh +++ b/install/nextcloudpi-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index ce7e2cb4..830c02fa 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh index b2a77d13..fb618460 100644 --- a/install/nocodb-v5-install.sh +++ b/install/nocodb-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh index a8437881..e20934ef 100644 --- a/install/node-red-v5-install.sh +++ b/install/node-red-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh index e7e38878..6e79e690 100644 --- a/install/omada-v5-install.sh +++ b/install/omada-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh index 55aa1f09..6f0e8a1e 100644 --- a/install/omv-v5-install.sh +++ b/install/omv-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh index 74372081..1899ae34 100644 --- a/install/openhab-v5-install.sh +++ b/install/openhab-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-v5-install.sh index 6e7e3e49..5efaa813 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/photoprism-v5-install.sh b/install/photoprism-v5-install.sh index a51074eb..ac39c48d 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh index 6e25aea0..63df2f5b 100644 --- a/install/pihole-v5-install.sh +++ b/install/pihole-v5-install.sh @@ -70,7 +70,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh index 701636a2..f866c55e 100644 --- a/install/plex-v5-install.sh +++ b/install/plex-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh index 02878114..4b594c70 100644 --- a/install/podman-homeassistant-v5-install.sh +++ b/install/podman-homeassistant-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh index b551de69..3e2aa3e8 100644 --- a/install/podman-v5-install.sh +++ b/install/podman-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 6ac71f6e..ceaee9ea 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" @@ -206,7 +206,7 @@ sudo systemctl restart postgresql msg_ok "Installed PostgreSQL" read -r -p "Would you like to add Adminer? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then ADMINER="Y" else ADMINER="N" diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh index 35434a3a..7d561256 100644 --- a/install/prometheus-v5-install.sh +++ b/install/prometheus-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh index 7d4a80a4..565541ac 100644 --- a/install/prowlarr-v5-install.sh +++ b/install/prowlarr-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/qbittorrent-v5-install.sh b/install/qbittorrent-v5-install.sh index 95512544..8ced8627 100644 --- a/install/qbittorrent-v5-install.sh +++ b/install/qbittorrent-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh index 6b73dfc4..655bf395 100644 --- a/install/radarr-v5-install.sh +++ b/install/radarr-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh index d6e2dea2..f2388649 100644 --- a/install/readarr-v5-install.sh +++ b/install/readarr-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/rstptoweb-v5-install.sh b/install/rstptoweb-v5-install.sh index dbc1d606..f1c28169 100644 --- a/install/rstptoweb-v5-install.sh +++ b/install/rstptoweb-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh index e135afb6..9d9cb825 100644 --- a/install/sabnzbd-v5-install.sh +++ b/install/sabnzbd-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 1054b8d1..0ee2a517 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" @@ -148,7 +148,7 @@ $STD python3 -m pip install aiofiles debugpy typing_extensions typing msg_ok "Installed Python3" read -r -p "Would you like to add Coral Edge TPU support? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then CORAL="Y" else CORAL="N" diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh index ff165a74..755148af 100644 --- a/install/shinobi-v5-install.sh +++ b/install/shinobi-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh index 955d0cc6..9ca338dc 100644 --- a/install/sonarr-v5-install.sh +++ b/install/sonarr-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh index 958a63f6..315a88da 100644 --- a/install/syncthing-v5-install.sh +++ b/install/syncthing-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh index 79c00018..705a53ce 100644 --- a/install/tdarr-v5-install.sh +++ b/install/tdarr-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh index 3650c52a..8570aebc 100644 --- a/install/technitiumdns-v5-install.sh +++ b/install/technitiumdns-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh index b3708485..c2e22764 100644 --- a/install/transmission-v5-install.sh +++ b/install/transmission-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh index aba37afa..05a61efa 100644 --- a/install/trilium-v5-install.sh +++ b/install/trilium-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh index 19a880a3..9f1409ff 100644 --- a/install/ubuntu-v5-install.sh +++ b/install/ubuntu-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh index 236d4a10..8846aa68 100644 --- a/install/umbrel-v5-install.sh +++ b/install/umbrel-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh index 55a08456..1eaa6cf3 100644 --- a/install/unifi-v5-install.sh +++ b/install/unifi-v5-install.sh @@ -70,7 +70,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" @@ -94,7 +94,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" read -r -p "Local Controller? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then LOCAL="--local-controller" else LOCAL="" diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh index b0fdb9b4..d9c8284b 100644 --- a/install/uptimekuma-v5-install.sh +++ b/install/uptimekuma-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-v5-install.sh index 3c737500..c1d63e1f 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh index 0ba49544..82d4dce7 100644 --- a/install/whisparr-v5-install.sh +++ b/install/whisparr-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh index 6044e6d1..816a32df 100644 --- a/install/whoogle-v5-install.sh +++ b/install/whoogle-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh index 2c5433eb..71a6e946 100644 --- a/install/wikijs-v5-install.sh +++ b/install/wikijs-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh index 52a617b4..4d1b3127 100644 --- a/install/wireguard-v5-install.sh +++ b/install/wireguard-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh index b1baf047..b8366bf0 100644 --- a/install/yunohost-v5-install.sh +++ b/install/yunohost-v5-install.sh @@ -68,7 +68,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh index 3bcde768..ae1ec650 100644 --- a/install/zigbee2mqtt-v5-install.sh +++ b/install/zigbee2mqtt-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh index e97b125d..41cfb081 100644 --- a/install/zwave-js-ui-v5-install.sh +++ b/install/zwave-js-ui-v5-install.sh @@ -69,7 +69,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" diff --git a/misc/bluetooth.sh b/misc/bluetooth.sh index c95a1815..d3a3ca60 100644 --- a/misc/bluetooth.sh +++ b/misc/bluetooth.sh @@ -41,7 +41,7 @@ clear EOF read -r -p "Switch from dbus-daemon to dbus-broker? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then cat <>/etc/apt/sources.list deb http://deb.debian.org/debian bullseye-backports main contrib non-free @@ -52,7 +52,7 @@ apt-get -t bullseye-backports install -y dbus-broker &>/dev/null systemctl enable dbus-broker.service &>/dev/null fi read -r -p "Install BlueZ? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then apt-get -t bullseye-backports install -y bluez* &>/dev/null fi echo -e "Finished, reboot for changes to take affect" diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index 2a6ff6f0..39a0a320 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -58,7 +58,7 @@ function msg_ok() { clear header_info read -r -p "Disable Enterprise Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Disabling Enterprise Repository" sleep 2 sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pbs-enterprise.list @@ -66,7 +66,7 @@ if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ] fi read -r -p "Add/Correct PBS Sources (sources.list)? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Adding or Correcting PBS Sources" cat </etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib @@ -78,7 +78,7 @@ EOF fi read -r -p "Enable No-Subscription Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Enabling No-Subscription Repository" cat <>/etc/apt/sources.list deb http://download.proxmox.com/debian/pbs bullseye pbs-no-subscription @@ -88,7 +88,7 @@ EOF fi read -r -p "Add (Disabled) Beta/Test Repository? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Adding Beta/Test Repository and set disabled" cat <>/etc/apt/sources.list # deb http://download.proxmox.com/debian/pbs bullseye pbstest @@ -98,7 +98,7 @@ EOF fi read -r -p "Disable Subscription Nag? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Disabling Subscription Nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null @@ -106,7 +106,7 @@ if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ] fi read -r -p "Update Proxmox Backup Server now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Updating Proxmox Backup Server (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null @@ -114,7 +114,7 @@ if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ] fi read -r -p "Reboot Proxmox Backup Server now? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Rebooting Proxmox Backup Server" sleep 2 msg_ok "Completed Post Install Routines" diff --git a/misc/pyenv.sh b/misc/pyenv.sh index 5fb41779..ca43a5fd 100644 --- a/misc/pyenv.sh +++ b/misc/pyenv.sh @@ -69,7 +69,7 @@ pyenv install 3.10.8 &>/dev/null pyenv global 3.10.8 msg_ok "Installed Python 3.10.8" read -r -p "Would you like to install Home Assistant Beta? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then HA="Y" fi if [[ $HA == "Y" ]]; then @@ -101,7 +101,7 @@ hass fi read -r -p "Would you like to install ESPHome Beta? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then ESP="Y" fi if [[ $ESP == "Y" ]]; then @@ -146,7 +146,7 @@ exec $SHELL fi read -r -p "Would you like to install Matter-Server (Beta)? " prompt -if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then MTR="Y" fi if [[ $MTR == "Y" ]]; then From 6d2a8a2ec4f714f32335c3da56418695226386cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 15:23:14 -0500 Subject: [PATCH 4423/6505] Update docker-v5-install.sh code refactoring --- install/docker-v5-install.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh index 806f7f8b..83339fb5 100644 --- a/install/docker-v5-install.sh +++ b/install/docker-v5-install.sh @@ -118,12 +118,6 @@ msg_ok "Installed Docker $DOCKER_LATEST_VERSION" read -r -p "Would you like to add Portainer? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - PORTAINER="Y" -else - PORTAINER="N" -fi - -if [[ $PORTAINER == "Y" ]]; then msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null $STD docker run -d \ @@ -139,12 +133,6 @@ fi read -r -p "Would you like to add Docker Compose? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - DOCKER_COMPOSE="Y" -else - DOCKER_COMPOSE="N" -fi - -if [[ $DOCKER_COMPOSE == "Y" ]]; then msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins From 7305fa4f0ace2d1ba487d29c587ae48ec15112ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 15:37:32 -0500 Subject: [PATCH 4424/6505] code refactoring --- install/influxdb-v5-install.sh | 6 ------ install/k0s-v5-install.sh | 6 ------ install/mariadb-v5-install.sh | 6 ------ install/postgresql-v5-install.sh | 6 ------ install/scrypted-v5-install.sh | 6 ------ misc/pyenv.sh | 17 ++++------------- 6 files changed, 4 insertions(+), 43 deletions(-) diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh index 5e1a28c9..31fe8ece 100644 --- a/install/influxdb-v5-install.sh +++ b/install/influxdb-v5-install.sh @@ -120,12 +120,6 @@ msg_ok "Installed InfluxDB" read -r -p "Would you like to add Telegraf? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - TELEGRAF="Y" -else - TELEGRAF="N" -fi - -if [[ $TELEGRAF == "Y" ]]; then msg_info "Installing Telegraf" $STD apt-get install -y telegraf msg_ok "Installed Telegraf" diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh index b7c7db8d..c5bb38f5 100644 --- a/install/k0s-v5-install.sh +++ b/install/k0s-v5-install.sh @@ -102,12 +102,6 @@ msg_ok "Installed k0s Kubernetes" read -r -p "Would you like to add Helm Package Manager? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - HELM="Y" -else - HELM="N" -fi - -if [[ $HELM == "Y" ]]; then msg_info "Installing Helm" $STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) msg_ok "Installed Helm" diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh index 84ae6eca..63b2899e 100644 --- a/install/mariadb-v5-install.sh +++ b/install/mariadb-v5-install.sh @@ -100,12 +100,6 @@ msg_ok "Installed MariaDB" read -r -p "Would you like to add Adminer? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - ADMINER="Y" -else - ADMINER="N" -fi - -if [[ $ADMINER == "Y" ]]; then msg_info "Installing Adminer" $STD apt install -y adminer $STD a2enconf adminer diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index ceaee9ea..6c589a4f 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -207,12 +207,6 @@ msg_ok "Installed PostgreSQL" read -r -p "Would you like to add Adminer? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - ADMINER="Y" -else - ADMINER="N" -fi - -if [[ $ADMINER == "Y" ]]; then msg_info "Installing Adminer" $STD apt install -y adminer $STD sudo a2enconf adminer diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh index 0ee2a517..60b1e6e9 100644 --- a/install/scrypted-v5-install.sh +++ b/install/scrypted-v5-install.sh @@ -149,12 +149,6 @@ msg_ok "Installed Python3" read -r -p "Would you like to add Coral Edge TPU support? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - CORAL="Y" -else - CORAL="N" -fi - -if [[ $CORAL == "Y" ]]; then msg_info "Adding Coral Edge TPU Support" $STD apt-key add <(curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg) sh -c 'echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list' diff --git a/misc/pyenv.sh b/misc/pyenv.sh index ca43a5fd..675a0344 100644 --- a/misc/pyenv.sh +++ b/misc/pyenv.sh @@ -64,15 +64,12 @@ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path) msg_ok "Installed pyenv" . ~/.bashrc set -e -msg_info "Installing Python 3.10.8" -pyenv install 3.10.8 &>/dev/null -pyenv global 3.10.8 -msg_ok "Installed Python 3.10.8" +msg_info "Installing Python 3.11.1" +pyenv install 3.11.1 &>/dev/null +pyenv global 3.11.1 +msg_ok "Installed Python 3.11.1" read -r -p "Would you like to install Home Assistant Beta? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - HA="Y" -fi -if [[ $HA == "Y" ]]; then msg_info "Installing Home Assistant Beta" cat </etc/systemd/system/homeassistant.service [Unit] @@ -102,9 +99,6 @@ fi read -r -p "Would you like to install ESPHome Beta? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - ESP="Y" -fi -if [[ $ESP == "Y" ]]; then msg_info "Installing ESPHome Beta" mkdir /srv/esphome cd /srv/esphome @@ -147,9 +141,6 @@ fi read -r -p "Would you like to install Matter-Server (Beta)? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - MTR="Y" -fi -if [[ $MTR == "Y" ]]; then msg_info "Installing Matter Server" apt-get install -y \ libcairo2-dev \ From 6b10aa922afa27301eae8aaf7c45e20dc99bca02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 19:08:45 -0500 Subject: [PATCH 4425/6505] Update usb-passthrough.sh clean --- misc/usb-passthrough.sh | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index 8274d96b..851b3e06 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -15,31 +15,6 @@ while true; do esac done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null CHAR_DEVS+=("166:.*") From a153da3465b071626ddc6b18db341612ec30a470 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 20:19:37 -0500 Subject: [PATCH 4426/6505] Update scaling-governor.sh menu options dynamically based on the available scaling governors --- misc/scaling-governor.sh | 111 ++++++++++----------------------------- 1 file changed, 27 insertions(+), 84 deletions(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index edecd2c4..20138b08 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -5,21 +5,19 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -function header_info { - cat <<"EOF" +header_info() { +clear +cat < Date: Wed, 8 Mar 2023 20:29:42 -0500 Subject: [PATCH 4427/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index adc51ea3..2b5c2a03 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,14 @@ # Change Log All notable changes to this project will be documented in this file. + +## 2023-03-08 + +### Changed + +- **Proxmox CPU Scaling Governor** + - Menu options dynamically based on the available scaling governors. + ## 2023-03-07 ### Changed From 7a22dbfa98274c06bef6afc132b0e0f5897130a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Mar 2023 20:56:23 -0500 Subject: [PATCH 4428/6505] Update scaling-governor.sh tweak --- misc/scaling-governor.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 20138b08..1ca70809 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -17,7 +17,6 @@ Scaling Governors EOF } while true; do - header_info read -p "View CPU Scaling Governors. Proceed(y/n)?" yn case $yn in [Yy]*) break ;; From de020b93afd4d73e44bcb22b2dfb83746dec904d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Mar 2023 03:40:38 -0500 Subject: [PATCH 4429/6505] Update scaling-governor.sh revert 7a22dbf --- misc/scaling-governor.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 1ca70809..20138b08 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -17,6 +17,7 @@ Scaling Governors EOF } while true; do + header_info read -p "View CPU Scaling Governors. Proceed(y/n)?" yn case $yn in [Yy]*) break ;; From e396345058e8f6d58475ac483d47d154d2f9fa76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Mar 2023 22:06:56 -0500 Subject: [PATCH 4430/6505] code refactoring (#1141) * code refactoring * allow decimal numbers (such as 0.1) in addition to integers * adjust password menu --- ct/adguard-v5.sh | 329 +++++++++++++++++-------------- ct/alpine-v5.sh | 328 +++++++++++++++++-------------- ct/alpine-vaultwarden-v5.sh | 328 +++++++++++++++++-------------- ct/archlinux-v5.sh | 330 +++++++++++++++++-------------- ct/audiobookshelf-v5.sh | 330 +++++++++++++++++-------------- ct/autobrr-v5.sh | 330 +++++++++++++++++-------------- ct/blocky-v5.sh | 330 +++++++++++++++++-------------- ct/casaos-v5.sh | 359 ++++++++++++++++++---------------- ct/changedetection-v5.sh | 330 +++++++++++++++++-------------- ct/cronicle-v5.sh | 330 +++++++++++++++++-------------- ct/daemonsync-v5.sh | 330 +++++++++++++++++-------------- ct/dashy-v5.sh | 330 +++++++++++++++++-------------- ct/debian-v5.sh | 330 +++++++++++++++++-------------- ct/deconz-v5.sh | 334 +++++++++++++++++-------------- ct/deluge-v5.sh | 330 +++++++++++++++++-------------- ct/devuan-v5.sh | 330 +++++++++++++++++-------------- ct/docker-v5.sh | 345 +++++++++++++++++--------------- ct/emby-v5.sh | 341 +++++++++++++++++--------------- ct/emqx-v5.sh | 330 +++++++++++++++++-------------- ct/esphome-v5.sh | 331 +++++++++++++++++-------------- ct/go2rtc-v5.sh | 330 +++++++++++++++++-------------- ct/grafana-v5.sh | 330 +++++++++++++++++-------------- ct/grocy-v5.sh | 330 +++++++++++++++++-------------- ct/heimdalldashboard-v5.sh | 330 +++++++++++++++++-------------- ct/homeassistant-core-v5.sh | 328 +++++++++++++++++-------------- ct/homeassistant-v5.sh | 344 +++++++++++++++++--------------- ct/homebridge-v5.sh | 330 +++++++++++++++++-------------- ct/homepage-v5.sh | 330 +++++++++++++++++-------------- ct/homer-v5.sh | 330 +++++++++++++++++-------------- ct/hyperion-v5.sh | 334 +++++++++++++++++-------------- ct/influxdb-v5.sh | 330 +++++++++++++++++-------------- ct/iobroker-v5.sh | 330 +++++++++++++++++-------------- ct/jackett-v5.sh | 330 +++++++++++++++++-------------- ct/jellyfin-v5.sh | 342 +++++++++++++++++--------------- ct/k0s-v5.sh | 330 +++++++++++++++++-------------- ct/kavita-v5.sh | 330 +++++++++++++++++-------------- ct/keycloak-v5.sh | 330 +++++++++++++++++-------------- ct/lidarr-v5.sh | 330 +++++++++++++++++-------------- ct/magicmirror-v5.sh | 330 +++++++++++++++++-------------- ct/mariadb-v5.sh | 330 +++++++++++++++++-------------- ct/meshcentral-v5.sh | 330 +++++++++++++++++-------------- ct/motioneye-v5.sh | 330 +++++++++++++++++-------------- ct/mqtt-v5.sh | 329 +++++++++++++++++-------------- ct/n8n-v5.sh | 330 +++++++++++++++++-------------- ct/navidrome-v5.sh | 330 +++++++++++++++++-------------- ct/nextcloudpi-v5.sh | 334 +++++++++++++++++-------------- ct/nginxproxymanager-v5.sh | 330 +++++++++++++++++-------------- ct/nocodb-v5.sh | 330 +++++++++++++++++-------------- ct/node-red-v5.sh | 331 +++++++++++++++++-------------- ct/omada-v5.sh | 341 +++++++++++++++++--------------- ct/omv-v5.sh | 334 +++++++++++++++++-------------- ct/openhab-v5.sh | 330 +++++++++++++++++-------------- ct/paperless-ngx-v5.sh | 331 +++++++++++++++++-------------- ct/photoprism-v5.sh | 330 +++++++++++++++++-------------- ct/pihole-v5.sh | 330 +++++++++++++++++-------------- ct/plex-v5.sh | 342 +++++++++++++++++--------------- ct/podman-homeassistant-v5.sh | 330 +++++++++++++++++-------------- ct/podman-v5.sh | 330 +++++++++++++++++-------------- ct/postgresql-v5.sh | 330 +++++++++++++++++-------------- ct/prometheus-v5.sh | 330 +++++++++++++++++-------------- ct/prowlarr-v5.sh | 330 +++++++++++++++++-------------- ct/qbittorrent-v5.sh | 330 +++++++++++++++++-------------- ct/radarr-v5.sh | 330 +++++++++++++++++-------------- ct/readarr-v5.sh | 330 +++++++++++++++++-------------- ct/rockylinux-v5.sh | 10 +- ct/rstptoweb-v5.sh | 330 +++++++++++++++++-------------- ct/sabnzbd-v5.sh | 330 +++++++++++++++++-------------- ct/scrypted-v5.sh | 330 +++++++++++++++++-------------- ct/shinobi-v5.sh | 342 +++++++++++++++++--------------- ct/sonarr-v5.sh | 330 +++++++++++++++++-------------- ct/syncthing-v5.sh | 330 +++++++++++++++++-------------- ct/tdarr-v5.sh | 330 +++++++++++++++++-------------- ct/technitiumdns-v5.sh | 330 +++++++++++++++++-------------- ct/transmission-v5.sh | 330 +++++++++++++++++-------------- ct/trilium-v5.sh | 330 +++++++++++++++++-------------- ct/ubuntu-v5.sh | 342 +++++++++++++++++--------------- ct/umbrel-v5.sh | 345 +++++++++++++++++--------------- ct/unifi-v5.sh | 330 +++++++++++++++++-------------- ct/uptimekuma-v5.sh | 330 +++++++++++++++++-------------- ct/vaultwarden-v5.sh | 329 +++++++++++++++++-------------- ct/whisparr-v5.sh | 330 +++++++++++++++++-------------- ct/whoogle-v5.sh | 330 +++++++++++++++++-------------- ct/wikijs-v5.sh | 330 +++++++++++++++++-------------- ct/wireguard-v5.sh | 330 +++++++++++++++++-------------- ct/yunohost-v5.sh | 330 +++++++++++++++++-------------- ct/zigbee2mqtt-v5.sh | 331 +++++++++++++++++-------------- ct/zwave-js-ui-v5.sh | 331 +++++++++++++++++-------------- 87 files changed, 15659 insertions(+), 12886 deletions(-) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh index b642f680..73a5eb9c 100644 --- a/ct/adguard-v5.sh +++ b/ct/adguard-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,186 +123,217 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } function install_script() { diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh index 349f840f..6357beb8 100644 --- a/ct/alpine-v5.sh +++ b/ct/alpine-v5.sh @@ -29,7 +29,7 @@ var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,183 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="alpine" PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index 37f11493..644f43da 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -28,7 +28,7 @@ var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,183 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="alpine" PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/archlinux-v5.sh b/ct/archlinux-v5.sh index 69b82639..26385a0a 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux-v5.sh @@ -28,7 +28,7 @@ var_version="base" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="archlinux" PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh index a9790f62..ca4e5c9b 100644 --- a/ct/audiobookshelf-v5.sh +++ b/ct/audiobookshelf-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh index 36f1d9b2..b0ad08cc 100644 --- a/ct/autobrr-v5.sh +++ b/ct/autobrr-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh index cbbb49ff..64b905d2 100644 --- a/ct/blocky-v5.sh +++ b/ct/blocky-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index ee8ab94a..074c4065 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -124,209 +124,226 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + FUSE="yes" +else + FUSE="no" +fi + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi -} -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi +fi } + function update_script() { header_info msg_info "Updating ${APP} LXC" diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh index 7283f909..64899ce7 100644 --- a/ct/changedetection-v5.sh +++ b/ct/changedetection-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index 06918b55..c3c5069e 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh index aa53ad77..bb50f147 100644 --- a/ct/daemonsync-v5.sh +++ b/ct/daemonsync-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh index 6a8c85b2..0b63ea64 100644 --- a/ct/dashy-v5.sh +++ b/ct/dashy-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh index 54cc5976..b0c885f4 100644 --- a/ct/debian-v5.sh +++ b/ct/debian-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh index 86fda9a6..cdeb7a75 100644 --- a/ct/deconz-v5.sh +++ b/ct/deconz-v5.sh @@ -28,7 +28,7 @@ var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh index 11d82a66..7d95aa64 100644 --- a/ct/deluge-v5.sh +++ b/ct/deluge-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh index 2b124e54..ac845530 100644 --- a/ct/devuan-v5.sh +++ b/ct/devuan-v5.sh @@ -28,7 +28,7 @@ var_version="4.0" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password" 8 58 $NSAPP --title "ROOT PASSWORD" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="$NSAPP" PW="-password $NSAPP" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh index e0f39952..677398a0 100644 --- a/ct/docker-v5.sh +++ b/ct/docker-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -124,194 +124,226 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + FUSE="yes" +else + FUSE="no" +fi + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -327,6 +359,7 @@ header_info advanced_settings fi } + function update_script() { header_info msg_info "Updating ${APP} LXC" diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh index ec6c54f5..d138f812 100644 --- a/ct/emby-v5.sh +++ b/ct/emby-v5.sh @@ -28,7 +28,7 @@ var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,195 +123,229 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ +if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit-script +fi +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -327,6 +361,7 @@ header_info advanced_settings fi } + function update_script() { header_info LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh index 22f05ffc..45bbd9fa 100644 --- a/ct/emqx-v5.sh +++ b/ct/emqx-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh index e75e9f07..5cb1c4f2 100644 --- a/ct/esphome-v5.sh +++ b/ct/esphome-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -318,6 +350,7 @@ header_info advanced_settings fi } + function update_script() { header_info msg_info "Stopping ESPHome" diff --git a/ct/go2rtc-v5.sh b/ct/go2rtc-v5.sh index 11af6313..cf95a685 100644 --- a/ct/go2rtc-v5.sh +++ b/ct/go2rtc-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh index ccddc65d..2984483f 100644 --- a/ct/grafana-v5.sh +++ b/ct/grafana-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh index 02944358..ca85cf3f 100644 --- a/ct/grocy-v5.sh +++ b/ct/grocy-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh index b09170c6..8853bb2b 100644 --- a/ct/heimdalldashboard-v5.sh +++ b/ct/heimdalldashboard-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 81ac9bb9..988b31df 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -125,186 +125,216 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } function install_script() { diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh index da4c31ed..391f8080 100644 --- a/ct/homeassistant-v5.sh +++ b/ct/homeassistant-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -125,194 +125,225 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + FUSE="yes" +else + FUSE="no" +fi + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -328,6 +359,7 @@ header_info advanced_settings fi } + function update_script() { UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update ALL Containers" ON \ diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh index e77dbc51..955813c7 100644 --- a/ct/homebridge-v5.sh +++ b/ct/homebridge-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh index 32bc3745..cc799cb4 100644 --- a/ct/homepage-v5.sh +++ b/ct/homepage-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh index bca46fb8..c99f3a70 100644 --- a/ct/homer-v5.sh +++ b/ct/homer-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh index f57f81b0..13e1168c 100644 --- a/ct/hyperion-v5.sh +++ b/ct/hyperion-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh index 7306046c..3f1e42ed 100644 --- a/ct/influxdb-v5.sh +++ b/ct/influxdb-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh index 77e5a5e8..7e74a9f4 100644 --- a/ct/iobroker-v5.sh +++ b/ct/iobroker-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/jackett-v5.sh b/ct/jackett-v5.sh index 485c97cf..72a6a925 100644 --- a/ct/jackett-v5.sh +++ b/ct/jackett-v5.sh @@ -27,7 +27,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -121,187 +121,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh index d124f71a..b043cf38 100644 --- a/ct/jellyfin-v5.sh +++ b/ct/jellyfin-v5.sh @@ -29,7 +29,7 @@ var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -86,7 +86,6 @@ fi function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -125,195 +124,229 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ +if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit-script +fi +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -329,6 +362,7 @@ header_info advanced_settings fi } + function update_script() { header_info msg_info "Updating ${APP} LXC" diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh index 510c5aba..cdf959f6 100644 --- a/ct/k0s-v5.sh +++ b/ct/k0s-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh index d2a0aee0..32c7b540 100644 --- a/ct/kavita-v5.sh +++ b/ct/kavita-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh index 65043f38..7c2d8149 100644 --- a/ct/keycloak-v5.sh +++ b/ct/keycloak-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh index c5973a74..2fa8eab1 100644 --- a/ct/lidarr-v5.sh +++ b/ct/lidarr-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh index 8da28b49..87f20b9a 100644 --- a/ct/magicmirror-v5.sh +++ b/ct/magicmirror-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh index ca18035a..2bee684d 100644 --- a/ct/mariadb-v5.sh +++ b/ct/mariadb-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh index be017202..0899b146 100644 --- a/ct/meshcentral-v5.sh +++ b/ct/meshcentral-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh index 907f9182..245f2439 100644 --- a/ct/motioneye-v5.sh +++ b/ct/motioneye-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh index e16e0acd..46cfed5f 100644 --- a/ct/mqtt-v5.sh +++ b/ct/mqtt-v5.sh @@ -27,7 +27,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -121,186 +121,217 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } function install_script() { diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh index 046c20c7..13184630 100644 --- a/ct/n8n-v5.sh +++ b/ct/n8n-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh index 99606d17..c5d4eeb2 100644 --- a/ct/navidrome-v5.sh +++ b/ct/navidrome-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh index 4087e191..79ad1cff 100644 --- a/ct/nextcloudpi-v5.sh +++ b/ct/nextcloudpi-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index e2a6f421..1d22c093 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh index 7f5cc1b4..50b929cb 100644 --- a/ct/nocodb-v5.sh +++ b/ct/nocodb-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh index 6fae8624..e0a5fbf4 100644 --- a/ct/node-red-v5.sh +++ b/ct/node-red-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -318,6 +350,7 @@ header_info advanced_settings fi } + function update_script() { UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh index e3b04bc1..c9b9defc 100644 --- a/ct/omada-v5.sh +++ b/ct/omada-v5.sh @@ -28,7 +28,7 @@ var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,195 +123,230 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ +if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit-script +fi + +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh index 542c9fa3..692f323b 100644 --- a/ct/omv-v5.sh +++ b/ct/omv-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh index 23f0c177..45150c44 100644 --- a/ct/openhab-v5.sh +++ b/ct/openhab-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh index 4ffeb59a..88b62649 100644 --- a/ct/paperless-ngx-v5.sh +++ b/ct/paperless-ngx-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -319,6 +351,7 @@ header_info advanced_settings fi } + function update_script() { RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') SER=/etc/systemd/system/paperless-task-queue.service diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh index d182a728..f128744e 100644 --- a/ct/photoprism-v5.sh +++ b/ct/photoprism-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh index 486e2d28..f4e541af 100644 --- a/ct/pihole-v5.sh +++ b/ct/pihole-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh index 62243b55..a1d4b466 100644 --- a/ct/plex-v5.sh +++ b/ct/plex-v5.sh @@ -28,7 +28,7 @@ var_version="20.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -85,7 +85,6 @@ fi function default_settings() { echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" CT_TYPE="0" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -124,195 +123,229 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ +if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit-script +fi +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -328,6 +361,7 @@ header_info advanced_settings fi } + function update_script() { UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ "1" "Update LXC" ON \ diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh index 9553f229..daba5aec 100644 --- a/ct/podman-homeassistant-v5.sh +++ b/ct/podman-homeassistant-v5.sh @@ -32,7 +32,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -126,187 +126,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh index a388ea5f..582e0831 100644 --- a/ct/podman-v5.sh +++ b/ct/podman-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh index d8072ccf..47a66cf8 100644 --- a/ct/postgresql-v5.sh +++ b/ct/postgresql-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh index d0977b6c..34856e1a 100644 --- a/ct/prometheus-v5.sh +++ b/ct/prometheus-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh index e73b7249..758bf5a3 100644 --- a/ct/prowlarr-v5.sh +++ b/ct/prowlarr-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/qbittorrent-v5.sh b/ct/qbittorrent-v5.sh index 5eb36c37..b52a8f49 100644 --- a/ct/qbittorrent-v5.sh +++ b/ct/qbittorrent-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh index cf7cf23f..e9eb9667 100644 --- a/ct/radarr-v5.sh +++ b/ct/radarr-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh index 4b32964c..4d555119 100644 --- a/ct/readarr-v5.sh +++ b/ct/readarr-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh index 96f1f30e..e13fcb60 100644 --- a/ct/rockylinux-v5.sh +++ b/ct/rockylinux-v5.sh @@ -29,7 +29,7 @@ var_version="9" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,6 +123,13 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ @@ -304,6 +311,7 @@ function advanced_settings() { advanced_settings fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/rstptoweb-v5.sh b/ct/rstptoweb-v5.sh index e0bebee4..803d52c9 100644 --- a/ct/rstptoweb-v5.sh +++ b/ct/rstptoweb-v5.sh @@ -27,7 +27,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -121,187 +121,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index a3f9457d..a0f77356 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh index 1021fd8c..25867b90 100644 --- a/ct/scrypted-v5.sh +++ b/ct/scrypted-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh index f2411855..c2c2a019 100644 --- a/ct/shinobi-v5.sh +++ b/ct/shinobi-v5.sh @@ -28,7 +28,7 @@ var_version="22.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,195 +123,230 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ +if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" OFF \ "22.04" "Jammy" ON \ "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit-script +fi + +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -327,6 +362,7 @@ header_info advanced_settings fi } + function update_script() { header_info msg_info "Updating Shinobi LXC" diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh index f7f6d4b3..6018fcc2 100644 --- a/ct/sonarr-v5.sh +++ b/ct/sonarr-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh index 780653b1..0f88a88d 100644 --- a/ct/syncthing-v5.sh +++ b/ct/syncthing-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh index d15c5de0..4a879ece 100644 --- a/ct/tdarr-v5.sh +++ b/ct/tdarr-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh index 6927ee63..44b424f3 100644 --- a/ct/technitiumdns-v5.sh +++ b/ct/technitiumdns-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh index a7aad0ce..5fb1e37d 100644 --- a/ct/transmission-v5.sh +++ b/ct/transmission-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh index 688a2a60..3c447d88 100644 --- a/ct/trilium-v5.sh +++ b/ct/trilium-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh index 3a07a06b..79bcc700 100644 --- a/ct/ubuntu-v5.sh +++ b/ct/ubuntu-v5.sh @@ -28,7 +28,7 @@ var_version="22.04" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,195 +123,230 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 11 58 4 \ +if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ "18.04" "Bionic" OFF \ "20.04" "Focal" OFF \ "22.04" "Jammy" ON \ "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" +else + exit-script +fi + +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -327,6 +362,7 @@ header_info advanced_settings fi } + function update_script() { header_info msg_info "Updating ${APP} LXC" diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh index 6adff888..ee339e2b 100644 --- a/ct/umbrel-v5.sh +++ b/ct/umbrel-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -124,194 +124,226 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}Yes${CL}" - FUSE="yes" - else - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + FUSE="yes" +else + FUSE="no" +fi + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -327,6 +359,7 @@ header_info advanced_settings fi } + function update_script() { header_info msg_info "Updating ${APP} LXC" diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh index 2b299529..571c30fb 100644 --- a/ct/unifi-v5.sh +++ b/ct/unifi-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh index ad5cc724..09623497 100644 --- a/ct/uptimekuma-v5.sh +++ b/ct/uptimekuma-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index 055e893d..bda9fadf 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,218 @@ function default_settings() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh index 1f51216c..21b45677 100644 --- a/ct/whisparr-v5.sh +++ b/ct/whisparr-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh index 93fc469b..ec26eadb 100644 --- a/ct/whoogle-v5.sh +++ b/ct/whoogle-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh index 685f8783..3848eb4c 100644 --- a/ct/wikijs-v5.sh +++ b/ct/wikijs-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh index cc16fabd..8fce1701 100644 --- a/ct/wireguard-v5.sh +++ b/ct/wireguard-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh index 52629130..6d324d78 100644 --- a/ct/yunohost-v5.sh +++ b/ct/yunohost-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD (leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh index 53543482..f16cc025 100644 --- a/ct/zigbee2mqtt-v5.sh +++ b/ct/zigbee2mqtt-v5.sh @@ -29,7 +29,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -123,187 +123,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -319,6 +351,7 @@ header_info advanced_settings fi } + function update_script() { header_info cd /opt/zigbee2mqtt diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh index 510cb5fc..c4f360a6 100644 --- a/ct/zwave-js-ui-v5.sh +++ b/ct/zwave-js-ui-v5.sh @@ -28,7 +28,7 @@ var_version="11" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+$' +INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -122,187 +122,219 @@ function default_settings() { VERB="no" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" ON \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then - PW1="Automatic Login" PW=" " - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW1="Automatic Login" + PW=" " else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE1="Default" + GATE="" else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + GATE=",gw=$GATE1" fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU1="Default" + MTU="" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + MTU=",mtu=$MTU1" fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SX=Host + SD="" else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + SX=$SD + SD="-searchdomain=$SD" fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + NS="-nameserver=$NX" fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC1="Default" + MAC="" else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + VLAN=",tag=$VLAN1" fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else +else clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings - fi +fi } + function install_script() { ARCH_CHECK PVE_CHECK @@ -318,6 +350,7 @@ header_info advanced_settings fi } + function update_script() { header_info RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From ba7a7c172069ee2926f3d2756d8880599b2ab3a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Mar 2023 09:27:46 -0500 Subject: [PATCH 4431/6505] Update alpine-vaultwarden-v5-install.sh revert 12d5a78 Alpine doesn't like parameter expansion `${prompt,,}` fixes https://github.com/tteck/Proxmox/issues/1144 --- install/alpine-vaultwarden-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 187fb8c1..6c1a5d80 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -74,7 +74,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" From c47326ff2544b6a507f670b70b32ecbbb71204d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Mar 2023 09:50:48 -0500 Subject: [PATCH 4432/6505] Update alpine-vaultwarden-v5-install.sh match input if it's "y" or "yes" (case-insensitive) change `=~` operator in favor of `grep -Ei` in Alpine Linux --- install/alpine-vaultwarden-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 6c1a5d80..92e668b4 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -74,7 +74,7 @@ trap - ERR if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then + if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" From dc4e460b3cd094b43c93307f13814745396d04b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Mar 2023 19:36:10 -0500 Subject: [PATCH 4433/6505] Update update-lxcs.sh use the command line to exclude multiple containers simultaneously --- misc/update-lxcs.sh | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index b423b508..b1a6827a 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -34,8 +34,7 @@ while true; do esac done clear -exclude_container="$@" -containers=$(pct list | tail -n +2 | cut -f1 -d' ' | grep -vE "^($exclude_container)$") +excluded_containers=("$@") function update_container() { container=$1 header_info @@ -50,10 +49,22 @@ function update_container() { esac } header_info -for container in $containers; do - status=$(pct status $container) - template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") - if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then +for container in $(pct list | tail -n +2 | cut -f1 -d' '); do + excluded=false + for excluded_container in "${excluded_containers[@]}"; do + if [ "$container" == "$excluded_container" ]; then + excluded=true + break + fi + done + if [ "$excluded" == true ]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}" + sleep 1 + else + status=$(pct status $container) + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" pct start $container echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" @@ -63,6 +74,7 @@ for container in $containers; do pct shutdown $container & elif [ "$status" == "status: running" ]; then update_container $container + fi fi done wait From c18d373ff75c2af44201112ea4089c87e98c577b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Mar 2023 19:41:37 -0500 Subject: [PATCH 4434/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2b5c2a03..b932261a 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,12 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-10 + +### Changed + +- **Proxmox LXC Updater** + - You can use the command line to exclude multiple containers simultaneously. ## 2023-03-08 From 41109f0a8d331856c84d69786e9e16a141a125d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 04:07:19 -0500 Subject: [PATCH 4435/6505] Update cronicle-v5.sh add export variable fixes https://github.com/tteck/Proxmox/issues/1148 --- ct/cronicle-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh index c3c5069e..890b08cc 100644 --- a/ct/cronicle-v5.sh +++ b/ct/cronicle-v5.sh @@ -432,6 +432,7 @@ else fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +export tz=$timezone export SERV=$SERVER export DISABLEIPV6=$DISABLEIP6 export APPLICATION=$APP From 43f92cee142d18ce85840d5ade78c68b67e5fa08 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 06:22:43 -0500 Subject: [PATCH 4436/6505] Update alpine-vaultwarden-v5-install.sh --- install/alpine-vaultwarden-v5-install.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 92e668b4..5ab2786b 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -66,6 +66,11 @@ if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | c echo -e " 🖧 Check Network Settings" exit 1 fi +cat </etc/apk/repositories +https://dl-cdn.alpinelinux.org/alpine/latest-stable/main +https://dl-cdn.alpinelinux.org/alpine/latest-stable/community +https://dl-cdn.alpinelinux.org/alpine/edge/testing +EOF msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" @@ -102,7 +107,7 @@ $STD apk add mc msg_ok "Installed Dependencies" msg_info "Installing Vaultwarden" -$STD apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing vaultwarden +$STD apk add --no-cache vaultwarden cat </etc/conf.d/vaultwarden export DATA_FOLDER=/var/lib/vaultwarden export WEB_VAULT_ENABLED=true From 119b1c07911db0eab7ca01709a4d0467c6f377c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 06:32:34 -0500 Subject: [PATCH 4437/6505] Update alpine-vaultwarden-v5-install.sh --- install/alpine-vaultwarden-v5-install.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 5ab2786b..492ea700 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -110,6 +110,7 @@ msg_info "Installing Vaultwarden" $STD apk add --no-cache vaultwarden cat </etc/conf.d/vaultwarden export DATA_FOLDER=/var/lib/vaultwarden +export WEB_VAULT_FOLDER=/var/lib/vaultwarden/web-vault export WEB_VAULT_ENABLED=true export ADMIN_TOKEN=$(openssl rand -base64 48) export ROCKET_ADDRESS=0.0.0.0 @@ -117,6 +118,15 @@ EOF $STD rc-service vaultwarden start $STD rc-update add vaultwarden default msg_ok "Installed Vaultwarden" + +msg_info "Downloading Web-Vault" +WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') +$STD curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz +$STD tar -xzf bw_web_$WEBVAULT.tar.gz -C /var/lib/vaultwarden/ +msg_ok "Downloaded Web-Vault" + echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd if [[ "${SSH_ROOT}" == "yes" ]]; then $STD rc-update add sshd From 1a1cd2d0f9439338d405fdb03a32ad07dcd2f0e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 09:42:23 -0500 Subject: [PATCH 4438/6505] Update alpine-vaultwarden-v5-install.sh switch to edge repos --- install/alpine-vaultwarden-v5-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 492ea700..83deed2d 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -67,8 +67,8 @@ if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | c exit 1 fi cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/latest-stable/main -https://dl-cdn.alpinelinux.org/alpine/latest-stable/community +https://dl-cdn.alpinelinux.org/alpine/edge/main +https://dl-cdn.alpinelinux.org/alpine/edge/community https://dl-cdn.alpinelinux.org/alpine/edge/testing EOF msg_ok "Set up Container OS" From e1f4f4b436667e218ee18ec484d866a3da74eb8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 09:50:42 -0500 Subject: [PATCH 4439/6505] Update alpine-vaultwarden-v5-install.sh --- install/alpine-vaultwarden-v5-install.sh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 83deed2d..5d28238a 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -93,7 +93,7 @@ set -e trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" -$STD apk update +$STD apk update -a $STD apk upgrade msg_ok "Updated Container OS" @@ -119,14 +119,6 @@ $STD rc-service vaultwarden start $STD rc-update add vaultwarden default msg_ok "Installed Vaultwarden" -msg_info "Downloading Web-Vault" -WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') -$STD curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz -$STD tar -xzf bw_web_$WEBVAULT.tar.gz -C /var/lib/vaultwarden/ -msg_ok "Downloaded Web-Vault" - echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd if [[ "${SSH_ROOT}" == "yes" ]]; then $STD rc-update add sshd From f58bde28c83ea957de1f8f38886eb86409972a99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 09:55:16 -0500 Subject: [PATCH 4440/6505] Update alpine-vaultwarden-v5-install.sh --- install/alpine-vaultwarden-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index 5d28238a..a2b42c45 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -93,7 +93,7 @@ set -e trap 'error_handler $LINENO "$BASH_COMMAND"' ERR msg_info "Updating Container OS" -$STD apk update -a +$STD apk update $STD apk upgrade msg_ok "Updated Container OS" From 9bfbb57f110654decfb56ad187ed4bcd1e630516 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 10:09:26 -0500 Subject: [PATCH 4441/6505] Update alpine-vaultwarden-v5.sh change update --- ct/alpine-vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index 644f43da..74548ddc 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -369,7 +369,7 @@ while [ "$opt" != "" ]; do clear echo -e "${fgred}Update Vaultwarden${normal}" apk update &>/dev/null - apk upgrade --update-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing vaultwarden + apk upgrade &>/dev/null break ;; From e6db5a353b349a203a5b61e3a6caa38ed6d39d13 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 12:47:11 -0500 Subject: [PATCH 4442/6505] Update postgresql-v5-install.sh ensure that the PostgreSQL database server uses UTF-8 encoding and collation --- install/postgresql-v5-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/postgresql-v5-install.sh b/install/postgresql-v5-install.sh index 6c589a4f..7a003eb5 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-v5-install.sh @@ -47,6 +47,9 @@ function msg_error() { msg_info "Setting up Container OS " sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen locale-gen >/dev/null +LANG=$(grep -v '^#' /etc/locale.gen | grep -o '^[^ ]*') +update-locale LANG=$LANG +echo "export LANG=$LANG" >> ~/.bashrc echo $tz > /etc/timezone ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i=RETRY_NUM; i>0; i--)); do From d0311a3f1bef1ce5704adf65b4bf936798f0af22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Mar 2023 13:44:53 -0500 Subject: [PATCH 4443/6505] Update casaos-v5.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add function install_script 🤷🏻‍♂️ --- ct/casaos-v5.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh index 074c4065..7c00c6b3 100644 --- a/ct/casaos-v5.sh +++ b/ct/casaos-v5.sh @@ -344,6 +344,22 @@ else fi } +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + function update_script() { header_info msg_info "Updating ${APP} LXC" From ea7d5ae5140f54d8a28bc50ca2c77d7a12f3d7c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Mar 2023 03:42:02 -0400 Subject: [PATCH 4444/6505] Update vaultwarden-v5.sh recommend 4vCPU & 4096MiB RAM minimum for update --- ct/vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh index bda9fadf..88de3398 100644 --- a/ct/vaultwarden-v5.sh +++ b/ct/vaultwarden-v5.sh @@ -367,7 +367,7 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb header_info if [ "$UPD" == "1" ]; then -echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" +echo -e "\n ⚠️ Ensure you set 4vCPU & 4096MiB RAM minimum!!! \n" msg_info "Stopping Vaultwarden" systemctl stop vaultwarden.service msg_ok "Stopped Vaultwarden" From aee311706eb7475818c7535c82870228d37afe48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Mar 2023 08:01:43 -0400 Subject: [PATCH 4445/6505] Update clean-lxcs.sh skip non Debian/Ubuntu containers --- misc/clean-lxcs.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 0456383d..0273c2e3 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -function header_info { +function header_info() { clear cat <<"EOF" ________ __ _ ________ @@ -44,6 +44,13 @@ function clean_container() { } for container in $containers; do + os=$(pct config "$container" | awk '/^ostype/ {print $2}') + if [ "$os" != "debian" ] && [ "$os" != "ubuntu" ]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container is not Debian or Ubuntu ${CL} \n" + sleep 1 + continue + fi status=$(pct status $container) template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then From f8c38b8177002b059d36c2dd826d514627b92232 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Mar 2023 09:45:06 -0400 Subject: [PATCH 4446/6505] Add AppDaemon install to HA Core script (#1167) (#1168) Co-authored-by: Sergio Rius --- ct/homeassistant-core-v5.sh | 75 ++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh index 988b31df..cbb5aea1 100644 --- a/ct/homeassistant-core-v5.sh +++ b/ct/homeassistant-core-v5.sh @@ -356,10 +356,11 @@ header_info function update_script() { PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update Core" ON \ "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ + "4" "Install/Update AppDaemon" OFF \ 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then @@ -431,6 +432,78 @@ echo -e "FileBrowser should be reachable by going to the following URL. ${BL}http://$IP:8080${CL} admin|changeme\n" exit fi +if [ "$UPD" == "4" ]; then + clear + header_info + if [[ ! -d /srv/appdaemon ]]; then + msg_info "Installing AppDaemon" + mkdir /srv/appdaemon + cd /srv/appdaemon + python3 -m venv . + source bin/activate + pip install appdaemon &>/dev/null + mkdir -p /root/.homeassistant/appdaemon/apps + cat > /root/.homeassistant/appdaemon/appdaemon.yaml << EOF +# Sample appdaemon.yml file +# For configuration, please visit: https://appdaemon.readthedocs.io/en/latest/CONFIGURE.html +appdaemon: + time_zone: CET + latitude: 51.725 + longitude: 14.3434 + elevation: 0 + plugins: + HASS: + type: hass + ha_url: + token: +http: + url: http://127.0.0.1:5050 +admin: +api: +EOF + msg_ok "Installed AppDaemon" + + msg_info "Creating Service" + cat > /etc/systemd/system/appdaemon.service << EOF +[Unit] +Description=AppDaemon +After=homeassistant.service +Requires=homeassistant.service +[Service] +Type=simple +WorkingDirectory=/root/.homeassistant/appdaemon +ExecStart=/srv/appdaemon/bin/appdaemon -c "/root/.homeassistant/appdaemon" +RestartForceExitStatus=100 +[Install] +WantedBy=multi-user.target +EOF + systemctl enable --now appdaemon &>/dev/null + msg_ok "Created Service" + + msg_ok "Completed Successfully!\n" + echo -e "AppDaemon should be reachable by going to the following URL. + ${BL}http://$IP:5050${CL}\n" + exit + else + msg_info "Upgrading AppDaemon" + msg_info "Stopping AppDaemon" + systemctl stop appdaemon + msg_ok "Stopped AppDaemon" + + msg_info "Updating AppDaemon" + source /srv/appdaemon/bin/activate + pip install --upgrade appdaemon &>/dev/null + msg_ok "Updated AppDaemon" + + msg_info "Starting AppDaemon" + systemctl start appdaemon + sleep 2 + msg_ok "Started AppDaemon" + msg_ok "Update Successful" + echo -e "\n Go to http://${IP}:5050 \n" + exit + fi +fi } if command -v pveversion >/dev/null 2>&1; then From 0f607b725f8f8e03605fdadafa163d7619f5c4e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Mar 2023 15:39:25 -0400 Subject: [PATCH 4447/6505] Alpine-Grafana (#1171) * Created Alpine LXC (#1170) * Update alpine-grafana-v5-install.sh add base dependencies * Update alpine-grafana-v5.sh remove space --------- Co-authored-by: nicedevil007 --- ct/alpine-grafana-v5.sh | 421 +++++++++++++++++++++++++++ install/alpine-grafana-v5-install.sh | 118 ++++++++ 2 files changed, 539 insertions(+) create mode 100644 ct/alpine-grafana-v5.sh create mode 100644 install/alpine-grafana-v5-install.sh diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh new file mode 100644 index 00000000..fcdca216 --- /dev/null +++ b/ct/alpine-grafana-v5.sh @@ -0,0 +1,421 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ ____ + / ____/________ _/ __/___ _____v5____ _ + / / __/ ___/ __ / /_/ __ / __ \/ __ / +/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / +\____/_/ \__,_/_/ \__,_/_/ /_/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Grafana" +var_disk="0.5" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +timezone=$(cat /etc/timezone) +INTEGER='^[0-9]+([.][0-9]+)?$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" + PW="-password alpine" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function advanced_settings() { +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} + +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { +header_info +msg_info "Updating ${APP} LXC" +apk update &>/dev/null +apk upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export tz=$timezone +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/install/alpine-grafana-v5-install.sh b/install/alpine-grafana-v5-install.sh new file mode 100644 index 00000000..0b697f30 --- /dev/null +++ b/install/alpine-grafana-v5-install.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then +$STD sysctl net.ipv6.conf.all.disable_ipv6=1 +$STD sysctl net.ipv6.conf.default.disable_ipv6=1 +echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +$STD sysctl -p /etc/sysctl.d/99-sysctl.conf +fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +i=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +while [ $i -gt 0 ]; do + if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + i=$((i-1)) +done + +if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +cat </etc/apk/repositories +https://dl-cdn.alpinelinux.org/alpine/latest-stable/main +https://dl-cdn.alpinelinux.org/alpine/latest-stable/community +EOF +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" + +set +e +trap - ERR +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi + +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +msg_info "Updating Container OS" +$STD apk update +$STD apk upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apk add bash +$STD apk add curl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing Grafana" +$STD apk add --no-cache grafana +$STD sed -i '/http_addr/s/127.0.0.1/0.0.0.0/g' /etc/conf.d/grafana +$STD rc-service grafana start +$STD rc-update add grafana default +msg_ok "Installed Grafana" + +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +if [[ "${SSH_ROOT}" == "yes" ]]; then + $STD rc-update add sshd + $STD /etc/init.d/sshd start +fi From d1438e1e5ed768635e9098347330598c80a80650 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Mar 2023 15:52:56 -0400 Subject: [PATCH 4448/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b932261a..ff0bf564 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-15 + +### Changed + +- **Alpine-Grafana LXC** (Thanks @nicedevil007) + - NEW Script + ## 2023-03-10 ### Changed From 51def5ec4cf420f356cda77d6b1407eb9c9b2b27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Mar 2023 20:25:07 -0400 Subject: [PATCH 4449/6505] Update post-pve-install.sh (#1175) (#1176) Use a more specific regular expression to locate the line to modify. Co-authored-by: Alex Leigh --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 8404bc56..2e03f852 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -109,7 +109,7 @@ fi read -r -p "Disable Subscription Nag? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Disabling Subscription Nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag (Delete browser cache)" fi From 7458878882eda234a0a8df8183a52b871b0b4578 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Mar 2023 21:13:28 -0400 Subject: [PATCH 4450/6505] Update nginxproxymanager-v5.sh pause update until new version is confirmed working --- ct/nginxproxymanager-v5.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 1d22c093..a9ee5f89 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -357,7 +357,8 @@ header_info RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - +echo -e "Please wait until new version ${RELEASE} is confirmed working" +exit msg_info "Stopping Services" systemctl stop openresty systemctl stop npm From 2d47b876b24acbc3bdfb02543ea0f8bd46e1cf76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Mar 2023 21:31:40 -0400 Subject: [PATCH 4451/6505] Update nginxproxymanager-v5-install.sh hold v2.9.19 --- install/nginxproxymanager-v5-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 830c02fa..12bd374a 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -139,10 +139,10 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v${RELEASE}" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz -cd ./nginx-proxy-manager-${RELEASE} -msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" +msg_info "Downloading Nginx Proxy Manager v2.9.19" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.19 -O - | tar -xz +cd ./nginx-proxy-manager-2.9.19 +msg_ok "Downloaded Nginx Proxy Manager v2.9.19" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python From 78831d5bdea95523a264e368507d09f230ec5798 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 Mar 2023 08:26:26 -0400 Subject: [PATCH 4452/6505] Update nginxproxymanager-v5.sh fix update --- ct/nginxproxymanager-v5.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index a9ee5f89..1befe0d3 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -356,9 +356,7 @@ function update_script() { header_info RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') -echo -e "Please wait until new version ${RELEASE} is confirmed working" -exit + awk '{print substr($2, 3, length($2)-4) }') msg_info "Stopping Services" systemctl stop openresty systemctl stop npm @@ -454,6 +452,7 @@ EOF fi cd /app export NODE_ENV=development +sed -i 's/"liquidjs": "\^12\.9\.20",/"liquidjs": "\^10.6.1",/g' package.json yarn install --network-timeout=30000 &>/dev/null msg_ok "Initialized Backend" From e943987ea2a0af8b7e062106f5d6d21f26fdb3ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 Mar 2023 08:29:45 -0400 Subject: [PATCH 4453/6505] Update nginxproxymanager-v5-install.sh fix install --- install/nginxproxymanager-v5-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 12bd374a..359271c0 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -139,10 +139,10 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v2.9.19" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.19 -O - | tar -xz -cd ./nginx-proxy-manager-2.9.19 -msg_ok "Downloaded Nginx Proxy Manager v2.9.19" +msg_info "Downloading Nginx Proxy Manager v$RELEASE" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v$RELEASE -O - | tar -xz +cd ./nginx-proxy-manager-$RELEASE +msg_ok "Downloaded Nginx Proxy Manager v$RELEASE" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python @@ -227,6 +227,7 @@ EOF fi cd /app export NODE_ENV=development +sed -i 's/"liquidjs": "\^12\.9\.20",/"liquidjs": "\^10.6.1",/g' package.json $STD yarn install --network-timeout=30000 msg_ok "Initialized Backend" From 5e217698524145dda9bd35096c405118dd88a737 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 09:05:08 -0400 Subject: [PATCH 4454/6505] AdGuardHome-Alpine LXC (#1181) (#1185) * Alpine AdGuardHome LXC Co-authored-by: nicedevil007 --- ct/alpine-adguard-v5.sh | 486 +++++++++++++++++++++++++++ install/alpine-adguard-v5-install.sh | 123 +++++++ 2 files changed, 609 insertions(+) create mode 100644 ct/alpine-adguard-v5.sh create mode 100644 install/alpine-adguard-v5-install.sh diff --git a/ct/alpine-adguard-v5.sh b/ct/alpine-adguard-v5.sh new file mode 100644 index 00000000..a2fb5ad0 --- /dev/null +++ b/ct/alpine-adguard-v5.sh @@ -0,0 +1,486 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ __ + / | ____/ /___ ___v5______ __________/ / + / /| |/ __ / __ / / / / __ / ___/ __ / + / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / +/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-AdGuard" +var_disk="0.3" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +timezone=$(cat /etc/timezone) +INTEGER='^[0-9]+([.][0-9]+)?$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" + PW="-password alpine" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function advanced_settings() { +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} + +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { + header_info + normal=$(echo "\033[m") + menu=$(echo "\033[36m") + number=$(echo "\033[33m") + fgred=$(echo "\033[31m") + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${normal} Update LXC OS \n" + printf "${menu}**${number} 2)${normal} Update AdGuardHome\n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." + read opt + +while [ "$opt" != "" ]; do + case $opt in + 1) + clear + echo -e "${fgred}Update LXC OS${normal}" + msg_info "Updating LXC OS" + apk update &>/dev/null + apk upgrade &>/dev/null + msg_ok "Update Successfull" + + break + ;; + 2) + clear + echo -e "${fgred}Update AdGuardHome${normal}" + msg_info "Stopping AdguardHome" + /opt/AdGuardHome/AdGuardHome -s stop &>/dev/null + msg_ok "Stopped AdguardHome" + + VER=$(curl -sqI https://github.com/AdguardTeam/AdGuardHome/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); + msg_info "Updating AdguardHome to $VER" + wget -q "https://github.com/AdguardTeam/AdGuardHome/releases/download/$VER/AdGuardHome_linux_amd64.tar.gz" + tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null + mkdir -p adguard-backup + cp -rf /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ + cp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome + cp -r adguard-backup/* /opt/AdGuardHome/ + msg_ok "Updated AdguardHome" + + msg_info "Starting AdguardHome" + /opt/AdGuardHome/AdGuardHome -s start &>/dev/null + msg_ok "Started AdguardHome" + + msg_info "Cleaning Up" + rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup + msg_ok "Cleaned" + msg_ok "Update Successfull" + + break + ;; + x) + clear + echo -e "⚠ User exited script \n" + exit + ;; + \n) + clear + echo -e "⚠ User exited script \n" + exit + ;; + *) + clear + echo -e "Please choose an option from the menu" + update_script + ;; + esac +done + + +exit +} + +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /opt/AdGuardHome ]]; then + msg_error "No ${APP} Installation Found!" +fi + +if ! command -v pveversion >/dev/null 2>&1; then + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export tz=$timezone +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/install/alpine-adguard-v5-install.sh b/install/alpine-adguard-v5-install.sh new file mode 100644 index 00000000..0e858b7c --- /dev/null +++ b/install/alpine-adguard-v5-install.sh @@ -0,0 +1,123 @@ +#!/bin/sh + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then +$STD sysctl net.ipv6.conf.all.disable_ipv6=1 +$STD sysctl net.ipv6.conf.default.disable_ipv6=1 +echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +$STD sysctl -p /etc/sysctl.d/99-sysctl.conf +fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +i=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +while [ $i -gt 0 ]; do + if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + i=$((i-1)) +done + +if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +cat </etc/apk/repositories +https://dl-cdn.alpinelinux.org/alpine/latest-stable/main +https://dl-cdn.alpinelinux.org/alpine/latest-stable/community +EOF +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" + +set +e +trap - ERR +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi + +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +msg_info "Updating Container OS" +$STD apk update +$STD apk upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apk add wget +$STD apk add bash +$STD apk add curl +$STD apk add nano +$STD apk add mc +$STD apk add openssh +msg_ok "Installed Dependencies" + +msg_info "Installing AdguardHome" +VER=$(curl --silent -qI https://github.com/AdguardTeam/AdGuardHome/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); +$STD wget -q "https://github.com/AdguardTeam/AdGuardHome/releases/download/$VER/AdGuardHome_linux_amd64.tar.gz" +$STD tar -xvf AdGuardHome_linux_amd64.tar.gz >/dev/null 2>&1 +$STD mv AdGuardHome /opt +$STD rm AdGuardHome_linux_amd64.tar.gz +$STD chmod +x /opt/AdGuardHome/AdGuardHome +$STD /opt/AdGuardHome/AdGuardHome -s install +$STD /opt/AdGuardHome/AdGuardHome -s start +$STD msg_ok "Installed AdguardHome" + +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +if [[ "${SSH_ROOT}" == "yes" ]]; then + $STD rc-update add sshd + $STD /etc/init.d/sshd start +fi From ac97609e1b7d03c2ab9a5839e31fbaa9f5fbd5af Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 09:27:00 -0400 Subject: [PATCH 4455/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index ff0bf564..cfafe62d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-18 + +### Changed + +- **Alpine-AdGuard Home LXC** (Thanks @nicedevil007) + - NEW Script + ## 2023-03-15 ### Changed From c71eb79e792fd40910eb70415cfed0f858731180 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 12:10:03 -0400 Subject: [PATCH 4456/6505] Update nginxproxymanager-v5.sh issue fixed in v2.9.21 --- ct/nginxproxymanager-v5.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh index 1befe0d3..a12eb9dd 100644 --- a/ct/nginxproxymanager-v5.sh +++ b/ct/nginxproxymanager-v5.sh @@ -452,7 +452,6 @@ EOF fi cd /app export NODE_ENV=development -sed -i 's/"liquidjs": "\^12\.9\.20",/"liquidjs": "\^10.6.1",/g' package.json yarn install --network-timeout=30000 &>/dev/null msg_ok "Initialized Backend" From 1508ca2443bc0214e46da1fe261d212af1c11740 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 12:11:54 -0400 Subject: [PATCH 4457/6505] Update nginxproxymanager-v5-install.sh fixed issue in v2.9.21 --- install/nginxproxymanager-v5-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index 359271c0..d66e0adf 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -227,7 +227,6 @@ EOF fi cd /app export NODE_ENV=development -sed -i 's/"liquidjs": "\^12\.9\.20",/"liquidjs": "\^10.6.1",/g' package.json $STD yarn install --network-timeout=30000 msg_ok "Initialized Backend" From aea844765e295e73bf0e0f5f9bc0fc4c26481e7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:33:00 -0400 Subject: [PATCH 4458/6505] Create alpine-zigbee2mqtt-v5-install.sh --- install/alpine-zigbee2mqtt-v5-install.sh | 117 +++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 install/alpine-zigbee2mqtt-v5-install.sh diff --git a/install/alpine-zigbee2mqtt-v5-install.sh b/install/alpine-zigbee2mqtt-v5-install.sh new file mode 100644 index 00000000..3616d418 --- /dev/null +++ b/install/alpine-zigbee2mqtt-v5-install.sh @@ -0,0 +1,117 @@ +#!/bin/sh + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then +$STD sysctl net.ipv6.conf.all.disable_ipv6=1 +$STD sysctl net.ipv6.conf.default.disable_ipv6=1 +echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +$STD sysctl -p /etc/sysctl.d/99-sysctl.conf +fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +i=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +while [ $i -gt 0 ]; do + if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + i=$((i-1)) +done + +if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +cat </etc/apk/repositories +https://dl-cdn.alpinelinux.org/alpine/edge/main +https://dl-cdn.alpinelinux.org/alpine/edge/community +https://dl-cdn.alpinelinux.org/alpine/edge/testing +EOF +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" + +set +e +trap - ERR +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi + +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +msg_info "Updating Container OS" +$STD apk update +$STD apk upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apk add bash +$STD apk add curl +$STD apk add openssl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing $APPLICATION" +$STD apk add zigbee2mqtt +msg_ok "Installed $APPLICATION" + +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +if [[ "${SSH_ROOT}" == "yes" ]]; then + $STD rc-update add sshd + $STD /etc/init.d/sshd start +fi From ddd76642433f05aee116535aa705dec43ab4b587 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:36:28 -0400 Subject: [PATCH 4459/6505] Create alpine-zigbee2mqtt-v5.sh --- ct/alpine-zigbee2mqtt-v5.sh | 461 ++++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 ct/alpine-zigbee2mqtt-v5.sh diff --git a/ct/alpine-zigbee2mqtt-v5.sh b/ct/alpine-zigbee2mqtt-v5.sh new file mode 100644 index 00000000..20c39476 --- /dev/null +++ b/ct/alpine-zigbee2mqtt-v5.sh @@ -0,0 +1,461 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ _ __ ___ __ _______ ____________ +/__ / (_)___ _/ /_ ___v5___ |__ \ / |/ / __ \/_ __/_ __/ + / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / + / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / +/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ + /____/ Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Zigbee2MQTT" +var_disk="0.3" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +timezone=$(cat /etc/timezone) +INTEGER='^[0-9]+([.][0-9]+)?$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" + CT_TYPE="0" + echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" + PW="-password alpine" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function advanced_settings() { +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" ON \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} + +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { + normal=$(echo "\033[m") + menu=$(echo "\033[36m") + number=$(echo "\033[33m") + fgred=$(echo "\033[31m") + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${normal} Update ${APP} \n" + printf "\n${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." + read opt + +while [ "$opt" != "" ]; do + case $opt in + 1) + clear + echo -e "${fgred}Update ${APP}${normal}" + apk update &>/dev/null + apk upgrade &>/dev/null + + break + ;; + x) + exit + ;; + \n) + exit + ;; + *) + clear + echo -e "Please choose an option from the menu" + update_script + ;; + esac +done +exit +} +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/zigbee2mqtt/configuration.yaml ]]; then + msg_error "No ${APP} Installation Found!" +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ -f /etc/zigbee2mqtt/configuration.yaml ]]; then + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export tz=$timezone +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From 3d15e5b026287c3644d8ce047aff7398e95671a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:40:44 -0400 Subject: [PATCH 4460/6505] Update alpine-vaultwarden-v5-install.sh Tweak --- install/alpine-vaultwarden-v5-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh index a2b42c45..02edeb1a 100644 --- a/install/alpine-vaultwarden-v5-install.sh +++ b/install/alpine-vaultwarden-v5-install.sh @@ -106,8 +106,8 @@ $STD apk add nano $STD apk add mc msg_ok "Installed Dependencies" -msg_info "Installing Vaultwarden" -$STD apk add --no-cache vaultwarden +msg_info "Installing $APPLICATION" +$STD apk add vaultwarden cat </etc/conf.d/vaultwarden export DATA_FOLDER=/var/lib/vaultwarden export WEB_VAULT_FOLDER=/var/lib/vaultwarden/web-vault @@ -117,7 +117,7 @@ export ROCKET_ADDRESS=0.0.0.0 EOF $STD rc-service vaultwarden start $STD rc-update add vaultwarden default -msg_ok "Installed Vaultwarden" +msg_ok "Installed $APPLICATION" echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd if [[ "${SSH_ROOT}" == "yes" ]]; then From fc5521f2f96ab966279adf5879d3e8c4dd1e9646 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:43:10 -0400 Subject: [PATCH 4461/6505] Update alpine-adguard-v5-install.sh Tweak --- install/alpine-adguard-v5-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-adguard-v5-install.sh b/install/alpine-adguard-v5-install.sh index 0e858b7c..a5c73b3f 100644 --- a/install/alpine-adguard-v5-install.sh +++ b/install/alpine-adguard-v5-install.sh @@ -105,7 +105,7 @@ $STD apk add mc $STD apk add openssh msg_ok "Installed Dependencies" -msg_info "Installing AdguardHome" +msg_info "Installing $APPLICATION" VER=$(curl --silent -qI https://github.com/AdguardTeam/AdGuardHome/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); $STD wget -q "https://github.com/AdguardTeam/AdGuardHome/releases/download/$VER/AdGuardHome_linux_amd64.tar.gz" $STD tar -xvf AdGuardHome_linux_amd64.tar.gz >/dev/null 2>&1 @@ -114,7 +114,7 @@ $STD rm AdGuardHome_linux_amd64.tar.gz $STD chmod +x /opt/AdGuardHome/AdGuardHome $STD /opt/AdGuardHome/AdGuardHome -s install $STD /opt/AdGuardHome/AdGuardHome -s start -$STD msg_ok "Installed AdguardHome" +$STD msg_ok "Installed $APPLICATION" echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd if [[ "${SSH_ROOT}" == "yes" ]]; then From 2de9410db96a5f4de390766bbdeb6dd725e2b8c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:44:12 -0400 Subject: [PATCH 4462/6505] Update alpine-grafana-v5-install.sh Tweak --- install/alpine-grafana-v5-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/alpine-grafana-v5-install.sh b/install/alpine-grafana-v5-install.sh index 0b697f30..efd75bef 100644 --- a/install/alpine-grafana-v5-install.sh +++ b/install/alpine-grafana-v5-install.sh @@ -104,12 +104,12 @@ $STD apk add nano $STD apk add mc msg_ok "Installed Dependencies" -msg_info "Installing Grafana" -$STD apk add --no-cache grafana +msg_info "Installing $APPLICATION" +$STD apk add grafana $STD sed -i '/http_addr/s/127.0.0.1/0.0.0.0/g' /etc/conf.d/grafana $STD rc-service grafana start $STD rc-update add grafana default -msg_ok "Installed Grafana" +msg_ok "Installed $APPLICATION" echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd if [[ "${SSH_ROOT}" == "yes" ]]; then From 03c2c620d4fa0701f81b0389f0b12cefb712d32b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:58:26 -0400 Subject: [PATCH 4463/6505] Update alpine-adguard-v5.sh Tweak --- ct/alpine-adguard-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-adguard-v5.sh b/ct/alpine-adguard-v5.sh index a2fb5ad0..a618d254 100644 --- a/ct/alpine-adguard-v5.sh +++ b/ct/alpine-adguard-v5.sh @@ -13,7 +13,7 @@ cat <<"EOF" / /| |/ __ / __ / / / / __ / ___/ __ / / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / /_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ - /____/ + /____/ Alpine EOF } From 269bffed7e4d1567693e042d010e1f6593994d1c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:59:16 -0400 Subject: [PATCH 4464/6505] Update alpine-grafana-v5.sh Tweak --- ct/alpine-grafana-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh index fcdca216..72f76fa1 100644 --- a/ct/alpine-grafana-v5.sh +++ b/ct/alpine-grafana-v5.sh @@ -13,6 +13,7 @@ cat <<"EOF" / / __/ ___/ __ / /_/ __ / __ \/ __ / / /_/ / / / /_/ / __/ /_/ / / / / /_/ / \____/_/ \__,_/_/ \__,_/_/ /_/\__,_/ + Alpine EOF } From 84f00ebfabcbcc99947bf0bd6948019e2654e532 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 16:59:39 -0400 Subject: [PATCH 4465/6505] Update alpine-vaultwarden-v5.sh Tweak --- ct/alpine-vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index 74548ddc..7d62d2e9 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -13,7 +13,7 @@ cat <<"EOF" | | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ | |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / |___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ - Alpine 3.17 + Alpine EOF } From 5df97b8a2026a5ec0153d75e052fb5ad5662ebdd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 17:16:35 -0400 Subject: [PATCH 4466/6505] Update alpine-zigbee2mqtt-v5.sh Tweak --- ct/alpine-zigbee2mqtt-v5.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/alpine-zigbee2mqtt-v5.sh b/ct/alpine-zigbee2mqtt-v5.sh index 20c39476..aef1bdfb 100644 --- a/ct/alpine-zigbee2mqtt-v5.sh +++ b/ct/alpine-zigbee2mqtt-v5.sh @@ -457,5 +457,3 @@ pct set $CTID -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" From 3881ae9873138fb12d251f8ed5c2d9447f4c2bd7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 17:43:12 -0400 Subject: [PATCH 4467/6505] Create alpine-docker-v5-install.sh --- install/alpine-docker-v5-install.sh | 150 ++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 install/alpine-docker-v5-install.sh diff --git a/install/alpine-docker-v5-install.sh b/install/alpine-docker-v5-install.sh new file mode 100644 index 00000000..9d036f0c --- /dev/null +++ b/install/alpine-docker-v5-install.sh @@ -0,0 +1,150 @@ +#!/bin/sh + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi +silent() { "$@" > /dev/null 2>&1; } +if [ "$DISABLEIPV6" == "yes" ]; then +$STD sysctl net.ipv6.conf.all.disable_ipv6=1 +$STD sysctl net.ipv6.conf.default.disable_ipv6=1 +echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf +$STD sysctl -p /etc/sysctl.d/99-sysctl.conf +fi +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +BL=$(echo "\033[36m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +RETRY_NUM=10 +RETRY_EVERY=3 +i=$RETRY_NUM +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +BFR="\\r\\033[K" +HOLD="-" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Setting up Container OS " +while [ $i -gt 0 ]; do + if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + i=$((i-1)) +done + +if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 +fi +cat </etc/apk/repositories +https://dl-cdn.alpinelinux.org/alpine/edge/main +https://dl-cdn.alpinelinux.org/alpine/edge/community +https://dl-cdn.alpinelinux.org/alpine/edge/testing +EOF +msg_ok "Set up Container OS" +msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" + +set +e +trap - ERR +if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi +fi + +RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') +if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +msg_info "Updating Container OS" +$STD apk update +$STD apk upgrade +msg_ok "Updated Container OS" + +msg_info "Installing Dependencies" +$STD apk add bash +$STD apk add curl +$STD apk add openssl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing $APPLICATION" +$STD apk add docker +$STD rc-service docker start +$STD rc-update add docker default +msg_ok "Installed $APPLICATION" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") +DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") + +read -r -p "Would you like to add Portainer? " prompt +if echo "$prompt" | grep -Eq "^(y|yes)$"; then + msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" + docker volume create portainer_data >/dev/null + $STD docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest + msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" +fi + +read -r -p "Would you like to add Docker Compose? " prompt +if echo "$prompt" | grep -Eq "^(y|yes)$"; then + msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} + mkdir -p $DOCKER_CONFIG/cli-plugins + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose + chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose + msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" +fi + +echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd +if [[ "${SSH_ROOT}" == "yes" ]]; then + $STD rc-update add sshd + $STD /etc/init.d/sshd start +fi From fbdffa0d94beee11b8b1f8dd58cc12fabd155dd3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 17:44:27 -0400 Subject: [PATCH 4468/6505] Create alpine-docker-v5.sh --- ct/alpine-docker-v5.sh | 464 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 ct/alpine-docker-v5.sh diff --git a/ct/alpine-docker-v5.sh b/ct/alpine-docker-v5.sh new file mode 100644 index 00000000..638b1855 --- /dev/null +++ b/ct/alpine-docker-v5.sh @@ -0,0 +1,464 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \____ _____/ /_v5__ _____ + / / / / __ \/ ___/ //_/ _ \/ ___/ + / /_/ / /_/ / /__/ ,< / __/ / +/_____/\____/\___/_/|_|\___/_/ + Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Docker" +var_disk="2" +var_cpu="1" +var_ram="1024" +var_os="alpine" +var_version="3.17" +NSAPP=$(echo ${APP,,} | tr -d ' ') +var_install="${NSAPP}-v5-install" +timezone=$(cat /etc/timezone) +INTEGER='^[0-9]+([.][0-9]+)?$' +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function PVE_CHECK() { +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 +exit +fi +} +function ARCH_CHECK() { +if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 +exit +fi +} + +function default_settings() { + echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" + CT_TYPE="1" + echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" + PW="-password alpine" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + CT_ID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + HN=$NSAPP + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" + DISK_SIZE="$var_disk" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + RAM_SIZE="$var_ram" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + NET=dhcp + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + GATE="" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + DISABLEIP6="no" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + SD="" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + NS="" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + MAC="" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + SSH="no" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + VERB="no" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function advanced_settings() { +if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" On \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" +else + exit-script +fi + +if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" +else + exit-script +fi + +if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi +else + exit +fi + +if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" +else + exit-script +fi + +if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi +else + exit-script +fi + +if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi +else + exit-script +fi + +if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi +else + exit-script +fi + +if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi +else + exit-script +fi + +if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi +else + exit-script +fi +if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" +else + DISABLEIP6="no" +fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + +if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" +else + exit-script +fi + +if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" +else + exit-script +fi + +if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" +else + exit-script +fi + +if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi +else + exit-script +fi + +if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" +else + exit-script +fi + +if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" +else + SSH="no" +fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + +if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" +else + VERB="no" +fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + +if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" +else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings +fi +} + +function install_script() { +ARCH_CHECK +PVE_CHECK +NEXTID=$(pvesh get /cluster/nextid) +header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function update_script() { + normal=$(echo "\033[m") + menu=$(echo "\033[36m") + number=$(echo "\033[33m") + fgred=$(echo "\033[31m") + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${normal} Update ${APP} \n" + printf "\n${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." + read opt + +while [ "$opt" != "" ]; do + case $opt in + 1) + clear + echo -e "${fgred}Update ${APP}${normal}" + apk update &>/dev/null + apk upgrade &>/dev/null + + break + ;; + x) + exit + ;; + \n) + exit + ;; + *) + clear + echo -e "Please choose an option from the menu" + update_script + ;; + esac +done +exit +} +if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/zigbee2mqtt/configuration.yaml ]]; then + msg_error "No ${APP} Installation Found!" +fi + +if ! command -v pveversion >/dev/null 2>&1 && [[ -f /etc/zigbee2mqtt/configuration.yaml ]]; then + update_script +fi + +if [ "$VERB" == "yes" ]; then set -x; fi +if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" +else + FEATURES="nesting=1" +fi +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +export tz=$timezone +export DISABLEIPV6=$DISABLEIP6 +export APPLICATION=$APP +export VERBOSE=$VERB +export SSH_ROOT=${SSH} +export CTID=$CT_ID +export PCT_OSTYPE=$var_os +export PCT_OSVERSION=$var_version +export PCT_DISK_SIZE=$DISK_SIZE +export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW +" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit +LXC_CONFIG=/etc/pve/lxc/${CTID}.conf +cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF +if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF +fi +msg_info "Starting LXC Container" +pct start $CTID +msg_ok "Started LXC Container" +lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit +IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) +pct set $CTID -description "# ${APP} LXC +### https://tteck.github.io/Proxmox/ +" +msg_ok "Completed Successfully!\n" From 73cae0aa6073bf64f94f14d82ed62409c3709050 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 20:08:24 -0400 Subject: [PATCH 4469/6505] Update CHANGELOG.MD - Alpine-Docker LXC - Alpine-Zigbee2MQTT LXC --- CHANGELOG.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index cfafe62d..6bf0a220 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file. - **Alpine-AdGuard Home LXC** (Thanks @nicedevil007) - NEW Script +- **Alpine-Docker LXC** + - NEW Script +- **Alpine-Zigbee2MQTT LXC** + - NEW Script ## 2023-03-15 From 32a1ccb59a04a2f7dc46e087cec23c2f3af329e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 20:24:10 -0400 Subject: [PATCH 4470/6505] Update alpine-docker-v5.sh fix directory check --- ct/alpine-docker-v5.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/alpine-docker-v5.sh b/ct/alpine-docker-v5.sh index 638b1855..d0ec1d2f 100644 --- a/ct/alpine-docker-v5.sh +++ b/ct/alpine-docker-v5.sh @@ -396,12 +396,12 @@ if command -v pveversion >/dev/null 2>&1; then install_script fi -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/zigbee2mqtt/configuration.yaml ]]; then - msg_error "No ${APP} Installation Found!" -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ -f /etc/zigbee2mqtt/configuration.yaml ]]; then - update_script +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -d /etc/docker ]]; then + msg_error "No ${APP} Installation Found!" + else + update_script + fi fi if [ "$VERB" == "yes" ]; then set -x; fi From 54259a84c165246375546a34b0b5152b558acfb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 20:26:11 -0400 Subject: [PATCH 4471/6505] Update alpine-zigbee2mqtt-v5.sh Tweak --- ct/alpine-zigbee2mqtt-v5.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/alpine-zigbee2mqtt-v5.sh b/ct/alpine-zigbee2mqtt-v5.sh index aef1bdfb..209018a1 100644 --- a/ct/alpine-zigbee2mqtt-v5.sh +++ b/ct/alpine-zigbee2mqtt-v5.sh @@ -396,12 +396,12 @@ if command -v pveversion >/dev/null 2>&1; then install_script fi -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/zigbee2mqtt/configuration.yaml ]]; then - msg_error "No ${APP} Installation Found!" -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ -f /etc/zigbee2mqtt/configuration.yaml ]]; then - update_script +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/zigbee2mqtt/configuration.yaml ]]; then + msg_error "No ${APP} Installation Found!" + else + update_script + fi fi if [ "$VERB" == "yes" ]; then set -x; fi From ec8fe397125b26ad538a7f5adfbc5c45d72b7025 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 20:28:21 -0400 Subject: [PATCH 4472/6505] Update alpine-vaultwarden-v5.sh Tweak --- ct/alpine-vaultwarden-v5.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index 7d62d2e9..2123918d 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -404,13 +404,12 @@ if command -v pveversion >/dev/null 2>&1; then install_script fi -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/conf.d/vaultwarden ]]; then - msg_error "No ${APP} Installation Found!" -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ -f /etc/conf.d/vaultwarden ]]; then - update_script -fi +if ! command -v pveversion >/dev/null 2>&1; then + if [[ ! -f /etc/conf.d/vaultwarden ]]; then + msg_error "No ${APP} Installation Found!" + else + update_script + fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From 268a36a87102544a4d37f23a9e076349173706f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 20:32:07 -0400 Subject: [PATCH 4473/6505] Update alpine-grafana-v5.sh Tweak --- ct/alpine-grafana-v5.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh index 72f76fa1..e2b6f275 100644 --- a/ct/alpine-grafana-v5.sh +++ b/ct/alpine-grafana-v5.sh @@ -371,13 +371,11 @@ if command -v pveversion >/dev/null 2>&1; then fi if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit + if [[ ! -f /etc/conf.d/grafana ]]; then + msg_error "No ${APP} Installation Found!" + else + update_script fi - update_script -fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From cde33cf00e227a3625bde332fb92fc8442a5b415 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 20:34:33 -0400 Subject: [PATCH 4474/6505] Update alpine-adguard-v5.sh Tweak --- ct/alpine-adguard-v5.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ct/alpine-adguard-v5.sh b/ct/alpine-adguard-v5.sh index a618d254..06819168 100644 --- a/ct/alpine-adguard-v5.sh +++ b/ct/alpine-adguard-v5.sh @@ -435,13 +435,12 @@ if command -v pveversion >/dev/null 2>&1; then install_script fi -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /opt/AdGuardHome ]]; then - msg_error "No ${APP} Installation Found!" -fi - if ! command -v pveversion >/dev/null 2>&1; then - update_script -fi + if [[ ! -d /opt/AdGuardHome ]]; then + msg_error "No ${APP} Installation Found!" + else + update_script + fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From dcd1a633b80cc82cf89070cbc27d826839c6fd2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 22:32:45 -0400 Subject: [PATCH 4475/6505] Update alpine-docker-v5-install.sh tweak --- install/alpine-docker-v5-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-docker-v5-install.sh b/install/alpine-docker-v5-install.sh index 9d036f0c..8a36fa0e 100644 --- a/install/alpine-docker-v5-install.sh +++ b/install/alpine-docker-v5-install.sh @@ -67,8 +67,8 @@ if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | c exit 1 fi cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/edge/main -https://dl-cdn.alpinelinux.org/alpine/edge/community +https://dl-cdn.alpinelinux.org/alpine/latest-stable/main +https://dl-cdn.alpinelinux.org/alpine/latest-stable/community https://dl-cdn.alpinelinux.org/alpine/edge/testing EOF msg_ok "Set up Container OS" From 1bd635936a142328051c346378a412f650a939b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Mar 2023 22:33:32 -0400 Subject: [PATCH 4476/6505] Update alpine-zigbee2mqtt-v5-install.sh tweak --- install/alpine-zigbee2mqtt-v5-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-zigbee2mqtt-v5-install.sh b/install/alpine-zigbee2mqtt-v5-install.sh index 3616d418..26c35768 100644 --- a/install/alpine-zigbee2mqtt-v5-install.sh +++ b/install/alpine-zigbee2mqtt-v5-install.sh @@ -67,8 +67,8 @@ if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | c exit 1 fi cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/edge/main -https://dl-cdn.alpinelinux.org/alpine/edge/community +https://dl-cdn.alpinelinux.org/alpine/latest-stable/main +https://dl-cdn.alpinelinux.org/alpine/latest-stable/community https://dl-cdn.alpinelinux.org/alpine/edge/testing EOF msg_ok "Set up Container OS" From 187befbb59bb06e573c8f6dfd26eb7f5dd3fdf51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:21:05 -0400 Subject: [PATCH 4477/6505] Update alpine-adguard-v5.sh --- ct/alpine-adguard-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-adguard-v5.sh b/ct/alpine-adguard-v5.sh index 06819168..96ab78ba 100644 --- a/ct/alpine-adguard-v5.sh +++ b/ct/alpine-adguard-v5.sh @@ -441,6 +441,7 @@ if ! command -v pveversion >/dev/null 2>&1; then else update_script fi +fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From bbfabfc8f6cc311c12830daf8a040733dfac35de Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:31:48 -0400 Subject: [PATCH 4478/6505] Update alpine-vaultwarden-v5.sh --- ct/alpine-vaultwarden-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index 2123918d..c6c2ed81 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -410,6 +410,7 @@ if ! command -v pveversion >/dev/null 2>&1; then else update_script fi +fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From 243b65695c9a3b0289f78fac186565f9c185f95f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:32:45 -0400 Subject: [PATCH 4479/6505] Update alpine-grafana-v5.sh --- ct/alpine-grafana-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh index e2b6f275..b5dea2fe 100644 --- a/ct/alpine-grafana-v5.sh +++ b/ct/alpine-grafana-v5.sh @@ -376,6 +376,7 @@ if ! command -v pveversion >/dev/null 2>&1; then else update_script fi +fi if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then From 96e040fcb44faf95cec3c1b5b59708405d18f5c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:42:55 -0400 Subject: [PATCH 4480/6505] Update alpine-adguard-v5.sh --- ct/alpine-adguard-v5.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/alpine-adguard-v5.sh b/ct/alpine-adguard-v5.sh index 96ab78ba..ce03722e 100644 --- a/ct/alpine-adguard-v5.sh +++ b/ct/alpine-adguard-v5.sh @@ -27,7 +27,6 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") From 939c9fe7d247e48e99f3086d59ec59e2a9a97a75 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:43:48 -0400 Subject: [PATCH 4481/6505] Update alpine-docker-v5.sh --- ct/alpine-docker-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-docker-v5.sh b/ct/alpine-docker-v5.sh index d0ec1d2f..5d92c547 100644 --- a/ct/alpine-docker-v5.sh +++ b/ct/alpine-docker-v5.sh @@ -27,7 +27,6 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,6 +351,7 @@ header_info } function update_script() { + header_info normal=$(echo "\033[m") menu=$(echo "\033[36m") number=$(echo "\033[33m") From de1d37ebf2c136f28273cd0243d4921bbfb37006 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:44:28 -0400 Subject: [PATCH 4482/6505] Update alpine-grafana-v5.sh --- ct/alpine-grafana-v5.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh index b5dea2fe..d84b776a 100644 --- a/ct/alpine-grafana-v5.sh +++ b/ct/alpine-grafana-v5.sh @@ -27,7 +27,6 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") From 2a6d09477f311448f94a1d8d64b8c85afa7e290e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:45:13 -0400 Subject: [PATCH 4483/6505] Update alpine-vaultwarden-v5.sh --- ct/alpine-vaultwarden-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index c6c2ed81..f9aa6c81 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -27,7 +27,6 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,6 +351,7 @@ header_info } function update_script() { + header_info normal=$(echo "\033[m") menu=$(echo "\033[36m") number=$(echo "\033[33m") From 766adccf7a222cfd445f5385eef1ff4e2f9f253e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 09:46:12 -0400 Subject: [PATCH 4484/6505] Update alpine-zigbee2mqtt-v5.sh --- ct/alpine-zigbee2mqtt-v5.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-zigbee2mqtt-v5.sh b/ct/alpine-zigbee2mqtt-v5.sh index 209018a1..329c3fe7 100644 --- a/ct/alpine-zigbee2mqtt-v5.sh +++ b/ct/alpine-zigbee2mqtt-v5.sh @@ -27,7 +27,6 @@ var_os="alpine" var_version="3.17" NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) INTEGER='^[0-9]+([.][0-9]+)?$' YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -352,6 +351,7 @@ header_info } function update_script() { + header_info normal=$(echo "\033[m") menu=$(echo "\033[36m") number=$(echo "\033[33m") From 3d3161b1e72e87ecbb865a7a92c22c8be380cf64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 13:01:11 -0400 Subject: [PATCH 4485/6505] Created Update/Config for Alpine-Grafana (#1191) (#1192) Feature to configure the IP address on which the service is listening has been implemented Co-authored-by: nicedevil007 --- ct/alpine-grafana-v5.sh | 73 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh index d84b776a..6766e031 100644 --- a/ct/alpine-grafana-v5.sh +++ b/ct/alpine-grafana-v5.sh @@ -351,12 +351,73 @@ header_info } function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apk update &>/dev/null -apk upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" + header_info + normal=$(echo "\033[m") + menu=$(echo "\033[36m") + number=$(echo "\033[33m") + fgred=$(echo "\033[31m") + LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + printf "\n${menu}*********************************************${normal}\n" + printf "${menu}**${number} 1)${normal} Update LXC OS + Grafana \n" + printf "${menu}**${number} 2)${normal} Allow 0.0.0.0 for listening \n" + printf "${menu}**${number} 3)${normal} Allow only ${LXCIP} for listening \n" + printf "${menu}*********************************************${normal}\n" + printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." + read opt + +while [ "$opt" != "" ]; do + case $opt in + 1) + clear + echo -e "${fgred}Update LXC OS${normal}" + msg_info "Updating LXC OS + Grafana" + apk update &>/dev/null + apk upgrade &>/dev/null + msg_ok "Update Successfull" + + break + ;; + 2) + clear + echo -e "${fgred}Updating Grafana Config with IP: ${LXCIP}${normal}" + msg_info "Stopping Grafana" + service grafana stop &>/dev/null + sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=0.0.0.0/g" /etc/conf.d/grafana + msg_ok "Restarted Grafana" + service grafana start &>/dev/null + + break + ;; + 3) + clear + echo -e "${fgred}Updating Grafana Config with host IP: ${LXCIP}${normal}" + msg_info "Stopping Grafana" + service grafana stop &>/dev/null + sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=$LXCIP/g" /etc/conf.d/grafana + msg_ok "Restarted Grafana" + service grafana start &>/dev/null + + break + ;; + x) + clear + echo -e "⚠ User exited script \n" + exit + ;; + \n) + clear + echo -e "⚠ User exited script \n" + exit + ;; + *) + clear + echo -e "Please choose an option from the menu" + update_script + ;; + esac +done + + exit } From df68e1fa781511ffa83c269a50254ce004be4c20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 13:49:00 -0400 Subject: [PATCH 4486/6505] Update alpine-grafana-v5.sh fix timezone --- ct/alpine-grafana-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh index 6766e031..d9abeb4f 100644 --- a/ct/alpine-grafana-v5.sh +++ b/ct/alpine-grafana-v5.sh @@ -338,6 +338,7 @@ function install_script() { ARCH_CHECK PVE_CHECK NEXTID=$(pvesh get /cluster/nextid) +timezone=$(cat /etc/timezone) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info From 0647dc67a13398ecb355429961b7102d482bea50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 13:49:59 -0400 Subject: [PATCH 4487/6505] Update alpine-zigbee2mqtt-v5.sh --- ct/alpine-zigbee2mqtt-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-zigbee2mqtt-v5.sh b/ct/alpine-zigbee2mqtt-v5.sh index 329c3fe7..ed80ad45 100644 --- a/ct/alpine-zigbee2mqtt-v5.sh +++ b/ct/alpine-zigbee2mqtt-v5.sh @@ -338,6 +338,7 @@ function install_script() { ARCH_CHECK PVE_CHECK NEXTID=$(pvesh get /cluster/nextid) +timezone=$(cat /etc/timezone) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info From cab8db92bbf27c7da6ce1756d1a51a0466752a14 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 13:50:21 -0400 Subject: [PATCH 4488/6505] Update alpine-vaultwarden-v5.sh --- ct/alpine-vaultwarden-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh index f9aa6c81..731adbc7 100644 --- a/ct/alpine-vaultwarden-v5.sh +++ b/ct/alpine-vaultwarden-v5.sh @@ -338,6 +338,7 @@ function install_script() { ARCH_CHECK PVE_CHECK NEXTID=$(pvesh get /cluster/nextid) +timezone=$(cat /etc/timezone) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info From 79e7f7b38cf99636139c0ea291a36333d832240d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 13:50:45 -0400 Subject: [PATCH 4489/6505] Update alpine-docker-v5.sh --- ct/alpine-docker-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-docker-v5.sh b/ct/alpine-docker-v5.sh index 5d92c547..b220ed08 100644 --- a/ct/alpine-docker-v5.sh +++ b/ct/alpine-docker-v5.sh @@ -338,6 +338,7 @@ function install_script() { ARCH_CHECK PVE_CHECK NEXTID=$(pvesh get /cluster/nextid) +timezone=$(cat /etc/timezone) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info From 754dec41fc960c46acc38faa38b4c97ea0a78044 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 13:51:09 -0400 Subject: [PATCH 4490/6505] Update alpine-adguard-v5.sh --- ct/alpine-adguard-v5.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-adguard-v5.sh b/ct/alpine-adguard-v5.sh index ce03722e..4ed5ea19 100644 --- a/ct/alpine-adguard-v5.sh +++ b/ct/alpine-adguard-v5.sh @@ -338,6 +338,7 @@ function install_script() { ARCH_CHECK PVE_CHECK NEXTID=$(pvesh get /cluster/nextid) +timezone=$(cat /etc/timezone) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info From 6fccc26c9fdf745498354c47faf1a79ddf6bf5bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 18:53:39 -0400 Subject: [PATCH 4491/6505] Update nginxproxymanager-v5-install.sh add certbot-dns-cloudflare --- install/nginxproxymanager-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index d66e0adf..b33ddb02 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -113,7 +113,7 @@ $STD python3 -m venv /opt/certbot/ if [ "$(getconf LONG_BIT)" = "32" ]; then $STD python3 -m pip install --no-cache-dir -U cryptography==3.3.2 fi -$STD python3 -m pip install --no-cache-dir cffi certbot +$STD python3 -m pip install --no-cache-dir cffi certbot certbot-dns-cloudflare msg_ok "Installed Python" msg_info "Installing Openresty" From c43dcea48ed2e9e45a5a698bac954b8258e995fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Mar 2023 19:11:13 -0400 Subject: [PATCH 4492/6505] Update nginxproxymanager-v5-install.sh revert add certbot-dns-cloudflare --- install/nginxproxymanager-v5-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-v5-install.sh index b33ddb02..d66e0adf 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-v5-install.sh @@ -113,7 +113,7 @@ $STD python3 -m venv /opt/certbot/ if [ "$(getconf LONG_BIT)" = "32" ]; then $STD python3 -m pip install --no-cache-dir -U cryptography==3.3.2 fi -$STD python3 -m pip install --no-cache-dir cffi certbot certbot-dns-cloudflare +$STD python3 -m pip install --no-cache-dir cffi certbot msg_ok "Installed Python" msg_info "Installing Openresty" From 92596e895583b475d1724ee5550bd01e6bc92693 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Mar 2023 15:48:20 -0400 Subject: [PATCH 4493/6505] Update sabnzbd-v5.sh create update --- ct/sabnzbd-v5.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh index a0f77356..0f3aab85 100644 --- a/ct/sabnzbd-v5.sh +++ b/ct/sabnzbd-v5.sh @@ -353,10 +353,16 @@ header_info function update_script() { header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +msg_info "Updating $APP" +systemctl stop sabnzbd.service +RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) &>/dev/null +\cp -r SABnzbd-${RELEASE}/* /opt/sabnzbd &>/dev/null +rm -rf SABnzbd-${RELEASE} +cd /opt/sabnzbd +python3 -m pip install -r requirements.txt &>/dev/null +systemctl start sabnzbd.service +msg_ok "Updated $APP" exit } @@ -375,7 +381,7 @@ if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/sabnzbd ]]; then fi if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP}. Proceed?" 10 58); then clear echo -e "⚠ User exited script \n" exit From 4175b8d5f6766b26bd7f1863d2a1ef1bd2d6bcfe Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Mar 2023 20:48:20 -0400 Subject: [PATCH 4494/6505] The latest iteration of the scripts (#1220) --- ct/adguard-v5.sh | 444 ------------- ct/adguard.sh | 87 +++ ct/alpine-adguard-v5.sh | 486 --------------- ct/alpine-adguard.sh | 87 +++ ct/alpine-docker-v5.sh | 465 -------------- ct/alpine-docker.sh | 77 +++ ct/alpine-grafana-v5.sh | 482 -------------- ct/alpine-grafana.sh | 94 +++ ct/alpine-v5.sh | 419 ------------- ct/alpine-vaultwarden-v5.sh | 456 -------------- ct/alpine-vaultwarden.sh | 87 +++ ct/alpine-zigbee2mqtt-v5.sh | 460 -------------- ct/alpine-zigbee2mqtt.sh | 79 +++ ct/alpine.sh | 70 +++ ct/{archlinux-v5.sh => archlinux.sh} | 3 +- ct/audiobookshelf-v5.sh | 421 ------------- ct/audiobookshelf.sh | 69 +++ ct/autobrr-v5.sh | 437 ------------- ct/autobrr.sh | 80 +++ ct/blocky-v5.sh | 425 ------------- ct/blocky.sh | 67 ++ ct/casaos-v5.sh | 453 -------------- ct/casaos.sh | 70 +++ ct/changedetection-v5.sh | 426 ------------- ct/changedetection.sh | 69 +++ ct/cronicle-v5.sh | 468 -------------- ct/cronicle.sh | 108 ++++ ct/daemonsync-v5.sh | 427 ------------- ct/daemonsync.sh | 69 +++ ct/dashy-v5.sh | 452 -------------- ct/dashy.sh | 95 +++ ct/debian-v5.sh | 419 ------------- ct/debian.sh | 67 ++ ct/deconz-v5.sh | 442 ------------- ct/deconz.sh | 69 +++ ct/deluge-v5.sh | 427 ------------- ct/deluge.sh | 70 +++ ct/devuan-v5.sh | 419 ------------- ct/devuan.sh | 67 ++ ct/docker-v5.sh | 446 ------------- ct/docker.sh | 68 ++ ct/emby-v5.sh | 460 -------------- ct/emby.sh | 80 +++ ct/emqx-v5.sh | 421 ------------- ct/emqx.sh | 69 +++ ct/esphome-v5.sh | 434 ------------- ct/esphome.sh | 77 +++ ct/go2rtc-v5.sh | 421 ------------- ct/go2rtc.sh | 70 +++ ct/grafana-v5.sh | 427 ------------- ct/grafana.sh | 70 +++ ct/grocy-v5.sh | 426 ------------- ct/grocy.sh | 69 +++ ct/heimdalldashboard-v5.sh | 506 --------------- ct/heimdalldashboard.sh | 149 +++++ ct/homeassistant-core-v5.sh | 586 ------------------ ct/homeassistant-core.sh | 216 +++++++ ct/homeassistant-v5.sh | 520 ---------------- ct/homeassistant.sh | 138 +++++ ct/homebridge-v5.sh | 427 ------------- ct/homebridge.sh | 70 +++ ct/homepage-v5.sh | 433 ------------- ct/homepage.sh | 76 +++ ct/homer-v5.sh | 450 -------------- ct/homer.sh | 93 +++ ct/hyperion-v5.sh | 441 ------------- ct/hyperion.sh | 71 +++ ct/influxdb-v5.sh | 425 ------------- ct/influxdb.sh | 68 ++ ct/iobroker-v5.sh | 427 ------------- ct/iobroker.sh | 70 +++ ct/jackett-v5.sh | 425 ------------- ct/jackett.sh | 69 +++ ct/jellyfin-v5.sh | 450 -------------- ct/jellyfin.sh | 70 +++ ct/k0s-v5.sh | 425 ------------- ct/k0s.sh | 68 ++ ct/kavita-v5.sh | 426 ------------- ct/kavita.sh | 69 +++ ct/keycloak-v5.sh | 428 ------------- ct/keycloak.sh | 71 +++ ct/lidarr-v5.sh | 426 ------------- ct/lidarr.sh | 69 +++ ct/magicmirror-v5.sh | 429 ------------- ct/magicmirror.sh | 72 +++ ct/mariadb-v5.sh | 425 ------------- ct/mariadb.sh | 68 ++ ct/meshcentral-v5.sh | 427 ------------- ct/meshcentral.sh | 70 +++ ct/motioneye-v5.sh | 426 ------------- ct/motioneye.sh | 69 +++ ct/mqtt-v5.sh | 424 ------------- ct/mqtt.sh | 68 ++ ct/n8n-v5.sh | 427 ------------- ct/n8n.sh | 70 +++ ct/navidrome-v5.sh | 437 ------------- ct/navidrome.sh | 80 +++ ct/nextcloudpi-v5.sh | 427 ------------- ct/nextcloudpi.sh | 70 +++ ct/nginxproxymanager-v5.sh | 535 ---------------- ct/nginxproxymanager.sh | 180 ++++++ ct/nocodb-v5.sh | 429 ------------- ct/nocodb.sh | 72 +++ ct/node-red-v5.sh | 462 -------------- ct/node-red.sh | 105 ++++ ct/omada-v5.sh | 439 ------------- ct/omada.sh | 70 +++ ct/omv-v5.sh | 438 ------------- ct/omv.sh | 70 +++ ct/openhab-v5.sh | 428 ------------- ct/openhab.sh | 71 +++ ct/paperless-ngx-v5.sh | 495 --------------- ct/paperless-ngx.sh | 142 +++++ ct/photoprism-v5.sh | 452 -------------- ct/photoprism.sh | 99 +++ ct/pihole-v5.sh | 427 ------------- ct/pihole.sh | 71 +++ ct/plex-v5.sh | 460 -------------- ct/plex.sh | 81 +++ ct/podman-homeassistant-v5.sh | 497 --------------- ct/podman-homeassistant.sh | 121 ++++ ct/podman-v5.sh | 425 ------------- ct/podman.sh | 69 +++ ct/postgresql-v5.sh | 425 ------------- ct/postgresql.sh | 69 +++ ct/prometheus-v5.sh | 427 ------------- ct/prometheus.sh | 71 +++ ct/prowlarr-v5.sh | 426 ------------- ct/prowlarr.sh | 70 +++ ct/qbittorrent-v5.sh | 426 ------------- ct/qbittorrent.sh | 70 +++ ct/radarr-v5.sh | 426 ------------- ct/radarr.sh | 70 +++ ct/readarr-v5.sh | 426 ------------- ct/readarr.sh | 70 +++ ct/rockylinux-v5.sh | 400 ------------ ct/rockylinux.sh | 69 +++ ct/rstptoweb-v5.sh | 420 ------------- ct/rstptoweb.sh | 69 +++ ct/sabnzbd-v5.sh | 432 ------------- ct/sabnzbd.sh | 76 +++ ct/scrypted-v5.sh | 442 ------------- ct/scrypted.sh | 72 +++ ct/shinobi-v5.sh | 441 ------------- ct/shinobi.sh | 74 +++ ct/sonarr-v5.sh | 426 ------------- ct/sonarr.sh | 70 +++ ct/syncthing-v5.sh | 428 ------------- ct/syncthing.sh | 72 +++ ct/tdarr-v5.sh | 426 ------------- ct/tdarr.sh | 70 +++ ct/technitiumdns-v5.sh | 436 ------------- ct/technitiumdns.sh | 80 +++ ct/transmission-v5.sh | 426 ------------- ct/transmission.sh | 70 +++ ct/trilium-v5.sh | 446 ------------- ct/trilium.sh | 90 +++ ct/ubuntu-v5.sh | 431 ------------- ct/ubuntu.sh | 68 ++ ct/umbrel-v5.sh | 452 -------------- ct/umbrel.sh | 70 +++ ct/unifi-v5.sh | 427 ------------- ct/unifi.sh | 71 +++ ct/uptimekuma-v5.sh | 444 ------------- ct/uptimekuma.sh | 88 +++ ct/vaultwarden-v5.sh | 498 --------------- ct/vaultwarden.sh | 145 +++++ ct/whisparr-v5.sh | 427 ------------- ct/whisparr.sh | 71 +++ ct/whoogle-v5.sh | 426 ------------- ct/whoogle.sh | 70 +++ ct/wikijs-v5.sh | 449 -------------- ct/wikijs.sh | 93 +++ ct/wireguard-v5.sh | 479 -------------- ct/wireguard.sh | 123 ++++ ct/yunohost-v5.sh | 426 ------------- ct/yunohost.sh | 70 +++ ct/zigbee2mqtt-v5.sh | 486 --------------- ct/zigbee2mqtt.sh | 134 ++++ ct/zwave-js-ui-v5.sh | 455 -------------- ct/zwave-js-ui.sh | 87 +++ install/adguard-install.sh | 37 ++ install/adguard-v5-install.sh | 125 ---- install/alpine-adguard-install.sh | 35 ++ install/alpine-adguard-v5-install.sh | 123 ---- install/alpine-docker-install.sh | 61 ++ install/alpine-docker-v5-install.sh | 150 ----- install/alpine-grafana-install.sh | 31 + install/alpine-grafana-v5-install.sh | 118 ---- install/alpine-vaultwarden-install.sh | 38 ++ install/alpine-vaultwarden-v5-install.sh | 126 ---- install/alpine-zigbee2mqtt-install.sh | 28 + install/alpine-zigbee2mqtt-v5-install.sh | 117 ---- install/audiobookshelf-install.sh | 36 ++ install/audiobookshelf-v5-install.sh | 123 ---- install/autobrr-install.sh | 57 ++ install/autobrr-v5-install.sh | 144 ----- ...blocky-v5-install.sh => blocky-install.sh} | 105 +--- install/casaos-install.sh | 45 ++ install/casaos-v5-install.sh | 133 ---- install/changedetection-install.sh | 50 ++ install/changedetection-v5-install.sh | 137 ---- install/cronicle-install.sh | 56 ++ install/cronicle-v5-install.sh | 143 ----- install/daemonsync-install.sh | 35 ++ install/daemonsync-v5-install.sh | 123 ---- install/dashy-install.sh | 65 ++ install/dashy-v5-install.sh | 153 ----- install/debian-install.sh | 28 + install/debian-v5-install.sh | 115 ---- install/deconz-install.sh | 58 ++ install/deconz-v5-install.sh | 146 ----- install/deluge-install.sh | 73 +++ install/deluge-v5-install.sh | 160 ----- install/devuan-install.sh | 28 + install/devuan-v5-install.sh | 98 --- install/docker-install.sh | 77 +++ install/docker-v5-install.sh | 165 ----- install/emby-install.sh | 52 ++ install/emby-v5-install.sh | 140 ----- install/emqx-install.sh | 34 + install/emqx-v5-install.sh | 121 ---- install/esphome-install.sh | 54 ++ install/esphome-v5-install.sh | 142 ----- install/go2rtc-install.sh | 51 ++ install/go2rtc-v5-install.sh | 138 ----- install/grafana-install.sh | 41 ++ install/grafana-v5-install.sh | 131 ---- install/grocy-install.sh | 72 +++ install/grocy-v5-install.sh | 160 ----- install/heimdalldashboard-install.sh | 65 ++ install/heimdalldashboard-v5-install.sh | 153 ----- install/homeassistant-core-install.sh | 107 ++++ install/homeassistant-core-v5-install.sh | 195 ------ install/homeassistant-install.sh | 92 +++ install/homeassistant-v5-install.sh | 180 ------ install/homebridge-install.sh | 44 ++ install/homebridge-v5-install.sh | 132 ---- install/homepage-install.sh | 65 ++ install/homepage-v5-install.sh | 152 ----- install/homer-install.sh | 54 ++ install/homer-v5-install.sh | 141 ----- install/hyperion-install.sh | 39 ++ install/hyperion-v5-install.sh | 126 ---- install/influxdb-install.sh | 61 ++ install/influxdb-v5-install.sh | 149 ----- install/iobroker-install.sh | 32 + install/iobroker-v5-install.sh | 120 ---- install/jackett-install.sh | 54 ++ install/jackett-v5-install.sh | 141 ----- install/jellyfin-install.sh | 76 +++ install/jellyfin-v5-install.sh | 164 ----- install/k0s-install.sh | 43 ++ install/k0s-v5-install.sh | 130 ---- install/kavita-install.sh | 54 ++ install/kavita-v5-install.sh | 142 ----- install/keycloak-install.sh | 51 ++ install/keycloak-v5-install.sh | 139 ----- install/lidarr-install.sh | 60 ++ install/lidarr-v5-install.sh | 147 ----- ...r-v5-install.sh => magicmirror-install.sh} | 106 +--- install/mariadb-install.sh | 43 ++ install/mariadb-v5-install.sh | 131 ---- install/meshcentral-install.sh | 43 ++ install/meshcentral-v5-install.sh | 131 ---- install/motioneye-install.sh | 62 ++ install/motioneye-v5-install.sh | 150 ----- install/mqtt-install.sh | 39 ++ install/mqtt-v5-install.sh | 127 ---- install/n8n-install.sh | 54 ++ install/n8n-v5-install.sh | 142 ----- install/navidrome-install.sh | 84 +++ install/navidrome-v5-install.sh | 171 ----- install/nextcloudpi-install.sh | 35 ++ install/nextcloudpi-v5-install.sh | 122 ---- ...nstall.sh => nginxproxymanager-install.sh} | 106 +--- install/nocodb-install.sh | 61 ++ install/nocodb-v5-install.sh | 149 ----- install/node-red-install.sh | 64 ++ install/node-red-v5-install.sh | 152 ----- install/omada-install.sh | 39 ++ install/omada-v5-install.sh | 127 ---- install/omv-install.sh | 50 ++ install/omv-v5-install.sh | 138 ----- install/openhab-install.sh | 49 ++ install/openhab-v5-install.sh | 137 ---- ...v5-install.sh => paperless-ngx-install.sh} | 107 +--- ...sm-v5-install.sh => photoprism-install.sh} | 106 +--- install/pihole-install.sh | 54 ++ install/pihole-v5-install.sh | 143 ----- install/plex-install.sh | 55 ++ install/plex-v5-install.sh | 143 ----- install/podman-homeassistant-install.sh | 54 ++ install/podman-homeassistant-v5-install.sh | 142 ----- install/podman-install.sh | 34 + install/podman-v5-install.sh | 121 ---- ...ql-v5-install.sh => postgresql-install.sh} | 109 +--- install/prometheus-install.sh | 64 ++ install/prometheus-v5-install.sh | 152 ----- install/prowlarr-install.sh | 58 ++ install/prowlarr-v5-install.sh | 145 ----- install/qbittorrent-install.sh | 46 ++ install/qbittorrent-v5-install.sh | 133 ---- install/radarr-install.sh | 58 ++ install/radarr-v5-install.sh | 145 ----- install/readarr-install.sh | 58 ++ install/readarr-v5-install.sh | 145 ----- install/rstptoweb-install.sh | 61 ++ install/rstptoweb-v5-install.sh | 148 ----- install/sabnzbd-install.sh | 62 ++ install/sabnzbd-v5-install.sh | 149 ----- install/scrypted-install.sh | 117 ++++ install/scrypted-v5-install.sh | 203 ------ install/shinobi-install.sh | 90 +++ install/shinobi-v5-install.sh | 178 ------ install/sonarr-install.sh | 37 ++ install/sonarr-v5-install.sh | 125 ---- install/syncthing-install.sh | 41 ++ install/syncthing-v5-install.sh | 128 ---- install/tdarr-install.sh | 85 +++ install/tdarr-v5-install.sh | 172 ----- install/technitiumdns-install.sh | 43 ++ install/technitiumdns-v5-install.sh | 131 ---- install/transmission-install.sh | 36 ++ install/transmission-v5-install.sh | 123 ---- install/trilium-install.sh | 59 ++ install/trilium-v5-install.sh | 146 ----- install/ubuntu-install.sh | 28 + install/ubuntu-v5-install.sh | 116 ---- install/umbrel-install.sh | 46 ++ install/umbrel-v5-install.sh | 133 ---- install/unifi-install.sh | 40 ++ install/unifi-v5-install.sh | 129 ---- install/uptimekuma-install.sh | 61 ++ install/uptimekuma-v5-install.sh | 149 ----- ...n-v5-install.sh => vaultwarden-install.sh} | 106 +--- install/whisparr-install.sh | 58 ++ install/whisparr-v5-install.sh | 145 ----- install/whoogle-install.sh | 50 ++ install/whoogle-v5-install.sh | 138 ----- install/wikijs-install.sh | 78 +++ install/wikijs-v5-install.sh | 166 ----- install/wireguard-install.sh | 49 ++ install/wireguard-v5-install.sh | 138 ----- install/yunohost-install.sh | 38 ++ install/yunohost-v5-install.sh | 125 ---- install/zigbee2mqtt-install.sh | 77 +++ install/zigbee2mqtt-v5-install.sh | 165 ----- install/zwave-js-ui-install.sh | 54 ++ install/zwave-js-ui-v5-install.sh | 142 ----- misc/alpine-install.func | 116 ++++ misc/alpine.func | 400 ++++++++++++ misc/debian.func | 403 ++++++++++++ misc/docker.func | 409 ++++++++++++ misc/install.func | 133 ++++ misc/ubuntu.func | 428 +++++++++++++ vm/haos-vm-v5.sh | 323 +++++----- ...ik-routeros-v5.sh => mikrotik-routeros.sh} | 273 ++++---- vm/{pimox-haos-vm-v5.sh => pimox-haos-vm.sh} | 315 +++++----- 359 files changed, 14171 insertions(+), 52404 deletions(-) delete mode 100644 ct/adguard-v5.sh create mode 100644 ct/adguard.sh delete mode 100644 ct/alpine-adguard-v5.sh create mode 100644 ct/alpine-adguard.sh delete mode 100644 ct/alpine-docker-v5.sh create mode 100644 ct/alpine-docker.sh delete mode 100644 ct/alpine-grafana-v5.sh create mode 100644 ct/alpine-grafana.sh delete mode 100644 ct/alpine-v5.sh delete mode 100644 ct/alpine-vaultwarden-v5.sh create mode 100644 ct/alpine-vaultwarden.sh delete mode 100644 ct/alpine-zigbee2mqtt-v5.sh create mode 100644 ct/alpine-zigbee2mqtt.sh create mode 100644 ct/alpine.sh rename ct/{archlinux-v5.sh => archlinux.sh} (99%) delete mode 100644 ct/audiobookshelf-v5.sh create mode 100644 ct/audiobookshelf.sh delete mode 100644 ct/autobrr-v5.sh create mode 100644 ct/autobrr.sh delete mode 100644 ct/blocky-v5.sh create mode 100644 ct/blocky.sh delete mode 100644 ct/casaos-v5.sh create mode 100644 ct/casaos.sh delete mode 100644 ct/changedetection-v5.sh create mode 100644 ct/changedetection.sh delete mode 100644 ct/cronicle-v5.sh create mode 100644 ct/cronicle.sh delete mode 100644 ct/daemonsync-v5.sh create mode 100644 ct/daemonsync.sh delete mode 100644 ct/dashy-v5.sh create mode 100644 ct/dashy.sh delete mode 100644 ct/debian-v5.sh create mode 100644 ct/debian.sh delete mode 100644 ct/deconz-v5.sh create mode 100644 ct/deconz.sh delete mode 100644 ct/deluge-v5.sh create mode 100644 ct/deluge.sh delete mode 100644 ct/devuan-v5.sh create mode 100644 ct/devuan.sh delete mode 100644 ct/docker-v5.sh create mode 100644 ct/docker.sh delete mode 100644 ct/emby-v5.sh create mode 100644 ct/emby.sh delete mode 100644 ct/emqx-v5.sh create mode 100644 ct/emqx.sh delete mode 100644 ct/esphome-v5.sh create mode 100644 ct/esphome.sh delete mode 100644 ct/go2rtc-v5.sh create mode 100644 ct/go2rtc.sh delete mode 100644 ct/grafana-v5.sh create mode 100644 ct/grafana.sh delete mode 100644 ct/grocy-v5.sh create mode 100644 ct/grocy.sh delete mode 100644 ct/heimdalldashboard-v5.sh create mode 100644 ct/heimdalldashboard.sh delete mode 100644 ct/homeassistant-core-v5.sh create mode 100644 ct/homeassistant-core.sh delete mode 100644 ct/homeassistant-v5.sh create mode 100644 ct/homeassistant.sh delete mode 100644 ct/homebridge-v5.sh create mode 100644 ct/homebridge.sh delete mode 100644 ct/homepage-v5.sh create mode 100644 ct/homepage.sh delete mode 100644 ct/homer-v5.sh create mode 100644 ct/homer.sh delete mode 100644 ct/hyperion-v5.sh create mode 100644 ct/hyperion.sh delete mode 100644 ct/influxdb-v5.sh create mode 100644 ct/influxdb.sh delete mode 100644 ct/iobroker-v5.sh create mode 100644 ct/iobroker.sh delete mode 100644 ct/jackett-v5.sh create mode 100644 ct/jackett.sh delete mode 100644 ct/jellyfin-v5.sh create mode 100644 ct/jellyfin.sh delete mode 100644 ct/k0s-v5.sh create mode 100644 ct/k0s.sh delete mode 100644 ct/kavita-v5.sh create mode 100644 ct/kavita.sh delete mode 100644 ct/keycloak-v5.sh create mode 100644 ct/keycloak.sh delete mode 100644 ct/lidarr-v5.sh create mode 100644 ct/lidarr.sh delete mode 100644 ct/magicmirror-v5.sh create mode 100644 ct/magicmirror.sh delete mode 100644 ct/mariadb-v5.sh create mode 100644 ct/mariadb.sh delete mode 100644 ct/meshcentral-v5.sh create mode 100644 ct/meshcentral.sh delete mode 100644 ct/motioneye-v5.sh create mode 100644 ct/motioneye.sh delete mode 100644 ct/mqtt-v5.sh create mode 100644 ct/mqtt.sh delete mode 100644 ct/n8n-v5.sh create mode 100644 ct/n8n.sh delete mode 100644 ct/navidrome-v5.sh create mode 100644 ct/navidrome.sh delete mode 100644 ct/nextcloudpi-v5.sh create mode 100644 ct/nextcloudpi.sh delete mode 100644 ct/nginxproxymanager-v5.sh create mode 100644 ct/nginxproxymanager.sh delete mode 100644 ct/nocodb-v5.sh create mode 100644 ct/nocodb.sh delete mode 100644 ct/node-red-v5.sh create mode 100644 ct/node-red.sh delete mode 100644 ct/omada-v5.sh create mode 100644 ct/omada.sh delete mode 100644 ct/omv-v5.sh create mode 100644 ct/omv.sh delete mode 100644 ct/openhab-v5.sh create mode 100644 ct/openhab.sh delete mode 100644 ct/paperless-ngx-v5.sh create mode 100644 ct/paperless-ngx.sh delete mode 100644 ct/photoprism-v5.sh create mode 100644 ct/photoprism.sh delete mode 100644 ct/pihole-v5.sh create mode 100644 ct/pihole.sh delete mode 100644 ct/plex-v5.sh create mode 100644 ct/plex.sh delete mode 100644 ct/podman-homeassistant-v5.sh create mode 100644 ct/podman-homeassistant.sh delete mode 100644 ct/podman-v5.sh create mode 100644 ct/podman.sh delete mode 100644 ct/postgresql-v5.sh create mode 100644 ct/postgresql.sh delete mode 100644 ct/prometheus-v5.sh create mode 100644 ct/prometheus.sh delete mode 100644 ct/prowlarr-v5.sh create mode 100644 ct/prowlarr.sh delete mode 100644 ct/qbittorrent-v5.sh create mode 100644 ct/qbittorrent.sh delete mode 100644 ct/radarr-v5.sh create mode 100644 ct/radarr.sh delete mode 100644 ct/readarr-v5.sh create mode 100644 ct/readarr.sh delete mode 100644 ct/rockylinux-v5.sh create mode 100644 ct/rockylinux.sh delete mode 100644 ct/rstptoweb-v5.sh create mode 100644 ct/rstptoweb.sh delete mode 100644 ct/sabnzbd-v5.sh create mode 100644 ct/sabnzbd.sh delete mode 100644 ct/scrypted-v5.sh create mode 100644 ct/scrypted.sh delete mode 100644 ct/shinobi-v5.sh create mode 100644 ct/shinobi.sh delete mode 100644 ct/sonarr-v5.sh create mode 100644 ct/sonarr.sh delete mode 100644 ct/syncthing-v5.sh create mode 100644 ct/syncthing.sh delete mode 100644 ct/tdarr-v5.sh create mode 100644 ct/tdarr.sh delete mode 100644 ct/technitiumdns-v5.sh create mode 100644 ct/technitiumdns.sh delete mode 100644 ct/transmission-v5.sh create mode 100644 ct/transmission.sh delete mode 100644 ct/trilium-v5.sh create mode 100644 ct/trilium.sh delete mode 100644 ct/ubuntu-v5.sh create mode 100644 ct/ubuntu.sh delete mode 100644 ct/umbrel-v5.sh create mode 100644 ct/umbrel.sh delete mode 100644 ct/unifi-v5.sh create mode 100644 ct/unifi.sh delete mode 100644 ct/uptimekuma-v5.sh create mode 100644 ct/uptimekuma.sh delete mode 100644 ct/vaultwarden-v5.sh create mode 100644 ct/vaultwarden.sh delete mode 100644 ct/whisparr-v5.sh create mode 100644 ct/whisparr.sh delete mode 100644 ct/whoogle-v5.sh create mode 100644 ct/whoogle.sh delete mode 100644 ct/wikijs-v5.sh create mode 100644 ct/wikijs.sh delete mode 100644 ct/wireguard-v5.sh create mode 100644 ct/wireguard.sh delete mode 100644 ct/yunohost-v5.sh create mode 100644 ct/yunohost.sh delete mode 100644 ct/zigbee2mqtt-v5.sh create mode 100644 ct/zigbee2mqtt.sh delete mode 100644 ct/zwave-js-ui-v5.sh create mode 100644 ct/zwave-js-ui.sh create mode 100644 install/adguard-install.sh delete mode 100644 install/adguard-v5-install.sh create mode 100644 install/alpine-adguard-install.sh delete mode 100644 install/alpine-adguard-v5-install.sh create mode 100644 install/alpine-docker-install.sh delete mode 100644 install/alpine-docker-v5-install.sh create mode 100644 install/alpine-grafana-install.sh delete mode 100644 install/alpine-grafana-v5-install.sh create mode 100644 install/alpine-vaultwarden-install.sh delete mode 100644 install/alpine-vaultwarden-v5-install.sh create mode 100644 install/alpine-zigbee2mqtt-install.sh delete mode 100644 install/alpine-zigbee2mqtt-v5-install.sh create mode 100644 install/audiobookshelf-install.sh delete mode 100644 install/audiobookshelf-v5-install.sh create mode 100644 install/autobrr-install.sh delete mode 100644 install/autobrr-v5-install.sh rename install/{blocky-v5-install.sh => blocky-install.sh} (79%) create mode 100644 install/casaos-install.sh delete mode 100644 install/casaos-v5-install.sh create mode 100644 install/changedetection-install.sh delete mode 100644 install/changedetection-v5-install.sh create mode 100644 install/cronicle-install.sh delete mode 100644 install/cronicle-v5-install.sh create mode 100644 install/daemonsync-install.sh delete mode 100644 install/daemonsync-v5-install.sh create mode 100644 install/dashy-install.sh delete mode 100644 install/dashy-v5-install.sh create mode 100644 install/debian-install.sh delete mode 100644 install/debian-v5-install.sh create mode 100644 install/deconz-install.sh delete mode 100644 install/deconz-v5-install.sh create mode 100644 install/deluge-install.sh delete mode 100644 install/deluge-v5-install.sh create mode 100644 install/devuan-install.sh delete mode 100644 install/devuan-v5-install.sh create mode 100644 install/docker-install.sh delete mode 100644 install/docker-v5-install.sh create mode 100644 install/emby-install.sh delete mode 100644 install/emby-v5-install.sh create mode 100644 install/emqx-install.sh delete mode 100644 install/emqx-v5-install.sh create mode 100644 install/esphome-install.sh delete mode 100644 install/esphome-v5-install.sh create mode 100644 install/go2rtc-install.sh delete mode 100644 install/go2rtc-v5-install.sh create mode 100644 install/grafana-install.sh delete mode 100644 install/grafana-v5-install.sh create mode 100644 install/grocy-install.sh delete mode 100644 install/grocy-v5-install.sh create mode 100644 install/heimdalldashboard-install.sh delete mode 100644 install/heimdalldashboard-v5-install.sh create mode 100644 install/homeassistant-core-install.sh delete mode 100644 install/homeassistant-core-v5-install.sh create mode 100644 install/homeassistant-install.sh delete mode 100644 install/homeassistant-v5-install.sh create mode 100644 install/homebridge-install.sh delete mode 100644 install/homebridge-v5-install.sh create mode 100644 install/homepage-install.sh delete mode 100644 install/homepage-v5-install.sh create mode 100644 install/homer-install.sh delete mode 100644 install/homer-v5-install.sh create mode 100644 install/hyperion-install.sh delete mode 100644 install/hyperion-v5-install.sh create mode 100644 install/influxdb-install.sh delete mode 100644 install/influxdb-v5-install.sh create mode 100644 install/iobroker-install.sh delete mode 100644 install/iobroker-v5-install.sh create mode 100644 install/jackett-install.sh delete mode 100644 install/jackett-v5-install.sh create mode 100644 install/jellyfin-install.sh delete mode 100644 install/jellyfin-v5-install.sh create mode 100644 install/k0s-install.sh delete mode 100644 install/k0s-v5-install.sh create mode 100644 install/kavita-install.sh delete mode 100644 install/kavita-v5-install.sh create mode 100644 install/keycloak-install.sh delete mode 100644 install/keycloak-v5-install.sh create mode 100644 install/lidarr-install.sh delete mode 100644 install/lidarr-v5-install.sh rename install/{magicmirror-v5-install.sh => magicmirror-install.sh} (61%) create mode 100644 install/mariadb-install.sh delete mode 100644 install/mariadb-v5-install.sh create mode 100644 install/meshcentral-install.sh delete mode 100644 install/meshcentral-v5-install.sh create mode 100644 install/motioneye-install.sh delete mode 100644 install/motioneye-v5-install.sh create mode 100644 install/mqtt-install.sh delete mode 100644 install/mqtt-v5-install.sh create mode 100644 install/n8n-install.sh delete mode 100644 install/n8n-v5-install.sh create mode 100644 install/navidrome-install.sh delete mode 100644 install/navidrome-v5-install.sh create mode 100644 install/nextcloudpi-install.sh delete mode 100644 install/nextcloudpi-v5-install.sh rename install/{nginxproxymanager-v5-install.sh => nginxproxymanager-install.sh} (62%) create mode 100644 install/nocodb-install.sh delete mode 100644 install/nocodb-v5-install.sh create mode 100644 install/node-red-install.sh delete mode 100644 install/node-red-v5-install.sh create mode 100644 install/omada-install.sh delete mode 100644 install/omada-v5-install.sh create mode 100644 install/omv-install.sh delete mode 100644 install/omv-v5-install.sh create mode 100644 install/openhab-install.sh delete mode 100644 install/openhab-v5-install.sh rename install/{paperless-ngx-v5-install.sh => paperless-ngx-install.sh} (64%) rename install/{photoprism-v5-install.sh => photoprism-install.sh} (53%) create mode 100644 install/pihole-install.sh delete mode 100644 install/pihole-v5-install.sh create mode 100644 install/plex-install.sh delete mode 100644 install/plex-v5-install.sh create mode 100644 install/podman-homeassistant-install.sh delete mode 100644 install/podman-homeassistant-v5-install.sh create mode 100644 install/podman-install.sh delete mode 100644 install/podman-v5-install.sh rename install/{postgresql-v5-install.sh => postgresql-install.sh} (60%) create mode 100644 install/prometheus-install.sh delete mode 100644 install/prometheus-v5-install.sh create mode 100644 install/prowlarr-install.sh delete mode 100644 install/prowlarr-v5-install.sh create mode 100644 install/qbittorrent-install.sh delete mode 100644 install/qbittorrent-v5-install.sh create mode 100644 install/radarr-install.sh delete mode 100644 install/radarr-v5-install.sh create mode 100644 install/readarr-install.sh delete mode 100644 install/readarr-v5-install.sh create mode 100644 install/rstptoweb-install.sh delete mode 100644 install/rstptoweb-v5-install.sh create mode 100644 install/sabnzbd-install.sh delete mode 100644 install/sabnzbd-v5-install.sh create mode 100644 install/scrypted-install.sh delete mode 100644 install/scrypted-v5-install.sh create mode 100644 install/shinobi-install.sh delete mode 100644 install/shinobi-v5-install.sh create mode 100644 install/sonarr-install.sh delete mode 100644 install/sonarr-v5-install.sh create mode 100644 install/syncthing-install.sh delete mode 100644 install/syncthing-v5-install.sh create mode 100644 install/tdarr-install.sh delete mode 100644 install/tdarr-v5-install.sh create mode 100644 install/technitiumdns-install.sh delete mode 100644 install/technitiumdns-v5-install.sh create mode 100644 install/transmission-install.sh delete mode 100644 install/transmission-v5-install.sh create mode 100644 install/trilium-install.sh delete mode 100644 install/trilium-v5-install.sh create mode 100644 install/ubuntu-install.sh delete mode 100644 install/ubuntu-v5-install.sh create mode 100644 install/umbrel-install.sh delete mode 100644 install/umbrel-v5-install.sh create mode 100644 install/unifi-install.sh delete mode 100644 install/unifi-v5-install.sh create mode 100644 install/uptimekuma-install.sh delete mode 100644 install/uptimekuma-v5-install.sh rename install/{vaultwarden-v5-install.sh => vaultwarden-install.sh} (50%) create mode 100644 install/whisparr-install.sh delete mode 100644 install/whisparr-v5-install.sh create mode 100644 install/whoogle-install.sh delete mode 100644 install/whoogle-v5-install.sh create mode 100644 install/wikijs-install.sh delete mode 100644 install/wikijs-v5-install.sh create mode 100644 install/wireguard-install.sh delete mode 100644 install/wireguard-v5-install.sh create mode 100644 install/yunohost-install.sh delete mode 100644 install/yunohost-v5-install.sh create mode 100644 install/zigbee2mqtt-install.sh delete mode 100644 install/zigbee2mqtt-v5-install.sh create mode 100644 install/zwave-js-ui-install.sh delete mode 100644 install/zwave-js-ui-v5-install.sh create mode 100644 misc/alpine-install.func create mode 100644 misc/alpine.func create mode 100644 misc/debian.func create mode 100644 misc/docker.func create mode 100644 misc/install.func create mode 100644 misc/ubuntu.func rename vm/{mikrotik-routeros-v5.sh => mikrotik-routeros.sh} (51%) rename vm/{pimox-haos-vm-v5.sh => pimox-haos-vm.sh} (50%) diff --git a/ct/adguard-v5.sh b/ct/adguard-v5.sh deleted file mode 100644 index 73a5eb9c..00000000 --- a/ct/adguard-v5.sh +++ /dev/null @@ -1,444 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ___ __ __ - / | ____/ /___ ___v5______ __________/ / - / /| |/ __ / __ / / / / __ / ___/ __ / - / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / -/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ - /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Adguard" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Stopping AdguardHome" -systemctl stop AdGuardHome -msg_ok "Stopped AdguardHome" - -msg_info "Updating AdguardHome" -wget -qL https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz -tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null -mkdir -p adguard-backup -cp -r /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ -cp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome -cp -r adguard-backup/* /opt/AdGuardHome/ -msg_ok "Updated AdguardHome" - -msg_info "Starting AdguardHome" -systemctl start AdGuardHome -msg_ok "Started AdguardHome" - -msg_info "Cleaning Up" -rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup -msg_ok "Cleaned" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/AdGuardHome ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/adguard.sh b/ct/adguard.sh new file mode 100644 index 00000000..682fc877 --- /dev/null +++ b/ct/adguard.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ __ + / | ____/ /___ ___ ______ __________/ / + / /| |/ __ / __ / / / / __ / ___/ __ / + / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / +/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Adguard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/AdGuardHome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping AdguardHome" +systemctl stop AdGuardHome +msg_ok "Stopped AdguardHome" + +msg_info "Updating AdguardHome" +wget -qL https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz +tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null +mkdir -p adguard-backup +cp -r /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ +cp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome +cp -r adguard-backup/* /opt/AdGuardHome/ +msg_ok "Updated AdguardHome" + +msg_info "Starting AdguardHome" +systemctl start AdGuardHome +msg_ok "Started AdguardHome" + +msg_info "Cleaning Up" +rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup +msg_ok "Cleaned" +msg_ok "Update Successfull" +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}:3000${CL} \n" diff --git a/ct/alpine-adguard-v5.sh b/ct/alpine-adguard-v5.sh deleted file mode 100644 index 4ed5ea19..00000000 --- a/ct/alpine-adguard-v5.sh +++ /dev/null @@ -1,486 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ___ __ __ - / | ____/ /___ ___v5______ __________/ / - / /| |/ __ / __ / / / / __ / ___/ __ / - / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / -/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ - /____/ Alpine - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-AdGuard" -var_disk="0.3" -var_cpu="1" -var_ram="256" -var_os="alpine" -var_version="3.17" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" - PW="-password alpine" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -timezone=$(cat /etc/timezone) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - header_info - normal=$(echo "\033[m") - menu=$(echo "\033[36m") - number=$(echo "\033[33m") - fgred=$(echo "\033[31m") - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Update LXC OS \n" - printf "${menu}**${number} 2)${normal} Update AdGuardHome\n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." - read opt - -while [ "$opt" != "" ]; do - case $opt in - 1) - clear - echo -e "${fgred}Update LXC OS${normal}" - msg_info "Updating LXC OS" - apk update &>/dev/null - apk upgrade &>/dev/null - msg_ok "Update Successfull" - - break - ;; - 2) - clear - echo -e "${fgred}Update AdGuardHome${normal}" - msg_info "Stopping AdguardHome" - /opt/AdGuardHome/AdGuardHome -s stop &>/dev/null - msg_ok "Stopped AdguardHome" - - VER=$(curl -sqI https://github.com/AdguardTeam/AdGuardHome/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); - msg_info "Updating AdguardHome to $VER" - wget -q "https://github.com/AdguardTeam/AdGuardHome/releases/download/$VER/AdGuardHome_linux_amd64.tar.gz" - tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null - mkdir -p adguard-backup - cp -rf /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ - cp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome - cp -r adguard-backup/* /opt/AdGuardHome/ - msg_ok "Updated AdguardHome" - - msg_info "Starting AdguardHome" - /opt/AdGuardHome/AdGuardHome -s start &>/dev/null - msg_ok "Started AdguardHome" - - msg_info "Cleaning Up" - rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup - msg_ok "Cleaned" - msg_ok "Update Successfull" - - break - ;; - x) - clear - echo -e "⚠ User exited script \n" - exit - ;; - \n) - clear - echo -e "⚠ User exited script \n" - exit - ;; - *) - clear - echo -e "Please choose an option from the menu" - update_script - ;; - esac -done - - -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /opt/AdGuardHome ]]; then - msg_error "No ${APP} Installation Found!" - else - update_script - fi -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh new file mode 100644 index 00000000..4604fbcb --- /dev/null +++ b/ct/alpine-adguard.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ___ __ __ + / | ____/ /___ ___ ______ __________/ / + / /| |/ __ / __ / / / / __ / ___/ __ / + / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / +/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ + /____/ Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-AdGuard" +var_disk="0.3" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="-password alpine" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ + "1" "Update LXC OS" \ + "2" "Manually Update AdGuardHome" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + apk update && apk upgrade + exit + ;; + 2) + header_info + echo "In the process of creating a method to update" + exit + ;; + esac + done +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/alpine-docker-v5.sh b/ct/alpine-docker-v5.sh deleted file mode 100644 index b220ed08..00000000 --- a/ct/alpine-docker-v5.sh +++ /dev/null @@ -1,465 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ____ __ - / __ \____ _____/ /_v5__ _____ - / / / / __ \/ ___/ //_/ _ \/ ___/ - / /_/ / /_/ / /__/ ,< / __/ / -/_____/\____/\___/_/|_|\___/_/ - Alpine - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-Docker" -var_disk="2" -var_cpu="1" -var_ram="1024" -var_os="alpine" -var_version="3.17" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" - PW="-password alpine" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" On \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -timezone=$(cat /etc/timezone) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - header_info - normal=$(echo "\033[m") - menu=$(echo "\033[36m") - number=$(echo "\033[33m") - fgred=$(echo "\033[31m") - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Update ${APP} \n" - printf "\n${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." - read opt - -while [ "$opt" != "" ]; do - case $opt in - 1) - clear - echo -e "${fgred}Update ${APP}${normal}" - apk update &>/dev/null - apk upgrade &>/dev/null - - break - ;; - x) - exit - ;; - \n) - exit - ;; - *) - clear - echo -e "Please choose an option from the menu" - update_script - ;; - esac -done -exit -} -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -d /etc/docker ]]; then - msg_error "No ${APP} Installation Found!" - else - update_script - fi -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh new file mode 100644 index 00000000..21bd2144 --- /dev/null +++ b/ct/alpine-docker.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ____ __ + / __ \____ _____/ /_ __ _____ + / / / / __ \/ ___/ //_/ _ \/ ___/ + / /_/ / /_/ / /__/ ,< / __/ / +/_____/\____/\___/_/|_|\___/_/ + Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Docker" +var_disk="2" +var_cpu="1" +var_ram="1024" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="-password alpine" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ + "1" "Check for Docker Updates" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + apk update && apk upgrade + exit + ;; + esac +done + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/alpine-grafana-v5.sh b/ct/alpine-grafana-v5.sh deleted file mode 100644 index d9abeb4f..00000000 --- a/ct/alpine-grafana-v5.sh +++ /dev/null @@ -1,482 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ______ ____ - / ____/________ _/ __/___ _____v5____ _ - / / __/ ___/ __ / /_/ __ / __ \/ __ / -/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / -\____/_/ \__,_/_/ \__,_/_/ /_/\__,_/ - Alpine - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-Grafana" -var_disk="0.5" -var_cpu="1" -var_ram="256" -var_os="alpine" -var_version="3.17" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" - PW="-password alpine" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -timezone=$(cat /etc/timezone) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - header_info - normal=$(echo "\033[m") - menu=$(echo "\033[36m") - number=$(echo "\033[33m") - fgred=$(echo "\033[31m") - LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Update LXC OS + Grafana \n" - printf "${menu}**${number} 2)${normal} Allow 0.0.0.0 for listening \n" - printf "${menu}**${number} 3)${normal} Allow only ${LXCIP} for listening \n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." - read opt - -while [ "$opt" != "" ]; do - case $opt in - 1) - clear - echo -e "${fgred}Update LXC OS${normal}" - msg_info "Updating LXC OS + Grafana" - apk update &>/dev/null - apk upgrade &>/dev/null - msg_ok "Update Successfull" - - break - ;; - 2) - clear - echo -e "${fgred}Updating Grafana Config with IP: ${LXCIP}${normal}" - msg_info "Stopping Grafana" - service grafana stop &>/dev/null - sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=0.0.0.0/g" /etc/conf.d/grafana - msg_ok "Restarted Grafana" - service grafana start &>/dev/null - - break - ;; - 3) - clear - echo -e "${fgred}Updating Grafana Config with host IP: ${LXCIP}${normal}" - msg_info "Stopping Grafana" - service grafana stop &>/dev/null - sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=$LXCIP/g" /etc/conf.d/grafana - msg_ok "Restarted Grafana" - service grafana start &>/dev/null - - break - ;; - x) - clear - echo -e "⚠ User exited script \n" - exit - ;; - \n) - clear - echo -e "⚠ User exited script \n" - exit - ;; - *) - clear - echo -e "Please choose an option from the menu" - update_script - ;; - esac -done - - -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/conf.d/grafana ]]; then - msg_error "No ${APP} Installation Found!" - else - update_script - fi -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh new file mode 100644 index 00000000..4dd13bda --- /dev/null +++ b/ct/alpine-grafana.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ______ ____ + / ____/________ _/ __/___ _____ ____ _ + / / __/ ___/ __ / /_/ __ / __ \/ __ / +/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / +\____/_/ \__,_/_/ \__,_/_/ /_/\__,_/ + Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Grafana" +var_disk="0.5" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="-password alpine" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" --cancel-button Exit-Script 11 58 3 \ + "1" "Check for Grafana Updates" \ + "2" "Allow 0.0.0.0 for listening" \ + "3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + apk update && apk upgrade + exit + ;; + 2) + sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=0.0.0.0/g" /etc/conf.d/grafana + service grafana restart + exit + ;; + 3) + sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=$LXCIP/g" /etc/conf.d/grafana + service grafana restart + exit + ;; + esac + done +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/alpine-v5.sh b/ct/alpine-v5.sh deleted file mode 100644 index 6357beb8..00000000 --- a/ct/alpine-v5.sh +++ /dev/null @@ -1,419 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ___ v5 __ _ - / | / /___ (_)___ ___ - / /| | / / __ \/ / __ \/ _ \ - / ___ |/ / /_/ / / / / / __/ -/_/ |_/_/ .___/_/_/ /_/\___/ - /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine" -var_disk="0.1" -var_cpu="1" -var_ram="512" -var_os="alpine" -var_version="3.17" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" - PW="-password alpine" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apk update &>/dev/null -apk upgrade &>/dev/null -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/alpine-vaultwarden-v5.sh b/ct/alpine-vaultwarden-v5.sh deleted file mode 100644 index 731adbc7..00000000 --- a/ct/alpine-vaultwarden-v5.sh +++ /dev/null @@ -1,456 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - _ __ ____ __ -| | / /___ ___ __/ / /__ ______ __________/ /__v5____ -| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ -| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / -|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ - Alpine - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-Vaultwarden" -var_disk="0.3" -var_cpu="1" -var_ram="256" -var_os="alpine" -var_version="3.17" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" - PW="-password alpine" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -timezone=$(cat /etc/timezone) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - header_info - normal=$(echo "\033[m") - menu=$(echo "\033[36m") - number=$(echo "\033[33m") - fgred=$(echo "\033[31m") - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Update Vaultwarden \n" - printf "${menu}**${number} 2)${normal} View Admin Token\n" - printf "\n${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." - read opt - -while [ "$opt" != "" ]; do - case $opt in - 1) - clear - echo -e "${fgred}Update Vaultwarden${normal}" - apk update &>/dev/null - apk upgrade &>/dev/null - - break - ;; - 2) - clear - echo -e "${fgred}View the Admin Token${normal}" - cat /etc/conf.d/vaultwarden | grep "ADMIN_TOKEN" | awk '{print substr($2, 7) }' - - break - ;; - x) - exit - ;; - \n) - exit - ;; - *) - clear - echo -e "Please choose an option from the menu" - update_script - ;; - esac -done -exit -} -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/conf.d/vaultwarden ]]; then - msg_error "No ${APP} Installation Found!" - else - update_script - fi -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh new file mode 100644 index 00000000..0f6c9930 --- /dev/null +++ b/ct/alpine-vaultwarden.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + _ __ ____ __ +| | / /___ ___ __/ / /__ ______ __________/ /__ ____ +| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ +| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / +|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ + Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Vaultwarden" +var_disk="0.3" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="-password alpine" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ + "1" "Update VaultWarden" \ + "2" "Show Admin Token" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + apk update && apk upgrade + exit + ;; + 2) + whiptail --title "ADMIN TOKEN" --msgbox "$(cat /etc/conf.d/vaultwarden | grep ADMIN_TOKEN | awk '{print substr($2, 13) }')" 7 68 + clear + exit + ;; + esac + done +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/alpine-zigbee2mqtt-v5.sh b/ct/alpine-zigbee2mqtt-v5.sh deleted file mode 100644 index ed80ad45..00000000 --- a/ct/alpine-zigbee2mqtt-v5.sh +++ /dev/null @@ -1,460 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - _____ _ __ ___ __ _______ ____________ -/__ / (_)___ _/ /_ ___v5___ |__ \ / |/ / __ \/_ __/_ __/ - / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / - / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / -/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ - /____/ Alpine - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-Zigbee2MQTT" -var_disk="0.3" -var_cpu="1" -var_ram="256" -var_os="alpine" -var_version="3.17" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" - PW="-password alpine" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -timezone=$(cat /etc/timezone) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - header_info - normal=$(echo "\033[m") - menu=$(echo "\033[36m") - number=$(echo "\033[33m") - fgred=$(echo "\033[31m") - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Update ${APP} \n" - printf "\n${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." - read opt - -while [ "$opt" != "" ]; do - case $opt in - 1) - clear - echo -e "${fgred}Update ${APP}${normal}" - apk update &>/dev/null - apk upgrade &>/dev/null - - break - ;; - x) - exit - ;; - \n) - exit - ;; - *) - clear - echo -e "Please choose an option from the menu" - update_script - ;; - esac -done -exit -} -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if [[ ! -f /etc/zigbee2mqtt/configuration.yaml ]]; then - msg_error "No ${APP} Installation Found!" - else - update_script - fi -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- ash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh new file mode 100644 index 00000000..28bcaf3b --- /dev/null +++ b/ct/alpine-zigbee2mqtt.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + _____ _ __ ___ __ _______ ____________ +/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ + / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / + / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / +/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ + /____/ Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Zigbee2MQTT" +var_disk="0.3" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="-password alpine" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ + "1" "Check for Zigbee2MQTT Updates" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + apk update && apk upgrade + exit + ;; + esac + done +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/alpine.sh b/ct/alpine.sh new file mode 100644 index 00000000..19074a97 --- /dev/null +++ b/ct/alpine.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ _ + / | / /___ (_)___ ___ + / /| | / / __ \/ / __ \/ _ \ + / ___ |/ / /_/ / / / / / __/ +/_/ |_/_/ .___/_/_/ /_/\___/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine" +var_disk="0.1" +var_cpu="1" +var_ram="512" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="-password alpine" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 1 \ + "1" "Check for Alpine Updates" ON \ + 3>&1 1>&2 2>&3) + +header_info +if [ "$UPD" == "1" ]; then +apk update && apk upgrade +exit; +fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/archlinux-v5.sh b/ct/archlinux.sh similarity index 99% rename from ct/archlinux-v5.sh rename to ct/archlinux.sh index 26385a0a..62f04bb3 100644 --- a/ct/archlinux-v5.sh +++ b/ct/archlinux.sh @@ -8,9 +8,8 @@ function header_info { clear cat <<"EOF" - ___ __ __ _ - / | __________/ /_ v5 / / (_)___ __ ___ __ + / | __________/ /_ / / (_)___ __ ___ __ / /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ / ___ |/ / / /__/ / / / / /___/ / / / / /_/ /> < /_/ |_/_/ \___/_/ /_/ /_____/_/_/ /_/\__,_/_/|_| diff --git a/ct/audiobookshelf-v5.sh b/ct/audiobookshelf-v5.sh deleted file mode 100644 index ca4e5c9b..00000000 --- a/ct/audiobookshelf-v5.sh +++ /dev/null @@ -1,421 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ___ __ __ __ ______ - ____ ___ ______/ (_)___v5/ /_ ____ ____ / /_______/ /_ ___ / / __/ - / __ `/ / / / __ / / __ \/ __ \/ __ \/ __ \/ //_/ ___/ __ \/ _ \/ / /_ -/ /_/ / /_/ / /_/ / / /_/ / /_/ / /_/ / /_/ / ,< (__ ) / / / __/ / __/ -\__,_/\__,_/\__,_/_/\____/_.___/\____/\____/_/|_/____/_/ /_/\___/_/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="audiobookshelf" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:13378${CL} \n" diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh new file mode 100644 index 00000000..7e1de964 --- /dev/null +++ b/ct/audiobookshelf.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ __ __ ______ + ____ ___ ______/ (_)___ / /_ ____ ____ / /_______/ /_ ___ / / __/ + / __ `/ / / / __ / / __ \/ __ \/ __ \/ __ \/ //_/ ___/ __ \/ _ \/ / /_ +/ /_/ / /_/ / /_/ / / /_/ / /_/ / /_/ / /_/ / ,< (__ ) / / / __/ / __/ +\__,_/\__,_/\__,_/_/\____/_.___/\____/\____/_/|_/____/_/ /_/\___/_/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="audiobookshelf" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:13378${CL} \n" diff --git a/ct/autobrr-v5.sh b/ct/autobrr-v5.sh deleted file mode 100644 index b0ad08cc..00000000 --- a/ct/autobrr-v5.sh +++ /dev/null @@ -1,437 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ___ __ __ - / | __ __/ /_____ / /_v5__________ - / /| |/ / / / __/ __ \/ __ \/ ___/ ___/ - / ___ / /_/ / /_/ /_/ / /_/ / / / / -/_/ |_\__,_/\__/\____/_.___/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Autobrr" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Stopping ${APP} LXC" -systemctl stop autobrr.service -msg_ok "Stopped ${APP} LXC" - -msg_info "Updating ${APP} LXC" -rm -rf /usr/local/bin/* -wget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\" -f4) -tar -C /usr/local/bin -xzf autobrr*.tar.gz -rm -rf autobrr*.tar.gz -msg_ok "Updated ${APP} LXC" - -msg_info "Starting ${APP} LXC" -systemctl start autobrr.service -msg_ok "Started ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /root/.config/autobrr/config.toml ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:7474${CL} \n" diff --git a/ct/autobrr.sh b/ct/autobrr.sh new file mode 100644 index 00000000..7571c138 --- /dev/null +++ b/ct/autobrr.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ __ + / | __ __/ /_____ / /_ __________ + / /| |/ / / / __/ __ \/ __ \/ ___/ ___/ + / ___ / /_/ / /_/ /_/ / /_/ / / / / +/_/ |_\__,_/\__/\____/_.___/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Autobrr" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /root/.config/autobrr/config.toml ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ${APP} LXC" +systemctl stop autobrr.service +msg_ok "Stopped ${APP} LXC" + +msg_info "Updating ${APP} LXC" +rm -rf /usr/local/bin/* +wget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\" -f4) +tar -C /usr/local/bin -xzf autobrr*.tar.gz +rm -rf autobrr*.tar.gz +msg_ok "Updated ${APP} LXC" + +msg_info "Starting ${APP} LXC" +systemctl start autobrr.service +msg_ok "Started ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7474${CL} \n" diff --git a/ct/blocky-v5.sh b/ct/blocky-v5.sh deleted file mode 100644 index 64b905d2..00000000 --- a/ct/blocky-v5.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ __ - / __ )/ /___v5_____/ /____ __ - / __ / / __ \/ ___/ //_/ / / / - / /_/ / / /_/ / /__/ ,< / /_/ / -/_____/_/\____/\___/_/|_|\__, / - /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Blocky" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/blocky ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/blocky.sh b/ct/blocky.sh new file mode 100644 index 00000000..cfa21ed8 --- /dev/null +++ b/ct/blocky.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ __ + / __ )/ /___ _____/ /____ __ + / __ / / __ \/ ___/ //_/ / / / + / /_/ / / /_/ / /__/ ,< / /_/ / +/_____/_/\____/\___/_/|_|\__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Blocky" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/casaos-v5.sh b/ct/casaos-v5.sh deleted file mode 100644 index 7c00c6b3..00000000 --- a/ct/casaos-v5.sh +++ /dev/null @@ -1,453 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ ____ _____ - / ____/___ __v5______ _/ __ \/ ___/ - / / / __ `/ ___/ __ `/ / / /\__ \ -/ /___/ /_/ (__ ) /_/ / /_/ /___/ / -\____/\__,_/____/\__,_/\____//____/ - -EOF -} -header_info -echo -e "Loading..." -APP="CasaOS" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - FUSE="yes" -else - FUSE="no" -fi - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/docker ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export ST=$FUSE -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$CT_TYPE" == "0" ]; then -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP} ${CL} \n" diff --git a/ct/casaos.sh b/ct/casaos.sh new file mode 100644 index 00000000..e7bcf8e2 --- /dev/null +++ b/ct/casaos.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/docker.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ ____ _____ + / ____/___ __________ _/ __ \/ ___/ + / / / __ `/ ___/ __ `/ / / /\__ \ +/ /___/ /_/ (__ ) /_/ / /_/ /___/ / +\____/\__,_/____/\__,_/\____//____/ + +EOF +} +header_info +echo -e "Loading..." +APP="CasaOS" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + FUSE="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +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} ${CL} \n" diff --git a/ct/changedetection-v5.sh b/ct/changedetection-v5.sh deleted file mode 100644 index 64899ce7..00000000 --- a/ct/changedetection-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ________ ____ __ __ _ - / ____/ /_v5____ _____ ____ ____ / __ \___ / /____ _____/ /_(_)___ ____ - / / / __ \/ __ `/ __ \/ __ `/ _ \ / / / / _ \/ __/ _ \/ ___/ __/ / __ \/ __ \ -/ /___/ / / / /_/ / / / / /_/ / __/ / /_/ / __/ /_/ __/ /__/ /_/ / /_/ / / / / -\____/_/ /_/\__,_/_/ /_/\__, /\___/ /_____/\___/\__/\___/\___/\__/_/\____/_/ /_/ - /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Change Detection" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -pip3 install changedetection.io --upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/changedetection.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/changedetection.sh b/ct/changedetection.sh new file mode 100644 index 00000000..3f94891c --- /dev/null +++ b/ct/changedetection.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ ____ __ __ _ + / ____/ /_ ____ _____ ____ ____ / __ \___ / /____ _____/ /_(_)___ ____ + / / / __ \/ __ `/ __ \/ __ `/ _ \ / / / / _ \/ __/ _ \/ ___/ __/ / __ \/ __ \ +/ /___/ / / / /_/ / / / / /_/ / __/ / /_/ / __/ /_/ __/ /__/ /_/ / /_/ / / / / +\____/_/ /_/\__,_/_/ /_/\__, /\___/ /_____/\___/\__/\___/\___/\__/_/\____/_/ /_/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Change Detection" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/changedetection.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +pip3 install changedetection.io --upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/cronicle-v5.sh b/ct/cronicle-v5.sh deleted file mode 100644 index 890b08cc..00000000 --- a/ct/cronicle-v5.sh +++ /dev/null @@ -1,468 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ _ __ - / ____/________v5____ (_)____/ /__ - / / / ___/ __ \/ __ \/ / ___/ / _ \ -/ /___/ / / /_/ / / / / / /__/ / __/ -\____/_/ \____/_/ /_/_/\___/_/\___/ - -EOF -} -header_info -echo -e "Loading..." -APP="Cronicle" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -hostname="$(hostname)" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info -SERVER="y" - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ - "1" "Update ${APP}" ON \ - "2" "Install ${APP} Worker" OFF \ - 3>&1 1>&2 2>&3) - -header_info -if [ "$UPD" == "1" ]; then - if [[ ! -d /opt/cronicle ]]; then - msg_error "No ${APP} Installation Found!"; - exit - fi -msg_info "Updating ${APP}" -/opt/cronicle/bin/control.sh upgrade &>/dev/null -msg_ok "Updated ${APP}" -exit -fi -if [ "$UPD" == "2" ]; then -LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -IP=$(hostname -I | awk '{print $1}') -msg_info "Installing Dependencies" - -apt-get install -y git &>/dev/null -apt-get install -y make &>/dev/null -apt-get install -y g++ &>/dev/null -apt-get install -y gcc &>/dev/null -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) &>/dev/null -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -apt-get install -y nodejs &>/dev/null -msg_ok "Installed Node.js" - -msg_info "Installing Cronicle Worker" -mkdir -p /opt/cronicle -cd /opt/cronicle -tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 &>/dev/null -npm install &>/dev/null -node bin/build.js dist &>/dev/null -sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json -/opt/cronicle/bin/control.sh start &>/dev/null -cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled &>/dev/null -chmod 775 /etc/init.d/cronicled -update-rc.d cronicled defaults &>/dev/null -msg_ok "Installed Cronicle Worker on $hostname" -echo -e "\n Add Masters secret key to /opt/cronicle/conf/config.json \n" -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export SERV=$SERVER -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Primary should be reachable by going to the following URL. - ${BL}http://${IP}:3012${CL} admin|admin \n" diff --git a/ct/cronicle.sh b/ct/cronicle.sh new file mode 100644 index 00000000..85019ee5 --- /dev/null +++ b/ct/cronicle.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ _ __ + / ____/________ ____ (_)____/ /__ + / / / ___/ __ \/ __ \/ / ___/ / _ \ +/ /___/ / / /_/ / / / / / /__/ / __/ +\____/_/ \____/_/ /_/_/\___/_/\___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Cronicle" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +if [[ ! -d /opt/cronicle ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + "1" "Update ${APP}" ON \ + "2" "Install ${APP} Worker" OFF \ + 3>&1 1>&2 2>&3) + +header_info +msg_info "Updating ${APP}" +/opt/cronicle/bin/control.sh upgrade &>/dev/null +msg_ok "Updated ${APP}" +exit +fi +if [ "$UPD" == "2" ]; then +LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +IP=$(hostname -I | awk '{print $1}') +msg_info "Installing Dependencies" + +apt-get install -y git &>/dev/null +apt-get install -y make &>/dev/null +apt-get install -y g++ &>/dev/null +apt-get install -y gcc &>/dev/null +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) &>/dev/null +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +apt-get install -y nodejs &>/dev/null +msg_ok "Installed Node.js" + +msg_info "Installing Cronicle Worker" +mkdir -p /opt/cronicle +cd /opt/cronicle +tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 &>/dev/null +npm install &>/dev/null +node bin/build.js dist &>/dev/null +sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json +/opt/cronicle/bin/control.sh start &>/dev/null +cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled &>/dev/null +chmod 775 /etc/init.d/cronicled +update-rc.d cronicled defaults &>/dev/null +msg_ok "Installed Cronicle Worker on $hostname" +echo -e "\n Add Masters secret key to /opt/cronicle/conf/config.json \n" +exit +fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} Primary should be reachable by going to the following URL. + ${BL}http://${IP}:3012${CL} admin|admin \n" diff --git a/ct/daemonsync-v5.sh b/ct/daemonsync-v5.sh deleted file mode 100644 index bb50f147..00000000 --- a/ct/daemonsync-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ _____ - / __ \____ ____ ____ ___ ____ ____ / ___/__v5______ _____ - / / / / __ / _ \/ __ __ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/ - / /_/ / /_/ / __/ / / / / / /_/ / / / / ___/ / /_/ / / / / /__ -/_____/\__,_/\___/_/ /_/ /_/\____/_/ /_/ /____/\__, /_/ /_/\___/ - /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Daemon Sync" -var_disk="8" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/daemonsync ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh new file mode 100644 index 00000000..5b0a2ee6 --- /dev/null +++ b/ct/daemonsync.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _____ + / __ \____ ____ ____ ___ ____ ____ / ___/__ ______ _____ + / / / / __ / _ \/ __ __ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/ + / /_/ / /_/ / __/ / / / / / /_/ / / / / ___/ / /_/ / / / / /__ +/_____/\__,_/\___/_/ /_/ /_/\____/_/ /_/ /____/\__, /_/ /_/\___/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Daemon Sync" +var_disk="8" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8084${CL} \n" diff --git a/ct/dashy-v5.sh b/ct/dashy-v5.sh deleted file mode 100644 index 0b63ea64..00000000 --- a/ct/dashy-v5.sh +++ /dev/null @@ -1,452 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \____ ______/ /_ __ __ - / / / / __ / ___/ __ \/ / / / - / /_/ / /_/ (__ ) / / / /_/ / -/_____/\__,_/____/_/ /_/\__, / - v5 /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Dashy" -var_disk="6" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Stopping ${APP}" -systemctl stop dashy -msg_ok "Stopped ${APP}" - -msg_info "Backing up conf.yml" -cd ~ -cp -R /dashy/public/conf.yml conf.yml -msg_ok "Backed up conf.yml" - -msg_info "Updating Dashy" -cd /dashy -git merge &>/dev/null -git pull origin master &>/dev/null -yarn &>/dev/null -yarn build &>/dev/null -msg_ok "Updated Dashy" - -msg_info "Restoring conf.yml" -cd ~ -cp -R conf.yml /dashy/public -msg_ok "Restored conf.yml" - -msg_info "Cleaning" -rm -rf conf.yml -msg_ok "Cleaned" - -msg_info "Starting Dashy" -systemctl start dashy -msg_ok "Started Dashy" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/dashy.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/dashy.sh b/ct/dashy.sh new file mode 100644 index 00000000..63338364 --- /dev/null +++ b/ct/dashy.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \____ ______/ /_ __ __ + / / / / __ / ___/ __ \/ / / / + / /_/ / /_/ (__ ) / / / /_/ / +/_____/\__,_/____/_/ /_/\__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Dashy" +var_disk="6" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /dashy/public/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ${APP}" +systemctl stop dashy +msg_ok "Stopped ${APP}" + +msg_info "Backing up conf.yml" +cd ~ +cp -R /dashy/public/conf.yml conf.yml +msg_ok "Backed up conf.yml" + +msg_info "Updating Dashy" +cd /dashy +git merge &>/dev/null +git pull origin master &>/dev/null +yarn &>/dev/null +yarn build &>/dev/null +msg_ok "Updated Dashy" + +msg_info "Restoring conf.yml" +cd ~ +cp -R conf.yml /dashy/public +msg_ok "Restored conf.yml" + +msg_info "Cleaning" +rm -rf conf.yml +msg_ok "Cleaned" + +msg_info "Starting Dashy" +systemctl start dashy +msg_ok "Started Dashy" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:4000${CL} \n" diff --git a/ct/debian-v5.sh b/ct/debian-v5.sh deleted file mode 100644 index b0c885f4..00000000 --- a/ct/debian-v5.sh +++ /dev/null @@ -1,419 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ _ - / __ \___v5/ /_ (_)___ _____ - / / / / _ \/ __ \/ / __ `/ __ \ - / /_/ / __/ /_/ / / /_/ / / / / -/_____/\___/_.___/_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Debian" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/debian.sh b/ct/debian.sh new file mode 100644 index 00000000..3ece2f2a --- /dev/null +++ b/ct/debian.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ _ + / __ \___ / /_ (_)___ _____ + / / / / _ \/ __ \/ / __ `/ __ \ + / /_/ / __/ /_/ / / /_/ / / / / +/_____/\___/_.___/_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Debian" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" \ No newline at end of file diff --git a/ct/deconz-v5.sh b/ct/deconz-v5.sh deleted file mode 100644 index cdeb7a75..00000000 --- a/ct/deconz-v5.sh +++ /dev/null @@ -1,442 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __________ _ _______ - ____/ /v5 / ____/ __ \/ | / /__ / - / __ / _ \/ / / / / / |/ / / / -/ /_/ / __/ /___/ /_/ / /| / / /__ -\__,_/\___/\____/\____/_/ |_/ /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="deCONZ" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/deconz.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL}\n" diff --git a/ct/deconz.sh b/ct/deconz.sh new file mode 100644 index 00000000..d43073f8 --- /dev/null +++ b/ct/deconz.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __________ _ _______ + ____/ /__ / ____/ __ \/ | / /__ / + / __ / _ \/ / / / / / |/ / / / +/ /_/ / __/ /___/ /_/ / /| / / /__ +\__,_/\___/\____/\____/_/ |_/ /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="deCONZ" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="ubuntu" +var_version="20.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/deconz.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL}\n" diff --git a/ct/deluge-v5.sh b/ct/deluge-v5.sh deleted file mode 100644 index 7d95aa64..00000000 --- a/ct/deluge-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \___ / /_v5______ ____ - / / / / _ \/ / / / / __ `/ _ \ - / /_/ / __/ / /_/ / /_/ / __/ -/_____/\___/_/\__,_/\__, /\___/ - /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Deluge" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -pip3 install deluge[all] --upgrade -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/deluged.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8112${CL} \n" diff --git a/ct/deluge.sh b/ct/deluge.sh new file mode 100644 index 00000000..da8ce1eb --- /dev/null +++ b/ct/deluge.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \___ / /_ ______ ____ + / / / / _ \/ / / / / __ `/ _ \ + / /_/ / __/ / /_/ / /_/ / __/ +/_____/\___/_/\__,_/\__, /\___/ + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Deluge" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/deluged.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +pip3 install deluge[all] --upgrade +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8112${CL} \n" diff --git a/ct/devuan-v5.sh b/ct/devuan-v5.sh deleted file mode 100644 index ac845530..00000000 --- a/ct/devuan-v5.sh +++ /dev/null @@ -1,419 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ - / __ \___ _ ____ ______v5____ - / / / / _ \ | / / / / / __ `/ __ \ - / /_/ / __/ |/ / /_/ / /_/ / / / / -/_____/\___/|___/\__,_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Devuan" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="devuan" -var_version="4.0" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}$NSAPP${CL}" - PW="-password $NSAPP" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/devuan.sh b/ct/devuan.sh new file mode 100644 index 00000000..6c51b605 --- /dev/null +++ b/ct/devuan.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ + / __ \___ _ ____ ______ ____ + / / / / _ \ | / / / / / __ `/ __ \ + / /_/ / __/ |/ / /_/ / /_/ / / / / +/_____/\___/|___/\__,_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Devuan" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="devuan" +var_version="4.0" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/docker-v5.sh b/ct/docker-v5.sh deleted file mode 100644 index 677398a0..00000000 --- a/ct/docker-v5.sh +++ /dev/null @@ -1,446 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \____ _____/ /_v5__ _____ - / / / / __ \/ ___/ //_/ _ \/ ___/ - / /_/ / /_/ / /__/ ,< / __/ / -/_____/\____/\___/_/|_|\___/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Docker" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - FUSE="yes" -else - FUSE="no" -fi - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export ST=$FUSE -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$CT_TYPE" == "0" ]; then -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/docker.sh b/ct/docker.sh new file mode 100644 index 00000000..37ca3808 --- /dev/null +++ b/ct/docker.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/docker.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \____ _____/ /_ __ _____ + / / / / __ \/ ___/ //_/ _ \/ ___/ + / /_/ / /_/ / /__/ ,< / __/ / +/_____/\____/\___/_/|_|\___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Docker" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + FUSE="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/emby-v5.sh b/ct/emby-v5.sh deleted file mode 100644 index d138f812..00000000 --- a/ct/emby-v5.sh +++ /dev/null @@ -1,460 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ __ - / ____/___ v5_ / /_ __ __ - / __/ / __ __ \/ __ \/ / / / - / /___/ / / / / / /_/ / /_/ / -/_____/_/ /_/ /_/_.___/\__, / - /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Emby" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit-script -fi -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -msg_info "Stopping ${APP}" -systemctl stop emby-server -msg_ok "Stopped ${APP}" - -msg_info "Updating ${APP}" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null -dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null -rm emby-server-deb_${LATEST}_amd64.deb -msg_ok "Updated ${APP}" - -msg_info "Starting ${APP}" -systemctl start emby-server -msg_ok "Started ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/emby-server ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/emby.sh b/ct/emby.sh new file mode 100644 index 00000000..dd296190 --- /dev/null +++ b/ct/emby.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ __ + / ____/___ ___ / /_ __ __ + / __/ / __ __ \/ __ \/ / / / + / /___/ / / / / / /_/ / /_/ / +/_____/_/ /_/ /_/_.___/\__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Emby" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/emby-server ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +msg_info "Stopping ${APP}" +systemctl stop emby-server +msg_ok "Stopped ${APP}" + +msg_info "Updating ${APP}" +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null +dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null +rm emby-server-deb_${LATEST}_amd64.deb +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +systemctl start emby-server +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/emqx-v5.sh b/ct/emqx-v5.sh deleted file mode 100644 index 45bbd9fa..00000000 --- a/ct/emqx-v5.sh +++ /dev/null @@ -1,421 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ________ _______v5 _ __ - / ____/ |/ / __ \ | |/ / - / __/ / /|_/ / / / / | / - / /___/ / / / /_/ / / | -/_____/_/ /_/\___\_\/_/|_| - -EOF -} -header_info -echo -e "Loading..." -APP="EMQX" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:18083${CL} \n" diff --git a/ct/emqx.sh b/ct/emqx.sh new file mode 100644 index 00000000..69afa53d --- /dev/null +++ b/ct/emqx.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ _______ _ __ + / ____/ |/ / __ \ | |/ / + / __/ / /|_/ / / / / | / + / /___/ / / / /_/ / / | +/_____/_/ /_/\___\_\/_/|_| + +EOF +} +header_info +echo -e "Loading..." +APP="EMQX" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +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}:18083${CL} \n" diff --git a/ct/esphome-v5.sh b/ct/esphome-v5.sh deleted file mode 100644 index 5cb1c4f2..00000000 --- a/ct/esphome-v5.sh +++ /dev/null @@ -1,434 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ___________ ____ __ __ - / ____/ ___// __ \/ / / /___v5____ ___ ___ - / __/ \__ \/ /_/ / /_/ / __ \/ __ `__ \/ _ \ - / /___ ___/ / ____/ __ / /_/ / / / / / / __/ -/_____//____/_/ /_/ /_/\____/_/ /_/ /_/\___/ - -EOF -} -header_info -echo -e "Loading..." -APP="ESPHome" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Stopping ESPHome" -systemctl stop esphomeDashboard -msg_ok "Stopped ESPHome" - -msg_info "Updating ESPHome" -pip3 install esphome --upgrade &>/dev/null -msg_ok "Updated ESPHome" - -msg_info "Starting ESPHome" -systemctl start esphomeDashboard -msg_ok "Started ESPHome" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /usr/local/bin/esphome ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/esphome.sh b/ct/esphome.sh new file mode 100644 index 00000000..1c25bd4f --- /dev/null +++ b/ct/esphome.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___________ ____ __ __ + / ____/ ___// __ \/ / / /___ ____ ___ ___ + / __/ \__ \/ /_/ / /_/ / __ \/ __ `__ \/ _ \ + / /___ ___/ / ____/ __ / /_/ / / / / / / __/ +/_____//____/_/ /_/ /_/\____/_/ /_/ /_/\___/ + +EOF +} +header_info +echo -e "Loading..." +APP="ESPHome" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /usr/local/bin/esphome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ESPHome" +systemctl stop esphomeDashboard +msg_ok "Stopped ESPHome" + +msg_info "Updating ESPHome" +pip3 install esphome --upgrade &>/dev/null +msg_ok "Updated ESPHome" + +msg_info "Starting ESPHome" +systemctl start esphomeDashboard +msg_ok "Started ESPHome" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6052${CL} \n" diff --git a/ct/go2rtc-v5.sh b/ct/go2rtc-v5.sh deleted file mode 100644 index cf95a685..00000000 --- a/ct/go2rtc-v5.sh +++ /dev/null @@ -1,421 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ___ __ - ____ _____ |__ \ _____/ /__v5__ - / __ `/ __ \__/ // ___/ __/ ___/ - / /_/ / /_/ / __// / / /_/ /__ - \__, /\____/____/_/ \__/\___/ -/____/ - -EOF -} -header_info -echo -e "Loading..." -APP="go2rtc" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:1984${CL} \n" diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh new file mode 100644 index 00000000..ebd1fade --- /dev/null +++ b/ct/go2rtc.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ + ____ _____ |__ \ _____/ /______ + / __ `/ __ \__/ // ___/ __/ ___/ + / /_/ / /_/ / __// / / /_/ /__ + \__, /\____/____/_/ \__/\___/ +/____/ + +EOF +} +header_info +echo -e "Loading..." +APP="go2rtc" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:1984${CL} \n" diff --git a/ct/grafana-v5.sh b/ct/grafana-v5.sh deleted file mode 100644 index 2984483f..00000000 --- a/ct/grafana-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ ____ - / ____/________ _/ __/___ _____v5____ _ - / / __/ ___/ __ / /_/ __ / __ \/ __ / -/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / -\____/_/ \__,_/_/ \__,_/_/ /_/\__,_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Grafana" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/grafana.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grafana.sh b/ct/grafana.sh new file mode 100644 index 00000000..f908c465 --- /dev/null +++ b/ct/grafana.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ ____ + / ____/________ _/ __/___ _____ ____ _ + / / __/ ___/ __ / /_/ __ / __ \/ __ / +/ /_/ / / / /_/ / __/ /_/ / / / / /_/ / +\____/_/ \__,_/_/ \__,_/_/ /_/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Grafana" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/grocy-v5.sh b/ct/grocy-v5.sh deleted file mode 100644 index ca85cf3f..00000000 --- a/ct/grocy-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __________ _______ __ - / __ / ___/ __ \/ ___/ / / / - / /_/ / / / /_/ / /__/ /_/ / - \__, /_/ v5\____/\___/\__, / -/____/ /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="grocy" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP}" -bash /var/www/html/update.sh -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/grocy.sh b/ct/grocy.sh new file mode 100644 index 00000000..bf7a05b8 --- /dev/null +++ b/ct/grocy.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __________ _______ __ + / __ / ___/ __ \/ ___/ / / / + / /_/ / / / /_/ / /__/ /_/ / + \__, /_/ \____/\___/\__, / +/____/ /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="grocy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +bash /var/www/html/update.sh +msg_ok "Updated ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" diff --git a/ct/heimdalldashboard-v5.sh b/ct/heimdalldashboard-v5.sh deleted file mode 100644 index 8853bb2b..00000000 --- a/ct/heimdalldashboard-v5.sh +++ /dev/null @@ -1,506 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ _ _ _ ___ _ _ _ - /\ /\___(_)_ __ ___ __| | __ _| | | / \__ _ ___| |__ | |__ ___ __ _ _ __ __| | - / /_/ / _ \ | '_ ` _ \ / _` |/ _` | | | / /\ / _` / __| '_ \| '_ \ / _ \ / _` | '__/ _` | -/ __ / __/ | | | | | | (_| | (_| | | |v5/ /_// (_| \__ \ | | | |_) | (_) | (_| | | | (_| | -\/ /_/ \___|_|_| |_| |_|\__,_|\__,_|_|_| /___,' \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| - -EOF -} -header_info -echo -e "Loading..." -APP="Heimdall Dashboard" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Stopping ${APP}" -systemctl disable heimdall.service &>/dev/null -systemctl stop heimdall -sleep 1 -msg_ok "Stopped ${APP}" - -msg_info "Backing up Data" -if [ -d "/opt/Heimdall-2.4.6" ]; then - cp -R /opt/Heimdall-2.4.6/database database-backup - cp -R /opt/Heimdall-2.4.6/public public-backup -elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then - cp -R /opt/Heimdall-2.4.7b/database database-backup - cp -R /opt/Heimdall-2.4.7b/public public-backup -elif [[ -d "/opt/Heimdall-2.4.8" ]]; then - cp -R /opt/Heimdall-2.4.8/database database-backup - cp -R /opt/Heimdall-2.4.8/public public-backup -else - cp -R /opt/Heimdall/database database-backup - cp -R /opt/Heimdall/public public-backup -fi -sleep 1 -msg_ok "Backed up Data" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -msg_info "Updating Heimdall Dashboard to ${RELEASE}" -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -if [ ! -d "/opt/Heimdall" ]; then - mv Heimdall-${VER} /opt/Heimdall -else - cp -R Heimdall-${VER}/* /opt/Heimdall -fi - -service_path="/etc/systemd/system/heimdall.service" -echo "[Unit] -Description=Heimdall -After=network.target -[Service] -Restart=always -RestartSec=5 -Type=simple -User=root -WorkingDirectory=/opt/Heimdall -ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 -TimeoutStopSec=30 -[Install] -WantedBy=multi-user.target" >$service_path -msg_ok "Updated Heimdall Dashboard to ${RELEASE}" - -msg_info "Restoring Data" -cp -R database-backup/* /opt/Heimdall/database -cp -R public-backup/* /opt/Heimdall/public -sleep 1 -msg_ok "Restored Data" - -msg_info "Cleanup" -if [ -d "/opt/Heimdall-2.4.6" ]; then - rm -rf /opt/Heimdall-2.4.6 - rm -rf /opt/v2.4.6.tar.gz -elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then - rm -rf /opt/Heimdall-2.4.7b - rm -rf /opt/v2.4.7b.tar.gz -elif [[ -d "/opt/Heimdall-2.4.8" ]]; then - rm -rf /opt/Heimdall-2.4.8 - rm -rf /opt/v2.4.8.tar.gz -fi - -rm -rf ${RELEASE}.tar.gz -rm -rf Heimdall-${VER} -rm -rf public-backup -rm -rf database-backup -rm -rf Heimdall -sleep 1 -msg_ok "Cleaned" - -msg_info "Starting ${APP}" -systemctl enable --now heimdall.service &>/dev/null -sleep 2 -msg_ok "Started ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/Heimdall ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh new file mode 100644 index 00000000..3a631eeb --- /dev/null +++ b/ct/heimdalldashboard.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ _ _ _ ___ _ _ _ + /\ /\___(_)_ __ ___ __| | __ _| | | / \__ _ ___| |__ | |__ ___ __ _ _ __ __| | + / /_/ / _ \ | '_ ` _ \ / _` |/ _` | | | / /\ / _` / __| '_ \| '_ \ / _ \ / _` | '__/ _` | +/ __ / __/ | | | | | | (_| | (_| | | | / /_// (_| \__ \ | | | |_) | (_) | (_| | | | (_| | +\/ /_/ \___|_|_| |_| |_|\__,_|\__,_|_|_| /___,' \__,_|___/_| |_|_.__/ \___/ \__,_|_| \__,_| + +EOF +} +header_info +echo -e "Loading..." +APP="Heimdall Dashboard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/Heimdall ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ${APP}" +systemctl disable heimdall.service &>/dev/null +systemctl stop heimdall +sleep 1 +msg_ok "Stopped ${APP}" + +msg_info "Backing up Data" +if [ -d "/opt/Heimdall-2.4.6" ]; then + cp -R /opt/Heimdall-2.4.6/database database-backup + cp -R /opt/Heimdall-2.4.6/public public-backup +elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then + cp -R /opt/Heimdall-2.4.7b/database database-backup + cp -R /opt/Heimdall-2.4.7b/public public-backup +elif [[ -d "/opt/Heimdall-2.4.8" ]]; then + cp -R /opt/Heimdall-2.4.8/database database-backup + cp -R /opt/Heimdall-2.4.8/public public-backup +else + cp -R /opt/Heimdall/database database-backup + cp -R /opt/Heimdall/public public-backup +fi +sleep 1 +msg_ok "Backed up Data" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +msg_info "Updating Heimdall Dashboard to ${RELEASE}" +curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null +tar xvzf ${RELEASE}.tar.gz &>/dev/null +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +if [ ! -d "/opt/Heimdall" ]; then + mv Heimdall-${VER} /opt/Heimdall +else + cp -R Heimdall-${VER}/* /opt/Heimdall +fi + +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 +[Install] +WantedBy=multi-user.target" >$service_path +msg_ok "Updated Heimdall Dashboard to ${RELEASE}" + +msg_info "Restoring Data" +cp -R database-backup/* /opt/Heimdall/database +cp -R public-backup/* /opt/Heimdall/public +sleep 1 +msg_ok "Restored Data" + +msg_info "Cleanup" +if [ -d "/opt/Heimdall-2.4.6" ]; then + rm -rf /opt/Heimdall-2.4.6 + rm -rf /opt/v2.4.6.tar.gz +elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then + rm -rf /opt/Heimdall-2.4.7b + rm -rf /opt/v2.4.7b.tar.gz +elif [[ -d "/opt/Heimdall-2.4.8" ]]; then + rm -rf /opt/Heimdall-2.4.8 + rm -rf /opt/v2.4.8.tar.gz +fi + +rm -rf ${RELEASE}.tar.gz +rm -rf Heimdall-${VER} +rm -rf public-backup +rm -rf database-backup +rm -rf Heimdall +sleep 1 +msg_ok "Cleaned" + +msg_info "Starting ${APP}" +systemctl enable --now heimdall.service &>/dev/null +sleep 2 +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7990${CL} \n" diff --git a/ct/homeassistant-core-v5.sh b/ct/homeassistant-core-v5.sh deleted file mode 100644 index cbb5aea1..00000000 --- a/ct/homeassistant-core-v5.sh +++ /dev/null @@ -1,586 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ _ _ _ ___ - /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___v5_ __ ___ - / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ -/ __ / (_) | | | | | | __/ / _ \__ \__ \ \__ \ || (_| | | | | |_ / /__| (_) | | | __/ -\/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| - -EOF -} -header_info -echo -e "Loading..." -APP="Home Assistant-Core" -var_disk="8" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') -BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "default" | awk '{print substr($2, 2, length($2)-3) }') -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - PY=$(ls /srv/homeassistant/lib/) - IP=$(hostname -I | awk '{print $1}') - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ - "1" "Update Core" ON \ - "2" "Install HACS" OFF \ - "3" "Install FileBrowser" OFF \ - "4" "Install/Update AppDaemon" OFF \ - 3>&1 1>&2 2>&3) -header_info -if [ "$UPD" == "1" ]; then - if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then - clear - header_info - echo -e "${GN}Updating to Version ${BETA}${CL}" - BR="--pre " - else - clear - header_info - echo -e "${GN}Updating to Version ${STABLE}${CL}" - BR="" - fi - if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi - -msg_info "Stopping Home Assistant" -systemctl stop homeassistant -msg_ok "Stopped Home Assistant" - -msg_info "Updating Home Assistant" -source /srv/homeassistant/bin/activate -pip install ${BR}--upgrade homeassistant &>/dev/null -msg_ok "Updated Home Assistant" - -msg_info "Starting Home Assistant" -systemctl start homeassistant -sleep 2 -msg_ok "Started Home Assistant" -msg_ok "Update Successful" -echo -e "\n Go to http://${IP}:8123 \n" -exit -fi -if [ "$UPD" == "2" ]; then -msg_info "Installing Home Assistant Comunity Store (HACS)" -apt update &>/dev/null -apt install unzip &>/dev/null -cd .homeassistant -bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null -msg_ok "Installed Home Assistant Comunity Store (HACS)" -echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" -exit -fi -if [ "$UPD" == "3" ]; then -msg_info "Installing FileBrowser" -curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null -filebrowser config init -a '0.0.0.0' &>/dev/null -filebrowser config set -a '0.0.0.0' &>/dev/null -filebrowser users add admin changeme --perm.admin &>/dev/null -msg_ok "Installed FileBrowser" - -msg_info "Creating Service" -service_path="/etc/systemd/system/filebrowser.service" -echo "[Unit] -Description=Filebrowser -After=network-online.target -[Service] -User=root -WorkingDirectory=/root/ -ExecStart=/usr/local/bin/filebrowser -r /root/.homeassistant -[Install] -WantedBy=default.target" >$service_path - -systemctl enable --now filebrowser.service &>/dev/null -msg_ok "Created Service" - -msg_ok "Completed Successfully!\n" -echo -e "FileBrowser should be reachable by going to the following URL. - ${BL}http://$IP:8080${CL} admin|changeme\n" -exit -fi -if [ "$UPD" == "4" ]; then - clear - header_info - if [[ ! -d /srv/appdaemon ]]; then - msg_info "Installing AppDaemon" - mkdir /srv/appdaemon - cd /srv/appdaemon - python3 -m venv . - source bin/activate - pip install appdaemon &>/dev/null - mkdir -p /root/.homeassistant/appdaemon/apps - cat > /root/.homeassistant/appdaemon/appdaemon.yaml << EOF -# Sample appdaemon.yml file -# For configuration, please visit: https://appdaemon.readthedocs.io/en/latest/CONFIGURE.html -appdaemon: - time_zone: CET - latitude: 51.725 - longitude: 14.3434 - elevation: 0 - plugins: - HASS: - type: hass - ha_url: - token: -http: - url: http://127.0.0.1:5050 -admin: -api: -EOF - msg_ok "Installed AppDaemon" - - msg_info "Creating Service" - cat > /etc/systemd/system/appdaemon.service << EOF -[Unit] -Description=AppDaemon -After=homeassistant.service -Requires=homeassistant.service -[Service] -Type=simple -WorkingDirectory=/root/.homeassistant/appdaemon -ExecStart=/srv/appdaemon/bin/appdaemon -c "/root/.homeassistant/appdaemon" -RestartForceExitStatus=100 -[Install] -WantedBy=multi-user.target -EOF - systemctl enable --now appdaemon &>/dev/null - msg_ok "Created Service" - - msg_ok "Completed Successfully!\n" - echo -e "AppDaemon should be reachable by going to the following URL. - ${BL}http://$IP:5050${CL}\n" - exit - else - msg_info "Upgrading AppDaemon" - msg_info "Stopping AppDaemon" - systemctl stop appdaemon - msg_ok "Stopped AppDaemon" - - msg_info "Updating AppDaemon" - source /srv/appdaemon/bin/activate - pip install --upgrade appdaemon &>/dev/null - msg_ok "Updated AppDaemon" - - msg_info "Starting AppDaemon" - systemctl start appdaemon - sleep 2 - msg_ok "Started AppDaemon" - msg_ok "Update Successful" - echo -e "\n Go to http://${IP}:5050 \n" - exit - fi -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /srv/homeassistant ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL}" diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh new file mode 100644 index 00000000..68cbf783 --- /dev/null +++ b/ct/homeassistant-core.sh @@ -0,0 +1,216 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + _ _ _ _ ___ + /\ /\___ _ __ ___ ___ /_\ ___ ___(_)___| |_ __ _ _ __ | |_ / __\___ _ __ ___ + / /_/ / _ \| '_ ` _ \ / _ \ //_\\/ __/ __| / __| __/ _` | '_ \| __| / / / _ \| '__/ _ \ +/ __ / (_) | | | | | | __/ / _ \__ \__ \ \__ \ || (_| | | | | |_ / /__| (_) | | | __/ +\/ /_/ \___/|_| |_| |_|\___| \_/ \_/___/___/_|___/\__\__,_|_| |_|\__| \____/\___/|_| \___| + +EOF +} +header_info +echo -e "Loading..." +APP="Home Assistant-Core" +var_disk="8" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -d /srv/homeassistant ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + PY=$(ls /srv/homeassistant/lib/) + IP=$(hostname -I | awk '{print $1}') + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + "1" "Update Core" ON \ + "2" "Install HACS" OFF \ + "3" "Install FileBrowser" OFF \ + "4" "Install/Update AppDaemon" OFF \ + 3>&1 1>&2 2>&3) + header_info + if [ "$UPD" == "1" ]; then + if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then + clear + header_info + echo -e "${GN}Updating to Version ${BETA}${CL}" + BR="--pre " + else + clear + header_info + echo -e "${GN}Updating to Version ${STABLE}${CL}" + BR="" + fi + if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi + + msg_info "Stopping Home Assistant" + systemctl stop homeassistant + msg_ok "Stopped Home Assistant" + + msg_info "Updating Home Assistant" + source /srv/homeassistant/bin/activate + pip install ${BR}--upgrade homeassistant &>/dev/null + msg_ok "Updated Home Assistant" + + msg_info "Starting Home Assistant" + systemctl start homeassistant + sleep 2 + msg_ok "Started Home Assistant" + msg_ok "Update Successful" + echo -e "\n Go to http://${IP}:8123 \n" + exit + fi + if [ "$UPD" == "2" ]; then + msg_info "Installing Home Assistant Comunity Store (HACS)" + apt update &>/dev/null + apt install unzip &>/dev/null + cd .homeassistant + bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null + msg_ok "Installed Home Assistant Comunity Store (HACS)" + echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" + exit + fi + if [ "$UPD" == "3" ]; then + msg_info "Installing FileBrowser" + curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null + filebrowser config init -a '0.0.0.0' &>/dev/null + filebrowser config set -a '0.0.0.0' &>/dev/null + filebrowser users add admin changeme --perm.admin &>/dev/null + msg_ok "Installed FileBrowser" + + msg_info "Creating Service" + service_path="/etc/systemd/system/filebrowser.service" + echo "[Unit] +Description=Filebrowser +After=network-online.target +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r /root/.homeassistant +[Install] +WantedBy=default.target" >$service_path + + systemctl enable --now filebrowser.service &>/dev/null + msg_ok "Created Service" + + msg_ok "Completed Successfully!\n" + echo -e "FileBrowser should be reachable by going to the following URL. + ${BL}http://$IP:8080${CL} admin|changeme\n" + exit + fi + if [ "$UPD" == "4" ]; then + clear + header_info + if [[ ! -d /srv/appdaemon ]]; then + msg_info "Installing AppDaemon" + mkdir /srv/appdaemon + cd /srv/appdaemon + python3 -m venv . + source bin/activate + pip install appdaemon &>/dev/null + mkdir -p /root/.homeassistant/appdaemon/apps + cat >/root/.homeassistant/appdaemon/appdaemon.yaml < + token: +http: + url: http://127.0.0.1:5050 +admin: +api: +EOF + msg_ok "Installed AppDaemon" + + msg_info "Creating Service" + cat >/etc/systemd/system/appdaemon.service </dev/null + msg_ok "Created Service" + + msg_ok "Completed Successfully!\n" + echo -e "AppDaemon should be reachable by going to the following URL. + ${BL}http://$IP:5050${CL}\n" + exit + else + msg_info "Upgrading AppDaemon" + msg_info "Stopping AppDaemon" + systemctl stop appdaemon + msg_ok "Stopped AppDaemon" + + msg_info "Updating AppDaemon" + source /srv/appdaemon/bin/activate + pip install --upgrade appdaemon &>/dev/null + msg_ok "Updated AppDaemon" + + msg_info "Starting AppDaemon" + systemctl start appdaemon + sleep 2 + msg_ok "Started AppDaemon" + msg_ok "Update Successful" + echo -e "\n Go to http://${IP}:5050 \n" + exit + fi + fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL}" diff --git a/ct/homeassistant-v5.sh b/ct/homeassistant-v5.sh deleted file mode 100644 index 391f8080..00000000 --- a/ct/homeassistant-v5.sh +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ ___ _ __ __ - / / / /___v5____ ___ ___ / | __________(_)____/ /_____ _____ / /_ - / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ - -EOF -} -header_info -echo -e "Loading..." -APP="Home Assistant" -var_disk="16" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - FUSE="yes" -else - FUSE="no" -fi - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ - "1" "Update ALL Containers" ON \ - "2" "Remove ALL Unused Images" OFF \ - "3" "Install HACS" OFF \ - "4" "Install FileBrowser" OFF \ - 3>&1 1>&2 2>&3) -header_info -if [ "$UPD" == "1" ]; then -msg_info "Updating All Containers" -CONTAINER_LIST="${1:-$(docker ps -q)}" -for container in ${CONTAINER_LIST}; do - CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" - RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" - docker pull "${CONTAINER_IMAGE}" - LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" - if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then - echo "Updating ${container} image ${CONTAINER_IMAGE}" - DOCKER_COMMAND="$(runlike "${container}")" - docker rm --force "${container}" - eval ${DOCKER_COMMAND} - fi -done -msg_ok "Updated All Containers" -exit -fi -if [ "$UPD" == "2" ]; then -msg_info "Removing ALL Unused Images" -docker image prune -af -msg_ok "Removed ALL Unused Images" -exit -fi -if [ "$UPD" == "3" ]; then -msg_info "Installing Home Assistant Comunity Store (HACS)" -apt update &>/dev/null -apt install unzip &>/dev/null -cd /var/lib/docker/volumes/hass_config/_data -bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null -msg_ok "Installed Home Assistant Comunity Store (HACS)" -echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" -exit -fi -if [ "$UPD" == "4" ]; then -IP=$(hostname -I | awk '{print $1}') -msg_info "Installing FileBrowser" -curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null -filebrowser config init -a '0.0.0.0' &>/dev/null -filebrowser config set -a '0.0.0.0' &>/dev/null -filebrowser users add admin changeme --perm.admin &>/dev/null -msg_ok "Installed FileBrowser" - -msg_info "Creating Service" -service_path="/etc/systemd/system/filebrowser.service" -echo "[Unit] -Description=Filebrowser -After=network-online.target -[Service] -User=root -WorkingDirectory=/root/ -ExecStart=/usr/local/bin/filebrowser -r / -[Install] -WantedBy=default.target" >$service_path - -systemctl enable --now filebrowser.service &>/dev/null -msg_ok "Created Service" - -msg_ok "Completed Successfully!\n" -echo -e "FileBrowser should be reachable by going to the following URL. - ${BL}http://$IP:8080${CL} admin|changeme\n" -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/docker/volumes/hass_config/_data - ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export ST=$FUSE -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$CT_TYPE" == "0" ]; then -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} -Portainer should be reachable by going to the following URL. - ${BL}http://${IP}:9000${CL}\n" diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh new file mode 100644 index 00000000..1bb58440 --- /dev/null +++ b/ct/homeassistant.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ ___ _ __ __ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="Home Assistant" +var_disk="16" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -d /var/lib/docker/volumes/hass_config/_data ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + "1" "Update ALL Containers" ON \ + "2" "Remove ALL Unused Images" OFF \ + "3" "Install HACS" OFF \ + "4" "Install FileBrowser" OFF \ + 3>&1 1>&2 2>&3) + header_info + if [ "$UPD" == "1" ]; then + msg_info "Updating All Containers" + CONTAINER_LIST="${1:-$(docker ps -q)}" + for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike "${container}")" + docker rm --force "${container}" + eval ${DOCKER_COMMAND} + fi + done + msg_ok "Updated All Containers" + exit + fi + if [ "$UPD" == "2" ]; then + msg_info "Removing ALL Unused Images" + docker image prune -af + msg_ok "Removed ALL Unused Images" + exit + fi + if [ "$UPD" == "3" ]; then + msg_info "Installing Home Assistant Comunity Store (HACS)" + apt update &>/dev/null + apt install unzip &>/dev/null + cd /var/lib/docker/volumes/hass_config/_data + bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null + msg_ok "Installed Home Assistant Comunity Store (HACS)" + echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" + exit + fi + if [ "$UPD" == "4" ]; then + IP=$(hostname -I | awk '{print $1}') + msg_info "Installing FileBrowser" + curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null + filebrowser config init -a '0.0.0.0' &>/dev/null + filebrowser config set -a '0.0.0.0' &>/dev/null + filebrowser users add admin changeme --perm.admin &>/dev/null + msg_ok "Installed FileBrowser" + + msg_info "Creating Service" + service_path="/etc/systemd/system/filebrowser.service" + echo "[Unit] +Description=Filebrowser +After=network-online.target +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r / +[Install] +WantedBy=default.target" >$service_path + + systemctl enable --now filebrowser.service &>/dev/null + msg_ok "Created Service" + + msg_ok "Completed Successfully!\n" + echo -e "FileBrowser should be reachable by going to the following URL. + ${BL}http://$IP:8080${CL} admin|changeme\n" + exit + fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} +Portainer should be reachable by going to the following URL. + ${BL}http://${IP}:9000${CL}\n" diff --git a/ct/homebridge-v5.sh b/ct/homebridge-v5.sh deleted file mode 100644 index 955813c7..00000000 --- a/ct/homebridge-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ______ __ _____________ ____ ________ ____________ - / / / / __ \/ |/ / ____/ __ )/ __ \/ _/ __ \/ ____/ ____/ - / /_/ / / / / /|_/ / __/ / __ / /_/ // // / / / / __/ __/ - / __ / /_/ / / / / /___/ /_/ / _, _// // /_/ / /_/ / /___ -/_/ /_/\____/_/v5/_/_____/_____/_/ |_/___/_____/\____/_____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Homebridge" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/homebridge.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/homebridge.sh b/ct/homebridge.sh new file mode 100644 index 00000000..ebc25192 --- /dev/null +++ b/ct/homebridge.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ______ __ _____________ ____ ________ ____________ + / / / / __ \/ |/ / ____/ __ )/ __ \/ _/ __ \/ ____/ ____/ + / /_/ / / / / /|_/ / __/ / __ / /_/ // // / / / / __/ __/ + / __ / /_/ / / / / /___/ /_/ / _, _// // /_/ / /_/ / /___ +/_/ /_/\____/_/ /_/_____/_____/_/ |_/___/_____/\____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Homebridge" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8581${CL} \n" diff --git a/ct/homepage-v5.sh b/ct/homepage-v5.sh deleted file mode 100644 index cc799cb4..00000000 --- a/ct/homepage-v5.sh +++ /dev/null @@ -1,433 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ - / / / /___ ____ ___ ___ ____ ____ _____ ____ - / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ - / __ / /_/ / / / / / / __/ /_/ / /_/ / /_/ / __/ -/_/ /_/\____/_/ /_/ /_/\___/ .___/\__,_/\__, /\___/ - /_/ v5 /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Homepage" -var_disk="3" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP}" -if ! command -v pnpm >/dev/null 2>&1; then - npm install -g pnpm &>/dev/null -fi -cd /opt/homepage -systemctl stop homepage -git pull --force &>/dev/null -pnpm install &>/dev/null -pnpm build &>/dev/null -systemctl start homepage -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/homepage.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/homepage.sh b/ct/homepage.sh new file mode 100644 index 00000000..90538100 --- /dev/null +++ b/ct/homepage.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ + / / / /___ ____ ___ ___ ____ ____ _____ ____ + / /_/ / __ \/ __ `__ \/ _ \/ __ \/ __ `/ __ `/ _ \ + / __ / /_/ / / / / / / __/ /_/ / /_/ / /_/ / __/ +/_/ /_/\____/_/ /_/ /_/\___/ .___/\__,_/\__, /\___/ + /_/ /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Homepage" +var_disk="3" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/homepage ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +if ! command -v pnpm >/dev/null 2>&1; then + npm install -g pnpm &>/dev/null +fi +cd /opt/homepage +systemctl stop homepage +git pull --force &>/dev/null +pnpm install &>/dev/null +pnpm build &>/dev/null +systemctl start homepage +msg_ok "Update Successfull" +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}:3000${CL} \n" diff --git a/ct/homer-v5.sh b/ct/homer-v5.sh deleted file mode 100644 index c99f3a70..00000000 --- a/ct/homer-v5.sh +++ /dev/null @@ -1,450 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ - / / / /___ ____ ___v5___ _____ - / /_/ / __ \/ __ `__ \/ _ \/ ___/ - / __ / /_/ / / / / / / __/ / -/_/ /_/\____/_/ /_/ /_/\___/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Homer" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Stopping ${APP}" -systemctl stop homer -msg_ok "Stopped ${APP}" - -msg_info "Backing up config.yml" -cd ~ -cp -R /opt/homer/assets/config.yml config.yml -msg_ok "Backed up config.yml" - -msg_info "Updating ${APP}" -rm -rf /opt/homer/* -cd /opt/homer -wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip -unzip homer.zip &>/dev/null -msg_ok "Updated ${APP}" -msg_info "Restoring conf.yml" -cd ~ -cp -R config.yml /opt/homer/assets -msg_ok "Restored conf.yml" - -msg_info "Cleaning" -rm -rf config.yml /opt/homer/homer.zip -msg_ok "Cleaned" - -msg_info "Starting ${APP}" -systemctl start homer -msg_ok "Started ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/homer ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8010${CL} \n" diff --git a/ct/homer.sh b/ct/homer.sh new file mode 100644 index 00000000..13d2b64b --- /dev/null +++ b/ct/homer.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ + / / / /___ ____ ___ ___ _____ + / /_/ / __ \/ __ `__ \/ _ \/ ___/ + / __ / /_/ / / / / / / __/ / +/_/ /_/\____/_/ /_/ /_/\___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Homer" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/homer ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ${APP}" +systemctl stop homer +msg_ok "Stopped ${APP}" + +msg_info "Backing up config.yml" +cd ~ +cp -R /opt/homer/assets/config.yml config.yml +msg_ok "Backed up config.yml" + +msg_info "Updating ${APP}" +rm -rf /opt/homer/* +cd /opt/homer +wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip +unzip homer.zip &>/dev/null +msg_ok "Updated ${APP}" +msg_info "Restoring conf.yml" +cd ~ +cp -R config.yml /opt/homer/assets +msg_ok "Restored conf.yml" + +msg_info "Cleaning" +rm -rf config.yml /opt/homer/homer.zip +msg_ok "Cleaned" + +msg_info "Starting ${APP}" +systemctl start homer +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8010${CL} \n" diff --git a/ct/hyperion-v5.sh b/ct/hyperion-v5.sh deleted file mode 100644 index 13e1168c..00000000 --- a/ct/hyperion-v5.sh +++ /dev/null @@ -1,441 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - __ __ _ - / / / /_ ______v5___ _____(_)___ ____ - / /_/ / / / / __ \/ _ \/ ___/ / __ \/ __ \ - / __ / /_/ / /_/ / __/ / / / /_/ / / / / -/_/ /_/\__, / .___/\___/_/ /_/\____/_/ /_/ - /____/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Hyperion" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get install -y hyperion &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/hyperion.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8090${CL} \n" diff --git a/ct/hyperion.sh b/ct/hyperion.sh new file mode 100644 index 00000000..64b0fa33 --- /dev/null +++ b/ct/hyperion.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ _ + / / / /_ ______ ___ _____(_)___ ____ + / /_/ / / / / __ \/ _ \/ ___/ / __ \/ __ \ + / __ / /_/ / /_/ / __/ / / / /_/ / / / / +/_/ /_/\__, / .___/\___/_/ /_/\____/_/ /_/ + /____/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Hyperion" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/hyperion.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get install -y hyperion &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8090${CL} \n" diff --git a/ct/influxdb-v5.sh b/ct/influxdb-v5.sh deleted file mode 100644 index 3f1e42ed..00000000 --- a/ct/influxdb-v5.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ ______ ____ ____ - / _/_v5 / __/ /_ ___ __/ __ \/ __ ) - / // __ \/ /_/ / / / / |/_/ / / / __ | - _/ // / / / __/ / /_/ /> &1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/influxdb.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/influxdb.sh b/ct/influxdb.sh new file mode 100644 index 00000000..44b3eddb --- /dev/null +++ b/ct/influxdb.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ ______ ____ ____ + / _/___ / __/ /_ ___ __/ __ \/ __ ) + / // __ \/ /_/ / / / / |/_/ / / / __ | + _/ // / / / __/ / /_/ /> /dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/iobroker-v5.sh b/ct/iobroker-v5.sh deleted file mode 100644 index 7e74a9f4..00000000 --- a/ct/iobroker-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ ____ __ - (_)___ / __ )_________ / /_____ _____ - / / __ \/ __ / ___/ __ \/ //_/ _ \/ ___/ - / / /_/ / /_/ / / / /_/ / ,< / __/ / -/_/\____/_____/_/ v5\____/_/|_|\___/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="ioBroker" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/iobroker ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8081${CL} \n" diff --git a/ct/iobroker.sh b/ct/iobroker.sh new file mode 100644 index 00000000..31b5a552 --- /dev/null +++ b/ct/iobroker.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ ____ __ + (_)___ / __ )_________ / /_____ _____ + / / __ \/ __ / ___/ __ \/ //_/ _ \/ ___/ + / / /_/ / /_/ / / / /_/ / ,< / __/ / +/_/\____/_____/_/ \____/_/|_|\___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="ioBroker" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/iobroker ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8081${CL} \n" diff --git a/ct/jackett-v5.sh b/ct/jackett-v5.sh deleted file mode 100644 index 72a6a925..00000000 --- a/ct/jackett-v5.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - __ __ __ __ - / /___ ______/ /_____v5/ /_/ /_ - __ / / __ `/ ___/ //_/ _ \/ __/ __/ -/ /_/ / /_/ / /__/ ,< / __/ /_/ /_ -\____/\__,_/\___/_/|_|\___/\__/\__/ - -EOF -} -header_info -echo -e "Loading..." -APP="Jackett" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/jackett.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:9117${CL}\n" diff --git a/ct/jackett.sh b/ct/jackett.sh new file mode 100644 index 00000000..ec991c7d --- /dev/null +++ b/ct/jackett.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ __ __ + / /___ ______/ /_____ / /_/ /_ + __ / / __ `/ ___/ //_/ _ \/ __/ __/ +/ /_/ / /_/ / /__/ ,< / __/ /_/ /_ +\____/\__,_/\___/_/|_|\___/\__/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="Jackett" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/jackett.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9117${CL}\n" diff --git a/ct/jellyfin-v5.sh b/ct/jellyfin-v5.sh deleted file mode 100644 index b043cf38..00000000 --- a/ct/jellyfin-v5.sh +++ /dev/null @@ -1,450 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ____ _____ - / /__ / / /_v5__/ __(_)___ - __ / / _ \/ / / / / / /_/ / __ \ -/ /_/ / __/ / / /_/ / __/ / / / / -\____/\___/_/_/\__, /_/ /_/_/ /_/ - /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Jellyfin" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit-script -fi -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /usr/lib/jellyfin ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh new file mode 100644 index 00000000..c4bdef50 --- /dev/null +++ b/ct/jellyfin.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ____ _____ + / /__ / / /_ __/ __(_)___ + __ / / _ \/ / / / / / /_/ / __ \ +/ /_/ / __/ / / /_/ / __/ / / / / +\____/\___/_/_/\__, /_/ /_/_/ /_/ + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Jellyfin" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /usr/lib/jellyfin ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8096${CL}\n" diff --git a/ct/k0s-v5.sh b/ct/k0s-v5.sh deleted file mode 100644 index cdf959f6..00000000 --- a/ct/k0s-v5.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ____ __ __ __ __ - / /__/ __ \_____ / //_/_ __/ /_ ___v5_________ ___ / /____ _____ - / //_/ / / / ___/ / ,< / / / / __ \/ _ \/ ___/ __ \/ _ \/ __/ _ \/ ___/ - / ,< / /_/ (__ ) / /| / /_/ / /_/ / __/ / / / / / __/ /_/ __(__ ) -/_/|_|\____/____/ /_/ |_\__,_/_.___/\___/_/ /_/ /_/\___/\__/\___/____/ - -EOF -} -header_info -echo -e "Loading..." -APP="k0s" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/k0s/k0s.yaml ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/k0s.sh b/ct/k0s.sh new file mode 100644 index 00000000..710dd461 --- /dev/null +++ b/ct/k0s.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ____ __ __ __ __ + / /__/ __ \_____ / //_/_ __/ /_ ___ _________ ___ / /____ _____ + / //_/ / / / ___/ / ,< / / / / __ \/ _ \/ ___/ __ \/ _ \/ __/ _ \/ ___/ + / ,< / /_/ (__ ) / /| / /_/ / /_/ / __/ / / / / / __/ /_/ __(__ ) +/_/|_|\____/____/ /_/ |_\__,_/_.___/\___/_/ /_/ /_/\___/\__/\___/____/ + +EOF +} +header_info +echo -e "Loading..." +APP="k0s" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/k0s/k0s.yaml ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/kavita-v5.sh b/ct/kavita-v5.sh deleted file mode 100644 index 32c7b540..00000000 --- a/ct/kavita-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ _ __ - / //_/___ __ v5__(_) /_____ _ - / ,< / __ `/ | / / / __/ __ `/ - / /| / /_/ /| |/ / / /_/ /_/ / -/_/ |_\__,_/ |___/_/\__/\__,_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Kavita" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/Kavita ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/kavita.sh b/ct/kavita.sh new file mode 100644 index 00000000..b80d4728 --- /dev/null +++ b/ct/kavita.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ _ __ + / //_/___ __ __(_) /_____ _ + / ,< / __ `/ | / / / __/ __ `/ + / /| / /_/ /| |/ / / /_/ /_/ / +/_/ |_\__,_/ |___/_/\__/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Kavita" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/Kavita ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/keycloak-v5.sh b/ct/keycloak-v5.sh deleted file mode 100644 index 7c2d8149..00000000 --- a/ct/keycloak-v5.sh +++ /dev/null @@ -1,428 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ __ __ - / //_/__v5__ _______/ /___ ____ _/ /__ - / ,< / _ \/ / / / ___/ / __ \/ __ / //_/ - / /| / __/ /_/ / /__/ / /_/ / /_/ / ,< -/_/ |_\___/\__, /\___/_/\____/\__,_/_/|_| - /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Keycloak" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/keycloak.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/keycloak.sh b/ct/keycloak.sh new file mode 100644 index 00000000..98ae1938 --- /dev/null +++ b/ct/keycloak.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ __ __ + / //_/__ __ _______/ /___ ____ _/ /__ + / ,< / _ \/ / / / ___/ / __ \/ __ / //_/ + / /| / __/ /_/ / /__/ / /_/ / /_/ / ,< +/_/ |_\___/\__, /\___/_/\____/\__,_/_/|_| + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Keycloak" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/keycloak.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/lidarr-v5.sh b/ct/lidarr-v5.sh deleted file mode 100644 index 2fa8eab1..00000000 --- a/ct/lidarr-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ _ __ - / / (_)___/ /___v5__________ - / / / / __ / __ `/ ___/ ___/ - / /___/ / /_/ / /_/ / / / / -/_____/_/\__,_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Lidarr" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/lidarr/ ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8686${CL} \n" diff --git a/ct/lidarr.sh b/ct/lidarr.sh new file mode 100644 index 00000000..c8cf9b26 --- /dev/null +++ b/ct/lidarr.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ _ __ + / / (_)___/ /___ __________ + / / / / __ / __ `/ ___/ ___/ + / /___/ / /_/ / /_/ / / / / +/_____/_/\__,_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Lidarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var/lib/lidarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8686${CL} \n" diff --git a/ct/magicmirror-v5.sh b/ct/magicmirror-v5.sh deleted file mode 100644 index 87f20b9a..00000000 --- a/ct/magicmirror-v5.sh +++ /dev/null @@ -1,429 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ___ _ __ ____ - / |/ /___ _____ _(_)____/ |/ (_)_____________ _____ - / /|_/ / __ / __ / / ___/ /|_/ / / ___/ ___/ __ \/ ___/ - / / / / /_/ / /_/ / / /__/ / / / / / / / / /_/ / / -/_/ /_/\__,_/\__, /_/\___/_/ /_/_/_/ /_/ \____/_/ - /____/ v5 - -EOF -} -header_info -echo -e "Loading..." -APP="MagicMirror" -var_disk="3" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -cd /opt/magicmirror -git pull &>/dev/null -npm install --only=prod --omit=dev &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/magicmirror ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh new file mode 100644 index 00000000..408e1107 --- /dev/null +++ b/ct/magicmirror.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ _ __ ____ + / |/ /___ _____ _(_)____/ |/ (_)_____________ _____ + / /|_/ / __ / __ / / ___/ /|_/ / / ___/ ___/ __ \/ ___/ + / / / / /_/ / /_/ / / /__/ / / / / / / / / /_/ / / +/_/ /_/\__,_/\__, /_/\___/_/ /_/_/_/ /_/ \____/_/ + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="MagicMirror" +var_disk="3" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/magicmirror ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +cd /opt/magicmirror +git pull &>/dev/null +npm install --only=prod --omit=dev &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/mariadb-v5.sh b/ct/mariadb-v5.sh deleted file mode 100644 index 2bee684d..00000000 --- a/ct/mariadb-v5.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ___ _ ____ ____ - / |/ /___ ______(_)___ _/ __ \/ __ ) - / /|_/ / __ / ___/ / __ / / / / __ | - / / / / /_/ / / / / /_/ / /_/ / /_/ / -/_/ /_/\__,_/_/v5/_/\__,_/_____/_____/ - -EOF -} -header_info -echo -e "Loading..." -APP="MariaDB" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/mariadb.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/mariadb.sh b/ct/mariadb.sh new file mode 100644 index 00000000..04b0ba93 --- /dev/null +++ b/ct/mariadb.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ _ ____ ____ + / |/ /___ ______(_)___ _/ __ \/ __ ) + / /|_/ / __ / ___/ / __ / / / / __ | + / / / / /_/ / / / / /_/ / /_/ / /_/ / +/_/ /_/\__,_/_/ /_/\__,_/_____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="MariaDB" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/mariadb.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/meshcentral-v5.sh b/ct/meshcentral-v5.sh deleted file mode 100644 index 0899b146..00000000 --- a/ct/meshcentral-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ___ __ ______ __ __ - / |/ /__ _____/ /_ / ____/__ ____ / /__________ _/ / - / /|_/ / _ \/ ___/ __ \/ / / _ \/ __ \/ __/ ___/ __ / / - / / / / __(__ ) / / / /___/ __/ / / / /_/ / / /_/ / / -/_/ /_/\___/____/_/ /_/\____/\___/_/ /_/\__/_/ v5\__,_/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="MeshCentral" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/meshcentral ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh new file mode 100644 index 00000000..7d544d0b --- /dev/null +++ b/ct/meshcentral.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ __ ______ __ __ + / |/ /__ _____/ /_ / ____/__ ____ / /__________ _/ / + / /|_/ / _ \/ ___/ __ \/ / / _ \/ __ \/ __/ ___/ __ / / + / / / / __(__ ) / / / /___/ __/ / / / /_/ / / /_/ / / +/_/ /_/\___/____/_/ /_/\____/\___/_/ /_/\__/_/ \__,_/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="MeshCentral" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/meshcentral ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" diff --git a/ct/motioneye-v5.sh b/ct/motioneye-v5.sh deleted file mode 100644 index 245f2439..00000000 --- a/ct/motioneye-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ___ __ _ - / |/ /___ / /_(_)___ ____v5___ __ _____ - / /|_/ / __ \/ __/ / __ \/ __ \/ _ \/ / / / _ \ - / / / / /_/ / /_/ / /_/ / / / / __/ /_/ / __/ -/_/ /_/\____/\__/_/\____/_/ /_/\___/\__, /\___/ - /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Motioneye" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -pip install motioneye --upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/motioneye.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/motioneye.sh b/ct/motioneye.sh new file mode 100644 index 00000000..6dc03205 --- /dev/null +++ b/ct/motioneye.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ __ _ + / |/ /___ / /_(_)___ ____ ___ __ _____ + / /|_/ / __ \/ __/ / __ \/ __ \/ _ \/ / / / _ \ + / / / / /_/ / /_/ / /_/ / / / / __/ /_/ / __/ +/_/ /_/\____/\__/_/\____/_/ /_/\___/\__, /\___/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Motioneye" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/motioneye.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +pip install motioneye --upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8765${CL} \n" diff --git a/ct/mqtt-v5.sh b/ct/mqtt-v5.sh deleted file mode 100644 index 46cfed5f..00000000 --- a/ct/mqtt-v5.sh +++ /dev/null @@ -1,424 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - __ ___ ____ _ ____________ - / |/ /___v5_____/ __ \__ __(_)_ __/_ __/___ - / /|_/ / __ \/ ___/ / / / / / / / / / / / / __ \ - / / / / /_/ (__ ) /_/ / /_/ / / / / / / / /_/ / -/_/ /_/\____/____/\___\_\__,_/_/ /_/ /_/ \____/ - -EOF -} -header_info -echo -e "Loading..." -APP="MQTT" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/mosquitto-bullseye.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/mqtt.sh b/ct/mqtt.sh new file mode 100644 index 00000000..d0ccf349 --- /dev/null +++ b/ct/mqtt.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ ____ _ ____________ + / |/ /___ _____/ __ \__ __(_)_ __/_ __/___ + / /|_/ / __ \/ ___/ / / / / / / / / / / / / __ \ + / / / / /_/ (__ ) /_/ / /_/ / / / / / / / /_/ / +/_/ /_/\____/____/\___\_\__,_/_/ /_/ /_/ \____/ + +EOF +} +header_info +echo -e "Loading..." +APP="MQTT" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/mosquitto-bullseye.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/n8n-v5.sh b/ct/n8n-v5.sh deleted file mode 100644 index 13184630..00000000 --- a/ct/n8n-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ___ - / _ \ - _ __ | (_) |_v5_ - | _ \ > _ <| _ \ - | | | | (_) | | | | - |_| |_|\___/|_| |_| - -EOF -} -header_info -echo -e "Loading..." -APP="n8n" -var_disk="3" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -npm update -g n8n &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/n8n.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5678${CL} \n" diff --git a/ct/n8n.sh b/ct/n8n.sh new file mode 100644 index 00000000..944d0fe3 --- /dev/null +++ b/ct/n8n.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ + / _ \ + _ __ | (_) |____ + | _ \ > _ <| _ \ + | | | | (_) | | | | + |_| |_|\___/|_| |_| + +EOF +} +header_info +echo -e "Loading..." +APP="n8n" +var_disk="3" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/n8n.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +npm update -g n8n &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5678${CL} \n" diff --git a/ct/navidrome-v5.sh b/ct/navidrome-v5.sh deleted file mode 100644 index c5d4eeb2..00000000 --- a/ct/navidrome-v5.sh +++ /dev/null @@ -1,437 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ __ _ __ - / | / /___ __ v5__(_)___/ /________ ____ ___ ___ - / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ - / /| / /_/ /| |/ / / /_/ / / / /_/ / / / / / / __/ -/_/ |_/\__,_/ |___/_/\__,_/_/ \____/_/ /_/ /_/\___/ - -EOF -} -header_info -echo -e "Loading..." -APP="Navidrome" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Stopping ${APP}" -systemctl stop navidrome.service -msg_ok "Stopped Navidrome" - -msg_info "Updating to v${RELEASE}" -wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null -tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null -msg_ok "Updated ${APP}" -rm Navidrome.tar.gz - -msg_info "${GN} Starting ${APP}" -systemctl start navidrome.service -msg_ok "Started ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/navidrome ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:4533${CL} \n" diff --git a/ct/navidrome.sh b/ct/navidrome.sh new file mode 100644 index 00000000..2aef956b --- /dev/null +++ b/ct/navidrome.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ _ __ + / | / /___ __ __(_)___/ /________ ____ ___ ___ + / |/ / __ / | / / / __ / ___/ __ \/ __ __ \/ _ \ + / /| / /_/ /| |/ / / /_/ / / / /_/ / / / / / / __/ +/_/ |_/\__,_/ |___/_/\__,_/_/ \____/_/ /_/ /_/\___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Navidrome" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/navidrome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Stopping ${APP}" +systemctl stop navidrome.service +msg_ok "Stopped Navidrome" + +msg_info "Updating to v${RELEASE}" +wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null +tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null +msg_ok "Updated ${APP}" +rm Navidrome.tar.gz + +msg_info "${GN} Starting ${APP}" +systemctl start navidrome.service +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:4533${CL} \n" diff --git a/ct/nextcloudpi-v5.sh b/ct/nextcloudpi-v5.sh deleted file mode 100644 index 79ad1cff..00000000 --- a/ct/nextcloudpi-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ __ __ ________ ______ _ - / | / /__ _ __/ /_/ ____/ /___ __v5______/ / __ \(_) - / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / /_/ / / - / /| / __/> &1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /lib/systemd/system/nextcloud-domain.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}https://${IP}/${CL} \n" diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh new file mode 100644 index 00000000..6f887d8c --- /dev/null +++ b/ct/nextcloudpi.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ __ ________ ______ _ + / | / /__ _ __/ /_/ ____/ /___ __ ______/ / __ \(_) + / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / /_/ / / + / /| / __/> /dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}https://${IP}/${CL} \n" diff --git a/ct/nginxproxymanager-v5.sh b/ct/nginxproxymanager-v5.sh deleted file mode 100644 index a12eb9dd..00000000 --- a/ct/nginxproxymanager-v5.sh +++ /dev/null @@ -1,535 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ __ _ ____ __ ___ - / | / /___ _(_)___ _ __ / __ \_________v5_ ____ __ / |/ /___ _____ ____ _____ ____ _____ - / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ - / /| / /_/ / / / / /> < / ____/ / / /_/ /> &1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') -msg_info "Stopping Services" -systemctl stop openresty -systemctl stop npm -msg_ok "Stopped Services" - -msg_info "Cleaning Old Files" - rm -rf /app \ - /var/www/html \ - /etc/nginx \ - /var/log/nginx \ - /var/lib/nginx \ - /var/cache/nginx &>/dev/null -msg_ok "Cleaned Old Files" - -msg_info "Downloading NPM v${RELEASE}" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null -cd nginx-proxy-manager-${RELEASE} -msg_ok "Downloaded NPM v${RELEASE}" - -msg_info "Setting up Enviroment" -ln -sf /usr/bin/python3 /usr/bin/python -ln -sf /usr/bin/certbot /opt/certbot/bin/certbot -ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx -ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+${RELEASE}+g" backend/package.json -sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json -sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf -NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") -for NGINX_CONF in $NGINX_CONFS; do - sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" -done -mkdir -p /var/www/html /etc/nginx/logs -cp -r docker/rootfs/var/www/html/* /var/www/html/ -cp -r docker/rootfs/etc/nginx/* /etc/nginx/ -cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini -cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager -ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf -rm -f /etc/nginx/conf.d/dev.conf -mkdir -p /tmp/nginx/body \ - /run/nginx \ - /data/nginx \ - /data/custom_ssl \ - /data/logs \ - /data/access \ - /data/nginx/default_host \ - /data/nginx/default_www \ - /data/nginx/proxy_host \ - /data/nginx/redirection_host \ - /data/nginx/stream \ - /data/nginx/dead_host \ - /data/nginx/temp \ - /var/lib/nginx/cache/public \ - /var/lib/nginx/cache/private \ - /var/cache/nginx/proxy_temp -chmod -R 777 /var/cache/nginx -chown root /tmp/nginx -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf -if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null -fi -mkdir -p /app/global /app/frontend/images -cp -r backend/* /app -cp -r global/* /app/global -msg_ok "Setup Enviroment" - -msg_info "Building Frontend" -cd ./frontend -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -yarn build &>/dev/null -cp -r dist/* /app/frontend -cp -r app-images/* /app/frontend/images -msg_ok "Built Frontend" - - -msg_info "Initializing Backend" -rm -rf /app/config/default.json &>/dev/null -if [ ! -f /app/config/production.json ]; then - cat <<'EOF' >/app/config/production.json -{ - "database": { - "engine": "knex-native", - "knex": { - "client": "sqlite3", - "connection": { - "filename": "/data/database.sqlite" - } - } - } -} -EOF -fi -cd /app -export NODE_ENV=development -yarn install --network-timeout=30000 &>/dev/null -msg_ok "Initialized Backend" - -msg_info "Starting Services" -systemctl enable npm &>/dev/null -systemctl start openresty -systemctl start npm -msg_ok "Started Services" - -msg_info "Cleaning up" -rm -rf ~/nginx-proxy-manager-* -msg_ok "Cleaned" - -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /lib/systemd/system/npm.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh new file mode 100644 index 00000000..215e8e24 --- /dev/null +++ b/ct/nginxproxymanager.sh @@ -0,0 +1,180 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + _ __ _ ____ __ ___ + / | / /___ _(_)___ _ __ / __ \_________ __ ____ __ / |/ /___ _____ ____ _____ ____ _____ + / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ + / /| / /_/ / / / / /> < / ____/ / / /_/ /> /dev/null + msg_ok "Cleaned Old Files" + + msg_info "Downloading NPM v${RELEASE}" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null + cd nginx-proxy-manager-${RELEASE} + msg_ok "Downloaded NPM v${RELEASE}" + + msg_info "Setting up Enviroment" + ln -sf /usr/bin/python3 /usr/bin/python + ln -sf /usr/bin/certbot /opt/certbot/bin/certbot + ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx + ln -sf /usr/local/openresty/nginx/ /etc/nginx + sed -i "s+0.0.0+${RELEASE}+g" backend/package.json + sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json + sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf + NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") + for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" + done + mkdir -p /var/www/html /etc/nginx/logs + cp -r docker/rootfs/var/www/html/* /var/www/html/ + cp -r docker/rootfs/etc/nginx/* /etc/nginx/ + cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini + cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager + ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf + rm -f /etc/nginx/conf.d/dev.conf + mkdir -p /tmp/nginx/body \ + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp + chmod -R 777 /var/cache/nginx + chown root /tmp/nginx + echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf + if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null + fi + mkdir -p /app/global /app/frontend/images + cp -r backend/* /app + cp -r global/* /app/global + msg_ok "Setup Enviroment" + + msg_info "Building Frontend" + cd ./frontend + export NODE_ENV=development + yarn install --network-timeout=30000 &>/dev/null + yarn build &>/dev/null + cp -r dist/* /app/frontend + cp -r app-images/* /app/frontend/images + msg_ok "Built Frontend" + + msg_info "Initializing Backend" + rm -rf /app/config/default.json &>/dev/null + if [ ! -f /app/config/production.json ]; then + cat <<'EOF' >/app/config/production.json +{ + "database": { + "engine": "knex-native", + "knex": { + "client": "sqlite3", + "connection": { + "filename": "/data/database.sqlite" + } + } + } +} +EOF + fi + cd /app + export NODE_ENV=development + yarn install --network-timeout=30000 &>/dev/null + msg_ok "Initialized Backend" + + msg_info "Starting Services" + systemctl enable npm &>/dev/null + systemctl start openresty + systemctl start npm + msg_ok "Started Services" + + msg_info "Cleaning up" + rm -rf ~/nginx-proxy-manager-* + msg_ok "Cleaned" + + msg_ok "Update Successfull" + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:81${CL} \n" diff --git a/ct/nocodb-v5.sh b/ct/nocodb-v5.sh deleted file mode 100644 index 50b929cb..00000000 --- a/ct/nocodb-v5.sh +++ /dev/null @@ -1,429 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ __ ____ ____ - / | / /___ ____v5___ / __ \/ __ ) - / |/ / __ \/ ___/ __ \/ / / / __ | - / /| / /_/ / /__/ /_/ / /_/ / /_/ / -/_/ |_/\____/\___/\____/_____/_____/ - -EOF -} -header_info -echo -e "Loading..." -APP="NocoDB" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP}" -cd /opt/nocodb -npm uninstall -s --save nocodb &>/dev/null -npm install -s --save nocodb &>/dev/null -systemctl restart nocodb.service -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/nocodb.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080/dashboard${CL} \n" diff --git a/ct/nocodb.sh b/ct/nocodb.sh new file mode 100644 index 00000000..50677ceb --- /dev/null +++ b/ct/nocodb.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ ____ ____ + / | / /___ ____ ___ / __ \/ __ ) + / |/ / __ \/ ___/ __ \/ / / / __ | + / /| / /_/ / /__/ /_/ / /_/ / /_/ / +/_/ |_/\____/\___/\____/_____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="NocoDB" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/nocodb.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +cd /opt/nocodb +npm uninstall -s --save nocodb &>/dev/null +npm install -s --save nocodb &>/dev/null +systemctl restart nocodb.service +msg_ok "Updated ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080/dashboard${CL} \n" diff --git a/ct/node-red-v5.sh b/ct/node-red-v5.sh deleted file mode 100644 index e0a5fbf4..00000000 --- a/ct/node-red-v5.sh +++ /dev/null @@ -1,462 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ __ __ ____ __ - / | / /___ ____/ /__ v5 / __ \___ ____/ / - / |/ / __ \/ __ / _ \ / /_/ / _ \/ __ / - / /| / /_/ / /_/ / __/ / _, _/ __/ /_/ / -/_/ |_/\____/\__,_/\___/ /_/ |_|\___/\__,_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Node-Red" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ - "1" "Update ${APP}" ON \ - "2" "Install Themes" OFF \ - 3>&1 1>&2 2>&3) -header_info -if [ "$UPD" == "1" ]; then -msg_info "Stopping ${APP}" -systemctl stop nodered -msg_ok "Stopped ${APP}" - -msg_info "Updating ${APP}" -npm install -g --unsafe-perm node-red &>/dev/null -msg_ok "Updated ${APP}" - -msg_info "Starting ${APP}" -systemctl start nodered -msg_ok "Started ${APP}" -msg_ok "Update Successful" -exit -fi -if [ "$UPD" == "2" ]; then -THEME=$(whiptail --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ - "dark" "" OFF \ - "dracula" "" OFF \ - "midnight-red" "" ON \ - "oled" "" OFF \ - "solarized-dark" "" OFF \ - "solarized-light" "" OFF \ - 3>&1 1>&2 2>&3) -header_info -msg_info "Installing ${THEME} Theme" -cd /root/.node-red -sed -i 's|//theme: "",|theme: "",|g' /root/.node-red/settings.js -npm install @node-red-contrib-themes/${THEME} &>/dev/null -sed -i "{s/theme: ".*"/theme: '${THEME}',/g}" /root/.node-red/settings.js -msg_ok "Installed ${THEME} Theme" - -msg_info "Restarting ${APP}" -systemctl restart nodered -msg_ok "Restarted ${APP}" -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /root/.node-red ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/node-red.sh b/ct/node-red.sh new file mode 100644 index 00000000..b625d323 --- /dev/null +++ b/ct/node-red.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ __ ____ __ + / | / /___ ____/ /__ / __ \___ ____/ / + / |/ / __ \/ __ / _ \ / /_/ / _ \/ __ / + / /| / /_/ / /_/ / __/ / _, _/ __/ /_/ / +/_/ |_/\____/\__,_/\___/ /_/ |_|\___/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Node-Red" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +if [[ ! -d /root/.node-red ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + "1" "Update ${APP}" ON \ + "2" "Install Themes" OFF \ + 3>&1 1>&2 2>&3) +header_info +if [ "$UPD" == "1" ]; then +msg_info "Stopping ${APP}" +systemctl stop nodered +msg_ok "Stopped ${APP}" + +msg_info "Updating ${APP}" +npm install -g --unsafe-perm node-red &>/dev/null +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +systemctl start nodered +msg_ok "Started ${APP}" +msg_ok "Update Successful" +exit +fi +if [ "$UPD" == "2" ]; then +THEME=$(whiptail --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ + "dark" "" OFF \ + "dracula" "" OFF \ + "midnight-red" "" ON \ + "oled" "" OFF \ + "solarized-dark" "" OFF \ + "solarized-light" "" OFF \ + 3>&1 1>&2 2>&3) +header_info +msg_info "Installing ${THEME} Theme" +cd /root/.node-red +sed -i 's|//theme: "",|theme: "",|g' /root/.node-red/settings.js +npm install @node-red-contrib-themes/${THEME} &>/dev/null +sed -i "{s/theme: ".*"/theme: '${THEME}',/g}" /root/.node-red/settings.js +msg_ok "Installed ${THEME} Theme" + +msg_info "Restarting ${APP}" +systemctl restart nodered +msg_ok "Restarted ${APP}" +exit +fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:1880${CL} \n" diff --git a/ct/omada-v5.sh b/ct/omada-v5.sh deleted file mode 100644 index c9b9defc..00000000 --- a/ct/omada-v5.sh +++ /dev/null @@ -1,439 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \____ ___v5____ _____/ /___ _ - / / / / __ __ \/ __ / __ / __ / -/ /_/ / / / / / / /_/ / /_/ / /_/ / -\____/_/ /_/ /_/\__,_/\__,_/\__,_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Omada" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit-script -fi - -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/tplink ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}https://${IP}:8043${CL} \n" diff --git a/ct/omada.sh b/ct/omada.sh new file mode 100644 index 00000000..40eea690 --- /dev/null +++ b/ct/omada.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \____ ___ ____ _____/ /___ _ + / / / / __ __ \/ __ / __ / __ / +/ /_/ / / / / / / /_/ / /_/ / /_/ / +\____/_/ /_/ /_/\__,_/\__,_/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Omada" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:8043${CL} \n" diff --git a/ct/omv-v5.sh b/ct/omv-v5.sh deleted file mode 100644 index 692f323b..00000000 --- a/ct/omv-v5.sh +++ /dev/null @@ -1,438 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ ___ ___ _ __ ____ - / __ \____v5___ ____ / |/ /__ ____/ (_)___ | | / /___ ___ __/ / /_ - / / / / __ \/ _ \/ __ \/ /|_/ / _ \/ __ / / __ `/ | / / __ `/ / / / / __/ -/ /_/ / /_/ / __/ / / / / / / __/ /_/ / / /_/ /| |/ / /_/ / /_/ / / /_ -\____/ .___/\___/_/ /_/_/ /_/\___/\__,_/_/\__,_/ |___/\__,_/\__,_/_/\__/ - /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="OMV" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/openmediavault.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -EOF -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}${CL} \n" diff --git a/ct/omv.sh b/ct/omv.sh new file mode 100644 index 00000000..f370db72 --- /dev/null +++ b/ct/omv.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ ___ ___ _ __ ____ + / __ \____ ___ ____ / |/ /__ ____/ (_)___ | | / /___ ___ __/ / /_ + / / / / __ \/ _ \/ __ \/ /|_/ / _ \/ __ / / __ `/ | / / __ `/ / / / / __/ +/ /_/ / /_/ / __/ / / / / / / __/ /_/ / / /_/ /| |/ / /_/ / /_/ / / /_ +\____/ .___/\___/_/ /_/_/ /_/\___/\__,_/_/\__,_/ |___/\__,_/\__,_/_/\__/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="OMV" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/openmediavault.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" diff --git a/ct/openhab-v5.sh b/ct/openhab-v5.sh deleted file mode 100644 index 45150c44..00000000 --- a/ct/openhab-v5.sh +++ /dev/null @@ -1,428 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ _____ ____ - ____v5____ ___ ____ / / / / | / __ ) - / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __ | -/ /_/ / /_/ / __/ / / / __ / ___ |/ /_/ / -\____/ .___/\___/_/ /_/_/ /_/_/ |_/_____/ - /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="openHAB" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/openhab.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/openhab.sh b/ct/openhab.sh new file mode 100644 index 00000000..6e3357a6 --- /dev/null +++ b/ct/openhab.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ _____ ____ + ____ ____ ___ ____ / / / / | / __ ) + / __ \/ __ \/ _ \/ __ \/ /_/ / /| | / __ | +/ /_/ / /_/ / __/ / / / __ / ___ |/ /_/ / +\____/ .___/\___/_/ /_/_/ /_/_/ |_/_____/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="openHAB" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/openhab.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/paperless-ngx-v5.sh b/ct/paperless-ngx-v5.sh deleted file mode 100644 index 88b62649..00000000 --- a/ct/paperless-ngx-v5.sh +++ /dev/null @@ -1,495 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \____ _____ ___ _____/ /__v5__________ ____ ____ __ __ - / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ - / ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> < -/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| - /_/ /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Paperless-ngx" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -SER=/etc/systemd/system/paperless-task-queue.service - -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ - "1" "Update Paperless-ngx to $RELEASE" ON \ - "2" "Paperless-ngx Credentials" OFF \ - 3>&1 1>&2 2>&3) -header_info -if [ "$UPD" == "1" ]; then -msg_info "Stopping Paperless-ngx" -systemctl stop paperless-consumer paperless-webserver paperless-scheduler - if [ -f "$SER" ]; then - systemctl stop paperless-task-queue.service - fi -sleep 1 -msg_ok "Stopped Paperless-ngx" - -msg_info "Updating to ${RELEASE}" - if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }'|wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null - wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null - tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null - cp -r /opt/paperless/paperless.conf paperless-ngx/ - cp -r paperless-ngx/* /opt/paperless/ - cd /opt/paperless - sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt - pip install -r requirements.txt &>/dev/null - cd /opt/paperless/src - /usr/bin/python3 manage.py migrate &>/dev/null - if [ -f "$SER" ]; then - msg_ok "paperless-task-queue.service Exists." - else -cat </etc/systemd/system/paperless-task-queue.service -[Unit] -Description=Paperless Celery Workers -Requires=redis.service -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless worker --loglevel INFO -[Install] -WantedBy=multi-user.target -EOF -systemctl enable paperless-task-queue &>/dev/null -msg_ok "paperless-task-queue.service Created." - fi -cat </etc/systemd/system/paperless-scheduler.service -[Unit] -Description=Paperless Celery beat -Requires=redis.service -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless beat --loglevel INFO -[Install] -WantedBy=multi-user.target -EOF -msg_ok "Updated to ${RELEASE}" - -msg_info "Cleaning up" -cd ~ -rm paperless-ngx-$RELEASE.tar.xz -rm -rf paperless-ngx -msg_ok "Cleaned" - -msg_info "Starting Paperless-ngx" -systemctl daemon-reload -systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service -sleep 1 -msg_ok "Started Paperless-ngx" -msg_ok "Updated Successfully!\n" -exit -fi -if [ "$UPD" == "2" ]; then -cat paperless.creds -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/paperless ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh new file mode 100644 index 00000000..dadc2f51 --- /dev/null +++ b/ct/paperless-ngx.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + + ____ __ + / __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __ + / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ + / ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> < +/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_| + /_/ /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Paperless-ngx" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -d /opt/paperless ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + SER=/etc/systemd/system/paperless-task-queue.service + + UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + "1" "Update Paperless-ngx to $RELEASE" ON \ + "2" "Paperless-ngx Credentials" OFF \ + 3>&1 1>&2 2>&3) + header_info + if [ "$UPD" == "1" ]; then + msg_info "Stopping Paperless-ngx" + systemctl stop paperless-consumer paperless-webserver paperless-scheduler + if [ -f "$SER" ]; then + systemctl stop paperless-task-queue.service + fi + sleep 1 + msg_ok "Stopped Paperless-ngx" + + msg_info "Updating to ${RELEASE}" + if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }' | wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null + wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null + tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null + cp -r /opt/paperless/paperless.conf paperless-ngx/ + cp -r paperless-ngx/* /opt/paperless/ + cd /opt/paperless + sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt + pip install -r requirements.txt &>/dev/null + cd /opt/paperless/src + /usr/bin/python3 manage.py migrate &>/dev/null + if [ -f "$SER" ]; then + msg_ok "paperless-task-queue.service Exists." + else + cat </etc/systemd/system/paperless-task-queue.service +[Unit] +Description=Paperless Celery Workers +Requires=redis.service +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless worker --loglevel INFO +[Install] +WantedBy=multi-user.target +EOF + systemctl enable paperless-task-queue &>/dev/null + msg_ok "paperless-task-queue.service Created." + fi + cat </etc/systemd/system/paperless-scheduler.service +[Unit] +Description=Paperless Celery beat +Requires=redis.service +[Service] +WorkingDirectory=/opt/paperless/src +ExecStart=celery --app paperless beat --loglevel INFO +[Install] +WantedBy=multi-user.target +EOF + msg_ok "Updated to ${RELEASE}" + + msg_info "Cleaning up" + cd ~ + rm paperless-ngx-$RELEASE.tar.xz + rm -rf paperless-ngx + msg_ok "Cleaned" + + msg_info "Starting Paperless-ngx" + systemctl daemon-reload + systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service + sleep 1 + msg_ok "Started Paperless-ngx" + msg_ok "Updated Successfully!\n" + exit + fi + if [ "$UPD" == "2" ]; then + cat paperless.creds + exit + fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/photoprism-v5.sh b/ct/photoprism-v5.sh deleted file mode 100644 index f128744e..00000000 --- a/ct/photoprism-v5.sh +++ /dev/null @@ -1,452 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ ______ __________ ____ ____ _________ __ ___ - / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / - / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / - / ____/ __ / /_/ / / / / /_/ / ____/ _, _// / v5_/ / / / / -/_/ /_/ /_/\____/ /_/ \____/_/ /_/ |_/___//____/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="PhotoPrism" -var_disk="8" -var_cpu="4" -var_ram="4096" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" -msg_info "Stopping PhotoPrism" -sudo systemctl stop photoprism -msg_ok "Stopped PhotoPrism" - -msg_info "Cloning PhotoPrism" -git clone https://github.com/photoprism/photoprism.git &>/dev/null -cd photoprism -git checkout release &>/dev/null -msg_ok "Cloned PhotoPrism" - -msg_info "Building PhotoPrism" -sudo make all &>/dev/null -sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null -sudo rm -rf /opt/photoprism/assets -sudo cp -r assets/ /opt/photoprism/ &>/dev/null -msg_ok "Built PhotoPrism" - -msg_info "Cleaning" -cd ~ -rm -rf photoprism -msg_ok "Cleaned" - -msg_info "Starting PhotoPrism" -sudo systemctl start photoprism -msg_ok "Started PhotoPrism" -msg_ok "Update Successful" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/photoprism ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 2048 -msg_ok "Set Container to Normal Resources" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/photoprism.sh b/ct/photoprism.sh new file mode 100644 index 00000000..1e789870 --- /dev/null +++ b/ct/photoprism.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + + ____ __ ______ __________ ____ ____ _________ __ ___ + / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / + / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / + / ____/ __ / /_/ / / / / /_/ / ____/ _, _// / ___/ / / / / +/_/ /_/ /_/\____/ /_/ \____/_/ /_/ |_/___//____/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="PhotoPrism" +var_disk="8" +var_cpu="4" +var_ram="4096" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + header_info + if [[ ! -d /opt/photoprism ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + echo -e "\n ⚠️ Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \n" + msg_info "Stopping PhotoPrism" + sudo systemctl stop photoprism + msg_ok "Stopped PhotoPrism" + + msg_info "Cloning PhotoPrism" + git clone https://github.com/photoprism/photoprism.git &>/dev/null + cd photoprism + git checkout release &>/dev/null + msg_ok "Cloned PhotoPrism" + + msg_info "Building PhotoPrism" + sudo make all &>/dev/null + sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null + sudo rm -rf /opt/photoprism/assets + sudo cp -r assets/ /opt/photoprism/ &>/dev/null + msg_ok "Built PhotoPrism" + + msg_info "Cleaning" + cd ~ + rm -rf photoprism + msg_ok "Cleaned" + + msg_info "Starting PhotoPrism" + sudo systemctl start photoprism + msg_ok "Started PhotoPrism" + msg_ok "Update Successful" + exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 2048 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:2342${CL} \n" diff --git a/ct/pihole-v5.sh b/ct/pihole-v5.sh deleted file mode 100644 index f4e541af..00000000 --- a/ct/pihole-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ ____ __ ______ __ ______ - / __ \/ _/ / / / / __ \/ / / ____/ - / /_/ // /___/ /_/ / / / / / / __/ - / ____// /___/ __ / /_/ / /v5_/ /___ -/_/ /___/ /_/ /_/\____/_____/_____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Pihole" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/pihole ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}/admin${CL} \n" diff --git a/ct/pihole.sh b/ct/pihole.sh new file mode 100644 index 00000000..b5de9177 --- /dev/null +++ b/ct/pihole.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ ____ __ ______ __ ______ + / __ \/ _/ / / / / __ \/ / / ____/ + / /_/ // /___/ /_/ / / / / / / __/ + / ____// /___/ __ / /_/ / /___/ /___ +/_/ /___/ /_/ /_/\____/_____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Pihole" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /etc/pihole ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}/admin${CL} \n" diff --git a/ct/plex-v5.sh b/ct/plex-v5.sh deleted file mode 100644 index a1d4b466..00000000 --- a/ct/plex-v5.sh +++ /dev/null @@ -1,460 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ __ ___ ___ _____ - / __ \/ /__ _ __ / |/ /__v5____/ (_)___ _ / ___/___ ______ _____ _____ - / /_/ / / _ \| |/_/ / /|_/ / _ \/ __ / / __ `/ \__ \/ _ \/ ___/ | / / _ \/ ___/ - / ____/ / __/> < / / / / __/ /_/ / / /_/ / ___/ / __/ / | |/ / __/ / -/_/ /_/\___/_/|_| /_/ /_/\___/\__,_/_/\__,_/ /____/\___/_/ |___/\___/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Plex" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="20.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit-script -fi -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ - "1" "Update LXC" ON \ - "2" "Run plexupdate" OFF \ - 3>&1 1>&2 2>&3) - -header_info -if [ "$UPD" == "1" ]; then -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -fi -if [ "$UPD" == "2" ]; then -bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)" -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:32400/web${CL}\n" diff --git a/ct/plex.sh b/ct/plex.sh new file mode 100644 index 00000000..a944d8b6 --- /dev/null +++ b/ct/plex.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ __ ___ ___ _____ + / __ \/ /__ _ __ / |/ /__ ____/ (_)___ _ / ___/___ ______ _____ _____ + / /_/ / / _ \| |/_/ / /|_/ / _ \/ __ / / __ `/ \__ \/ _ \/ ___/ | / / _ \/ ___/ + / ____/ / __/> < / / / / __/ /_/ / / /_/ / ___/ / __/ / | |/ / __/ / +/_/ /_/\___/_/|_| /_/ /_/\___/\__,_/_/\__,_/ /____/\___/_/ |___/\___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Plex" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="20.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ + "1" "Update LXC" ON \ + "2" "Run plexupdate" OFF \ + 3>&1 1>&2 2>&3) + +header_info +if [ "$UPD" == "1" ]; then +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +fi +if [ "$UPD" == "2" ]; then +bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)" +exit +fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:32400/web${CL}\n" diff --git a/ct/podman-homeassistant-v5.sh b/ct/podman-homeassistant-v5.sh deleted file mode 100644 index daba5aec..00000000 --- a/ct/podman-homeassistant-v5.sh +++ /dev/null @@ -1,497 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \____ ____/ /___ ___ ____ _____ - / /_/ / __ \/ __ / __ __ \/ __ / __ \ - / ____/ /_/ / /_/ / / / / / / /_/ / / / / - __ __ /_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/__ __ - / / / /___ ____ ___ ___ v5 / | __________(_)____/ /_____ _____ / /_ - / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ - -EOF -} -header_info -echo -e "Loading..." -APP="Podman-Home Assistant" -var_disk="16" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ - "1" "Update Podman" ON \ - "2" "Install HACS" OFF \ - "3" "Install FileBrowser" OFF \ - 3>&1 1>&2 2>&3) -header_info -if [ "$UPD" == "1" ]; then -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -fi -if [ "$UPD" == "2" ]; then -msg_info "Installing Home Assistant Comunity Store (HACS)" -apt update &>/dev/null -apt install unzip &>/dev/null -cd /var/lib/containers/storage/volumes/hass_config/_data -bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null -msg_ok "Installed Home Assistant Comunity Store (HACS)" -echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" -exit -fi -if [ "$UPD" == "3" ]; then -IP=$(hostname -I | awk '{print $1}') -msg_info "Installing FileBrowser" -curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null -filebrowser config init -a '0.0.0.0' &>/dev/null -filebrowser config set -a '0.0.0.0' &>/dev/null -filebrowser users add admin changeme --perm.admin &>/dev/null -msg_ok "Installed FileBrowser" - -msg_info "Creating Service" -service_path="/etc/systemd/system/filebrowser.service" -echo "[Unit] -Description=Filebrowser -After=network-online.target -[Service] -User=root -WorkingDirectory=/root/ -ExecStart=/usr/local/bin/filebrowser -r / -[Install] -WantedBy=default.target" >$service_path - -systemctl enable --now filebrowser.service &>/dev/null -msg_ok "Created Service" - -msg_ok "Completed Successfully!\n" -echo -e "FileBrowser should be reachable by going to the following URL. - ${BL}http://$IP:8080${CL} admin|changeme\n" -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/homeassistant.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -if [ "$CT_TYPE" == "0" ]; then - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -else - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8123${CL} \n" diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh new file mode 100644 index 00000000..14947e9d --- /dev/null +++ b/ct/podman-homeassistant.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ + / __ \____ ____/ /___ ___ ____ _____ + / /_/ / __ \/ __ / __ __ \/ __ / __ \ + / ____/ /_/ / /_/ / / / / / / /_/ / / / / + __ __ /_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/__ __ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ + / /_/ / __ \/ __ __ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ / __ \/ __/ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="Podman-Home Assistant" +var_disk="16" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + [[ ! -f /etc/systemd/system/homeassistant.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + "1" "Update Podman" ON \ + "2" "Install HACS" OFF \ + "3" "Install FileBrowser" OFF \ + 3>&1 1>&2 2>&3) +header_info +if [ "$UPD" == "1" ]; then +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +fi +if [ "$UPD" == "2" ]; then +msg_info "Installing Home Assistant Comunity Store (HACS)" +apt update &>/dev/null +apt install unzip &>/dev/null +cd /var/lib/containers/storage/volumes/hass_config/_data +bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null +msg_ok "Installed Home Assistant Comunity Store (HACS)" +echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" +exit +fi +if [ "$UPD" == "3" ]; then +IP=$(hostname -I | awk '{print $1}') +msg_info "Installing FileBrowser" +curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null +filebrowser config init -a '0.0.0.0' &>/dev/null +filebrowser config set -a '0.0.0.0' &>/dev/null +filebrowser users add admin changeme --perm.admin &>/dev/null +msg_ok "Installed FileBrowser" + +msg_info "Creating Service" +service_path="/etc/systemd/system/filebrowser.service" +echo "[Unit] +Description=Filebrowser +After=network-online.target +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r / +[Install] +WantedBy=default.target" >$service_path + +systemctl enable --now filebrowser.service &>/dev/null +msg_ok "Created Service" + +msg_ok "Completed Successfully!\n" +echo -e "FileBrowser should be reachable by going to the following URL. + ${BL}http://$IP:8080${CL} admin|changeme\n" +exit +fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8123${CL} \n" diff --git a/ct/podman-v5.sh b/ct/podman-v5.sh deleted file mode 100644 index 582e0831..00000000 --- a/ct/podman-v5.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \____v5____/ /___ ___ ____ _____ - / /_/ / __ \/ __ / __ `__ \/ __ `/ __ \ - / ____/ /_/ / /_/ / / / / / / /_/ / / / / -/_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Podman" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/containers/registries.conf ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/podman.sh b/ct/podman.sh new file mode 100644 index 00000000..ef57de78 --- /dev/null +++ b/ct/podman.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ + / __ \____ ____/ /___ ___ ____ _____ + / /_/ / __ \/ __ / __ `__ \/ __ `/ __ \ + / ____/ /_/ / /_/ / / / / / / /_/ / / / / +/_/ \____/\__,_/_/ /_/ /_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Podman" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/containers/registries.conf ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/postgresql-v5.sh b/ct/postgresql-v5.sh deleted file mode 100644 index 47a66cf8..00000000 --- a/ct/postgresql-v5.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ _____ ____ __ - / __ \____ _____/ /_____ _________ / ___// __ \ / / - / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / - / ____/ /_/ (__ ) /_/ /_/ / / / __/__/ / /_/ / / /___ -/_/ \____/____/\__/\__, /_/v5 \___/____/\___\_\/_____/ - /____/ -EOF -} -header_info -echo -e "Loading..." -APP="PostgreSQL" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/postgresql.sh b/ct/postgresql.sh new file mode 100644 index 00000000..1275649a --- /dev/null +++ b/ct/postgresql.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ _____ ____ __ + / __ \____ _____/ /_____ _________ / ___// __ \ / / + / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / + / ____/ /_/ (__ ) /_/ /_/ / / / __/__/ / /_/ / / /___ +/_/ \____/____/\__/\__, /_/ \___/____/\___\_\/_____/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="PostgreSQL" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/prometheus-v5.sh b/ct/prometheus-v5.sh deleted file mode 100644 index 34856e1a..00000000 --- a/ct/prometheus-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ __ - / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ - / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ - / ____/ / / /_/ / / / / / / __/ /_/ / / / __/ /_/ (__ ) -/_/ v5/_/ \____/_/ /_/ /_/\___/\__/_/ /_/\___/\__,_/____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Prometheus" -var_disk="4" -var_cpu="1" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/prometheus.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:9090${CL} \n" diff --git a/ct/prometheus.sh b/ct/prometheus.sh new file mode 100644 index 00000000..c1514477 --- /dev/null +++ b/ct/prometheus.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ __ + / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ + / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ + / ____/ / / /_/ / / / / / / __/ /_/ / / / __/ /_/ (__ ) +/_/ /_/ \____/_/ /_/ /_/\___/\__/_/ /_/\___/\__,_/____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Prometheus" +var_disk="4" +var_cpu="1" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/prometheus.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9090${CL} \n" diff --git a/ct/prowlarr-v5.sh b/ct/prowlarr-v5.sh deleted file mode 100644 index 758bf5a3..00000000 --- a/ct/prowlarr-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \_________ _ __/ /___v5__________ - / /_/ / ___/ __ \ | /| / / / __ `/ ___/ ___/ - / ____/ / / /_/ / |/ |/ / / /_/ / / / / -/_/ /_/ \____/|__/|__/_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Prowlarr" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/prowlarr/ ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:9696${CL} \n" diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh new file mode 100644 index 00000000..a61d6144 --- /dev/null +++ b/ct/prowlarr.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ + / __ \_________ _ __/ /___ __________ + / /_/ / ___/ __ \ | /| / / / __ `/ ___/ ___/ + / ____/ / / /_/ / |/ |/ / / /_/ / / / / +/_/ /_/ \____/|__/|__/_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Prowlarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var/lib/prowlarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9696${CL} \n" diff --git a/ct/qbittorrent-v5.sh b/ct/qbittorrent-v5.sh deleted file mode 100644 index b52a8f49..00000000 --- a/ct/qbittorrent-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ____ _ __ __ __ - ____ _/ __ )(_) /_/ /_____ _____________v5____ / /_ - / __ `/ __ / / __/ __/ __ \/ ___/ ___/ _ \/ __ \/ __/ -/ /_/ / /_/ / / /_/ /_/ /_/ / / / / / __/ / / / /_ -\__, /_____/_/\__/\__/\____/_/ /_/ \___/_/ /_/\__/ - /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="qBittorrent" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/qbittorrent-nox.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8090${CL}\n" diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh new file mode 100644 index 00000000..d5e20ddf --- /dev/null +++ b/ct/qbittorrent.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _ __ __ __ + ____ _/ __ )(_) /_/ /_____ _____________ ____ / /_ + / __ `/ __ / / __/ __/ __ \/ ___/ ___/ _ \/ __ \/ __/ +/ /_/ / /_/ / / /_/ /_/ /_/ / / / / / __/ / / / /_ +\__, /_____/_/\__/\__/\____/_/ /_/ \___/_/ /_/\__/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="qBittorrent" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/qbittorrent-nox.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8090${CL}\n" diff --git a/ct/radarr-v5.sh b/ct/radarr-v5.sh deleted file mode 100644 index e9eb9667..00000000 --- a/ct/radarr-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \____ _____/ /___v5__________ - / /_/ / __ `/ __ / __ `/ ___/ ___/ - / _, _/ /_/ / /_/ / /_/ / / / / -/_/ |_|\__,_/\__,_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Radarr" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/radarr/ ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:7878${CL} \n" diff --git a/ct/radarr.sh b/ct/radarr.sh new file mode 100644 index 00000000..0664fc5d --- /dev/null +++ b/ct/radarr.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ + / __ \____ _____/ /___ __________ + / /_/ / __ `/ __ / __ `/ ___/ ___/ + / _, _/ /_/ / /_/ / /_/ / / / / +/_/ |_|\__,_/\__,_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Radarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var/lib/radarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7878${CL} \n" diff --git a/ct/readarr-v5.sh b/ct/readarr-v5.sh deleted file mode 100644 index 4d555119..00000000 --- a/ct/readarr-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ - / __ \___ ____ _____/ /___v5__________ - / /_/ / _ \/ __ `/ __ / __ `/ ___/ ___/ - / _, _/ __/ /_/ / /_/ / /_/ / / / / -/_/ |_|\___/\__,_/\__,_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Readarr" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/readarr/ ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8787${CL} \n" diff --git a/ct/readarr.sh b/ct/readarr.sh new file mode 100644 index 00000000..3ac5ee57 --- /dev/null +++ b/ct/readarr.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ + / __ \___ ____ _____/ /___ __________ + / /_/ / _ \/ __ `/ __ / __ `/ ___/ ___/ + / _, _/ __/ /_/ / /_/ / /_/ / / / / +/_/ |_|\___/\__,_/\__,_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Readarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var/lib/readarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8787${CL} \n" diff --git a/ct/rockylinux-v5.sh b/ct/rockylinux-v5.sh deleted file mode 100644 index e13fcb60..00000000 --- a/ct/rockylinux-v5.sh +++ /dev/null @@ -1,400 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ____ __ __ _ - / __ \____ _____/ /____ __ / / (_)___v5__ ___ __ - / /_/ / __ \/ ___/ //_/ / / / / / / / __ \/ / / / |/_/ - / _, _/ /_/ / /__/ ,< / /_/ / / /___/ / / / / /_/ /> < -/_/ |_|\____/\___/_/|_|\__, / /_____/_/_/ /_/\__,_/_/|_| - /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Rocky Linux" -var_disk="1" -var_cpu="1" -var_ram="512" -var_os="rockylinux" -var_version="9" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}archlinux${CL}" - PW="-password rockylinux" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { - CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - fi - PW1=$(whiptail --inputbox "Set Root Password (needed for root ssh access)" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $PW1 ]; then - PW1="rockylinux" PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - fi - fi - CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_ID ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi - fi - CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CT_NAME ]; then - HN="$NSAPP" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then - HN=$(echo ${CT_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - fi - DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $DISK_SIZE ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}" - advanced_settings - fi - fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi - fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi - fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi - fi - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi - fi - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $GATE1 ]; then - GATE1="Default" GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - fi - fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - echo -e "${DGN}Disable IPv6: ${BGN}Yes${CL}" - DISABLEIP6="yes" - else - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - fi - fi - SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $SD ]; then - SD="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - else - SX=$SD - SD="-searchdomain=$SD" - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - fi - fi - NS=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $NS ]; then - NS="" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}Host${CL}" - else - NX=$NS - NS="-nameserver=$NS" - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - fi - fi - MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $MAC1 ]; then - MAC1="Default" MAC="" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - echo -e "${DGN}Enable Root SSH Access: ${BGN}Yes${CL}" - SSH="yes" - else - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - echo -e "${DGN}Enable Verbose Mode: ${BGN}Yes${CL}" - VERB="yes" - else - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -dnf -y update -dnf -y upgrade -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/pacman.d ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh new file mode 100644 index 00000000..eb955c9d --- /dev/null +++ b/ct/rockylinux.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ __ __ _ + / __ \____ _____/ /____ __ / / (_)___ __ ___ __ + / /_/ / __ \/ ___/ //_/ / / / / / / / __ \/ / / / |/_/ + / _, _/ /_/ / /__/ ,< / /_/ / / /___/ / / / / /_/ /> < +/_/ |_|\____/\___/_/|_|\__, / /_____/_/_/ /_/\__,_/_/|_| + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Rocky Linux" +var_disk="1" +var_cpu="1" +var_ram="512" +var_os="rockylinux" +var_version="9" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="-password rockylinux" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /etc/pacman.d ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +dnf -y update +dnf -y upgrade +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/rstptoweb-v5.sh b/ct/rstptoweb-v5.sh deleted file mode 100644 index 803d52c9..00000000 --- a/ct/rstptoweb-v5.sh +++ /dev/null @@ -1,420 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ____ _______________ __ _ ____________ - / __ \/ ___/_ __/ __ \/ /_____| | v5 / / ____/ __ ) - / /_/ /\__ \ / / / /_/ / __/ __ \ | /| / / __/ / __ | - / _, _/___/ // / / ____/ /_/ /_/ / |/ |/ / /___/ /_/ / -/_/ |_|/____//_/ /_/ \__/\____/|__/|__/_____/_____/ - -EOF -} -header_info -echo -e "Loading..." -APP="RSTPtoWEB" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:8083 ${CL} \n" diff --git a/ct/rstptoweb.sh b/ct/rstptoweb.sh new file mode 100644 index 00000000..b3e9dfb5 --- /dev/null +++ b/ct/rstptoweb.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _______________ __ _ ____________ + / __ \/ ___/_ __/ __ \/ /_____| | / / ____/ __ ) + / /_/ /\__ \ / / / /_/ / __/ __ \ | /| / / __/ / __ | + / _, _/___/ // / / ____/ /_/ /_/ / |/ |/ / /___/ /_/ / +/_/ |_|/____//_/ /_/ \__/\____/|__/|__/_____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="RSTPtoWEB" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +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}:8083 ${CL} \n" diff --git a/ct/sabnzbd-v5.sh b/ct/sabnzbd-v5.sh deleted file mode 100644 index 0f3aab85..00000000 --- a/ct/sabnzbd-v5.sh +++ /dev/null @@ -1,432 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _____ ___ ____ __ __ - / ___// | / __ )____v5____ / /_ ____/ / - \__ \/ /| | / __ / __ \/_ / / __ \/ __ / - ___/ / ___ |/ /_/ / / / / / /_/ /_/ / /_/ / -/____/_/ |_/_____/_/ /_/ /___/_.___/\__,_/ - -EOF -} -header_info -echo -e "Loading..." -APP="SABnzbd" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP" -systemctl stop sabnzbd.service -RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) &>/dev/null -\cp -r SABnzbd-${RELEASE}/* /opt/sabnzbd &>/dev/null -rm -rf SABnzbd-${RELEASE} -cd /opt/sabnzbd -python3 -m pip install -r requirements.txt &>/dev/null -systemctl start sabnzbd.service -msg_ok "Updated $APP" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/sabnzbd ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP}. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:7777${CL} \n" diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh new file mode 100644 index 00000000..2f1a8c1b --- /dev/null +++ b/ct/sabnzbd.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _____ ___ ____ __ __ + / ___// | / __ )____ ____ / /_ ____/ / + \__ \/ /| | / __ / __ \/_ / / __ \/ __ / + ___/ / ___ |/ /_/ / / / / / /_/ /_/ / /_/ / +/____/_/ |_/_____/_/ /_/ /___/_.___/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="SABnzbd" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/sabnzbd ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +systemctl stop sabnzbd.service +RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) &>/dev/null +\cp -r SABnzbd-${RELEASE}/* /opt/sabnzbd &>/dev/null +rm -rf SABnzbd-${RELEASE} +cd /opt/sabnzbd +python3 -m pip install -r requirements.txt &>/dev/null +systemctl start sabnzbd.service +msg_ok "Updated $APP" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7777${CL} \n" diff --git a/ct/scrypted-v5.sh b/ct/scrypted-v5.sh deleted file mode 100644 index 25867b90..00000000 --- a/ct/scrypted-v5.sh +++ /dev/null @@ -1,442 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _____ __ __ - / ___/____________v5______ / /____ ____/ / - \__ \/ ___/ ___/ / / / __ \/ __/ _ \/ __ / - ___/ / /__/ / / /_/ / /_/ / /_/ __/ /_/ / -/____/\___/_/ \__, / .___/\__/\___/\__,_/ - /____/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Scrypted" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/scrypted.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}https://${IP}:10443${CL} \n" diff --git a/ct/scrypted.sh b/ct/scrypted.sh new file mode 100644 index 00000000..c10a33be --- /dev/null +++ b/ct/scrypted.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _____ __ __ + / ___/____________ ______ / /____ ____/ / + \__ \/ ___/ ___/ / / / __ \/ __/ _ \/ __ / + ___/ / /__/ / / /_/ / /_/ / /_/ __/ /_/ / +/____/\___/_/ \__, / .___/\__/\___/\__,_/ + /____/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Scrypted" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/scrypted.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}https://${IP}:10443${CL} \n" diff --git a/ct/shinobi-v5.sh b/ct/shinobi-v5.sh deleted file mode 100644 index c2c2a019..00000000 --- a/ct/shinobi-v5.sh +++ /dev/null @@ -1,441 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _____ __ _ __ _ - / ___// /_ (_)___v5____ / /_ (_) - \__ \/ __ \/ / __ \/ __ \/ __ \/ / - ___/ / / / / / / / / /_/ / /_/ / / -/____/_/ /_/_/_/ /_/\____/_.___/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Shinobi" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="ubuntu" -var_version="22.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" OFF \ - "22.04" "Jammy" ON \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit-script -fi - -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating Shinobi LXC" -cd /opt/Shinobi -sh UPDATE.sh -pm2 flush -pm2 restart camera -pm2 restart cron -msg_ok "Updated Shinobi LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/Shinobi ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. - ${BL}http://${IP}:8080/super${CL} \n" diff --git a/ct/shinobi.sh b/ct/shinobi.sh new file mode 100644 index 00000000..23020d04 --- /dev/null +++ b/ct/shinobi.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _____ __ _ __ _ + / ___// /_ (_)___ ____ / /_ (_) + \__ \/ __ \/ / __ \/ __ \/ __ \/ / + ___/ / / / / / / / / /_/ / /_/ / / +/____/_/ /_/_/_/ /_/\____/_.___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Shinobi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="22.04" +var_version="20.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/Shinobi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating Shinobi LXC" +cd /opt/Shinobi +sh UPDATE.sh +pm2 flush +pm2 restart camera +pm2 restart cron +msg_ok "Updated Shinobi LXC" +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}:8080/super${CL} \n" diff --git a/ct/sonarr-v5.sh b/ct/sonarr-v5.sh deleted file mode 100644 index 6018fcc2..00000000 --- a/ct/sonarr-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _____ - / ___/____ ____ ____v5__________ - \__ \/ __ \/ __ \/ __ `/ ___/ ___/ - ___/ / /_/ / / / / /_/ / / / / -/____/\____/_/ /_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Sonarr" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/sonarr.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8989${CL} \n" diff --git a/ct/sonarr.sh b/ct/sonarr.sh new file mode 100644 index 00000000..e8152274 --- /dev/null +++ b/ct/sonarr.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _____ + / ___/____ ____ ____ __________ + \__ \/ __ \/ __ \/ __ `/ ___/ ___/ + ___/ / /_/ / / / / /_/ / / / / +/____/\____/_/ /_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Sonarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/sonarr.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8989${CL} \n" diff --git a/ct/syncthing-v5.sh b/ct/syncthing-v5.sh deleted file mode 100644 index 0f88a88d..00000000 --- a/ct/syncthing-v5.sh +++ /dev/null @@ -1,428 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _____ __ __ _ - / ___/__ ______v5_____/ /_/ /_ (_)___ ____ _ - \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ - ___/ / /_/ / / / / /__/ /_/ / / / / / / / /_/ / -/____/\__, /_/ /_/\___/\__/_/ /_/_/_/ /_/\__, / - /____/ /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Syncthing" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/sources.list.d/syncthing.list ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8384 ${CL} \n" diff --git a/ct/syncthing.sh b/ct/syncthing.sh new file mode 100644 index 00000000..e26dbd56 --- /dev/null +++ b/ct/syncthing.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _____ __ __ _ + / ___/__ ______ _____/ /_/ /_ (_)___ ____ _ + \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ + ___/ / /_/ / / / / /__/ /_/ / / / / / / / /_/ / +/____/\__, /_/ /_/\___/\__/_/ /_/_/_/ /_/\__, / + /____/ /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Syncthing" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/syncthing.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8384 ${CL} \n" diff --git a/ct/tdarr-v5.sh b/ct/tdarr-v5.sh deleted file mode 100644 index 4a879ece..00000000 --- a/ct/tdarr-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ __ - /_ __/___/ /___v5__________ - / / / __ / __ `/ ___/ ___/ - / / / /_/ / /_/ / / / / -/_/ \__,_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Tdarr" -var_disk="4" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/tdarr ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8265${CL} \n" diff --git a/ct/tdarr.sh b/ct/tdarr.sh new file mode 100644 index 00000000..ba2f9149 --- /dev/null +++ b/ct/tdarr.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ______ __ + /_ __/___/ /___ __________ + / / / __ / __ `/ ___/ ___/ + / / / /_/ / /_/ / / / / +/_/ \__,_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Tdarr" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/tdarr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8265${CL} \n" diff --git a/ct/technitiumdns-v5.sh b/ct/technitiumdns-v5.sh deleted file mode 100644 index 44b424f3..00000000 --- a/ct/technitiumdns-v5.sh +++ /dev/null @@ -1,436 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ __ _ __ _ ____ _ _______ - /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ v5 / __ \/ | / / ___/ - / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ - / / / __/ /__/ / / / / / / / /_/ / /_/ / / / / / / / /_/ / /| /___/ / -/_/ \___/\___/_/ /_/_/ /_/_/\__/_/\__,_/_/ /_/ /_/ /_____/_/ |_//____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Technitium DNS" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP}" - -if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then - wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb - dpkg -i packages-microsoft-prod.deb - apt-get update - apt-get install -y aspnetcore-runtime-7.0 - rm packages-microsoft-prod.deb -fi -wget -q https://download.technitium.com/dns/DnsServerPortable.tar.gz -tar -zxf DnsServerPortable.tar.gz -C /etc/dns/ &>/dev/null -rm -rf DnsServerPortable.tar.gz -systemctl restart dns.service -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/dns ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh new file mode 100644 index 00000000..fbe2c925 --- /dev/null +++ b/ct/technitiumdns.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ______ __ _ __ _ ____ _ _______ + /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ / __ \/ | / / ___/ + / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ + / / / __/ /__/ / / / / / / / /_/ / /_/ / / / / / / / /_/ / /| /___/ / +/_/ \___/\___/_/ /_/_/ /_/_/\__/_/\__,_/_/ /_/ /_/ /_____/_/ |_//____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Technitium DNS" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /etc/dns ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" + +if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then + wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb + dpkg -i packages-microsoft-prod.deb + apt-get update + apt-get install -y aspnetcore-runtime-7.0 + rm packages-microsoft-prod.deb +fi +wget -q https://download.technitium.com/dns/DnsServerPortable.tar.gz +tar -zxf DnsServerPortable.tar.gz -C /etc/dns/ &>/dev/null +rm -rf DnsServerPortable.tar.gz +systemctl restart dns.service +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5380${CL} \n" diff --git a/ct/transmission-v5.sh b/ct/transmission-v5.sh deleted file mode 100644 index 5fb1e37d..00000000 --- a/ct/transmission-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ _ _ - /_ __/________ _____v5_________ ___ (_)_________(_)___ ____ - / / / ___/ __ `/ __ \/ ___/ __ `__ \/ / ___/ ___/ / __ \/ __ \ - / / / / / /_/ / / / (__ ) / / / / / (__ |__ ) / /_/ / / / / -/_/ /_/ \__,_/_/ /_/____/_/ /_/ /_/_/____/____/_/\____/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Transmission" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/transmission-daemon/settings.json ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:9091/transmission${CL} \n" diff --git a/ct/transmission.sh b/ct/transmission.sh new file mode 100644 index 00000000..86d45292 --- /dev/null +++ b/ct/transmission.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ______ _ _ + /_ __/________ _____ _________ ___ (_)_________(_)___ ____ + / / / ___/ __ `/ __ \/ ___/ __ `__ \/ / ___/ ___/ / __ \/ __ \ + / / / / / /_/ / / / (__ ) / / / / / (__ |__ ) / /_/ / / / / +/_/ /_/ \__,_/_/ /_/____/_/ /_/ /_/_/____/____/_/\____/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Transmission" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/transmission-daemon/settings.json ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9091/transmission${CL} \n" diff --git a/ct/trilium-v5.sh b/ct/trilium-v5.sh deleted file mode 100644 index 3c447d88..00000000 --- a/ct/trilium-v5.sh +++ /dev/null @@ -1,446 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - ______ _ ___ - /_ __/_v5_(_) (_)_ ______ ___ - / / / ___/ / / / / / / __ `__ \ - / / / / / / / / /_/ / / / / / / -/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Trilium" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -msg_info "Stopping ${APP}" -systemctl stop trilium.service -sleep 1 -msg_ok "Stopped ${APP}" - -msg_info "Updating to v${RELEASE}" -wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz -tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null -cp -r trilium-linux-x64-server/* /opt/trilium/ -msg_ok "Updated to v${RELEASE}" - -msg_info "Cleaning up" -rm -rf trilium-linux-x64-server-$RELEASE.tar.xz trilium-linux-x64-server -msg_ok "Cleaned" - -msg_info "Starting ${APP}" -systemctl start trilium.service -sleep 1 -msg_ok "Started ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/trilium ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/trilium.sh b/ct/trilium.sh new file mode 100644 index 00000000..dd2b2578 --- /dev/null +++ b/ct/trilium.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ______ _ ___ + /_ __/____(_) (_)_ ______ ___ + / / / ___/ / / / / / / __ `__ \ + / / / / / / / / /_/ / / / / / / +/_/ /_/ /_/_/_/\__,_/_/ /_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Trilium" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/trilium ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Stopping ${APP}" +systemctl stop trilium.service +sleep 1 +msg_ok "Stopped ${APP}" + +msg_info "Updating to v${RELEASE}" +wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz +tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null +cp -r trilium-linux-x64-server/* /opt/trilium/ +msg_ok "Updated to v${RELEASE}" + +msg_info "Cleaning up" +rm -rf trilium-linux-x64-server-$RELEASE.tar.xz trilium-linux-x64-server +msg_ok "Cleaned" + +msg_info "Starting ${APP}" +systemctl start trilium.service +sleep 1 +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/ct/ubuntu-v5.sh b/ct/ubuntu-v5.sh deleted file mode 100644 index 79bcc700..00000000 --- a/ct/ubuntu-v5.sh +++ /dev/null @@ -1,431 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ ____ __ - / / / / /_v5__ ______ / /___ __ - / / / / __ \/ / / / __ \/ __/ / / / -/ /_/ / /_/ / /_/ / / / / /_/ /_/ / -\____/_.___/\__,_/_/ /_/\__/\__,_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Ubuntu" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="ubuntu" -var_version="22.04" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" OFF \ - "22.04" "Jammy" ON \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" -else - exit-script -fi - -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh new file mode 100644 index 00000000..9fce57ed --- /dev/null +++ b/ct/ubuntu.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + __ ____ __ + / / / / /_ __ ______ / /___ __ + / / / / __ \/ / / / __ \/ __/ / / / +/ /_/ / /_/ / /_/ / / / / /_/ /_/ / +\____/_.___/\__,_/_/ /_/\__/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Ubuntu" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="ubuntu" +var_version="22.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/umbrel-v5.sh b/ct/umbrel-v5.sh deleted file mode 100644 index ee339e2b..00000000 --- a/ct/umbrel-v5.sh +++ /dev/null @@ -1,452 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ __ __ - / / / /___ ___v5/ /_ ________ / / - / / / / __ `__ \/ __ \/ ___/ _ \/ / -/ /_/ / / / / / / /_/ / / / __/ / -\____/_/ /_/ /_/_.___/_/ \___/_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Umbrel" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - FUSE="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - FUSE="yes" -else - FUSE="no" -fi - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /root/umbrel ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$FUSE" == "yes" ]; then -FEATURES="fuse=1,keyctl=1,nesting=1" -else -FEATURES="keyctl=1,nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export ST=$FUSE -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -LXC_CONFIG=/etc/pve/lxc/${CTID}.conf -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF -if [ "$CT_TYPE" == "0" ]; then -cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL (reboot is required before app installs). - ${BL}http://${IP} ${CL} \n" diff --git a/ct/umbrel.sh b/ct/umbrel.sh new file mode 100644 index 00000000..796693ce --- /dev/null +++ b/ct/umbrel.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/docker.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + __ __ __ __ + / / / /___ ___ / /_ ________ / / + / / / / __ `__ \/ __ \/ ___/ _ \/ / +/ /_/ / / / / / / /_/ / / / __/ / +\____/_/ /_/ /_/_.___/_/ \___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Umbrel" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + FUSE="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL (reboot is required before apps install). + ${BL}http://${IP} ${CL} \n" diff --git a/ct/unifi-v5.sh b/ct/unifi-v5.sh deleted file mode 100644 index 571c30fb..00000000 --- a/ct/unifi-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ _ _____ - / / / /_v5 (_) __(_) - / / / / __ \/ / /_/ / -/ /_/ / / / / / __/ / -\____/_/ /_/_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Unifi" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP}" -wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh -bash unifi-update.sh -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /usr/lib/unifi ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP}${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:8443${CL} \n" diff --git a/ct/unifi.sh b/ct/unifi.sh new file mode 100644 index 00000000..c5993242 --- /dev/null +++ b/ct/unifi.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + __ __ _ _____ + / / / /__ (_) __(_) + / / / / __ \/ / /_/ / +/ /_/ / / / / / __/ / +\____/_/ /_/_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Unifi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /usr/lib/unifi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh +bash unifi-update.sh +msg_ok "Updated ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP}${CL} should be reachable by going to the following URL. + ${BL}https://${IP}:8443${CL} \n" diff --git a/ct/uptimekuma-v5.sh b/ct/uptimekuma-v5.sh deleted file mode 100644 index 09623497..00000000 --- a/ct/uptimekuma-v5.sh +++ /dev/null @@ -1,444 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - __ __ __ _ __ __ - / / / /___ / /_(_)___ ___ ___ v5 / //_/_ ______ ___ ____ _ - / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / -/ /_/ / /_/ / /_/ / / / / / / __/ / /| / /_/ / / / / / / /_/ / -\____/ .___/\__/_/_/ /_/ /_/\___/ /_/ |_\__,_/_/ /_/ /_/\__,_/ - /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Uptime Kuma" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -msg_info "Stopping ${APP}" -sudo systemctl stop uptime-kuma &>/dev/null -msg_ok "Stopped ${APP}" - -cd /opt/uptime-kuma - -msg_info "Pulling ${APP} ${LATEST}" -git fetch --all &>/dev/null -git checkout $LATEST --force &>/dev/null -msg_ok "Pulled ${APP} ${LATEST}" - -msg_info "Updating ${APP} to ${LATEST}" -npm install --production &>/dev/null -npm run download-dist &>/dev/null -msg_ok "Updated ${APP}" - -msg_info "Starting ${APP}" -sudo systemctl start uptime-kuma &>/dev/null -msg_ok "Started ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/uptime-kuma ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3001${CL} \n" diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh new file mode 100644 index 00000000..86644bf9 --- /dev/null +++ b/ct/uptimekuma.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + __ __ __ _ __ __ + / / / /___ / /_(_)___ ___ ___ / //_/_ ______ ___ ____ _ + / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / +/ /_/ / /_/ / /_/ / / / / / / __/ / /| / /_/ / / / / / / /_/ / +\____/ .___/\__/_/_/ /_/ /_/\___/ /_/ |_\__,_/_/ /_/ /_/\__,_/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Uptime Kuma" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/uptime-kuma ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +msg_info "Stopping ${APP}" +sudo systemctl stop uptime-kuma &>/dev/null +msg_ok "Stopped ${APP}" + +cd /opt/uptime-kuma + +msg_info "Pulling ${APP} ${LATEST}" +git fetch --all &>/dev/null +git checkout $LATEST --force &>/dev/null +msg_ok "Pulled ${APP} ${LATEST}" + +msg_info "Updating ${APP} to ${LATEST}" +npm install --production &>/dev/null +npm run download-dist &>/dev/null +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +sudo systemctl start uptime-kuma &>/dev/null +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3001${CL} \n" diff --git a/ct/vaultwarden-v5.sh b/ct/vaultwarden-v5.sh deleted file mode 100644 index 88de3398..00000000 --- a/ct/vaultwarden-v5.sh +++ /dev/null @@ -1,498 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ __ ____ _ __ __ -| | / /___ ___v5__/ / /| | / /___ __________/ /__ ____ -| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ -| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / -|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Vaultwarden" -var_disk="6" -var_cpu="4" -var_ram="4096" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') -WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ - "1" "VaultWarden $VAULT" ON \ - "2" "Web-Vault $WVRELEASE" OFF \ - "3" "Show Admin Token" OFF \ - 3>&1 1>&2 2>&3) - -header_info -if [ "$UPD" == "1" ]; then -echo -e "\n ⚠️ Ensure you set 4vCPU & 4096MiB RAM minimum!!! \n" -msg_info "Stopping Vaultwarden" -systemctl stop vaultwarden.service -msg_ok "Stopped Vaultwarden" - -msg_info "Updating VaultWarden to $VAULT (Patience)" -cd ~ && rm -rf vaultwarden -git clone https://github.com/dani-garcia/vaultwarden &>/dev/null -cd vaultwarden -cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null -DIR=/usr/bin/vaultwarden - if [ -d "$DIR" ]; then - cp target/release/vaultwarden /usr/bin/ - else - cp target/release/vaultwarden /opt/vaultwarden/bin/ - fi -msg_ok "Updated VaultWarden" - -msg_info "Cleaning up" -cd ~ && rm -rf vaultwarden -msg_ok "Cleaned" - -msg_info "Starting Vaultwarden" -systemctl start vaultwarden.service -msg_ok "Started Vaultwarden" - -msg_ok "$VAULT Update Successful" -echo -e "\n ⚠️ Ensure you set resources back to normal settings \n" -exit; -fi -if [ "$UPD" == "2" ]; then -msg_info "Stopping Vaultwarden" -systemctl stop vaultwarden.service -msg_ok "Stopped Vaultwarden" - -msg_info "Updating Web-Vault to $WVRELEASE" -curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WVRELEASE/bw_web_$WVRELEASE.tar.gz &>/dev/null -tar -zxf bw_web_$WVRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null -msg_ok "Updated Web-Vault" - -msg_info "Cleaning up" -rm bw_web_$WVRELEASE.tar.gz -msg_ok "Cleaned" - -msg_info "Starting Vaultwarden" -systemctl start vaultwarden.service -msg_ok "Started Vaultwarden" -msg_ok "$WVRELEASE Update Successful" -exit; -fi -if [ "$UPD" == "3" ]; then -DIR=/usr/bin/vaultwarden - if [ -d "$DIR" ]; then - cat /etc/vaultwarden.env | grep "ADMIN_TOKEN" - else - cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" - fi -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/systemd/system/vaultwarden.service ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 512 -pct set $CTID -cores 1 -msg_ok "Set Container to Normal Resources" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh new file mode 100644 index 00000000..3a9aed9a --- /dev/null +++ b/ct/vaultwarden.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + + _ __ ____ _ __ __ +| | / /___ ___ __/ / /| | / /___ __________/ /__ ____ +| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ +| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / / / /_/ / __/ / / / +|___/\__,_/\__,_/_/\__/ |__/|__/\__,_/_/ \__,_/\___/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Vaultwarden" +var_disk="6" +var_cpu="4" +var_ram="4096" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -f /etc/systemd/system/vaultwarden.service ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') + WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') + + UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ + "1" "VaultWarden $VAULT" ON \ + "2" "Web-Vault $WVRELEASE" OFF \ + "3" "Show Admin Token" OFF \ + 3>&1 1>&2 2>&3) + + header_info + if [ "$UPD" == "1" ]; then + echo -e "\n ⚠️ Ensure you set 4vCPU & 4096MiB RAM minimum!!! \n" + msg_info "Stopping Vaultwarden" + systemctl stop vaultwarden.service + msg_ok "Stopped Vaultwarden" + + msg_info "Updating VaultWarden to $VAULT (Patience)" + cd ~ && rm -rf vaultwarden + git clone https://github.com/dani-garcia/vaultwarden &>/dev/null + cd vaultwarden + cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null + DIR=/usr/bin/vaultwarden + if [ -d "$DIR" ]; then + cp target/release/vaultwarden /usr/bin/ + else + cp target/release/vaultwarden /opt/vaultwarden/bin/ + fi + msg_ok "Updated VaultWarden" + + msg_info "Cleaning up" + cd ~ && rm -rf vaultwarden + msg_ok "Cleaned" + + msg_info "Starting Vaultwarden" + systemctl start vaultwarden.service + msg_ok "Started Vaultwarden" + + msg_ok "$VAULT Update Successful" + echo -e "\n ⚠️ Ensure you set resources back to normal settings \n" + exit + fi + if [ "$UPD" == "2" ]; then + msg_info "Stopping Vaultwarden" + systemctl stop vaultwarden.service + msg_ok "Stopped Vaultwarden" + + msg_info "Updating Web-Vault to $WVRELEASE" + curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WVRELEASE/bw_web_$WVRELEASE.tar.gz &>/dev/null + tar -zxf bw_web_$WVRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null + msg_ok "Updated Web-Vault" + + msg_info "Cleaning up" + rm bw_web_$WVRELEASE.tar.gz + msg_ok "Cleaned" + + msg_info "Starting Vaultwarden" + systemctl start vaultwarden.service + msg_ok "Started Vaultwarden" + msg_ok "$WVRELEASE Update Successful" + exit + fi + if [ "$UPD" == "3" ]; then + DIR=/usr/bin/vaultwarden + if [ -d "$DIR" ]; then + cat /etc/vaultwarden.env | grep "ADMIN_TOKEN" + else + cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" + fi + exit + fi +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 512 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" diff --git a/ct/whisparr-v5.sh b/ct/whisparr-v5.sh deleted file mode 100644 index 21b45677..00000000 --- a/ct/whisparr-v5.sh +++ /dev/null @@ -1,427 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ ____ _ -| | / / /_ (_)________ ____v5__________ -| | /| / / __ \/ / ___/ __ \/ __ `/ ___/ ___/ -| |/ |/ / / / / (__ ) /_/ / /_/ / / / / -|__/|__/_/ /_/_/____/ .___/\__,_/_/ /_/ - /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Whisparr" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /var/lib/whisparr ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:6969${CL} \n" diff --git a/ct/whisparr.sh b/ct/whisparr.sh new file mode 100644 index 00000000..7c3adbe4 --- /dev/null +++ b/ct/whisparr.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _ ____ _ +| | / / /_ (_)________ ____ __________ +| | /| / / __ \/ / ___/ __ \/ __ `/ ___/ ___/ +| |/ |/ / / / / (__ ) /_/ / /_/ / / / / +|__/|__/_/ /_/_/____/ .___/\__,_/_/ /_/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Whisparr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var/lib/whisparr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6969${CL} \n" diff --git a/ct/whoogle-v5.sh b/ct/whoogle-v5.sh deleted file mode 100644 index ec26eadb..00000000 --- a/ct/whoogle-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ ____ ______ ____ ________ ______ -| | v5 / / / / / __ \/ __ \/ ____/ / / ____/ -| | /| / / /_/ / / / / / / / / __/ / / __/ -| |/ |/ / __ / /_/ / /_/ / /_/ / /___/ /___ -|__/|__/_/ /_/\____/\____/\____/_____/_____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Whoogle" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -pip3 install whoogle-search --upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /usr/local/bin/whoogle-search ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/whoogle.sh b/ct/whoogle.sh new file mode 100644 index 00000000..e1bf927c --- /dev/null +++ b/ct/whoogle.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _ ____ ______ ____ ________ ______ +| | / / / / / __ \/ __ \/ ____/ / / ____/ +| | /| / / /_/ / / / / / / / / __/ / / __/ +| |/ |/ / __ / /_/ / /_/ / /_/ / /___/ /___ +|__/|__/_/ /_/\____/\____/\____/_____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Whoogle" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /usr/local/bin/whoogle-search ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +pip3 install whoogle-search --upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" diff --git a/ct/wikijs-v5.sh b/ct/wikijs-v5.sh deleted file mode 100644 index 3848eb4c..00000000 --- a/ct/wikijs-v5.sh +++ /dev/null @@ -1,449 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ ___ __ _ _ -| | v5 / (_) /__(_) (_)____ -| | /| / / / //_/ / / / ___/ -| |/ |/ / / ,< / / / (__ ) -|__/|__/_/_/|_/_(_)_/ /____/ - /___/ - -EOF -} -header_info -echo -e "Loading..." -APP="Wikijs" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Stopping ${APP}" -systemctl stop wikijs -msg_ok "Stopped ${APP}" - -msg_info "Backing up Data" -mkdir -p data-backup -cp -R /opt/wikijs/{db.sqlite,config.yml,/data} ~/data-backup -msg_ok "Backed up Data" - -msg_info "Updating ${APP}" -rm -rf /opt/wikijs/* -cd /opt/wikijs -wget -q https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz -tar xzf wiki-js.tar.gz -msg_ok "Updated ${APP}" - -msg_info "Restoring Data" -cp -R ~/data-backup/* /opt/wikijs -rm -rf ~/data-backup -npm rebuild sqlite3 &>/dev/null -msg_ok "Restored Data" - -msg_info "Starting ${APP}" -systemctl start wikijs -msg_ok "Started ${APP}" -msg_ok "Update Successfull" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/wikijs ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/wikijs.sh b/ct/wikijs.sh new file mode 100644 index 00000000..377eeba0 --- /dev/null +++ b/ct/wikijs.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _ ___ __ _ _ +| | / (_) /__(_) (_)____ +| | /| / / / //_/ / / / ___/ +| |/ |/ / / ,< / / / (__ ) +|__/|__/_/_/|_/_(_)_/ /____/ + /___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Wikijs" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/wikijs ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ${APP}" +systemctl stop wikijs +msg_ok "Stopped ${APP}" + +msg_info "Backing up Data" +mkdir -p data-backup +cp -R /opt/wikijs/{db.sqlite,config.yml,/data} ~/data-backup +msg_ok "Backed up Data" + +msg_info "Updating ${APP}" +rm -rf /opt/wikijs/* +cd /opt/wikijs +wget -q https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz +tar xzf wiki-js.tar.gz +msg_ok "Updated ${APP}" + +msg_info "Restoring Data" +cp -R ~/data-backup/* /opt/wikijs +rm -rf ~/data-backup +npm rebuild sqlite3 &>/dev/null +msg_ok "Restored Data" + +msg_info "Starting ${APP}" +systemctl start wikijs +msg_ok "Started ${APP}" +msg_ok "Update Successfull" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/wireguard-v5.sh b/ct/wireguard-v5.sh deleted file mode 100644 index 8fce1701..00000000 --- a/ct/wireguard-v5.sh +++ /dev/null @@ -1,479 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _ ___ ______ __ -| | / (_)_______ / ____/_ ______ __________/ / -| | /| / / / ___/ _ \/ / __/ / / / __ `/ ___/ __ / -| |/ |/ / / / / __/ /_/ / /_/ / /_/ / / / /_/ / -|__/|__/_/_/ v5\___/\____/\__,_/\__,_/_/ \__,_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Wireguard" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ - "1" "Update ${APP} LXC" ON \ - "2" "Install WGDashboard" OFF \ - 3>&1 1>&2 2>&3) -header_info -if [ "$UPD" == "1" ]; then -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit -fi -if [ "$UPD" == "2" ]; then - if [[ -f /etc/systemd/system/wg-dashboard.service ]]; then - msg_error "Existing WGDashboard Installation Found!"; - exit - fi -IP=$(hostname -I | awk '{print $1}') -msg_info "Installing Python3-pip" -apt-get install -y python3-pip &>/dev/null -pip install flask &>/dev/null -pip install ifcfg &>/dev/null -pip install flask_qrcode &>/dev/null -pip install icmplib &>/dev/null -msg_ok "Installed Python3-pip" - -msg_info "Installing WGDashboard" -WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest | - grep "tag_name" | - awk '{print substr($2, 2, length($2)-3) }') - -git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null -cd /etc/wgdashboard/src -sudo chmod u+x wgd.sh -sudo ./wgd.sh install &>/dev/null -sudo chmod -R 755 /etc/wireguard -msg_ok "Installed WGDashboard" - -msg_info "Creating Service" -service_path="/etc/systemd/system/wg-dashboard.service" -echo "[Unit] -After=systemd-networkd.service - -[Service] -WorkingDirectory=/etc/wgdashboard/src -ExecStart=/usr/bin/python3 /etc/wgdashboard/src/dashboard.py -Restart=always - - -[Install] -WantedBy=default.target" >$service_path -chmod 664 /etc/systemd/system/wg-dashboard.service -systemctl daemon-reload -systemctl enable wg-dashboard.service &>/dev/null -systemctl start wg-dashboard.service &>/dev/null -msg_ok "Created Service" -echo -e "WGDashboard should be reachable by going to the following URL. - ${BL}http://${IP}:10086${CL} admin|admin \n" -exit -fi -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /etc/pivpn/wireguard ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/wireguard.sh b/ct/wireguard.sh new file mode 100644 index 00000000..cfd017be --- /dev/null +++ b/ct/wireguard.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + _ ___ ______ __ +| | / (_)_______ / ____/_ ______ __________/ / +| | /| / / / ___/ _ \/ / __/ / / / __ `/ ___/ __ / +| |/ |/ / / / / __/ /_/ / /_/ / /_/ / / / /_/ / +|__/|__/_/_/ \___/\____/\__,_/\__,_/_/ \__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Wireguard" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +if [[ ! -d /etc/pivpn/wireguard ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + "1" "Update ${APP} LXC" ON \ + "2" "Install WGDashboard" OFF \ + 3>&1 1>&2 2>&3) +header_info +if [ "$UPD" == "1" ]; then +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +msg_ok "Update Successfull" +exit +fi +if [ "$UPD" == "2" ]; then + if [[ -f /etc/systemd/system/wg-dashboard.service ]]; then + msg_error "Existing WGDashboard Installation Found!"; + exit + fi +IP=$(hostname -I | awk '{print $1}') +msg_info "Installing Python3-pip" +apt-get install -y python3-pip &>/dev/null +pip install flask &>/dev/null +pip install ifcfg &>/dev/null +pip install flask_qrcode &>/dev/null +pip install icmplib &>/dev/null +msg_ok "Installed Python3-pip" + +msg_info "Installing WGDashboard" +WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest | + grep "tag_name" | + awk '{print substr($2, 2, length($2)-3) }') + +git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null +cd /etc/wgdashboard/src +sudo chmod u+x wgd.sh +sudo ./wgd.sh install &>/dev/null +sudo chmod -R 755 /etc/wireguard +msg_ok "Installed WGDashboard" + +msg_info "Creating Service" +service_path="/etc/systemd/system/wg-dashboard.service" +echo "[Unit] +After=systemd-networkd.service + +[Service] +WorkingDirectory=/etc/wgdashboard/src +ExecStart=/usr/bin/python3 /etc/wgdashboard/src/dashboard.py +Restart=always + + +[Install] +WantedBy=default.target" >$service_path +chmod 664 /etc/systemd/system/wg-dashboard.service +systemctl daemon-reload +systemctl enable wg-dashboard.service &>/dev/null +systemctl start wg-dashboard.service &>/dev/null +msg_ok "Created Service" +echo -e "WGDashboard should be reachable by going to the following URL. + ${BL}http://${IP}:10086${CL} admin|admin \n" +exit +fi +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/yunohost-v5.sh b/ct/yunohost-v5.sh deleted file mode 100644 index 6d324d78..00000000 --- a/ct/yunohost-v5.sh +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - -__ __ __ __ __ -\ \/ /_ ______v5____ / / / /___ _____/ /_ - \ / / / / __ \/ __ \/ /_/ / __ \/ ___/ __/ - / / /_/ / / / / /_/ / __ / /_/ (__ ) /_ -/_/\__,_/_/ /_/\____/_/ /_/\____/____/\__/ - -EOF -} -header_info -echo -e "Loading..." -APP="YunoHost" -var_disk="20" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -f /etc/apt/trusted.gpg.d/php.gpg ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}/ ${CL}" diff --git a/ct/yunohost.sh b/ct/yunohost.sh new file mode 100644 index 00000000..931ad446 --- /dev/null +++ b/ct/yunohost.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + +__ __ __ __ __ +\ \/ /_ ______ ____ / / / /___ _____/ /_ + \ / / / / __ \/ __ \/ /_/ / __ \/ ___/ __/ + / / /_/ / / / / /_/ / __ / /_/ (__ ) /_ +/_/\__,_/_/ /_/\____/_/ /_/\____/____/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="YunoHost" +var_disk="20" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/trusted.gpg.d/php.gpg ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}/ ${CL}" diff --git a/ct/zigbee2mqtt-v5.sh b/ct/zigbee2mqtt-v5.sh deleted file mode 100644 index f16cc025..00000000 --- a/ct/zigbee2mqtt-v5.sh +++ /dev/null @@ -1,486 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _____ _ __ ___ __ _______ ____________ -/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ - / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / - / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / -/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ - v5 /____/ 🐝 - -EOF -} -header_info -echo -e "Loading..." -APP="Zigbee2MQTT" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -cd /opt/zigbee2mqtt - -stop_zigbee2mqtt() { - if which systemctl 2> /dev/null > /dev/null; then - echo "Shutting down Zigbee2MQTT..." - sudo systemctl stop zigbee2mqtt - else - echo "Skipped stopping Zigbee2MQTT, no systemctl found" - fi -} - -start_zigbee2mqtt() { - if which systemctl 2> /dev/null > /dev/null; then - echo "Starting Zigbee2MQTT..." - sudo systemctl start zigbee2mqtt - else - echo "Skipped starting Zigbee2MQTT, no systemctl found" - fi -} - -set -e - -if [ -d data-backup ]; then - echo "ERROR: Backup directory exists. May be previous restoring was failed?" - echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later." - echo "2. Manually delete 'data-backup' dir and try again." - exit 1 -fi - -stop_zigbee2mqtt - -echo "Generating a backup of the configuration..." -cp -R data data-backup || { echo "Failed to create backup."; exit 1; } - -echo "Initiating update" -if ! git pull; then - echo "Update failed, temporarily storing changes and trying again." - git stash && git pull || (echo "Update failed even after storing changes. Aborting."; exit 1) -fi - -echo "Acquiring necessary components..." -npm ci || { echo "Failed to install necessary components."; exit 1; } - -echo "Restoring configuration..." -cp -R data-backup/* data || { echo "Failed to restore configuration."; exit 1; } - -rm -rf data-backup || { echo "Failed to remove backup directory."; exit 1; } - -start_zigbee2mqtt - -echo "Done!" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/zigbee2mqtt ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh new file mode 100644 index 00000000..2030a5dd --- /dev/null +++ b/ct/zigbee2mqtt.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + + _____ _ __ ___ __ _______ ____________ +/__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ + / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / + / /__/ / /_/ / /_/ / __/ __/ __// / / / /_/ / / / / / +/____/_/\__, /_.___/\___/\___/____/_/ /_/\___\_\/_/ /_/ + /____/ 🐝 + +EOF +} +header_info +echo -e "Loading..." +APP="Zigbee2MQTT" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + header_info + if [[ ! -d /opt/zigbee2mqtt ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + cd /opt/zigbee2mqtt + + stop_zigbee2mqtt() { + if which systemctl 2>/dev/null >/dev/null; then + echo "Shutting down Zigbee2MQTT..." + sudo systemctl stop zigbee2mqtt + else + echo "Skipped stopping Zigbee2MQTT, no systemctl found" + fi + } + + start_zigbee2mqtt() { + if which systemctl 2>/dev/null >/dev/null; then + echo "Starting Zigbee2MQTT..." + sudo systemctl start zigbee2mqtt + else + echo "Skipped starting Zigbee2MQTT, no systemctl found" + fi + } + + set -e + + if [ -d data-backup ]; then + echo "ERROR: Backup directory exists. May be previous restoring was failed?" + echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later." + echo "2. Manually delete 'data-backup' dir and try again." + exit 1 + fi + + stop_zigbee2mqtt + + echo "Generating a backup of the configuration..." + cp -R data data-backup || { + echo "Failed to create backup." + exit 1 + } + + echo "Initiating update" + if ! git pull; then + echo "Update failed, temporarily storing changes and trying again." + git stash && git pull || ( + echo "Update failed even after storing changes. Aborting." + exit 1 + ) + fi + + echo "Acquiring necessary components..." + npm ci || { + echo "Failed to install necessary components." + exit 1 + } + + echo "Restoring configuration..." + cp -R data-backup/* data || { + echo "Failed to restore configuration." + exit 1 + } + + rm -rf data-backup || { + echo "Failed to remove backup directory." + exit 1 + } + + start_zigbee2mqtt + + echo "Done!" + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/ct/zwave-js-ui-v5.sh b/ct/zwave-js-ui-v5.sh deleted file mode 100644 index c4f360a6..00000000 --- a/ct/zwave-js-ui-v5.sh +++ /dev/null @@ -1,455 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - - _____ _______ __ ______ -/__ /_ ______ __v5 _____ / / ___/ / / / / _/ - / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / - / /_| |/ |/ / /_/ /| |/ / __/ / /_/ /___/ / / /_/ // / -/____/__/|__/\__,_/ |___/\___/ \____//____/ \____/___/ - -EOF -} -header_info -echo -e "Loading..." -APP="Zwave-JS-UI" -var_disk="4" -var_cpu="2" -var_ram="1024" -var_os="debian" -var_version="11" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Privileged${CL}" - CT_TYPE="0" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - PW="" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" OFF \ - "0" "Privileged" ON \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -msg_info "Stopping Z-wave JS UI" -systemctl stop zwave-js-ui.service -msg_ok "Stopped Z-wave JS UI" - -msg_info "Updating Z-wave JS UI" -wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null -\cp -R zwave-js-ui-linux /opt/zwave-js-ui -msg_ok "Updated Z-wave JS UI" - -msg_info "Starting Z-wave JS UI" -systemctl enable --now zwave-js-ui.service -msg_ok "Started Z-wave JS UI" - -msg_info "Cleanup" -rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store -msg_ok "Cleaned" -msg_ok "Updated Successfully!\n" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1 && [[ ! -d /opt/zwave-js-ui ]]; then - msg_error "No ${APP} Installation Found!" - exit -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF -fi -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8091${CL} \n" diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh new file mode 100644 index 00000000..7dc9ec31 --- /dev/null +++ b/ct/zwave-js-ui.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + + _____ _______ __ ______ +/__ /_ ______ __ _____ / / ___/ / / / / _/ + / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / + / /_| |/ |/ / /_/ /| |/ / __/ / /_/ /___/ / / /_/ // / +/____/__/|__/\__,_/ |___/\___/ \____//____/ \____/___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Zwave-JS-UI" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + header_info + if [[ ! -d /opt/zwave-js-ui ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + msg_info "Stopping Z-wave JS UI" + systemctl stop zwave-js-ui.service + msg_ok "Stopped Z-wave JS UI" + + msg_info "Updating Z-wave JS UI" + wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null + unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null + \cp -R zwave-js-ui-linux /opt/zwave-js-ui + msg_ok "Updated Z-wave JS UI" + + msg_info "Starting Z-wave JS UI" + systemctl enable --now zwave-js-ui.service + msg_ok "Started Z-wave JS UI" + + msg_info "Cleanup" + rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store + msg_ok "Cleaned" + msg_ok "Updated Successfully!\n" + exit +} + +start +build_container +description + +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8091${CL} \n" diff --git a/install/adguard-install.sh b/install/adguard-install.sh new file mode 100644 index 00000000..fb490e06 --- /dev/null +++ b/install/adguard-install.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing AdGuard Home" +systemctl stop systemd-resolved +echo "DNSStubListener=no" >>/etc/systemd/resolved.conf +ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf +wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh +$STD bash install.sh +rm install.sh +msg_ok "Installed AdGuard Home" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/adguard-v5-install.sh b/install/adguard-v5-install.sh deleted file mode 100644 index 4f8ae86e..00000000 --- a/install/adguard-v5-install.sh +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing AdGuard Home" -systemctl stop systemd-resolved -echo "DNSStubListener=no" >>/etc/systemd/resolved.conf -ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh -$STD bash install.sh -rm install.sh -msg_ok "Installed AdGuard Home" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/alpine-adguard-install.sh b/install/alpine-adguard-install.sh new file mode 100644 index 00000000..4dd81790 --- /dev/null +++ b/install/alpine-adguard-install.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add nano +$STD apk add mc +$STD apk add openssh +msg_ok "Installed Dependencies" + +msg_info "Installing Alpine-AdGuard" +VER=$(curl --silent -qI https://github.com/AdguardTeam/AdGuardHome/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); +$STD wget -q "https://github.com/AdguardTeam/AdGuardHome/releases/download/$VER/AdGuardHome_linux_amd64.tar.gz" +$STD tar -xvf AdGuardHome_linux_amd64.tar.gz >/dev/null 2>&1 +$STD mv AdGuardHome /opt +$STD rm AdGuardHome_linux_amd64.tar.gz +$STD chmod +x /opt/AdGuardHome/AdGuardHome +$STD /opt/AdGuardHome/AdGuardHome -s install +$STD /opt/AdGuardHome/AdGuardHome -s start +$STD msg_ok "Installed Alpine-AdGuard" + +motd_ssh diff --git a/install/alpine-adguard-v5-install.sh b/install/alpine-adguard-v5-install.sh deleted file mode 100644 index a5c73b3f..00000000 --- a/install/alpine-adguard-v5-install.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then -$STD sysctl net.ipv6.conf.all.disable_ipv6=1 -$STD sysctl net.ipv6.conf.default.disable_ipv6=1 -echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -$STD sysctl -p /etc/sysctl.d/99-sysctl.conf -fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -i=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -while [ $i -gt 0 ]; do - if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - i=$((i-1)) -done - -if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/latest-stable/main -https://dl-cdn.alpinelinux.org/alpine/latest-stable/community -EOF -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi - -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apk update -$STD apk upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apk add wget -$STD apk add bash -$STD apk add curl -$STD apk add nano -$STD apk add mc -$STD apk add openssh -msg_ok "Installed Dependencies" - -msg_info "Installing $APPLICATION" -VER=$(curl --silent -qI https://github.com/AdguardTeam/AdGuardHome/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); -$STD wget -q "https://github.com/AdguardTeam/AdGuardHome/releases/download/$VER/AdGuardHome_linux_amd64.tar.gz" -$STD tar -xvf AdGuardHome_linux_amd64.tar.gz >/dev/null 2>&1 -$STD mv AdGuardHome /opt -$STD rm AdGuardHome_linux_amd64.tar.gz -$STD chmod +x /opt/AdGuardHome/AdGuardHome -$STD /opt/AdGuardHome/AdGuardHome -s install -$STD /opt/AdGuardHome/AdGuardHome -s start -$STD msg_ok "Installed $APPLICATION" - -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -if [[ "${SSH_ROOT}" == "yes" ]]; then - $STD rc-update add sshd - $STD /etc/init.d/sshd start -fi diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh new file mode 100644 index 00000000..ac7dce79 --- /dev/null +++ b/install/alpine-docker-install.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing Docker" +$STD apk add docker +$STD rc-service docker start +$STD rc-update add docker default +msg_ok "Installed Docker" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") +DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") + +read -r -p "Would you like to add Portainer? " prompt +if echo "$prompt" | grep -Eq "^(y|yes)$"; then + msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" + docker volume create portainer_data >/dev/null + $STD docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest + msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" +fi + +read -r -p "Would you like to add Docker Compose? " prompt +if echo "$prompt" | grep -Eq "^(y|yes)$"; then + msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} + mkdir -p $DOCKER_CONFIG/cli-plugins + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose + chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose + msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" +fi + +motd_ssh diff --git a/install/alpine-docker-v5-install.sh b/install/alpine-docker-v5-install.sh deleted file mode 100644 index 8a36fa0e..00000000 --- a/install/alpine-docker-v5-install.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then -$STD sysctl net.ipv6.conf.all.disable_ipv6=1 -$STD sysctl net.ipv6.conf.default.disable_ipv6=1 -echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -$STD sysctl -p /etc/sysctl.d/99-sysctl.conf -fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -i=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -while [ $i -gt 0 ]; do - if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - i=$((i-1)) -done - -if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/latest-stable/main -https://dl-cdn.alpinelinux.org/alpine/latest-stable/community -https://dl-cdn.alpinelinux.org/alpine/edge/testing -EOF -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi - -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apk update -$STD apk upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apk add bash -$STD apk add curl -$STD apk add openssl -$STD apk add openssh -$STD apk add nano -$STD apk add mc -msg_ok "Installed Dependencies" - -msg_info "Installing $APPLICATION" -$STD apk add docker -$STD rc-service docker start -$STD rc-update add docker default -msg_ok "Installed $APPLICATION" - -get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} -PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") -DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") - -read -r -p "Would you like to add Portainer? " prompt -if echo "$prompt" | grep -Eq "^(y|yes)$"; then - msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" - docker volume create portainer_data >/dev/null - $STD docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest - msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" -fi - -read -r -p "Would you like to add Docker Compose? " prompt -if echo "$prompt" | grep -Eq "^(y|yes)$"; then - msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" - DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} - mkdir -p $DOCKER_CONFIG/cli-plugins - curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose - chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose - msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" -fi - -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -if [[ "${SSH_ROOT}" == "yes" ]]; then - $STD rc-update add sshd - $STD /etc/init.d/sshd start -fi diff --git a/install/alpine-grafana-install.sh b/install/alpine-grafana-install.sh new file mode 100644 index 00000000..86f1e97d --- /dev/null +++ b/install/alpine-grafana-install.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing Grafana" +$STD apk add grafana +$STD sed -i '/http_addr/s/127.0.0.1/0.0.0.0/g' /etc/conf.d/grafana +$STD rc-service grafana start +$STD rc-update add grafana default +msg_ok "Installed Grafana" + +motd_ssh diff --git a/install/alpine-grafana-v5-install.sh b/install/alpine-grafana-v5-install.sh deleted file mode 100644 index efd75bef..00000000 --- a/install/alpine-grafana-v5-install.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then -$STD sysctl net.ipv6.conf.all.disable_ipv6=1 -$STD sysctl net.ipv6.conf.default.disable_ipv6=1 -echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -$STD sysctl -p /etc/sysctl.d/99-sysctl.conf -fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -i=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -while [ $i -gt 0 ]; do - if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - i=$((i-1)) -done - -if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/latest-stable/main -https://dl-cdn.alpinelinux.org/alpine/latest-stable/community -EOF -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi - -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apk update -$STD apk upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apk add bash -$STD apk add curl -$STD apk add openssh -$STD apk add nano -$STD apk add mc -msg_ok "Installed Dependencies" - -msg_info "Installing $APPLICATION" -$STD apk add grafana -$STD sed -i '/http_addr/s/127.0.0.1/0.0.0.0/g' /etc/conf.d/grafana -$STD rc-service grafana start -$STD rc-update add grafana default -msg_ok "Installed $APPLICATION" - -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -if [[ "${SSH_ROOT}" == "yes" ]]; then - $STD rc-update add sshd - $STD /etc/init.d/sshd start -fi diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh new file mode 100644 index 00000000..952922e7 --- /dev/null +++ b/install/alpine-vaultwarden-install.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing Alpine-Vaultwarden" +$STD apk add vaultwarden +cat </etc/conf.d/vaultwarden +export DATA_FOLDER=/var/lib/vaultwarden +export WEB_VAULT_FOLDER=/var/lib/vaultwarden/web-vault +export WEB_VAULT_ENABLED=true +export ADMIN_TOKEN=$(openssl rand -base64 48) +export ROCKET_ADDRESS=0.0.0.0 +EOF +$STD rc-service vaultwarden start +$STD rc-update add vaultwarden default +msg_ok "Installed Alpine-Vaultwarden" + +motd_ssh diff --git a/install/alpine-vaultwarden-v5-install.sh b/install/alpine-vaultwarden-v5-install.sh deleted file mode 100644 index 02edeb1a..00000000 --- a/install/alpine-vaultwarden-v5-install.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then -$STD sysctl net.ipv6.conf.all.disable_ipv6=1 -$STD sysctl net.ipv6.conf.default.disable_ipv6=1 -echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -$STD sysctl -p /etc/sysctl.d/99-sysctl.conf -fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -i=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -while [ $i -gt 0 ]; do - if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - i=$((i-1)) -done - -if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/edge/main -https://dl-cdn.alpinelinux.org/alpine/edge/community -https://dl-cdn.alpinelinux.org/alpine/edge/testing -EOF -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi - -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apk update -$STD apk upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apk add bash -$STD apk add curl -$STD apk add openssl -$STD apk add openssh -$STD apk add nano -$STD apk add mc -msg_ok "Installed Dependencies" - -msg_info "Installing $APPLICATION" -$STD apk add vaultwarden -cat </etc/conf.d/vaultwarden -export DATA_FOLDER=/var/lib/vaultwarden -export WEB_VAULT_FOLDER=/var/lib/vaultwarden/web-vault -export WEB_VAULT_ENABLED=true -export ADMIN_TOKEN=$(openssl rand -base64 48) -export ROCKET_ADDRESS=0.0.0.0 -EOF -$STD rc-service vaultwarden start -$STD rc-update add vaultwarden default -msg_ok "Installed $APPLICATION" - -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -if [[ "${SSH_ROOT}" == "yes" ]]; then - $STD rc-update add sshd - $STD /etc/init.d/sshd start -fi diff --git a/install/alpine-zigbee2mqtt-install.sh b/install/alpine-zigbee2mqtt-install.sh new file mode 100644 index 00000000..f3698db9 --- /dev/null +++ b/install/alpine-zigbee2mqtt-install.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing Alpine-Zigbee2MQTT" +$STD apk add zigbee2mqtt +msg_ok "Installed Alpine-Zigbee2MQTT" + +motd_ssh diff --git a/install/alpine-zigbee2mqtt-v5-install.sh b/install/alpine-zigbee2mqtt-v5-install.sh deleted file mode 100644 index 26c35768..00000000 --- a/install/alpine-zigbee2mqtt-v5-install.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then -$STD sysctl net.ipv6.conf.all.disable_ipv6=1 -$STD sysctl net.ipv6.conf.default.disable_ipv6=1 -echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-sysctl.conf -$STD sysctl -p /etc/sysctl.d/99-sysctl.conf -fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -i=$RETRY_NUM -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -while [ $i -gt 0 ]; do - if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY - i=$((i-1)) -done - -if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/latest-stable/main -https://dl-cdn.alpinelinux.org/alpine/latest-stable/community -https://dl-cdn.alpinelinux.org/alpine/edge/testing -EOF -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if echo "$prompt" | grep -Ei "^(y|yes)$" > /dev/null; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi - -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apk update -$STD apk upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apk add bash -$STD apk add curl -$STD apk add openssl -$STD apk add openssh -$STD apk add nano -$STD apk add mc -msg_ok "Installed Dependencies" - -msg_info "Installing $APPLICATION" -$STD apk add zigbee2mqtt -msg_ok "Installed $APPLICATION" - -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -if [[ "${SSH_ROOT}" == "yes" ]]; then - $STD rc-update add sshd - $STD /etc/init.d/sshd start -fi diff --git a/install/audiobookshelf-install.sh b/install/audiobookshelf-install.sh new file mode 100644 index 00000000..5586918e --- /dev/null +++ b/install/audiobookshelf-install.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y gnupg +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing audiobookshelf" +$STD apt-key add <(curl -s --compressed "https://advplyr.github.io/audiobookshelf-ppa/KEY.gpg") +sh -c 'echo "deb https://advplyr.github.io/audiobookshelf-ppa ./" > /etc/apt/sources.list.d/audiobookshelf.list' +$STD apt-get update +$STD apt install audiobookshelf +msg_ok "Installed audiobookshelf" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/audiobookshelf-v5-install.sh b/install/audiobookshelf-v5-install.sh deleted file mode 100644 index f32761b2..00000000 --- a/install/audiobookshelf-v5-install.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y gnupg -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing audiobookshelf" -$STD apt-key add <(curl -s --compressed "https://advplyr.github.io/audiobookshelf-ppa/KEY.gpg") -sh -c 'echo "deb https://advplyr.github.io/audiobookshelf-ppa ./" > /etc/apt/sources.list.d/audiobookshelf.list' -$STD apt-get update -$STD apt install audiobookshelf -msg_ok "Installed audiobookshelf" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/autobrr-install.sh b/install/autobrr-install.sh new file mode 100644 index 00000000..dbf1cea3 --- /dev/null +++ b/install/autobrr-install.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Autobrr" +wget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\" -f4) +tar -C /usr/local/bin -xzf autobrr*.tar.gz +rm -rf autobrr*.tar.gz +mkdir -p /root/.config/autobrr +cat <>/root/.config/autobrr/config.toml +# https://autobrr.com/configuration/autobrr +host = "0.0.0.0" +port = 7474 +logLevel = "DEBUG" +sessionSecret = "$(openssl rand -base64 24)" +EOF +msg_ok "Installed Autobrr" + +msg_info "Creating Service" +service_path="/etc/systemd/system/autobrr.service" +echo "[Unit] +Description=autobrr service +After=syslog.target network-online.target +[Service] +Type=simple +User=root +Group=root +ExecStart=/usr/local/bin/autobrr --config=/root/.config/autobrr/ +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q autobrr.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/autobrr-v5-install.sh b/install/autobrr-v5-install.sh deleted file mode 100644 index 61a9c8c2..00000000 --- a/install/autobrr-v5-install.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Autobrr" -wget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\" -f4) -tar -C /usr/local/bin -xzf autobrr*.tar.gz -rm -rf autobrr*.tar.gz -mkdir -p /root/.config/autobrr -cat <>/root/.config/autobrr/config.toml -# https://autobrr.com/configuration/autobrr -host = "0.0.0.0" -port = 7474 -logLevel = "DEBUG" -sessionSecret = "$(openssl rand -base64 24)" -EOF -msg_ok "Installed Autobrr" - -msg_info "Creating Service" -service_path="/etc/systemd/system/autobrr.service" -echo "[Unit] -Description=autobrr service -After=syslog.target network-online.target -[Service] -Type=simple -User=root -Group=root -ExecStart=/usr/local/bin/autobrr --config=/root/.config/autobrr/ -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q autobrr.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/blocky-v5-install.sh b/install/blocky-install.sh similarity index 79% rename from install/blocky-v5-install.sh rename to install/blocky-install.sh index aa1722b0..e4656a13 100644 --- a/install/blocky-v5-install.sh +++ b/install/blocky-install.sh @@ -5,85 +5,13 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os msg_info "Installing Dependencies" $STD apt-get install -y curl @@ -353,23 +281,8 @@ EOF $STD systemctl enable --now blocky msg_ok "Created Service" -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi +motd_ssh +root msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/casaos-install.sh b/install/casaos-install.sh new file mode 100644 index 00000000..cf4ee609 --- /dev/null +++ b/install/casaos-install.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing CasaOS (Patience)" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +fi +$STD bash <(curl -fsSL https://get.casaos.io) +msg_ok "Installed CasaOS" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/casaos-v5-install.sh b/install/casaos-v5-install.sh deleted file mode 100644 index 22f05ba7..00000000 --- a/install/casaos-v5-install.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y unzip -msg_ok "Installed Dependencies" - -msg_info "Installing CasaOS (Patience)" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi -$STD bash <(curl -fsSL https://get.casaos.io) -msg_ok "Installed CasaOS" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh new file mode 100644 index 00000000..fc9832c7 --- /dev/null +++ b/install/changedetection-install.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y pip +msg_ok "Installed Dependencies" + +msg_info "Installing Change Detection" +mkdir /opt/changedetection +$STD pip3 install changedetection.io +$STD python3 -m pip install dnspython==2.2.1 +msg_ok "Installed Change Detection" + +msg_info "Creating Service" +cat </etc/systemd/system/changedetection.service +[Unit] +Description=Change Detection +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/opt/changedetection +ExecStart=changedetection.io -d /opt/changedetection -p 5000 +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now changedetection +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/changedetection-v5-install.sh b/install/changedetection-v5-install.sh deleted file mode 100644 index 433ee0f9..00000000 --- a/install/changedetection-v5-install.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y pip -msg_ok "Installed Dependencies" - -msg_info "Installing Change Detection" -mkdir /opt/changedetection -$STD pip3 install changedetection.io -$STD python3 -m pip install dnspython==2.2.1 -msg_ok "Installed Change Detection" - -msg_info "Creating Service" -cat </etc/systemd/system/changedetection.service -[Unit] -Description=Change Detection -After=network-online.target -[Service] -Type=simple -WorkingDirectory=/opt/changedetection -ExecStart=changedetection.io -d /opt/changedetection -p 5000 -[Install] -WantedBy=multi-user.target -EOF -$STD systemctl enable --now changedetection -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/cronicle-install.sh b/install/cronicle-install.sh new file mode 100644 index 00000000..1060a494 --- /dev/null +++ b/install/cronicle-install.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Cronicle Primary Server" +LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +IP=$(hostname -I | awk '{print $1}') +mkdir -p /opt/cronicle +cd /opt/cronicle +$STD tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 +$STD npm install +$STD node bin/build.js dist +sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json +if [[ $SERV == "y" ]]; then $STD /opt/cronicle/bin/control.sh setup; fi +$STD /opt/cronicle/bin/control.sh start +$STD cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled +chmod 775 /etc/init.d/cronicled +$STD update-rc.d cronicled defaults +msg_ok "Installed Cronicle Primary Server" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/cronicle-v5-install.sh b/install/cronicle-v5-install.sh deleted file mode 100644 index d9addbf6..00000000 --- a/install/cronicle-v5-install.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -$STD apt-get install -y make -$STD apt-get install -y g++ -$STD apt-get install -y gcc -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing Cronicle Primary Server" -LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -IP=$(hostname -I | awk '{print $1}') -mkdir -p /opt/cronicle -cd /opt/cronicle -$STD tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 -$STD npm install -$STD node bin/build.js dist -sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json -if [[ $SERV == "y" ]]; then $STD /opt/cronicle/bin/control.sh setup; fi -$STD /opt/cronicle/bin/control.sh start -$STD cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled -chmod 775 /etc/init.d/cronicled -$STD update-rc.d cronicled defaults -msg_ok "Installed Cronicle Primary Server" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/daemonsync-install.sh b/install/daemonsync-install.sh new file mode 100644 index 00000000..dead1801 --- /dev/null +++ b/install/daemonsync-install.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y g++-multilib +msg_ok "Installed Dependencies" + +msg_info "Installing Daemon Sync Server" +wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_amd64.deb +$STD dpkg -i daemonsync_2.2.0.0059_amd64.deb +msg_ok "Installed Daemon Sync Server" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf daemonsync_2.2.0.0059_amd64.deb +$STD apt-get autoremove >/dev/null +$STD apt-get autoclean >/dev/null +msg_ok "Cleaned" diff --git a/install/daemonsync-v5-install.sh b/install/daemonsync-v5-install.sh deleted file mode 100644 index abe4dec6..00000000 --- a/install/daemonsync-v5-install.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y g++-multilib -msg_ok "Installed Dependencies" - -msg_info "Installing Daemon Sync Server" -wget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_amd64.deb -$STD dpkg -i daemonsync_2.2.0.0059_amd64.deb -msg_ok "Installed Daemon Sync Server" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf daemonsync_2.2.0.0059_amd64.deb -$STD apt-get autoremove >/dev/null -$STD apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/dashy-install.sh b/install/dashy-install.sh new file mode 100644 index 00000000..089fcdde --- /dev/null +++ b/install/dashy-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs git make g++ gcc +msg_ok "Installed Node.js" + +msg_info "Installing Yarn" +$STD npm install --global yarn +msg_ok "Installed Yarn" + +msg_info "Installing Dashy (Patience)" +$STD git clone https://github.com/Lissy93/dashy.git +cd /dashy +$STD yarn +export NODE_OPTIONS=--max-old-space-size=1000 +$STD yarn build +msg_ok "Installed Dashy" + +msg_info "Creating Service" +cat </etc/systemd/system/dashy.service +[Unit] +Description=dashy + +[Service] +Type=simple +WorkingDirectory=/dashy +ExecStart=/usr/bin/yarn start +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable dashy +systemctl start dashy +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/dashy-v5-install.sh b/install/dashy-v5-install.sh deleted file mode 100644 index 1bd8e71d..00000000 --- a/install/dashy-v5-install.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs git make g++ gcc -msg_ok "Installed Node.js" - -msg_info "Installing Yarn" -$STD npm install --global yarn -msg_ok "Installed Yarn" - -msg_info "Installing Dashy (Patience)" -$STD git clone https://github.com/Lissy93/dashy.git -cd /dashy -$STD yarn -export NODE_OPTIONS=--max-old-space-size=1000 -$STD yarn build -msg_ok "Installed Dashy" - -msg_info "Creating Service" -cat </etc/systemd/system/dashy.service -[Unit] -Description=dashy - -[Service] -Type=simple -WorkingDirectory=/dashy -ExecStart=/usr/bin/yarn start -[Install] -WantedBy=multi-user.target -EOF -$STD systemctl enable dashy -systemctl start dashy -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/debian-install.sh b/install/debian-install.sh new file mode 100644 index 00000000..0e4905fb --- /dev/null +++ b/install/debian-install.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" \ No newline at end of file diff --git a/install/debian-v5-install.sh b/install/debian-v5-install.sh deleted file mode 100644 index ef9e1a6f..00000000 --- a/install/debian-v5-install.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/deconz-install.sh b/install/deconz-install.sh new file mode 100644 index 00000000..068cf5f3 --- /dev/null +++ b/install/deconz-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Setting Phoscon Repository" +$STD apt-key add <(curl -fsSL http://phoscon.de/apt/deconz.pub.key) +sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" +msg_ok "Setup Phoscon Repository" + +msg_info "Installing deConz" +$STD apt-get update +$STD apt-get install -y deconz +msg_ok "Installed deConz" + +msg_info "Creating Service" +service_path="/lib/systemd/system/deconz.service" +echo "[Unit] +Description=deCONZ: ZigBee gateway -- REST API +Wants=deconz-init.service deconz-update.service +StartLimitIntervalSec=0 + +[Service] +User=root +ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80 +Restart=on-failure +RestartSec=30 +AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now deconz +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/deconz-v5-install.sh b/install/deconz-v5-install.sh deleted file mode 100644 index ad060379..00000000 --- a/install/deconz-v5-install.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -msg_ok "Installed Dependencies" - -msg_info "Setting Phoscon Repository" -$STD apt-key add <(curl -fsSL http://phoscon.de/apt/deconz.pub.key) -sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" -msg_ok "Setup Phoscon Repository" - -msg_info "Installing deConz" -$STD apt-get update -$STD apt-get install -y deconz -msg_ok "Installed deConz" - -msg_info "Creating Service" -service_path="/lib/systemd/system/deconz.service" -echo "[Unit] -Description=deCONZ: ZigBee gateway -- REST API -Wants=deconz-init.service deconz-update.service -StartLimitIntervalSec=0 - -[Service] -User=root -ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80 -Restart=on-failure -RestartSec=30 -AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME - -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now deconz -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/deluge-install.sh b/install/deluge-install.sh new file mode 100644 index 00000000..1a55fb27 --- /dev/null +++ b/install/deluge-install.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Python3-pip" +$STD apt-get install -y python3-pip +msg_ok "Installed Python3-pip" + +msg_info "Installing Deluge" +$STD pip install deluge[all] +$STD pip install lbry-libtorrent +msg_ok "Installed Deluge" + +msg_info "Creating Service" +service_path="/etc/systemd/system/deluged.service" +echo "[Unit] +Description=Deluge Bittorrent Client Daemon +Documentation=man:deluged +After=network-online.target + +[Service] +Type=simple +UMask=007 +ExecStart=/usr/local/bin/deluged -d +Restart=on-failure +TimeoutStopSec=300 + +[Install] +WantedBy=multi-user.target" >$service_path + +service_path="/etc/systemd/system/deluge-web.service" +echo "[Unit] +Description=Deluge Bittorrent Client Web Interface +Documentation=man:deluge-web +After=deluged.service +Wants=deluged.service + +[Service] +Type=simple +UMask=027 +ExecStart=/usr/local/bin/deluge-web -d +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q deluged.service +systemctl enable --now -q deluge-web.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/deluge-v5-install.sh b/install/deluge-v5-install.sh deleted file mode 100644 index dbc85972..00000000 --- a/install/deluge-v5-install.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" - -msg_info "Installing Deluge" -$STD pip install deluge[all] -$STD pip install lbry-libtorrent -msg_ok "Installed Deluge" - -msg_info "Creating Service" -service_path="/etc/systemd/system/deluged.service" -echo "[Unit] -Description=Deluge Bittorrent Client Daemon -Documentation=man:deluged -After=network-online.target - -[Service] -Type=simple -UMask=007 -ExecStart=/usr/local/bin/deluged -d -Restart=on-failure -TimeoutStopSec=300 - -[Install] -WantedBy=multi-user.target" >$service_path - -service_path="/etc/systemd/system/deluge-web.service" -echo "[Unit] -Description=Deluge Bittorrent Client Web Interface -Documentation=man:deluge-web -After=deluged.service -Wants=deluged.service - -[Service] -Type=simple -UMask=027 -ExecStart=/usr/local/bin/deluge-web -d -Restart=on-failure - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q deluged.service -systemctl enable --now -q deluge-web.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/devuan-install.sh b/install/devuan-install.sh new file mode 100644 index 00000000..eb2b237b --- /dev/null +++ b/install/devuan-install.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/devuan-v5-install.sh b/install/devuan-v5-install.sh deleted file mode 100644 index a8ca650d..00000000 --- a/install/devuan-v5-install.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/docker-install.sh b/install/docker-install.sh new file mode 100644 index 00000000..c2a33444 --- /dev/null +++ b/install/docker-install.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") +DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") + +msg_info "Installing Docker $DOCKER_LATEST_VERSION" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +fi +$STD sh <(curl -sSL https://get.docker.com) +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" + +read -r -p "Would you like to add Portainer? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" + docker volume create portainer_data >/dev/null + $STD docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest + msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" +fi + +read -r -p "Would you like to add Docker Compose? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} + mkdir -p $DOCKER_CONFIG/cli-plugins + curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose + chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose + msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" +fi + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/docker-v5-install.sh b/install/docker-v5-install.sh deleted file mode 100644 index 83339fb5..00000000 --- a/install/docker-v5-install.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} - -DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") -PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") -DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") - -msg_info "Installing Docker $DOCKER_LATEST_VERSION" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi -$STD sh <(curl -sSL https://get.docker.com) -msg_ok "Installed Docker $DOCKER_LATEST_VERSION" - -read -r -p "Would you like to add Portainer? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" - docker volume create portainer_data >/dev/null - $STD docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest - msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" -fi - -read -r -p "Would you like to add Docker Compose? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" - DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} - mkdir -p $DOCKER_CONFIG/cli-plugins - curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose - chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose - msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" -fi - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/emby-install.sh b/install/emby-install.sh new file mode 100644 index 00000000..668222f7 --- /dev/null +++ b/install/emby-install.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 + if [[ ${PCT_OSVERSION} == "20.04" ]]; then + $STD apt-get install -y beignet-opencl-icd + else + $STD apt-get install -y intel-opencl-icd + fi + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + +LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) + +msg_info "Installing Emby" +wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb +$STD dpkg -i emby-server-deb_${LATEST}_amd64.deb +msg_ok "Installed Emby" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm emby-server-deb_${LATEST}_amd64.deb +msg_ok "Cleaned" diff --git a/install/emby-v5-install.sh b/install/emby-v5-install.sh deleted file mode 100644 index 0a41c2c5..00000000 --- a/install/emby-v5-install.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then - $STD apt-get install -y beignet-opencl-icd - else - $STD apt-get install -y intel-opencl-icd - fi - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* - msg_ok "Set Up Hardware Acceleration" -fi - -LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) - -msg_info "Installing Emby" -wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb -$STD dpkg -i emby-server-deb_${LATEST}_amd64.deb -msg_ok "Installed Emby" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -rm emby-server-deb_${LATEST}_amd64.deb -msg_ok "Cleaned" diff --git a/install/emqx-install.sh b/install/emqx-install.sh new file mode 100644 index 00000000..74b3c2d3 --- /dev/null +++ b/install/emqx-install.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing EMQX" +$STD bash <(curl -fsSL https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh) +$STD apt-get install -y emqx +$STD systemctl enable --now emqx +msg_ok "Installed EMQX" + +motd_ssh +root + +msg_info "Cleaning up" +apt-get autoremove >/dev/null +apt-get autoclean >/dev/null +msg_ok "Cleaned" diff --git a/install/emqx-v5-install.sh b/install/emqx-v5-install.sh deleted file mode 100644 index 853a3cdb..00000000 --- a/install/emqx-v5-install.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing EMQX" -$STD bash <(curl -fsSL https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh) -$STD apt-get install -y emqx -$STD systemctl enable --now emqx -msg_ok "Installed EMQX" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -apt-get autoremove >/dev/null -apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/esphome-install.sh b/install/esphome-install.sh new file mode 100644 index 00000000..fe8e8e46 --- /dev/null +++ b/install/esphome-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Installing Python3-pip" +$STD apt-get install -y python3-pip +msg_ok "Installed Python3-pip" + +msg_info "Installing ESPHome" +$STD pip3 install esphome +msg_ok "Installed ESPHome" + +msg_info "Installing ESPHome Dashboard" +$STD pip3 install tornado esptool + +service_path="/etc/systemd/system/esphomeDashboard.service" +echo "[Unit] +Description=ESPHome Dashboard +After=network.target +[Service] +ExecStart=/usr/local/bin/esphome /root/config/ dashboard +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable esphomeDashboard.service +systemctl start esphomeDashboard +msg_ok "Installed ESPHome Dashboard" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/esphome-v5-install.sh b/install/esphome-v5-install.sh deleted file mode 100644 index 7bd8b99f..00000000 --- a/install/esphome-v5-install.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" - -msg_info "Installing ESPHome" -$STD pip3 install esphome -msg_ok "Installed ESPHome" - -msg_info "Installing ESPHome Dashboard" -$STD pip3 install tornado esptool - -service_path="/etc/systemd/system/esphomeDashboard.service" -echo "[Unit] -Description=ESPHome Dashboard -After=network.target -[Service] -ExecStart=/usr/local/bin/esphome /root/config/ dashboard -Restart=always -User=root -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable esphomeDashboard.service -systemctl start esphomeDashboard -msg_ok "Installed ESPHome Dashboard" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/go2rtc-install.sh b/install/go2rtc-install.sh new file mode 100644 index 00000000..75211aeb --- /dev/null +++ b/install/go2rtc-install.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing go2rtc" +mkdir -p /opt/go2rtc +cd /opt/go2rtc +wget -q https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64 +chmod +x go2rtc_linux_amd64 +msg_ok "Installed go2rtc" + +msg_info "Creating Service" +service_path="/etc/systemd/system/go2rtc.service" +echo "[Unit] +Description=go2rtc service +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/opt/go2rtc/go2rtc_linux_amd64 + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable -q --now go2rtc +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/go2rtc-v5-install.sh b/install/go2rtc-v5-install.sh deleted file mode 100644 index 57577695..00000000 --- a/install/go2rtc-v5-install.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing go2rtc" -mkdir -p /opt/go2rtc -cd /opt/go2rtc -wget -q https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64 -chmod +x go2rtc_linux_amd64 -msg_ok "Installed go2rtc" - -msg_info "Creating Service" -service_path="/etc/systemd/system/go2rtc.service" -echo "[Unit] -Description=go2rtc service -After=network.target - -[Service] -Type=simple -User=root -ExecStart=/opt/go2rtc/go2rtc_linux_amd64 - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable -q --now go2rtc -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/grafana-install.sh b/install/grafana-install.sh new file mode 100644 index 00000000..718cc230 --- /dev/null +++ b/install/grafana-install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +$STD apt-get install -y apt-transport-https +$STD apt-get install -y software-properties-common +msg_ok "Installed Dependencies" + +msg_info "Setting up Grafana Repository" +wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key +sh -c 'echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list' +msg_ok "Set up Grafana Repository" + +msg_info "Installing Grafana" +$STD apt-get update +$STD apt-get install -y grafana +msg_ok "Installed Grafana" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/grafana-v5-install.sh b/install/grafana-v5-install.sh deleted file mode 100644 index 9b327c23..00000000 --- a/install/grafana-v5-install.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -$STD apt-get install -y apt-transport-https -$STD apt-get install -y software-properties-common -msg_ok "Installed Dependencies" - -msg_info "Setting up Grafana Repository" -wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key -sh -c 'echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list' -msg_ok "Set up Grafana Repository" - -msg_info "Installing Grafana" -$STD apt-get update -$STD apt-get install -y grafana -msg_ok "Installed Grafana" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi -systemctl start grafana-server -$STD systemctl enable grafana-server.service - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/grocy-install.sh b/install/grocy-install.sh new file mode 100644 index 00000000..b51cfbcc --- /dev/null +++ b/install/grocy-install.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y apache2 +$STD apt-get install -y unzip +$STD apt-get install -y apt-transport-https +$STD apt-get install -y lsb-release +msg_ok "Installed Dependencies" + +msg_info "Installing PHP 8.1" +curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg +sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' +$STD apt-get update +$STD apt-get install -y php8.1 +$STD apt-get install -y libapache2-mod-php8.1 +$STD apt-get install -y php8.1-sqlite3 +$STD apt-get install -y php8.1-gd +$STD apt-get install -y php8.1-intl +$STD apt-get install -y php8.1-mbstring +msg_ok "Installed PHP 8.1" + +msg_info "Installing grocy" +wget -q https://releases.grocy.info/latest +$STD unzip latest -d /var/www/html +chown -R www-data:www-data /var/www/html +cp /var/www/html/config-dist.php /var/www/html/data/config.php +chmod +x /var/www/html/update.sh + +cat </etc/apache2/sites-available/grocy.conf + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html/public + ErrorLog /var/log/apache2/error.log + + Options Indexes FollowSymLinks MultiViews + AllowOverride All + Order allow,deny + allow from all + + +EOF + +$STD a2dissite 000-default.conf +$STD a2ensite grocy.conf +$STD a2enmod rewrite +systemctl reload apache2 +msg_ok "Installed grocy" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/latest +msg_ok "Cleaned" diff --git a/install/grocy-v5-install.sh b/install/grocy-v5-install.sh deleted file mode 100644 index f5bf1469..00000000 --- a/install/grocy-v5-install.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y apache2 -$STD apt-get install -y unzip -$STD apt-get install -y apt-transport-https -$STD apt-get install -y lsb-release -msg_ok "Installed Dependencies" - -msg_info "Installing PHP 8.1" -curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg -sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' -$STD apt-get update -$STD apt-get install -y php8.1 -$STD apt-get install -y libapache2-mod-php8.1 -$STD apt-get install -y php8.1-sqlite3 -$STD apt-get install -y php8.1-gd -$STD apt-get install -y php8.1-intl -$STD apt-get install -y php8.1-mbstring -msg_ok "Installed PHP 8.1" - -msg_info "Installing grocy" -wget -q https://releases.grocy.info/latest -$STD unzip latest -d /var/www/html -chown -R www-data:www-data /var/www/html -cp /var/www/html/config-dist.php /var/www/html/data/config.php -chmod +x /var/www/html/update.sh - -cat </etc/apache2/sites-available/grocy.conf - - ServerAdmin webmaster@localhost - DocumentRoot /var/www/html/public - ErrorLog /var/log/apache2/error.log - - Options Indexes FollowSymLinks MultiViews - AllowOverride All - Order allow,deny - allow from all - - -EOF - -$STD a2dissite 000-default.conf -$STD a2ensite grocy.conf -$STD a2enmod rewrite -systemctl reload apache2 -msg_ok "Installed grocy" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -rm -rf /root/latest -msg_ok "Cleaned" diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh new file mode 100644 index 00000000..8e83e9ef --- /dev/null +++ b/install/heimdalldashboard-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing PHP" +$STD apt-get install -y php +$STD apt-get install -y php-sqlite3 +$STD apt-get install -y php-zip +msg_ok "Installed PHP" + +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +msg_info "Installing Heimdall Dashboard ${RELEASE}" +$STD curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" +$STD tar xvzf ${RELEASE}.tar.gz +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') +rm -rf ${RELEASE}.tar.gz +mv Heimdall-${VER} /opt/Heimdall +msg_ok "Installed Heimdall Dashboard ${RELEASE}" + +msg_info "Creating Service" +service_path="/etc/systemd/system/heimdall.service" +echo "[Unit] +Description=Heimdall +After=network.target + +[Service] +Restart=always +RestartSec=5 +Type=simple +User=root +WorkingDirectory=/opt/Heimdall +ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 +TimeoutStopSec=30 + +[Install] +WantedBy=multi-user.target" >$service_path +$STD sudo systemctl enable --now heimdall.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/heimdalldashboard-v5-install.sh b/install/heimdalldashboard-v5-install.sh deleted file mode 100644 index 4fcc9888..00000000 --- a/install/heimdalldashboard-v5-install.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing PHP" -$STD apt-get install -y php -$STD apt-get install -y php-sqlite3 -$STD apt-get install -y php-zip -msg_ok "Installed PHP" - -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -msg_info "Installing Heimdall Dashboard ${RELEASE}" -$STD curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" -$STD tar xvzf ${RELEASE}.tar.gz -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') -rm -rf ${RELEASE}.tar.gz -mv Heimdall-${VER} /opt/Heimdall -msg_ok "Installed Heimdall Dashboard ${RELEASE}" - -msg_info "Creating Service" -service_path="/etc/systemd/system/heimdall.service" -echo "[Unit] -Description=Heimdall -After=network.target - -[Service] -Restart=always -RestartSec=5 -Type=simple -User=root -WorkingDirectory=/opt/Heimdall -ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 -TimeoutStopSec=30 - -[Install] -WantedBy=multi-user.target" >$service_path -$STD sudo systemctl enable --now heimdall.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh new file mode 100644 index 00000000..d7b64ad1 --- /dev/null +++ b/install/homeassistant-core-install.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y \ + make \ + build-essential \ + libjpeg-dev \ + libpcap-dev \ + libssl-dev \ + zlib1g-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + libmariadb-dev-compat \ + autoconf \ + git \ + curl \ + sudo \ + mc \ + llvm \ + libncursesw5-dev \ + xz-utils \ + tzdata \ + bluez \ + tk-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libffi-dev \ + libopenjp2-7 \ + libtiff5 \ + libturbojpeg0-dev \ + liblzma-dev +msg_ok "Installed Dependencies" + +msg_info "Installing Linux D-Bus Message Broker" +cat <>/etc/apt/sources.list +deb http://deb.debian.org/debian bullseye-backports main contrib non-free +deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free +EOF +$STD apt-get update +$STD apt-get -t bullseye-backports install -y dbus-broker +$STD systemctl enable --now dbus-broker.service +msg_ok "Installed Linux D-Bus Message Broker" + +msg_info "Installing pyenv" +$STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv +set +e +echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc +echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc +echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc +msg_ok "Installed pyenv" +. ~/.bashrc +set -e +msg_info "Installing Python 3.11.1" +$STD pyenv install 3.11.1 +pyenv global 3.11.1 +msg_ok "Installed Python 3.11.1" + +msg_info "Installing Home Assistant-Core" +mkdir /srv/homeassistant +cd /srv/homeassistant +python3 -m venv . +source bin/activate +$STD pip install --upgrade pip +$STD python3 -m pip install wheel +$STD pip install mysqlclient +$STD pip install psycopg2-binary +$STD pip install homeassistant +mkdir -p /root/.homeassistant +msg_ok "Installed Home Assistant-Core" + +msg_info "Creating Service" +cat </etc/systemd/system/homeassistant.service +[Unit] +Description=Home Assistant +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/root/.homeassistant +ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" +RestartForceExitStatus=100 +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now homeassistant +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/homeassistant-core-v5-install.sh b/install/homeassistant-core-v5-install.sh deleted file mode 100644 index 71f3186d..00000000 --- a/install/homeassistant-core-v5-install.sh +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y \ - make \ - build-essential \ - libjpeg-dev \ - libpcap-dev \ - libssl-dev \ - zlib1g-dev \ - libbz2-dev \ - libreadline-dev \ - libsqlite3-dev \ - libmariadb-dev-compat \ - autoconf \ - git \ - curl \ - sudo \ - mc \ - llvm \ - libncursesw5-dev \ - xz-utils \ - tzdata \ - bluez \ - tk-dev \ - libxml2-dev \ - libxmlsec1-dev \ - libffi-dev \ - libopenjp2-7 \ - libtiff5 \ - libturbojpeg0-dev \ - liblzma-dev -msg_ok "Installed Dependencies" - -msg_info "Installing Linux D-Bus Message Broker" -cat <>/etc/apt/sources.list -deb http://deb.debian.org/debian bullseye-backports main contrib non-free -deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free -EOF -$STD apt-get update -$STD apt-get -t bullseye-backports install -y dbus-broker -$STD systemctl enable --now dbus-broker.service -msg_ok "Installed Linux D-Bus Message Broker" - -msg_info "Installing pyenv" -$STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv -set +e -echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc -echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc -echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc -msg_ok "Installed pyenv" -. ~/.bashrc -set -e -msg_info "Installing Python 3.11.1" -$STD pyenv install 3.11.1 -pyenv global 3.11.1 -msg_ok "Installed Python 3.11.1" - -msg_info "Installing Home Assistant-Core" -mkdir /srv/homeassistant -cd /srv/homeassistant -python3 -m venv . -source bin/activate -$STD pip install --upgrade pip -$STD python3 -m pip install wheel -$STD pip install mysqlclient -$STD pip install psycopg2-binary -$STD pip install homeassistant -mkdir -p /root/.homeassistant -msg_ok "Installed Home Assistant-Core" - -msg_info "Creating Service" -cat </etc/systemd/system/homeassistant.service -[Unit] -Description=Home Assistant -After=network-online.target -[Service] -Type=simple -WorkingDirectory=/root/.homeassistant -ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" -RestartForceExitStatus=100 -[Install] -WantedBy=multi-user.target -EOF -$STD systemctl enable --now homeassistant -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh new file mode 100644 index 00000000..ab92e64a --- /dev/null +++ b/install/homeassistant-install.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing runlike" +$STD apt-get install -y python3-pip +$STD pip3 install runlike +msg_ok "Installed runlike" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") + +msg_info "Installing Docker $DOCKER_LATEST_VERSION" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +fi +$STD sh <(curl -sSL https://get.docker.com) +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" + +msg_info "Pulling Portainer $PORTAINER_LATEST_VERSION Image" +$STD docker pull portainer/portainer-ce:latest +msg_ok "Pulled Portainer $PORTAINER_LATEST_VERSION Image" + +msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" +$STD docker volume create portainer_data +$STD docker run -d \ + -p 8000:8000 \ + -p 9000:9000 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest +msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" + +msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" +$STD docker pull homeassistant/home-assistant:stable +msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" + +msg_info "Installing Home Assistant $CORE_LATEST_VERSION" +$STD docker volume create hass_config +$STD docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + homeassistant/home-assistant:stable + mkdir /root/hass_config +msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/homeassistant-v5-install.sh b/install/homeassistant-v5-install.sh deleted file mode 100644 index 12a5efbc..00000000 --- a/install/homeassistant-v5-install.sh +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing runlike" -$STD apt-get install -y python3-pip -$STD pip3 install runlike -msg_ok "Installed runlike" - -get_latest_release() { - curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 -} - -DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") -CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") -PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") - -msg_info "Installing Docker $DOCKER_LATEST_VERSION" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi -$STD sh <(curl -sSL https://get.docker.com) -msg_ok "Installed Docker $DOCKER_LATEST_VERSION" - -msg_info "Pulling Portainer $PORTAINER_LATEST_VERSION Image" -$STD docker pull portainer/portainer-ce:latest -msg_ok "Pulled Portainer $PORTAINER_LATEST_VERSION Image" - -msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" -$STD docker volume create portainer_data -$STD docker run -d \ - -p 8000:8000 \ - -p 9000:9000 \ - --name=portainer \ - --restart=always \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v portainer_data:/data \ - portainer/portainer-ce:latest -msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" - -msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" -$STD docker pull homeassistant/home-assistant:stable -msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" - -msg_info "Installing Home Assistant $CORE_LATEST_VERSION" -$STD docker volume create hass_config -$STD docker run -d \ - --name homeassistant \ - --privileged \ - --restart unless-stopped \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - --net=host \ - homeassistant/home-assistant:stable - mkdir /root/hass_config -msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh new file mode 100644 index 00000000..5c12bbfe --- /dev/null +++ b/install/homebridge-install.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs gcc g++ make python net-tools +msg_ok "Installed Node.js" + +msg_info "Installing Homebridge" +$STD npm install -g --unsafe-perm homebridge homebridge-config-ui-x +msg_info "Installed Homebridge" + +msg_info "Creating Service" +$STD hb-service install --user homebridge +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/homebridge-v5-install.sh b/install/homebridge-v5-install.sh deleted file mode 100644 index ac0fec01..00000000 --- a/install/homebridge-v5-install.sh +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs gcc g++ make python net-tools -msg_ok "Installed Node.js" - -msg_info "Installing Homebridge" -$STD npm install -g --unsafe-perm homebridge homebridge-config-ui-x -msg_info "Installed Homebridge" - -msg_info "Creating Service" -$STD hb-service install --user homebridge -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/homepage-install.sh b/install/homepage-install.sh new file mode 100644 index 00000000..4ebc685e --- /dev/null +++ b/install/homepage-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +$STD npm install -g pnpm +msg_ok "Installed Node.js" + +msg_info "Installing Homepage (Patience)" +$STD git clone https://github.com/benphelps/homepage.git /opt/homepage +cd /opt/homepage +mkdir -p config +cp /opt/homepage/src/skeleton/* /opt/homepage/config +$STD pnpm install +$STD pnpm build +msg_ok "Installed Homepage" + +msg_info "Creating Service" +service_path="/etc/systemd/system/homepage.service" +echo "[Unit] +Description=Homepage +After=network.target +StartLimitIntervalSec=0 +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +WorkingDirectory=/opt/homepage/ +ExecStart=pnpm start +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now homepage +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/homepage-v5-install.sh b/install/homepage-v5-install.sh deleted file mode 100644 index ca0fe0c4..00000000 --- a/install/homepage-v5-install.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -$STD npm install -g pnpm -msg_ok "Installed Node.js" - -msg_info "Installing Homepage (Patience)" -$STD git clone https://github.com/benphelps/homepage.git /opt/homepage -cd /opt/homepage -mkdir -p config -cp /opt/homepage/src/skeleton/* /opt/homepage/config -$STD pnpm install -$STD pnpm build -msg_ok "Installed Homepage" - -msg_info "Creating Service" -service_path="/etc/systemd/system/homepage.service" -echo "[Unit] -Description=Homepage -After=network.target -StartLimitIntervalSec=0 -[Service] -Type=simple -Restart=always -RestartSec=1 -User=root -WorkingDirectory=/opt/homepage/ -ExecStart=pnpm start -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now homepage -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/homer-install.sh b/install/homer-install.sh new file mode 100644 index 00000000..197af604 --- /dev/null +++ b/install/homer-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +$STD apt-get install -y pip +msg_ok "Installed Dependencies" + +msg_info "Installing Homer" +mkdir -p /opt/homer +cd /opt/homer +wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip +$STD unzip homer.zip +rm -rf homer.zip +cp assets/config.yml.dist assets/config.yml +msg_ok "Installed Homer" + +msg_info "Creating Service" +cat </etc/systemd/system/homer.service +[Unit] +Description=Homer Dashboard +After=network-online.target +[Service] +Type=simple +WorkingDirectory=/opt/homer +ExecStart=python3 -m http.server 8010 +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now homer +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/homer-v5-install.sh b/install/homer-v5-install.sh deleted file mode 100644 index 539c4aed..00000000 --- a/install/homer-v5-install.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y unzip -$STD apt-get install -y pip -msg_ok "Installed Dependencies" - -msg_info "Installing Homer" -mkdir -p /opt/homer -cd /opt/homer -wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip -$STD unzip homer.zip -rm -rf homer.zip -cp assets/config.yml.dist assets/config.yml -msg_ok "Installed Homer" - -msg_info "Creating Service" -cat </etc/systemd/system/homer.service -[Unit] -Description=Homer Dashboard -After=network-online.target -[Service] -Type=simple -WorkingDirectory=/opt/homer -ExecStart=python3 -m http.server 8010 -[Install] -WantedBy=multi-user.target -EOF -$STD systemctl enable --now homer -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh new file mode 100644 index 00000000..f8a3df3c --- /dev/null +++ b/install/hyperion-install.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y lsb-release +$STD apt-get install -y gpg +$STD apt-get install -y apt-transport-https +msg_ok "Installed Dependencies" + +msg_info "Installing Hyperion" +wget -qO- https://apt.hyperion-project.org/hyperion.pub.key | gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg +sh -c 'echo "deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/hyperion.list' +$STD apt-get update +$STD apt-get install -y hyperion +$STD systemctl enable --now hyperion@root.service +msg_ok "Installed Hyperion" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove >/dev/null +$STD apt-get autoclean >/dev/null +msg_ok "Cleaned" diff --git a/install/hyperion-v5-install.sh b/install/hyperion-v5-install.sh deleted file mode 100644 index 4e2668f2..00000000 --- a/install/hyperion-v5-install.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y lsb-release -$STD apt-get install -y gpg -$STD apt-get install -y apt-transport-https -msg_ok "Installed Dependencies" - -msg_info "Installing Hyperion" -wget -qO- https://apt.hyperion-project.org/hyperion.pub.key | gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg -sh -c 'echo "deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/hyperion.list' -$STD apt-get update -$STD apt-get install -y hyperion -$STD systemctl enable --now hyperion@root.service -msg_ok "Installed Hyperion" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove >/dev/null -$STD apt-get autoclean >/dev/null -msg_ok "Cleaned" diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh new file mode 100644 index 00000000..1c501b0b --- /dev/null +++ b/install/influxdb-install.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y lsb-base +$STD apt-get install -y lsb-release +$STD apt-get install -y gnupg2 +msg_ok "Installed Dependencies" + +msg_info "Setting up InfluxDB Repository" +wget -q https://repos.influxdata.com/influxdata-archive_compat.key +cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null +sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' +msg_ok "Set up InfluxDB Repository" + +read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt +if [[ $prompt == "2" ]]; then + INFLUX="2" +else + INFLUX="1" +fi + +msg_info "Installing InfluxDB" +$STD apt-get update +if [[ $INFLUX == "2" ]]; then + $STD apt-get install -y influxdb2 +else + $STD apt-get install -y influxdb +fi +$STD systemctl enable --now influxdb +msg_ok "Installed InfluxDB" + +read -r -p "Would you like to add Telegraf? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Telegraf" + $STD apt-get install -y telegraf + msg_ok "Installed Telegraf" +fi + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/influxdb-v5-install.sh b/install/influxdb-v5-install.sh deleted file mode 100644 index 31fe8ece..00000000 --- a/install/influxdb-v5-install.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y lsb-base -$STD apt-get install -y lsb-release -$STD apt-get install -y gnupg2 -msg_ok "Installed Dependencies" - -msg_info "Setting up InfluxDB Repository" -wget -q https://repos.influxdata.com/influxdata-archive_compat.key -cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null -sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' -msg_ok "Set up InfluxDB Repository" - -read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt -if [[ $prompt == "2" ]]; then - INFLUX="2" -else - INFLUX="1" -fi - -msg_info "Installing InfluxDB" -$STD apt-get update -if [[ $INFLUX == "2" ]]; then - $STD apt-get install -y influxdb2 -else - $STD apt-get install -y influxdb -fi -$STD systemctl enable --now influxdb -msg_ok "Installed InfluxDB" - -read -r -p "Would you like to add Telegraf? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Installing Telegraf" - $STD apt-get install -y telegraf - msg_ok "Installed Telegraf" -fi - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/iobroker-install.sh b/install/iobroker-install.sh new file mode 100644 index 00000000..5146abea --- /dev/null +++ b/install/iobroker-install.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing ioBroker (Patience)" +$STD bash <(curl -fsSL https://iobroker.net/install.sh) +msg_ok "Installed ioBroker" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/iobroker-v5-install.sh b/install/iobroker-v5-install.sh deleted file mode 100644 index 7c8152b3..00000000 --- a/install/iobroker-v5-install.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing ioBroker (Patience)" -$STD bash <(curl -fsSL https://iobroker.net/install.sh) -msg_ok "Installed ioBroker" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/jackett-install.sh b/install/jackett-install.sh new file mode 100644 index 00000000..b4982d3c --- /dev/null +++ b/install/jackett-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Jackett" +RELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz +tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt +rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz +msg_ok "Installed Jackett" + +msg_info "Creating Service" +cat </etc/systemd/system/jackett.service +[Unit] +Description=Jackett Daemon +After=network.target +[Service] +SyslogIdentifier=jackett +Restart=always +RestartSec=5 +Type=simple +WorkingDirectory=/opt/Jackett +ExecStart=/bin/sh /opt/Jackett/jackett_launcher.sh +TimeoutStopSec=30 +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now jackett.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/jackett-v5-install.sh b/install/jackett-v5-install.sh deleted file mode 100644 index 7baee1b1..00000000 --- a/install/jackett-v5-install.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Jackett" -RELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) -wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz -tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt -rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz -msg_ok "Installed Jackett" - -msg_info "Creating Service" -cat </etc/systemd/system/jackett.service -[Unit] -Description=Jackett Daemon -After=network.target -[Service] -SyslogIdentifier=jackett -Restart=always -RestartSec=5 -Type=simple -WorkingDirectory=/opt/Jackett -ExecStart=/bin/sh /opt/Jackett/jackett_launcher.sh -TimeoutStopSec=30 -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now jackett.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh new file mode 100644 index 00000000..e0ac97b4 --- /dev/null +++ b/install/jellyfin-install.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y apt-transport-https +$STD apt-get install -y software-properties-common +msg_ok "Installed Dependencies" + +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 + if [[ ${PCT_OSVERSION} == "20.04" ]]; then + $STD apt-get install -y beignet-opencl-icd + else + $STD apt-get install -y intel-opencl-icd + fi + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + +msg_info "Setting Up Jellyfin Repository" +$STD add-apt-repository universe -y +$STD apt-key add <(curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key) +sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://repo.jellyfin.org/ubuntu $(lsb_release -c -s) main" > /etc/apt/sources.list.d/jellyfin.list' +msg_ok "Set Up Jellyfin Repository" + +msg_info "Installing Jellyfin" +$STD apt-get update +$STD apt install jellyfin-server -y +$STD apt install jellyfin-ffmpeg5 -y +msg_ok "Installed Jellyfin" + +msg_info "Creating Service" +cat <<'EOF' >/lib/systemd/system/jellyfin.service +[Unit] +Description = Jellyfin Media Server +After = network.target +[Service] +Type = simple +EnvironmentFile = /etc/default/jellyfin +User = root +ExecStart = /usr/bin/jellyfin +Restart = on-failure +TimeoutSec = 15 +[Install] +WantedBy = multi-user.target +EOF +ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/jellyfin-v5-install.sh b/install/jellyfin-v5-install.sh deleted file mode 100644 index 821bfe0e..00000000 --- a/install/jellyfin-v5-install.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y apt-transport-https -$STD apt-get install -y software-properties-common -msg_ok "Installed Dependencies" - -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then - $STD apt-get install -y beignet-opencl-icd - else - $STD apt-get install -y intel-opencl-icd - fi - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* - msg_ok "Set Up Hardware Acceleration" -fi - -msg_info "Setting Up Jellyfin Repository" -$STD add-apt-repository universe -y -$STD apt-key add <(curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key) -sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://repo.jellyfin.org/ubuntu $(lsb_release -c -s) main" > /etc/apt/sources.list.d/jellyfin.list' -msg_ok "Set Up Jellyfin Repository" - -msg_info "Installing Jellyfin" -$STD apt-get update -$STD apt install jellyfin-server -y -$STD apt install jellyfin-ffmpeg5 -y -msg_ok "Installed Jellyfin" - -msg_info "Creating Service" -cat <<'EOF' >/lib/systemd/system/jellyfin.service -[Unit] -Description = Jellyfin Media Server -After = network.target -[Service] -Type = simple -EnvironmentFile = /etc/default/jellyfin -User = root -ExecStart = /usr/bin/jellyfin -Restart = on-failure -TimeoutSec = 15 -[Install] -WantedBy = multi-user.target -EOF -ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/k0s-install.sh b/install/k0s-install.sh new file mode 100644 index 00000000..7e772932 --- /dev/null +++ b/install/k0s-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Installing k0s Kubernetes" +$STD bash <(curl -sSLf https://get.k0s.sh) +$STD k0s install controller --single +$STD k0s start +mkdir -p /etc/k0s +k0s config create > /etc/k0s/k0s.yaml +msg_ok "Installed k0s Kubernetes" + +read -r -p "Would you like to add Helm Package Manager? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then +msg_info "Installing Helm" +$STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) +msg_ok "Installed Helm" +fi +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/k0s-v5-install.sh b/install/k0s-v5-install.sh deleted file mode 100644 index c5bb38f5..00000000 --- a/install/k0s-v5-install.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Installing k0s Kubernetes" -$STD bash <(curl -sSLf https://get.k0s.sh) -$STD k0s install controller --single -$STD k0s start -mkdir -p /etc/k0s -k0s config create > /etc/k0s/k0s.yaml -msg_ok "Installed k0s Kubernetes" - -read -r -p "Would you like to add Helm Package Manager? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then -msg_info "Installing Helm" -$STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) -msg_ok "Installed Helm" -fi -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/kavita-install.sh b/install/kavita-install.sh new file mode 100644 index 00000000..72e353d9 --- /dev/null +++ b/install/kavita-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Kavita" +cd /opt +RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) && +msg_ok "Installed Kavita" + +msg_info "Creating Service" +service_path="/etc/systemd/system/kavita.service" +echo "[Unit] +Description=Kavita Server +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/Kavita +ExecStart=/opt/Kavita/Kavita +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +chmod +x /opt/Kavita/* && chown root /opt/Kavita/* +systemctl enable --now -q kavita.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/kavita-v5-install.sh b/install/kavita-v5-install.sh deleted file mode 100644 index fb3d3af2..00000000 --- a/install/kavita-v5-install.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" - - -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Kavita" -cd /opt -RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) && -msg_ok "Installed Kavita" - -msg_info "Creating Service" -service_path="/etc/systemd/system/kavita.service" -echo "[Unit] -Description=Kavita Server -After=network.target - -[Service] -Type=simple -WorkingDirectory=/opt/Kavita -ExecStart=/opt/Kavita/Kavita -TimeoutStopSec=20 -KillMode=process -Restart=on-failure - -[Install] -WantedBy=multi-user.target" >$service_path -chmod +x /opt/Kavita/* && chown root /opt/Kavita/* -systemctl enable --now -q kavita.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh new file mode 100644 index 00000000..0dcf8c8f --- /dev/null +++ b/install/keycloak-install.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y openjdk-11-jdk +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +msg_info "Installing Keycloak v$RELEASE" +cd /opt +wget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz +$STD tar -xvf keycloak-$RELEASE.tar.gz +mv keycloak-$RELEASE keycloak +msg_ok "Installed Keycloak" + +msg_info "Creating Service" +service_path="/etc/systemd/system/keycloak.service" +echo "[Unit] +Description=Keycloak +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/keycloak +ExecStart=/opt/keycloak/bin/kc.sh start-dev +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now keycloak.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/keycloak-v5-install.sh b/install/keycloak-v5-install.sh deleted file mode 100644 index 65fc382c..00000000 --- a/install/keycloak-v5-install.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y openjdk-11-jdk -msg_ok "Installed Dependencies" - -RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -msg_info "Installing Keycloak v$RELEASE" -cd /opt -wget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz -$STD tar -xvf keycloak-$RELEASE.tar.gz -mv keycloak-$RELEASE keycloak -msg_ok "Installed Keycloak" - -msg_info "Creating Service" -service_path="/etc/systemd/system/keycloak.service" -echo "[Unit] -Description=Keycloak -After=network-online.target -[Service] -User=root -WorkingDirectory=/opt/keycloak -ExecStart=/opt/keycloak/bin/kc.sh start-dev -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now keycloak.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/lidarr-install.sh b/install/lidarr-install.sh new file mode 100644 index 00000000..a7ec14d2 --- /dev/null +++ b/install/lidarr-install.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y sqlite3 +$STD apt-get install -y libchromaprint-tools +$STD apt-get install -y mediainfo +msg_ok "Installed Dependencies" + +msg_info "Installing Lidarr" +mkdir -p /var/lib/lidarr/ +chmod 775 /var/lib/lidarr/ +$STD wget --content-disposition 'https://lidarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Lidarr.master.*.tar.gz +mv Lidarr /opt +chmod 775 /opt/Lidarr +msg_ok "Installed Lidarr" + +msg_info "Creating Service" +cat </etc/systemd/system/lidarr.service +[Unit] +Description=Lidarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Lidarr/Lidarr -nobrowser -data=/var/lib/lidarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q lidarr +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf Lidarr.master.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/lidarr-v5-install.sh b/install/lidarr-v5-install.sh deleted file mode 100644 index 35354173..00000000 --- a/install/lidarr-v5-install.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y sqlite3 -$STD apt-get install -y libchromaprint-tools -$STD apt-get install -y mediainfo -msg_ok "Installed Dependencies" - -msg_info "Installing Lidarr" -mkdir -p /var/lib/lidarr/ -chmod 775 /var/lib/lidarr/ -$STD wget --content-disposition 'https://lidarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' -$STD tar -xvzf Lidarr.master.*.tar.gz -mv Lidarr /opt -chmod 775 /opt/Lidarr -msg_ok "Installed Lidarr" - -msg_info "Creating Service" -cat </etc/systemd/system/lidarr.service -[Unit] -Description=Lidarr Daemon -After=syslog.target network.target -[Service] -UMask=0002 -Type=simple -ExecStart=/opt/Lidarr/Lidarr -nobrowser -data=/var/lib/lidarr/ -TimeoutStopSec=20 -KillMode=process -Restart=on-failure -[Install] -WantedBy=multi-user.target -EOF -systemctl -q daemon-reload -systemctl enable --now -q lidarr -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf Lidarr.master.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/magicmirror-v5-install.sh b/install/magicmirror-install.sh similarity index 61% rename from install/magicmirror-v5-install.sh rename to install/magicmirror-install.sh index 3cfc369d..249f46a6 100644 --- a/install/magicmirror-v5-install.sh +++ b/install/magicmirror-install.sh @@ -5,86 +5,13 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os msg_info "Installing Dependencies" $STD apt-get install -y curl @@ -220,23 +147,8 @@ WantedBy=multi-user.target" >$service_path $STD systemctl enable --now magicmirror msg_ok "Created Service" -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi +motd_ssh +root msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh new file mode 100644 index 00000000..a3326a35 --- /dev/null +++ b/install/mariadb-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing MariaDB" +$STD bash <(curl -fsSL https://r.mariadb.com/downloads/mariadb_repo_setup) +$STD apt-get update +$STD apt-get install -y mariadb-server +msg_ok "Installed MariaDB" + +read -r -p "Would you like to add Adminer? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Adminer" + $STD apt install -y adminer + $STD a2enconf adminer + systemctl reload apache2 + msg_ok "Installed Adminer" +fi + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/mariadb-v5-install.sh b/install/mariadb-v5-install.sh deleted file mode 100644 index 63b2899e..00000000 --- a/install/mariadb-v5-install.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing MariaDB" -$STD bash <(curl -fsSL https://r.mariadb.com/downloads/mariadb_repo_setup) -$STD apt-get update -$STD apt-get install -y mariadb-server -msg_ok "Installed MariaDB" - -read -r -p "Would you like to add Adminer? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Installing Adminer" - $STD apt install -y adminer - $STD a2enconf adminer - systemctl reload apache2 - msg_ok "Installed Adminer" -fi - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh new file mode 100644 index 00000000..3defc5eb --- /dev/null +++ b/install/meshcentral-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing MeshCentral" +mkdir /opt/meshcentral +cd /opt/meshcentral +$STD npm install meshcentral +$STD node node_modules/meshcentral --install +msg_ok "Installed MeshCentral" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/meshcentral-v5-install.sh b/install/meshcentral-v5-install.sh deleted file mode 100644 index f0b22abb..00000000 --- a/install/meshcentral-v5-install.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing MeshCentral" -mkdir /opt/meshcentral -cd /opt/meshcentral -$STD npm install meshcentral -$STD node node_modules/meshcentral --install -msg_ok "Installed MeshCentral" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh new file mode 100644 index 00000000..69489209 --- /dev/null +++ b/install/motioneye-install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y cifs-utils +msg_ok "Installed Dependencies" + +msg_info "Installing Motion" +$STD apt-get install -y motion +systemctl stop motion +$STD systemctl disable motion +msg_ok "Installed Motion" + +msg_info "Installing FFmpeg" +$STD apt-get install -y ffmpeg v4l-utils +msg_ok "Installed FFmpeg" + +msg_info "Installing Python" +$STD apt-get update +$STD apt-get install -y python2 +curl -sSL https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py +$STD python2 get-pip.py +$STD apt-get install -y libffi-dev libzbar-dev libzbar0 +$STD apt-get install -y python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev +msg_ok "Installed Python" + +msg_info "Installing MotionEye" +$STD apt-get update +$STD pip install motioneye +mkdir -p /etc/motioneye +cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf +mkdir -p /var/lib/motioneye +msg_ok "Installed MotionEye" + +msg_info "Creating Service" +cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service +$STD systemctl enable motioneye +systemctl start motioneye +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/motioneye-v5-install.sh b/install/motioneye-v5-install.sh deleted file mode 100644 index 14ea8991..00000000 --- a/install/motioneye-v5-install.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y cifs-utils -msg_ok "Installed Dependencies" - -msg_info "Installing Motion" -$STD apt-get install -y motion -systemctl stop motion -$STD systemctl disable motion -msg_ok "Installed Motion" - -msg_info "Installing FFmpeg" -$STD apt-get install -y ffmpeg v4l-utils -msg_ok "Installed FFmpeg" - -msg_info "Installing Python" -$STD apt-get update -$STD apt-get install -y python2 -curl -sSL https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py -$STD python2 get-pip.py -$STD apt-get install -y libffi-dev libzbar-dev libzbar0 -$STD apt-get install -y python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -msg_ok "Installed Python" - -msg_info "Installing MotionEye" -$STD apt-get update -$STD pip install motioneye -mkdir -p /etc/motioneye -cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf -mkdir -p /var/lib/motioneye -msg_ok "Installed MotionEye" - -msg_info "Creating Service" -cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service -$STD systemctl enable motioneye -systemctl start motioneye -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh new file mode 100644 index 00000000..135abf56 --- /dev/null +++ b/install/mqtt-install.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing Mosquitto MQTT Broker" +$STD wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key +$STD apt-key add mosquitto-repo.gpg.key +cd /etc/apt/sources.list.d/ +$STD wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list +$STD apt-get update +$STD apt-get -y install mosquitto +$STD apt-get -y install mosquitto-clients +msg_ok "Installed Mosquitto MQTT Broker" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/mqtt-v5-install.sh b/install/mqtt-v5-install.sh deleted file mode 100644 index 3f13f8a4..00000000 --- a/install/mqtt-v5-install.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -msg_ok "Installed Dependencies" - -msg_info "Installing Mosquitto MQTT Broker" -$STD wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key -$STD apt-key add mosquitto-repo.gpg.key -cd /etc/apt/sources.list.d/ -$STD wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list -$STD apt-get update -$STD apt-get -y install mosquitto -$STD apt-get -y install mosquitto-clients -msg_ok "Installed Mosquitto MQTT Broker" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/n8n-install.sh b/install/n8n-install.sh new file mode 100644 index 00000000..7e735a09 --- /dev/null +++ b/install/n8n-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing n8n (Patience)" +$STD npm install --global n8n +msg_ok "Installed n8n" + +msg_info "Creating Service" +cat </etc/systemd/system/n8n.service +[Unit] +Description=n8n + +[Service] +Type=simple +ExecStart=n8n start +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable --now n8n +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/n8n-v5-install.sh b/install/n8n-v5-install.sh deleted file mode 100644 index 76a45c05..00000000 --- a/install/n8n-v5-install.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing n8n (Patience)" -$STD npm install --global n8n -msg_ok "Installed n8n" - -msg_info "Creating Service" -cat </etc/systemd/system/n8n.service -[Unit] -Description=n8n - -[Service] -Type=simple -ExecStart=n8n start -[Install] -WantedBy=multi-user.target -EOF -$STD systemctl enable --now n8n -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh new file mode 100644 index 00000000..67f255a2 --- /dev/null +++ b/install/navidrome-install.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (patience)" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y ffmpeg +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Installing Navidrome" +install -d -o root -g root /opt/navidrome +install -d -o root -g root /var/lib/navidrome +$STD wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz +$STD tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ +chown -R root:root /opt/navidrome +mkdir -p /music +cat </var/lib/navidrome/navidrome.toml +MusicFolder = '/music' +EOF +msg_ok "Installed Navidrome" + +msg_info "Creating Service" +service_path="/etc/systemd/system/navidrome.service" + +echo "[Unit] +Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic +After=remote-fs.target network.target +AssertPathExists=/var/lib/navidrome + +[Service] +User=root +Group=root +Type=simple +ExecStart=/opt/navidrome/navidrome --configfile '/var/lib/navidrome/navidrome.toml' +WorkingDirectory=/var/lib/navidrome +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +DevicePolicy=closed +NoNewPrivileges=yes +PrivateTmp=yes +PrivateUsers=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +RestrictNamespaces=yes +RestrictRealtime=yes +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap +ReadWritePaths=/var/lib/navidrome +ProtectSystem=full + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl daemon-reload +$STD systemctl enable --now navidrome.service + +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/Navidrome.tar.gz +msg_ok "Cleaned" diff --git a/install/navidrome-v5-install.sh b/install/navidrome-v5-install.sh deleted file mode 100644 index 67a38067..00000000 --- a/install/navidrome-v5-install.sh +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies (patience)" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y ffmpeg -msg_ok "Installed Dependencies" - -RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -msg_info "Installing Navidrome" -install -d -o root -g root /opt/navidrome -install -d -o root -g root /var/lib/navidrome -$STD wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz -$STD tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ -chown -R root:root /opt/navidrome -mkdir -p /music -cat </var/lib/navidrome/navidrome.toml -MusicFolder = '/music' -EOF -msg_ok "Installed Navidrome" - -msg_info "Creating Service" -service_path="/etc/systemd/system/navidrome.service" - -echo "[Unit] -Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic -After=remote-fs.target network.target -AssertPathExists=/var/lib/navidrome - -[Service] -User=root -Group=root -Type=simple -ExecStart=/opt/navidrome/navidrome --configfile '/var/lib/navidrome/navidrome.toml' -WorkingDirectory=/var/lib/navidrome -TimeoutStopSec=20 -KillMode=process -Restart=on-failure -DevicePolicy=closed -NoNewPrivileges=yes -PrivateTmp=yes -PrivateUsers=yes -ProtectControlGroups=yes -ProtectKernelModules=yes -ProtectKernelTunables=yes -RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 -RestrictNamespaces=yes -RestrictRealtime=yes -SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap -ReadWritePaths=/var/lib/navidrome -ProtectSystem=full - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl daemon-reload -$STD systemctl enable --now navidrome.service - -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -rm -rf /root/Navidrome.tar.gz -msg_ok "Cleaned" diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh new file mode 100644 index 00000000..0e73cb55 --- /dev/null +++ b/install/nextcloudpi-install.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing NextCloudPi (Patience)" +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) +sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php +sed -i '{s|root:/usr/sbin/nologin|root:/bin/bash|g}' /etc/passwd +service apache2 restart +msg_ok "Installed NextCloudPi" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/nextcloudpi-v5-install.sh b/install/nextcloudpi-v5-install.sh deleted file mode 100644 index 6ccada06..00000000 --- a/install/nextcloudpi-v5-install.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing NextCloudPi (Patience)" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) -sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php -sed -i '{s|root:/usr/sbin/nologin|root:/bin/bash|g}' /etc/passwd -service apache2 restart -msg_ok "Installed NextCloudPi" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/nginxproxymanager-v5-install.sh b/install/nginxproxymanager-install.sh similarity index 62% rename from install/nginxproxymanager-v5-install.sh rename to install/nginxproxymanager-install.sh index d66e0adf..b2baa37f 100644 --- a/install/nginxproxymanager-v5-install.sh +++ b/install/nginxproxymanager-install.sh @@ -5,86 +5,13 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os msg_info "Installing Dependencies" $STD apt-get update @@ -250,23 +177,8 @@ WantedBy=multi-user.target EOF msg_ok "Created Service" -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi +motd_ssh +root msg_info "Starting Services" $STD systemctl enable --now openresty diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh new file mode 100644 index 00000000..63bf1ca6 --- /dev/null +++ b/install/nocodb-install.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD sudo apt-get install -y nodejs git make g++ gcc +msg_ok "Installed Node.js" + +msg_info "Installing NocoDB" +$STD git clone https://github.com/nocodb/nocodb-seed +mv nocodb-seed /opt/nocodb +cd /opt/nocodb +$STD npm install +msg_ok "Installed NocoDB" + +msg_info "Creating Service" +service_path="/etc/systemd/system/nocodb.service" +echo "[Unit] +Description=nocodb + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/nocodb +ExecStart=/usr/bin/npm start + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now nocodb.service &>/dev/null +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/nocodb-v5-install.sh b/install/nocodb-v5-install.sh deleted file mode 100644 index fb618460..00000000 --- a/install/nocodb-v5-install.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD sudo apt-get install -y nodejs git make g++ gcc -msg_ok "Installed Node.js" - -msg_info "Installing NocoDB" -$STD git clone https://github.com/nocodb/nocodb-seed -mv nocodb-seed /opt/nocodb -cd /opt/nocodb -$STD npm install -msg_ok "Installed NocoDB" - -msg_info "Creating Service" -service_path="/etc/systemd/system/nocodb.service" -echo "[Unit] -Description=nocodb - -[Service] -Type=simple -Restart=always -User=root -WorkingDirectory=/opt/nocodb -ExecStart=/usr/bin/npm start - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now nocodb.service &>/dev/null -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/node-red-install.sh b/install/node-red-install.sh new file mode 100644 index 00000000..fd2760f4 --- /dev/null +++ b/install/node-red-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Node-Red" +$STD npm install -g --unsafe-perm node-red +msg_ok "Installed Node-Red" + +msg_info "Creating Service" +service_path="/etc/systemd/system/nodered.service" +echo "[Unit] +Description=Node-RED +After=syslog.target network.target + +[Service] +ExecStart=/usr/bin/node-red --max-old-space-size=128 -v +Restart=on-failure +KillSignal=SIGINT + +SyslogIdentifier=node-red +StandardOutput=syslog + +WorkingDirectory=/root/ +User=root +Group=root + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now nodered.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/node-red-v5-install.sh b/install/node-red-v5-install.sh deleted file mode 100644 index e20934ef..00000000 --- a/install/node-red-v5-install.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing Node-Red" -$STD npm install -g --unsafe-perm node-red -msg_ok "Installed Node-Red" - -msg_info "Creating Service" -service_path="/etc/systemd/system/nodered.service" -echo "[Unit] -Description=Node-RED -After=syslog.target network.target - -[Service] -ExecStart=/usr/bin/node-red --max-old-space-size=128 -v -Restart=on-failure -KillSignal=SIGINT - -SyslogIdentifier=node-red -StandardOutput=syslog - -WorkingDirectory=/root/ -User=root -Group=root - -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now nodered.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/omada-install.sh b/install/omada-install.sh new file mode 100644 index 00000000..0bc5fe85 --- /dev/null +++ b/install/omada-install.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +$STD apt-get install -y openjdk-8-jre-headless +$STD apt-get install -y jsvc +wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb +$STD dpkg -i mongodb-org-server_3.6.23_amd64.deb +msg_ok "Installed Dependencies" + +msg_info "Installing Omada Controller v5.9.31" +wget -qL https://static.tp-link.com/upload/software/2023/202303/20230321/Omada_SDN_Controller_v5.9.31_Linux_x64.deb +$STD dpkg -i Omada_SDN_Controller_v5.9.31_Linux_x64.deb +msg_ok "Installed Omada Controller" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf Omada_SDN_Controller_v5.9.9_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/omada-v5-install.sh b/install/omada-v5-install.sh deleted file mode 100644 index 6e79e690..00000000 --- a/install/omada-v5-install.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -$STD apt-get install -y openjdk-8-jre-headless -$STD apt-get install -y jsvc -wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb -$STD dpkg -i mongodb-org-server_3.6.23_amd64.deb -msg_ok "Installed Dependencies" - -msg_info "Installing Omada Controller v5.9.9" -wget -qL https://static.tp-link.com/upload/software/2023/202302/20230227/Omada_SDN_Controller_v5.9.9_Linux_x64.deb -$STD dpkg -i Omada_SDN_Controller_v5.9.9_Linux_x64.deb -msg_ok "Installed Omada Controller" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_v5.9.9_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/omv-install.sh b/install/omv-install.sh new file mode 100644 index 00000000..fbc2f03b --- /dev/null +++ b/install/omv-install.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing OpenMediaVault (Patience)" +wget -q -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key +$STD apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" &>/dev/null + +cat <>/etc/apt/sources.list.d/openmediavault.list +deb https://packages.openmediavault.org/public shaitan main +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main +## Uncomment the following line to add software from the proposed repository. +# deb https://packages.openmediavault.org/public shaitan-proposed main +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan-proposed main +## This software is not part of OpenMediaVault, but is offered by third-party +## developers as a service to OpenMediaVault users. +# deb https://packages.openmediavault.org/public shaitan partner +# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner +EOF +$STD apt-get update +$STD apt-get -y install openmediavault-keyring +$STD apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends install openmediavault +omv-confdbadm populate +msg_ok "Installed OpenMediaVault" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/omv-v5-install.sh b/install/omv-v5-install.sh deleted file mode 100644 index 6f0e8a1e..00000000 --- a/install/omv-v5-install.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -export DEBIAN_FRONTEND=noninteractive -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -msg_ok "Installed Dependencies" - -msg_info "Installing OpenMediaVault (Patience)" -wget -q -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key -$STD apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" &>/dev/null - -cat <>/etc/apt/sources.list.d/openmediavault.list -deb https://packages.openmediavault.org/public shaitan main -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main -## Uncomment the following line to add software from the proposed repository. -# deb https://packages.openmediavault.org/public shaitan-proposed main -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan-proposed main -## This software is not part of OpenMediaVault, but is offered by third-party -## developers as a service to OpenMediaVault users. -# deb https://packages.openmediavault.org/public shaitan partner -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner -EOF -$STD apt-get update -$STD apt-get -y install openmediavault-keyring -$STD apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends install openmediavault -omv-confdbadm populate -msg_ok "Installed OpenMediaVault" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/openhab-install.sh b/install/openhab-install.sh new file mode 100644 index 00000000..43d5454b --- /dev/null +++ b/install/openhab-install.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +$STD apt-get install -y apt-transport-https +msg_ok "Installed Dependencies" + +msg_info "Installing Azul Zulu" +$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 +wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb +$STD apt-get install ./zulu-repo_1.0.0-3_all.deb +$STD apt-get update +$STD apt-get -y install zulu11-jdk +msg_ok "Installed Azul Zulu" + +msg_info "Installing openHAB" +curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor >openhab.gpg +mv openhab.gpg /usr/share/keyrings +chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg +sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main" > /etc/apt/sources.list.d/openhab.list' +$STD apt update +$STD apt-get -y install openhab +systemctl daemon-reload +$STD systemctl enable --now openhab.service +msg_ok "Installed openHAB" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/openhab-v5-install.sh b/install/openhab-v5-install.sh deleted file mode 100644 index 1899ae34..00000000 --- a/install/openhab-v5-install.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -$STD apt-get install -y apt-transport-https -msg_ok "Installed Dependencies" - -msg_info "Installing Azul Zulu" -$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 -wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb -$STD apt-get install ./zulu-repo_1.0.0-3_all.deb -$STD apt-get update -$STD apt-get -y install zulu11-jdk -msg_ok "Installed Azul Zulu" - -msg_info "Installing openHAB" -curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor >openhab.gpg -mv openhab.gpg /usr/share/keyrings -chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg -sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main" > /etc/apt/sources.list.d/openhab.list' -$STD apt update -$STD apt-get -y install openhab -systemctl daemon-reload -$STD systemctl enable --now openhab.service -msg_ok "Installed openHAB" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/paperless-ngx-v5-install.sh b/install/paperless-ngx-install.sh similarity index 64% rename from install/paperless-ngx-v5-install.sh rename to install/paperless-ngx-install.sh index 5efaa813..8d31b183 100644 --- a/install/paperless-ngx-v5-install.sh +++ b/install/paperless-ngx-install.sh @@ -5,86 +5,13 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os msg_info "Installing Python3" $STD apt-get install -y --no-install-recommends \ @@ -263,26 +190,10 @@ sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /et systemctl daemon-reload $STD systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service - msg_ok "Created Services" -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi +motd_ssh +root msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/photoprism-v5-install.sh b/install/photoprism-install.sh similarity index 53% rename from install/photoprism-v5-install.sh rename to install/photoprism-install.sh index ac39c48d..92c00afb 100644 --- a/install/photoprism-v5-install.sh +++ b/install/photoprism-install.sh @@ -5,86 +5,13 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os msg_info "Installing Dependencies (Patience)" $STD apt-get install -y curl @@ -191,23 +118,8 @@ ExecStop=/opt/photoprism/bin/photoprism down WantedBy=multi-user.target" >$service_path msg_ok "Created Service" -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi +motd_ssh +root msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/pihole-install.sh b/install/pihole-install.sh new file mode 100644 index 00000000..8cf049f7 --- /dev/null +++ b/install/pihole-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y ufw +$STD apt-get install -y ntp +msg_ok "Installed Dependencies" + +msg_info "Installing Pi-hole" +systemctl stop systemd-resolved +echo "DNSStubListener=no" >>/etc/systemd/resolved.conf +ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf +mkdir -p /etc/pihole/ +cat </etc/pihole/setupVars.conf +PIHOLE_INTERFACE=eth0 +PIHOLE_DNS_1=8.8.8.8 +PIHOLE_DNS_2=8.8.4.4 +QUERY_LOGGING=true +INSTALL_WEB_SERVER=true +INSTALL_WEB_INTERFACE=true +LIGHTTPD_ENABLED=true +CACHE_SIZE=10000 +DNS_FQDN_REQUIRED=true +DNS_BOGUS_PRIV=true +DNSMASQ_LISTENING=local +WEBPASSWORD=$(openssl rand -base64 48) +BLOCKING_ENABLED=true +EOF + +$STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended +msg_ok "Installed Pi-hole" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/pihole-v5-install.sh b/install/pihole-v5-install.sh deleted file mode 100644 index 63df2f5b..00000000 --- a/install/pihole-v5-install.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -export DEBIAN_FRONTEND=noninteractive -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y ufw -$STD apt-get install -y ntp -msg_ok "Installed Dependencies" - -msg_info "Installing Pi-hole" -systemctl stop systemd-resolved -echo "DNSStubListener=no" >>/etc/systemd/resolved.conf -ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -mkdir -p /etc/pihole/ -cat </etc/pihole/setupVars.conf -PIHOLE_INTERFACE=eth0 -PIHOLE_DNS_1=8.8.8.8 -PIHOLE_DNS_2=8.8.4.4 -QUERY_LOGGING=true -INSTALL_WEB_SERVER=true -INSTALL_WEB_INTERFACE=true -LIGHTTPD_ENABLED=true -CACHE_SIZE=10000 -DNS_FQDN_REQUIRED=true -DNS_BOGUS_PRIV=true -DNSMASQ_LISTENING=local -WEBPASSWORD=$(openssl rand -base64 48) -BLOCKING_ENABLED=true -EOF - -$STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended -msg_ok "Installed Pi-hole" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/plex-install.sh b/install/plex-install.sh new file mode 100644 index 00000000..01744201 --- /dev/null +++ b/install/plex-install.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 + if [[ ${PCT_OSVERSION} == "20.04" ]]; then + $STD apt-get install -y beignet-opencl-icd + else + $STD apt-get install -y intel-opencl-icd + fi + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + +msg_info "Setting Up Plex Media Server Repository" +$STD apt-key add <(curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key) +sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" > /etc/apt/sources.list.d/plexmediaserver.list' +msg_ok "Set Up Plex Media Server Repository" + +msg_info "Installing Plex Media Server" +$STD apt-get update +$STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver +msg_ok "Installed Plex Media Server" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/plex-v5-install.sh b/install/plex-v5-install.sh deleted file mode 100644 index f866c55e..00000000 --- a/install/plex-v5-install.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -msg_ok "Installed Dependencies" - -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then - $STD apt-get install -y beignet-opencl-icd - else - $STD apt-get install -y intel-opencl-icd - fi - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* - msg_ok "Set Up Hardware Acceleration" -fi - -msg_info "Setting Up Plex Media Server Repository" -$STD apt-key add <(curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key) -sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" > /etc/apt/sources.list.d/plexmediaserver.list' -msg_ok "Set Up Plex Media Server Repository" - -msg_info "Installing Plex Media Server" -$STD apt-get update -$STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver -msg_ok "Installed Plex Media Server" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/podman-homeassistant-install.sh b/install/podman-homeassistant-install.sh new file mode 100644 index 00000000..70351f5e --- /dev/null +++ b/install/podman-homeassistant-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Podman" +$STD apt-get -y install podman +$STD systemctl enable --now podman.socket +msg_ok "Installed Podman" + +msg_info "Pulling Home Assistant Image" +$STD podman pull docker.io/homeassistant/home-assistant:stable +msg_ok "Pulled Home Assistant Image" + +msg_info "Installing Home Assistant" +$STD podman volume create hass_config +$STD podman run -d \ + --name homeassistant \ + --restart unless-stopped \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --net=host \ + homeassistant/home-assistant:stable +podman generate systemd \ + --new --name homeassistant \ + >/etc/systemd/system/homeassistant.service +$STD systemctl enable --now homeassistant +msg_ok "Installed Home Assistant" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/podman-homeassistant-v5-install.sh b/install/podman-homeassistant-v5-install.sh deleted file mode 100644 index 4b594c70..00000000 --- a/install/podman-homeassistant-v5-install.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Podman" -$STD apt-get -y install podman -$STD systemctl enable --now podman.socket -msg_ok "Installed Podman" - -msg_info "Pulling Home Assistant Image" -$STD podman pull docker.io/homeassistant/home-assistant:stable -msg_ok "Pulled Home Assistant Image" - -msg_info "Installing Home Assistant" -$STD podman volume create hass_config -$STD podman run -d \ - --name homeassistant \ - --restart unless-stopped \ - -v /dev:/dev \ - -v hass_config:/config \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --net=host \ - homeassistant/home-assistant:stable -podman generate systemd \ - --new --name homeassistant \ - >/etc/systemd/system/homeassistant.service -$STD systemctl enable --now homeassistant -msg_ok "Installed Home Assistant" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/podman-install.sh b/install/podman-install.sh new file mode 100644 index 00000000..8c248463 --- /dev/null +++ b/install/podman-install.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Podman" +$STD apt-get -y install podman +$STD systemctl enable --now podman.socket +echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registries.conf +msg_ok "Installed Podman" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/podman-v5-install.sh b/install/podman-v5-install.sh deleted file mode 100644 index 3e2aa3e8..00000000 --- a/install/podman-v5-install.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Podman" -$STD apt-get -y install podman -$STD systemctl enable --now podman.socket -echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registries.conf -msg_ok "Installed Podman" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/postgresql-v5-install.sh b/install/postgresql-install.sh similarity index 60% rename from install/postgresql-v5-install.sh rename to install/postgresql-install.sh index 7a003eb5..53fb2a25 100644 --- a/install/postgresql-v5-install.sh +++ b/install/postgresql-install.sh @@ -5,89 +5,13 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -LANG=$(grep -v '^#' /etc/locale.gen | grep -o '^[^ ]*') -update-locale LANG=$LANG -echo "export LANG=$LANG" >> ~/.bashrc -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os msg_info "Installing Dependencies" $STD apt-get install -y curl @@ -217,23 +141,8 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_ok "Installed Adminer" fi -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi +motd_ssh +root msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/prometheus-install.sh b/install/prometheus-install.sh new file mode 100644 index 00000000..4d3d77a2 --- /dev/null +++ b/install/prometheus-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Prometheus" +RELEASE=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +mkdir -p /etc/prometheus +mkdir -p /var/lib/prometheus +$STD wget https://github.com/prometheus/prometheus/releases/download/v${RELEASE}/prometheus-${RELEASE}.linux-amd64.tar.gz +$STD tar -xvf prometheus-${RELEASE}.linux-amd64.tar.gz +cd prometheus-${RELEASE}.linux-amd64 +mv prometheus promtool /usr/local/bin/ +mv consoles/ console_libraries/ /etc/prometheus/ +mv prometheus.yml /etc/prometheus/prometheus.yml +msg_ok "Installed Prometheus" + +msg_info "Creating Service" +service_path="/etc/systemd/system/prometheus.service" +echo "[Unit] +Description=Prometheus +Wants=network-online.target +After=network-online.target + +[Service] +User=root +Restart=always +Type=simple +ExecStart=/usr/local/bin/prometheus \ + --config.file=/etc/prometheus/prometheus.yml \ + --storage.tsdb.path=/var/lib/prometheus/ \ + --web.console.templates=/etc/prometheus/consoles \ + --web.console.libraries=/etc/prometheus/console_libraries \ + --web.listen-address=0.0.0.0:9090 + +[Install] +WantedBy=multi-user.target" >$service_path +$STD sudo systemctl enable --now prometheus +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/prometheus-${RELEASE}.linux-amd64 /root/prometheus-${RELEASE}.linux-amd64.tar.gz +msg_ok "Cleaned" diff --git a/install/prometheus-v5-install.sh b/install/prometheus-v5-install.sh deleted file mode 100644 index 7d561256..00000000 --- a/install/prometheus-v5-install.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Prometheus" -RELEASE=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -mkdir -p /etc/prometheus -mkdir -p /var/lib/prometheus -$STD wget https://github.com/prometheus/prometheus/releases/download/v${RELEASE}/prometheus-${RELEASE}.linux-amd64.tar.gz -$STD tar -xvf prometheus-${RELEASE}.linux-amd64.tar.gz -cd prometheus-${RELEASE}.linux-amd64 -mv prometheus promtool /usr/local/bin/ -mv consoles/ console_libraries/ /etc/prometheus/ -mv prometheus.yml /etc/prometheus/prometheus.yml -msg_ok "Installed Prometheus" - -msg_info "Creating Service" -service_path="/etc/systemd/system/prometheus.service" -echo "[Unit] -Description=Prometheus -Wants=network-online.target -After=network-online.target - -[Service] -User=root -Restart=always -Type=simple -ExecStart=/usr/local/bin/prometheus \ - --config.file=/etc/prometheus/prometheus.yml \ - --storage.tsdb.path=/var/lib/prometheus/ \ - --web.console.templates=/etc/prometheus/consoles \ - --web.console.libraries=/etc/prometheus/console_libraries \ - --web.listen-address=0.0.0.0:9090 - -[Install] -WantedBy=multi-user.target" >$service_path -$STD sudo systemctl enable --now prometheus -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -rm -rf /root/prometheus-${RELEASE}.linux-amd64 /root/prometheus-${RELEASE}.linux-amd64.tar.gz -msg_ok "Cleaned" diff --git a/install/prowlarr-install.sh b/install/prowlarr-install.sh new file mode 100644 index 00000000..638d93c1 --- /dev/null +++ b/install/prowlarr-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Prowlarr" +mkdir -p /var/lib/prowlarr/ +chmod 775 /var/lib/prowlarr/ +$STD wget --content-disposition 'https://prowlarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Prowlarr.master.*.tar.gz +mv Prowlarr /opt +chmod 775 /opt/Prowlarr +msg_ok "Installed Prowlarr" + +msg_info "Creating Service" +cat </etc/systemd/system/prowlarr.service +[Unit] +Description=Prowlarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q prowlarr +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf Prowlarr.master.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/prowlarr-v5-install.sh b/install/prowlarr-v5-install.sh deleted file mode 100644 index 565541ac..00000000 --- a/install/prowlarr-v5-install.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y sqlite3 -msg_ok "Installed Dependencies" - -msg_info "Installing Prowlarr" -mkdir -p /var/lib/prowlarr/ -chmod 775 /var/lib/prowlarr/ -$STD wget --content-disposition 'https://prowlarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' -$STD tar -xvzf Prowlarr.master.*.tar.gz -mv Prowlarr /opt -chmod 775 /opt/Prowlarr -msg_ok "Installed Prowlarr" - -msg_info "Creating Service" -cat </etc/systemd/system/prowlarr.service -[Unit] -Description=Prowlarr Daemon -After=syslog.target network.target -[Service] -UMask=0002 -Type=simple -ExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr/ -TimeoutStopSec=20 -KillMode=process -Restart=on-failure -[Install] -WantedBy=multi-user.target -EOF -systemctl -q daemon-reload -systemctl enable --now -q prowlarr -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf Prowlarr.master.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/qbittorrent-install.sh b/install/qbittorrent-install.sh new file mode 100644 index 00000000..6995f6bb --- /dev/null +++ b/install/qbittorrent-install.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing qbittorrent-nox" +$STD apt-get install -y qbittorrent-nox +msg_ok "qbittorrent-nox" + +msg_info "Creating Service" +cat </etc/systemd/system/qbittorrent-nox.service +[Unit] +Description=qBittorrent client +After=network.target +[Service] +ExecStart=/usr/bin/qbittorrent-nox --webui-port=8090 +Restart=always +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now qbittorrent-nox +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/qbittorrent-v5-install.sh b/install/qbittorrent-v5-install.sh deleted file mode 100644 index 8ced8627..00000000 --- a/install/qbittorrent-v5-install.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing qbittorrent-nox" -$STD apt-get install -y qbittorrent-nox -msg_ok "qbittorrent-nox" - -msg_info "Creating Service" -cat </etc/systemd/system/qbittorrent-nox.service -[Unit] -Description=qBittorrent client -After=network.target -[Service] -ExecStart=/usr/bin/qbittorrent-nox --webui-port=8090 -Restart=always -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now qbittorrent-nox -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/radarr-install.sh b/install/radarr-install.sh new file mode 100644 index 00000000..4c736895 --- /dev/null +++ b/install/radarr-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Radarr" +mkdir -p /var/lib/radarr/ +chmod 775 /var/lib/radarr/ +$STD wget --content-disposition 'https://radarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Radarr.master.*.tar.gz +mv Radarr /opt +chmod 775 /opt/Radarr +msg_ok "Installed Radarr" + +msg_info "Creating Service" +cat </etc/systemd/system/radarr.service +[Unit] +Description=Radarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q radarr +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf Radarr.master.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/radarr-v5-install.sh b/install/radarr-v5-install.sh deleted file mode 100644 index 655bf395..00000000 --- a/install/radarr-v5-install.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y sqlite3 -msg_ok "Installed Dependencies" - -msg_info "Installing Radarr" -mkdir -p /var/lib/radarr/ -chmod 775 /var/lib/radarr/ -$STD wget --content-disposition 'https://radarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64' -$STD tar -xvzf Radarr.master.*.tar.gz -mv Radarr /opt -chmod 775 /opt/Radarr -msg_ok "Installed Radarr" - -msg_info "Creating Service" -cat </etc/systemd/system/radarr.service -[Unit] -Description=Radarr Daemon -After=syslog.target network.target -[Service] -UMask=0002 -Type=simple -ExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr/ -TimeoutStopSec=20 -KillMode=process -Restart=on-failure -[Install] -WantedBy=multi-user.target -EOF -systemctl -q daemon-reload -systemctl enable --now -q radarr -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf Radarr.master.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/readarr-install.sh b/install/readarr-install.sh new file mode 100644 index 00000000..9452caa3 --- /dev/null +++ b/install/readarr-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Readarr" +mkdir -p /var/lib/readarr/ +chmod 775 /var/lib/readarr/ +$STD wget --content-disposition 'https://readarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Readarr.develop.*.tar.gz +mv Readarr /opt +chmod 775 /opt/Readarr +msg_ok "Installed Readarr" + +msg_info "Creating Service" +cat </etc/systemd/system/readarr.service +[Unit] +Description=Readarr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q readarr +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf Readarr.develop.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/readarr-v5-install.sh b/install/readarr-v5-install.sh deleted file mode 100644 index f2388649..00000000 --- a/install/readarr-v5-install.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y sqlite3 -msg_ok "Installed Dependencies" - -msg_info "Installing Readarr" -mkdir -p /var/lib/readarr/ -chmod 775 /var/lib/readarr/ -$STD wget --content-disposition 'https://readarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=x64' -$STD tar -xvzf Readarr.develop.*.tar.gz -mv Readarr /opt -chmod 775 /opt/Readarr -msg_ok "Installed Readarr" - -msg_info "Creating Service" -cat </etc/systemd/system/readarr.service -[Unit] -Description=Readarr Daemon -After=syslog.target network.target -[Service] -UMask=0002 -Type=simple -ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/ -TimeoutStopSec=20 -KillMode=process -Restart=on-failure -[Install] -WantedBy=multi-user.target -EOF -systemctl -q daemon-reload -systemctl enable --now -q readarr -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf Readarr.develop.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/rstptoweb-install.sh b/install/rstptoweb-install.sh new file mode 100644 index 00000000..76c3792d --- /dev/null +++ b/install/rstptoweb-install.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y git +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Golang" +$STD wget https://golang.org/dl/go1.20.1.linux-amd64.tar.gz +$STD tar -xzf go1.20.1.linux-amd64.tar.gz -C /usr/local +$STD ln -s /usr/local/go/bin/go /usr/local/bin/go +rm -rf go1.20.1.linux-amd64.tar.gz +msg_ok "Installed Golang" + +msg_info "Installing RSTPtoWEB" +$STD git clone https://github.com/deepch/RTSPtoWeb /opt/rtsptoweb +cat <>/opt/rtsptoweb/start +#!/bin/bash +cd /opt/rtsptoweb && GO111MODULE=on go run *.go +EOF +chmod +x /opt/rtsptoweb/start +msg_ok "Installed RSTPtoWEB" + +msg_info "Creating Service" +service_path="/etc/systemd/system/rtsptoweb.service" +echo "[Unit] +Description=RTSP to Web Streaming Service +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/opt/rtsptoweb/start + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable -q --now rtsptoweb +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/rstptoweb-v5-install.sh b/install/rstptoweb-v5-install.sh deleted file mode 100644 index f1c28169..00000000 --- a/install/rstptoweb-v5-install.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y git -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Golang" -$STD wget https://golang.org/dl/go1.20.1.linux-amd64.tar.gz -$STD tar -xzf go1.20.1.linux-amd64.tar.gz -C /usr/local -$STD ln -s /usr/local/go/bin/go /usr/local/bin/go -rm -rf go1.20.1.linux-amd64.tar.gz -msg_ok "Installed Golang" - -msg_info "Installing RSTPtoWEB" -$STD git clone https://github.com/deepch/RTSPtoWeb /opt/rtsptoweb -cat <>/opt/rtsptoweb/start -#!/bin/bash -cd /opt/rtsptoweb && GO111MODULE=on go run *.go -EOF -chmod +x /opt/rtsptoweb/start -msg_ok "Installed RSTPtoWEB" - -msg_info "Creating Service" -service_path="/etc/systemd/system/rtsptoweb.service" -echo "[Unit] -Description=RTSP to Web Streaming Service -After=network.target - -[Service] -Type=simple -User=root -ExecStart=/opt/rtsptoweb/start - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable -q --now rtsptoweb -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh new file mode 100644 index 00000000..b779e31d --- /dev/null +++ b/install/sabnzbd-install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +$STD apt-get install -y par2 +$STD apt-get install -y p7zip-full +wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_6.0.3-1+deb11u1_amd64.deb +$STD dpkg -i unrar_6.0.3-1+deb11u1_amd64.deb +rm unrar_6.0.3-1+deb11u1_amd64.deb +msg_ok "Installed Dependencies" + +msg_info "Installing Python3-pip" +$STD apt-get install -y python3-setuptools +$STD apt-get install -y python3-pip +msg_ok "Installed Python3-pip" + +msg_info "Installing SABnzbd" +RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +$STD tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) +mv SABnzbd-${RELEASE} /opt/sabnzbd +cd /opt/sabnzbd +$STD python3 -m pip install -r requirements.txt +msg_ok "Installed SABnzbd" + +msg_info "Creating Service" +service_path="/etc/systemd/system/sabnzbd.service" +echo "[Unit] +Description=SABnzbd +After=network.target +[Service] +WorkingDirectory=/opt/sabnzbd +ExecStart=python3 SABnzbd.py -s 0.0.0.0:7777 +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q sabnzbd.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/sabnzbd-v5-install.sh b/install/sabnzbd-v5-install.sh deleted file mode 100644 index 9d9cb825..00000000 --- a/install/sabnzbd-v5-install.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y unzip -$STD apt-get install -y par2 -$STD apt-get install -y p7zip-full -wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_6.0.3-1+deb11u1_amd64.deb -$STD dpkg -i unrar_6.0.3-1+deb11u1_amd64.deb -rm unrar_6.0.3-1+deb11u1_amd64.deb -msg_ok "Installed Dependencies" - -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-setuptools -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" - -msg_info "Installing SABnzbd" -RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -$STD tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) -mv SABnzbd-${RELEASE} /opt/sabnzbd -cd /opt/sabnzbd -$STD python3 -m pip install -r requirements.txt -msg_ok "Installed SABnzbd" - -msg_info "Creating Service" -service_path="/etc/systemd/system/sabnzbd.service" -echo "[Unit] -Description=SABnzbd -After=network.target -[Service] -WorkingDirectory=/opt/sabnzbd -ExecStart=python3 SABnzbd.py -s 0.0.0.0:7777 -Restart=always -User=root -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q sabnzbd.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh new file mode 100644 index 00000000..5294e95b --- /dev/null +++ b/install/scrypted-install.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get -y install software-properties-common apt-utils +$STD apt-get -y update +$STD apt-get -y upgrade +$STD apt-get -y install \ + build-essential \ + gcc \ + gir1.2-gtk-3.0 \ + libcairo2-dev \ + libgirepository1.0-dev \ + libglib2.0-dev \ + libjpeg-dev \ + libgif-dev \ + libopenjp2-7 \ + libpango1.0-dev \ + librsvg2-dev \ + pkg-config \ + curl \ + sudo \ + mc +msg_ok "Installed Dependencies" + +msg_info "Installing GStreamer" +$STD apt-get -y install \ + gstreamer1.0-tools \ + libgstreamer1.0-dev \ + libgstreamer-plugins-base1.0-dev \ + libgstreamer-plugins-bad1.0-dev \ + gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-ugly \ + gstreamer1.0-libav \ + gstreamer1.0-alsa +msg_ok "Installed GStreamer" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Python3" +$STD apt-get -y install \ + python3 \ + python3-dev \ + python3-gi \ + python3-gst-1.0 \ + python3-matplotlib \ + python3-numpy \ + python3-opencv \ + python3-pil \ + python3-pip \ + python3-setuptools \ + python3-skimage \ + python3-wheel +$STD python3 -m pip install --upgrade pip +$STD python3 -m pip install aiofiles debugpy typing_extensions typing +msg_ok "Installed Python3" + +read -r -p "Would you like to add Coral Edge TPU support? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then +msg_info "Adding Coral Edge TPU Support" +$STD apt-key add <(curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg) +sh -c 'echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list' +$STD apt-get -y update +$STD apt-get -y install libedgetpu1-std +msg_ok "Coral Edge TPU Support Added" +fi + +msg_info "Installing Scrypted" +$STD sudo -u root npx -y scrypted@latest install-server +msg_info "Installed Scrypted" + +msg_info "Creating Service" +service_path="/etc/systemd/system/scrypted.service" +echo "[Unit] +Description=Scrypted service +After=network.target + +[Service] +User=root +Group=root +Type=simple +ExecStart=/usr/bin/npx -y scrypted serve +Restart=on-failure +RestartSec=3 + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now scrypted.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/scrypted-v5-install.sh b/install/scrypted-v5-install.sh deleted file mode 100644 index 60b1e6e9..00000000 --- a/install/scrypted-v5-install.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get -y install software-properties-common apt-utils -$STD apt-get -y update -$STD apt-get -y upgrade -$STD apt-get -y install \ - build-essential \ - gcc \ - gir1.2-gtk-3.0 \ - libcairo2-dev \ - libgirepository1.0-dev \ - libglib2.0-dev \ - libjpeg-dev \ - libgif-dev \ - libopenjp2-7 \ - libpango1.0-dev \ - librsvg2-dev \ - pkg-config \ - curl \ - sudo \ - mc -msg_ok "Installed Dependencies" - -msg_info "Installing GStreamer" -$STD apt-get -y install \ - gstreamer1.0-tools \ - libgstreamer1.0-dev \ - libgstreamer-plugins-base1.0-dev \ - libgstreamer-plugins-bad1.0-dev \ - gstreamer1.0-plugins-base \ - gstreamer1.0-plugins-good \ - gstreamer1.0-plugins-bad \ - gstreamer1.0-plugins-ugly \ - gstreamer1.0-libav \ - gstreamer1.0-alsa -msg_ok "Installed GStreamer" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing Python3" -$STD apt-get -y install \ - python3 \ - python3-dev \ - python3-gi \ - python3-gst-1.0 \ - python3-matplotlib \ - python3-numpy \ - python3-opencv \ - python3-pil \ - python3-pip \ - python3-setuptools \ - python3-skimage \ - python3-wheel -$STD python3 -m pip install --upgrade pip -$STD python3 -m pip install aiofiles debugpy typing_extensions typing -msg_ok "Installed Python3" - -read -r -p "Would you like to add Coral Edge TPU support? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then -msg_info "Adding Coral Edge TPU Support" -$STD apt-key add <(curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg) -sh -c 'echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list' -$STD apt-get -y update -$STD apt-get -y install libedgetpu1-std -msg_ok "Coral Edge TPU Support Added" -fi - -msg_info "Installing Scrypted" -$STD sudo -u root npx -y scrypted@latest install-server -msg_info "Installed Scrypted" - -msg_info "Creating Service" -service_path="/etc/systemd/system/scrypted.service" -echo "[Unit] -Description=Scrypted service -After=network.target - -[Service] -User=root -Group=root -Type=simple -ExecStart=/usr/bin/npx -y scrypted serve -Restart=on-failure -RestartSec=3 - -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now scrypted.service -msg_ok "Created Service" -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh new file mode 100644 index 00000000..d6682ba3 --- /dev/null +++ b/install/shinobi-install.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +ubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) +if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then + apt install sudo wget -y + sudo apt install -y software-properties-common + sudo add-apt-repository universe -y + apt update -y + apt update --fix-missing -y +fi + +msg_info "Installing Dependencies" +$STD apt-get install -y curl sudo git mc +$STD apt-get install -y make zip net-tools +$STD apt-get install -y gcc g++ cmake +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing FFMPEG" +$STD apt-get install -y ffmpeg +msg_ok "Installed FFMPEG" + +msg_info "Clonning Shinobi" +cd /opt +$STD git clone https://gitlab.com/Shinobi-Systems/Shinobi.git -b master Shinobi +cd Shinobi +gitVersionNumber=$(git rev-parse HEAD) +theDateRightNow=$(date) +touch version.json +chmod 777 version.json +echo '{"Product" : "'"Shinobi"'" , "Branch" : "'"master"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"https://gitlab.com/Shinobi-Systems/Shinobi.git"'"}' > version.json +msg_ok "Cloned Shinobi" + +msg_info "Installing Database" +sqlpass="" +echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections +echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections +$STD apt-get install -y mariadb-server +service mysql start +sqluser="root" +mysql -e "source sql/user.sql" || true +mysql -e "source sql/framework.sql" || true +msg_ok "Installed Database" +cp conf.sample.json conf.json +cronKey=$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)}') +sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json +cp super.sample.json super.json + +msg_info "Installing Shinobi" +$STD npm i npm -g +$STD npm install --unsafe-perm +$STD npm install pm2@latest -g +chmod -R 755 . +touch INSTALL/installed.txt +ln -s /opt/Shinobi/INSTALL/shinobi /usr/bin/shinobi +node /opt/Shinobi/tools/modifyConfiguration.js addToConfig="{\"cron\":{\"key\":\"$(head -c 64 < /dev/urandom | sha256sum | awk '{print substr($1,1,60)}')\"}}" &>/dev/null +$STD pm2 start camera.js +$STD pm2 start cron.js +$STD pm2 startup +$STD pm2 save +$STD pm2 list +msg_ok "Installed Shinobi" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/shinobi-v5-install.sh b/install/shinobi-v5-install.sh deleted file mode 100644 index 755148af..00000000 --- a/install/shinobi-v5-install.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update --fix-missing -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -ubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) -if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then - apt install sudo wget -y - sudo apt install -y software-properties-common - sudo add-apt-repository universe -y - apt update -y - apt update --fix-missing -y -fi - -msg_info "Installing Dependencies" -$STD apt-get install -y curl sudo git mc -$STD apt-get install -y make zip net-tools -$STD apt-get install -y gcc g++ cmake -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing FFMPEG" -$STD apt-get install -y ffmpeg -msg_ok "Installed FFMPEG" - -msg_info "Clonning Shinobi" -cd /opt -$STD git clone https://gitlab.com/Shinobi-Systems/Shinobi.git -b master Shinobi -cd Shinobi -gitVersionNumber=$(git rev-parse HEAD) -theDateRightNow=$(date) -touch version.json -chmod 777 version.json -echo '{"Product" : "'"Shinobi"'" , "Branch" : "'"master"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"https://gitlab.com/Shinobi-Systems/Shinobi.git"'"}' > version.json -msg_ok "Cloned Shinobi" - -msg_info "Installing Database" -sqlpass="" -echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections -echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections -$STD apt-get install -y mariadb-server -service mysql start -sqluser="root" -mysql -e "source sql/user.sql" || true -mysql -e "source sql/framework.sql" || true -msg_ok "Installed Database" -cp conf.sample.json conf.json -cronKey=$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)}') -sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json -cp super.sample.json super.json - -msg_info "Installing Shinobi" -$STD npm i npm -g -$STD npm install --unsafe-perm -$STD npm install pm2@latest -g -chmod -R 755 . -touch INSTALL/installed.txt -ln -s /opt/Shinobi/INSTALL/shinobi /usr/bin/shinobi -node /opt/Shinobi/tools/modifyConfiguration.js addToConfig="{\"cron\":{\"key\":\"$(head -c 64 < /dev/urandom | sha256sum | awk '{print substr($1,1,60)}')\"}}" &>/dev/null -$STD pm2 start camera.js -$STD pm2 start cron.js -$STD pm2 startup -$STD pm2 save -$STD pm2 list -msg_ok "Installed Shinobi" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh new file mode 100644 index 00000000..52961b31 --- /dev/null +++ b/install/sonarr-install.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +$STD apt-get install -y ca-certificates +msg_ok "Installed Dependencies" + +msg_info "Installing Sonarr" +$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 +sh -c 'echo "deb https://apt.sonarr.tv/debian buster-develop main" > /etc/apt/sources.list.d/sonarr.list' +$STD apt-get update +$STD apt-get -o Dpkg::Options::="--force-confold" install -y sonarr +msg_ok "Installed Sonarr" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/sonarr-v5-install.sh b/install/sonarr-v5-install.sh deleted file mode 100644 index 9ca338dc..00000000 --- a/install/sonarr-v5-install.sh +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -export DEBIAN_FRONTEND=noninteractive -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -$STD apt-get install -y ca-certificates -msg_ok "Installed Dependencies" - -msg_info "Installing Sonarr" -$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 -sh -c 'echo "deb https://apt.sonarr.tv/debian buster-develop main" > /etc/apt/sources.list.d/sonarr.list' -$STD apt-get update -$STD apt-get -o Dpkg::Options::="--force-confold" install -y sonarr -msg_ok "Installed Sonarr" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh new file mode 100644 index 00000000..14cd1b99 --- /dev/null +++ b/install/syncthing-install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing Syncthing" +curl -s -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg +sh -c 'echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" > /etc/apt/sources.list.d/syncthing.list' +$STD apt-get update +$STD apt-get install -y syncthing +$STD systemctl enable syncthing@root.service +systemctl start syncthing@root.service +sleep 5 +sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.config/syncthing/config.xml +systemctl restart syncthing@root.service +msg_ok "Installed Syncthing" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/syncthing-v5-install.sh b/install/syncthing-v5-install.sh deleted file mode 100644 index 315a88da..00000000 --- a/install/syncthing-v5-install.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -msg_ok "Installed Dependencies" - -msg_info "Installing Syncthing" -curl -s -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg -sh -c 'echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" > /etc/apt/sources.list.d/syncthing.list' -$STD apt-get update -$STD apt-get install -y syncthing -$STD systemctl enable syncthing@root.service -systemctl start syncthing@root.service -sleep 5 -sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.config/syncthing/config.xml -systemctl restart syncthing@root.service -msg_ok "Installed Syncthing" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh new file mode 100644 index 00000000..34e4ce6a --- /dev/null +++ b/install/tdarr-install.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing Tdarr" +mkdir -p /opt/tdarr +cd /opt/tdarr +wget -q https://f000.backblazeb2.com/file/tdarrs/versions/2.00.15/linux_x64/Tdarr_Updater.zip +$STD unzip Tdarr_Updater.zip +chmod +x Tdarr_Updater +$STD ./Tdarr_Updater +msg_ok "Installed Tdarr" + +msg_info "Creating Service" +service_path="/etc/systemd/system/tdarr-server.service" +echo "[Unit] +Description=Tdarr Server Daemon +After=network.target +# Enable if using ZFS, edit and enable if other FS mounting is required to access directory +#Requires=zfs-mount.service + +[Service] +User=root +Group=root + +Type=simple +WorkingDirectory=/opt/tdarr/Tdarr_Server +ExecStartPre=/opt/tdarr/Tdarr_Updater +ExecStart=/opt/tdarr/Tdarr_Server/Tdarr_Server +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path + +service_path="/etc/systemd/system/tdarr-node.service" +echo "[Unit] +Description=Tdarr Node Daemon +After=network.target +Requires=tdarr-server.service + +[Service] +User=root +Group=root + +Type=simple +WorkingDirectory=/opt/tdarr/Tdarr_Node +ExecStart=/opt/tdarr/Tdarr_Node/Tdarr_Node +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q tdarr-server.service +systemctl enable --now -q tdarr-node.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf Tdarr_Updater.zip +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/tdarr-v5-install.sh b/install/tdarr-v5-install.sh deleted file mode 100644 index 705a53ce..00000000 --- a/install/tdarr-v5-install.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y unzip -msg_ok "Installed Dependencies" - -msg_info "Installing Tdarr" -mkdir -p /opt/tdarr -cd /opt/tdarr -wget -q https://f000.backblazeb2.com/file/tdarrs/versions/2.00.15/linux_x64/Tdarr_Updater.zip -$STD unzip Tdarr_Updater.zip -chmod +x Tdarr_Updater -$STD ./Tdarr_Updater -msg_ok "Installed Tdarr" - -msg_info "Creating Service" -service_path="/etc/systemd/system/tdarr-server.service" -echo "[Unit] -Description=Tdarr Server Daemon -After=network.target -# Enable if using ZFS, edit and enable if other FS mounting is required to access directory -#Requires=zfs-mount.service - -[Service] -User=root -Group=root - -Type=simple -WorkingDirectory=/opt/tdarr/Tdarr_Server -ExecStartPre=/opt/tdarr/Tdarr_Updater -ExecStart=/opt/tdarr/Tdarr_Server/Tdarr_Server -TimeoutStopSec=20 -KillMode=process -Restart=on-failure - -[Install] -WantedBy=multi-user.target" >$service_path - -service_path="/etc/systemd/system/tdarr-node.service" -echo "[Unit] -Description=Tdarr Node Daemon -After=network.target -Requires=tdarr-server.service - -[Service] -User=root -Group=root - -Type=simple -WorkingDirectory=/opt/tdarr/Tdarr_Node -ExecStart=/opt/tdarr/Tdarr_Node/Tdarr_Node -TimeoutStopSec=20 -KillMode=process -Restart=on-failure - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q tdarr-server.service -systemctl enable --now -q tdarr-node.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf Tdarr_Updater.zip -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh new file mode 100644 index 00000000..a795fa37 --- /dev/null +++ b/install/technitiumdns-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing ASP.NET Core Runtime" +wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb +$STD dpkg -i packages-microsoft-prod.deb +rm -rf packages-microsoft-prod.deb +$STD apt-get update +$STD apt-get install -y aspnetcore-runtime-7.0 +msg_ok "Installed ASP.NET Core Runtime" + +msg_info "Installing Technitium DNS" +systemctl stop systemd-resolved +echo "DNSStubListener=no" >>/etc/systemd/resolved.conf +ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf +$STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) +msg_ok "Installed Technitium DNS" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/technitiumdns-v5-install.sh b/install/technitiumdns-v5-install.sh deleted file mode 100644 index 8570aebc..00000000 --- a/install/technitiumdns-v5-install.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing ASP.NET Core Runtime" -wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb -$STD dpkg -i packages-microsoft-prod.deb -rm -rf packages-microsoft-prod.deb -$STD apt-get update -$STD apt-get install -y aspnetcore-runtime-7.0 -msg_ok "Installed ASP.NET Core Runtime" - -msg_info "Installing Technitium DNS" -systemctl stop systemd-resolved -echo "DNSStubListener=no" >>/etc/systemd/resolved.conf -ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -$STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) -msg_ok "Installed Technitium DNS" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/transmission-install.sh b/install/transmission-install.sh new file mode 100644 index 00000000..1c7c6f0c --- /dev/null +++ b/install/transmission-install.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + + +msg_info "Installing Transmission" +$STD apt-get install -y transmission-daemon +systemctl stop transmission-daemon +sed -i '{s/"rpc-whitelist-enabled": true/"rpc-whitelist-enabled": false/g; s/"rpc-host-whitelist-enabled": true,/"rpc-host-whitelist-enabled": false,/g}' /etc/transmission-daemon/settings.json +systemctl start transmission-daemon +msg_ok "Installed Transmission" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/transmission-v5-install.sh b/install/transmission-v5-install.sh deleted file mode 100644 index c2e22764..00000000 --- a/install/transmission-v5-install.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - - -msg_info "Installing Transmission" -$STD apt-get install -y transmission-daemon -systemctl stop transmission-daemon -sed -i '{s/"rpc-whitelist-enabled": true/"rpc-whitelist-enabled": false/g; s/"rpc-host-whitelist-enabled": true,/"rpc-host-whitelist-enabled": false,/g}' /etc/transmission-daemon/settings.json -systemctl start transmission-daemon -msg_ok "Installed Transmission" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/trilium-install.sh b/install/trilium-install.sh new file mode 100644 index 00000000..02ab6d0f --- /dev/null +++ b/install/trilium-install.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Installing Trilium" +wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz +$STD tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz +mv trilium-linux-x64-server /opt/trilium +msg_ok "Installed Trilium" + +msg_info "Creating Service" +service_path="/etc/systemd/system/trilium.service" + +echo "[Unit] +Description=Trilium Daemon +After=syslog.target network.target + +[Service] +User=root +Type=simple +ExecStart=/opt/trilium/trilium.sh +WorkingDirectory=/opt/trilium/ +TimeoutStopSec=20 +Restart=always + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q trilium +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +rm -rf /root/trilium-linux-x64-server-$RELEASE.tar.xz +msg_ok "Cleaned" diff --git a/install/trilium-v5-install.sh b/install/trilium-v5-install.sh deleted file mode 100644 index 05a61efa..00000000 --- a/install/trilium-v5-install.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -msg_info "Installing Trilium" -wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz -$STD tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz -mv trilium-linux-x64-server /opt/trilium -msg_ok "Installed Trilium" - -msg_info "Creating Service" -service_path="/etc/systemd/system/trilium.service" - -echo "[Unit] -Description=Trilium Daemon -After=syslog.target network.target - -[Service] -User=root -Type=simple -ExecStart=/opt/trilium/trilium.sh -WorkingDirectory=/opt/trilium/ -TimeoutStopSec=20 -Restart=always - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q trilium -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -rm -rf /root/trilium-linux-x64-server-$RELEASE.tar.xz -msg_ok "Cleaned" diff --git a/install/ubuntu-install.sh b/install/ubuntu-install.sh new file mode 100644 index 00000000..eb2b237b --- /dev/null +++ b/install/ubuntu-install.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/ubuntu-v5-install.sh b/install/ubuntu-v5-install.sh deleted file mode 100644 index 9f1409ff..00000000 --- a/install/ubuntu-v5-install.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/umbrel-install.sh b/install/umbrel-install.sh new file mode 100644 index 00000000..4ec349db --- /dev/null +++ b/install/umbrel-install.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Umbrel (Patience)" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then +VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /usr/local/bin +curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 +chmod 755 /usr/local/bin/fuse-overlayfs +cd ~ +echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +else +echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json +fi +$STD bash <(curl -fsSL https://umbrel.sh) +systemctl daemon-reload +$STD systemctl enable --now umbrel-startup.service +msg_ok "Installed Umbrel" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/umbrel-v5-install.sh b/install/umbrel-v5-install.sh deleted file mode 100644 index 8846aa68..00000000 --- a/install/umbrel-v5-install.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Umbrel (Patience)" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi -$STD bash <(curl -fsSL https://umbrel.sh) -systemctl daemon-reload -$STD systemctl enable --now umbrel-startup.service -msg_ok "Installed Umbrel" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/unifi-install.sh b/install/unifi-install.sh new file mode 100644 index 00000000..530fcd0d --- /dev/null +++ b/install/unifi-install.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +read -r -p "Local Controller? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + LOCAL="--local-controller" +else + LOCAL="" +fi + +msg_info "Installing UniFi Network Application (Patience)" +wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh +$STD bash unifi-latest.sh --skip --add-repository $LOCAL +msg_ok "Installed UniFi Network Application" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/unifi-v5-install.sh b/install/unifi-v5-install.sh deleted file mode 100644 index 1eaa6cf3..00000000 --- a/install/unifi-v5-install.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -#https://community.ui.com/questions/UniFi-Installation-Scripts-or-UniFi-Easy-Update-Script-or-UniFi-Lets-Encrypt-or-UniFi-Easy-Encrypt-/ccbc7530-dd61-40a7-82ec-22b17f027776 -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -read -r -p "Local Controller? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - LOCAL="--local-controller" -else - LOCAL="" -fi - -msg_info "Installing UniFi Network Application (Patience)" -wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh -$STD bash unifi-latest.sh --skip --add-repository $LOCAL -msg_ok "Installed UniFi Network Application" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh new file mode 100644 index 00000000..d5af2231 --- /dev/null +++ b/install/uptimekuma-install.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD sudo apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Uptime Kuma" +$STD git clone https://github.com/louislam/uptime-kuma.git +mv uptime-kuma /opt/uptime-kuma +cd /opt/uptime-kuma +$STD npm run setup +msg_ok "Installed Uptime Kuma" + +msg_info "Creating Service" +service_path="/etc/systemd/system/uptime-kuma.service" +echo "[Unit] +Description=uptime-kuma + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/uptime-kuma +ExecStart=/usr/bin/npm start + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now uptime-kuma.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/uptimekuma-v5-install.sh b/install/uptimekuma-v5-install.sh deleted file mode 100644 index d9c8284b..00000000 --- a/install/uptimekuma-v5-install.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD sudo apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing Uptime Kuma" -$STD git clone https://github.com/louislam/uptime-kuma.git -mv uptime-kuma /opt/uptime-kuma -cd /opt/uptime-kuma -$STD npm run setup -msg_ok "Installed Uptime Kuma" - -msg_info "Creating Service" -service_path="/etc/systemd/system/uptime-kuma.service" -echo "[Unit] -Description=uptime-kuma - -[Service] -Type=simple -Restart=always -User=root -WorkingDirectory=/opt/uptime-kuma -ExecStart=/usr/bin/npm start - -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now uptime-kuma.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/vaultwarden-v5-install.sh b/install/vaultwarden-install.sh similarity index 50% rename from install/vaultwarden-v5-install.sh rename to install/vaultwarden-install.sh index c1d63e1f..dd079560 100644 --- a/install/vaultwarden-v5-install.sh +++ b/install/vaultwarden-install.sh @@ -5,86 +5,13 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os msg_info "Installing Dependencies" $STD apt-get update @@ -182,23 +109,8 @@ systemctl daemon-reload $STD systemctl enable --now vaultwarden.service msg_ok "Created Service" -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi +motd_ssh +root msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/whisparr-install.sh b/install/whisparr-install.sh new file mode 100644 index 00000000..64b757f5 --- /dev/null +++ b/install/whisparr-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Whisparr" +mkdir -p /var/lib/whisparr/ +chmod 775 /var/lib/whisparr/ +$STD wget --content-disposition 'https://whisparr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=x64' +$STD tar -xvzf Whisparr.develop.*.tar.gz +mv Whisparr /opt +chmod 775 /opt/Whisparr +msg_ok "Installed Whisparr" + +msg_info "Creating Service" +cat </etc/systemd/system/whisparr.service +[Unit] +Description=whisparr Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/opt/Whisparr/Whisparr -nobrowser -data=/var/lib/whisparr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl -q daemon-reload +systemctl enable --now -q whisparr +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf Whisparr.develop.*.tar.gz +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/whisparr-v5-install.sh b/install/whisparr-v5-install.sh deleted file mode 100644 index 82d4dce7..00000000 --- a/install/whisparr-v5-install.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y sqlite3 -msg_ok "Installed Dependencies" - -msg_info "Installing Whisparr" -mkdir -p /var/lib/whisparr/ -chmod 775 /var/lib/whisparr/ -$STD wget --content-disposition 'https://whisparr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=x64' -$STD tar -xvzf Whisparr.develop.*.tar.gz -mv Whisparr /opt -chmod 775 /opt/Whisparr -msg_ok "Installed Whisparr" - -msg_info "Creating Service" -cat </etc/systemd/system/whisparr.service -[Unit] -Description=whisparr Daemon -After=syslog.target network.target -[Service] -UMask=0002 -Type=simple -ExecStart=/opt/Whisparr/Whisparr -nobrowser -data=/var/lib/whisparr/ -TimeoutStopSec=20 -KillMode=process -Restart=on-failure -[Install] -WantedBy=multi-user.target -EOF -systemctl -q daemon-reload -systemctl enable --now -q whisparr -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm -rf Whisparr.develop.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh new file mode 100644 index 00000000..943c59ad --- /dev/null +++ b/install/whoogle-install.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Python3-pip" +$STD apt-get install -y python3-pip +msg_ok "Installed Python3-pip" + +msg_info "Installing Whoogle" +$STD pip install brotli +$STD pip install whoogle-search + +service_path="/etc/systemd/system/whoogle.service" +echo "[Unit] +Description=Whoogle-Search +After=network.target +[Service] +ExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0 +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path + +$STD systemctl enable --now whoogle.service +msg_ok "Installed Whoogle" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/whoogle-v5-install.sh b/install/whoogle-v5-install.sh deleted file mode 100644 index 816a32df..00000000 --- a/install/whoogle-v5-install.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" - -msg_info "Installing Whoogle" -$STD pip install brotli -$STD pip install whoogle-search - -service_path="/etc/systemd/system/whoogle.service" -echo "[Unit] -Description=Whoogle-Search -After=network.target -[Service] -ExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0 -Restart=always -User=root -[Install] -WantedBy=multi-user.target" >$service_path - -$STD systemctl enable --now whoogle.service -msg_ok "Installed Whoogle" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh new file mode 100644 index 00000000..4bea8690 --- /dev/null +++ b/install/wikijs-install.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Wiki.js" +mkdir -p /opt/wikijs +cd /opt/wikijs +$STD wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz +tar xzf wiki-js.tar.gz +rm wiki-js.tar.gz + +cat </opt/wikijs/config.yml +bindIP: 0.0.0.0 +port: 3000 +db: + type: sqlite + storage: /opt/wikijs/db.sqlite +logLevel: info +logFormat: default +dataPath: /opt/wikijs/data +bodyParserLimit: 5mb +EOF +$STD npm rebuild sqlite3 +msg_ok "Installed Wiki.js" + +msg_info "Creating Service" +service_path="/etc/systemd/system/wikijs.service" + +echo "[Unit] +Description=Wiki.js +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/node server +Restart=always +User=root +Environment=NODE_ENV=production +WorkingDirectory=/opt/wikijs + +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable --now wikijs +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/wikijs-v5-install.sh b/install/wikijs-v5-install.sh deleted file mode 100644 index 71a6e946..00000000 --- a/install/wikijs-v5-install.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing Wiki.js" -mkdir -p /opt/wikijs -cd /opt/wikijs -$STD wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz -tar xzf wiki-js.tar.gz -rm wiki-js.tar.gz - -cat </opt/wikijs/config.yml -bindIP: 0.0.0.0 -port: 3000 -db: - type: sqlite - storage: /opt/wikijs/db.sqlite -logLevel: info -logFormat: default -dataPath: /opt/wikijs/data -bodyParserLimit: 5mb -EOF -$STD npm rebuild sqlite3 -msg_ok "Installed Wiki.js" - -msg_info "Creating Service" -service_path="/etc/systemd/system/wikijs.service" - -echo "[Unit] -Description=Wiki.js -After=network.target - -[Service] -Type=simple -ExecStart=/usr/bin/node server -Restart=always -User=root -Environment=NODE_ENV=production -WorkingDirectory=/opt/wikijs - -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now wikijs -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh new file mode 100644 index 00000000..f63333c9 --- /dev/null +++ b/install/wireguard-install.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gunicorn +msg_ok "Installed Dependencies" + +msg_info "Installing WireGuard (using pivpn.io)" +OPTIONS_PATH='/options.conf' +cat >$OPTIONS_PATH <<'EOF' +IPv4dev=eth0 +install_user=root +VPN=wireguard +pivpnNET=10.6.0.0 +subnetClass=24 +ALLOWED_IPS="0.0.0.0/0, ::0/0" +pivpnMTU=1420 +pivpnPORT=51820 +pivpnDNS1=1.1.1.1 +pivpnDNS2=8.8.8.8 +pivpnHOST= +pivpnPERSISTENTKEEPALIVE=25 +UNATTUPG=1 +EOF +$STD bash <(curl -fsSL https://install.pivpn.io) --unattended options.conf +msg_ok "Installed WireGuard" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/wireguard-v5-install.sh b/install/wireguard-v5-install.sh deleted file mode 100644 index 4d1b3127..00000000 --- a/install/wireguard-v5-install.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -OPTIONS_PATH='/options.conf' -cat >$OPTIONS_PATH <<'EOF' -IPv4dev=eth0 -install_user=root -VPN=wireguard -pivpnNET=10.6.0.0 -subnetClass=24 -ALLOWED_IPS="0.0.0.0/0, ::0/0" -pivpnMTU=1420 -pivpnPORT=51820 -pivpnDNS1=1.1.1.1 -pivpnDNS2=8.8.8.8 -pivpnHOST= -pivpnPERSISTENTKEEPALIVE=25 -UNATTUPG=1 -EOF - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gunicorn -msg_ok "Installed Dependencies" - -msg_info "Installing WireGuard (using pivpn.io)" -$STD bash <(curl -fsSL https://install.pivpn.io) --unattended options.conf -msg_ok "Installed WireGuard" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/yunohost-install.sh b/install/yunohost-install.sh new file mode 100644 index 00000000..48e7bbd6 --- /dev/null +++ b/install/yunohost-install.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg +$STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' +$STD apt-get install -y apt-transport-https +$STD apt-get install -y lsb-release +$STD apt-get install -y ca-certificates +msg_ok "Installed Dependencies" + +msg_info "Installing YunoHost (Patience)" +wget -q -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg +$STD bash <(curl -fsSL https://install.yunohost.org) -a +msg_ok "Installed YunoHost" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/yunohost-v5-install.sh b/install/yunohost-v5-install.sh deleted file mode 100644 index b8366bf0..00000000 --- a/install/yunohost-v5-install.sh +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS" -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y gnupg -$STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' -$STD apt-get install -y apt-transport-https -$STD apt-get install -y lsb-release -$STD apt-get install -y ca-certificates -msg_ok "Installed Dependencies" - -msg_info "Installing YunoHost (Patience)" -wget -q -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg -$STD bash <(curl -fsSL https://install.yunohost.org) -a -msg_ok "Installed YunoHost" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh new file mode 100644 index 00000000..ca4e2905 --- /dev/null +++ b/install/zigbee2mqtt-install.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Setting up Zigbee2MQTT Repository" +$STD git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt +msg_ok "Set up Zigbee2MQTT Repository" + +read -r -p "Switch to Edge/dev branch? (y/N) " prompt +if [[ $prompt == "y" ]]; then + DEV="y" +else + DEV="n" +fi + +msg_info "Installing Zigbee2MQTT" +cd /opt/zigbee2mqtt +if [[ $DEV == "y" ]]; then +$STD git checkout dev +fi +$STD npm ci +msg_ok "Installed Zigbee2MQTT" + +msg_info "Creating Service" +service_path="/etc/systemd/system/zigbee2mqtt.service" +echo "[Unit] +Description=zigbee2mqtt +After=network.target +[Service] +Environment=NODE_ENV=production +ExecStart=/usr/bin/npm start +WorkingDirectory=/opt/zigbee2mqtt +StandardOutput=inherit +StandardError=inherit +Restart=always +User=root +[Install] +WantedBy=multi-user.target" >$service_path +$STD systemctl enable zigbee2mqtt.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/zigbee2mqtt-v5-install.sh b/install/zigbee2mqtt-v5-install.sh deleted file mode 100644 index ae1ec650..00000000 --- a/install/zigbee2mqtt-v5-install.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -$STD apt-get install -y make -$STD apt-get install -y g++ -$STD apt-get install -y gcc -msg_ok "Installed Dependencies" - -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Setting up Zigbee2MQTT Repository" -$STD git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt -msg_ok "Set up Zigbee2MQTT Repository" - -read -r -p "Switch to Edge/dev branch? (y/N) " prompt -if [[ $prompt == "y" ]]; then - DEV="y" -else - DEV="n" -fi - -msg_info "Installing Zigbee2MQTT" -cd /opt/zigbee2mqtt -if [[ $DEV == "y" ]]; then -$STD git checkout dev -fi -$STD npm ci -msg_ok "Installed Zigbee2MQTT" - -msg_info "Creating Service" -service_path="/etc/systemd/system/zigbee2mqtt.service" -echo "[Unit] -Description=zigbee2mqtt -After=network.target -[Service] -Environment=NODE_ENV=production -ExecStart=/usr/bin/npm start -WorkingDirectory=/opt/zigbee2mqtt -StandardOutput=inherit -StandardError=inherit -Restart=always -User=root -[Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable zigbee2mqtt.service -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh new file mode 100644 index 00000000..67862f1f --- /dev/null +++ b/install/zwave-js-ui-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing Z-Wave JS UI" +mkdir /opt/zwave-js-ui +cd /opt/zwave-js-ui +RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +$STD wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip +$STD unzip zwave-js-ui-${RELEASE}-linux.zip +msg_ok "Installed Z-Wave JS UI" + +msg_info "Creating Service" +service_path="/etc/systemd/system/zwave-js-ui.service" +echo "[Unit] +Description=zwave-js-ui +Wants=network-online.target +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/zwave-js-ui +ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux +[Install] +WantedBy=multi-user.target" >$service_path +systemctl start zwave-js-ui +$STD systemctl enable zwave-js-ui +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm zwave-js-ui-${RELEASE}-linux.zip +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/zwave-js-ui-v5-install.sh b/install/zwave-js-ui-v5-install.sh deleted file mode 100644 index 41cfb081..00000000 --- a/install/zwave-js-ui-v5-install.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if [ "$VERBOSE" = "yes" ]; then set -x; STD=""; else STD="silent"; fi -silent() { "$@" > /dev/null 2>&1; } -if [ "$DISABLEIPV6" == "yes" ]; then echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf; $STD sysctl -p; fi -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -RETRY_NUM=10 -RETRY_EVERY=3 -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -BFR="\\r\\033[K" -HOLD="-" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -msg_info "Setting up Container OS " -sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen -locale-gen >/dev/null -echo $tz > /etc/timezone -ln -sf /usr/share/zoneinfo/$tz /etc/localtime -for ((i=RETRY_NUM; i>0; i--)); do - if [ "$(hostname -I)" != "" ]; then - break - fi - echo 1>&2 -en "${CROSS}${RD} No Network! " - sleep $RETRY_EVERY -done -if [ "$(hostname -I)" = "" ]; then - echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" - echo -e " 🖧 Check Network Settings" - exit 1 -fi -msg_ok "Set up Container OS" -msg_ok "Network Connected: ${BL}$(hostname -I)" - -set +e -trap - ERR -if ping -c 1 -W 1 1.1.1.1 &> /dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi -fi -RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') -if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi -set -e -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR - -msg_info "Updating Container OS" -$STD apt-get update -$STD apt-get -y upgrade -msg_ok "Updated Container OS" - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y unzip -msg_ok "Installed Dependencies" - -msg_info "Installing Z-Wave JS UI" -mkdir /opt/zwave-js-ui -cd /opt/zwave-js-ui -RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -$STD wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip -$STD unzip zwave-js-ui-${RELEASE}-linux.zip -msg_ok "Installed Z-Wave JS UI" - -msg_info "Creating Service" -service_path="/etc/systemd/system/zwave-js-ui.service" -echo "[Unit] -Description=zwave-js-ui -Wants=network-online.target -After=network-online.target -[Service] -User=root -WorkingDirectory=/opt/zwave-js-ui -ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux -[Install] -WantedBy=multi-user.target" >$service_path -systemctl start zwave-js-ui -$STD systemctl enable zwave-js-ui -msg_ok "Created Service" - -echo "export TERM='xterm-256color'" >>/root/.bashrc -echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" > /etc/motd -chmod -x /etc/update-motd.d/* -if ! getent shadow root | grep -q "^root:[^\!*]"; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM -EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" -fi -if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config; systemctl restart sshd; fi - -msg_info "Cleaning up" -rm zwave-js-ui-${RELEASE}-linux.zip -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" diff --git a/misc/alpine-install.func b/misc/alpine-install.func new file mode 100644 index 00000000..f2f74a08 --- /dev/null +++ b/misc/alpine-install.func @@ -0,0 +1,116 @@ +color() { + YW=$(echo "\033[33m") + BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") + BGN=$(echo "\033[4;92m") + GN=$(echo "\033[1;92m") + DGN=$(echo "\033[32m") + CL=$(echo "\033[m") + RETRY_NUM=10 + RETRY_EVERY=3 + i=$RETRY_NUM + CM="${GN}✓${CL}" + CROSS="${RD}✗${CL}" + BFR="\\r\\033[K" + HOLD="-" +} + +verb_ip6() { + if [ "$VERBOSE" = "yes" ]; then + set -x + STD="" + else STD="silent"; fi + silent() { "$@" >/dev/null 2>&1; } + if [ "$DISABLEIPV6" == "yes" ]; then + echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf + $STD sysctl -p + fi +} + +catch_errors() { + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +setting_up_container() { + msg_info "Setting up Container OS" + while [ $i -gt 0 ]; do + if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + i=$((i - 1)) + done + + if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 + fi + cat </etc/apk/repositories +https://dl-cdn.alpinelinux.org/alpine/edge/main +https://dl-cdn.alpinelinux.org/alpine/edge/community +https://dl-cdn.alpinelinux.org/alpine/edge/testing +EOF + msg_ok "Set up Container OS" + msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" +} + +network_check() { + set +e + trap - ERR + if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if echo "$prompt" | grep -Eq "^(y|yes)$"; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi + fi + RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') + if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi + set -e + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +update_os() { + msg_info "Updating Container OS" + $STD apk update + $STD apk upgrade + msg_ok "Updated Container OS" +} + +motd_ssh() { + echo "export TERM='xterm-256color'" >>/root/.bashrc + echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" >/etc/motd + if [[ "${SSH_ROOT}" == "yes" ]]; then + $STD rc-update add sshd + $STD /etc/init.d/sshd start + fi +} diff --git a/misc/alpine.func b/misc/alpine.func new file mode 100644 index 00000000..b784217c --- /dev/null +++ b/misc/alpine.func @@ -0,0 +1,400 @@ +variables() { + NSAPP=$(echo ${APP,,} | tr -d ' ') + var_install="${NSAPP}-install" + INTEGER='^[0-9]+([.][0-9]+)?$' +} + +color() { + YW=$(echo "\033[33m") + BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") + BGN=$(echo "\033[4;92m") + GN=$(echo "\033[1;92m") + DGN=$(echo "\033[32m") + CL=$(echo "\033[m") + CM="${GN}✓${CL}" + CROSS="${RD}✗${CL}" + BFR="\\r\\033[K" + HOLD="-" +} + +catch_errors() { + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +pve_check() { + if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +echo_default() { + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +advanced_settings() { + if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + else + exit-script + fi + + if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + exit-script + fi + + if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else + exit + fi + + if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + exit-script + fi + + if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi + else + exit-script + fi + + if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" + else + DISABLEIP6="no" + fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + exit-script + fi + + if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + else + exit-script + fi + + if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + else + exit-script + fi + + if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" + else + VERB="no" + fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +install_script() { + arch_check + pve_check + timezone=$(cat /etc/timezone) + NEXTID=$(pvesh get /cluster/nextid) + header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +start() { + if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script + fi + + if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + set +e + update_script + fi +} + +build_container() { + if [ "$VERB" == "yes" ]; then set -x; fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) + pushd $TEMP_DIR >/dev/null + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)" + export tz="$timezone" + export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export VERBOSE="$VERB" + export SSH_ROOT="${SSH}" + export CTID=$CT_ID" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW + " + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + if [ "$CT_TYPE" == "0" ]; then + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF + fi + msg_info "Starting LXC Container" + pct start "$CTID" + msg_ok "Started LXC Container" + pct exec "$CTID" -- ash -c "apk add bash >/dev/null" + lxc-attach -n "$CTID" -- bash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit + +} + +description() { + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + pct set "$CTID" -description "# ${APP} LXC + ### https://tteck.github.io/Proxmox/ + " +} diff --git a/misc/debian.func b/misc/debian.func new file mode 100644 index 00000000..fff5e559 --- /dev/null +++ b/misc/debian.func @@ -0,0 +1,403 @@ +variables() { + NSAPP=$(echo ${APP,,} | tr -d ' ') + var_install="${NSAPP}-install" + timezone=$(cat /etc/timezone) + INTEGER='^[0-9]+([.][0-9]+)?$' +} + +color() { + YW=$(echo "\033[33m") + BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") + BGN=$(echo "\033[4;92m") + GN=$(echo "\033[1;92m") + DGN=$(echo "\033[32m") + CL=$(echo "\033[m") + CM="${GN}✓${CL}" + CROSS="${RD}✗${CL}" + BFR="\\r\\033[K" + HOLD="-" +} + +catch_errors() { + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +pve_check() { + if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +echo_default() { + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +advanced_settings() { + if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + else + exit-script + fi + + if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + exit-script + fi + + if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else + exit + fi + + if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + exit-script + fi + + if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi + else + exit-script + fi + + if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" + else + DISABLEIP6="no" + fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + exit-script + fi + + if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + else + exit-script + fi + + if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + else + exit-script + fi + + if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" + else + VERB="no" + fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +install_script() { + arch_check + pve_check + NEXTID=$(pvesh get /cluster/nextid) + header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +start() { + if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script + fi + + if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script + fi +} + +build_container() { + if [ "$VERB" == "yes" ]; then set -x; fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) + pushd $TEMP_DIR >/dev/null + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" + export tz="$timezone" + export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export VERBOSE="$VERB" + export SSH_ROOT="${SSH}" + export CTID="$CT_ID" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW + " + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + if [ "$CT_TYPE" == "0" ]; then + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF + else + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + fi + msg_info "Starting LXC Container" + pct start "$CTID" + msg_ok "Started LXC Container" + lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit + +} + +description() { + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + pct set "$CTID" -description "# ${APP} LXC + ### https://tteck.github.io/Proxmox/ + " +} diff --git a/misc/docker.func b/misc/docker.func new file mode 100644 index 00000000..702f598e --- /dev/null +++ b/misc/docker.func @@ -0,0 +1,409 @@ +variables() { + NSAPP=$(echo ${APP,,} | tr -d ' ') + var_install="${NSAPP}-install" + timezone=$(cat /etc/timezone) + INTEGER='^[0-9]+([.][0-9]+)?$' +} + +color() { + YW=$(echo "\033[33m") + BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") + BGN=$(echo "\033[4;92m") + GN=$(echo "\033[1;92m") + DGN=$(echo "\033[32m") + CL=$(echo "\033[m") + CM="${GN}✓${CL}" + CROSS="${RD}✗${CL}" + BFR="\\r\\033[K" + HOLD="-" +} + +catch_errors() { + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +pve_check() { + if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +echo_default() { + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +advanced_settings() { + if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + else + exit-script + fi + + if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + exit-script + fi + + if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else + exit + fi + + if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + exit-script + fi + + if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi + else + exit-script + fi + + if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" + else + DISABLEIP6="no" + fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + exit-script + fi + + if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + else + exit-script + fi + + if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + else + exit-script + fi + + if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + FUSE="yes" + else + FUSE="no" + fi + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" + + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" + else + VERB="no" + fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +install_script() { + arch_check + pve_check + NEXTID=$(pvesh get /cluster/nextid) + header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +start() { + if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script + fi + + if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script + fi +} + +build_container() { + if [ "$VERB" == "yes" ]; then set -x; fi + if [ "$FUSE" == "yes" ]; then + FEATURES="fuse=1,keyctl=1,nesting=1" + else + FEATURES="keyctl=1,nesting=1" + fi + TEMP_DIR=$(mktemp -d) + pushd $TEMP_DIR >/dev/null + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" + export tz="$timezone" + export ST="$FUSE" + export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export VERBOSE="$VERB" + export SSH_ROOT="${SSH}" + export CTID="$CT_ID" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW + " + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +EOF + if [ "$CT_TYPE" == "0" ]; then + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF + fi + msg_info "Starting LXC Container" + pct start "$CTID" + msg_ok "Started LXC Container" + lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit + +} + +description() { + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + pct set "$CTID" -description "# ${APP} LXC + ### https://tteck.github.io/Proxmox/ + " +} diff --git a/misc/install.func b/misc/install.func new file mode 100644 index 00000000..a2fa99e0 --- /dev/null +++ b/misc/install.func @@ -0,0 +1,133 @@ +color() { + YW=$(echo "\033[33m") + BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") + BGN=$(echo "\033[4;92m") + GN=$(echo "\033[1;92m") + DGN=$(echo "\033[32m") + CL=$(echo "\033[m") + RETRY_NUM=10 + RETRY_EVERY=3 + CM="${GN}✓${CL}" + CROSS="${RD}✗${CL}" + BFR="\\r\\033[K" + HOLD="-" +} + +verb_ip6() { + if [ "$VERBOSE" = "yes" ]; then + set -x + STD="" + else STD="silent"; fi + silent() { "$@" >/dev/null 2>&1; } + if [ "$DISABLEIPV6" == "yes" ]; then + echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf + $STD sysctl -p + fi +} + +catch_errors() { + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +setting_up_container() { + msg_info "Setting up Container OS" + sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen + locale-gen >/dev/null + echo $tz >/etc/timezone + ln -sf /usr/share/zoneinfo/$tz /etc/localtime + for ((i = RETRY_NUM; i > 0; i--)); do + if [ "$(hostname -I)" != "" ]; then + break + fi + echo 1>&2 -en "${CROSS}${RD} No Network! " + sleep $RETRY_EVERY + done + if [ "$(hostname -I)" = "" ]; then + echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" + echo -e " 🖧 Check Network Settings" + exit 1 + fi + msg_ok "Set up Container OS" + msg_ok "Network Connected: ${BL}$(hostname -I)" +} + +network_check() { + set +e + trap - ERR + if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then msg_ok "Internet Connected"; else + msg_error "Internet NOT Connected" + read -r -p "Would you like to continue anyway? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi + fi + RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') + if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi + set -e + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +update_os() { + msg_info "Updating Container OS" + $STD apt-get update + $STD apt-get -y upgrade + msg_ok "Updated Container OS" +} + +motd_ssh() { + echo "export TERM='xterm-256color'" >>/root/.bashrc + echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" >/etc/motd + chmod -x /etc/update-motd.d/* + if [[ "${SSH_ROOT}" == "yes" ]]; then + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config + systemctl restart sshd + fi +} + +customize() { + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE + [Service] + ExecStart= + ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM +EOF + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" +} + +root() { + if ! getent shadow root | grep -q "^root:[^\!*]"; then + customize + fi +} diff --git a/misc/ubuntu.func b/misc/ubuntu.func new file mode 100644 index 00000000..04695499 --- /dev/null +++ b/misc/ubuntu.func @@ -0,0 +1,428 @@ +variables() { + NSAPP=$(echo ${APP,,} | tr -d ' ') + var_install="${NSAPP}-install" + timezone=$(cat /etc/timezone) + INTEGER='^[0-9]+([.][0-9]+)?$' +} + +color() { + YW=$(echo "\033[33m") + BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") + BGN=$(echo "\033[4;92m") + GN=$(echo "\033[1;92m") + DGN=$(echo "\033[32m") + CL=$(echo "\033[m") + CM="${GN}✓${CL}" + CROSS="${RD}✗${CL}" + BFR="\\r\\033[K" + HOLD="-" +} + +catch_errors() { + set -Eeuo pipefail + trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +} + +error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" +} + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +pve_check() { + if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.0 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +echo_default() { + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" + echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" + echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" + echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" + echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" + echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" + echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" + echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" + echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" + echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" +} + +exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +advanced_settings() { + if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" + else + exit-script + fi + + if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" ON \ + "0" "Privileged" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + else + exit-script + fi + + if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW=" " + else + PW="-password $PW1" + fi + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + exit-script + fi + + if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if [ -z "$CT_ID" ]; then + CT_ID="$NEXTID" + echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" + else + echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" + fi + else + exit + fi + + if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if [ -z "$CT_NAME" ]; then + HN="$NSAPP" + else + HN=$(echo ${CT_NAME,,} | tr -d ' ') + fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + exit-script + fi + + if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if [ -z "$DISK_SIZE" ]; then + DISK_SIZE="$var_disk" + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + else + if ! [[ $DISK_SIZE =~ $INTEGER ]]; then + echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" + advanced_settings + fi + echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if [ -z "$CORE_COUNT" ]; then + CORE_COUNT="$var_cpu" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if [ -z "$RAM_SIZE" ]; then + RAM_SIZE="$var_ram" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if [ -z "$BRG" ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $NET ]; then + NET="dhcp" + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + else + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + fi + else + exit-script + fi + + if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then + if [ -z $GATE1 ]; then + GATE1="Default" + GATE="" + else + GATE=",gw=$GATE1" + fi + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + DISABLEIP6="yes" + else + DISABLEIP6="no" + fi + echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" + + if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + else + MTU=",mtu=$MTU1" + fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + exit-script + fi + + if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if [ -z $SD ]; then + SX=Host + SD="" + else + SX=$SD + SD="-searchdomain=$SD" + fi + echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" + else + exit-script + fi + + if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if [ -z $NX ]; then + NX=Host + NS="" + else + NS="-nameserver=$NX" + fi + echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" + else + exit-script + fi + + if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC1="Default" + MAC="" + else + MAC=",hwaddr=$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + else + VLAN=",tag=$VLAN1" + fi + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + exit-script + fi + + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + VERB="yes" + else + VERB="no" + fi + echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" + + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +install_script() { + arch_check + pve_check + NEXTID=$(pvesh get /cluster/nextid) + header_info + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +start() { + if command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + install_script + fi + + if ! command -v pveversion >/dev/null 2>&1; then + if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + clear + echo -e "⚠ User exited script \n" + exit + fi + update_script + fi +} + +build_container() { + if [ "$VERB" == "yes" ]; then set -x; fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" + fi + TEMP_DIR=$(mktemp -d) + pushd $TEMP_DIR >/dev/null + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" + export tz="$timezone" + export DISABLEIPV6="$DISABLEIP6" + export APPLICATION="$APP" + export VERBOSE="$VERB" + export SSH_ROOT="${SSH}" + export CTID="$CT_ID" + export PCT_OSTYPE="$var_os" + export PCT_OSVERSION="$var_version" + export PCT_DISK_SIZE="$DISK_SIZE" + export PCT_OPTIONS=" + -features $FEATURES + -hostname $HN + $SD + $NS + -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU + -onboot 1 + -cores $CORE_COUNT + -memory $RAM_SIZE + -unprivileged $CT_TYPE + $PW + " + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf + if [ "$CT_TYPE" == "0" ]; then + if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" ]]; then + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 188:* rwm +lxc.cgroup2.devices.allow: c 189:* rwm +lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir +lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file +lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file +EOF + fi + fi + + if [ "$CT_TYPE" == "0" ]; then + if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" ]]; then + cat <>$LXC_CONFIG +lxc.cgroup2.devices.allow: a +lxc.cap.drop: +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file +EOF + fi + fi + + msg_info "Starting LXC Container" + pct start "$CTID" + msg_ok "Started LXC Container" + lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit + +} + +description() { + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) + pct set "$CTID" -description "# ${APP} LXC + ### https://tteck.github.io/Proxmox/ + " +} diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm-v5.sh index e89c1951..5160d8be 100644 --- a/vm/haos-vm-v5.sh +++ b/vm/haos-vm-v5.sh @@ -6,10 +6,10 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { -clear -cat <<"EOF" + clear + cat <<"EOF" __ __ ___ _ __ __ ____ _____ - / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____v5/ /_ / __ \/ ___/ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / /_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ @@ -20,18 +20,18 @@ header_info echo -e "\n Loading..." GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') NEXTID=$(pvesh get /cluster/nextid) -VERSIONS=( stable beta dev ) +VERSIONS=(stable beta dev) for version in "${VERSIONS[@]}"; do eval "$version=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/$version.json | grep "ova" | cut -d '"' -f 4)" done -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -HA=`echo "\033[1;34m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -67,25 +67,25 @@ else fi function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" - echo -e "Exiting..." - sleep 2 - exit -fi + if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi } function ARCH_CHECK() { if [ "$(dpkg --print-architecture)" != "amd64" ]; then @@ -122,121 +122,138 @@ function default_settings() { echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ -"$stable" "Stable " ON \ -"$beta" "Beta " OFF \ -"$dev" "Dev " OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi -while true; do - VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ + "$stable" "Stable " ON \ + "$beta" "Beta " OFF \ + "$dev" "Dev " OFF \ + 3>&1 1>&2 2>&3) exitstatus=$? - if [ -z "$VMID" ]; then - VMID="$NEXTID" - echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" - break - else - if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then - echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" - sleep 2 - continue + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi + while true; do + VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z "$VMID" ]; then + VMID="$NEXTID" + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break fi - echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" - break - fi -done + done -MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ -"i440fx" "Machine i440fx" ON \ -"q35" "Machine q35" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $MACH = q35 ]; then - echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" - FORMAT="" - MACHINE=" -machine q35" + MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "i440fx" "Machine i440fx" ON \ + "q35" "Machine q35" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" else - echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" - FORMAT=",efitype=4m" - MACHINE="" -fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $VM_NAME ]; then HN="haos${BRANCH}"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $MAC1 ]; then MAC="$GEN_MAC"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}"; -else - if [ $exitstatus = 0 ]; then MAC="$MAC1"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"; fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" fi -fi -if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $VM_NAME ]; then + HN="haos${BRANCH}" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="4096" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + if [ $exitstatus = 0 ]; then + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" -else + else echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function START_SCRIPT() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } ARCH_CHECK PVE_CHECK @@ -251,29 +268,29 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi -STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content images | awk 'NR>1') VALID=$(pvesm status -content images | awk 'NR>1') if [ -z "$VALID" ]; then -msg_error "Unable to detect a valid storage location." + msg_error "Unable to detect a valid storage location." exit -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the HAOS VM?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "Which storage pool you would like to use for the HAOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image" -if [ "$BRANCH" == "$dev" ]; then -URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +if [ "$BRANCH" == "$dev" ]; then + URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz else -URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz + URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz fi sleep 2 msg_ok "${CL}${BL}${URL}${CL}" @@ -285,19 +302,19 @@ msg_info "Extracting KVM Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_IMPORT="-format raw" - THIN="" - ;; - btrfs) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_IMPORT="-format raw" - FORMAT=",efitype=4m" - THIN="" - ;; +nfs | dir) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + THIN="" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" + ;; esac for i in {0,1}; do disk="DISK$i" @@ -319,8 +336,8 @@ qm set $VMID \ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then -msg_info "Starting Home Assistant OS VM" -qm start $VMID -msg_ok "Started Home Assistant OS VM" + msg_info "Starting Home Assistant OS VM" + qm start $VMID + msg_ok "Started Home Assistant OS VM" fi msg_ok "Completed Successfully!\n" diff --git a/vm/mikrotik-routeros-v5.sh b/vm/mikrotik-routeros.sh similarity index 51% rename from vm/mikrotik-routeros-v5.sh rename to vm/mikrotik-routeros.sh index 7e0bcdda..62930234 100644 --- a/vm/mikrotik-routeros-v5.sh +++ b/vm/mikrotik-routeros.sh @@ -6,9 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { -cat <<"EOF" + cat <<"EOF" __ ____ __ __ _ __ ____ __ ____ _____ - / |/ (_) /___________ / /_(_) /__ / __ \____v5__ __/ /____ _____/ __ \/ ___/ + / |/ (_) /___________ / /_(_) /__ / __ \____ __ __/ /____ _____/ __ \/ ___/ / /|_/ / / //_/ ___/ __ \/ __/ / //_/ / /_/ / __ \/ / / / __/ _ \/ ___/ / / /\__ \ / / / / / < / / / /_/ / /_/ / < / _ _/ /_/ / /_/ / /_/ __/ / / /_/ /___/ / /_/ /_/_/_/|_/_/ \____/\__/_/_/|_| /_/ |_|\____/\__,_/\__/\___/_/ \____//____/ @@ -20,14 +20,14 @@ header_info echo -e "Loading..." GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') NEXTID=$(pvesh get /cluster/nextid) -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -HA=`echo "\033[1;34m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -62,144 +62,145 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ `pveversion | grep "pve-manager/7" | wc -l` -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: 7.XX" - echo "Exiting..." - sleep 3 - exit +if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: 7.XX" + echo "Exiting..." + sleep 3 + exit fi if (whiptail --title "Mikrotik RouterOS VM" --yesno "This will create a New Mikrotik RouterOS VM. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function default_settings() { - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}mikrotik-routeros${CL}" - HN=mikrotik-routeros - echo -e "${DGN}Allocated Cores: ${BGN}1${CL}" - CORE_COUNT="1" - echo -e "${DGN}Allocated RAM: ${BGN}1024${CL}" - RAM_SIZE="1024" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" - START_VM="no" - echo -e "${BL}Creating a Mikrotik RouterOS VM using the above default settings${CL}" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}mikrotik-routeros${CL}" + HN=mikrotik-routeros + echo -e "${DGN}Allocated Cores: ${BGN}1${CL}" + CORE_COUNT="1" + echo -e "${DGN}Allocated RAM: ${BGN}1024${CL}" + RAM_SIZE="1024" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + echo -e "${BL}Creating a Mikrotik RouterOS VM using the above default settings${CL}" } function advanced_settings() { -VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" -else + else exit -fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 Mikrotik-RouterOS --title "HOSTNAME" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + fi + VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 Mikrotik-RouterOS --title "HOSTNAME" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' ') echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else + else exit -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" -else + else exit -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" -else + else exit -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" -else + else exit -fi -MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then + fi + MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then MAC="$MAC1" echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" -else - exit -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + exit fi -fi -if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS VM when completed?" 10 58); then + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS VM when completed?" 10 58); then echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}yes${CL}" START_VM="yes" -else + else echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}no${CL}" START_VM="no" -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create Mikrotik RouterOS VM?" 10 58); then + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create Mikrotik RouterOS VM?" 10 58); then echo -e "${RD}Creating Mikrotik RouterOS VM using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function start_script() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } start_script msg_info "Validating Storage" @@ -212,21 +213,21 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi -STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content images | awk 'NR>1') VALID=$(pvesm status -content images | awk 'NR>1') if [ -z "$VALID" ]; then - echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" - echo -e "Exiting..." - exit -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then + echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" + echo -e "Exiting..." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the Mikrotik RouterOS VM?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "Which storage pool you would like to use for the Mikrotik RouterOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." @@ -245,17 +246,17 @@ msg_info "Extracting Mikrotik RouterOS Disk Image" gunzip -f -S .zip $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DISK_IMPORT="-format qcow2" - ;; - btrfs) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_FORMAT="subvol" - DISK_IMPORT="-format raw" - ;; +nfs | dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_FORMAT="subvol" + DISK_IMPORT="-format raw" + ;; esac for i in {0,1}; do disk="DISK$i" @@ -277,8 +278,8 @@ qm set $VMID \ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Mikrotik RouterOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then -msg_info "Starting Mikrotik RouterOS VM" -qm start $VMID -msg_ok "Started Mikrotik RouterOS VM" + msg_info "Starting Mikrotik RouterOS VM" + qm start $VMID + msg_ok "Started Mikrotik RouterOS VM" fi msg_ok "Completed Successfully!\n" diff --git a/vm/pimox-haos-vm-v5.sh b/vm/pimox-haos-vm.sh similarity index 50% rename from vm/pimox-haos-vm-v5.sh rename to vm/pimox-haos-vm.sh index c116c84a..ca69e858 100644 --- a/vm/pimox-haos-vm-v5.sh +++ b/vm/pimox-haos-vm.sh @@ -6,13 +6,13 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { -cat <<"EOF" + cat <<"EOF" ____ _ __ ___ / __ \(_) |/ /___ _ __ / /_/ / / /|_/ / __ \| |/_/ / ____/ / / / / /_/ /> < __ __ /_/_ /_/_/ /_/\____/_/|_| __ ____ _____ - / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____v5/ /_ / __ \/ ___/ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / /_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ @@ -28,14 +28,14 @@ NEXTID=$(pvesh get /cluster/nextid) STABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') BETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') DEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep "ova" | awk '{print substr($2, 2, length($2)-3) }') -YW=`echo "\033[33m"` -BL=`echo "\033[36m"` -HA=`echo "\033[1;34m"` -RD=`echo "\033[01;31m"` -BGN=`echo "\033[4;92m"` -GN=`echo "\033[1;92m"` -DGN=`echo "\033[32m"` -CL=`echo "\033[m"` +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" @@ -72,20 +72,20 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if (whiptail --title "PiMox HAOS VM" --yesno "This will create a New PiMox HAOS VM. Proceed?" 10 58); then - echo "User selected Yes" + echo "User selected Yes" else - clear - echo -e "⚠ User exited script \n" - exit + clear + echo -e "⚠ User exited script \n" + exit fi function PVE_CHECK() { -if [ `pveversion | grep "pve-manager/7.2\|7.3" | wc -l` -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: =>7.2" - echo "Exiting..." - sleep 2 - exit -fi + if [ $(pveversion | grep "pve-manager/7.2\|7.3" | wc -l) -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: =>7.2" + echo "Exiting..." + sleep 2 + exit + fi } function ARCH_CHECK() { ARCH=$(dpkg --print-architecture) @@ -97,142 +97,160 @@ function ARCH_CHECK() { fi } function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } function default_settings() { - echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" - BRANCH=${STABLE} - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" - VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" - HN=haos${STABLE} - echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" - CORE_COUNT="2" - echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" - RAM_SIZE="4096" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" - MAC=$GEN_MAC - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" - echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" + echo -e "${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}" + BRANCH=${STABLE} + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}" + HN=haos${STABLE} + echo -e "${DGN}Allocated Cores: ${BGN}2${CL}" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}4096${CL}" + RAM_SIZE="4096" + echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { -BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ -"$STABLE" "Stable" ON \ -"$BETA" "Beta" OFF \ -"$DEV" "Dev" OFF \ -3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi -VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $VMID ]; then VMID="$NEXTID"; echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}"; + BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ + "$STABLE" "Stable" ON \ + "$BETA" "Beta" OFF \ + "$DEV" "Dev" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi + VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $VMID ]; then + VMID="$NEXTID" + echo -e "${DGN}Virtual Machine: ${BGN}$VMID${CL}" else - if echo "$USEDID" | egrep -q "$VMID" - then + if echo "$USEDID" | egrep -q "$VMID"; then echo -e "\n🚨 ${RD}ID $VMID is already in use${CL} \n" echo -e "Exiting Script \n" - sleep 2; + sleep 2 exit - else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi; + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi fi -fi -VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $VM_NAME ]; then HN="haos${BRANCH}"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; -else - if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; -fi -CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $CORE_COUNT ]; then CORE_COUNT="2"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; -fi -RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $RAM_SIZE ]; then RAM_SIZE="4096"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; -fi -BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; -else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; -fi -MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ -z $MAC1 ]; then MAC="$GEN_MAC"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}"; -else - if [ $exitstatus = 0 ]; then MAC="$MAC1"; echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"; fi -fi -VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi -fi -MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) -exitstatus=$? -if [ $exitstatus = 0 ]; then - if [ -z $MTU1 ]; then - MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi -fi -if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $VM_NAME ]; then + HN="haos${BRANCH}" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + if [ $exitstatus = 0 ]; then + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $RAM_SIZE ]; then + RAM_SIZE="4096" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + fi + MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + if [ $exitstatus = 0 ]; then + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" -else + else echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" -fi -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } function START_SCRIPT() { -if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - clear - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi } ARCH_CHECK PVE_CHECK @@ -246,19 +264,19 @@ while read -r line; do if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content images | awk 'NR>1') -if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then +if [ $((${#STORAGE_MENU[@]} / 3)) -eq 0 ]; then echo -e "'Disk image' needs to be selected for at least one storage location." die "Unable to detect valid storage location." -elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the HAOS VM?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "Which storage pool you would like to use for the HAOS VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." @@ -275,10 +293,11 @@ msg_info "Extracting Disk Image" unxz $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in - nfs|dir) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DISK_IMPORT="-format qcow2" +nfs | dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; esac for i in {0,1}; do disk="DISK$i" @@ -301,8 +320,8 @@ qm set $VMID -description "# PiMox HAOS [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then -msg_info "Starting Home Assistant OS VM" -qm start $VMID -msg_ok "Started Home Assistant OS VM" + msg_info "Starting Home Assistant OS VM" + qm start $VMID + msg_ok "Started Home Assistant OS VM" fi msg_ok "Completed Successfully!\n" From 5c51a02e72a84e7fdad78de51f2f2c70e7461f03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Mar 2023 20:56:42 -0400 Subject: [PATCH 4495/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 6bf0a220..907c02ea 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,15 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-22 + +### Changed + +- **The latest iteration of the scripts** + - Going forward, versioning will no longer be utilized in order to avoid breaking web-links in blogs and YouTube videos. + - The scripts have been made more legible as the repetitive code has been moved to function files, making it simpler to share among the scripts and hopefully easier to maintain. This also makes it simpler to contribute to the project. + - When a container is created with privileged mode enabled, the USB passthrough feature is automatically activated. + ## 2023-03-18 ### Changed From dfe60d333f4281eb561b798522df2507d6bdbfd6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Mar 2023 21:43:08 -0400 Subject: [PATCH 4496/6505] tweak --- misc/debian.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/debian.func b/misc/debian.func index fff5e559..de4979d3 100644 --- a/misc/debian.func +++ b/misc/debian.func @@ -369,6 +369,7 @@ build_container() { $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf if [ "$CT_TYPE" == "0" ]; then cat <>$LXC_CONFIG From 7d893af4e880845fa2db997090a5cf9918559073 Mon Sep 17 00:00:00 2001 From: Jimi Ford Date: Wed, 22 Mar 2023 20:14:35 -0600 Subject: [PATCH 4497/6505] fix EOF whitespace issue (#1223) --- misc/debian.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/debian.func b/misc/debian.func index de4979d3..38a2d271 100644 --- a/misc/debian.func +++ b/misc/debian.func @@ -387,7 +387,7 @@ EOF cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: -EOF +EOF fi msg_info "Starting LXC Container" pct start "$CTID" From 33cc2d9c992133edd402a128031e0b2774338fd5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Mar 2023 22:24:31 -0400 Subject: [PATCH 4498/6505] Update alpine.func fix open bracket --- misc/alpine.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/alpine.func b/misc/alpine.func index b784217c..5e58cfd9 100644 --- a/misc/alpine.func +++ b/misc/alpine.func @@ -353,7 +353,7 @@ build_container() { export APPLICATION="$APP" export VERBOSE="$VERB" export SSH_ROOT="${SSH}" - export CTID=$CT_ID" + export CTID="$CT_ID" export PCT_OSTYPE="$var_os" export PCT_OSVERSION="$var_version" export PCT_DISK_SIZE="$DISK_SIZE" From baa9bb9e2ea7ea1d198488d182c5e14c5b9945f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 00:09:04 -0400 Subject: [PATCH 4499/6505] code refactoring --- ct/adguard.sh | 2 +- ct/audiobookshelf.sh | 2 +- ct/autobrr.sh | 2 +- ct/blocky.sh | 2 +- ct/changedetection.sh | 2 +- ct/cronicle.sh | 2 +- ct/daemonsync.sh | 2 +- ct/dashy.sh | 2 +- ct/debian.sh | 2 +- ct/deconz.sh | 2 +- ct/deluge.sh | 2 +- ct/devuan.sh | 2 +- ct/emby.sh | 2 +- ct/emqx.sh | 2 +- ct/esphome.sh | 2 +- ct/go2rtc.sh | 2 +- ct/grafana.sh | 2 +- ct/grocy.sh | 2 +- ct/heimdalldashboard.sh | 2 +- ct/homeassistant-core.sh | 2 +- ct/homeassistant.sh | 2 +- ct/homebridge.sh | 2 +- ct/homepage.sh | 2 +- ct/homer.sh | 2 +- ct/hyperion.sh | 2 +- ct/influxdb.sh | 2 +- ct/iobroker.sh | 2 +- ct/jackett.sh | 2 +- ct/jellyfin.sh | 2 +- ct/k0s.sh | 2 +- ct/kavita.sh | 2 +- ct/keycloak.sh | 2 +- ct/lidarr.sh | 2 +- ct/magicmirror.sh | 2 +- ct/mariadb.sh | 2 +- ct/meshcentral.sh | 2 +- ct/motioneye.sh | 2 +- ct/mqtt.sh | 2 +- ct/n8n.sh | 2 +- ct/navidrome.sh | 2 +- ct/nextcloudpi.sh | 2 +- ct/nginxproxymanager.sh | 2 +- ct/nocodb.sh | 2 +- ct/node-red.sh | 2 +- ct/omada.sh | 2 +- ct/omv.sh | 2 +- ct/openhab.sh | 2 +- ct/paperless-ngx.sh | 2 +- ct/photoprism.sh | 2 +- ct/pihole.sh | 2 +- ct/plex.sh | 2 +- ct/podman-homeassistant.sh | 2 +- ct/podman.sh | 2 +- ct/postgresql.sh | 2 +- ct/prometheus.sh | 2 +- ct/prowlarr.sh | 2 +- ct/qbittorrent.sh | 2 +- ct/radarr.sh | 2 +- ct/readarr.sh | 2 +- ct/rockylinux.sh | 2 +- ct/rstptoweb.sh | 2 +- ct/sabnzbd.sh | 2 +- ct/scrypted.sh | 2 +- ct/shinobi.sh | 2 +- ct/sonarr.sh | 2 +- ct/syncthing.sh | 2 +- ct/tdarr.sh | 2 +- ct/technitiumdns.sh | 2 +- ct/transmission.sh | 2 +- ct/trilium.sh | 2 +- ct/ubuntu.sh | 2 +- ct/unifi.sh | 2 +- ct/uptimekuma.sh | 2 +- ct/vaultwarden.sh | 2 +- ct/whisparr.sh | 2 +- ct/whoogle.sh | 2 +- ct/wikijs.sh | 2 +- ct/wireguard.sh | 2 +- ct/yunohost.sh | 2 +- ct/zigbee2mqtt.sh | 2 +- ct/zwave-js-ui.sh | 2 +- misc/{debian.func => build.func} | 43 ++++++++++++++++++++++++++------ 82 files changed, 117 insertions(+), 88 deletions(-) rename misc/{debian.func => build.func} (90%) diff --git a/ct/adguard.sh b/ct/adguard.sh index 682fc877..e8c65085 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 7e1de964..558dbc44 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 7571c138..3261b560 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/blocky.sh b/ct/blocky.sh index cfa21ed8..08e769e8 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 3f94891c..c8da20ae 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 85019ee5..da4f1550 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index 5b0a2ee6..d13e5b40 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/dashy.sh b/ct/dashy.sh index 63338364..5c76cf70 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/debian.sh b/ct/debian.sh index 3ece2f2a..b67a0a26 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/deconz.sh b/ct/deconz.sh index d43073f8..6195bd10 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/deluge.sh b/ct/deluge.sh index da8ce1eb..0b3ce6c4 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/devuan.sh b/ct/devuan.sh index 6c51b605..db48bf4e 100644 --- a/ct/devuan.sh +++ b/ct/devuan.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/emby.sh b/ct/emby.sh index dd296190..2e617cfb 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/emqx.sh b/ct/emqx.sh index 69afa53d..7c0ffcd9 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/esphome.sh b/ct/esphome.sh index 1c25bd4f..cd6e56d2 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index ebd1fade..58b82f5c 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/grafana.sh b/ct/grafana.sh index f908c465..3de34626 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/grocy.sh b/ct/grocy.sh index bf7a05b8..dd30c554 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 3a631eeb..aad87f46 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 68cbf783..261089a6 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 1bb58440..590a9bf6 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/homebridge.sh b/ct/homebridge.sh index ebc25192..22039d22 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/homepage.sh b/ct/homepage.sh index 90538100..e8041087 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/homer.sh b/ct/homer.sh index 13d2b64b..217b2800 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 64b0fa33..92535765 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 44b3eddb..f6c078cf 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 31b5a552..841f135e 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/jackett.sh b/ct/jackett.sh index ec991c7d..f895f4d7 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index c4bdef50..d11b8212 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/k0s.sh b/ct/k0s.sh index 710dd461..75b5648a 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/kavita.sh b/ct/kavita.sh index b80d4728..8410daa7 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 98ae1938..4488dd1a 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/lidarr.sh b/ct/lidarr.sh index c8cf9b26..6bc88997 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index 408e1107..c57121c2 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 04b0ba93..d6894ed9 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 7d544d0b..2739b517 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 6dc03205..4a106f03 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/mqtt.sh b/ct/mqtt.sh index d0ccf349..0dde1c0e 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/n8n.sh b/ct/n8n.sh index 944d0fe3..d4862ef1 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/navidrome.sh b/ct/navidrome.sh index 2aef956b..c9e53584 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index 6f887d8c..a1718208 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 215e8e24..99b95e30 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 50677ceb..4b7636f6 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/node-red.sh b/ct/node-red.sh index b625d323..3dba9183 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/omada.sh b/ct/omada.sh index 40eea690..104183df 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/omv.sh b/ct/omv.sh index f370db72..532df042 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/openhab.sh b/ct/openhab.sh index 6e3357a6..21a77dc7 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index dadc2f51..d2a9b9d1 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 1e789870..d40335e3 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/pihole.sh b/ct/pihole.sh index b5de9177..7efeb280 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/plex.sh b/ct/plex.sh index a944d8b6..17a8ecea 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index 14947e9d..0f0182e2 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/podman.sh b/ct/podman.sh index ef57de78..dd25f057 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 1275649a..754ced8b 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/prometheus.sh b/ct/prometheus.sh index c1514477..4bc71930 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index a61d6144..b0dffde3 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index d5e20ddf..83cc8526 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/radarr.sh b/ct/radarr.sh index 0664fc5d..9ddd1b45 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/readarr.sh b/ct/readarr.sh index 3ac5ee57..deca401d 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index eb955c9d..d9c97165 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/rstptoweb.sh b/ct/rstptoweb.sh index b3e9dfb5..1c1bb453 100644 --- a/ct/rstptoweb.sh +++ b/ct/rstptoweb.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index 2f1a8c1b..195e7955 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/scrypted.sh b/ct/scrypted.sh index c10a33be..45de42d4 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/shinobi.sh b/ct/shinobi.sh index 23020d04..dd27cd59 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/sonarr.sh b/ct/sonarr.sh index e8152274..c6bceefa 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/syncthing.sh b/ct/syncthing.sh index e26dbd56..d7bf2724 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/tdarr.sh b/ct/tdarr.sh index ba2f9149..cb1e415a 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index fbe2c925..7233ca55 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/transmission.sh b/ct/transmission.sh index 86d45292..8b4c06a0 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/trilium.sh b/ct/trilium.sh index dd2b2578..4ed13fca 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 9fce57ed..81501e20 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ubuntu.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/unifi.sh b/ct/unifi.sh index c5993242..19cb57e2 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 86644bf9..467f927c 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 3a9aed9a..28d7150c 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/whisparr.sh b/ct/whisparr.sh index 7c3adbe4..4ae3b249 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/whoogle.sh b/ct/whoogle.sh index e1bf927c..488babeb 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/wikijs.sh b/ct/wikijs.sh index 377eeba0..96a2e4dd 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/wireguard.sh b/ct/wireguard.sh index cfd017be..02bef523 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 931ad446..1d202995 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 2030a5dd..243b7d7b 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 7dc9ec31..bfecfad7 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/debian.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/misc/debian.func b/misc/build.func similarity index 90% rename from misc/debian.func rename to misc/build.func index 38a2d271..3f594990 100644 --- a/misc/debian.func +++ b/misc/build.func @@ -67,6 +67,9 @@ arch_check() { } echo_default() { + if [ "$var_os" == "ubuntu" ]; then + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + fi echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -95,6 +98,19 @@ exit-script() { } advanced_settings() { + if [ "$var_os" == "ubuntu" ]; then + if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ + "18.04" "Bionic" OFF \ + "20.04" "Focal" ON \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" + else + exit-script + fi + fi + if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ @@ -346,7 +362,7 @@ build_container() { fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/dev/misc/install.func)" export tz="$timezone" export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" @@ -368,11 +384,12 @@ build_container() { -unprivileged $CT_TYPE $PW " - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf if [ "$CT_TYPE" == "0" ]; then - cat <>$LXC_CONFIG + if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" ]]; then + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm @@ -383,16 +400,28 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF - else - cat <>$LXC_CONFIG + fi + fi + + if [ "$CT_TYPE" == "0" ]; then + if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" ]]; then + cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF + fi fi + msg_info "Starting LXC Container" pct start "$CTID" msg_ok "Started LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit + lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/install/$var_install.sh)" || exit } @@ -401,4 +430,4 @@ description() { pct set "$CTID" -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " -} +} \ No newline at end of file From 36f610127b679ae8ecdb6aec2fb4ed60650b4e3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 00:17:04 -0400 Subject: [PATCH 4500/6505] Delete ubuntu.func --- misc/ubuntu.func | 428 ----------------------------------------------- 1 file changed, 428 deletions(-) delete mode 100644 misc/ubuntu.func diff --git a/misc/ubuntu.func b/misc/ubuntu.func deleted file mode 100644 index 04695499..00000000 --- a/misc/ubuntu.func +++ /dev/null @@ -1,428 +0,0 @@ -variables() { - NSAPP=$(echo ${APP,,} | tr -d ' ') - var_install="${NSAPP}-install" - timezone=$(cat /etc/timezone) - INTEGER='^[0-9]+([.][0-9]+)?$' -} - -color() { - YW=$(echo "\033[33m") - BL=$(echo "\033[36m") - RD=$(echo "\033[01;31m") - BGN=$(echo "\033[4;92m") - GN=$(echo "\033[1;92m") - DGN=$(echo "\033[32m") - CL=$(echo "\033[m") - CM="${GN}✓${CL}" - CROSS="${RD}✗${CL}" - BFR="\\r\\033[K" - HOLD="-" -} - -catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -pve_check() { - if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -echo_default() { - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -advanced_settings() { - if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" - else - exit-script - fi - - if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - else - exit-script - fi - - if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - exit-script - fi - - if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else - exit - fi - - if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - exit-script - fi - - if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi - else - exit-script - fi - - if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi - else - exit-script - fi - - if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi - else - exit-script - fi - - if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi - else - exit-script - fi - - if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi - else - exit-script - fi - - if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - exit-script - fi - - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" - else - DISABLEIP6="no" - fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - - if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - else - exit-script - fi - - if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - else - exit-script - fi - - if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - else - exit-script - fi - - if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - else - exit-script - fi - - if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - exit-script - fi - - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" - else - SSH="no" - fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" - else - VERB="no" - fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -install_script() { - arch_check - pve_check - NEXTID=$(pvesh get /cluster/nextid) - header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -start() { - if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script - fi - - if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script - fi -} - -build_container() { - if [ "$VERB" == "yes" ]; then set -x; fi - if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - TEMP_DIR=$(mktemp -d) - pushd $TEMP_DIR >/dev/null - export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" - export tz="$timezone" - export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export VERBOSE="$VERB" - export SSH_ROOT="${SSH}" - export CTID="$CT_ID" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW - " - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" ]]; then - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF - fi - fi - - if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" ]]; then - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 226:0 rwm -lxc.cgroup2.devices.allow: c 226:128 rwm -lxc.cgroup2.devices.allow: c 29:0 rwm -lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file -lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir -lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file -EOF - fi - fi - - msg_info "Starting LXC Container" - pct start "$CTID" - msg_ok "Started LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit - -} - -description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "# ${APP} LXC - ### https://tteck.github.io/Proxmox/ - " -} From d3b7ccc33324d57b98034b17e80f87fecebdb6a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 00:28:47 -0400 Subject: [PATCH 4501/6505] Update pull_request_template.md --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ad7ef3fc..4bf88433 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ -# All Pull Requests should be made to the `pull-requests` branch +## I wanted to make you aware that I am meticulous when it comes to merging code into the main branch, so please don't take it personally if I reject your request. ## Description From 3d6eea583187a4c9c2ccb095c2b12df4360252cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 04:22:01 -0400 Subject: [PATCH 4502/6505] indent --- misc/build.func | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/build.func b/misc/build.func index 3f594990..b5516b47 100644 --- a/misc/build.func +++ b/misc/build.func @@ -68,7 +68,7 @@ arch_check() { echo_default() { if [ "$var_os" == "ubuntu" ]; then - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" + echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" fi echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" @@ -106,8 +106,8 @@ advanced_settings() { "22.10" "Kinetic" OFF \ 3>&1 1>&2 2>&3); then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" - else - exit-script + else + exit-script fi fi @@ -385,7 +385,7 @@ build_container() { $PW " bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/ct/create_lxc.sh)" || exit - + LXC_CONFIG=/etc/pve/lxc/${CTID}.conf if [ "$CT_TYPE" == "0" ]; then if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" ]]; then @@ -430,4 +430,4 @@ description() { pct set "$CTID" -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " -} \ No newline at end of file +} From ddc8c69e952e531fe55de628d671484b752c626f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 04:41:35 -0400 Subject: [PATCH 4503/6505] Update build.func fix --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index b5516b47..75bb5243 100644 --- a/misc/build.func +++ b/misc/build.func @@ -421,7 +421,7 @@ EOF msg_info "Starting LXC Container" pct start "$CTID" msg_ok "Started LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/install/$var_install.sh)" || exit + lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit } From 98e88174ce5bbb24b7088ac93c28331357121d6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 04:50:06 -0400 Subject: [PATCH 4504/6505] Update build.func --- misc/build.func | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index 75bb5243..977d4706 100644 --- a/misc/build.func +++ b/misc/build.func @@ -362,7 +362,7 @@ build_container() { fi TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/dev/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" export tz="$timezone" export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" @@ -384,7 +384,7 @@ build_container() { -unprivileged $CT_TYPE $PW " - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/ct/create_lxc.sh)" || exit + bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf if [ "$CT_TYPE" == "0" ]; then From 8cdff0aca5009f62bce7e5cb7c68baa4d5d3679e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 05:14:02 -0400 Subject: [PATCH 4505/6505] fix core update --- ct/homeassistant-core.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 261089a6..a8429ed7 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -68,12 +68,12 @@ function update_script() { if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then clear header_info - echo -e "${GN}Updating to Version ${BETA}${CL}" + echo -e "${GN}Updating to Beta Version${CL}" BR="--pre " else clear header_info - echo -e "${GN}Updating to Version ${STABLE}${CL}" + echo -e "${GN}Updating to Srable Version${CL}" BR="" fi if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi @@ -125,7 +125,7 @@ ExecStart=/usr/local/bin/filebrowser -r /root/.homeassistant [Install] WantedBy=default.target" >$service_path - systemctl enable --now filebrowser.service &>/dev/null + systemctl enable --now -q filebrowser.service msg_ok "Created Service" msg_ok "Completed Successfully!\n" From dab04f23a307f426995feb699f233d79d1a0a320 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:20:36 +0100 Subject: [PATCH 4506/6505] Consistency to all other Alpine Menus (#1230) that was the only script with the "Exit-Script" for the Alpine ones. Now it is consistent --- ct/alpine-grafana.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 4dd13bda..c1811d10 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -55,7 +55,7 @@ function update_script() { LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" --cancel-button Exit-Script 11 58 3 \ + whiptail --title "SUPPORT" --menu "Select option" 11 58 3 \ "1" "Check for Grafana Updates" \ "2" "Allow 0.0.0.0 for listening" \ "3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3 From 8500e495b00117651449896f6289fc8aec8c4b21 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 07:07:49 -0400 Subject: [PATCH 4507/6505] add Docker LXCs to build.func & tweaks --- ct/casaos.sh | 2 +- ct/docker.sh | 2 +- ct/homeassistant.sh | 1 + ct/paperless-ngx.sh | 1 - ct/photoprism.sh | 1 - ct/pihole.sh | 1 - ct/plex.sh | 1 - ct/podman-homeassistant.sh | 1 - ct/podman.sh | 1 - ct/postgresql.sh | 1 - ct/prometheus.sh | 1 - ct/prowlarr.sh | 1 - ct/radarr.sh | 1 - ct/readarr.sh | 1 - ct/rockylinux.sh | 1 - ct/sabnzbd.sh | 1 - ct/scrypted.sh | 1 - ct/shinobi.sh | 1 - ct/sonarr.sh | 1 - ct/syncthing.sh | 1 - ct/tdarr.sh | 1 - ct/technitiumdns.sh | 1 - ct/transmission.sh | 1 - ct/trilium.sh | 1 - ct/ubuntu.sh | 1 - ct/umbrel.sh | 3 +-- ct/unifi.sh | 1 - ct/uptimekuma.sh | 1 - ct/vaultwarden.sh | 1 - ct/whisparr.sh | 1 - ct/whoogle.sh | 1 - ct/wikijs.sh | 1 - ct/wireguard.sh | 1 - ct/yunohost.sh | 1 - ct/zigbee2mqtt.sh | 1 - ct/zwave-js-ui.sh | 1 - misc/build.func | 34 ++++++++++++++++++++++++++++++---- 37 files changed, 34 insertions(+), 40 deletions(-) diff --git a/ct/casaos.sh b/ct/casaos.sh index e7bcf8e2..c98a025d 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/docker.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/docker.sh b/ct/docker.sh index 37ca3808..1805787c 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/docker.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 590a9bf6..ac667247 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -46,6 +46,7 @@ function default_settings() { MAC="" VLAN="" SSH="no" + FUSE="no" VERB="no" echo_default } diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index d2a9b9d1..09d46d45 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ / __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __ / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/ diff --git a/ct/photoprism.sh b/ct/photoprism.sh index d40335e3..231f7d1e 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ ______ __________ ____ ____ _________ __ ___ / __ \/ / / / __ \/_ __/ __ \/ __ \/ __ \/ _/ ___// |/ / / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \__ \/ /|_/ / diff --git a/ct/pihole.sh b/ct/pihole.sh index 7efeb280..07e786ea 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ ____ __ ______ __ ______ / __ \/ _/ / / / / __ \/ / / ____/ / /_/ // /___/ /_/ / / / / / / __/ diff --git a/ct/plex.sh b/ct/plex.sh index 17a8ecea..48d12505 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ __ ___ ___ _____ / __ \/ /__ _ __ / |/ /__ ____/ (_)___ _ / ___/___ ______ _____ _____ / /_/ / / _ \| |/_/ / /|_/ / _ \/ __ / / __ `/ \__ \/ _ \/ ___/ | / / _ \/ ___/ diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index 0f0182e2..be35917e 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ / __ \____ ____/ /___ ___ ____ _____ / /_/ / __ \/ __ / __ __ \/ __ / __ \ diff --git a/ct/podman.sh b/ct/podman.sh index dd25f057..b4297c51 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ / __ \____ ____/ /___ ___ ____ _____ / /_/ / __ \/ __ / __ `__ \/ __ `/ __ \ diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 754ced8b..f0b606a1 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ _____ ____ __ / __ \____ _____/ /_____ _________ / ___// __ \ / / / /_/ / __ \/ ___/ __/ __ / ___/ _ \\__ \/ / / / / / diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 4bc71930..16f17758 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ __ / __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ / /_/ / ___/ __ \/ __ __ \/ _ \/ __/ __ \/ _ \/ / / / ___/ diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index b0dffde3..2c323541 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ / __ \_________ _ __/ /___ __________ / /_/ / ___/ __ \ | /| / / / __ `/ ___/ ___/ diff --git a/ct/radarr.sh b/ct/radarr.sh index 9ddd1b45..a379e8ac 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ / __ \____ _____/ /___ __________ / /_/ / __ `/ __ / __ `/ ___/ ___/ diff --git a/ct/readarr.sh b/ct/readarr.sh index deca401d..bea527d0 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ / __ \___ ____ _____/ /___ __________ / /_/ / _ \/ __ `/ __ / __ `/ ___/ ___/ diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index d9c97165..edc69291 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ __ __ _ / __ \____ _____/ /____ __ / / (_)___ __ ___ __ / /_/ / __ \/ ___/ //_/ / / / / / / / __ \/ / / / |/_/ diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index 195e7955..ea75032d 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ ___ ____ __ __ / ___// | / __ )____ ____ / /_ ____/ / \__ \/ /| | / __ / __ \/_ / / __ \/ __ / diff --git a/ct/scrypted.sh b/ct/scrypted.sh index 45de42d4..d307d78c 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ __ __ / ___/____________ ______ / /____ ____/ / \__ \/ ___/ ___/ / / / __ \/ __/ _ \/ __ / diff --git a/ct/shinobi.sh b/ct/shinobi.sh index dd27cd59..bc5572e6 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ __ _ __ _ / ___// /_ (_)___ ____ / /_ (_) \__ \/ __ \/ / __ \/ __ \/ __ \/ / diff --git a/ct/sonarr.sh b/ct/sonarr.sh index c6bceefa..ac6f2399 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ / ___/____ ____ ____ __________ \__ \/ __ \/ __ \/ __ `/ ___/ ___/ diff --git a/ct/syncthing.sh b/ct/syncthing.sh index d7bf2724..292cf4db 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ __ __ _ / ___/__ ______ _____/ /_/ /_ (_)___ ____ _ \__ \/ / / / __ \/ ___/ __/ __ \/ / __ \/ __ `/ diff --git a/ct/tdarr.sh b/ct/tdarr.sh index cb1e415a..994ae3db 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ __ /_ __/___/ /___ __________ / / / __ / __ `/ ___/ ___/ diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index 7233ca55..f947cd07 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ __ _ __ _ ____ _ _______ /_ __/__ _____/ /_ ____ (_) /_(_)_ ______ ___ / __ \/ | / / ___/ / / / _ \/ ___/ __ \/ __ \/ / __/ / / / / __ __ \ / / / / |/ /\__ \ diff --git a/ct/transmission.sh b/ct/transmission.sh index 8b4c06a0..94e654d6 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ _ _ /_ __/________ _____ _________ ___ (_)_________(_)___ ____ / / / ___/ __ `/ __ \/ ___/ __ `__ \/ / ___/ ___/ / __ \/ __ \ diff --git a/ct/trilium.sh b/ct/trilium.sh index 4ed13fca..3e15c458 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ _ ___ /_ __/____(_) (_)_ ______ ___ / / / ___/ / / / / / / __ `__ \ diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 81501e20..bc2f0cc6 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - __ ____ __ / / / / /_ __ ______ / /___ __ / / / / __ \/ / / / __ \/ __/ / / / diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 796693ce..46ed1aa2 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/docker.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/docke function header_info { clear cat <<"EOF" - __ __ __ __ / / / /___ ___ / /_ ________ / / / / / / __ `__ \/ __ \/ ___/ _ \/ / diff --git a/ct/unifi.sh b/ct/unifi.sh index 19cb57e2..542f1f87 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - __ __ _ _____ / / / /__ (_) __(_) / / / / __ \/ / /_/ / diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 467f927c..4f64ecc3 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - __ __ __ _ __ __ / / / /___ / /_(_)___ ___ ___ / //_/_ ______ ___ ____ _ / / / / __ \/ __/ / __ __ \/ _ \ / ,< / / / / __ __ \/ __ / diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 28d7150c..8f887956 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _ __ ____ _ __ __ | | / /___ ___ __/ / /| | / /___ __________/ /__ ____ | | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __ / _ \/ __ \ diff --git a/ct/whisparr.sh b/ct/whisparr.sh index 4ae3b249..c616282a 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _ ____ _ | | / / /_ (_)________ ____ __________ | | /| / / __ \/ / ___/ __ \/ __ `/ ___/ ___/ diff --git a/ct/whoogle.sh b/ct/whoogle.sh index 488babeb..e93b19d7 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _ ____ ______ ____ ________ ______ | | / / / / / __ \/ __ \/ ____/ / / ____/ | | /| / / /_/ / / / / / / / / __/ / / __/ diff --git a/ct/wikijs.sh b/ct/wikijs.sh index 96a2e4dd..e1ac9863 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _ ___ __ _ _ | | / (_) /__(_) (_)____ | | /| / / / //_/ / / / ___/ diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 02bef523..553de4e5 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _ ___ ______ __ | | / (_)_______ / ____/_ ______ __________/ / | | /| / / / ___/ _ \/ / __/ / / / __ `/ ___/ __ / diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 1d202995..22198999 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - __ __ __ __ __ \ \/ /_ ______ ____ / / / /___ _____/ /_ \ / / / / __ \/ __ \/ /_/ / __ \/ ___/ __/ diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 243b7d7b..c1c59ff0 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ _ __ ___ __ _______ ____________ /__ / (_)___ _/ /_ ___ ___ |__ \ / |/ / __ \/_ __/_ __/ / / / / __ / __ \/ _ \/ _ \__/ // /|_/ / / / / / / / / diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index bfecfad7..ed8c0d64 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -8,7 +8,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ _______ __ ______ /__ /_ ______ __ _____ / / ___/ / / / / _/ / /| | /| / / __ `/ | / / _ \ __ / /\__ \ / / / // / diff --git a/misc/build.func b/misc/build.func index 977d4706..24336f62 100644 --- a/misc/build.func +++ b/misc/build.func @@ -87,6 +87,9 @@ echo_default() { echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" + fi echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } @@ -300,6 +303,15 @@ advanced_settings() { fi echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + FUSE="yes" + else + FUSE="no" + fi + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then VERB="yes" else @@ -355,15 +367,29 @@ start() { build_container() { if [ "$VERB" == "yes" ]; then set -x; fi - if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" + + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + if [ "$FUSE" == "yes" ]; then + FEATURES="fuse=1,keyctl=1,nesting=1" + else + FEATURES="keyctl=1,nesting=1" + fi fi + if [[ "$APP" != "Docker" && "$APP" != "Umbrel" && "$APP" != "CasaOS" && "$APP" != "Home Assistant"]]; then + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" + fi + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" export tz="$timezone" + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + export ST="$FUSE" + fi export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" export VERBOSE="$VERB" From 3d6b65895a30050d7b42880c16d9a259865238ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 07:18:14 -0400 Subject: [PATCH 4508/6505] Update build.func revert --- misc/build.func | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/misc/build.func b/misc/build.func index 24336f62..977d4706 100644 --- a/misc/build.func +++ b/misc/build.func @@ -87,9 +87,6 @@ echo_default() { echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - fi echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } @@ -303,15 +300,6 @@ advanced_settings() { fi echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - FUSE="yes" - else - FUSE="no" - fi - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" - fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then VERB="yes" else @@ -367,29 +355,15 @@ start() { build_container() { if [ "$VERB" == "yes" ]; then set -x; fi - - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - if [ "$FUSE" == "yes" ]; then - FEATURES="fuse=1,keyctl=1,nesting=1" - else - FEATURES="keyctl=1,nesting=1" - fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="nesting=1,keyctl=1" + else + FEATURES="nesting=1" fi - if [[ "$APP" != "Docker" && "$APP" != "Umbrel" && "$APP" != "CasaOS" && "$APP" != "Home Assistant"]]; then - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi - fi - TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" export tz="$timezone" - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - export ST="$FUSE" - fi export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" export VERBOSE="$VERB" From 3d6e1a27707b92c1ee61de4bd3d675ded08cd577 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 07:33:03 -0400 Subject: [PATCH 4509/6505] Update build.func update --- misc/build.func | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index 977d4706..79e87246 100644 --- a/misc/build.func +++ b/misc/build.func @@ -87,6 +87,9 @@ echo_default() { echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" + fi echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } @@ -300,6 +303,15 @@ advanced_settings() { fi echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + FUSE="yes" + else + FUSE="no" + fi + echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" + fi + if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then VERB="yes" else @@ -355,15 +367,29 @@ start() { build_container() { if [ "$VERB" == "yes" ]; then set -x; fi - if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" + + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + if [ "$FUSE" == "yes" ]; then + FEATURES="fuse=1,keyctl=1,nesting=1" + else + FEATURES="keyctl=1,nesting=1" + fi fi + if [[ "$APP" != "Docker" && "$APP" != "Umbrel" && "$APP" != "CasaOS" && "$APP" != "Home Assistant" ]]; then + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" + fi + fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" export tz="$timezone" + if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then + export ST="$FUSE" + fi export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" export VERBOSE="$VERB" From ac82a25d4c4951283b5027f5c87abd88a15bab99 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 10:19:26 -0400 Subject: [PATCH 4510/6505] fix update --- ct/alpine-docker.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 21bd2144..8545582a 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -51,6 +51,7 @@ function default_settings() { echo_default } +function update_script() { while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ @@ -69,6 +70,7 @@ while true; do ;; esac done +} start build_container From bb30640180d222365346ea7086c022b353fcab35 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 10:35:48 -0400 Subject: [PATCH 4511/6505] Update alpine-docker.sh indent update --- ct/alpine-docker.sh | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 8545582a..c01b79e0 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -52,24 +52,24 @@ function default_settings() { } function update_script() { -while true; do - CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ - "1" "Check for Docker Updates" 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - clear - exit-script - fi - header_info - case $CHOICE in - 1) - apk update && apk upgrade - exit - ;; - esac -done + while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ + "1" "Check for Docker Updates" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + apk update && apk upgrade + exit + ;; + esac + done } start From b4ced6ced633dd4b69cdc0b683bf5031a9d9d016 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 11:03:53 -0400 Subject: [PATCH 4512/6505] Delete docker.func --- misc/docker.func | 409 ----------------------------------------------- 1 file changed, 409 deletions(-) delete mode 100644 misc/docker.func diff --git a/misc/docker.func b/misc/docker.func deleted file mode 100644 index 702f598e..00000000 --- a/misc/docker.func +++ /dev/null @@ -1,409 +0,0 @@ -variables() { - NSAPP=$(echo ${APP,,} | tr -d ' ') - var_install="${NSAPP}-install" - timezone=$(cat /etc/timezone) - INTEGER='^[0-9]+([.][0-9]+)?$' -} - -color() { - YW=$(echo "\033[33m") - BL=$(echo "\033[36m") - RD=$(echo "\033[01;31m") - BGN=$(echo "\033[4;92m") - GN=$(echo "\033[1;92m") - DGN=$(echo "\033[32m") - CL=$(echo "\033[m") - CM="${GN}✓${CL}" - CROSS="${RD}✗${CL}" - BFR="\\r\\033[K" - HOLD="-" -} - -catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -pve_check() { - if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -echo_default() { - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -advanced_settings() { - if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - else - exit-script - fi - - if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - exit-script - fi - - if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else - exit - fi - - if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - exit-script - fi - - if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi - else - exit-script - fi - - if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi - else - exit-script - fi - - if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi - else - exit-script - fi - - if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi - else - exit-script - fi - - if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi - else - exit-script - fi - - if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - exit-script - fi - - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" - else - DISABLEIP6="no" - fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - - if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - else - exit-script - fi - - if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - else - exit-script - fi - - if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - else - exit-script - fi - - if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - else - exit-script - fi - - if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - exit-script - fi - - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" - else - SSH="no" - fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - FUSE="yes" - else - FUSE="no" - fi - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" - - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" - else - VERB="no" - fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -install_script() { - arch_check - pve_check - NEXTID=$(pvesh get /cluster/nextid) - header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -start() { - if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script - fi - - if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script - fi -} - -build_container() { - if [ "$VERB" == "yes" ]; then set -x; fi - if [ "$FUSE" == "yes" ]; then - FEATURES="fuse=1,keyctl=1,nesting=1" - else - FEATURES="keyctl=1,nesting=1" - fi - TEMP_DIR=$(mktemp -d) - pushd $TEMP_DIR >/dev/null - export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" - export tz="$timezone" - export ST="$FUSE" - export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export VERBOSE="$VERB" - export SSH_ROOT="${SSH}" - export CTID="$CT_ID" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW - " - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -EOF - if [ "$CT_TYPE" == "0" ]; then - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF - fi - msg_info "Starting LXC Container" - pct start "$CTID" - msg_ok "Started LXC Container" - lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit - -} - -description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "# ${APP} LXC - ### https://tteck.github.io/Proxmox/ - " -} From 190cdf58589aae71dc8b299c88789d2033450eed Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 12:31:19 -0400 Subject: [PATCH 4513/6505] Update build.func move variable --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 79e87246..a4e63753 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1,7 +1,6 @@ variables() { NSAPP=$(echo ${APP,,} | tr -d ' ') var_install="${NSAPP}-install" - timezone=$(cat /etc/timezone) INTEGER='^[0-9]+([.][0-9]+)?$' } @@ -333,6 +332,7 @@ install_script() { arch_check pve_check NEXTID=$(pvesh get /cluster/nextid) + timezone=$(cat /etc/timezone) header_info if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info From 2c6c2a7dfe08cb8e887dd2f43bdc1df78cb62172 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 12:32:10 -0400 Subject: [PATCH 4514/6505] Update alpine-adguard.sh use build.func --- ct/alpine-adguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 4604fbcb..39e27995 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT From 21a842eacd92247f32d16488e46229a8f31996dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 12:41:01 -0400 Subject: [PATCH 4515/6505] add alpine to build.func --- misc/build.func | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/build.func b/misc/build.func index a4e63753..02631526 100644 --- a/misc/build.func +++ b/misc/build.func @@ -447,6 +447,9 @@ EOF msg_info "Starting LXC Container" pct start "$CTID" msg_ok "Started LXC Container" + if [ "$var_os" == "alpine" ]; then + pct exec "$CTID" -- ash -c "apk add bash >/dev/null" + fi lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit } From 3c74788eb5211efad50556d2d918c3e6487529fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 12:51:53 -0400 Subject: [PATCH 4516/6505] set alpine FUNCTIONS_FILE_PATH in build.func --- misc/build.func | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/misc/build.func b/misc/build.func index 02631526..88375fa3 100644 --- a/misc/build.func +++ b/misc/build.func @@ -385,7 +385,11 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null + if [ "$var_os" == "alpine" ]; then + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)" + else export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" + fi export tz="$timezone" if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then export ST="$FUSE" From 8e3731de0cca69e428a5acce23d3385ff9202483 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 12:56:13 -0400 Subject: [PATCH 4517/6505] use build.func --- ct/alpine-vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 0f6c9930..d51d7ad9 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT From a73ae028184ea249c04943b93a3bd24cdc77d94d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 13:02:16 -0400 Subject: [PATCH 4518/6505] switch alpine to build.func --- ct/alpine-docker.sh | 2 +- ct/alpine-grafana.sh | 2 +- ct/alpine-zigbee2mqtt.sh | 2 +- ct/alpine.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index c01b79e0..9d8ee785 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index c1811d10..ea7fd804 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 28bcaf3b..cd44e350 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT diff --git a/ct/alpine.sh b/ct/alpine.sh index 19074a97..a3348a9f 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT From b5ac68a22b25498180bcfe1441585bc3a1416044 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 13:38:15 -0400 Subject: [PATCH 4519/6505] Delete alpine.func --- misc/alpine.func | 400 ----------------------------------------------- 1 file changed, 400 deletions(-) delete mode 100644 misc/alpine.func diff --git a/misc/alpine.func b/misc/alpine.func deleted file mode 100644 index 5e58cfd9..00000000 --- a/misc/alpine.func +++ /dev/null @@ -1,400 +0,0 @@ -variables() { - NSAPP=$(echo ${APP,,} | tr -d ' ') - var_install="${NSAPP}-install" - INTEGER='^[0-9]+([.][0-9]+)?$' -} - -color() { - YW=$(echo "\033[33m") - BL=$(echo "\033[36m") - RD=$(echo "\033[01;31m") - BGN=$(echo "\033[4;92m") - GN=$(echo "\033[1;92m") - DGN=$(echo "\033[32m") - CL=$(echo "\033[m") - CM="${GN}✓${CL}" - CROSS="${RD}✗${CL}" - BFR="\\r\\033[K" - HOLD="-" -} - -catch_errors() { - set -Eeuo pipefail - trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -} - -error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -pve_check() { - if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -echo_default() { - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - echo -e "${DGN}Using Root Password: ${BGN}alpine${CL}" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -advanced_settings() { - if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - else - exit-script - fi - - if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - exit-script - fi - - if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi - else - exit - fi - - if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - exit-script - fi - - if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi - else - exit-script - fi - - if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi - else - exit-script - fi - - if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi - else - exit-script - fi - - if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi - else - exit-script - fi - - if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi - else - exit-script - fi - - if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - exit-script - fi - - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" - else - DISABLEIP6="no" - fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - - if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - else - exit-script - fi - - if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" - else - exit-script - fi - - if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" - else - exit-script - fi - - if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - else - exit-script - fi - - if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - exit-script - fi - - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" - else - SSH="no" - fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" - else - VERB="no" - fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" - else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -install_script() { - arch_check - pve_check - timezone=$(cat /etc/timezone) - NEXTID=$(pvesh get /cluster/nextid) - header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -start() { - if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script - fi - - if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - set +e - update_script - fi -} - -build_container() { - if [ "$VERB" == "yes" ]; then set -x; fi - if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" - else - FEATURES="nesting=1" - fi - TEMP_DIR=$(mktemp -d) - pushd $TEMP_DIR >/dev/null - export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)" - export tz="$timezone" - export DISABLEIPV6="$DISABLEIP6" - export APPLICATION="$APP" - export VERBOSE="$VERB" - export SSH_ROOT="${SSH}" - export CTID="$CT_ID" - export PCT_OSTYPE="$var_os" - export PCT_OSVERSION="$var_version" - export PCT_DISK_SIZE="$DISK_SIZE" - export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW - " - bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit - if [ "$CT_TYPE" == "0" ]; then - LXC_CONFIG=/etc/pve/lxc/${CTID}.conf - cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: -lxc.cgroup2.devices.allow: c 188:* rwm -lxc.cgroup2.devices.allow: c 189:* rwm -lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir -lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file -lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file -EOF - fi - msg_info "Starting LXC Container" - pct start "$CTID" - msg_ok "Started LXC Container" - pct exec "$CTID" -- ash -c "apk add bash >/dev/null" - lxc-attach -n "$CTID" -- bash -c "$(wget -qO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit - -} - -description() { - IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "# ${APP} LXC - ### https://tteck.github.io/Proxmox/ - " -} From 46ba32c586416f0616754308b7056b71bb988994 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 14:12:48 -0400 Subject: [PATCH 4520/6505] Rename haos-vm-v5.sh to haos-vm.sh --- vm/{haos-vm-v5.sh => haos-vm.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename vm/{haos-vm-v5.sh => haos-vm.sh} (100%) diff --git a/vm/haos-vm-v5.sh b/vm/haos-vm.sh similarity index 100% rename from vm/haos-vm-v5.sh rename to vm/haos-vm.sh From 7987b8697eca156c1cf64abb17fc20ca70b7f806 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 17:08:07 -0400 Subject: [PATCH 4521/6505] Update cronicle.sh remove unexpected token --- ct/cronicle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index da4f1550..9621c991 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -62,7 +62,7 @@ msg_info "Updating ${APP}" /opt/cronicle/bin/control.sh upgrade &>/dev/null msg_ok "Updated ${APP}" exit -fi + if [ "$UPD" == "2" ]; then LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) IP=$(hostname -I | awk '{print $1}') From adf460d5447b809ccddbaf787a13af034b5f6b5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 17:13:37 -0400 Subject: [PATCH 4522/6505] Update cronicle.sh --- ct/cronicle.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 9621c991..53702989 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -57,12 +57,13 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb "2" "Install ${APP} Worker" OFF \ 3>&1 1>&2 2>&3) +if [ "$UPD" == "1" ]; then header_info msg_info "Updating ${APP}" /opt/cronicle/bin/control.sh upgrade &>/dev/null msg_ok "Updated ${APP}" exit - +fi if [ "$UPD" == "2" ]; then LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) IP=$(hostname -I | awk '{print $1}') From 3abd2a9698a7cb3eb9d183d0eab1aed250bf9252 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Mar 2023 18:18:53 -0400 Subject: [PATCH 4523/6505] Update omv-install.sh fix unattended install --- install/omv-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/omv-install.sh b/install/omv-install.sh index fbc2f03b..be058e99 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -36,8 +36,8 @@ deb https://packages.openmediavault.org/public shaitan main # deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner EOF $STD apt-get update -$STD apt-get -y install openmediavault-keyring -$STD apt-get --yes --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends install openmediavault +apt-get -y install openmediavault-keyring &>/dev/null +DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy openmediavault &>/dev/null omv-confdbadm populate msg_ok "Installed OpenMediaVault" From a8675fea6dbf0904d8b883ee95f37a31dcaeb64c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 05:40:31 -0400 Subject: [PATCH 4524/6505] Update sonarr-install.sh fix unattended install --- install/sonarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index 52961b31..db1a7bf4 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -25,7 +25,7 @@ msg_info "Installing Sonarr" $STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 sh -c 'echo "deb https://apt.sonarr.tv/debian buster-develop main" > /etc/apt/sources.list.d/sonarr.list' $STD apt-get update -$STD apt-get -o Dpkg::Options::="--force-confold" install -y sonarr +DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy sonarr &>/dev/null msg_ok "Installed Sonarr" motd_ssh From 851b8458e37be3451603430462ea230ff1a5e1d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 08:07:49 -0400 Subject: [PATCH 4525/6505] Update alpine-vaultwarden.sh tweak --- ct/alpine-vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index d51d7ad9..937e7ac7 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -55,7 +55,7 @@ function update_script() { while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ - "1" "Update VaultWarden" \ + "1" "Update Vaultwarden" \ "2" "Show Admin Token" 3>&2 2>&1 1>&3 ) exit_status=$? From 2b5ff5bb0ed9e238e17dd292f285f1ebada6056b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:23:11 -0400 Subject: [PATCH 4526/6505] Update alpine-adguard.sh add `newt` check --- ct/alpine-adguard.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 39e27995..7b2b79cb 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -52,6 +52,9 @@ function default_settings() { } function update_script() { + if ! apk -e info newt >/dev/null 2>&1; then + apk add newt + fi while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ From 2facedfe71d1ac4655a2f4019f6675d578339a3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:23:58 -0400 Subject: [PATCH 4527/6505] Update alpine-docker.sh add `newt` check --- ct/alpine-docker.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 9d8ee785..ad195e50 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -52,6 +52,9 @@ function default_settings() { } function update_script() { + if ! apk -e info newt >/dev/null 2>&1; then + apk add newt + fi while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ From 0e49af62dff4eb881077e5eea8bc71f6f89a01ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:24:30 -0400 Subject: [PATCH 4528/6505] Update alpine-grafana.sh add `newt` check --- ct/alpine-grafana.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index ea7fd804..170845b7 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -52,6 +52,9 @@ function default_settings() { } function update_script() { + if ! apk -e info newt >/dev/null 2>&1; then + apk add newt + fi LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do CHOICE=$( From b1abfa9ac6d76b741377fbe7ecbdd093eb0c11dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:26:04 -0400 Subject: [PATCH 4529/6505] Update alpine-vaultwarden.sh add `newt` check --- ct/alpine-vaultwarden.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 937e7ac7..0eddef93 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -52,6 +52,9 @@ function default_settings() { } function update_script() { + if ! apk -e info newt >/dev/null 2>&1; then + apk add -q newt + fi while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ From b10106aa2a8428d9a4a3a271efcfbe2ccc02982b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:27:20 -0400 Subject: [PATCH 4530/6505] Update alpine-zigbee2mqtt.sh add `newt` check --- ct/alpine-zigbee2mqtt.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index cd44e350..51ec6030 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -52,6 +52,9 @@ function default_settings() { } function update_script() { + if ! apk -e info newt >/dev/null 2>&1; then + apk add -q newt + fi while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ From d9445a3d642930c9a3ba1d9fd5561468d7d0864c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:27:57 -0400 Subject: [PATCH 4531/6505] Update alpine-adguard.sh -q --- ct/alpine-adguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 7b2b79cb..f36ca7c4 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -53,7 +53,7 @@ function default_settings() { function update_script() { if ! apk -e info newt >/dev/null 2>&1; then - apk add newt + apk add -q newt fi while true; do CHOICE=$( From 29ff02c742ebffc9c126fc17bb8316acb53e5ec7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:28:19 -0400 Subject: [PATCH 4532/6505] Update alpine-docker.sh -q --- ct/alpine-docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index ad195e50..87c04d1c 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -53,7 +53,7 @@ function default_settings() { function update_script() { if ! apk -e info newt >/dev/null 2>&1; then - apk add newt + apk add -q newt fi while true; do CHOICE=$( From e589e28fa410fc952b08d58357e831eb872116f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:28:39 -0400 Subject: [PATCH 4533/6505] Update alpine-grafana.sh -q --- ct/alpine-grafana.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 170845b7..dd5283ab 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -53,7 +53,7 @@ function default_settings() { function update_script() { if ! apk -e info newt >/dev/null 2>&1; then - apk add newt + apk add -q newt fi LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do From 35f5b8413d31bec7b09eeb334d0cbfd9481ae2d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Mar 2023 13:34:25 -0400 Subject: [PATCH 4534/6505] Update homeassistant-core.sh spelling --- ct/homeassistant-core.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index a8429ed7..858433c2 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -73,7 +73,7 @@ function update_script() { else clear header_info - echo -e "${GN}Updating to Srable Version${CL}" + echo -e "${GN}Updating to Stable Version${CL}" BR="" fi if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi From 6829e1121d505227866ac0a82a1c9293543b2257 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 06:12:45 -0400 Subject: [PATCH 4535/6505] default, no root password for alpine-* install --- ct/alpine-adguard.sh | 2 +- ct/alpine-docker.sh | 2 +- ct/alpine-grafana.sh | 2 +- ct/alpine-vaultwarden.sh | 2 +- ct/alpine-zigbee2mqtt.sh | 2 +- install/alpine-adguard-install.sh | 1 + install/alpine-docker-install.sh | 1 + install/alpine-grafana-install.sh | 1 + install/alpine-vaultwarden-install.sh | 1 + install/alpine-zigbee2mqtt-install.sh | 1 + misc/alpine-install.func | 12 ++++++++++++ 11 files changed, 22 insertions(+), 5 deletions(-) diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index f36ca7c4..248aa7f2 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -31,7 +31,7 @@ catch_errors function default_settings() { CT_TYPE="1" - PW="-password alpine" + PW="" CT_ID=$NEXTID HN=$NSAPP DISK_SIZE="$var_disk" diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 87c04d1c..a7b08ba6 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -31,7 +31,7 @@ catch_errors function default_settings() { CT_TYPE="1" - PW="-password alpine" + PW="" CT_ID=$NEXTID HN=$NSAPP DISK_SIZE="$var_disk" diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index dd5283ab..7cb26ae6 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -31,7 +31,7 @@ catch_errors function default_settings() { CT_TYPE="1" - PW="-password alpine" + PW="" CT_ID=$NEXTID HN=$NSAPP DISK_SIZE="$var_disk" diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 0eddef93..45ea5390 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -31,7 +31,7 @@ catch_errors function default_settings() { CT_TYPE="1" - PW="-password alpine" + PW="" CT_ID=$NEXTID HN=$NSAPP DISK_SIZE="$var_disk" diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 51ec6030..55df4544 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -31,7 +31,7 @@ catch_errors function default_settings() { CT_TYPE="1" - PW="-password alpine" + PW="" CT_ID=$NEXTID HN=$NSAPP DISK_SIZE="$var_disk" diff --git a/install/alpine-adguard-install.sh b/install/alpine-adguard-install.sh index 4dd81790..aa9b09ae 100644 --- a/install/alpine-adguard-install.sh +++ b/install/alpine-adguard-install.sh @@ -33,3 +33,4 @@ $STD /opt/AdGuardHome/AdGuardHome -s start $STD msg_ok "Installed Alpine-AdGuard" motd_ssh +root \ No newline at end of file diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh index ac7dce79..4ed450e5 100644 --- a/install/alpine-docker-install.sh +++ b/install/alpine-docker-install.sh @@ -59,3 +59,4 @@ if echo "$prompt" | grep -Eq "^(y|yes)$"; then fi motd_ssh +root \ No newline at end of file diff --git a/install/alpine-grafana-install.sh b/install/alpine-grafana-install.sh index 86f1e97d..d20a7aca 100644 --- a/install/alpine-grafana-install.sh +++ b/install/alpine-grafana-install.sh @@ -29,3 +29,4 @@ $STD rc-update add grafana default msg_ok "Installed Grafana" motd_ssh +root \ No newline at end of file diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 952922e7..6c6f90a5 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -36,3 +36,4 @@ $STD rc-update add vaultwarden default msg_ok "Installed Alpine-Vaultwarden" motd_ssh +root \ No newline at end of file diff --git a/install/alpine-zigbee2mqtt-install.sh b/install/alpine-zigbee2mqtt-install.sh index f3698db9..4abf334e 100644 --- a/install/alpine-zigbee2mqtt-install.sh +++ b/install/alpine-zigbee2mqtt-install.sh @@ -26,3 +26,4 @@ $STD apk add zigbee2mqtt msg_ok "Installed Alpine-Zigbee2MQTT" motd_ssh +root \ No newline at end of file diff --git a/misc/alpine-install.func b/misc/alpine-install.func index f2f74a08..af32878f 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -114,3 +114,15 @@ motd_ssh() { $STD /etc/init.d/sshd start fi } + +customize() { + msg_info "Customizing Container" + bash -c "/etc/init.d/syslog stop;rc-update del syslog boot;passwd -d root" >/dev/null 2>&1 + msg_ok "Customized Container" +} + +root() { + if ! getent shadow root | grep -q '^root:[^:]*:\?\$'; then + customize + fi +} \ No newline at end of file From 2e581463806c8c9d563baec048dea1d3e55bb889 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 06:23:17 -0400 Subject: [PATCH 4536/6505] Update build.func rest 5 sec after start container if alpine --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index 88375fa3..50ba9e1a 100644 --- a/misc/build.func +++ b/misc/build.func @@ -452,6 +452,7 @@ EOF pct start "$CTID" msg_ok "Started LXC Container" if [ "$var_os" == "alpine" ]; then + sleep 5 pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit From bdc8d02f064f84a8348a962380e7904bb3701e65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 06:28:42 -0400 Subject: [PATCH 4537/6505] Update alpine-adguard-install.sh tweak --- install/alpine-adguard-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-adguard-install.sh b/install/alpine-adguard-install.sh index aa9b09ae..33df28ab 100644 --- a/install/alpine-adguard-install.sh +++ b/install/alpine-adguard-install.sh @@ -30,7 +30,7 @@ $STD rm AdGuardHome_linux_amd64.tar.gz $STD chmod +x /opt/AdGuardHome/AdGuardHome $STD /opt/AdGuardHome/AdGuardHome -s install $STD /opt/AdGuardHome/AdGuardHome -s start -$STD msg_ok "Installed Alpine-AdGuard" +msg_ok "Installed Alpine-AdGuard" motd_ssh -root \ No newline at end of file +root From 8e6f6dc28270ca700b9e6fc045b909dd9835e0b0 Mon Sep 17 00:00:00 2001 From: glerak Date: Sat, 25 Mar 2023 12:38:42 +0100 Subject: [PATCH 4538/6505] Update podman-homeassistant.sh (#1251) --- ct/podman-homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index be35917e..d916cc95 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -55,7 +55,7 @@ function default_settings() { } function update_script() { - [[ ! -f /etc/systemd/system/homeassistant.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ ! -f /etc/systemd/system/homeassistant.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update Podman" ON \ "2" "Install HACS" OFF \ From 1f32020d5c791bcbf2650af6bcbf807be7a4a657 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 08:22:24 -0400 Subject: [PATCH 4539/6505] Update alpine-install.func tweak --- misc/alpine-install.func | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index af32878f..f85d8d83 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -117,7 +117,7 @@ motd_ssh() { customize() { msg_info "Customizing Container" - bash -c "/etc/init.d/syslog stop;rc-update del syslog boot;passwd -d root" >/dev/null 2>&1 + bash -c "passwd -d root" >/dev/null 2>&1 msg_ok "Customized Container" } @@ -125,4 +125,4 @@ root() { if ! getent shadow root | grep -q '^root:[^:]*:\?\$'; then customize fi -} \ No newline at end of file +} From fb08167a832ba1f5f2cac748b3d83e78270b497c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 09:06:32 -0400 Subject: [PATCH 4540/6505] Create alpine-esphome.sh --- ct/alpine-esphome.sh | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 ct/alpine-esphome.sh diff --git a/ct/alpine-esphome.sh b/ct/alpine-esphome.sh new file mode 100644 index 00000000..7d39590a --- /dev/null +++ b/ct/alpine-esphome.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ___________ ____ __ __ + / ____/ ___// __ \/ / / /___ ____ ___ ___ + / __/ \__ \/ /_/ / /_/ / __ \/ __ `__ \/ _ \ + / /___ ___/ / ____/ __ / /_/ / / / / / / __/ +/_____//____/_/ /_/ /_/\____/_/ /_/ /_/\___/ + Alpine + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-ESPHome" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -f /usr/bin/esphome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ + "1" "Check for ESPHome Updates" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + esphome stop + pip3 install esphome --upgrade + esphome start + exit + ;; + esac + done +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6052${CL} \n" From a7a1c1717ce6c2e3a0a463fbff3c89fce5007af8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 09:08:07 -0400 Subject: [PATCH 4541/6505] Create alpine-esphome-install.sh --- install/alpine-esphome-install.sh | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 install/alpine-esphome-install.sh diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh new file mode 100644 index 00000000..857243a2 --- /dev/null +++ b/install/alpine-esphome-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +$STD apk add git +msg_ok "Installed Dependencies" + +msg_info "Installing Alpine-ESPHome" +$STD apk add py3-pip +$STD pip3 install esphome +$STD pip3 install tornado esptool +cat </etc/init.d/esphome +#!/sbin/openrc-run + +name="esphome" +description="ESPHome Service" +command="/usr/bin/esphome /root/config/ dashboard" +pidfile="/run/$RC_SVCNAME/pid" + +depend() { + need net +} + +start_pre() { + checkpath --directory --mode 0755 /run/$RC_SVCNAME +} + +start() { + ebegin "Starting $description" + start-stop-daemon --start --quiet --exec $command + eend $? +} + +stop() { + ebegin "Stopping $description" + start-stop-daemon --stop --quiet --exec $command + eend $? +} +EOF + +chmod 755 /etc/init.d/esphome +/etc/init.d/esphome start +rc-update add esphome default +msg_ok "Installed Alpine-ESPHome" + +motd_ssh +root From 38307912f8069f790f800c1c8046670782a58a5a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 09:15:22 -0400 Subject: [PATCH 4542/6505] Update alpine-esphome-install.sh --- install/alpine-esphome-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh index 857243a2..15fde305 100644 --- a/install/alpine-esphome-install.sh +++ b/install/alpine-esphome-install.sh @@ -31,6 +31,7 @@ cat </etc/init.d/esphome name="esphome" description="ESPHome Service" +RC_SVCNAME="esphome" command="/usr/bin/esphome /root/config/ dashboard" pidfile="/run/$RC_SVCNAME/pid" From 1e42e065b49f62c17dcd38f95c5e0696e14bb336 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 09:20:18 -0400 Subject: [PATCH 4543/6505] Update alpine-esphome-install.sh --- install/alpine-esphome-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh index 15fde305..b8dbf590 100644 --- a/install/alpine-esphome-install.sh +++ b/install/alpine-esphome-install.sh @@ -26,6 +26,7 @@ msg_info "Installing Alpine-ESPHome" $STD apk add py3-pip $STD pip3 install esphome $STD pip3 install tornado esptool +RC_SVCNAME="esphome" cat </etc/init.d/esphome #!/sbin/openrc-run From 18af21a1cc202f96bab9ee56082d99992f93f6ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 09:25:12 -0400 Subject: [PATCH 4544/6505] Update alpine-esphome-install.sh --- install/alpine-esphome-install.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh index b8dbf590..e189e9a2 100644 --- a/install/alpine-esphome-install.sh +++ b/install/alpine-esphome-install.sh @@ -26,22 +26,20 @@ msg_info "Installing Alpine-ESPHome" $STD apk add py3-pip $STD pip3 install esphome $STD pip3 install tornado esptool -RC_SVCNAME="esphome" cat </etc/init.d/esphome #!/sbin/openrc-run name="esphome" description="ESPHome Service" -RC_SVCNAME="esphome" command="/usr/bin/esphome /root/config/ dashboard" -pidfile="/run/$RC_SVCNAME/pid" +pidfile="/run/esphome/pid" depend() { need net } start_pre() { - checkpath --directory --mode 0755 /run/$RC_SVCNAME + checkpath --directory --mode 0755 /run/esphome } start() { From d345712e7b06309dab9e6f529bdf2b9a57f41bfe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 11:49:10 -0400 Subject: [PATCH 4545/6505] Update alpine-esphome-install.sh --- install/alpine-esphome-install.sh | 37 ++++++++++++++++--------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh index e189e9a2..6a9cecc6 100644 --- a/install/alpine-esphome-install.sh +++ b/install/alpine-esphome-install.sh @@ -26,38 +26,39 @@ msg_info "Installing Alpine-ESPHome" $STD apk add py3-pip $STD pip3 install esphome $STD pip3 install tornado esptool -cat </etc/init.d/esphome -#!/sbin/openrc-run -name="esphome" -description="ESPHome Service" -command="/usr/bin/esphome /root/config/ dashboard" -pidfile="/run/esphome/pid" +service_path="/etc/init.d/esphome" +echo "#!/sbin/openrc-run +name=\"esphome\" +description=\"ESPHome Dashboard\" +command=\"/usr/bin/esphome /root/config/ dashboard\" +command_user=\"root\" +command_background=true +pidfile=\"/run/\$name.pid\" depend() { need net } start_pre() { - checkpath --directory --mode 0755 /run/esphome + checkpath --directory --mode 0755 /run/\$name } start() { - ebegin "Starting $description" - start-stop-daemon --start --quiet --exec $command - eend $? + ebegin \"Starting \$description\" + start-stop-daemon --start --quiet --background --exec /usr/bin/esphome -- /root/config/ dashboard + eend \$? } stop() { - ebegin "Stopping $description" - start-stop-daemon --stop --quiet --exec $command - eend $? -} -EOF + ebegin \"Stopping \$description\" + pkill esphome + eend \$? +}" > $service_path -chmod 755 /etc/init.d/esphome -/etc/init.d/esphome start -rc-update add esphome default +chmod 755 $service_path +$STD rc-update add esphome default +$STD /etc/init.d/esphome start msg_ok "Installed Alpine-ESPHome" motd_ssh From ac62f07362221094c422ed06a6faa4a831239159 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 11:49:59 -0400 Subject: [PATCH 4546/6505] Update alpine-esphome.sh --- ct/alpine-esphome.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/alpine-esphome.sh b/ct/alpine-esphome.sh index 7d39590a..da0534ba 100644 --- a/ct/alpine-esphome.sh +++ b/ct/alpine-esphome.sh @@ -66,9 +66,7 @@ function update_script() { header_info case $CHOICE in 1) - esphome stop pip3 install esphome --upgrade - esphome start exit ;; esac From 86ec03dc35e70d4feb9b925ea7a54146fd499f27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 14:56:07 -0400 Subject: [PATCH 4547/6505] Update alpine-esphome.sh tweak update --- ct/alpine-esphome.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/alpine-esphome.sh b/ct/alpine-esphome.sh index da0534ba..0acbc670 100644 --- a/ct/alpine-esphome.sh +++ b/ct/alpine-esphome.sh @@ -66,7 +66,10 @@ function update_script() { header_info case $CHOICE in 1) - pip3 install esphome --upgrade + msg_info "Updating ESPHome" + pip3 install esphome --upgrade &>/dev/null + rc-service -q esphome restart + msg_ok "Updated Successfully!" exit ;; esac From 642048fb6d9c2306ddea24a9d8ce6d4be20f128e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 14:57:42 -0400 Subject: [PATCH 4548/6505] Update alpine-esphome-install.sh correct openrc --- install/alpine-esphome-install.sh | 37 +++++++++---------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh index 6a9cecc6..ca9f4628 100644 --- a/install/alpine-esphome-install.sh +++ b/install/alpine-esphome-install.sh @@ -27,38 +27,21 @@ $STD apk add py3-pip $STD pip3 install esphome $STD pip3 install tornado esptool -service_path="/etc/init.d/esphome" echo "#!/sbin/openrc-run -name=\"esphome\" -description=\"ESPHome Dashboard\" -command=\"/usr/bin/esphome /root/config/ dashboard\" -command_user=\"root\" -command_background=true -pidfile=\"/run/\$name.pid\" - -depend() { - need net -} - -start_pre() { - checkpath --directory --mode 0755 /run/\$name -} - +description=\"ESPHome\" +pidfile=\"/run/esphome.pid\" start() { - ebegin \"Starting \$description\" - start-stop-daemon --start --quiet --background --exec /usr/bin/esphome -- /root/config/ dashboard - eend \$? + esphome dashboard /root/esphome/config/ > /dev/null 2>&1 & + echo \$! > \$pidfile } - stop() { - ebegin \"Stopping \$description\" - pkill esphome - eend \$? -}" > $service_path + kill \$(cat \$pidfile) + rm \$pidfile +}" > /etc/init.d/esphome -chmod 755 $service_path -$STD rc-update add esphome default -$STD /etc/init.d/esphome start +chmod 755 /etc/init.d/esphome +rc-service -q esphome start +rc-update add -q esphome default msg_ok "Installed Alpine-ESPHome" motd_ssh From 676f240113c2eb235340cdd19797e85add50c30f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 15:07:06 -0400 Subject: [PATCH 4549/6505] Update alpine-esphome-install.sh tweak --- install/alpine-esphome-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh index ca9f4628..9f7b1070 100644 --- a/install/alpine-esphome-install.sh +++ b/install/alpine-esphome-install.sh @@ -22,8 +22,11 @@ $STD apk add mc $STD apk add git msg_ok "Installed Dependencies" -msg_info "Installing Alpine-ESPHome" +msg_info "Installing pip3 Package Manager" $STD apk add py3-pip +msg_ok "Installed pip3 Package Manager" + +msg_info "Installing Alpine-ESPHome" $STD pip3 install esphome $STD pip3 install tornado esptool From 4db1c1360e0c98972d2bdc40e81a282d90d4e395 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 15:23:24 -0400 Subject: [PATCH 4550/6505] Create alpine-whoogle-install.sh --- install/alpine-whoogle-install.sh | 52 +++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 install/alpine-whoogle-install.sh diff --git a/install/alpine-whoogle-install.sh b/install/alpine-whoogle-install.sh new file mode 100644 index 00000000..443001bd --- /dev/null +++ b/install/alpine-whoogle-install.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +msg_info "Installing pip3 Package Manager" +$STD apk add py3-pip +msg_ok "Installed pip3 Package Manager" + +msg_info "Installing Alpine-Whoogle" +$STD pip3 install brotli +$STD pip3 install whoogle-search + +echo "#!/sbin/openrc-run +description=\"Whoogle-Search\" +pidfile=\"/run/whoogle.pid\" + +start() { + /usr/bin/whoogle-search --host 0.0.0.0 & + echo \$! > \$pidfile +} + +stop() { + kill \$(cat \$pidfile) + rm \$pidfile +}" > /etc/init.d/whoogle + +chmod 755 /etc/init.d/whoogle +rc-service -q whoogle start +rc-update add -q whoogle default +msg_ok "Installed Alpine-Whoogle" + +motd_ssh +root From ac837891e057ea19c2a9196e62aed4f1f121c1ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 15:28:01 -0400 Subject: [PATCH 4551/6505] Create alpine-whoogle.sh --- ct/alpine-whoogle.sh | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 ct/alpine-whoogle.sh diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh new file mode 100644 index 00000000..1b20e9fa --- /dev/null +++ b/ct/alpine-whoogle.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + _ ____ __ +| | / / /_ ____ ____ ____ _/ /__ +| | /| / / __ \/ __ \/ __ \/ __ `/ / _ \ +| |/ |/ / / / / /_/ / /_/ / /_/ / / __/ +|__/|__/_/ /_/\____/\____/\__, /_/\___/ + Alpine /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Alpine-Whoogle" +var_disk="0.3" +var_cpu="1" +var_ram="256" +var_os="alpine" +var_version="3.17" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -f /usr/bin/whoogle-search ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + while true; do + CHOICE=$( + whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ + "1" "Check for Whoogle Updates" 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + msg_info "Updating Whoogle" + pip3 install whoogle-search --upgrade &>/dev/null + rc-service -q whoogle restart + msg_ok "Updated Successfully!" + exit + ;; + esac + done +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From be211699b90f18729fcf55ddefb7723e79e1588c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 17:24:06 -0400 Subject: [PATCH 4552/6505] Update alpine-esphome.sh tweak --- ct/alpine-esphome.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/alpine-esphome.sh b/ct/alpine-esphome.sh index 0acbc670..5497853b 100644 --- a/ct/alpine-esphome.sh +++ b/ct/alpine-esphome.sh @@ -52,7 +52,10 @@ function default_settings() { } function update_script() { - if [[ ! -f /usr/bin/esphome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ ! -f /usr/bin/esphome ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ From b0c767d9abcb25d83401a393150a811f591f5ada Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 17:25:23 -0400 Subject: [PATCH 4553/6505] Update alpine-whoogle.sh tweak --- ct/alpine-whoogle.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh index 1b20e9fa..b2e2eaa7 100644 --- a/ct/alpine-whoogle.sh +++ b/ct/alpine-whoogle.sh @@ -52,7 +52,10 @@ function default_settings() { } function update_script() { - if [[ ! -f /usr/bin/whoogle-search ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ ! -f /usr/bin/whoogle-search ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi while true; do CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ From b494fa404bd2fabc510a269cc1ef51ac2bb98788 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 17:26:28 -0400 Subject: [PATCH 4554/6505] Update build.func lower rest time --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 50ba9e1a..7de773bd 100644 --- a/misc/build.func +++ b/misc/build.func @@ -452,7 +452,7 @@ EOF pct start "$CTID" msg_ok "Started LXC Container" if [ "$var_os" == "alpine" ]; then - sleep 5 + sleep 2 pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit From 1954973e7722571691ef7873f5d78d142a3acb50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 17:29:00 -0400 Subject: [PATCH 4555/6505] Update alpine-whoogle-install.sh tweak --- install/alpine-whoogle-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-whoogle-install.sh b/install/alpine-whoogle-install.sh index 443001bd..b85e76d0 100644 --- a/install/alpine-whoogle-install.sh +++ b/install/alpine-whoogle-install.sh @@ -4,7 +4,7 @@ # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 @@ -41,7 +41,7 @@ start() { stop() { kill \$(cat \$pidfile) rm \$pidfile -}" > /etc/init.d/whoogle +}" >/etc/init.d/whoogle chmod 755 /etc/init.d/whoogle rc-service -q whoogle start From 59cf81026e0dcbc15b35989737b975ce4e7b56f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 17:30:25 -0400 Subject: [PATCH 4556/6505] Update alpine-esphome-install.sh tweak --- install/alpine-esphome-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh index 9f7b1070..d9d84bde 100644 --- a/install/alpine-esphome-install.sh +++ b/install/alpine-esphome-install.sh @@ -4,7 +4,7 @@ # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 @@ -40,7 +40,7 @@ start() { stop() { kill \$(cat \$pidfile) rm \$pidfile -}" > /etc/init.d/esphome +}" >/etc/init.d/esphome chmod 755 /etc/init.d/esphome rc-service -q esphome start From e2b999caa0ac62a0e593941a3098cc023d3e25c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 17:51:04 -0400 Subject: [PATCH 4557/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 907c02ea..94366868 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,15 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-25 + +### Changed + +- **Alpine-ESPHome LXC** + - NEW Script +- **Alpine-Whoogle LXC** + - NEW Script + ## 2023-03-22 ### Changed From ab40267e90f8309d79e2165fb219ec8877e8010a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Mar 2023 20:21:12 -0400 Subject: [PATCH 4558/6505] Update alpine-install.func enable root SSH access --- misc/alpine-install.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index f85d8d83..a7d282d9 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -111,6 +111,7 @@ motd_ssh() { echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" >/etc/motd if [[ "${SSH_ROOT}" == "yes" ]]; then $STD rc-update add sshd + sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config $STD /etc/init.d/sshd start fi } From 10ecbb856b4599ebcb0c029efc51783c84efda03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Mar 2023 11:06:28 -0400 Subject: [PATCH 4559/6505] Update build.func ssh_check --- misc/build.func | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/misc/build.func b/misc/build.func index 7de773bd..53000673 100644 --- a/misc/build.func +++ b/misc/build.func @@ -65,6 +65,18 @@ arch_check() { fi } +ssh_check() { +if command -v pveversion >/dev/null 2>&1; then + if [ -n "$SSH_CLIENT" ]; then + if whiptail --defaultno --title "SSH DETECTED" --yesno "The scripts suggest using the Proxmox shell instead of SSH, since the latter can create issues while gathering variables. Would you like to proceed with using SSH?" 10 68; then + echo "you've been warned" + else + exit + fi + fi +fi +} + echo_default() { if [ "$var_os" == "ubuntu" ]; then echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" From 6368df0b9ded6c3ba01f0fbfecfe1626aa78ff58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Mar 2023 11:11:13 -0400 Subject: [PATCH 4560/6505] Update build.func shfmt --- misc/build.func | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/misc/build.func b/misc/build.func index 53000673..45176495 100644 --- a/misc/build.func +++ b/misc/build.func @@ -66,15 +66,15 @@ arch_check() { } ssh_check() { -if command -v pveversion >/dev/null 2>&1; then - if [ -n "$SSH_CLIENT" ]; then - if whiptail --defaultno --title "SSH DETECTED" --yesno "The scripts suggest using the Proxmox shell instead of SSH, since the latter can create issues while gathering variables. Would you like to proceed with using SSH?" 10 68; then - echo "you've been warned" - else - exit - fi + if command -v pveversion >/dev/null 2>&1; then + if [ -n "$SSH_CLIENT" ]; then + if whiptail --defaultno --title "SSH DETECTED" --yesno "The scripts suggest using the Proxmox shell instead of SSH, since the latter can create issues while gathering variables. Would you like to proceed with using SSH?" 10 68; then + echo "you've been warned" + else + exit + fi + fi fi -fi } echo_default() { @@ -398,9 +398,9 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)" + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)" else - export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" fi export tz="$timezone" if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then @@ -464,8 +464,8 @@ EOF pct start "$CTID" msg_ok "Started LXC Container" if [ "$var_os" == "alpine" ]; then - sleep 2 - pct exec "$CTID" -- ash -c "apk add bash >/dev/null" + sleep 2 + pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit From ec432fce345e6fabd29afd068bf0edcb42e15cb0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Mar 2023 22:56:13 -0400 Subject: [PATCH 4561/6505] Update nginxproxymanager-install.sh hold v2.9.22 --- install/nginxproxymanager-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index b2baa37f..bda3670c 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -66,10 +66,10 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v$RELEASE" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v$RELEASE -O - | tar -xz -cd ./nginx-proxy-manager-$RELEASE -msg_ok "Downloaded Nginx Proxy Manager v$RELEASE" +msg_info "Downloading Nginx Proxy Manager v2.9.22" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz +cd ./nginx-proxy-manager-2.9.22 +msg_ok "Downloaded Nginx Proxy Manager v2.9.22" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python @@ -77,8 +77,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+${RELEASE}+g" backend/package.json -sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json +sed -i "s+0.0.0+2.9.22+g" backend/package.json +sed -i "s+0.0.0+2.9.22+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") From 636ca27c9e3aea3cfcd45d96abc34b1e00327340 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Mar 2023 22:58:34 -0400 Subject: [PATCH 4562/6505] Update nginxproxymanager.sh hold v2.9.22 --- ct/nginxproxymanager.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 99b95e30..ce7fc32f 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -74,18 +74,18 @@ function update_script() { /var/cache/nginx &>/dev/null msg_ok "Cleaned Old Files" - msg_info "Downloading NPM v${RELEASE}" - wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null - cd nginx-proxy-manager-${RELEASE} - msg_ok "Downloaded NPM v${RELEASE}" + msg_info "Downloading NPM v2.9.22" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz &>/dev/null + cd nginx-proxy-manager-2.9.22 + msg_ok "Downloaded NPM v2.9.22" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx - sed -i "s+0.0.0+${RELEASE}+g" backend/package.json - sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json + sed -i "s+0.0.0+2.9.22+g" backend/package.json + sed -i "s+0.0.0+2.9.22+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do From 7daa751c3c9866a2148331bd24a27ff07dac2e4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 10:03:50 -0400 Subject: [PATCH 4563/6505] Update grafana-install.sh enable/start grafana --- install/grafana-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/grafana-install.sh b/install/grafana-install.sh index 718cc230..1ab76079 100644 --- a/install/grafana-install.sh +++ b/install/grafana-install.sh @@ -30,6 +30,8 @@ msg_ok "Set up Grafana Repository" msg_info "Installing Grafana" $STD apt-get update $STD apt-get install -y grafana +systemctl start grafana-server +systemctl enable --now -q grafana-server.service msg_ok "Installed Grafana" motd_ssh From c536591de396b07b41e5011a65f24eeb73604042 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 11:09:03 -0400 Subject: [PATCH 4564/6505] Delete alpine-esphome.sh nonoperational --- ct/alpine-esphome.sh | 88 -------------------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 ct/alpine-esphome.sh diff --git a/ct/alpine-esphome.sh b/ct/alpine-esphome.sh deleted file mode 100644 index 5497853b..00000000 --- a/ct/alpine-esphome.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { - clear - cat <<"EOF" - ___________ ____ __ __ - / ____/ ___// __ \/ / / /___ ____ ___ ___ - / __/ \__ \/ /_/ / /_/ / __ \/ __ `__ \/ _ \ - / /___ ___/ / ____/ __ / /_/ / / / / / / __/ -/_____//____/_/ /_/ /_/\____/_/ /_/ /_/\___/ - Alpine - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-ESPHome" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="alpine" -var_version="3.17" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET=dhcp - GATE="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { - if [[ ! -f /usr/bin/esphome ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - while true; do - CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ - "1" "Check for ESPHome Updates" 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - clear - exit-script - fi - header_info - case $CHOICE in - 1) - msg_info "Updating ESPHome" - pip3 install esphome --upgrade &>/dev/null - rc-service -q esphome restart - msg_ok "Updated Successfully!" - exit - ;; - esac - done -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:6052${CL} \n" From 0efbaa27eeb0ed12fc0714c84141df9377f7f655 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 11:09:34 -0400 Subject: [PATCH 4565/6505] Delete alpine-esphome-install.sh nonoperational --- install/alpine-esphome-install.sh | 51 ------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 install/alpine-esphome-install.sh diff --git a/install/alpine-esphome-install.sh b/install/alpine-esphome-install.sh deleted file mode 100644 index d9d84bde..00000000 --- a/install/alpine-esphome-install.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" - -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apk add newt -$STD apk add curl -$STD apk add openssh -$STD apk add nano -$STD apk add mc -$STD apk add git -msg_ok "Installed Dependencies" - -msg_info "Installing pip3 Package Manager" -$STD apk add py3-pip -msg_ok "Installed pip3 Package Manager" - -msg_info "Installing Alpine-ESPHome" -$STD pip3 install esphome -$STD pip3 install tornado esptool - -echo "#!/sbin/openrc-run -description=\"ESPHome\" -pidfile=\"/run/esphome.pid\" -start() { - esphome dashboard /root/esphome/config/ > /dev/null 2>&1 & - echo \$! > \$pidfile -} -stop() { - kill \$(cat \$pidfile) - rm \$pidfile -}" >/etc/init.d/esphome - -chmod 755 /etc/init.d/esphome -rc-service -q esphome start -rc-update add -q esphome default -msg_ok "Installed Alpine-ESPHome" - -motd_ssh -root From 8ff557f9c2e53bfc1671ed6138e0390a171d2c47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 11:11:49 -0400 Subject: [PATCH 4566/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 94366868..1463c0d3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-27 + +### Changed + +- **Removed Alpine-ESPHome LXC** + - Nonoperational + ## 2023-03-25 ### Changed From 3d3a03ce3faefebbcaba6626bdb6fbbe8ea9460b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 18:58:28 -0400 Subject: [PATCH 4567/6505] Update alpine-whoogle.sh ssh_check --- ct/alpine-whoogle.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh index b2e2eaa7..7dbf5066 100644 --- a/ct/alpine-whoogle.sh +++ b/ct/alpine-whoogle.sh @@ -79,6 +79,7 @@ function update_script() { done } +ssh_check start build_container description From 36ee55e61d2fbcbadf5c111fe38064ef1e827fe5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 19:02:50 -0400 Subject: [PATCH 4568/6505] Update build.func tweak --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index 45176495..465d132f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -71,6 +71,7 @@ ssh_check() { if whiptail --defaultno --title "SSH DETECTED" --yesno "The scripts suggest using the Proxmox shell instead of SSH, since the latter can create issues while gathering variables. Would you like to proceed with using SSH?" 10 68; then echo "you've been warned" else + clear exit fi fi From 726cbe6ba9ecaf515dc01944df787752a65a326a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 19:09:22 -0400 Subject: [PATCH 4569/6505] add ssh_check --- ct/adguard.sh | 1 + ct/alpine-adguard.sh | 1 + ct/alpine-docker.sh | 1 + ct/alpine-grafana.sh | 1 + ct/alpine-vaultwarden.sh | 1 + ct/alpine-zigbee2mqtt.sh | 1 + ct/alpine.sh | 1 + ct/audiobookshelf.sh | 1 + ct/autobrr.sh | 1 + ct/blocky.sh | 1 + ct/casaos.sh | 1 + ct/changedetection.sh | 1 + ct/cronicle.sh | 1 + ct/daemonsync.sh | 1 + ct/dashy.sh | 1 + ct/debian.sh | 1 + ct/deconz.sh | 1 + ct/deluge.sh | 1 + ct/devuan.sh | 1 + ct/docker.sh | 1 + ct/emby.sh | 1 + ct/emqx.sh | 1 + ct/esphome.sh | 1 + ct/go2rtc.sh | 1 + ct/grafana.sh | 1 + ct/grocy.sh | 1 + ct/heimdalldashboard.sh | 1 + ct/homeassistant-core.sh | 1 + ct/homeassistant.sh | 1 + ct/homebridge.sh | 1 + ct/homepage.sh | 1 + ct/homer.sh | 1 + ct/hyperion.sh | 1 + ct/influxdb.sh | 1 + ct/iobroker.sh | 1 + ct/jackett.sh | 1 + ct/jellyfin.sh | 1 + ct/k0s.sh | 1 + ct/kavita.sh | 1 + ct/keycloak.sh | 1 + ct/lidarr.sh | 1 + ct/magicmirror.sh | 1 + ct/mariadb.sh | 1 + ct/meshcentral.sh | 1 + ct/motioneye.sh | 1 + ct/mqtt.sh | 1 + ct/n8n.sh | 1 + ct/navidrome.sh | 1 + ct/nextcloudpi.sh | 1 + ct/nginxproxymanager.sh | 1 + ct/nocodb.sh | 1 + ct/node-red.sh | 1 + ct/omada.sh | 1 + ct/omv.sh | 1 + ct/openhab.sh | 1 + ct/paperless-ngx.sh | 1 + ct/photoprism.sh | 1 + ct/pihole.sh | 1 + ct/plex.sh | 1 + ct/podman-homeassistant.sh | 1 + ct/podman.sh | 1 + ct/postgresql.sh | 1 + ct/prometheus.sh | 1 + ct/prowlarr.sh | 1 + ct/qbittorrent.sh | 1 + ct/radarr.sh | 1 + ct/readarr.sh | 1 + ct/rockylinux.sh | 1 + ct/rstptoweb.sh | 1 + ct/sabnzbd.sh | 1 + ct/scrypted.sh | 1 + ct/shinobi.sh | 1 + ct/sonarr.sh | 1 + ct/syncthing.sh | 1 + ct/tdarr.sh | 1 + ct/technitiumdns.sh | 1 + ct/transmission.sh | 1 + ct/trilium.sh | 1 + ct/ubuntu.sh | 1 + ct/umbrel.sh | 1 + ct/unifi.sh | 1 + ct/uptimekuma.sh | 1 + ct/vaultwarden.sh | 1 + ct/whisparr.sh | 1 + ct/whoogle.sh | 1 + ct/wikijs.sh | 1 + ct/wireguard.sh | 1 + ct/yunohost.sh | 1 + ct/zigbee2mqtt.sh | 1 + ct/zwave-js-ui.sh | 1 + 90 files changed, 90 insertions(+) diff --git a/ct/adguard.sh b/ct/adguard.sh index e8c65085..c36e12bf 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -78,6 +78,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 248aa7f2..5dd9e955 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -81,6 +81,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index a7b08ba6..8bde63ce 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -75,6 +75,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 7cb26ae6..36872876 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -88,6 +88,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 45ea5390..70b5f7f8 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -81,6 +81,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 55df4544..f9185143 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -75,6 +75,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine.sh b/ct/alpine.sh index a3348a9f..3eb6a0c9 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -63,6 +63,7 @@ exit; fi } +ssh_check start build_container description diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 558dbc44..b208249c 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 3261b560..91e8a8be 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -71,6 +71,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/blocky.sh b/ct/blocky.sh index 08e769e8..4a2f77b2 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/casaos.sh b/ct/casaos.sh index c98a025d..593379c8 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/changedetection.sh b/ct/changedetection.sh index c8da20ae..d0ba97e8 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 53702989..3f812270 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -100,6 +100,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index d13e5b40..7f6ed79f 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/dashy.sh b/ct/dashy.sh index 5c76cf70..7b95c492 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -86,6 +86,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/debian.sh b/ct/debian.sh index b67a0a26..dc09cba4 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/deconz.sh b/ct/deconz.sh index 6195bd10..f5aee5fc 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/deluge.sh b/ct/deluge.sh index 0b3ce6c4..b82cebce 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -61,6 +61,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/devuan.sh b/ct/devuan.sh index db48bf4e..beb4b23d 100644 --- a/ct/devuan.sh +++ b/ct/devuan.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/docker.sh b/ct/docker.sh index 1805787c..77b9c184 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/emby.sh b/ct/emby.sh index 2e617cfb..d87c1aae 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -71,6 +71,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/emqx.sh b/ct/emqx.sh index 7c0ffcd9..e3ce0056 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/esphome.sh b/ct/esphome.sh index cd6e56d2..82c0c6c8 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -68,6 +68,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 58b82f5c..b840dc30 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -61,6 +61,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/grafana.sh b/ct/grafana.sh index 3de34626..4a363954 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/grocy.sh b/ct/grocy.sh index dd30c554..f33b8a87 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index aad87f46..6eeaf236 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -140,6 +140,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 858433c2..b635db1d 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -207,6 +207,7 @@ EOF fi } +ssh_check start build_container description diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index ac667247..7c96ab1c 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -128,6 +128,7 @@ WantedBy=default.target" >$service_path fi } +ssh_check start build_container description diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 22039d22..8b67fdb1 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/homepage.sh b/ct/homepage.sh index e8041087..87bc8cc1 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -67,6 +67,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/homer.sh b/ct/homer.sh index 217b2800..05939da2 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -84,6 +84,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 92535765..0021c3be 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/influxdb.sh b/ct/influxdb.sh index f6c078cf..8b6c3150 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 841f135e..17dcd29d 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/jackett.sh b/ct/jackett.sh index f895f4d7..2c6eff8d 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index d11b8212..a67c5967 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/k0s.sh b/ct/k0s.sh index 75b5648a..5f39de39 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/kavita.sh b/ct/kavita.sh index 8410daa7..f0ebf4cc 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 4488dd1a..2585d900 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/lidarr.sh b/ct/lidarr.sh index 6bc88997..c4959153 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index c57121c2..aeda1e47 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -63,6 +63,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/mariadb.sh b/ct/mariadb.sh index d6894ed9..857fabbb 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 2739b517..932ea4bd 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 4a106f03..b5084568 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 0dde1c0e..312c467d 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/n8n.sh b/ct/n8n.sh index d4862ef1..297c9eed 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/navidrome.sh b/ct/navidrome.sh index c9e53584..0ebb3d38 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -71,6 +71,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index a1718208..52f04f49 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index ce7fc32f..012ebd53 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -171,6 +171,7 @@ EOF exit } +ssh_check start build_container description diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 4b7636f6..e56521ba 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -63,6 +63,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/node-red.sh b/ct/node-red.sh index 3dba9183..c90d898c 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -96,6 +96,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/omada.sh b/ct/omada.sh index 104183df..51127d43 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/omv.sh b/ct/omv.sh index 532df042..c898c92e 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/openhab.sh b/ct/openhab.sh index 21a77dc7..d197aec1 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 09d46d45..30b1d9f9 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -132,6 +132,7 @@ EOF fi } +ssh_check start build_container description diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 231f7d1e..c6c943bd 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -86,6 +86,7 @@ function update_script() { exit } +ssh_check start build_container description diff --git a/ct/pihole.sh b/ct/pihole.sh index 07e786ea..57f09f15 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/plex.sh b/ct/plex.sh index 48d12505..beb328e7 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -71,6 +71,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index d916cc95..e3ccf4d7 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -111,6 +111,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/podman.sh b/ct/podman.sh index b4297c51..c18a858a 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/postgresql.sh b/ct/postgresql.sh index f0b606a1..606ee95d 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 16f17758..bfbf2367 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index 2c323541..cb5c5347 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 83cc8526..499cfcf3 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/radarr.sh b/ct/radarr.sh index a379e8ac..df6704a8 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/readarr.sh b/ct/readarr.sh index bea527d0..40e2ac20 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index edc69291..715a4a5f 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/rstptoweb.sh b/ct/rstptoweb.sh index 1c1bb453..c7db7f59 100644 --- a/ct/rstptoweb.sh +++ b/ct/rstptoweb.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index ea75032d..8514ba30 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -66,6 +66,7 @@ msg_ok "Updated $APP" exit } +ssh_check start build_container description diff --git a/ct/scrypted.sh b/ct/scrypted.sh index d307d78c..eadc2f0f 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/shinobi.sh b/ct/shinobi.sh index bc5572e6..b8b003bf 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -64,6 +64,7 @@ msg_ok "Updated Shinobi LXC" exit } +ssh_check start build_container description diff --git a/ct/sonarr.sh b/ct/sonarr.sh index ac6f2399..48a249e5 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/syncthing.sh b/ct/syncthing.sh index 292cf4db..f6b3d67c 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 994ae3db..1d570df8 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index f947cd07..ca568c91 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -70,6 +70,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/transmission.sh b/ct/transmission.sh index 94e654d6..cb0f21d8 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/trilium.sh b/ct/trilium.sh index 3e15c458..1288b82a 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -80,6 +80,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index bc2f0cc6..c30b4067 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 46ed1aa2..d35b3ac1 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/unifi.sh b/ct/unifi.sh index 542f1f87..bd619787 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 4f64ecc3..77b81ecc 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -78,6 +78,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 8f887956..e5373967 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -131,6 +131,7 @@ function update_script() { fi } +ssh_check start build_container description diff --git a/ct/whisparr.sh b/ct/whisparr.sh index c616282a..2a99863f 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -61,6 +61,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/whoogle.sh b/ct/whoogle.sh index e93b19d7..67ecf793 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/wikijs.sh b/ct/wikijs.sh index e1ac9863..a8051de0 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -83,6 +83,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 553de4e5..4afea4d0 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -115,6 +115,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 22198999..6ffda45d 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index c1c59ff0..a91c9ec4 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -126,6 +126,7 @@ function update_script() { exit } +ssh_check start build_container description diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index ed8c0d64..2dfcaaa5 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -78,6 +78,7 @@ function update_script() { exit } +ssh_check start build_container description From 43ca5981f7c57b87f316be96820013e4be68b0f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 20:00:26 -0400 Subject: [PATCH 4570/6505] Update build.func reword ssh_check --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 465d132f..df2de2d2 100644 --- a/misc/build.func +++ b/misc/build.func @@ -68,7 +68,7 @@ arch_check() { ssh_check() { if command -v pveversion >/dev/null 2>&1; then if [ -n "$SSH_CLIENT" ]; then - if whiptail --defaultno --title "SSH DETECTED" --yesno "The scripts suggest using the Proxmox shell instead of SSH, since the latter can create issues while gathering variables. Would you like to proceed with using SSH?" 10 68; then + if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then echo "you've been warned" else clear From 6bf9e68f89aca2a64687be82802099de365988f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 20:24:49 -0400 Subject: [PATCH 4571/6505] Update haos-vm.sh add SSH_CHECK --- vm/haos-vm.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 5160d8be..87cf3b3e 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -95,6 +95,18 @@ function ARCH_CHECK() { exit fi } +function SSH_CHECK() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "$SSH_CLIENT" ]; then + if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} function default_settings() { BRANCH="$stable" VMID="$NEXTID" @@ -257,6 +269,7 @@ function START_SCRIPT() { } ARCH_CHECK PVE_CHECK +SSH_CHECK START_SCRIPT msg_info "Validating Storage" while read -r line; do From 23d8d1b807038258cb4f62238d68aae9d291868d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 20:52:46 -0400 Subject: [PATCH 4572/6505] revert ssh_check --- ct/adguard.sh | 1 - ct/alpine-adguard.sh | 1 - ct/alpine-docker.sh | 1 - ct/alpine-grafana.sh | 1 - ct/alpine-vaultwarden.sh | 1 - ct/alpine-whoogle.sh | 1 - ct/alpine-zigbee2mqtt.sh | 1 - ct/alpine.sh | 1 - ct/audiobookshelf.sh | 1 - ct/autobrr.sh | 1 - ct/blocky.sh | 1 - ct/casaos.sh | 1 - ct/changedetection.sh | 1 - ct/cronicle.sh | 1 - ct/daemonsync.sh | 1 - ct/dashy.sh | 1 - ct/debian.sh | 1 - ct/deconz.sh | 1 - ct/deluge.sh | 1 - ct/devuan.sh | 1 - ct/docker.sh | 1 - ct/emby.sh | 1 - ct/emqx.sh | 1 - ct/esphome.sh | 1 - ct/go2rtc.sh | 1 - ct/grafana.sh | 1 - ct/grocy.sh | 1 - ct/heimdalldashboard.sh | 1 - ct/homeassistant-core.sh | 1 - ct/homeassistant.sh | 1 - ct/homebridge.sh | 1 - ct/homepage.sh | 1 - ct/homer.sh | 1 - ct/hyperion.sh | 1 - ct/influxdb.sh | 1 - ct/iobroker.sh | 1 - ct/jackett.sh | 1 - ct/jellyfin.sh | 1 - ct/k0s.sh | 1 - ct/kavita.sh | 1 - ct/keycloak.sh | 1 - ct/lidarr.sh | 1 - ct/magicmirror.sh | 1 - ct/mariadb.sh | 1 - ct/meshcentral.sh | 1 - ct/motioneye.sh | 1 - ct/mqtt.sh | 1 - ct/n8n.sh | 1 - ct/navidrome.sh | 1 - ct/nextcloudpi.sh | 1 - ct/nginxproxymanager.sh | 1 - ct/nocodb.sh | 1 - ct/node-red.sh | 1 - ct/omada.sh | 1 - ct/omv.sh | 1 - ct/openhab.sh | 1 - ct/paperless-ngx.sh | 1 - ct/photoprism.sh | 1 - ct/pihole.sh | 1 - ct/plex.sh | 1 - ct/podman-homeassistant.sh | 1 - ct/podman.sh | 1 - ct/postgresql.sh | 1 - ct/prometheus.sh | 1 - ct/prowlarr.sh | 1 - ct/qbittorrent.sh | 1 - ct/radarr.sh | 1 - ct/readarr.sh | 1 - ct/rockylinux.sh | 1 - ct/rstptoweb.sh | 1 - ct/sabnzbd.sh | 1 - ct/scrypted.sh | 1 - ct/shinobi.sh | 1 - ct/sonarr.sh | 1 - ct/syncthing.sh | 1 - ct/tdarr.sh | 1 - ct/technitiumdns.sh | 1 - ct/transmission.sh | 1 - ct/trilium.sh | 1 - ct/ubuntu.sh | 1 - ct/umbrel.sh | 1 - ct/unifi.sh | 1 - ct/uptimekuma.sh | 1 - ct/vaultwarden.sh | 1 - ct/whisparr.sh | 1 - ct/whoogle.sh | 1 - ct/wikijs.sh | 1 - ct/wireguard.sh | 1 - ct/yunohost.sh | 1 - ct/zigbee2mqtt.sh | 1 - ct/zwave-js-ui.sh | 1 - 91 files changed, 91 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index c36e12bf..e8c65085 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -78,7 +78,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 5dd9e955..248aa7f2 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -81,7 +81,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 8bde63ce..a7b08ba6 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -75,7 +75,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 36872876..7cb26ae6 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -88,7 +88,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 70b5f7f8..45ea5390 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -81,7 +81,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh index 7dbf5066..b2e2eaa7 100644 --- a/ct/alpine-whoogle.sh +++ b/ct/alpine-whoogle.sh @@ -79,7 +79,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index f9185143..55df4544 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -75,7 +75,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine.sh b/ct/alpine.sh index 3eb6a0c9..a3348a9f 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -63,7 +63,6 @@ exit; fi } -ssh_check start build_container description diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index b208249c..558dbc44 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 91e8a8be..3261b560 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -71,7 +71,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/blocky.sh b/ct/blocky.sh index 4a2f77b2..08e769e8 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/casaos.sh b/ct/casaos.sh index 593379c8..c98a025d 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/changedetection.sh b/ct/changedetection.sh index d0ba97e8..c8da20ae 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 3f812270..53702989 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -100,7 +100,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index 7f6ed79f..d13e5b40 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/dashy.sh b/ct/dashy.sh index 7b95c492..5c76cf70 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -86,7 +86,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/debian.sh b/ct/debian.sh index dc09cba4..b67a0a26 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/deconz.sh b/ct/deconz.sh index f5aee5fc..6195bd10 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/deluge.sh b/ct/deluge.sh index b82cebce..0b3ce6c4 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -61,7 +61,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/devuan.sh b/ct/devuan.sh index beb4b23d..db48bf4e 100644 --- a/ct/devuan.sh +++ b/ct/devuan.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/docker.sh b/ct/docker.sh index 77b9c184..1805787c 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/emby.sh b/ct/emby.sh index d87c1aae..2e617cfb 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -71,7 +71,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/emqx.sh b/ct/emqx.sh index e3ce0056..7c0ffcd9 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/esphome.sh b/ct/esphome.sh index 82c0c6c8..cd6e56d2 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -68,7 +68,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index b840dc30..58b82f5c 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -61,7 +61,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/grafana.sh b/ct/grafana.sh index 4a363954..3de34626 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/grocy.sh b/ct/grocy.sh index f33b8a87..dd30c554 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 6eeaf236..aad87f46 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -140,7 +140,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index b635db1d..858433c2 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -207,7 +207,6 @@ EOF fi } -ssh_check start build_container description diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 7c96ab1c..ac667247 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -128,7 +128,6 @@ WantedBy=default.target" >$service_path fi } -ssh_check start build_container description diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 8b67fdb1..22039d22 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/homepage.sh b/ct/homepage.sh index 87bc8cc1..e8041087 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -67,7 +67,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/homer.sh b/ct/homer.sh index 05939da2..217b2800 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -84,7 +84,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 0021c3be..92535765 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 8b6c3150..f6c078cf 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 17dcd29d..841f135e 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/jackett.sh b/ct/jackett.sh index 2c6eff8d..f895f4d7 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index a67c5967..d11b8212 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/k0s.sh b/ct/k0s.sh index 5f39de39..75b5648a 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/kavita.sh b/ct/kavita.sh index f0ebf4cc..8410daa7 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 2585d900..4488dd1a 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/lidarr.sh b/ct/lidarr.sh index c4959153..6bc88997 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index aeda1e47..c57121c2 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -63,7 +63,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 857fabbb..d6894ed9 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 932ea4bd..2739b517 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/motioneye.sh b/ct/motioneye.sh index b5084568..4a106f03 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 312c467d..0dde1c0e 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/n8n.sh b/ct/n8n.sh index 297c9eed..d4862ef1 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/navidrome.sh b/ct/navidrome.sh index 0ebb3d38..c9e53584 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -71,7 +71,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index 52f04f49..a1718208 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 012ebd53..ce7fc32f 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -171,7 +171,6 @@ EOF exit } -ssh_check start build_container description diff --git a/ct/nocodb.sh b/ct/nocodb.sh index e56521ba..4b7636f6 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -63,7 +63,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/node-red.sh b/ct/node-red.sh index c90d898c..3dba9183 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -96,7 +96,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/omada.sh b/ct/omada.sh index 51127d43..104183df 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/omv.sh b/ct/omv.sh index c898c92e..532df042 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/openhab.sh b/ct/openhab.sh index d197aec1..21a77dc7 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 30b1d9f9..09d46d45 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -132,7 +132,6 @@ EOF fi } -ssh_check start build_container description diff --git a/ct/photoprism.sh b/ct/photoprism.sh index c6c943bd..231f7d1e 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -86,7 +86,6 @@ function update_script() { exit } -ssh_check start build_container description diff --git a/ct/pihole.sh b/ct/pihole.sh index 57f09f15..07e786ea 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/plex.sh b/ct/plex.sh index beb328e7..48d12505 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -71,7 +71,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index e3ccf4d7..d916cc95 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -111,7 +111,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/podman.sh b/ct/podman.sh index c18a858a..b4297c51 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 606ee95d..f0b606a1 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/prometheus.sh b/ct/prometheus.sh index bfbf2367..16f17758 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index cb5c5347..2c323541 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 499cfcf3..83cc8526 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/radarr.sh b/ct/radarr.sh index df6704a8..a379e8ac 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/readarr.sh b/ct/readarr.sh index 40e2ac20..bea527d0 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index 715a4a5f..edc69291 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/rstptoweb.sh b/ct/rstptoweb.sh index c7db7f59..1c1bb453 100644 --- a/ct/rstptoweb.sh +++ b/ct/rstptoweb.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index 8514ba30..ea75032d 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -66,7 +66,6 @@ msg_ok "Updated $APP" exit } -ssh_check start build_container description diff --git a/ct/scrypted.sh b/ct/scrypted.sh index eadc2f0f..d307d78c 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/shinobi.sh b/ct/shinobi.sh index b8b003bf..bc5572e6 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -64,7 +64,6 @@ msg_ok "Updated Shinobi LXC" exit } -ssh_check start build_container description diff --git a/ct/sonarr.sh b/ct/sonarr.sh index 48a249e5..ac6f2399 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/syncthing.sh b/ct/syncthing.sh index f6b3d67c..292cf4db 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 1d570df8..994ae3db 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index ca568c91..f947cd07 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -70,7 +70,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/transmission.sh b/ct/transmission.sh index cb0f21d8..94e654d6 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/trilium.sh b/ct/trilium.sh index 1288b82a..3e15c458 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -80,7 +80,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index c30b4067..bc2f0cc6 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/umbrel.sh b/ct/umbrel.sh index d35b3ac1..46ed1aa2 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/unifi.sh b/ct/unifi.sh index bd619787..542f1f87 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 77b81ecc..4f64ecc3 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -78,7 +78,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index e5373967..8f887956 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -131,7 +131,6 @@ function update_script() { fi } -ssh_check start build_container description diff --git a/ct/whisparr.sh b/ct/whisparr.sh index 2a99863f..c616282a 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -61,7 +61,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/whoogle.sh b/ct/whoogle.sh index 67ecf793..e93b19d7 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/wikijs.sh b/ct/wikijs.sh index a8051de0..e1ac9863 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -83,7 +83,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 4afea4d0..553de4e5 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -115,7 +115,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 6ffda45d..22198999 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index a91c9ec4..c1c59ff0 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -126,7 +126,6 @@ function update_script() { exit } -ssh_check start build_container description diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 2dfcaaa5..ed8c0d64 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -78,7 +78,6 @@ function update_script() { exit } -ssh_check start build_container description From 92c24cefe48ab13c5829789fb835f042eed3fb96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 20:53:51 -0400 Subject: [PATCH 4573/6505] revert SSH_CHECK --- vm/haos-vm.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 87cf3b3e..aa19d7b9 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -269,7 +269,6 @@ function START_SCRIPT() { } ARCH_CHECK PVE_CHECK -SSH_CHECK START_SCRIPT msg_info "Validating Storage" while read -r line; do From 8bf03a6cb6d520094d6d659256291c9e934295fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 21:16:23 -0400 Subject: [PATCH 4574/6505] Update build.func update ssh_check code --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index df2de2d2..a6e7e0e3 100644 --- a/misc/build.func +++ b/misc/build.func @@ -67,7 +67,7 @@ arch_check() { ssh_check() { if command -v pveversion >/dev/null 2>&1; then - if [ -n "$SSH_CLIENT" ]; then + if [ -n "${SSH_CLIENT:+x}" ]; then if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then echo "you've been warned" else From b19b5e1039f38f4be9eefaa5872c9c32d577e609 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 21:21:14 -0400 Subject: [PATCH 4575/6505] revert revert ssh_check --- ct/adguard.sh | 1 + ct/alpine-adguard.sh | 1 + ct/alpine-docker.sh | 1 + ct/alpine-grafana.sh | 1 + ct/alpine-vaultwarden.sh | 1 + ct/alpine-whoogle.sh | 1 + ct/alpine-zigbee2mqtt.sh | 1 + ct/alpine.sh | 1 + ct/audiobookshelf.sh | 1 + ct/autobrr.sh | 1 + ct/blocky.sh | 1 + ct/casaos.sh | 1 + ct/changedetection.sh | 1 + ct/cronicle.sh | 1 + ct/daemonsync.sh | 1 + ct/dashy.sh | 1 + ct/debian.sh | 1 + ct/deconz.sh | 1 + ct/deluge.sh | 1 + ct/devuan.sh | 1 + ct/docker.sh | 1 + ct/emby.sh | 1 + ct/emqx.sh | 1 + ct/esphome.sh | 1 + ct/go2rtc.sh | 1 + ct/grafana.sh | 1 + ct/grocy.sh | 1 + ct/heimdalldashboard.sh | 1 + ct/homeassistant-core.sh | 1 + ct/homeassistant.sh | 1 + ct/homebridge.sh | 1 + ct/homepage.sh | 1 + ct/homer.sh | 1 + ct/hyperion.sh | 1 + ct/influxdb.sh | 1 + ct/iobroker.sh | 1 + ct/jackett.sh | 1 + ct/jellyfin.sh | 1 + ct/k0s.sh | 1 + ct/kavita.sh | 1 + ct/keycloak.sh | 1 + ct/lidarr.sh | 1 + ct/magicmirror.sh | 1 + ct/mariadb.sh | 1 + ct/meshcentral.sh | 1 + ct/motioneye.sh | 1 + ct/mqtt.sh | 1 + ct/n8n.sh | 1 + ct/navidrome.sh | 1 + ct/nextcloudpi.sh | 1 + ct/nginxproxymanager.sh | 1 + ct/nocodb.sh | 1 + ct/node-red.sh | 1 + ct/omada.sh | 1 + ct/omv.sh | 1 + ct/openhab.sh | 1 + ct/paperless-ngx.sh | 1 + ct/photoprism.sh | 1 + ct/pihole.sh | 1 + ct/plex.sh | 1 + ct/podman-homeassistant.sh | 1 + ct/podman.sh | 1 + ct/postgresql.sh | 1 + ct/prometheus.sh | 1 + ct/prowlarr.sh | 1 + ct/qbittorrent.sh | 1 + ct/radarr.sh | 1 + ct/readarr.sh | 1 + ct/rockylinux.sh | 1 + ct/rstptoweb.sh | 1 + ct/sabnzbd.sh | 1 + ct/scrypted.sh | 1 + ct/shinobi.sh | 1 + ct/sonarr.sh | 1 + ct/syncthing.sh | 1 + ct/tdarr.sh | 1 + ct/technitiumdns.sh | 1 + ct/transmission.sh | 1 + ct/trilium.sh | 1 + ct/ubuntu.sh | 1 + ct/umbrel.sh | 1 + ct/unifi.sh | 1 + ct/uptimekuma.sh | 1 + ct/vaultwarden.sh | 1 + ct/whisparr.sh | 1 + ct/whoogle.sh | 1 + ct/wikijs.sh | 1 + ct/wireguard.sh | 1 + ct/yunohost.sh | 1 + ct/zigbee2mqtt.sh | 1 + ct/zwave-js-ui.sh | 1 + vm/haos-vm.sh | 3 ++- 92 files changed, 93 insertions(+), 1 deletion(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index e8c65085..c36e12bf 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -78,6 +78,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 248aa7f2..5dd9e955 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -81,6 +81,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index a7b08ba6..8bde63ce 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -75,6 +75,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 7cb26ae6..36872876 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -88,6 +88,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 45ea5390..70b5f7f8 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -81,6 +81,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh index b2e2eaa7..7dbf5066 100644 --- a/ct/alpine-whoogle.sh +++ b/ct/alpine-whoogle.sh @@ -79,6 +79,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 55df4544..f9185143 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -75,6 +75,7 @@ function update_script() { done } +ssh_check start build_container description diff --git a/ct/alpine.sh b/ct/alpine.sh index a3348a9f..3eb6a0c9 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -63,6 +63,7 @@ exit; fi } +ssh_check start build_container description diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 558dbc44..b208249c 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 3261b560..91e8a8be 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -71,6 +71,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/blocky.sh b/ct/blocky.sh index 08e769e8..4a2f77b2 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/casaos.sh b/ct/casaos.sh index c98a025d..593379c8 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/changedetection.sh b/ct/changedetection.sh index c8da20ae..d0ba97e8 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 53702989..3f812270 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -100,6 +100,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index d13e5b40..7f6ed79f 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/dashy.sh b/ct/dashy.sh index 5c76cf70..7b95c492 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -86,6 +86,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/debian.sh b/ct/debian.sh index b67a0a26..dc09cba4 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/deconz.sh b/ct/deconz.sh index 6195bd10..f5aee5fc 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/deluge.sh b/ct/deluge.sh index 0b3ce6c4..b82cebce 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -61,6 +61,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/devuan.sh b/ct/devuan.sh index db48bf4e..beb4b23d 100644 --- a/ct/devuan.sh +++ b/ct/devuan.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/docker.sh b/ct/docker.sh index 1805787c..77b9c184 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/emby.sh b/ct/emby.sh index 2e617cfb..d87c1aae 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -71,6 +71,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/emqx.sh b/ct/emqx.sh index 7c0ffcd9..e3ce0056 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/esphome.sh b/ct/esphome.sh index cd6e56d2..82c0c6c8 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -68,6 +68,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 58b82f5c..b840dc30 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -61,6 +61,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/grafana.sh b/ct/grafana.sh index 3de34626..4a363954 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/grocy.sh b/ct/grocy.sh index dd30c554..f33b8a87 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index aad87f46..6eeaf236 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -140,6 +140,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 858433c2..b635db1d 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -207,6 +207,7 @@ EOF fi } +ssh_check start build_container description diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index ac667247..7c96ab1c 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -128,6 +128,7 @@ WantedBy=default.target" >$service_path fi } +ssh_check start build_container description diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 22039d22..8b67fdb1 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/homepage.sh b/ct/homepage.sh index e8041087..87bc8cc1 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -67,6 +67,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/homer.sh b/ct/homer.sh index 217b2800..05939da2 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -84,6 +84,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 92535765..0021c3be 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/influxdb.sh b/ct/influxdb.sh index f6c078cf..8b6c3150 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 841f135e..17dcd29d 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/jackett.sh b/ct/jackett.sh index f895f4d7..2c6eff8d 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index d11b8212..a67c5967 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/k0s.sh b/ct/k0s.sh index 75b5648a..5f39de39 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/kavita.sh b/ct/kavita.sh index 8410daa7..f0ebf4cc 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 4488dd1a..2585d900 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/lidarr.sh b/ct/lidarr.sh index 6bc88997..c4959153 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index c57121c2..aeda1e47 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -63,6 +63,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/mariadb.sh b/ct/mariadb.sh index d6894ed9..857fabbb 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 2739b517..932ea4bd 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 4a106f03..b5084568 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 0dde1c0e..312c467d 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/n8n.sh b/ct/n8n.sh index d4862ef1..297c9eed 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/navidrome.sh b/ct/navidrome.sh index c9e53584..0ebb3d38 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -71,6 +71,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index a1718208..52f04f49 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index ce7fc32f..012ebd53 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -171,6 +171,7 @@ EOF exit } +ssh_check start build_container description diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 4b7636f6..e56521ba 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -63,6 +63,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/node-red.sh b/ct/node-red.sh index 3dba9183..c90d898c 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -96,6 +96,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/omada.sh b/ct/omada.sh index 104183df..51127d43 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/omv.sh b/ct/omv.sh index 532df042..c898c92e 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/openhab.sh b/ct/openhab.sh index 21a77dc7..d197aec1 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 09d46d45..30b1d9f9 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -132,6 +132,7 @@ EOF fi } +ssh_check start build_container description diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 231f7d1e..c6c943bd 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -86,6 +86,7 @@ function update_script() { exit } +ssh_check start build_container description diff --git a/ct/pihole.sh b/ct/pihole.sh index 07e786ea..57f09f15 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/plex.sh b/ct/plex.sh index 48d12505..beb328e7 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -71,6 +71,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index d916cc95..e3ccf4d7 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -111,6 +111,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/podman.sh b/ct/podman.sh index b4297c51..c18a858a 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/postgresql.sh b/ct/postgresql.sh index f0b606a1..606ee95d 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 16f17758..bfbf2367 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index 2c323541..cb5c5347 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 83cc8526..499cfcf3 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -61,6 +61,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/radarr.sh b/ct/radarr.sh index a379e8ac..df6704a8 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/readarr.sh b/ct/readarr.sh index bea527d0..40e2ac20 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index edc69291..715a4a5f 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/rstptoweb.sh b/ct/rstptoweb.sh index 1c1bb453..c7db7f59 100644 --- a/ct/rstptoweb.sh +++ b/ct/rstptoweb.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index ea75032d..8514ba30 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -66,6 +66,7 @@ msg_ok "Updated $APP" exit } +ssh_check start build_container description diff --git a/ct/scrypted.sh b/ct/scrypted.sh index d307d78c..eadc2f0f 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/shinobi.sh b/ct/shinobi.sh index bc5572e6..b8b003bf 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -64,6 +64,7 @@ msg_ok "Updated Shinobi LXC" exit } +ssh_check start build_container description diff --git a/ct/sonarr.sh b/ct/sonarr.sh index ac6f2399..48a249e5 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/syncthing.sh b/ct/syncthing.sh index 292cf4db..f6b3d67c 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -62,6 +62,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 994ae3db..1d570df8 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index f947cd07..ca568c91 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -70,6 +70,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/transmission.sh b/ct/transmission.sh index 94e654d6..cb0f21d8 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/trilium.sh b/ct/trilium.sh index 3e15c458..1288b82a 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -80,6 +80,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index bc2f0cc6..c30b4067 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 46ed1aa2..d35b3ac1 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -60,6 +60,7 @@ msg_ok "Updated ${APP} LXC" exit } +ssh_check start build_container description diff --git a/ct/unifi.sh b/ct/unifi.sh index 542f1f87..bd619787 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -61,6 +61,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 4f64ecc3..77b81ecc 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -78,6 +78,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 8f887956..e5373967 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -131,6 +131,7 @@ function update_script() { fi } +ssh_check start build_container description diff --git a/ct/whisparr.sh b/ct/whisparr.sh index c616282a..2a99863f 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -61,6 +61,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/whoogle.sh b/ct/whoogle.sh index e93b19d7..67ecf793 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -60,6 +60,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/wikijs.sh b/ct/wikijs.sh index e1ac9863..a8051de0 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -83,6 +83,7 @@ msg_ok "Update Successfull" exit } +ssh_check start build_container description diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 553de4e5..4afea4d0 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -115,6 +115,7 @@ exit fi } +ssh_check start build_container description diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 22198999..6ffda45d 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -60,6 +60,7 @@ msg_ok "Updated $APP LXC" exit } +ssh_check start build_container description diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index c1c59ff0..a91c9ec4 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -126,6 +126,7 @@ function update_script() { exit } +ssh_check start build_container description diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index ed8c0d64..2dfcaaa5 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -78,6 +78,7 @@ function update_script() { exit } +ssh_check start build_container description diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index aa19d7b9..ab628f89 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -97,7 +97,7 @@ function ARCH_CHECK() { } function SSH_CHECK() { if command -v pveversion >/dev/null 2>&1; then - if [ -n "$SSH_CLIENT" ]; then + if [ -n "${SSH_CLIENT:+x}" ]; then if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then echo "you've been warned" else @@ -269,6 +269,7 @@ function START_SCRIPT() { } ARCH_CHECK PVE_CHECK +SSH_CHECK START_SCRIPT msg_info "Validating Storage" while read -r line; do From 0cc475115a286ab7d5c75a2c03952830c10a1a52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Mar 2023 21:44:58 -0400 Subject: [PATCH 4576/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1463c0d3..dd74f685 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Removed Alpine-ESPHome LXC** - Nonoperational +- **All Scripts** + - Incorporate code that examines whether SSH is being used and, if yes, offers a suggestion against it without restricting or blocking its usage. ## 2023-03-25 From b800e3485683fa3b5335a4a4fc9dfbd24f293b68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 Mar 2023 17:32:30 -0400 Subject: [PATCH 4577/6505] Update blocky-install.sh fix path change --- install/blocky-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/blocky-install.sh b/install/blocky-install.sh index e4656a13..aafff542 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -23,10 +23,10 @@ msg_info "Installing Blocky" systemctl stop systemd-resolved $STD systemctl disable systemd-resolved.service RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz +wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_v${RELEASE}_Linux_x86_64.tar.gz mkdir -p /opt/blocky -tar -xf blocky_${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky -rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz +tar -xf blocky_v${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky +rm -rf blocky_v${RELEASE}_Linux_x86_64.tar.gz cat </opt/blocky/config.yml upstream: # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query From 5b414def47ef8bdc1653e8922c9790d82cd57c1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Mar 2023 06:14:21 -0400 Subject: [PATCH 4578/6505] Update nginxproxymanager-install.sh fix for v2.10.1 --- install/nginxproxymanager-install.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index bda3670c..5e920bbb 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -66,10 +66,10 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v2.9.22" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz -cd ./nginx-proxy-manager-2.9.22 -msg_ok "Downloaded Nginx Proxy Manager v2.9.22" +msg_info "Downloading Nginx Proxy Manager v${RELEASE}" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz +cd ./nginx-proxy-manager-${RELEASE} +msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python @@ -77,8 +77,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+2.9.22+g" backend/package.json -sed -i "s+0.0.0+2.9.22+g" frontend/package.json +sed -i "s+0.0.0+${RELEASE}+g" backend/package.json +sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") @@ -181,6 +181,7 @@ motd_ssh root msg_info "Starting Services" +sed -i 's/^pid/#pid/' /usr/local/openresty/nginx/conf/nginx.conf $STD systemctl enable --now openresty $STD systemctl enable --now npm msg_ok "Started Services" From 420492341f4e0ce49683693804cbe33a60929308 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Mar 2023 06:14:49 -0400 Subject: [PATCH 4579/6505] Update nginxproxymanager.sh fix update for v2.10.1 --- ct/nginxproxymanager.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 012ebd53..7e7fafd2 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -158,6 +158,7 @@ EOF msg_ok "Initialized Backend" msg_info "Starting Services" + sed -i 's/^pid/#pid/' /usr/local/openresty/nginx/conf/nginx.conf systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm From 46836f0583045f4f10f77ec979e18861ae7b9186 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Mar 2023 06:17:21 -0400 Subject: [PATCH 4580/6505] Update nginxproxymanager.sh download latest --- ct/nginxproxymanager.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 7e7fafd2..c17e3c53 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -74,18 +74,18 @@ function update_script() { /var/cache/nginx &>/dev/null msg_ok "Cleaned Old Files" - msg_info "Downloading NPM v2.9.22" - wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz &>/dev/null - cd nginx-proxy-manager-2.9.22 - msg_ok "Downloaded NPM v2.9.22" + msg_info "Downloading NPM v${RELEASE}" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null + cd nginx-proxy-manager-${RELEASE} + msg_ok "Downloaded NPM v${RELEASE}" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx - sed -i "s+0.0.0+2.9.22+g" backend/package.json - sed -i "s+0.0.0+2.9.22+g" frontend/package.json + sed -i "s+0.0.0+${RELEASE}+g" backend/package.json + sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do From d0528d4913272b81d23baca1ad35044f3f48d4fb Mon Sep 17 00:00:00 2001 From: Jimi Ford Date: Wed, 29 Mar 2023 18:21:05 -0400 Subject: [PATCH 4581/6505] Update CONTRIBUTING.md (#1272) --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 2f938e25..bc95960c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,4 +2,4 @@ Everybody is invited and welcome to contribute to Proxmox Helper Scripts. -- Pull requests are always created against the [**pull-requests**](https://github.com/tteck/Proxmox/tree/pull-requests) branch. +- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if I reject your request. If you follow the patterns that have been established throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main) :partying_face:! From 651b81c7e27aebe509abe306bc6d7e7a66257d1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Mar 2023 18:41:02 -0400 Subject: [PATCH 4582/6505] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index acdc8c2d..74a9f44a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +

    Contributing to Proxmox Helper Scripts

    + These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup provides additional options such as container type, root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine.

    Proxmox Helper Scripts

    From 12a51913390165aa34b6a374661d79ddf91bf5a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Mar 2023 18:45:27 -0400 Subject: [PATCH 4583/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 74a9f44a..3e093c9a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Contributing to Proxmox Helper Scripts

    -These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup provides additional options such as container type, root password, hostname, disk size, core count, RAM size, network settings, and others. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine. +These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while The advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine.

    Proxmox Helper Scripts

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    From 5f8c6ecdf85b1b1686cd7c538440fbbdb852686a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Mar 2023 18:46:33 -0400 Subject: [PATCH 4584/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e093c9a..a94517d8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Contributing to Proxmox Helper Scripts

    -These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while The advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine. +These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine.

    Proxmox Helper Scripts

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    From 8d5e6aedd4d6a721d76af260c824d1b4198172b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Mar 2023 05:09:03 -0400 Subject: [PATCH 4585/6505] Update homepage-install.sh Change the installation method from using git to using releases. --- install/homepage-install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 4ebc685e..157352c0 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y git msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" @@ -30,7 +29,12 @@ $STD npm install -g pnpm msg_ok "Installed Node.js" msg_info "Installing Homepage (Patience)" -$STD git clone https://github.com/benphelps/homepage.git /opt/homepage +RELEASE=$(curl -s https://api.github.com/repos/benphelps/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q https://github.com/benphelps/homepage/archive/refs/tags/v${RELEASE}.tar.gz +$STD tar -xvf v${RELEASE}.tar.gz +mkdir -p /opt/homepage +cp -r homepage-${RELEASE}/* /opt/homepage +rm -rf v${RELEASE}.tar.gz homepage-${RELEASE} cd /opt/homepage mkdir -p config cp /opt/homepage/src/skeleton/* /opt/homepage/config From a243d8ef260f97fb14f0344f8c7245ababe52cd9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Mar 2023 05:17:16 -0400 Subject: [PATCH 4586/6505] Update homepage-install.sh add back git for update --- install/homepage-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 157352c0..3800244f 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y git msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" From 3b2c81cf1c21fa6d811e3f23a9f116b61c8520fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Mar 2023 07:02:00 -0400 Subject: [PATCH 4587/6505] Optimizing code --- ct/adguard.sh | 1 - ct/alpine-adguard.sh | 1 - ct/alpine-docker.sh | 1 - ct/alpine-grafana.sh | 1 - ct/alpine-vaultwarden.sh | 1 - ct/alpine-whoogle.sh | 1 - ct/alpine-zigbee2mqtt.sh | 1 - ct/alpine.sh | 1 - ct/audiobookshelf.sh | 1 - ct/autobrr.sh | 1 - ct/blocky.sh | 1 - ct/casaos.sh | 1 - ct/changedetection.sh | 1 - ct/cronicle.sh | 1 - ct/daemonsync.sh | 1 - ct/dashy.sh | 1 - ct/debian.sh | 1 - ct/deconz.sh | 1 - ct/deluge.sh | 1 - ct/devuan.sh | 1 - ct/docker.sh | 1 - ct/emby.sh | 1 - ct/emqx.sh | 1 - ct/esphome.sh | 1 - ct/go2rtc.sh | 1 - ct/grafana.sh | 1 - ct/grocy.sh | 1 - ct/heimdalldashboard.sh | 1 - ct/homeassistant-core.sh | 1 - ct/homeassistant.sh | 1 - ct/homebridge.sh | 1 - ct/homepage.sh | 1 - ct/homer.sh | 1 - ct/hyperion.sh | 1 - ct/influxdb.sh | 1 - ct/iobroker.sh | 1 - ct/jackett.sh | 1 - ct/jellyfin.sh | 1 - ct/k0s.sh | 1 - ct/kavita.sh | 1 - ct/keycloak.sh | 1 - ct/lidarr.sh | 1 - ct/magicmirror.sh | 1 - ct/mariadb.sh | 1 - ct/meshcentral.sh | 1 - ct/motioneye.sh | 1 - ct/mqtt.sh | 1 - ct/n8n.sh | 1 - ct/navidrome.sh | 1 - ct/nextcloudpi.sh | 1 - ct/nginxproxymanager.sh | 1 - ct/nocodb.sh | 1 - ct/node-red.sh | 1 - ct/omada.sh | 1 - ct/omv.sh | 1 - ct/openhab.sh | 1 - ct/paperless-ngx.sh | 1 - ct/photoprism.sh | 1 - ct/pihole.sh | 1 - ct/plex.sh | 1 - ct/podman-homeassistant.sh | 1 - ct/podman.sh | 1 - ct/postgresql.sh | 1 - ct/prometheus.sh | 1 - ct/prowlarr.sh | 1 - ct/qbittorrent.sh | 1 - ct/radarr.sh | 1 - ct/readarr.sh | 1 - ct/rockylinux.sh | 1 - ct/rstptoweb.sh | 1 - ct/sabnzbd.sh | 1 - ct/scrypted.sh | 1 - ct/shinobi.sh | 1 - ct/sonarr.sh | 1 - ct/syncthing.sh | 1 - ct/tdarr.sh | 1 - ct/technitiumdns.sh | 1 - ct/transmission.sh | 1 - ct/trilium.sh | 1 - ct/ubuntu.sh | 1 - ct/umbrel.sh | 1 - ct/unifi.sh | 1 - ct/uptimekuma.sh | 1 - ct/vaultwarden.sh | 1 - ct/whisparr.sh | 1 - ct/whoogle.sh | 1 - ct/wikijs.sh | 1 - ct/wireguard.sh | 1 - ct/yunohost.sh | 1 - ct/zigbee2mqtt.sh | 1 - ct/zwave-js-ui.sh | 1 - misc/build.func | 1 + 92 files changed, 1 insertion(+), 91 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index c36e12bf..e8c65085 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -78,7 +78,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 5dd9e955..248aa7f2 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -81,7 +81,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 8bde63ce..a7b08ba6 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -75,7 +75,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 36872876..7cb26ae6 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -88,7 +88,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 70b5f7f8..45ea5390 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -81,7 +81,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh index 7dbf5066..b2e2eaa7 100644 --- a/ct/alpine-whoogle.sh +++ b/ct/alpine-whoogle.sh @@ -79,7 +79,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index f9185143..55df4544 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -75,7 +75,6 @@ function update_script() { done } -ssh_check start build_container description diff --git a/ct/alpine.sh b/ct/alpine.sh index 3eb6a0c9..a3348a9f 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -63,7 +63,6 @@ exit; fi } -ssh_check start build_container description diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index b208249c..558dbc44 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 91e8a8be..3261b560 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -71,7 +71,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/blocky.sh b/ct/blocky.sh index 4a2f77b2..08e769e8 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/casaos.sh b/ct/casaos.sh index 593379c8..c98a025d 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/changedetection.sh b/ct/changedetection.sh index d0ba97e8..c8da20ae 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 3f812270..53702989 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -100,7 +100,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index 7f6ed79f..d13e5b40 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/dashy.sh b/ct/dashy.sh index 7b95c492..5c76cf70 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -86,7 +86,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/debian.sh b/ct/debian.sh index dc09cba4..b67a0a26 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/deconz.sh b/ct/deconz.sh index f5aee5fc..6195bd10 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/deluge.sh b/ct/deluge.sh index b82cebce..0b3ce6c4 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -61,7 +61,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/devuan.sh b/ct/devuan.sh index beb4b23d..db48bf4e 100644 --- a/ct/devuan.sh +++ b/ct/devuan.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/docker.sh b/ct/docker.sh index 77b9c184..1805787c 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/emby.sh b/ct/emby.sh index d87c1aae..2e617cfb 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -71,7 +71,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/emqx.sh b/ct/emqx.sh index e3ce0056..7c0ffcd9 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/esphome.sh b/ct/esphome.sh index 82c0c6c8..cd6e56d2 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -68,7 +68,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index b840dc30..58b82f5c 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -61,7 +61,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/grafana.sh b/ct/grafana.sh index 4a363954..3de34626 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/grocy.sh b/ct/grocy.sh index f33b8a87..dd30c554 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 6eeaf236..aad87f46 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -140,7 +140,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index b635db1d..858433c2 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -207,7 +207,6 @@ EOF fi } -ssh_check start build_container description diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 7c96ab1c..ac667247 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -128,7 +128,6 @@ WantedBy=default.target" >$service_path fi } -ssh_check start build_container description diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 8b67fdb1..22039d22 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/homepage.sh b/ct/homepage.sh index 87bc8cc1..e8041087 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -67,7 +67,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/homer.sh b/ct/homer.sh index 05939da2..217b2800 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -84,7 +84,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 0021c3be..92535765 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 8b6c3150..f6c078cf 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 17dcd29d..841f135e 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/jackett.sh b/ct/jackett.sh index 2c6eff8d..f895f4d7 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index a67c5967..d11b8212 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/k0s.sh b/ct/k0s.sh index 5f39de39..75b5648a 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/kavita.sh b/ct/kavita.sh index f0ebf4cc..8410daa7 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 2585d900..4488dd1a 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/lidarr.sh b/ct/lidarr.sh index c4959153..6bc88997 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index aeda1e47..c57121c2 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -63,7 +63,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 857fabbb..d6894ed9 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 932ea4bd..2739b517 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/motioneye.sh b/ct/motioneye.sh index b5084568..4a106f03 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 312c467d..0dde1c0e 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/n8n.sh b/ct/n8n.sh index 297c9eed..d4862ef1 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/navidrome.sh b/ct/navidrome.sh index 0ebb3d38..c9e53584 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -71,7 +71,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index 52f04f49..a1718208 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index c17e3c53..e8c5be3a 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -172,7 +172,6 @@ EOF exit } -ssh_check start build_container description diff --git a/ct/nocodb.sh b/ct/nocodb.sh index e56521ba..4b7636f6 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -63,7 +63,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/node-red.sh b/ct/node-red.sh index c90d898c..3dba9183 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -96,7 +96,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/omada.sh b/ct/omada.sh index 51127d43..104183df 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/omv.sh b/ct/omv.sh index c898c92e..532df042 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/openhab.sh b/ct/openhab.sh index d197aec1..21a77dc7 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 30b1d9f9..09d46d45 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -132,7 +132,6 @@ EOF fi } -ssh_check start build_container description diff --git a/ct/photoprism.sh b/ct/photoprism.sh index c6c943bd..231f7d1e 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -86,7 +86,6 @@ function update_script() { exit } -ssh_check start build_container description diff --git a/ct/pihole.sh b/ct/pihole.sh index 57f09f15..07e786ea 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/plex.sh b/ct/plex.sh index beb328e7..48d12505 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -71,7 +71,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index e3ccf4d7..d916cc95 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -111,7 +111,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/podman.sh b/ct/podman.sh index c18a858a..b4297c51 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 606ee95d..f0b606a1 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/prometheus.sh b/ct/prometheus.sh index bfbf2367..16f17758 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index cb5c5347..2c323541 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 499cfcf3..83cc8526 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -61,7 +61,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/radarr.sh b/ct/radarr.sh index df6704a8..a379e8ac 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/readarr.sh b/ct/readarr.sh index 40e2ac20..bea527d0 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index 715a4a5f..edc69291 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/rstptoweb.sh b/ct/rstptoweb.sh index c7db7f59..1c1bb453 100644 --- a/ct/rstptoweb.sh +++ b/ct/rstptoweb.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index 8514ba30..ea75032d 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -66,7 +66,6 @@ msg_ok "Updated $APP" exit } -ssh_check start build_container description diff --git a/ct/scrypted.sh b/ct/scrypted.sh index eadc2f0f..d307d78c 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/shinobi.sh b/ct/shinobi.sh index b8b003bf..bc5572e6 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -64,7 +64,6 @@ msg_ok "Updated Shinobi LXC" exit } -ssh_check start build_container description diff --git a/ct/sonarr.sh b/ct/sonarr.sh index 48a249e5..ac6f2399 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/syncthing.sh b/ct/syncthing.sh index f6b3d67c..292cf4db 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -62,7 +62,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 1d570df8..994ae3db 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index ca568c91..f947cd07 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -70,7 +70,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/transmission.sh b/ct/transmission.sh index cb0f21d8..94e654d6 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/trilium.sh b/ct/trilium.sh index 1288b82a..3e15c458 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -80,7 +80,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index c30b4067..bc2f0cc6 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/umbrel.sh b/ct/umbrel.sh index d35b3ac1..46ed1aa2 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -60,7 +60,6 @@ msg_ok "Updated ${APP} LXC" exit } -ssh_check start build_container description diff --git a/ct/unifi.sh b/ct/unifi.sh index bd619787..542f1f87 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -61,7 +61,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 77b81ecc..4f64ecc3 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -78,7 +78,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index e5373967..8f887956 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -131,7 +131,6 @@ function update_script() { fi } -ssh_check start build_container description diff --git a/ct/whisparr.sh b/ct/whisparr.sh index 2a99863f..c616282a 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -61,7 +61,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/whoogle.sh b/ct/whoogle.sh index 67ecf793..e93b19d7 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -60,7 +60,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/wikijs.sh b/ct/wikijs.sh index a8051de0..e1ac9863 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -83,7 +83,6 @@ msg_ok "Update Successfull" exit } -ssh_check start build_container description diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 4afea4d0..553de4e5 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -115,7 +115,6 @@ exit fi } -ssh_check start build_container description diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 6ffda45d..22198999 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -60,7 +60,6 @@ msg_ok "Updated $APP LXC" exit } -ssh_check start build_container description diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index a91c9ec4..c1c59ff0 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -126,7 +126,6 @@ function update_script() { exit } -ssh_check start build_container description diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 2dfcaaa5..ed8c0d64 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -78,7 +78,6 @@ function update_script() { exit } -ssh_check start build_container description diff --git a/misc/build.func b/misc/build.func index a6e7e0e3..43dd3fbe 100644 --- a/misc/build.func +++ b/misc/build.func @@ -342,6 +342,7 @@ advanced_settings() { } install_script() { + ssh_check arch_check pve_check NEXTID=$(pvesh get /cluster/nextid) From ca8ed4f5cb78eced991f4ec0e27d7a4a8b96581d Mon Sep 17 00:00:00 2001 From: LordXaosa Date: Fri, 31 Mar 2023 00:37:54 +0300 Subject: [PATCH 4588/6505] Fix missing methods (#1275) Some Heimdall apps uses method simplexml_load_string() which depends on php-xml package. Since Heimdall uses php 7.4 I added such dependency. --- install/heimdalldashboard-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index 8e83e9ef..a26b67ea 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -23,6 +23,7 @@ msg_info "Installing PHP" $STD apt-get install -y php $STD apt-get install -y php-sqlite3 $STD apt-get install -y php-zip +$STD apt-get install -y php7.4-xml msg_ok "Installed PHP" RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') From 645f0ab431f2a7694f75120e38c90daee3e9aafd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Mar 2023 23:25:02 -0400 Subject: [PATCH 4589/6505] Update heimdalldashboard-install.sh By default, Debian 11 (Bullseye) includes PHP version 7.4 --- install/heimdalldashboard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index a26b67ea..df8e7cc2 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -23,7 +23,7 @@ msg_info "Installing PHP" $STD apt-get install -y php $STD apt-get install -y php-sqlite3 $STD apt-get install -y php-zip -$STD apt-get install -y php7.4-xml +$STD apt-get install -y php-xml msg_ok "Installed PHP" RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') From 4ca034ed11449001f2ff445c0855100438715aa8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 00:57:43 -0400 Subject: [PATCH 4590/6505] Update nginxproxymanager.sh prep for v2.10.2 --- ct/nginxproxymanager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index e8c5be3a..1b9c33f6 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -158,7 +158,7 @@ EOF msg_ok "Initialized Backend" msg_info "Starting Services" - sed -i 's/^pid/#pid/' /usr/local/openresty/nginx/conf/nginx.conf + sed -i -e 's/^pid/#pid/' -e 's/^user/#user/' /usr/local/openresty/nginx/conf/nginx.conf systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm From 1088e52b615caa366ddf6dade3fdbba691f0fb68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 00:58:44 -0400 Subject: [PATCH 4591/6505] Update nginxproxymanager-install.sh prep for v2.10.2 --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 5e920bbb..1108198d 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -181,7 +181,7 @@ motd_ssh root msg_info "Starting Services" -sed -i 's/^pid/#pid/' /usr/local/openresty/nginx/conf/nginx.conf +sed -i -e 's/^pid/#pid/' -e 's/^user/#user/' /usr/local/openresty/nginx/conf/nginx.conf $STD systemctl enable --now openresty $STD systemctl enable --now npm msg_ok "Started Services" From 59bfc8d3e3fa2dc77f2c1f52957e2a666389ada0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 17:26:56 -0400 Subject: [PATCH 4592/6505] Update haos-vm.sh Include a choice within the "Advanced" settings to configure the disk cache. --- vm/haos-vm.sh | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index ab628f89..8f3c244b 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -112,6 +112,7 @@ function default_settings() { VMID="$NEXTID" FORMAT=",efitype=4m" MACHINE="" + DISK_CACHE="" HN="haos$stable" CORE_COUNT="2" RAM_SIZE="4096" @@ -123,6 +124,7 @@ function default_settings() { echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}Default${CL}" echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" @@ -141,6 +143,7 @@ function advanced_settings() { 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi + while true; do VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? @@ -173,6 +176,20 @@ function advanced_settings() { FORMAT=",efitype=4m" MACHINE="" fi + + DISK_CACHE1=$(whiptail --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "Default" ON \ + "1" "Write Through" OFF \ + 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $DISK_CACHE1 = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}Default${CL}" + DISK_CACHE="" + fi + VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $VM_NAME ]; then @@ -184,6 +201,7 @@ function advanced_settings() { echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" fi fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $CORE_COUNT ]; then @@ -192,6 +210,7 @@ function advanced_settings() { else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $RAM_SIZE ]; then @@ -200,6 +219,7 @@ function advanced_settings() { else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi fi + BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then @@ -208,6 +228,7 @@ function advanced_settings() { else if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi fi + MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $MAC1 ]; then @@ -219,6 +240,7 @@ function advanced_settings() { echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi + VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -230,6 +252,7 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then @@ -241,6 +264,7 @@ function advanced_settings() { echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi fi + if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" @@ -248,6 +272,7 @@ function advanced_settings() { echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" else @@ -342,7 +367,7 @@ pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ - -scsi0 ${DISK1_REF},${THIN}size=32G \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=32G \ -boot order=scsi0 \ -description "# Home Assistant OS ### https://github.com/tteck/Proxmox From 324a485930d8a2e292f9a224ccce34ad331a6653 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 17:30:53 -0400 Subject: [PATCH 4593/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index dd74f685..b577dfc1 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-03-31 + +### Changed + +- **Home Assistant OS VM** + - Include a choice within the "Advanced" settings to configure the disk cache. + ## 2023-03-27 ### Changed From daa1720d85e5288c4b279fc4eaccd31f2b06e75a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 18:02:24 -0400 Subject: [PATCH 4594/6505] Update nginxproxymanager-install.sh --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 1108198d..e3eb7d8b 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -40,7 +40,7 @@ $STD python3 -m venv /opt/certbot/ if [ "$(getconf LONG_BIT)" = "32" ]; then $STD python3 -m pip install --no-cache-dir -U cryptography==3.3.2 fi -$STD python3 -m pip install --no-cache-dir cffi certbot +$STD python3 -m pip install --no-cache-dir cffi certbot certbot-dns-cloudflare msg_ok "Installed Python" msg_info "Installing Openresty" From 1f17d282a611670e767f166f746e76bb3fccba0e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 18:04:25 -0400 Subject: [PATCH 4595/6505] Update nginxproxymanager.sh --- ct/nginxproxymanager.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 1b9c33f6..cb447ad2 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -124,6 +124,7 @@ function update_script() { mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global + python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null msg_ok "Setup Enviroment" msg_info "Building Frontend" From d8ed7b5060033ce3a9653d4961181e10534f2ac3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 20:02:47 -0400 Subject: [PATCH 4596/6505] Update nginxproxymanager-install.sh lock script to version 2.9.22 --- install/nginxproxymanager-install.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index e3eb7d8b..bda3670c 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -40,7 +40,7 @@ $STD python3 -m venv /opt/certbot/ if [ "$(getconf LONG_BIT)" = "32" ]; then $STD python3 -m pip install --no-cache-dir -U cryptography==3.3.2 fi -$STD python3 -m pip install --no-cache-dir cffi certbot certbot-dns-cloudflare +$STD python3 -m pip install --no-cache-dir cffi certbot msg_ok "Installed Python" msg_info "Installing Openresty" @@ -66,10 +66,10 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v${RELEASE}" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz -cd ./nginx-proxy-manager-${RELEASE} -msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" +msg_info "Downloading Nginx Proxy Manager v2.9.22" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz +cd ./nginx-proxy-manager-2.9.22 +msg_ok "Downloaded Nginx Proxy Manager v2.9.22" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python @@ -77,8 +77,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+${RELEASE}+g" backend/package.json -sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json +sed -i "s+0.0.0+2.9.22+g" backend/package.json +sed -i "s+0.0.0+2.9.22+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") @@ -181,7 +181,6 @@ motd_ssh root msg_info "Starting Services" -sed -i -e 's/^pid/#pid/' -e 's/^user/#user/' /usr/local/openresty/nginx/conf/nginx.conf $STD systemctl enable --now openresty $STD systemctl enable --now npm msg_ok "Started Services" From 5826ee33b36c82bd91ac5dda1f18d04294532038 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 Mar 2023 20:04:57 -0400 Subject: [PATCH 4597/6505] Update nginxproxymanager.sh lock script version to 2.9.22 --- ct/nginxproxymanager.sh | 310 +++++++++++++++++++++------------------- 1 file changed, 160 insertions(+), 150 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index cb447ad2..bda3670c 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -1,145 +1,144 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) + # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -function header_info { - clear - cat <<"EOF" - _ __ _ ____ __ ___ - / | / /___ _(_)___ _ __ / __ \_________ __ ____ __ / |/ /___ _____ ____ _____ ____ _____ - / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ - / /| / /_/ / / / / /> < / ____/ / / /_/ /> /dev/null - msg_ok "Cleaned Old Files" +msg_info "Installing Openresty" +$STD apt-key add <(curl -fsSL https://openresty.org/package/pubkey.gpg) +sh -c 'echo "deb http://openresty.org/package/debian $(lsb_release -cs) openresty" > /etc/apt/sources.list.d/openresty.list' +$STD apt-get -y update +$STD apt-get -y install --no-install-recommends openresty +msg_ok "Installed Openresty" - msg_info "Downloading NPM v${RELEASE}" - wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null - cd nginx-proxy-manager-${RELEASE} - msg_ok "Downloaded NPM v${RELEASE}" +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" - msg_info "Setting up Enviroment" - ln -sf /usr/bin/python3 /usr/bin/python - ln -sf /usr/bin/certbot /opt/certbot/bin/certbot - ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx - ln -sf /usr/local/openresty/nginx/ /etc/nginx - sed -i "s+0.0.0+${RELEASE}+g" backend/package.json - sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json - sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf - NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") - for NGINX_CONF in $NGINX_CONFS; do - sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" - done - mkdir -p /var/www/html /etc/nginx/logs - cp -r docker/rootfs/var/www/html/* /var/www/html/ - cp -r docker/rootfs/etc/nginx/* /etc/nginx/ - cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini - cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager - ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf - rm -f /etc/nginx/conf.d/dev.conf - mkdir -p /tmp/nginx/body \ - /run/nginx \ - /data/nginx \ - /data/custom_ssl \ - /data/logs \ - /data/access \ - /data/nginx/default_host \ - /data/nginx/default_www \ - /data/nginx/proxy_host \ - /data/nginx/redirection_host \ - /data/nginx/stream \ - /data/nginx/dead_host \ - /data/nginx/temp \ - /var/lib/nginx/cache/public \ - /var/lib/nginx/cache/private \ - /var/cache/nginx/proxy_temp - chmod -R 777 /var/cache/nginx - chown root /tmp/nginx - echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf - if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null - fi - mkdir -p /app/global /app/frontend/images - cp -r backend/* /app - cp -r global/* /app/global - python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null - msg_ok "Setup Enviroment" +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" - msg_info "Building Frontend" - cd ./frontend - export NODE_ENV=development - yarn install --network-timeout=30000 &>/dev/null - yarn build &>/dev/null - cp -r dist/* /app/frontend - cp -r app-images/* /app/frontend/images - msg_ok "Built Frontend" +msg_info "Installing Yarn" +$STD npm install --global yarn +msg_ok "Installed Yarn" - msg_info "Initializing Backend" - rm -rf /app/config/default.json &>/dev/null - if [ ! -f /app/config/production.json ]; then - cat <<'EOF' >/app/config/production.json +RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | + grep "tag_name" | + awk '{print substr($2, 3, length($2)-4) }') + +msg_info "Downloading Nginx Proxy Manager v2.9.22" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz +cd ./nginx-proxy-manager-2.9.22 +msg_ok "Downloaded Nginx Proxy Manager v2.9.22" + +msg_info "Setting up Enviroment" +ln -sf /usr/bin/python3 /usr/bin/python +ln -sf /usr/bin/certbot /opt/certbot/bin/certbot +ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx +ln -sf /usr/local/openresty/nginx/ /etc/nginx + +sed -i "s+0.0.0+2.9.22+g" backend/package.json +sed -i "s+0.0.0+2.9.22+g" frontend/package.json + +sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf +NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") +for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" +done + +mkdir -p /var/www/html /etc/nginx/logs +cp -r docker/rootfs/var/www/html/* /var/www/html/ +cp -r docker/rootfs/etc/nginx/* /etc/nginx/ +cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini +cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager +ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf +rm -f /etc/nginx/conf.d/dev.conf + +mkdir -p /tmp/nginx/body \ + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp + +chmod -R 777 /var/cache/nginx +chown root /tmp/nginx + +echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf + +if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -en "${GN} Generating dummy SSL Certificate... " + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null +fi + +mkdir -p /app/global /app/frontend/images +cp -r backend/* /app +cp -r global/* /app/global +msg_ok "Set up Enviroment" + +msg_info "Building Frontend" +cd ./frontend +export NODE_ENV=development +$STD yarn install --network-timeout=30000 +$STD yarn build +cp -r dist/* /app/frontend +cp -r app-images/* /app/frontend/images +msg_ok "Built Frontend" + +msg_info "Initializing Backend" +rm -rf /app/config/default.json +if [ ! -f /app/config/production.json ]; then + cat <<'EOF' >/app/config/production.json { "database": { "engine": "knex-native", @@ -152,31 +151,42 @@ function update_script() { } } EOF - fi - cd /app - export NODE_ENV=development - yarn install --network-timeout=30000 &>/dev/null - msg_ok "Initialized Backend" +fi +cd /app +export NODE_ENV=development +$STD yarn install --network-timeout=30000 +msg_ok "Initialized Backend" - msg_info "Starting Services" - sed -i -e 's/^pid/#pid/' -e 's/^user/#user/' /usr/local/openresty/nginx/conf/nginx.conf - systemctl enable npm &>/dev/null - systemctl start openresty - systemctl start npm - msg_ok "Started Services" +msg_info "Creating Service" +cat <<'EOF' >/lib/systemd/system/npm.service +[Unit] +Description=Nginx Proxy Manager +After=network.target +Wants=openresty.service - msg_info "Cleaning up" - rm -rf ~/nginx-proxy-manager-* - msg_ok "Cleaned" +[Service] +Type=simple +Environment=NODE_ENV=production +ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge +ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 +WorkingDirectory=/app +Restart=on-failure - msg_ok "Update Successfull" - exit -} +[Install] +WantedBy=multi-user.target +EOF +msg_ok "Created Service" -start -build_container -description +motd_ssh +root -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:81${CL} \n" +msg_info "Starting Services" +$STD systemctl enable --now openresty +$STD systemctl enable --now npm +msg_ok "Started Services" + +msg_info "Cleaning up" +rm -rf ../nginx-proxy-manager-* +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From a03831227ad3f501c1b07f3454e900c8c9ef0994 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Apr 2023 05:36:01 -0400 Subject: [PATCH 4598/6505] Update nginxproxymanager.sh --- ct/nginxproxymanager.sh | 308 +++++++++++++++++++--------------------- 1 file changed, 148 insertions(+), 160 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index bda3670c..ce7fc32f 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -1,144 +1,144 @@ #!/usr/bin/env bash - +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +function header_info { + clear + cat <<"EOF" + _ __ _ ____ __ ___ + / | / /___ _(_)___ _ __ / __ \_________ __ ____ __ / |/ /___ _____ ____ _____ ____ _____ + / |/ / __ / / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ / __ \/ __ / __ / _ \/ ___/ + / /| / /_/ / / / / /> < / ____/ / / /_/ /> /etc/apt/sources.list.d/openresty.list' -$STD apt-get -y update -$STD apt-get -y install --no-install-recommends openresty -msg_ok "Installed Openresty" + msg_info "Cleaning Old Files" + rm -rf /app \ + /var/www/html \ + /etc/nginx \ + /var/log/nginx \ + /var/lib/nginx \ + /var/cache/nginx &>/dev/null + msg_ok "Cleaned Old Files" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" + msg_info "Downloading NPM v2.9.22" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz &>/dev/null + cd nginx-proxy-manager-2.9.22 + msg_ok "Downloaded NPM v2.9.22" -msg_info "Installing Node.js" -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" + msg_info "Setting up Enviroment" + ln -sf /usr/bin/python3 /usr/bin/python + ln -sf /usr/bin/certbot /opt/certbot/bin/certbot + ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx + ln -sf /usr/local/openresty/nginx/ /etc/nginx + sed -i "s+0.0.0+2.9.22+g" backend/package.json + sed -i "s+0.0.0+2.9.22+g" frontend/package.json + sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf + NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") + for NGINX_CONF in $NGINX_CONFS; do + sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" + done + mkdir -p /var/www/html /etc/nginx/logs + cp -r docker/rootfs/var/www/html/* /var/www/html/ + cp -r docker/rootfs/etc/nginx/* /etc/nginx/ + cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini + cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager + ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf + rm -f /etc/nginx/conf.d/dev.conf + mkdir -p /tmp/nginx/body \ + /run/nginx \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp + chmod -R 777 /var/cache/nginx + chown root /tmp/nginx + echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf + if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then + echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" + openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null + fi + mkdir -p /app/global /app/frontend/images + cp -r backend/* /app + cp -r global/* /app/global + msg_ok "Setup Enviroment" -msg_info "Installing Yarn" -$STD npm install --global yarn -msg_ok "Installed Yarn" + msg_info "Building Frontend" + cd ./frontend + export NODE_ENV=development + yarn install --network-timeout=30000 &>/dev/null + yarn build &>/dev/null + cp -r dist/* /app/frontend + cp -r app-images/* /app/frontend/images + msg_ok "Built Frontend" -RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -msg_info "Downloading Nginx Proxy Manager v2.9.22" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz -cd ./nginx-proxy-manager-2.9.22 -msg_ok "Downloaded Nginx Proxy Manager v2.9.22" - -msg_info "Setting up Enviroment" -ln -sf /usr/bin/python3 /usr/bin/python -ln -sf /usr/bin/certbot /opt/certbot/bin/certbot -ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx -ln -sf /usr/local/openresty/nginx/ /etc/nginx - -sed -i "s+0.0.0+2.9.22+g" backend/package.json -sed -i "s+0.0.0+2.9.22+g" frontend/package.json - -sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf -NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") -for NGINX_CONF in $NGINX_CONFS; do - sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF" -done - -mkdir -p /var/www/html /etc/nginx/logs -cp -r docker/rootfs/var/www/html/* /var/www/html/ -cp -r docker/rootfs/etc/nginx/* /etc/nginx/ -cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini -cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager -ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf -rm -f /etc/nginx/conf.d/dev.conf - -mkdir -p /tmp/nginx/body \ - /run/nginx \ - /data/nginx \ - /data/custom_ssl \ - /data/logs \ - /data/access \ - /data/nginx/default_host \ - /data/nginx/default_www \ - /data/nginx/proxy_host \ - /data/nginx/redirection_host \ - /data/nginx/stream \ - /data/nginx/dead_host \ - /data/nginx/temp \ - /var/lib/nginx/cache/public \ - /var/lib/nginx/cache/private \ - /var/cache/nginx/proxy_temp - -chmod -R 777 /var/cache/nginx -chown root /tmp/nginx - -echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf - -if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -en "${GN} Generating dummy SSL Certificate... " - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null -fi - -mkdir -p /app/global /app/frontend/images -cp -r backend/* /app -cp -r global/* /app/global -msg_ok "Set up Enviroment" - -msg_info "Building Frontend" -cd ./frontend -export NODE_ENV=development -$STD yarn install --network-timeout=30000 -$STD yarn build -cp -r dist/* /app/frontend -cp -r app-images/* /app/frontend/images -msg_ok "Built Frontend" - -msg_info "Initializing Backend" -rm -rf /app/config/default.json -if [ ! -f /app/config/production.json ]; then - cat <<'EOF' >/app/config/production.json + msg_info "Initializing Backend" + rm -rf /app/config/default.json &>/dev/null + if [ ! -f /app/config/production.json ]; then + cat <<'EOF' >/app/config/production.json { "database": { "engine": "knex-native", @@ -151,42 +151,30 @@ if [ ! -f /app/config/production.json ]; then } } EOF -fi -cd /app -export NODE_ENV=development -$STD yarn install --network-timeout=30000 -msg_ok "Initialized Backend" + fi + cd /app + export NODE_ENV=development + yarn install --network-timeout=30000 &>/dev/null + msg_ok "Initialized Backend" -msg_info "Creating Service" -cat <<'EOF' >/lib/systemd/system/npm.service -[Unit] -Description=Nginx Proxy Manager -After=network.target -Wants=openresty.service + msg_info "Starting Services" + systemctl enable npm &>/dev/null + systemctl start openresty + systemctl start npm + msg_ok "Started Services" -[Service] -Type=simple -Environment=NODE_ENV=production -ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge -ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250 -WorkingDirectory=/app -Restart=on-failure + msg_info "Cleaning up" + rm -rf ~/nginx-proxy-manager-* + msg_ok "Cleaned" -[Install] -WantedBy=multi-user.target -EOF -msg_ok "Created Service" + msg_ok "Update Successfull" + exit +} -motd_ssh -root +start +build_container +description -msg_info "Starting Services" -$STD systemctl enable --now openresty -$STD systemctl enable --now npm -msg_ok "Started Services" - -msg_info "Cleaning up" -rm -rf ../nginx-proxy-manager-* -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:81${CL} \n" From 2ff5df2ea8e84ef636d23c824fcb8a977043d83f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Apr 2023 09:06:28 -0400 Subject: [PATCH 4599/6505] Update haos-vm.sh Code refactoring --- vm/haos-vm.sh | 199 +++++++++++++++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 83 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 8f3c244b..4af0722f 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -48,16 +48,19 @@ function error_handler() { echo -e "\n$error_message\n" cleanup_vmid } + function cleanup_vmid() { if qm status $VMID &>/dev/null; then qm stop $VMID &>/dev/null qm destroy $VMID &>/dev/null fi } + function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then @@ -70,15 +73,18 @@ function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } + function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + function msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } -function PVE_CHECK() { + +function pve_check() { if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 7.2 or higher" @@ -87,7 +93,8 @@ function PVE_CHECK() { exit fi } -function ARCH_CHECK() { + +function arch_check() { if [ "$(dpkg --print-architecture)" != "amd64" ]; then echo -e "\n ${CROSS} This script will not work with PiMox! \n" echo -e "Exiting..." @@ -95,7 +102,8 @@ function ARCH_CHECK() { exit fi } -function SSH_CHECK() { + +function ssh_check() { if command -v pveversion >/dev/null 2>&1; then if [ -n "${SSH_CLIENT:+x}" ]; then if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then @@ -107,6 +115,13 @@ function SSH_CHECK() { fi fi } + +exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function default_settings() { BRANCH="$stable" VMID="$NEXTID" @@ -136,133 +151,149 @@ function default_settings() { echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { - BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ + if BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ "$stable" "Stable " ON \ "$beta" "Beta " OFF \ "$dev" "Dev " OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" + else + exit-script + fi while true; do - VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z "$VMID" ]; then - VMID="$NEXTID" - echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" - break - else - if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then - echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" - sleep 2 - continue + if VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break fi - echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" - break + else + exit-script fi done - MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + if MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "i440fx" "Machine i440fx" ON \ "q35" "Machine q35" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $MACH = q35 ]; then - echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" - FORMAT="" - MACHINE=" -machine q35" + 3>&1 1>&2 2>&3); then + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" + fi else - echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" - FORMAT=",efitype=4m" - MACHINE="" + exit-script fi - DISK_CACHE1=$(whiptail --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + if DISK_CACHE1=$(whiptail --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ "0" "Default" ON \ "1" "Write Through" OFF \ - 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $DISK_CACHE1 = "1" ]; then - echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" - DISK_CACHE="cache=writethrough," + 3>&1 1>&2 2>&3); then + if [ $DISK_CACHE1 = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}Default${CL}" + DISK_CACHE="" + fi else - echo -e "${DGN}Using Disk Cache: ${BGN}Default${CL}" - DISK_CACHE="" + exit-script fi - VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $VM_NAME ]; then - HN="haos${BRANCH}" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - if [ $exitstatus = 0 ]; then + if VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="haos${BRANCH}" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else HN=$(echo ${VM_NAME,,} | tr -d ' ') echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" fi + else + exit-script fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $CORE_COUNT ]; then - CORE_COUNT="2" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi + exit-script fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $RAM_SIZE ]; then - RAM_SIZE="4096" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="4096" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi + exit-script fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi else - if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi + exit-script fi - MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ -z $MAC1 ]; then - MAC="$GEN_MAC" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" - else - if [ $exitstatus = 0 ]; then + if MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else MAC="$MAC1" echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi + else + exit-script fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" + VLAN1="Default" + VLAN="" echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" else VLAN=",tag=$VLAN1" echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi + else + exit-script fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" + MTU1="Default" + MTU="" echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" else MTU=",mtu=$MTU1" echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi + else + exit-script fi if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then @@ -281,7 +312,8 @@ function advanced_settings() { advanced_settings fi } -function START_SCRIPT() { + +function start_script() { if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" @@ -292,10 +324,11 @@ function START_SCRIPT() { advanced_settings fi } -ARCH_CHECK -PVE_CHECK -SSH_CHECK -START_SCRIPT + +arch_check +pve_check +ssh_check +start_script msg_info "Validating Storage" while read -r line; do TAG=$(echo $line | awk '{print $1}') From a2b5ce070d93e100accb9a51b4cd49eb844bb536 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Apr 2023 08:48:09 -0400 Subject: [PATCH 4600/6505] Update haos-vm.sh tweak --- vm/haos-vm.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 4af0722f..64eea8ba 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -116,7 +116,7 @@ function ssh_check() { fi } -exit-script() { +function exit-script() { clear echo -e "⚠ User exited script \n" exit @@ -150,6 +150,7 @@ function default_settings() { echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } + function advanced_settings() { if BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ "$stable" "Stable " ON \ @@ -329,6 +330,7 @@ arch_check pve_check ssh_check start_script + msg_info "Validating Storage" while read -r line; do TAG=$(echo $line | awk '{print $1}') From 49263e9874b602dccabb22cbc4adb43943411207 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Apr 2023 11:26:00 -0400 Subject: [PATCH 4601/6505] Update haos-vm.sh Include a choice within the "Advanced" settings to configure the CPU model between kvm64 (default) or host. --- vm/haos-vm.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 64eea8ba..199dabaa 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -129,6 +129,7 @@ function default_settings() { MACHINE="" DISK_CACHE="" HN="haos$stable" + CPU_TYPE="" CORE_COUNT="2" RAM_SIZE="4096" BRG="vmbr0" @@ -141,6 +142,7 @@ function default_settings() { echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" echo -e "${DGN}Using Disk Cache: ${BGN}Default${CL}" echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}Default${CL}" echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" @@ -226,6 +228,21 @@ function advanced_settings() { exit-script fi + if CPU_TYPE1=$(whiptail --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "KVM64 (Default)" ON \ + "1" "Host" OFF \ + 3>&1 1>&2 2>&3); then + if [ $CPU_TYPE1 = "1" ]; then + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + CPU_TYPE=" -cpu host" + else + echo -e "${DGN}Using CPU Model: ${BGN}Default${CL}" + CPU_TYPE="" + fi + else + exit-script + fi + if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $CORE_COUNT ]; then CORE_COUNT="2" @@ -396,7 +413,7 @@ for i in {0,1}; do done msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" -qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE \ +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null From b1451e795e1f0675fcd6c0d12cc216939edab9e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Apr 2023 11:28:39 -0400 Subject: [PATCH 4602/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index b577dfc1..352231e8 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,12 +2,19 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-02 + +### Changed + +- **Home Assistant OS VM** + - Include a choice within the "Advanced" settings to configure the CPU model between kvm64 (default) or host. + ## 2023-03-31 ### Changed - **Home Assistant OS VM** - - Include a choice within the "Advanced" settings to configure the disk cache. + - Include a choice within the "Advanced" settings to configure the disk cache between none (default) or Write Through. ## 2023-03-27 From 3e7f070ea836bf9436757f964269bb43b8a06a25 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Apr 2023 06:41:33 -0400 Subject: [PATCH 4603/6505] Update jellyfin-install.sh Use the Deb822 format jellyfin.sources --- install/jellyfin-install.sh | 49 +++++++++++++++---------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index e0ac97b4..98d427b0 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -16,9 +16,8 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo +$STD apt-get install -y gnupg $STD apt-get install -y mc -$STD apt-get install -y apt-transport-https -$STD apt-get install -y software-properties-common msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then @@ -37,35 +36,27 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then msg_ok "Set Up Hardware Acceleration" fi -msg_info "Setting Up Jellyfin Repository" -$STD add-apt-repository universe -y -$STD apt-key add <(curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key) -sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://repo.jellyfin.org/ubuntu $(lsb_release -c -s) main" > /etc/apt/sources.list.d/jellyfin.list' -msg_ok "Set Up Jellyfin Repository" - msg_info "Installing Jellyfin" -$STD apt-get update -$STD apt install jellyfin-server -y -$STD apt install jellyfin-ffmpeg5 -y -msg_ok "Installed Jellyfin" - -msg_info "Creating Service" -cat <<'EOF' >/lib/systemd/system/jellyfin.service -[Unit] -Description = Jellyfin Media Server -After = network.target -[Service] -Type = simple -EnvironmentFile = /etc/default/jellyfin -User = root -ExecStart = /usr/bin/jellyfin -Restart = on-failure -TimeoutSec = 15 -[Install] -WantedBy = multi-user.target +VERSION="$( awk -F'=' '/^UBUNTU_CODENAME=/{ print $NF }' /etc/os-release )" +# If the keyring directory is absent, create it +if [[ ! -d /etc/apt/keyrings ]]; then + mkdir -p /etc/apt/keyrings +fi +# Download the repository signing key and install it to the keyring directory +curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | gpg --dearmor --yes --output /etc/apt/keyrings/jellyfin.gpg +# Install the Deb822 format jellyfin.sources entry +cat </etc/apt/sources.list.d/jellyfin.sources +Types: deb +URIs: https://repo.jellyfin.org/${PCT_OSTYPE} +Suites: ${VERSION} +Components: main +Architectures: amd64 +Signed-By: /etc/apt/keyrings/jellyfin.gpg EOF -ln -s /usr/share/jellyfin/web/ /usr/lib/jellyfin/bin/jellyfin-web -msg_ok "Created Service" +# Install Jellyfin using the metapackage (which will fetch jellyfin-server, jellyfin-web, and jellyfin-ffmpeg5) +$STD apt-get update +$STD apt-get install -y jellyfin +msg_ok "Installed Jellyfin" motd_ssh root From cd275ac57adb7f5a33a6e257495f3c67d790afb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Apr 2023 06:42:37 -0400 Subject: [PATCH 4604/6505] Update jellyfin.sh Set v22.04 as default --- ct/jellyfin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index d11b8212..88eb4d8d 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -24,7 +24,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="ubuntu" -var_version="20.04" +var_version="22.04" variables color catch_errors From 6d644b35d73c7874dcf8202d3ef8a0af57f04e7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Apr 2023 06:44:12 -0400 Subject: [PATCH 4605/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 352231e8..7c6899db 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,14 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-05 + +### Changed + +- **Jellyfin LXC** + - Set Ubuntu 22.04 as default + - Use the Deb822 format jellyfin.sources configuration (jellyfin.list configuration has been obsoleted) + ## 2023-04-02 ### Changed From 1b0ec6b87d68b012745e96827cf8f582fefa4211 Mon Sep 17 00:00:00 2001 From: glerak Date: Fri, 7 Apr 2023 14:26:25 +0200 Subject: [PATCH 4606/6505] ct/podman-homeassistant.sh - added container update and purge images (#1304) Added podman container(s) update. Added removing unused images. --- ct/podman-homeassistant.sh | 98 +++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index d916cc95..e806a7a8 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -57,58 +57,80 @@ function default_settings() { function update_script() { if [[ ! -f /etc/systemd/system/homeassistant.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ - "1" "Update Podman" ON \ + "1" "Update system and containers" ON \ "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ + "4" "Remove ALL Unused Images" OFF \ 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" -exit + msg_info "Updating ${APP} LXC" + apt-get update &>/dev/null + apt-get -y upgrade &>/dev/null + msg_ok "Updated ${APP} LXC" + msg_ok "Update os system Successfull" + + msg_info "Updating All Containers\n" + CONTAINER_LIST="${1:-$(podman ps -q)}" + for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(podman inspect --format "{{.Config.Image}}" --type container ${container})" + RUNNING_IMAGE="$(podman inspect --format "{{.Image}}" --type container "${container}")" + podman pull "docker.io/${CONTAINER_IMAGE}" + LATEST_IMAGE="$(podman inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + echo "Updating ${container} image ${CONTAINER_IMAGE}" + systemctl restart homeassistant + fi + done + msg_ok "All containers updated." + exit fi if [ "$UPD" == "2" ]; then -msg_info "Installing Home Assistant Comunity Store (HACS)" -apt update &>/dev/null -apt install unzip &>/dev/null -cd /var/lib/containers/storage/volumes/hass_config/_data -bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null -msg_ok "Installed Home Assistant Comunity Store (HACS)" -echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" -exit + msg_info "Installing Home Assistant Comunity Store (HACS)" + apt update &>/dev/null + apt install unzip &>/dev/null + cd /var/lib/containers/storage/volumes/hass_config/_data + bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null + msg_ok "Installed Home Assistant Comunity Store (HACS)" + echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" + exit fi if [ "$UPD" == "3" ]; then -IP=$(hostname -I | awk '{print $1}') -msg_info "Installing FileBrowser" -curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null -filebrowser config init -a '0.0.0.0' &>/dev/null -filebrowser config set -a '0.0.0.0' &>/dev/null -filebrowser users add admin changeme --perm.admin &>/dev/null -msg_ok "Installed FileBrowser" + IP=$(hostname -I | awk '{print $1}') + msg_info "Installing FileBrowser" + curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null + filebrowser config init -a '0.0.0.0' &>/dev/null + filebrowser config set -a '0.0.0.0' &>/dev/null + filebrowser users add admin changeme --perm.admin &>/dev/null + msg_ok "Installed FileBrowser" -msg_info "Creating Service" -service_path="/etc/systemd/system/filebrowser.service" -echo "[Unit] -Description=Filebrowser -After=network-online.target -[Service] -User=root -WorkingDirectory=/root/ -ExecStart=/usr/local/bin/filebrowser -r / -[Install] -WantedBy=default.target" >$service_path + msg_info "Creating Service" + service_path="/etc/systemd/system/filebrowser.service" + echo "[Unit] + Description=Filebrowser + After=network-online.target + [Service] + User=root + WorkingDirectory=/root/ + ExecStart=/usr/local/bin/filebrowser -r / + [Install] + WantedBy=default.target" >$service_path -systemctl enable --now filebrowser.service &>/dev/null -msg_ok "Created Service" + systemctl enable --now filebrowser.service &>/dev/null + msg_ok "Created Service" -msg_ok "Completed Successfully!\n" -echo -e "FileBrowser should be reachable by going to the following URL. + msg_ok "Completed Successfully!\n" + echo -e "FileBrowser should be reachable by going to the following URL. ${BL}http://$IP:8080${CL} admin|changeme\n" -exit + exit fi +if [ "$UPD" == "4" ]; then + msg_info "Removing ALL Unused Images" + podman image prune -a -f + msg_ok "Removed ALL Unused Images" + exit +fi + } start From fb34f21e7b48ca52cf6d9c8126f33bfb5bd3f80a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Apr 2023 11:30:08 -0400 Subject: [PATCH 4607/6505] Update influxdb.sh fix for rotating keys --- ct/influxdb.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index f6c078cf..e945cdde 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -53,10 +53,14 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/apt/sources.list.d/influxdb.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" +msg_info "Updating ${APP}" +wget -q https://repos.influxdata.com/influxdata-archive_compat.key +cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null +echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | tee /etc/apt/sources.list.d/influxdata.list +rm -f /etc/apt/trusted.gpg.d/influxdb.gpg apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" +msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } From b2124be08f82169cc2902ba047f2544fb76d62af Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Apr 2023 11:32:38 -0400 Subject: [PATCH 4608/6505] Update grafana.sh fix for rotating keys --- ct/grafana.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ct/grafana.sh b/ct/grafana.sh index 3de34626..ea1136c5 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -52,11 +52,14 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" +if [[ ! -f /etc/apt/sources.list.d/grafana.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +apt-key del 4E40DDF6D76E284A4A6780E48C8C34C524098CB6 +wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key +echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee /etc/apt/sources.list.d/grafana.list apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" +msg_ok "Updated ${APP}" msg_ok "Update Successfull" exit } From c1f7fd340e9835b70b458fe763b7bd9444de7876 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 03:11:31 -0400 Subject: [PATCH 4609/6505] Update nginxproxymanager-install.sh v2.10.2 --- install/nginxproxymanager-install.sh | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index bda3670c..61a78c40 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -40,7 +40,7 @@ $STD python3 -m venv /opt/certbot/ if [ "$(getconf LONG_BIT)" = "32" ]; then $STD python3 -m pip install --no-cache-dir -U cryptography==3.3.2 fi -$STD python3 -m pip install --no-cache-dir cffi certbot +$STD python3 -m pip install --no-cache-dir cffi certbot certbot-dns-cloudflare msg_ok "Installed Python" msg_info "Installing Openresty" @@ -66,10 +66,10 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v2.9.22" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz -cd ./nginx-proxy-manager-2.9.22 -msg_ok "Downloaded Nginx Proxy Manager v2.9.22" +msg_info "Downloading Nginx Proxy Manager v2.10.2" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.10.2 -O - | tar -xz +cd ./nginx-proxy-manager-2.10.2 +msg_ok "Downloaded Nginx Proxy Manager v2.10.2" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python @@ -77,8 +77,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+2.9.22+g" backend/package.json -sed -i "s+0.0.0+2.9.22+g" frontend/package.json +sed -i "s+0.0.0+2.10.2+g" backend/package.json +sed -i "s+0.0.0+2.10.2+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") @@ -124,6 +124,10 @@ fi mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global +wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-noarch.tar.xz" +wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-x86_64.tar.xz" +tar -C / -Jxpf s6-overlay-noarch.tar.xz +tar -C / -Jxpf s6-overlay-x86_64.tar.xz msg_ok "Set up Enviroment" msg_info "Building Frontend" @@ -181,12 +185,13 @@ motd_ssh root msg_info "Starting Services" +sed -i -e 's/^pid/#pid/' -e 's/npmuser/root/' /usr/local/openresty/nginx/conf/nginx.conf $STD systemctl enable --now openresty $STD systemctl enable --now npm msg_ok "Started Services" msg_info "Cleaning up" -rm -rf ../nginx-proxy-manager-* +rm -rf ../nginx-proxy-manager-* s6-overlay-noarch.tar.xz s6-overlay-x86_64.tar.xz $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From b465ada678b56ee612c8f010aa66c8d8828b387b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 03:13:12 -0400 Subject: [PATCH 4610/6505] Update nginxproxymanager.sh v2.10.2 --- ct/nginxproxymanager.sh | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index ce7fc32f..62603405 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/dev/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT @@ -74,18 +74,18 @@ function update_script() { /var/cache/nginx &>/dev/null msg_ok "Cleaned Old Files" - msg_info "Downloading NPM v2.9.22" - wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.9.22 -O - | tar -xz &>/dev/null - cd nginx-proxy-manager-2.9.22 - msg_ok "Downloaded NPM v2.9.22" + msg_info "Downloading NPM v2.10.2" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.10.2 -O - | tar -xz &>/dev/null + cd nginx-proxy-manager-2.10.2 + msg_ok "Downloaded NPM v2.10.2" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx - sed -i "s+0.0.0+2.9.22+g" backend/package.json - sed -i "s+0.0.0+2.9.22+g" frontend/package.json + sed -i "s+0.0.0+2.10.2+g" backend/package.json + sed -i "s+0.0.0+2.10.2+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do @@ -124,6 +124,11 @@ function update_script() { mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global + wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-noarch.tar.xz" + wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-x86_64.tar.xz" + tar -C / -Jxpf s6-overlay-noarch.tar.xz + tar -C / -Jxpf s6-overlay-x86_64.tar.xz + python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null msg_ok "Setup Enviroment" msg_info "Building Frontend" @@ -158,13 +163,14 @@ EOF msg_ok "Initialized Backend" msg_info "Starting Services" + sed -i -e 's/^pid/#pid/' -e 's/npmuser/root/' /usr/local/openresty/nginx/conf/nginx.conf systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm msg_ok "Started Services" msg_info "Cleaning up" - rm -rf ~/nginx-proxy-manager-* + rm -rf ~/nginx-proxy-manager-* s6-overlay-noarch.tar.xz s6-overlay-x86_64.tar.xz msg_ok "Cleaned" msg_ok "Update Successfull" From b39bb439bf674bfb75ec6e44dd5b540f09beaa60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 03:46:42 -0400 Subject: [PATCH 4611/6505] Update nginxproxymanager.sh fix branch --- ct/nginxproxymanager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 62603405..9b71bfe5 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/dev/misc/build.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT From 14ddc3b5052301c89d5ed421e87ceafb36c0e943 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 09:04:49 -0400 Subject: [PATCH 4612/6505] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index bc95960c..d86a82c6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,4 +2,6 @@ Everybody is invited and welcome to contribute to Proxmox Helper Scripts. -- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if I reject your request. If you follow the patterns that have been established throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main) :partying_face:! +- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if I reject your request. If you follow the patterns that have been established throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). + +- While it is true that the decision to accept or decline a pull request ultimately rests with the project maintainer, it is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to show respect for the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. From 3bbb4e76d6cb14aedf83fa0d847ea2e5ce5cf0a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 09:07:57 -0400 Subject: [PATCH 4613/6505] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d86a82c6..73cca9f7 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,6 +2,6 @@ Everybody is invited and welcome to contribute to Proxmox Helper Scripts. -- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if I reject your request. If you follow the patterns that have been established throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). +- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. If you follow the patterns that have been established throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). - While it is true that the decision to accept or decline a pull request ultimately rests with the project maintainer, it is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to show respect for the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. From fc2ff40ad97a008593283611dd316ee92c498a16 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 09:09:33 -0400 Subject: [PATCH 4614/6505] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 73cca9f7..8a797bb8 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -4,4 +4,4 @@ Everybody is invited and welcome to contribute to Proxmox Helper Scripts. - Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. If you follow the patterns that have been established throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). -- While it is true that the decision to accept or decline a pull request ultimately rests with the project maintainer, it is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to show respect for the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. +- While it is true that the decision to accept or decline a pull request ultimately rests with the project maintainer, it is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. From 6d510952e25b1a4c86facfb2b32dd3a302f980a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 09:18:57 -0400 Subject: [PATCH 4615/6505] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8a797bb8..837e4bec 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,6 +2,6 @@ Everybody is invited and welcome to contribute to Proxmox Helper Scripts. -- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. If you follow the patterns that have been established throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). +- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. By adhering to the established patterns and conventions throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). - While it is true that the decision to accept or decline a pull request ultimately rests with the project maintainer, it is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. From c152e24ef8d393efb788dff14ddc35ac50fc5b3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 09:36:42 -0400 Subject: [PATCH 4616/6505] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 837e4bec..c8649c97 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -4,4 +4,4 @@ Everybody is invited and welcome to contribute to Proxmox Helper Scripts. - Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. By adhering to the established patterns and conventions throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). -- While it is true that the decision to accept or decline a pull request ultimately rests with the project maintainer, it is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. +- It is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. From 1267ac0131344d5a1b9a8ebfa56e23c1c2f4e579 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 23:45:57 -0400 Subject: [PATCH 4617/6505] Update vaultwarden.sh Use Argon2 to securely hash passwords and protect them against various types of attacks. --- ct/vaultwarden.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 8f887956..c5d06839 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -65,7 +65,7 @@ function update_script() { UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ "1" "VaultWarden $VAULT" ON \ "2" "Web-Vault $WVRELEASE" OFF \ - "3" "Show Admin Token" OFF \ + "3" "Set Admin Token" OFF \ 3>&1 1>&2 2>&3) header_info @@ -121,11 +121,12 @@ function update_script() { exit fi if [ "$UPD" == "3" ]; then - DIR=/usr/bin/vaultwarden - if [ -d "$DIR" ]; then - cat /etc/vaultwarden.env | grep "ADMIN_TOKEN" - else - cat /opt/vaultwarden/.env | grep "ADMIN_TOKEN" + if NEWTOKEN=$(whiptail --passwordbox "Set your ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then + if [[ -z "$NEWTOKEN" ]]; then exit; fi + if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi + TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) + sed -i "s|ADMIN_TOKEN='.*'|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env + systemctl restart vaultwarden fi exit fi From c46675f2504afedee99022ce6d32a918fecdc139 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 23:47:27 -0400 Subject: [PATCH 4618/6505] Update vaultwarden-install.sh Add Argon2 --- install/vaultwarden-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/vaultwarden-install.sh b/install/vaultwarden-install.sh index dd079560..fe0edc19 100644 --- a/install/vaultwarden-install.sh +++ b/install/vaultwarden-install.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -24,6 +24,7 @@ $STD apt-get -qqy install \ libpq-dev \ curl \ sudo \ + argon2 \ mc msg_ok "Installed Dependencies" @@ -61,7 +62,7 @@ $STD tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/ msg_ok "Downloaded Web-Vault ${WEBVAULT}" cat </opt/vaultwarden/.env -ADMIN_TOKEN=$(openssl rand -base64 48) +ADMIN_TOKEN='' ROCKET_ADDRESS=0.0.0.0 DATA_FOLDER=/opt/vaultwarden/data DATABASE_MAX_CONNS=10 From ab2cd43c159e79145b699e3c0bdda48c45ff776c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Apr 2023 23:50:49 -0400 Subject: [PATCH 4619/6505] Update vaultwarden.sh tweak --- ct/vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index c5d06839..74fb9f94 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -121,7 +121,7 @@ function update_script() { exit fi if [ "$UPD" == "3" ]; then - if NEWTOKEN=$(whiptail --passwordbox "Set your ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then + if NEWTOKEN=$(whiptail --passwordbox "Set the ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then if [[ -z "$NEWTOKEN" ]]; then exit; fi if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) From a4720801277a76b91f51fd4b535340330b8e9d49 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 10 Apr 2023 00:21:11 -0400 Subject: [PATCH 4620/6505] Update vaultwarden.sh tweak --- ct/vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 74fb9f94..f74ef4fe 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -125,7 +125,7 @@ function update_script() { if [[ -z "$NEWTOKEN" ]]; then exit; fi if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) - sed -i "s|ADMIN_TOKEN='.*'|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env + sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env systemctl restart vaultwarden fi exit From d21c70bc850f5fb6d4b42fcf0c38f07e96ed416d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 10 Apr 2023 05:49:23 -0400 Subject: [PATCH 4621/6505] Update cronicle-install.sh fix unbound variable --- install/cronicle-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/cronicle-install.sh b/install/cronicle-install.sh index 1060a494..281a6f19 100644 --- a/install/cronicle-install.sh +++ b/install/cronicle-install.sh @@ -40,7 +40,7 @@ $STD tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST $STD npm install $STD node bin/build.js dist sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json -if [[ $SERV == "y" ]]; then $STD /opt/cronicle/bin/control.sh setup; fi +$STD /opt/cronicle/bin/control.sh setup $STD /opt/cronicle/bin/control.sh start $STD cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled chmod 775 /etc/init.d/cronicled From 3621dd0c35043a10bc9d918021bc38d917a7cea6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 10 Apr 2023 06:34:44 -0400 Subject: [PATCH 4622/6505] Update cronicle.sh --- ct/cronicle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 53702989..e210d897 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -106,4 +106,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} Primary should be reachable by going to the following URL. - ${BL}http://${IP}:3012${CL} admin|admin \n" + ${BL}http://${IP}:3012${CL} \n" From 76479a7733b1e1122835a1b1b0afd05a5204e6b0 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Mon, 10 Apr 2023 14:16:47 +0200 Subject: [PATCH 4623/6505] alpine-vaultwarden-argon2 (#1314) Use Argon2 to securely hash passwords and protect them against various types of attacks. --- ct/alpine-vaultwarden.sh | 14 ++++++++++++-- install/alpine-vaultwarden-install.sh | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 45ea5390..3783d633 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -59,7 +59,7 @@ function update_script() { CHOICE=$( whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ "1" "Update Vaultwarden" \ - "2" "Show Admin Token" 3>&2 2>&1 1>&3 + "2" "Reset ADMIN_TOKEN" 3>&2 2>&1 1>&3 ) exit_status=$? if [ $exit_status == 1 ]; then @@ -73,7 +73,17 @@ function update_script() { exit ;; 2) - whiptail --title "ADMIN TOKEN" --msgbox "$(cat /etc/conf.d/vaultwarden | grep ADMIN_TOKEN | awk '{print substr($2, 13) }')" 7 68 + if NEWTOKEN=$(whiptail --passwordbox "Setup your ADMIN_TOKEN (make it strong)" 10 58 3>&1 1>&2 2>&3); then + if [[ -z "$NEWTOKEN" ]]; then exit-script; fi + if ! command -v argon2 >/dev/null 2>&1; then apk add argon2 &>/dev/null; fi + TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1) + if [[ ! -f /var/lib/vaultwarden/config.json ]]; then + sed -i "s|export ADMIN_TOKEN=.*|export ADMIN_TOKEN='${TOKEN}'|" /etc/conf.d/vaultwarden + else + sed -i "s|\"admin_token\": .*|\"admin_token\": \"${TOKEN}\",|" /var/lib/vaultwarden/config.json + fi + rc-service vaultwarden restart -q + fi clear exit ;; diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 6c6f90a5..f048745b 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -20,6 +20,7 @@ $STD apk add openssl $STD apk add openssh $STD apk add nano $STD apk add mc +$STD apk add argon2 msg_ok "Installed Dependencies" msg_info "Installing Alpine-Vaultwarden" @@ -28,7 +29,7 @@ cat </etc/conf.d/vaultwarden export DATA_FOLDER=/var/lib/vaultwarden export WEB_VAULT_FOLDER=/var/lib/vaultwarden/web-vault export WEB_VAULT_ENABLED=true -export ADMIN_TOKEN=$(openssl rand -base64 48) +export ADMIN_TOKEN='' export ROCKET_ADDRESS=0.0.0.0 EOF $STD rc-service vaultwarden start From 322de1f407407f94ab718f921a827e9f670f6702 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Apr 2023 10:34:18 -0400 Subject: [PATCH 4624/6505] Update nginxproxymanager-install.sh Python interpreter will include packages installed in the global site-packages directory. --- install/nginxproxymanager-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 61a78c40..05194c8f 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -186,6 +186,7 @@ root msg_info "Starting Services" sed -i -e 's/^pid/#pid/' -e 's/npmuser/root/' /usr/local/openresty/nginx/conf/nginx.conf +sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg $STD systemctl enable --now openresty $STD systemctl enable --now npm msg_ok "Started Services" From d0ccf41b59cd4365639e00273a8ed937ac531264 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Apr 2023 11:02:15 -0400 Subject: [PATCH 4625/6505] Update nginxproxymanager.sh Python interpreter will include packages installed in the global site-packages. --- ct/nginxproxymanager.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 9b71bfe5..defdbde9 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -164,6 +164,7 @@ EOF msg_info "Starting Services" sed -i -e 's/^pid/#pid/' -e 's/npmuser/root/' /usr/local/openresty/nginx/conf/nginx.conf + sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg systemctl enable npm &>/dev/null systemctl start openresty systemctl start npm From 21574e25a6123200284a7fc223b0c0ac03afe0e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Apr 2023 06:14:14 -0400 Subject: [PATCH 4626/6505] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a94517d8..fc889b20 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -

    Contributing to Proxmox Helper Scripts

    +

    Contributing to Proxmox VE Helper Scripts

    These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine. -

    Proxmox Helper Scripts

    -
    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    +

    Proxmox VE Helper Scripts

    +
    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    + +
    Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.
    From cc19644063592f9c7e23ee332f51937842237917 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Apr 2023 06:38:33 -0400 Subject: [PATCH 4627/6505] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c8649c97..142f6aa9 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributing to Proxmox Helper Scripts +# Contributing to Proxmox VE Helper Scripts -Everybody is invited and welcome to contribute to Proxmox Helper Scripts. +Everybody is invited and welcome to contribute to Proxmox VE Helper Scripts. - Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. By adhering to the established patterns and conventions throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). From b85dd70aca3f5ddcde2419bc1683d532a90e3054 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Apr 2023 12:42:31 -0400 Subject: [PATCH 4628/6505] Update tdarr-install.sh fix install fixes https://github.com/tteck/Proxmox/issues/1329 --- install/tdarr-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index 34e4ce6a..212df862 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -25,8 +25,9 @@ mkdir -p /opt/tdarr cd /opt/tdarr wget -q https://f000.backblazeb2.com/file/tdarrs/versions/2.00.15/linux_x64/Tdarr_Updater.zip $STD unzip Tdarr_Updater.zip +rm -rf Tdarr_Updater.zip chmod +x Tdarr_Updater -$STD ./Tdarr_Updater +./Tdarr_Updater &>/dev/null msg_ok "Installed Tdarr" msg_info "Creating Service" From 994a7f1067915b2a224eeb4752d98de741083455 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Apr 2023 11:58:14 -0400 Subject: [PATCH 4629/6505] Create cloudflared-install.sh --- install/cloudflared-install.sh | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 install/cloudflared-install.sh diff --git a/install/cloudflared-install.sh b/install/cloudflared-install.sh new file mode 100644 index 00000000..d75c0191 --- /dev/null +++ b/install/cloudflared-install.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Cloudflared" +mkdir -p --mode=0755 /usr/share/keyrings +curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null +echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared bullseye main' | tee /etc/apt/sources.list.d/cloudflared.list >/dev/null +$STD apt-get update +$STD apt-get install -y cloudflared +msg_ok "Installed Cloudflared" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 6192f0d48c4d3b531f422e24f2f68fbe1f74e55b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Apr 2023 11:59:16 -0400 Subject: [PATCH 4630/6505] Create cloudflared.sh --- ct/cloudflared.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 ct/cloudflared.sh diff --git a/ct/cloudflared.sh b/ct/cloudflared.sh new file mode 100644 index 00000000..b4fa4518 --- /dev/null +++ b/ct/cloudflared.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ ________ __ + / ____/ /___ __ ______/ / __/ /___ _________ ____/ / + / / / / __ \/ / / / __ / /_/ / __ `/ ___/ _ \/ __ / +/ /___/ / /_/ / /_/ / /_/ / __/ / /_/ / / / __/ /_/ / +\____/_/\____/\__,_/\__,_/_/ /_/\__,_/_/ \___/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Cloudflared" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" From 024c80287c4e76e5d18f3a8a1ea0c28ec3768e19 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Apr 2023 13:30:40 -0400 Subject: [PATCH 4631/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7c6899db..f4636445 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-14 + +### Changed + +- **Cloudflared LXC** + - NEW Script + ## 2023-04-05 ### Changed From b60c21522373205b7a5a8c7be75eddf5ca1f577d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Apr 2023 18:52:27 -0400 Subject: [PATCH 4632/6505] Update kavita-install.sh tweak --- install/kavita-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/kavita-install.sh b/install/kavita-install.sh index 72e353d9..b46f819a 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -22,7 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Kavita" cd /opt RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) && +$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) msg_ok "Installed Kavita" msg_info "Creating Service" From 65dbf8a75bbab2ffa54e28d7ed228e7d363e9392 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Apr 2023 07:10:50 -0400 Subject: [PATCH 4633/6505] Update influxdb-install.sh Choosing InfluxDB v1 will result in Chronograf being installed automatically. --- install/influxdb-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh index 1c501b0b..8167b01f 100644 --- a/install/influxdb-install.sh +++ b/install/influxdb-install.sh @@ -41,6 +41,8 @@ if [[ $INFLUX == "2" ]]; then $STD apt-get install -y influxdb2 else $STD apt-get install -y influxdb + wget -q https://dl.influxdata.com/chronograf/releases/chronograf_1.10.1_amd64.deb + $STD dpkg -i chronograf_1.10.1_amd64.deb fi $STD systemctl enable --now influxdb msg_ok "Installed InfluxDB" From a80a0e666744741bc7e4dd94fba228db8d28bde7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Apr 2023 07:12:47 -0400 Subject: [PATCH 4634/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index f4636445..38e56d87 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-15 + +### Changed + +- **InfluxDB LXC** + - Choosing InfluxDB v1 will result in Chronograf being installed automatically. + ## 2023-04-14 ### Changed From b366d4e7ee8918f78d7bdb855bf8ecd8a710824d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Apr 2023 08:03:29 -0400 Subject: [PATCH 4635/6505] Create USER_SUBMITTED_GUIDES.md In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. --- USER_SUBMITTED_GUIDES.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 USER_SUBMITTED_GUIDES.md diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md new file mode 100644 index 00000000..28046569 --- /dev/null +++ b/USER_SUBMITTED_GUIDES.md @@ -0,0 +1,6 @@ +

    User Submitted Guides

    + + In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. + +[Installing Home Assistant OS using Proxmox 7](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-7/201835) + From b706c9016879f7b8364f6857da7f8e975a3a6681 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Apr 2023 08:12:23 -0400 Subject: [PATCH 4636/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 38e56d87..154c12f9 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **InfluxDB LXC** - Choosing InfluxDB v1 will result in Chronograf being installed automatically. +- **[User Submitted Guides](https://github.com/tteck/Proxmox/blob/main/USER_SUBMITTED_GUIDES.md)** + - Informative guides that demonstrate how to install various software packages using Proxmox VE Helper Scripts. ## 2023-04-14 From 3bd8e3eaa80bb6ff2d80e1bf30d595b30e4b3ec0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Apr 2023 16:28:59 -0400 Subject: [PATCH 4637/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 28046569..0e7de8e4 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -4,3 +4,11 @@ [Installing Home Assistant OS using Proxmox 7](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-7/201835) +[How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/) + +[How To Install Home Assistant On Proxmox: The Easy Way](https://smarthomescene.com/guides/how-to-install-home-assistant-on-proxmox-the-easy-way/) + +[Home Assistant: Installing InfluxDB (LXC)](https://www.derekseaman.com/2023/04/home-assistant-installing-influxdb-lxc.html) + +[Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/04/installing-home-assistant-on-proxmox-quick-start-guide.html) + From 33654ab8c92997245f9070c8d5b5c55680fb2053 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Apr 2023 22:19:34 -0400 Subject: [PATCH 4638/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 0e7de8e4..6f66327b 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -12,3 +12,4 @@ [Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/04/installing-home-assistant-on-proxmox-quick-start-guide.html) +[Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html) From aa18e6ad7b718cb581f3618eb59e63fad225bc56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Apr 2023 08:24:39 -0400 Subject: [PATCH 4639/6505] Update homeassistant-core-install.sh Python 3.11.2 --- install/homeassistant-core-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index d7b64ad1..d42b53b5 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -64,10 +64,10 @@ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path) msg_ok "Installed pyenv" . ~/.bashrc set -e -msg_info "Installing Python 3.11.1" -$STD pyenv install 3.11.1 -pyenv global 3.11.1 -msg_ok "Installed Python 3.11.1" +msg_info "Installing Python 3.11.2" +$STD pyenv install 3.11.2 +pyenv global 3.11.2 +msg_ok "Installed Python 3.11.2" msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant From 663197feefc568f74f1b1b712320b74364142c7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Apr 2023 08:27:14 -0400 Subject: [PATCH 4640/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 154c12f9..7f240e60 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-16 + +### Changed + +- **Home Assistant Core LXC** + - Python 3.11.2 + ## 2023-04-15 ### Changed From d14a41e94e9bfa6ad59be7cb46db3b1a4cbc3502 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Apr 2023 03:27:46 -0400 Subject: [PATCH 4641/6505] Update homebridge-install.sh add avahi-daemon --- install/homebridge-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh index 5c12bbfe..573acf8f 100644 --- a/install/homebridge-install.sh +++ b/install/homebridge-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y avahi-daemon msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" From 3492971e461944de1e29a0f935576bfc96f57638 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Apr 2023 03:29:32 -0400 Subject: [PATCH 4642/6505] Update scrypted-install.sh add avahi-daemon --- install/scrypted-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 5294e95b..dd766825 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get -y install software-properties-common apt-utils $STD apt-get -y update $STD apt-get -y upgrade +$STD apt-get install -y avahi-daemon $STD apt-get -y install \ build-essential \ gcc \ From 0675f9bb2865ebc3383409da14bfc3bcb2a04c1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Apr 2023 14:30:34 -0400 Subject: [PATCH 4643/6505] Update zigbee2mqtt.sh set default settings to privileged --- ct/zigbee2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index c1c59ff0..21562435 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -30,7 +30,7 @@ color catch_errors function default_settings() { - CT_TYPE="1" + CT_TYPE="0" PW="" CT_ID=$NEXTID HN=$NSAPP From 5d7da7e83390a660c2996b9297fe275620e4d1bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Apr 2023 14:30:56 -0400 Subject: [PATCH 4644/6505] Update zwave-js-ui.sh set default settings to privileged --- ct/zwave-js-ui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index ed8c0d64..2255e299 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="1" + CT_TYPE="0" PW="" CT_ID=$NEXTID HN=$NSAPP From 202827ce4189ccf71080bc0a2521fb96b757c524 Mon Sep 17 00:00:00 2001 From: Chris Heath Date: Tue, 18 Apr 2023 06:12:17 -0500 Subject: [PATCH 4645/6505] Update adguard.sh (#1343) Fix for DNS lookup failing during wget command. --- ct/adguard.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index e8c65085..b90049bc 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -54,12 +54,12 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/AdGuardHome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +wget -qL https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz msg_info "Stopping AdguardHome" systemctl stop AdGuardHome msg_ok "Stopped AdguardHome" msg_info "Updating AdguardHome" -wget -qL https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz tar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null mkdir -p adguard-backup cp -r /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/ @@ -74,7 +74,7 @@ msg_ok "Started AdguardHome" msg_info "Cleaning Up" rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup msg_ok "Cleaned" -msg_ok "Update Successfull" +msg_ok "Update Successful" exit } From c44ab752e4e243ba75e78a1e42b15a0aab39aea9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Apr 2023 07:40:03 -0400 Subject: [PATCH 4646/6505] grammar --- ct/adguard.sh | 2 +- ct/archlinux.sh | 2 +- ct/autobrr.sh | 2 +- ct/changedetection.sh | 3 +-- ct/dashy.sh | 2 +- ct/emby.sh | 2 +- ct/esphome.sh | 2 +- ct/grafana.sh | 3 +-- ct/grocy.sh | 3 +-- ct/heimdalldashboard.sh | 2 +- ct/homebridge.sh | 3 +-- ct/homepage.sh | 2 +- ct/homer.sh | 2 +- ct/hyperion.sh | 3 +-- ct/influxdb.sh | 3 +-- ct/iobroker.sh | 3 +-- ct/k0s.sh | 3 +-- ct/keycloak.sh | 3 +-- ct/magicmirror.sh | 3 +-- ct/mariadb.sh | 3 +-- ct/meshcentral.sh | 3 +-- ct/motioneye.sh | 3 +-- ct/mqtt.sh | 3 +-- ct/n8n.sh | 3 +-- ct/navidrome.sh | 2 +- ct/nextcloudpi.sh | 3 +-- ct/nginxproxymanager.sh | 2 +- ct/nocodb.sh | 3 +-- ct/omada.sh | 3 +-- ct/omv.sh | 3 +-- ct/openhab.sh | 3 +-- ct/pihole.sh | 3 +-- ct/podman-homeassistant.sh | 3 +-- ct/podman.sh | 3 +-- ct/postgresql.sh | 3 +-- ct/prometheus.sh | 3 +-- ct/rockylinux.sh | 2 +- ct/scrypted.sh | 3 +-- ct/syncthing.sh | 3 +-- ct/technitiumdns.sh | 2 +- ct/trilium.sh | 2 +- ct/unifi.sh | 3 +-- ct/uptimekuma.sh | 2 +- ct/whoogle.sh | 3 +-- ct/wikijs.sh | 2 +- ct/wireguard.sh | 3 +-- 46 files changed, 46 insertions(+), 76 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index b90049bc..4c7db3a7 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -74,7 +74,7 @@ msg_ok "Started AdguardHome" msg_info "Cleaning Up" rm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup msg_ok "Cleaned" -msg_ok "Update Successful" +msg_ok "Updated Successfully" exit } diff --git a/ct/archlinux.sh b/ct/archlinux.sh index 62f04bb3..a28cfed3 100644 --- a/ct/archlinux.sh +++ b/ct/archlinux.sh @@ -356,7 +356,7 @@ msg_info "Updating ${APP} LXC" pacman-key --init pacman-key --populate archlinux pacman -Sy archlinux-keyring && pacman -Su -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 3261b560..b92412f0 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -67,7 +67,7 @@ msg_ok "Updated ${APP} LXC" msg_info "Starting ${APP} LXC" systemctl start autobrr.service msg_ok "Started ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/changedetection.sh b/ct/changedetection.sh index c8da20ae..80748b5e 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -55,8 +55,7 @@ header_info if [[ ! -f /etc/systemd/system/changedetection.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" pip3 install changedetection.io --upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/dashy.sh b/ct/dashy.sh index 5c76cf70..69385bd4 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -82,7 +82,7 @@ msg_ok "Cleaned" msg_info "Starting Dashy" systemctl start dashy msg_ok "Started Dashy" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/emby.sh b/ct/emby.sh index 2e617cfb..63abf748 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -67,7 +67,7 @@ msg_ok "Updated ${APP}" msg_info "Starting ${APP}" systemctl start emby-server msg_ok "Started ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/esphome.sh b/ct/esphome.sh index cd6e56d2..2bbd3d4d 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -64,7 +64,7 @@ msg_ok "Updated ESPHome" msg_info "Starting ESPHome" systemctl start esphomeDashboard msg_ok "Started ESPHome" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/grafana.sh b/ct/grafana.sh index ea1136c5..e1164a01 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -59,8 +59,7 @@ wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee /etc/apt/sources.list.d/grafana.list apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/grocy.sh b/ct/grocy.sh index dd30c554..6e0a66d9 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -55,8 +55,7 @@ header_info if [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" bash /var/www/html/update.sh -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index aad87f46..c06501f3 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -136,7 +136,7 @@ msg_info "Starting ${APP}" systemctl enable --now heimdall.service &>/dev/null sleep 2 msg_ok "Started ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 22039d22..36281e8e 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -56,8 +56,7 @@ if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/homepage.sh b/ct/homepage.sh index e8041087..13b4fca6 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -63,7 +63,7 @@ git pull --force &>/dev/null pnpm install &>/dev/null pnpm build &>/dev/null systemctl start homepage -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/homer.sh b/ct/homer.sh index 217b2800..34bf6620 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -80,7 +80,7 @@ msg_ok "Cleaned" msg_info "Starting ${APP}" systemctl start homer msg_ok "Started ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 92535765..51108e46 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -57,8 +57,7 @@ if [[ ! -f /etc/apt/sources.list.d/hyperion.list ]]; then msg_error "No ${APP} I msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get install -y hyperion &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/influxdb.sh b/ct/influxdb.sh index e945cdde..1505020a 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -60,8 +60,7 @@ echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https rm -f /etc/apt/trusted.gpg.d/influxdb.gpg apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 841f135e..d715199a 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -56,8 +56,7 @@ if [[ ! -d /opt/iobroker ]]; then msg_error "No ${APP} Installation Found!"; exi msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/k0s.sh b/ct/k0s.sh index 75b5648a..1d64a0ce 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -56,8 +56,7 @@ if [[ ! -f /etc/k0s/k0s.yaml ]]; then msg_error "No ${APP} Installation Found!"; msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 4488dd1a..218f56f4 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -57,8 +57,7 @@ if [[ ! -f /etc/systemd/system/keycloak.service ]]; then msg_error "No ${APP} In msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index c57121c2..2554bd1b 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -58,8 +58,7 @@ msg_info "Updating ${APP} LXC" cd /opt/magicmirror git pull &>/dev/null npm install --only=prod --omit=dev &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/mariadb.sh b/ct/mariadb.sh index d6894ed9..03e24726 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -56,8 +56,7 @@ if [[ ! -f /etc/apt/sources.list.d/mariadb.list ]]; then msg_error "No ${APP} In msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 2739b517..a9288d90 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -56,8 +56,7 @@ if [[ ! -d /opt/meshcentral ]]; then msg_error "No ${APP} Installation Found!"; msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 4a106f03..e46e9fd4 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -55,8 +55,7 @@ header_info if [[ ! -f /etc/systemd/system/motioneye.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" pip install motioneye --upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 0dde1c0e..0eb3c974 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -56,8 +56,7 @@ if [[ ! -f /etc/apt/sources.list.d/mosquitto-bullseye.list ]]; then msg_error "N msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/n8n.sh b/ct/n8n.sh index d4862ef1..58e56db7 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -56,8 +56,7 @@ header_info if [[ ! -f /etc/systemd/system/n8n.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" npm update -g n8n &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/navidrome.sh b/ct/navidrome.sh index c9e53584..10c308c3 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -67,7 +67,7 @@ rm Navidrome.tar.gz msg_info "${GN} Starting ${APP}" systemctl start navidrome.service msg_ok "Started ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index a1718208..8e18cc2a 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -56,8 +56,7 @@ if [[ ! -f /lib/systemd/system/nextcloud-domain.service ]]; then msg_error "No $ msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index defdbde9..89b0382d 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -174,7 +174,7 @@ EOF rm -rf ~/nginx-proxy-manager-* s6-overlay-noarch.tar.xz s6-overlay-x86_64.tar.xz msg_ok "Cleaned" - msg_ok "Update Successfull" + msg_ok "Updated Successfully" exit } diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 4b7636f6..bcfcdc7b 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -58,8 +58,7 @@ cd /opt/nocodb npm uninstall -s --save nocodb &>/dev/null npm install -s --save nocodb &>/dev/null systemctl restart nocodb.service -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/omada.sh b/ct/omada.sh index 104183df..3b02947e 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -56,8 +56,7 @@ if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/omv.sh b/ct/omv.sh index 532df042..7b31de75 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -57,8 +57,7 @@ if [[ ! -f /etc/apt/sources.list.d/openmediavault.list ]]; then msg_error "No ${ msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/openhab.sh b/ct/openhab.sh index 21a77dc7..d4c33704 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -57,8 +57,7 @@ if [[ ! -f /etc/apt/sources.list.d/openhab.list ]]; then msg_error "No ${APP} In msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/pihole.sh b/ct/pihole.sh index 07e786ea..d5233719 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -56,8 +56,7 @@ if [[ ! -d /etc/pihole ]]; then msg_error "No ${APP} Installation Found!"; exit; msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index e806a7a8..fbdc906e 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -67,8 +67,7 @@ if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null - msg_ok "Updated ${APP} LXC" - msg_ok "Update os system Successfull" + msg_ok "Updated Successfully" msg_info "Updating All Containers\n" CONTAINER_LIST="${1:-$(podman ps -q)}" diff --git a/ct/podman.sh b/ct/podman.sh index b4297c51..b313e673 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -56,8 +56,7 @@ if [[ ! -f /etc/containers/registries.conf ]]; then msg_error "No ${APP} Install msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/postgresql.sh b/ct/postgresql.sh index f0b606a1..700ad409 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -56,8 +56,7 @@ if [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then msg_error "No ${APP} Insta msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 16f17758..571a18bb 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -56,8 +56,7 @@ if [[ ! -f /etc/systemd/system/prometheus.service ]]; then msg_error "No ${APP} msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index edc69291..38700c95 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -57,7 +57,7 @@ if [[ ! -d /etc/pacman.d ]]; then msg_error "No ${APP} Installation Found!"; exi msg_info "Updating ${APP} LXC" dnf -y update dnf -y upgrade -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/scrypted.sh b/ct/scrypted.sh index d307d78c..f4b7d0ee 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -57,8 +57,7 @@ if [[ ! -f /etc/systemd/system/scrypted.service ]]; then msg_error "No ${APP} In msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/syncthing.sh b/ct/syncthing.sh index 292cf4db..4df4d33a 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -57,8 +57,7 @@ if [[ ! -f /etc/apt/sources.list.d/syncthing.list ]]; then msg_error "No ${APP} msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index f947cd07..7c9d30f4 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -66,7 +66,7 @@ wget -q https://download.technitium.com/dns/DnsServerPortable.tar.gz tar -zxf DnsServerPortable.tar.gz -C /etc/dns/ &>/dev/null rm -rf DnsServerPortable.tar.gz systemctl restart dns.service -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/trilium.sh b/ct/trilium.sh index 3e15c458..350a945e 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -76,7 +76,7 @@ msg_info "Starting ${APP}" systemctl start trilium.service sleep 1 msg_ok "Started ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/unifi.sh b/ct/unifi.sh index 542f1f87..cb8f2e68 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -56,8 +56,7 @@ if [[ ! -d /usr/lib/unifi ]]; then msg_error "No ${APP} Installation Found!"; ex msg_info "Updating ${APP}" wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh bash unifi-update.sh -msg_ok "Updated ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 4f64ecc3..d7d1cc0f 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -74,7 +74,7 @@ msg_ok "Updated ${APP}" msg_info "Starting ${APP}" sudo systemctl start uptime-kuma &>/dev/null msg_ok "Started ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/whoogle.sh b/ct/whoogle.sh index e93b19d7..bb4257ec 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -55,8 +55,7 @@ header_info if [[ ! -f /usr/local/bin/whoogle-search ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" pip3 install whoogle-search --upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/wikijs.sh b/ct/wikijs.sh index e1ac9863..416e54ee 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -79,7 +79,7 @@ msg_ok "Restored Data" msg_info "Starting ${APP}" systemctl start wikijs msg_ok "Started ${APP}" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit } diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 553de4e5..d6a6b48e 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -61,8 +61,7 @@ if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_ok "Update Successfull" +msg_ok "Updated Successfully" exit fi if [ "$UPD" == "2" ]; then From bd7c1ee7dbdefc7c4edff8f3c6932a6bcb532c2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Apr 2023 10:53:30 -0400 Subject: [PATCH 4647/6505] Update nextcloudpi-install.sh set `memory_limit = 512M` --- install/nextcloudpi-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh index 0e73cb55..a2ac437c 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-install.sh @@ -23,6 +23,7 @@ msg_info "Installing NextCloudPi (Patience)" $STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php sed -i '{s|root:/usr/sbin/nologin|root:/bin/bash|g}' /etc/passwd +sed -i 's/memory_limit = .*/memory_limit = 512M/' /etc/php/8.1/fpm/php.ini /etc/php/8.1/cli/php.ini service apache2 restart msg_ok "Installed NextCloudPi" From 9aade4f6a78f92c62c9267d441c7a63337914b6b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Apr 2023 01:03:18 -0400 Subject: [PATCH 4648/6505] Update kavita-install.sh --- install/kavita-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install/kavita-install.sh b/install/kavita-install.sh index b46f819a..af0e6bba 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -22,7 +22,9 @@ msg_ok "Installed Dependencies" msg_info "Installing Kavita" cd /opt RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) +wget -q https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz +$STD tar -xvf kavita-linux-x64.tar.gz +rm kavita-linux-x64.tar.gz msg_ok "Installed Kavita" msg_info "Creating Service" From 92f58314ffcd7384f3ddf367b883d6b78aeb6801 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Apr 2023 01:07:17 -0400 Subject: [PATCH 4649/6505] Update kavita-install.sh --- install/kavita-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/kavita-install.sh b/install/kavita-install.sh index af0e6bba..59886f1c 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -23,7 +23,7 @@ msg_info "Installing Kavita" cd /opt RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget -q https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz -$STD tar -xvf kavita-linux-x64.tar.gz +$STD tar -xvzf kavita-linux-x64.tar.gz rm kavita-linux-x64.tar.gz msg_ok "Installed Kavita" From 488322bf2a9150642ec4c33329e54d39d210d9e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Apr 2023 01:20:31 -0400 Subject: [PATCH 4650/6505] Update kavita-install.sh --- install/kavita-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/kavita-install.sh b/install/kavita-install.sh index 59886f1c..3f119a0e 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -23,7 +23,7 @@ msg_info "Installing Kavita" cd /opt RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget -q https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz -$STD tar -xvzf kavita-linux-x64.tar.gz +tar -xvzf kavita-linux-x64.tar.gz &>/dev/null rm kavita-linux-x64.tar.gz msg_ok "Installed Kavita" From 8a780c67f80dd552de09c78484b313f7c87e937c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Apr 2023 01:58:56 -0400 Subject: [PATCH 4651/6505] Update kavita-install.sh fix unprivileged install --- install/kavita-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install/kavita-install.sh b/install/kavita-install.sh index 3f119a0e..eaf48992 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -22,9 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Kavita" cd /opt RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -wget -q https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz -tar -xvzf kavita-linux-x64.tar.gz &>/dev/null -rm kavita-linux-x64.tar.gz +$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) --no-same-owner msg_ok "Installed Kavita" msg_info "Creating Service" From 1e23eb23be1c6e6d2fcf32cca8659b84e4bba612 Mon Sep 17 00:00:00 2001 From: ka2er Date: Thu, 20 Apr 2023 08:05:51 +0200 Subject: [PATCH 4652/6505] ENH : point webdriver to 127.0.0.1:4444/wd/hub instead of browser-chrome:4444/wd/hub (#1349) --- install/changedetection-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index fc9832c7..53c78041 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -34,6 +34,7 @@ After=network-online.target [Service] Type=simple WorkingDirectory=/opt/changedetection +Environment="WEBDRIVER_URL=http://127.0.0.1:4444/wd/hub" ExecStart=changedetection.io -d /opt/changedetection -p 5000 [Install] WantedBy=multi-user.target From bb7c08e0fe8d994fadffd6aca718b2360a83c161 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Apr 2023 02:12:48 -0400 Subject: [PATCH 4653/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 6f66327b..fadae182 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -13,3 +13,5 @@ [Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/04/installing-home-assistant-on-proxmox-quick-start-guide.html) [Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html) + +[Proxmox: Plex LXC with Alder Lake Transcoding](https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html) From 90b7a7f2d9bb8fe9e3e7cee0478f76a5b1738898 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:07:02 -0400 Subject: [PATCH 4654/6505] Update and rename bug_report.md to bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.md | 16 -------------- .github/ISSUE_TEMPLATE/bug_report.yaml | 29 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 16 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index dae485c8..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve (script related) -title: '' -labels: '' -assignees: '' - ---- - -**Describe the issue** -A clear and concise description of what the bug is. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Bug reports will be closed after 12 hours of NO activity.** diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 00000000..91a749f7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,29 @@ +name: Bug report +description: Create a report to help us improve (script related) +body: + - type: markdown + attributes: + value: | + **IMPORTANT:** Before submitting: + - Please search through the closed issues to see if the bug you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. + - type: textarea + id: bug + attributes: + label: A clear and concise description of the bug. + validations: + required: true + - type: textarea + id: expect_to_happen + attributes: + label: A clear and concise description of what you expected to happen. + placeholder: I expected that ... + validations: + required: false + - type: textarea + id: reproduce + attributes: + label: Please provide detailed steps to reproduce the issue. + placeholder: First do this, then this.. + validations: + required: false + From 5ab4f10f9f30d1cb08729098442130cb56e0832c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:14:12 -0400 Subject: [PATCH 4655/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 91a749f7..adc9af1a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -12,6 +12,12 @@ body: label: A clear and concise description of the bug. validations: required: true + - type: textarea + id: screenshot + attributes: + label: If applicable, add screenshots to help explain the issue. + validations: + required: false - type: textarea id: expect_to_happen attributes: @@ -26,4 +32,3 @@ body: placeholder: First do this, then this.. validations: required: false - From 1da3bcb81778e32fa9d60c11f9aeb93e4fccf187 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:22:16 -0400 Subject: [PATCH 4656/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index adc9af1a..cc13c3ad 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -15,7 +15,7 @@ body: - type: textarea id: screenshot attributes: - label: If applicable, add screenshots to help explain the issue. + label: If relevant, including screenshots or a code block can be helpful in clarifying the issue. validations: required: false - type: textarea From 233f7c80018b47fa4b7f022d4f84ee4cd914e8c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:28:47 -0400 Subject: [PATCH 4657/6505] Update and rename feature-script-request.md to feature-script-request.yaml --- .github/ISSUE_TEMPLATE/feature-script-request.md | 11 ----------- .github/ISSUE_TEMPLATE/feature-script-request.yaml | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/feature-script-request.md create mode 100644 .github/ISSUE_TEMPLATE/feature-script-request.yaml diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.md b/.github/ISSUE_TEMPLATE/feature-script-request.md deleted file mode 100644 index ddcfa3a4..00000000 --- a/.github/ISSUE_TEMPLATE/feature-script-request.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: Feature/Script Request -about: Suggest an idea for this project in Discussions -title: Please submit feature/script requests in Discussions -labels: Feature Request -assignees: tteck - ---- - -Please submit feature/script requests in Discussions -https://github.com/tteck/Proxmox/discussions diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.yaml b/.github/ISSUE_TEMPLATE/feature-script-request.yaml new file mode 100644 index 00000000..94c3b299 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-script-request.yaml @@ -0,0 +1,11 @@ +name: Feature/Script Request +about: Suggest an idea for this project in Discussions +title: Please submit feature/script requests in Discussions + +body: + - type: markdown + attributes: + value: | + **NOTICE:** + - If you have requests for features or scripts, please share them in the Discussions section. + From 3a5952431a164545af12af8df5ca97387cf44af4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:37:09 -0400 Subject: [PATCH 4658/6505] Update feature-script-request.yaml --- .github/ISSUE_TEMPLATE/feature-script-request.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.yaml b/.github/ISSUE_TEMPLATE/feature-script-request.yaml index 94c3b299..3534ec4b 100644 --- a/.github/ISSUE_TEMPLATE/feature-script-request.yaml +++ b/.github/ISSUE_TEMPLATE/feature-script-request.yaml @@ -8,4 +8,13 @@ body: value: | **NOTICE:** - If you have requests for features or scripts, please share them in the Discussions section. + - type: dropdown + validations: + required: false + attributes: + label: Discussions + description: > + Discussions + options: + - From 81daa5820b22f14c6b5afb4f282eb5e721b0fd70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:38:24 -0400 Subject: [PATCH 4659/6505] Update feature-script-request.yaml --- .github/ISSUE_TEMPLATE/feature-script-request.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.yaml b/.github/ISSUE_TEMPLATE/feature-script-request.yaml index 3534ec4b..70825921 100644 --- a/.github/ISSUE_TEMPLATE/feature-script-request.yaml +++ b/.github/ISSUE_TEMPLATE/feature-script-request.yaml @@ -11,10 +11,3 @@ body: - type: dropdown validations: required: false - attributes: - label: Discussions - description: > - Discussions - options: - - - From 1bfee11f7a85b2e75952558dddecffb0bb870bcd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:41:02 -0400 Subject: [PATCH 4660/6505] Update feature-script-request.yaml --- .github/ISSUE_TEMPLATE/feature-script-request.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.yaml b/.github/ISSUE_TEMPLATE/feature-script-request.yaml index 70825921..d64008c0 100644 --- a/.github/ISSUE_TEMPLATE/feature-script-request.yaml +++ b/.github/ISSUE_TEMPLATE/feature-script-request.yaml @@ -8,6 +8,9 @@ body: value: | **NOTICE:** - If you have requests for features or scripts, please share them in the Discussions section. - - type: dropdown + - type: textarea + id: feature + attributes: + label: Please submit feature/script requests in Discussions validations: required: false From d4aa6b0d07c4018c616fe066ca631759db512470 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:44:00 -0400 Subject: [PATCH 4661/6505] Update feature-script-request.yaml --- .github/ISSUE_TEMPLATE/feature-script-request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.yaml b/.github/ISSUE_TEMPLATE/feature-script-request.yaml index d64008c0..1da0d62b 100644 --- a/.github/ISSUE_TEMPLATE/feature-script-request.yaml +++ b/.github/ISSUE_TEMPLATE/feature-script-request.yaml @@ -1,5 +1,5 @@ name: Feature/Script Request -about: Suggest an idea for this project in Discussions +description: Suggest an idea for this project in Discussions title: Please submit feature/script requests in Discussions body: From 9463d406434d55b37f6c8025afe8766e38d15170 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:47:25 -0400 Subject: [PATCH 4662/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index cc13c3ad..98178a17 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -6,6 +6,7 @@ body: value: | **IMPORTANT:** Before submitting: - Please search through the closed issues to see if the bug you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. + - If you have requests for features or scripts, please share them in the Discussions section. - type: textarea id: bug attributes: From e6a104ad8b128b744f1babf93b60027acada1714 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:47:58 -0400 Subject: [PATCH 4663/6505] Delete feature-script-request.yaml --- .../ISSUE_TEMPLATE/feature-script-request.yaml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/feature-script-request.yaml diff --git a/.github/ISSUE_TEMPLATE/feature-script-request.yaml b/.github/ISSUE_TEMPLATE/feature-script-request.yaml deleted file mode 100644 index 1da0d62b..00000000 --- a/.github/ISSUE_TEMPLATE/feature-script-request.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: Feature/Script Request -description: Suggest an idea for this project in Discussions -title: Please submit feature/script requests in Discussions - -body: - - type: markdown - attributes: - value: | - **NOTICE:** - - If you have requests for features or scripts, please share them in the Discussions section. - - type: textarea - id: feature - attributes: - label: Please submit feature/script requests in Discussions - validations: - required: false From 93fc56336f97cf37ef1c4cae612dedf2dd91b2c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 13:57:28 -0400 Subject: [PATCH 4664/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 98178a17..56246301 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -6,7 +6,7 @@ body: value: | **IMPORTANT:** Before submitting: - Please search through the closed issues to see if the bug you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. - - If you have requests for features or scripts, please share them in the Discussions section. + - If you have requests for features or scripts, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: textarea id: bug attributes: From 90afb75199170c0ca2c394c0f4b8abc77af2505b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 14:40:03 -0400 Subject: [PATCH 4665/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 56246301..793c5779 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,16 +1,16 @@ -name: Bug report -description: Create a report to help us improve (script related) +name: Issue report +description: Generate a report on the issue pertaining specifically to the script in order to aid us in improving it. body: - type: markdown attributes: value: | **IMPORTANT:** Before submitting: - - Please search through the closed issues to see if the bug you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. + - Please search through the closed issues to see if the issue you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. - If you have requests for features or scripts, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: textarea id: bug attributes: - label: A clear and concise description of the bug. + label: A clear and concise description of the issue. validations: required: true - type: textarea @@ -30,6 +30,6 @@ body: id: reproduce attributes: label: Please provide detailed steps to reproduce the issue. - placeholder: First do this, then this.. + placeholder: First do this, then this ... validations: required: false From 3463abe13cadc2fab5c5f787eb0b8b4de2c7d399 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 14:43:05 -0400 Subject: [PATCH 4666/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 793c5779..9949dbb1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,4 +1,4 @@ -name: Issue report +name: Problems with a script. description: Generate a report on the issue pertaining specifically to the script in order to aid us in improving it. body: - type: markdown From 02c542d9dbd62024ccfd994e155537cb7713bb2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Apr 2023 18:54:12 -0400 Subject: [PATCH 4667/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 9949dbb1..e9641023 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -19,13 +19,6 @@ body: label: If relevant, including screenshots or a code block can be helpful in clarifying the issue. validations: required: false - - type: textarea - id: expect_to_happen - attributes: - label: A clear and concise description of what you expected to happen. - placeholder: I expected that ... - validations: - required: false - type: textarea id: reproduce attributes: From 0e9aa8e6200ec772b8232fe6fcf512980dff932e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Apr 2023 01:12:22 -0400 Subject: [PATCH 4668/6505] Update plex-install.sh move trusted.gpg --- install/plex-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/plex-install.sh b/install/plex-install.sh index 01744201..cabe3871 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -39,6 +39,7 @@ fi msg_info "Setting Up Plex Media Server Repository" $STD apt-key add <(curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key) sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" > /etc/apt/sources.list.d/plexmediaserver.list' +mv -f /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d/ &>/dev/null msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" From 52ce746cbeb2f8f8662de85ec6ded9ae38bc5000 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Apr 2023 05:31:32 -0400 Subject: [PATCH 4669/6505] Update plex-install.sh - The command apt-key is now considered deprecated, so migrate keyring to the new location with the new format. - Remove the unnecessary dependency gnupg --- install/plex-install.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/install/plex-install.sh b/install/plex-install.sh index cabe3871..127d4a11 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y gnupg msg_ok "Installed Dependencies" if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then @@ -37,9 +36,8 @@ if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then fi msg_info "Setting Up Plex Media Server Repository" -$STD apt-key add <(curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.key) -sh -c 'echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" > /etc/apt/sources.list.d/plexmediaserver.list' -mv -f /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d/ &>/dev/null +wget -qO- https://downloads.plex.tv/plex-keys/PlexSign.key >/etc/apt/trusted.gpg.d/PlexSign.asc +echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" >/etc/apt/sources.list.d/plexmediaserver.list msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" From 811589a470ba815493287dcdcbf125634eb1df8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Apr 2023 05:37:20 -0400 Subject: [PATCH 4670/6505] Update build.func Remove Ubuntu 18.04, which will reach EOL on April 30, 2023 --- misc/build.func | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index 43dd3fbe..f513ab21 100644 --- a/misc/build.func +++ b/misc/build.func @@ -114,8 +114,7 @@ exit-script() { advanced_settings() { if [ "$var_os" == "ubuntu" ]; then - if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 4 \ - "18.04" "Bionic" OFF \ + if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "20.04" "Focal" ON \ "22.04" "Jammy" OFF \ "22.10" "Kinetic" OFF \ From 775134c2595cc96aa669410207fef32519dce598 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Apr 2023 21:40:43 -0400 Subject: [PATCH 4671/6505] Update prometheus-install.sh correct path --- install/prometheus-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/prometheus-install.sh b/install/prometheus-install.sh index 4d3d77a2..118241fd 100644 --- a/install/prometheus-install.sh +++ b/install/prometheus-install.sh @@ -60,5 +60,5 @@ root msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean -rm -rf /root/prometheus-${RELEASE}.linux-amd64 /root/prometheus-${RELEASE}.linux-amd64.tar.gz +rm -rf ../prometheus-${RELEASE}.linux-amd64 ../prometheus-${RELEASE}.linux-amd64.tar.gz msg_ok "Cleaned" From fc89a4b42688e36cdb9f7ba0c95ea8efa8850062 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 10:56:37 -0400 Subject: [PATCH 4672/6505] Update blocky-install.sh pin to version 0.20 for now --- install/blocky-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/blocky-install.sh b/install/blocky-install.sh index aafff542..521156b7 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -22,7 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Blocky" systemctl stop systemd-resolved $STD systemctl disable systemd-resolved.service -RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +RELEASE=0.20 #$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_v${RELEASE}_Linux_x86_64.tar.gz mkdir -p /opt/blocky tar -xf blocky_v${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky From 3f309d3fda52359559e14f00894dc6c4bc07d0e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 11:07:23 -0400 Subject: [PATCH 4673/6505] Update blocky-install.sh fix path for older downloads --- install/blocky-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/blocky-install.sh b/install/blocky-install.sh index 521156b7..5e8821ec 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -23,7 +23,7 @@ msg_info "Installing Blocky" systemctl stop systemd-resolved $STD systemctl disable systemd-resolved.service RELEASE=0.20 #$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_v${RELEASE}_Linux_x86_64.tar.gz +wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz mkdir -p /opt/blocky tar -xf blocky_v${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky rm -rf blocky_v${RELEASE}_Linux_x86_64.tar.gz From ec321b76d9e86cd8eb365ebb1205754d1eada152 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 11:13:42 -0400 Subject: [PATCH 4674/6505] Update blocky-install.sh --- install/blocky-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/blocky-install.sh b/install/blocky-install.sh index 5e8821ec..3f0409bf 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -25,8 +25,8 @@ $STD systemctl disable systemd-resolved.service RELEASE=0.20 #$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz mkdir -p /opt/blocky -tar -xf blocky_v${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky -rm -rf blocky_v${RELEASE}_Linux_x86_64.tar.gz +tar -xf blocky_${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky +rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz cat </opt/blocky/config.yml upstream: # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query From 4744ccb562d2bc17450567176b8d590370ed72f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 11:26:27 -0400 Subject: [PATCH 4675/6505] Update plex.sh --- ct/plex.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/plex.sh b/ct/plex.sh index 48d12505..5e23d446 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -66,6 +66,7 @@ msg_ok "Updated ${APP} LXC" exit fi if [ "$UPD" == "2" ]; then +set +e bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)" exit fi From 34d311371c8c3c7ecbbc7e3b660366a4b7184016 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 18:09:32 -0400 Subject: [PATCH 4676/6505] Update build.func provide the option for users to switch between Debian and Ubuntu distributions --- misc/build.func | 67 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/misc/build.func b/misc/build.func index f513ab21..a464738b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -79,9 +79,8 @@ ssh_check() { } echo_default() { - if [ "$var_os" == "ubuntu" ]; then - echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" - fi + echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}" + echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" @@ -113,26 +112,56 @@ exit-script() { } advanced_settings() { + if [ "$var_os" != "alpine" ]; then + var_os="" + while [ -z "$var_os" ]; do + if var_os=$(whiptail --title "DISTRIBUTION" --radiolist "Choose" 10 58 2 \ + "debian" "" OFF \ + "ubuntu" "" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$var_os" ]; then + echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}" + fi + else + exit-script + fi + done + fi + + if [ "$var_os" == "debian" ]; then + var_version="11" + fi + if [ "$var_os" == "ubuntu" ]; then - if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ - "20.04" "Focal" ON \ - "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ + var_version="" + while [ -z "$var_version" ]; do + if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + "20.04" "Focal" OFF \ + "22.04" "Jammy" OFF \ + "22.10" "Kinetic" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$var_version" ]; then + echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" + fi + else + exit-script + fi + done + fi + + CT_TYPE="" + while [ -z "$CT_TYPE" ]; do + if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + "1" "Unprivileged" OFF \ + "0" "Privileged" OFF \ 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" + if [ -n "$CT_TYPE" ]; then + echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" + fi else exit-script fi - fi - - if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" - else - exit-script - fi + done if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then @@ -468,7 +497,7 @@ EOF sleep 2 pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi - lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit + lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/install/$var_install.sh)" || exit } From 83c7091d21bdac069a24e911cb91958c241f5796 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 18:12:25 -0400 Subject: [PATCH 4677/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7f240e60..d43b2266 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-23 + +### Changed + +- **Non-Alpine LXC's** + - Advanced settings provide the option for users to switch between Debian and Ubuntu distributions. However, some applications or services, such as Deconz or Omada, may not be compatible with the selected distribution due to dependencies. + ## 2023-04-16 ### Changed From ab48d60861e95b32c554af59b4deef80fa2c33d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 18:13:25 -0400 Subject: [PATCH 4678/6505] Update build.func fix branch --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index a464738b..8eeeac53 100644 --- a/misc/build.func +++ b/misc/build.func @@ -497,7 +497,7 @@ EOF sleep 2 pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi - lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/dev/install/$var_install.sh)" || exit + lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit } From e31ddbac140b41c613efb1a00755c2f1bd124ddb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 18:19:05 -0400 Subject: [PATCH 4679/6505] Update build.func tweak --- misc/build.func | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 8eeeac53..1643c42a 100644 --- a/misc/build.func +++ b/misc/build.func @@ -130,6 +130,7 @@ advanced_settings() { if [ "$var_os" == "debian" ]; then var_version="11" + echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" fi if [ "$var_os" == "ubuntu" ]; then @@ -141,7 +142,7 @@ advanced_settings() { "22.10" "Kinetic" OFF \ 3>&1 1>&2 2>&3); then if [ -n "$var_version" ]; then - echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}" + echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" fi else exit-script From d8809c9e801a57afa017be8fb0c6dc9e784247fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Apr 2023 18:34:36 -0400 Subject: [PATCH 4680/6505] Update plex.sh set default Ubuntu 22.04 --- ct/plex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex.sh b/ct/plex.sh index 5e23d446..bcc7d96d 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="ubuntu" -var_version="20.04" +var_version="22.04" variables color catch_errors From 899c015fb9f202398238f4ecda43fdff18cafb45 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Apr 2023 12:06:45 -0400 Subject: [PATCH 4681/6505] Update post-pve-install.sh Code refactoring --- misc/post-pve-install.sh | 226 ++++++++++++++++++++++++++++----------- 1 file changed, 163 insertions(+), 63 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 2e03f852..e4787cad 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -5,8 +5,9 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -function header_info { - cat <<"EOF" +header_info() { + clear + cat <<"EOF" ____ _ _____________ ____ __ ____ __ ____ / __ \ | / / ____/__ / / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / @@ -15,120 +16,219 @@ function header_info { EOF } -set -euo pipefail -shopt -s inherit_errexit nullglob -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") +YW=$(echo "\033[33m") GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -clear -header_info -echo -e "${BL}This script will Perform Post Install Routines.${CL}" -while true; do - read -p "Start the PVE7 Post Install Script (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -if ! command -v pveversion >/dev/null 2>&1; then - echo -e "\n🛑 No PVE Detected, Wrong Script!\n" - exit 1 -fi +set -euo pipefail +shopt -s inherit_errexit nullglob -if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then - echo -e "\n${RD}⚠ This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version: 7.XX${CL}" - echo -e "\nExiting..." - sleep 3 - exit -fi - -function msg_info() { +msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } -function msg_ok() { +msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -clear -header_info -read -r -p "Disable Enterprise Repository? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +exit_script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +start_routines() { + header_info + CHOICE=$( + whiptail --title "Proxmox VE 7 Post Install" --menu "\nDisable Enterprise Repository?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + exit_script + fi + case $CHOICE in + yes) msg_info "Disabling Enterprise Repository" - sleep 2 sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list msg_ok "Disabled Enterprise Repository" -fi + ;; + no) + msg_error "Selected no to Disabling Enterprise Repository" + ;; + esac -read -r -p "Add/Correct PVE7 Sources (sources.list)? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + CHOICE=$( + whiptail --title "Proxmox VE 7 Post Install" --menu "\nAdd/Correct PVE7 Sources (sources.list)?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + exit_script + fi + case $CHOICE in + yes) msg_info "Adding or Correcting PVE7 Sources" cat </etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib deb http://ftp.debian.org/debian bullseye-updates main contrib deb http://security.debian.org/debian-security bullseye-security main contrib EOF - sleep 2 msg_ok "Added or Corrected PVE7 Sources" -fi + ;; + no) + msg_error "Selected no to Correcting PVE7 Sources" + ;; + esac - -read -r -p "Enable No-Subscription Repository? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + CHOICE=$( + whiptail --title "Proxmox VE 7 Post Install" --menu "\nEnable No-Subscription Repository?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + exit_script + fi + case $CHOICE in + yes) msg_info "Enabling No-Subscription Repository" cat <>/etc/apt/sources.list deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription EOF - sleep 2 msg_ok "Enabled No-Subscription Repository" -fi + ;; + no) + msg_error "Selected no to Enabling No-Subscription Repository" + ;; + esac -read -r -p "Add (Disabled) Beta/Test Repository? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + CHOICE=$( + whiptail --title "Proxmox VE 7 Post Install" --menu "\nAdd (Disabled) Beta/Test Repository?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + exit_script + fi + case $CHOICE in + yes) msg_info "Adding Beta/Test Repository and set disabled" cat <>/etc/apt/sources.list # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF - sleep 2 msg_ok "Added Beta/Test Repository" -fi + ;; + no) + msg_error "Selected no to Adding Beta/Test Repository" + ;; + esac -read -r -p "Disable Subscription Nag? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + CHOICE=$( + whiptail --title "Proxmox VE 7 Post Install" --menu "\nDisable Subscription Nag?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + exit_script + fi + case $CHOICE in + yes) msg_info "Disabling Subscription Nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled Subscription Nag (Delete browser cache)" -fi + ;; + no) + msg_error "Selected no to Disabling Subscription Nag" + ;; + esac -read -r -p "Update Proxmox VE 7 now? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + CHOICE=$( + whiptail --title "Proxmox VE 7 Post Install" --menu "\nUpdate Proxmox VE 7 now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + exit_script + fi + case $CHOICE in + yes) msg_info "Updating Proxmox VE 7 (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null - msg_ok "Updated Proxmox VE 7 (⚠ Reboot Recommended)" -fi + msg_ok "Updated Proxmox VE 7 (Reboot Recommended)" + ;; + no) + msg_error "Selected no to Updating Proxmox VE 7" + ;; + esac -read -r -p "Reboot Proxmox VE 7 now? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + CHOICE=$( + whiptail --title "Proxmox VE 7 Post Install" --menu "\nReboot Proxmox VE 7 now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3 + ) + exit_status=$? + if [ $exit_status == 1 ]; then + exit_script + fi + case $CHOICE in + yes) msg_info "Rebooting Proxmox VE 7" sleep 2 msg_ok "Completed Post Install Routines" reboot + ;; + no) + msg_error "Selected no to Rebooting Proxmox VE 7" + msg_ok "Completed Post Install Routines" + ;; + esac +} + +header_info +echo -e "\nThis script will Perform Post Install Routines.\n" +while true; do + read -p "Start the PVE7 Post Install Script (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit_script ;; + *) echo "Please answer yes or no." ;; + esac +done + +if ! command -v pveversion >/dev/null 2>&1; then + header_info + msg_error "\n No PVE Detected!\n" + exit fi -sleep 2 -msg_ok "Completed Post Install Routines" +if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then + header_info + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e " Requires PVE Version: 7.XX" + echo -e "\nExiting..." + sleep 3 + exit +fi + +start_routines From e09d96287cf68817304f096dc7c52abc76db0384 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Apr 2023 21:05:10 -0400 Subject: [PATCH 4682/6505] Update post-pve-install.sh add description --- misc/post-pve-install.sh | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index e4787cad..e8fae97f 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -53,7 +53,7 @@ exit_script() { start_routines() { header_info CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "\nDisable Enterprise Repository?" 11 58 2 \ + whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3 ) @@ -63,17 +63,17 @@ start_routines() { fi case $CHOICE in yes) - msg_info "Disabling Enterprise Repository" + msg_info "Disabling 'pve-enterprise' repository" sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list - msg_ok "Disabled Enterprise Repository" + msg_ok "Disabled 'pve-enterprise' repository" ;; no) - msg_error "Selected no to Disabling Enterprise Repository" + msg_error "Selected no to Disabling 'pve-enterprise' repository" ;; esac CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "\nAdd/Correct PVE7 Sources (sources.list)?" 11 58 2 \ + whiptail --title "Proxmox VE 7 Post Install" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 7 server.\n \nCorrect Proxmox VE 7 sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3 ) @@ -83,21 +83,21 @@ start_routines() { fi case $CHOICE in yes) - msg_info "Adding or Correcting PVE7 Sources" + msg_info "Correcting Proxmox VE 7 Sources" cat </etc/apt/sources.list deb http://ftp.debian.org/debian bullseye main contrib deb http://ftp.debian.org/debian bullseye-updates main contrib deb http://security.debian.org/debian-security bullseye-security main contrib EOF - msg_ok "Added or Corrected PVE7 Sources" + msg_ok "Corrected Proxmox VE 7 Sources" ;; no) - msg_error "Selected no to Correcting PVE7 Sources" + msg_error "Selected no to Correcting Proxmox VE 7 Sources" ;; esac CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "\nEnable No-Subscription Repository?" 11 58 2 \ + whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3 ) @@ -107,19 +107,19 @@ EOF fi case $CHOICE in yes) - msg_info "Enabling No-Subscription Repository" + msg_info "Enabling 'pve-no-subscription' repository" cat <>/etc/apt/sources.list deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription EOF - msg_ok "Enabled No-Subscription Repository" + msg_ok "Enabled 'pve-no-subscription' repository" ;; no) - msg_error "Selected no to Enabling No-Subscription Repository" + msg_error "Selected no to Enabling 'pve-no-subscription' repository" ;; esac CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "\nAdd (Disabled) Beta/Test Repository?" 11 58 2 \ + whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3 ) @@ -129,19 +129,19 @@ EOF fi case $CHOICE in yes) - msg_info "Adding Beta/Test Repository and set disabled" + msg_info "Adding 'pvetest' repository and set disabled" cat <>/etc/apt/sources.list # deb http://download.proxmox.com/debian/pve bullseye pvetest EOF - msg_ok "Added Beta/Test Repository" + msg_ok "Added 'pvetest' repository" ;; no) - msg_error "Selected no to Adding Beta/Test Repository" + msg_error "Selected no to Adding 'pvetest' repository" ;; esac CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "\nDisable Subscription Nag?" 11 58 2 \ + whiptail --title "Proxmox VE 7 Post Install" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3 ) @@ -151,13 +151,13 @@ EOF fi case $CHOICE in yes) - msg_info "Disabling Subscription Nag" + msg_info "Disabling subscription nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null - msg_ok "Disabled Subscription Nag (Delete browser cache)" + msg_ok "Disabled subscription nag (Delete browser cache)" ;; no) - msg_error "Selected no to Disabling Subscription Nag" + msg_error "Selected no to Disabling subscription nag" ;; esac @@ -175,7 +175,7 @@ EOF msg_info "Updating Proxmox VE 7 (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null - msg_ok "Updated Proxmox VE 7 (Reboot Recommended)" + msg_ok "Updated Proxmox VE 7 (Reboot recommended)" ;; no) msg_error "Selected no to Updating Proxmox VE 7" @@ -208,7 +208,7 @@ EOF header_info echo -e "\nThis script will Perform Post Install Routines.\n" while true; do - read -p "Start the PVE7 Post Install Script (y/n)?" yn + read -p "Start the Proxmox VE 7 Post Install Script (y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit_script ;; From ec99f941fe61f7ae75df0d9abd3e00e528ad1e00 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Apr 2023 04:24:08 -0400 Subject: [PATCH 4683/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index e9641023..1157d709 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -6,6 +6,8 @@ body: value: | **IMPORTANT:** Before submitting: - Please search through the closed issues to see if the issue you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. + - Switching Linux distributions without verifying that the default settings function properly, may lead to immediate closure. + - Failing to run the script in verbose mode to determine the actual issue, while encountering the error message `[ERROR] in line 22: exit code *: while executing command "$@" > /dev/null 2>&1`, may lead to immediate closure. - If you have requests for features or scripts, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: textarea id: bug From 22300b0c4de9e64b5961ec22f5f03a35fa36c6f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Apr 2023 04:51:39 -0400 Subject: [PATCH 4684/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d43b2266..69cc48ab 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Changed - **Non-Alpine LXC's** - - Advanced settings provide the option for users to switch between Debian and Ubuntu distributions. However, some applications or services, such as Deconz or Omada, may not be compatible with the selected distribution due to dependencies. + - Advanced settings provide the option for users to switch between Debian and Ubuntu distributions. However, some applications or services, such as Deconz, grocy or Omada, may not be compatible with the selected distribution due to dependencies. ## 2023-04-16 From 70d51d964df90b425c9ed5da66ae723c19c83cb6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Apr 2023 05:51:55 -0400 Subject: [PATCH 4685/6505] Update build.func add default distribution message box --- misc/build.func | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 1643c42a..4859554b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -112,10 +112,11 @@ exit-script() { } advanced_settings() { + whiptail --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n" 8 58 if [ "$var_os" != "alpine" ]; then var_os="" while [ -z "$var_os" ]; do - if var_os=$(whiptail --title "DISTRIBUTION" --radiolist "Choose" 10 58 2 \ + if var_os=$(whiptail --title "DISTRIBUTION" --radiolist "Choose Distribution:" 10 58 2 \ "debian" "" OFF \ "ubuntu" "" OFF \ 3>&1 1>&2 2>&3); then From 513049c50b9dfd78012fef52bfa55052429714d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Apr 2023 05:38:40 -0400 Subject: [PATCH 4686/6505] Update pimox-haos-vm.sh update pve_check --- vm/pimox-haos-vm.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index ca69e858..fff2fa52 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -79,10 +79,10 @@ else exit fi function PVE_CHECK() { - if [ $(pveversion | grep "pve-manager/7.2\|7.3" | wc -l) -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: =>7.2" - echo "Exiting..." + if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." sleep 2 exit fi From 5569d7039883b82af5b444be1d5acfa24efe9487 Mon Sep 17 00:00:00 2001 From: Adam Maracz Date: Wed, 26 Apr 2023 11:40:14 +0200 Subject: [PATCH 4687/6505] updated cleanup with current omada version (#1365) --- install/omada-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index 0bc5fe85..6a359884 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -33,7 +33,7 @@ motd_ssh root msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_v5.9.9_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb +rm -f Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From a4f2aa59e25009c3978ced4b8dd8914c5e2d1c43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Apr 2023 09:05:28 -0400 Subject: [PATCH 4688/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 69cc48ab..2e77f146 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,12 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-26 + +### Changed + +- **The site can now be accessed through a more memorable URL, which is [helper-scripts.com](http://helper-scripts.com).** + ## 2023-04-23 ### Changed From 10deb58fcbd8370059f498a6584ccbc6e3842d32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Apr 2023 14:26:45 -0400 Subject: [PATCH 4689/6505] Update homepage-install.sh Switching from building a release to building from source --- install/homepage-install.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 3800244f..7cabc3c3 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -30,12 +30,8 @@ $STD npm install -g pnpm msg_ok "Installed Node.js" msg_info "Installing Homepage (Patience)" -RELEASE=$(curl -s https://api.github.com/repos/benphelps/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -q https://github.com/benphelps/homepage/archive/refs/tags/v${RELEASE}.tar.gz -$STD tar -xvf v${RELEASE}.tar.gz -mkdir -p /opt/homepage -cp -r homepage-${RELEASE}/* /opt/homepage -rm -rf v${RELEASE}.tar.gz homepage-${RELEASE} +cd /opt +$STD git clone https://github.com/benphelps/homepage.git cd /opt/homepage mkdir -p config cp /opt/homepage/src/skeleton/* /opt/homepage/config From 13e65979ee9d467798fdac89f9065f46827769b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Apr 2023 01:34:39 -0400 Subject: [PATCH 4690/6505] Update nginxproxymanager.sh enable services after update fixes https://github.com/tteck/Proxmox/issues/1368 --- ct/nginxproxymanager.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 89b0382d..4425570c 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -165,9 +165,8 @@ EOF msg_info "Starting Services" sed -i -e 's/^pid/#pid/' -e 's/npmuser/root/' /usr/local/openresty/nginx/conf/nginx.conf sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg - systemctl enable npm &>/dev/null - systemctl start openresty - systemctl start npm + systemctl enable -q --now openresty + systemctl enable -q --now npm msg_ok "Started Services" msg_info "Cleaning up" From f74869108c0c1a5a1a181a80de96c595666c265f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Apr 2023 01:48:35 -0400 Subject: [PATCH 4691/6505] Update update-lxcs.sh silent `apt update` and show `apt list --upgradable` --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index b1a6827a..8f2daf58 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -45,7 +45,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm";; fedora|rocky|centos|alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update && apt-get -y dist-upgrade" ;; + ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; esac } header_info From 700717da430ed6a6cd57894fce17895bf3887ba1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Apr 2023 16:45:11 -0400 Subject: [PATCH 4692/6505] Create monitor-lxcs.sh --- misc/monitor-lxcs.sh | 89 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 misc/monitor-lxcs.sh diff --git a/misc/monitor-lxcs.sh b/misc/monitor-lxcs.sh new file mode 100644 index 00000000..74ab9b0b --- /dev/null +++ b/misc/monitor-lxcs.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Proxmox VE LXC Monitor +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/monitor-lxcs.sh)" + +clear +cat <<"EOF" + __ ___ _ __ __ _ ________ + / |/ /___ ____ (_) /_____ _____ / / | |/ / ____/ + / /|_/ / __ \/ __ \/ / __/ __ \/ ___/ / / | / / + / / / / /_/ / / / / / /_/ /_/ / / / /___/ / /___ +/_/ /_/\____/_/ /_/_/\__/\____/_/ /_____/_/|_\____/ + +EOF + +while true; do + read -p "This script will add Monitor LXC to Proxmox VE. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +echo '#!/usr/bin/env bash +while true +do + # Get the list of containers + containers=$(pct list | tail -n +2 | cut -f1 -d" ") + + for container in $containers + do + # Skip containers based on templates + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "true" ]; then + continue + fi + + # Get the IP address of the container + IP=$(pct exec $container ip a s dev eth0 | awk '\''/inet / {print $2}'\'' | cut -d/ -f1) + + # Ping the container + if ! ping -c 1 $IP >/dev/null 2>&1; then + # If the container can'\''t be pinged, stop and start it + echo -e "$(date): Container $container is not responding, restarting..." + pct stop $container >/dev/null 2>&1 + sleep 5 + pct start $container >/dev/null 2>&1 + fi + done + + # Wait for 5 minutes + echo -e "$(date): Sleeping for 5 minutes..." + sleep 300 +done >> /var/log/ping-containers.log 2>&1' >/usr/local/bin/ping-containers.sh + +# Change the permissions +chmod +x /usr/local/bin/ping-containers.sh + +# Create service +echo '[Unit] +Description=Pings containers every 5 minutes and restarts if necessary + +[Service] +Type=simple +ExecStart=/usr/local/bin/ping-containers.sh +Restart=always +StandardOutput=file:/var/log/ping-containers.log +StandardError=file:/var/log/ping-containers.log + +[Install] +WantedBy=multi-user.target' >/etc/systemd/system/ping-containers.service + +# Reload daemon, enable and start ping-containers.service +systemctl daemon-reload +systemctl enable -q --now ping-containers.service +clear +echo -e "\n To view Monitor LXC logs: cat /var/log/ping-containers.log" + +# To remove Monitor LXC from Proxmox VE +# 1) systemctl stop ping-containers.service +# 2) systemctl disable ping-containers.service +# 3) rm /etc/systemd/system/ping-containers.service +# 4) rm /usr/local/bin/ping-containers.sh +# 5) rm /var/log/ping-containers.log From 488895ad5a2bfda13e87d958f9f9ad8cb82f89d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Apr 2023 18:38:02 -0400 Subject: [PATCH 4693/6505] Update monitor-lxcs.sh add option to exclude containers --- misc/monitor-lxcs.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/misc/monitor-lxcs.sh b/misc/monitor-lxcs.sh index 74ab9b0b..5648ba4d 100644 --- a/misc/monitor-lxcs.sh +++ b/misc/monitor-lxcs.sh @@ -11,9 +11,9 @@ clear cat <<"EOF" __ ___ _ __ __ _ ________ / |/ /___ ____ (_) /_____ _____ / / | |/ / ____/ - / /|_/ / __ \/ __ \/ / __/ __ \/ ___/ / / | / / + / /|_/ / __ \/ __ \/ / __/ __ \/ ___/ / / | / / / / / / /_/ / / / / / /_/ /_/ / / / /___/ / /___ -/_/ /_/\____/_/ /_/_/\__/\____/_/ /_____/_/|_\____/ +/_/ /_/\____/_/ /_/_/\__/\____/_/ /_____/_/|_\____/ EOF @@ -27,6 +27,11 @@ while true; do done echo '#!/usr/bin/env bash + +# Read excluded containers from command line arguments +excluded_containers=("$@") +echo "Excluded containers: ${excluded_containers[@]}" + while true do # Get the list of containers @@ -34,6 +39,11 @@ do for container in $containers do + # Skip excluded containers + if [[ " ${excluded_containers[@]} " =~ " ${container} " ]]; then + continue + fi + # Skip containers based on templates template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") if [ "$template" == "true" ]; then @@ -46,27 +56,29 @@ do # Ping the container if ! ping -c 1 $IP >/dev/null 2>&1; then # If the container can'\''t be pinged, stop and start it - echo -e "$(date): Container $container is not responding, restarting..." + echo "$(date): Container $container is not responding, restarting..." pct stop $container >/dev/null 2>&1 sleep 5 pct start $container >/dev/null 2>&1 fi done - # Wait for 5 minutes - echo -e "$(date): Sleeping for 5 minutes..." + # Wait for 5 minutes. (Edit to your needs) + echo "$(date): Sleeping for 5 minutes..." sleep 300 done >> /var/log/ping-containers.log 2>&1' >/usr/local/bin/ping-containers.sh -# Change the permissions +# Change file permissions to executable chmod +x /usr/local/bin/ping-containers.sh -# Create service +# Create ping-containers.service echo '[Unit] Description=Pings containers every 5 minutes and restarts if necessary [Service] Type=simple +# Include the container ID at the end of the line where ExecStart=/usr/local/bin/ping-containers.sh is specified, +# to indicate which container should be excluded. Example: ExecStart=/usr/local/bin/ping-containers.sh 100 102 ExecStart=/usr/local/bin/ping-containers.sh Restart=always StandardOutput=file:/var/log/ping-containers.log From c90063059f40fc23350de25ad5b7fbae2055520c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Apr 2023 07:22:15 -0400 Subject: [PATCH 4694/6505] Update cronicle.sh fix for worker --- ct/cronicle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index e210d897..8b45e79f 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -51,7 +51,7 @@ function default_settings() { } function update_script() { -if [[ ! -d /opt/cronicle ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +#if [[ ! -d /opt/cronicle ]]; then msg_error "No ${APP} Installation Found!"; exit; fi UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ "2" "Install ${APP} Worker" OFF \ From 8f9b06609fb4fa313002630c359956c2e72a14d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Apr 2023 08:17:20 -0400 Subject: [PATCH 4695/6505] Update monitor-lxcs.sh incorporate add/remove functions --- misc/monitor-lxcs.sh | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/misc/monitor-lxcs.sh b/misc/monitor-lxcs.sh index 5648ba4d..7576114a 100644 --- a/misc/monitor-lxcs.sh +++ b/misc/monitor-lxcs.sh @@ -17,6 +17,7 @@ cat <<"EOF" EOF +add() { while true; do read -p "This script will add Monitor LXC to Proxmox VE. Proceed(y/n)?" yn case $yn in @@ -92,10 +93,22 @@ systemctl daemon-reload systemctl enable -q --now ping-containers.service clear echo -e "\n To view Monitor LXC logs: cat /var/log/ping-containers.log" +} -# To remove Monitor LXC from Proxmox VE -# 1) systemctl stop ping-containers.service -# 2) systemctl disable ping-containers.service -# 3) rm /etc/systemd/system/ping-containers.service -# 4) rm /usr/local/bin/ping-containers.sh -# 5) rm /var/log/ping-containers.log +remove() { + systemctl stop ping-containers.service + systemctl disable ping-containers.service &>/dev/null + rm /etc/systemd/system/ping-containers.service + rm /usr/local/bin/ping-containers.sh + rm /var/log/ping-containers.log + echo "Removed Monitor LXC from Proxmox VE" +} + +if [ "$1" == "add" ]; then + add +elif [ "$1" == "remove" ]; then + remove +else + echo "Usage: $0 [add | remove]" + exit 1 +fi From c92d92a4999cfc0ca1df5a4bba257588eb3fa418 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Apr 2023 08:42:35 -0400 Subject: [PATCH 4696/6505] Update monitor-lxcs.sh tweak --- misc/monitor-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/monitor-lxcs.sh b/misc/monitor-lxcs.sh index 7576114a..4218e53a 100644 --- a/misc/monitor-lxcs.sh +++ b/misc/monitor-lxcs.sh @@ -109,6 +109,6 @@ if [ "$1" == "add" ]; then elif [ "$1" == "remove" ]; then remove else - echo "Usage: $0 [add | remove]" + echo "Usage: $0 [ -s add | -s remove ]" exit 1 fi From 0f26a686f9d691b956be5c20400c2fd272fbc5cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Apr 2023 09:20:11 -0400 Subject: [PATCH 4697/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2e77f146..77cffa3b 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-28 + +### Changed + +- **Proxmox VE LXC Monitor** + - NEW Script + ## 2023-04-26 ### Changed From 0abd1c5b84ffa5c7104d47c76fadc545b30f7646 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Apr 2023 09:25:14 -0400 Subject: [PATCH 4698/6505] Update cronicle.sh fix unbound variable --- ct/cronicle.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 8b45e79f..8eb6aaa5 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -51,7 +51,6 @@ function default_settings() { } function update_script() { -#if [[ ! -d /opt/cronicle ]]; then msg_error "No ${APP} Installation Found!"; exit; fi UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ "2" "Install ${APP} Worker" OFF \ @@ -59,6 +58,7 @@ UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spaceb if [ "$UPD" == "1" ]; then header_info +if [[ ! -d /opt/cronicle ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" /opt/cronicle/bin/control.sh upgrade &>/dev/null msg_ok "Updated ${APP}" @@ -94,7 +94,7 @@ sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled &>/dev/null chmod 775 /etc/init.d/cronicled update-rc.d cronicled defaults &>/dev/null -msg_ok "Installed Cronicle Worker on $hostname" +msg_ok "Installed Cronicle Worker" echo -e "\n Add Masters secret key to /opt/cronicle/conf/config.json \n" exit fi From e7194c92fc3b8b0958b510b8b33b26cea7df9d9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Apr 2023 00:04:09 -0400 Subject: [PATCH 4699/6505] Create monitor-all.sh --- misc/monitor-all.sh | 138 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 misc/monitor-all.sh diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh new file mode 100644 index 00000000..4eb0bb70 --- /dev/null +++ b/misc/monitor-all.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Proxmox VE LXC Monitor All +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/monitor-all.sh)" -s add + +clear +cat <<"EOF" + __ ___ _ __ ___ ____ + / |/ /___ ____ (_) /_____ _____ / | / / / + / /|_/ / __ \/ __ \/ / __/ __ \/ ___/ / /| | / / / + / / / / /_/ / / / / / /_/ /_/ / / / ___ |/ / / +/_/ /_/\____/_/ /_/_/\__/\____/_/ /_/ |_/_/_/ + +EOF + +add() { +while true; do + read -p "This script will add Monitor All to Proxmox VE. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +echo '#!/usr/bin/env bash +# Read excluded instances from command line arguments +excluded_instances=("$@") +echo "Excluded instances: ${excluded_instances[@]}" + +while true +do + # Get the list of containers and virtual machines + containers=$(pct list | tail -n +2 | cut -f1 -d" ") + virtual_machines=$(qm list | grep -oP "^\s*\K\d+(?=\s)") + + # Combine the container and virtual machine lists + all_instances="$containers $virtual_machines" + + for instance in $all_instances + do + # Skip excluded instances + if [[ " ${excluded_instances[@]} " =~ " ${instance} " ]]; then + continue + fi + + # Determine the type of the instance (container or virtual machine) + if pct status $instance >/dev/null 2>&1; then + # It is a container + config_cmd="pct config" + IP=$(pct exec $instance ip a s dev eth0 | awk '\''/inet / {print $2}'\'' | cut -d/ -f1) + else + # It is a virtual machine + config_cmd="qm config" + IP=$(qm guest cmd $instance network-get-interfaces | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -E "192\.|10\.") + fi + + # Skip instances based on templates + template=$($config_cmd $instance | grep template | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "true" ]; then + echo "Skipping $instance because it is a template" + continue + fi + + # Ping the instance + if ! ping -c 1 $IP >/dev/null 2>&1; then + # If the instance can not be pinged, stop and start it + if pct status $instance >/dev/null 2>&1; then + # It is a container + echo "$(date): CT $instance is not responding, restarting..." + pct stop $instance >/dev/null 2>&1 + sleep 5 + pct start $instance >/dev/null 2>&1 + else + # It is a virtual machine + if qm status $instance | grep -q "status: running"; then + echo "$(date): VM $instance is not responding, resetting..." + qm reset $instance >/dev/null 2>&1 + else + qm start $instance >/dev/null 2>&1 + echo "$(date): VM $instance is not running, starting..." + fi + fi + fi + done + + # Wait for 5 minutes. (Edit to your needs) + echo "$(date): Pausing for 5 minutes..." + sleep 300 +done >> /var/log/ping-instances.log 2>&1' >/usr/local/bin/ping-instances.sh + +# Change file permissions to executable +chmod +x /usr/local/bin/ping-instances.sh + +# Create ping-containers.service +echo '[Unit] +Description=Ping instances every 5 minutes and restarts if necessary + +[Service] +Type=simple +# Include the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified, +# to indicate which CT/VN should be excluded. Example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 +ExecStart=/usr/local/bin/ping-instances.sh +Restart=always +StandardOutput=file:/var/log/ping-instances.log +StandardError=file:/var/log/ping-instances.log + +[Install] +WantedBy=multi-user.target' >/etc/systemd/system/ping-instances.service + +# Reload daemon, enable and start ping-containers.service +systemctl daemon-reload +systemctl enable -q --now ping-instances.service +clear +echo -e "\n To view Monitor All logs: cat /var/log/ping-instances.log" +} + +remove() { + systemctl stop ping-instances.service + systemctl disable ping-instances.service &>/dev/null + rm /etc/systemd/system/ping-instances.service + rm /usr/local/bin/ping-instances.sh + rm /var/log/ping-instances.log + echo "Removed Monitor All from Proxmox VE" +} + +if [ "$1" == "add" ]; then + add +elif [ "$1" == "remove" ]; then + remove +else + echo "Usage: $0 [ -s add | -s remove ]" + exit 1 +fi From 2ca3e77bea73561c70c088fa731cf7435c0e0963 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Apr 2023 02:39:40 -0400 Subject: [PATCH 4700/6505] Update motioneye-install.sh switched to dev branch for continued development --- install/motioneye-install.sh | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index 69489209..cbb1a732 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y git $STD apt-get install -y cifs-utils msg_ok "Installed Dependencies" @@ -30,27 +31,23 @@ msg_info "Installing FFmpeg" $STD apt-get install -y ffmpeg v4l-utils msg_ok "Installed FFmpeg" -msg_info "Installing Python" -$STD apt-get update -$STD apt-get install -y python2 -curl -sSL https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py -$STD python2 get-pip.py -$STD apt-get install -y libffi-dev libzbar-dev libzbar0 -$STD apt-get install -y python2-dev libssl-dev libcurl4-openssl-dev libjpeg-dev -msg_ok "Installed Python" +msg_info "Installing Python3-pip" +$STD apt-get install -y python3-pip +msg_ok "Installed Python3-pip" msg_info "Installing MotionEye" $STD apt-get update -$STD pip install motioneye +$STD pip install git+https://github.com/motioneye-project/motioneye.git@dev mkdir -p /etc/motioneye -cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf +chown -R root:root /etc/motioneye +chmod -R 777 /etc/motioneye +cp /usr/local/lib/python3.9/dist-packages/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf mkdir -p /var/lib/motioneye msg_ok "Installed MotionEye" msg_info "Creating Service" -cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service -$STD systemctl enable motioneye -systemctl start motioneye +cp /usr/local/lib/python3.9/dist-packages/motioneye/extra/motioneye.systemd /etc/systemd/system/motioneye.service +systemctl enable -q --now motioneye msg_ok "Created Service" motd_ssh From 485444b07d5520aaa2a9874c64dfae583b91ec66 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 04:20:16 -0400 Subject: [PATCH 4701/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 8f2daf58..3590bb84 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -49,7 +49,7 @@ function update_container() { esac } header_info -for container in $(pct list | tail -n +2 | cut -f1 -d' '); do +for container in $(pct list | awk '{if(NR>1) print $1}'); do excluded=false for excluded_container in "${excluded_containers[@]}"; do if [ "$container" == "$excluded_container" ]; then From 15f528512029d4e21435324e72dfe990557d6beb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 04:22:09 -0400 Subject: [PATCH 4702/6505] Update monitor-all.sh Code refactoring --- misc/monitor-all.sh | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 4eb0bb70..ce61017c 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -34,14 +34,8 @@ echo "Excluded instances: ${excluded_instances[@]}" while true do - # Get the list of containers and virtual machines - containers=$(pct list | tail -n +2 | cut -f1 -d" ") - virtual_machines=$(qm list | grep -oP "^\s*\K\d+(?=\s)") - # Combine the container and virtual machine lists - all_instances="$containers $virtual_machines" - - for instance in $all_instances + for instance in $(pct list | awk '\''{if(NR>1) print $1}'\''; qm list | awk '\''{if(NR>1) print $1}'\'') do # Skip excluded instances if [[ " ${excluded_instances[@]} " =~ " ${instance} " ]]; then @@ -96,7 +90,7 @@ done >> /var/log/ping-instances.log 2>&1' >/usr/local/bin/ping-instances.sh # Change file permissions to executable chmod +x /usr/local/bin/ping-instances.sh -# Create ping-containers.service +# Create ping-instances.service echo '[Unit] Description=Ping instances every 5 minutes and restarts if necessary @@ -112,7 +106,7 @@ StandardError=file:/var/log/ping-instances.log [Install] WantedBy=multi-user.target' >/etc/systemd/system/ping-instances.service -# Reload daemon, enable and start ping-containers.service +# Reload daemon, enable and start ping-instances.service systemctl daemon-reload systemctl enable -q --now ping-instances.service clear From 1dc63002ad6023e95d661a4fe600834fc6d02f86 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 04:43:52 -0400 Subject: [PATCH 4703/6505] Update clean-lxcs.sh tweak --- misc/clean-lxcs.sh | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 0273c2e3..a3465dc1 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -6,8 +6,8 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info() { -clear -cat <<"EOF" + clear + cat <<"EOF" ________ __ _ ________ / ____/ /__ ____ _____ / / | |/ / ____/ / / / / _ \/ __ `/ __ \ / / | / / @@ -34,7 +34,6 @@ while true; do esac done clear -containers=$(pct list | tail -n +2 | cut -f1 -d' ') function clean_container() { container=$1 header_info @@ -43,7 +42,7 @@ function clean_container() { pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" } -for container in $containers; do +for container in $(pct list | awk '{if(NR>1) print $1}'); do os=$(pct config "$container" | awk '/^ostype/ {print $2}') if [ "$os" != "debian" ] && [ "$os" != "ubuntu" ]; then header_info @@ -53,16 +52,16 @@ for container in $containers; do fi status=$(pct status $container) template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") - if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then - echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" - pct start $container - echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" - sleep 5 - clean_container $container - echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" - pct shutdown $container & - elif [ "$status" == "status: running" ]; then - clean_container $container + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then + echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" + pct start $container + echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" + sleep 5 + clean_container $container + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + clean_container $container fi done wait From 465cd750150c6c761f77a6bf2aa8d46576990cb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 04:48:05 -0400 Subject: [PATCH 4704/6505] Update monitor-all.sh tweak --- misc/monitor-all.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index ce61017c..624e71d5 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -32,11 +32,9 @@ echo '#!/usr/bin/env bash excluded_instances=("$@") echo "Excluded instances: ${excluded_instances[@]}" -while true -do +while true; do - for instance in $(pct list | awk '\''{if(NR>1) print $1}'\''; qm list | awk '\''{if(NR>1) print $1}'\'') - do + for instance in $(pct list | awk '\''{if(NR>1) print $1}'\''; qm list | awk '\''{if(NR>1) print $1}'\''); do # Skip excluded instances if [[ " ${excluded_instances[@]} " =~ " ${instance} " ]]; then continue From e946f41890752745ec4a1885ca2c2a58a6573cb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 05:56:05 -0400 Subject: [PATCH 4705/6505] Update build.func Check if the Monitor-All service is currently active. If it is, stop the service until the creation process is complete. Once the creation process is finished, start the Monitor-All service again. --- misc/build.func | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/misc/build.func b/misc/build.func index 4859554b..3a80c03b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -375,6 +375,9 @@ install_script() { ssh_check arch_check pve_check + if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service + fi NEXTID=$(pvesh get /cluster/nextid) timezone=$(cat /etc/timezone) header_info @@ -508,4 +511,7 @@ description() { pct set "$CTID" -description "# ${APP} LXC ### https://tteck.github.io/Proxmox/ " + if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service + fi } From 70ce72fcbfb58daf0335eea1fee1b9dad3c2dc9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 05:59:26 -0400 Subject: [PATCH 4706/6505] Update monitor-all.sh final tweak --- misc/monitor-all.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 624e71d5..3b616b31 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -4,8 +4,6 @@ # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# Proxmox VE LXC Monitor All -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/monitor-all.sh)" -s add clear cat <<"EOF" From d51a8df90f611e9e2aff52cc090f93c946fe39cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 06:24:27 -0400 Subject: [PATCH 4707/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 77cffa3b..64fb6b37 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,14 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-04-30 + +### Changed + +- **Proxmox VE Monitor-All** + - NEW Script + - Replaces Proxmox VE LXC Monitor + ## 2023-04-28 ### Changed From eeafae190c2a36acb49f8c391e76fe2860ae9c61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Apr 2023 15:15:51 -0400 Subject: [PATCH 4708/6505] Update paperless-ngx-install.sh fix paperless-ngx incorrect user:pass https://github.com/tteck/Proxmox/issues/1376 --- install/paperless-ngx-install.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 8d31b183..55820dbb 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -94,7 +94,7 @@ msg_ok "Installed Natural Language Toolkit" msg_info "Setting up database" DB_USER=paperless -DB_PASS="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" DB_NAME=paperlessdb $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" @@ -118,11 +118,10 @@ msg_info "Setting up admin Paperless-ngx User & Password" cat <>~/paperless.creds echo "Paperless-ngx WebUI User" >>~/paperless.creds From 2139f9b9db8355cce707a27cb820cf5a63a9c738 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 May 2023 12:53:21 -0400 Subject: [PATCH 4709/6505] Create octoprint-install.sh --- install/octoprint-install.sh | 76 ++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 install/octoprint-install.sh diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh new file mode 100644 index 00000000..56492b3b --- /dev/null +++ b/install/octoprint-install.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y libyaml-dev +$STD apt-get install -y build-essential +msg_ok "Installed Dependencies" + +msg_info "Installing Python3" +$STD apt-get install -y \ + python3-pip \ + python3-dev \ + python3-setuptools \ + python3-venv +msg_ok "Installed Python3" + +msg_info "Creating user octoprint" +useradd -m -s /bin/bash -p $(openssl passwd -1 octoprint) octoprint +usermod -aG sudo,tty,dialout octoprint +chown -R octoprint:octoprint /opt +msg_ok "Created user octoprint" + +msg_info "Installing OctoPrint" +$STD sudo -u octoprint bash << EOF +mkdir /opt/octoprint +cd /opt/octoprint +python3 -m venv . +source bin/activate +pip install --upgrade pip +pip install octoprint +EOF +msg_ok "Installed OctoPrint" + +msg_info "Creating Service" +cat </etc/systemd/system/octoprint.service +[Unit] +Description=The snappy web interface for your 3D printer +After=network-online.target +Wants=network-online.target + +[Service] +Environment="LC_ALL=C.UTF-8" +Environment="LANG=C.UTF-8" +Type=exec +User=octoprint +ExecStart=/opt/octoprint/bin/octoprint serve + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now octoprint.service +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From bda2ff41545a8f4e56a97670f395da4cc08d76b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 May 2023 12:54:39 -0400 Subject: [PATCH 4710/6505] Create octoprint.sh --- ct/octoprint.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/octoprint.sh diff --git a/ct/octoprint.sh b/ct/octoprint.sh new file mode 100644 index 00000000..e7b93f45 --- /dev/null +++ b/ct/octoprint.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ ____ _ __ + / __ \_____/ /_____ / __ \_____(_)___ / /_ + / / / / ___/ __/ __ \/ /_/ / ___/ / __ \/ __/ +/ /_/ / /__/ /_/ /_/ / ____/ / / / / / / /_ +\____/\___/\__/\____/_/ /_/ /_/_/ /_/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="OctoPrint" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/octoprint ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From 5405f4dc9d02156e5c61bf372384118819ab48d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 May 2023 13:09:10 -0400 Subject: [PATCH 4711/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 64fb6b37..70ae780d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-05-01 + +### Changed + +- **OctoPrint LXC** + - NEW Script + ## 2023-04-30 ### Changed From e8bd1c21a01ce82cf2713c4d8904e00c3bc41f8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 May 2023 13:13:59 -0400 Subject: [PATCH 4712/6505] Update octoprint.sh create update script --- ct/octoprint.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ct/octoprint.sh b/ct/octoprint.sh index e7b93f45..e53023a6 100644 --- a/ct/octoprint.sh +++ b/ct/octoprint.sh @@ -53,10 +53,18 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/octoprint ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +msg_info "Stopping OctoPrint" +systemctl stop octoprint +msg_ok "Stopped OctoPrint" + +msg_info "Updating OctoPrint" +pip3 install octoprint --upgrade &>/dev/null +msg_ok "Updated OctoPrint" + +msg_info "Starting OctoPrint" +systemctl start octoprint +msg_ok "Started OctoPrint" +msg_ok "Updated Successfully" exit } From 214e0d13d5bbd490fdadd1ba3f8b2501352670b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 May 2023 13:33:30 -0400 Subject: [PATCH 4713/6505] Update octoprint.sh set source --- ct/octoprint.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/octoprint.sh b/ct/octoprint.sh index e53023a6..c0f14e37 100644 --- a/ct/octoprint.sh +++ b/ct/octoprint.sh @@ -58,6 +58,7 @@ systemctl stop octoprint msg_ok "Stopped OctoPrint" msg_info "Updating OctoPrint" +source /opt/octoprint/bin/activate pip3 install octoprint --upgrade &>/dev/null msg_ok "Updated OctoPrint" From eea752fa798c9f5237614a7b8bc9b2d826f7b4b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 May 2023 17:50:43 -0400 Subject: [PATCH 4714/6505] Create microcode.sh --- misc/microcode.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 misc/microcode.sh diff --git a/misc/microcode.sh b/misc/microcode.sh new file mode 100644 index 00000000..07b2fff5 --- /dev/null +++ b/misc/microcode.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +clear +while true; do + read -p "Install the latest Intel Processor Microcode (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +clear +cat <<"EOF" + ____ __ __ __ ____ __ + / _/___ / /____ / / / |/ (_)_____________ _________ ____/ /__ + / // __ \/ __/ _ \/ / / /|_/ / / ___/ ___/ __ \/ ___/ __ \/ __ / _ \ + _/ // / / / /_/ __/ / / / / / / /__/ / / /_/ / /__/ /_/ / /_/ / __/ +/___/_/ /_/\__/\___/_/ /_/ /_/_/\___/_/ \____/\___/\____/\__,_/\___/ + +EOF + +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" +apt-get install -y iucode-tool &>/dev/null +msg_ok "Installed iucode-tool" + +msg_info "Downloading the latest Intel Processor Microcode Package for Linux" +release=$(curl -s https://api.github.com/repos/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/latest | awk -F'"' '/tag_name/{print $4}' | tr -cd '[:digit:]') +wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.${release}.1_amd64.deb +msg_ok "Downloaded the latest Intel Processor Microcode Package" + +msg_info "Installing the Intel Processor Microcode (Patience)" +dpkg -i intel-microcode_3.${release}.1_amd64.deb &>/dev/null +msg_ok "Installed the Intel Processor Microcode" + +msg_info "Cleaning up" +rm intel-microcode_3.${release}.1_amd64.deb +msg_ok "Cleaned" + +echo -e "\n To apply the settings, the system will need to be rebooted.\n" From 07b088723f083798ca4dbf8e33b746598ea50801 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 May 2023 18:14:06 -0400 Subject: [PATCH 4715/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 70ae780d..cbe73016 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **OctoPrint LXC** - NEW Script +- **Proxmox VE Intel Processor Microcode** + - NEW Script ## 2023-04-30 From e6e421b38af23293ccf8d930fc2ebec49cd10846 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 May 2023 11:34:10 -0400 Subject: [PATCH 4716/6505] Update octoprint-install.sh add `pip install wheel` --- install/octoprint-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh index 56492b3b..b871219a 100644 --- a/install/octoprint-install.sh +++ b/install/octoprint-install.sh @@ -43,6 +43,7 @@ cd /opt/octoprint python3 -m venv . source bin/activate pip install --upgrade pip +pip install wheel pip install octoprint EOF msg_ok "Installed OctoPrint" From d9926b376b6dd03e82396e2345447e65b1fa4c2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 May 2023 12:58:36 -0400 Subject: [PATCH 4717/6505] Add files via upload --- misc/images/intel.png | Bin 0 -> 130540 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/intel.png diff --git a/misc/images/intel.png b/misc/images/intel.png new file mode 100644 index 0000000000000000000000000000000000000000..97b53a678cc69d6850865c839ea391a012eebe89 GIT binary patch literal 130540 zcmb?ig;&#W)JGAdML|MZ3F&S|gMf5*igbg(D3y{JJ-SmGqy!0(24QrENQ{BRU@&^` z;P<}&!MnrG&f)BS?|p83ZajBUn(A)|@m}CzU|LFA+FZ~d zxb8|uUKkieJ$LU118!g6VPMc>D9g*}`epyid7SR807g1Jq}P(xl-GRJjYW!?|K$OH zboA3cA1%$f#=Pin?A^P9cC)co2EC2LFEn{RKERw6q-V>wq|d^^Q+l=D-|I0Gpq4o8MBNK?p$cLc9F+T09exKCR zI&`b`_2re`1@Kz*e|dh?QzZDt=<+&xos8fIJd=6Hi3C3Q&HOssCmG?_ejVfr2+;u8 z{Ybf19q5{X9kTRzWe2}}Ux^fB^etzpI%(Go&!u2Ff(3o9$Got%UD=--~^%0lT%4&kT)@ttdX;20`| zn-P$a8$f*XuV*KaTPWeM{}A$iPjGmzze*3ga*OcOpHHWGX8R{2R=qeRcg~4^RT1x( zkcLi1r&T3sjw_!PgEIQs6LWg>2dsC#{=griQh&k-$n}1GbDK6b$4RsH_EI1xPX-cz zxo?2zNK2|I^y0&-40(hJ`S$sf(l+HZF*e;$H<+vR*BJ)H7(T5UO>)UE%?fU30d;rS*mIX5BQ1jzxlI{1=PEqTe?hrXDhM{&xU@gt*pE z>RUS4%D0<_OUTl?w>eKJk4b!sYY!<26LxVXc^R^2+92Z>!mt2HQPC65)78OpXNl-f zIw$Im8($H|V_|u2!Y>-?!LcH4^Q~jpd0=QxAVea>r6l)vlWy=za}O#b@8r-{$Xj8E z$A^Ex&qr%ktq(ap$`sn^TIVPy1t7|UNU1K19GTD5PMok%cC}irbS37hKm(FL@G)4- zf}p0eSigd+hu?s#7B@_vilC_f6FvV)BW3FFcV`dqbhGAsTzK%cO&-+_{>DEW*}=+y zr!;Fy$Jl)>N>XLen*75b^#tVAl*~D@CPj&Z{qJ}_sL1hADO>Z{+OSc@YSt1iS~iOD zx(d1G`k7Hgs2Z>CsL zjRy*#_0?qRLQcIPtCWZLqK%Ub*D0)MGrmZlc-wf}K74+vrphtwg~9nJD0j_i=i*65 z`s1Ar@H_ehtAz>8a>}%cDQ2re=k&V7B+!t0?%>6u=rqBM)DONCk#HOXoxth!k^S6* z$rxZ3+^VyBS9X#T(G*W{s21P)^~uYXzFrV1&7v7Z0UW5aH9D8Yg|mTmF9v-QTL*J3 zBz>aQ!$WI@wM#oM08-+Hbu4{J19?fK2Fa0**LZc4L~G$!$ggdZQ}iDoE=xxDyh<9TWrdo!o#-!Xpvq z$HbGF6%G0{vJA?ld7TdVA5#4NX&C^}f)WjP)0^2&=j~$7I_qLRr@~Sm(G9uU&t9fO=TYx8|tBU6Xx+T z!EfOOoatFV;psH6<@ocLJ?^ri&Y-S)-pV6y(eHQo^>DfgYs@+2SQ!VQ3V!Ib7b2Xx zBFa>yqKCS=!n!sLjBD20?~>fuPrQM*x5eTq46sxChbzpA6-U41{$q$8u8#+x~P9K4CobCA8YJ@p`w#h3fCuI9l|T@g=)?`_dO0ORS;n6D|~-1MNu3dm>B z>dfu4$@GdBm6uo{rwNv%D83B{3Wjkj<(DQ@>wR?@V;o;eznlH6O>p$ zWjI%R!B1H)U6g2ZPKDplovZlLfp~^}StwQda+Yp@lFf|S2zI%U z;eQnZ4ynS&=<$WI)(nsCR+^yz0Snof5w^3R1o$TAKgqDPxBa@aK)(}0SlHrXck(*rOw@l9khh41i4I~}P3L5etie#r6 zPXlwe@YmPhuX=e zfp35Z4BmmPFviJv<+-hJJ3g*0!-!GG_)_z)vcv*-Y=Dw_@Y9yhaB!J8V!lZd^`kTgs7$rOOZ{w#L{#7t#iY6tG&eSrVM z#l&fZ(PmlxY3qM>*3W39@TwS$X>5ZvHAr)m468kD>V5(5iI3vu5IJW}+pk{pnw zkLNdiBDgY!SWbqWy8>??w|~rXvsj)1zHg>V=MiAQG3IPSLYqu&=PsMM*;*u^@t5%3 zz{xU)*eipLn7k%7i$~S873_Ue{Z?P@0iFZPNOfU+-t5Df9)$~^;-QS#?_SeUi}5+v zk(g#uMe#~cfy6vqnQ{6G^X#hG;}W@e%RR1w4RU4fvf6#Qfpp=;)M#SQ)rr6N5k;Q> zv=cLfdsGEV2D;dhoCpRL#GNRizQoj7KV{*3`aU*ntQ7lXa3YNU>(fk|TDye*2yM5!OjY^AYV$YVn}jzqLu`c7X~jsk+m8HavF^lYTV;fLXuZfA>0~Ai%l*#7sFdYdmbl zOrIn5?`Kx7Qs*}|B-kvEWHhHu)fxm`Ro;EUn^L0!hLrK1KPu|+y!V?BKh?K$2=oWa(wUB)bi3*LFab-8;d4zXy_Pr=;WEofWTX8U5Iu1B6MBz?eg zCq$+kUYQ=)!RJ$qz7O4GVzG`xqL*4^xVDf`@+TwGMT(E%)M#28y?Ba@_fK|&y&&)W zB=0!$d@b(GDvu30XoYzRn}BPZ{Um5YD9He}gK5HiFv`62cCNc)$F|S z=ZNn}z8Cp2&ehjCr%_g`HH+b$6P1`$SRBjb#)!XFGP!uO+-n!pN8NwI=y8nMjo^V1 z18*`!;xrHenRlc=Unk4j<_sk{HRyJBeEi|TjC`y{AAs*dRMME#`>T%Ml?G$M$b?< zS=M0!8|yRuSJupR-Wy-u&Dny1dusq=^+dDvTjZ4?0ih>R#U!u*l&(pY(xIAJ4%vDm z+N(w~<+T~hBY1MecyvTyUVOm+{E@wvD1L&J38rC4tmD*oY7%Z#%J!vNJg>XWxr5brZtrHL9kb^BD_3V7 zZoEgVj*nJm)i;JW7QbBcJ_)hkk?h3nj8ezwIpWurLG}VgV3@^xkyGEgDJ8PY|J_oz zD8Nt;aX+JtPB=tyIK@hva4CX$N9Ns21`uX}1#)b8C~llcB9={Helmvdc4)Kf?KO$Y z!|QR;tW+|$HhhY!{SKtFp5GHmOJwt==}=|=NHABpj50Pok}a~Cpr^>Wi%J&P2JM^0 z#_z+NY%6zK$e+cwm1usW1z0ei`B2=WT$b!w$;ngdpIC4#tR;YhcHyus=ttOiL#tj8 zr$4~zUgfV;*=R}0ut@g9Lo4KV&PBy;JDTgpgG6i#9)yyhkCACteNYYxq=mvbk?Tam#U!NMGqq+y~|6rehOH ztG0{CYA!9E3bZVPFMf)f;=5q9W6WpACiMBoCmHp|I?guhOd5^uC?cN0x{Ye}sXB75 zCg6`I!44k8u^=C(z(=%72an$gt;bKw_5pf&^EHtYy3pePJBKeV< z@&TlGDy~*I0cEY9u%wgy=P;paY-GLS{q=g$6xmr58+H?Ooi3k0!HTV2{tZ#G1e;_0 z+(9G4=UH9g!9wzs{C_cu`G%b`dtxM`J-2&jIR-&AN#{h;!9}Z^cg}FfgHv$CYhtE& zU%L$leQFGBjI3j!qO_^q&TLnHv0Hvv?Bb@R+M00DV&Ts_X#9*Vv;4l~5A4*mJb@L%akO_}D4jQGuBIpbHM(TS zWM*pTqBe`TImJ`dCWh2Z0_V9CTAKXsWXA^Wpr5^jGxJ0Qcj7oHv7c^dTOO7o_LdXl z2F5qmW|-lu$!xQ2{xf-Z?*18DXIAY54(6?X^q-f^uux{z02+lHLx8s=-tD3q%Ut?Z zrxB&3Pd-neBleM?+~NtVi~fJQsZ^YZoB~BYlx_Vw&Wu?0+BxsBG{r9I%;p~&m*+y~ zKjLYDa8Zs?2c+;0{4Ol2UJCh(1=+hCj5<{2?3{~DGWjQ|i}$jnk(l4RQGF)p4bnht zb)r|4_&<4apMlifoYhOsb0(H9h=B)Q#U{VPsyeb4cmAP1Ke#)A{%aN&{a_n!EZ@5m zSA8Tk&Ke%n_^P=?xN}Y|mJ4Ry)NPs_eScUgXU~b2NPy$`WI zA?1~`t7(X*lOU^OkV4q?fg4eE(~+kv+QH>Gr3TdC7hRMv3qmxDk6iZ3l4V%}3YDb3 z^fX<={@Ex0_H{c%r`|0eVm-Kv*XrhNYe!{~kan4SD71`v_i74S`L1XxLZ1~H;!F>G&^0<{9jR8bYHjLc(L2W;tWasG z-lfhYKasd^4U0@l+_#L=0+O04Zj|zvs&&9lWjg`yoz|Of@(_0fUr}fXNb{_Ibf38u zY07ok_qD%0*gbs&yfx_ybIc)qdK|yLbr%El)f5jH!LDmA#gm+|8ff8Py=8kr`oX4Y zqV)l6p}3*w4Zok*jeKWI4lh!`y^J@AI8v1hx9!QpxM0hBkbdOL66VC9DtZ)KSLoFKXp?XW4OW+l4)c z6>xENs|)2~6PrM=>;DXm_*hz24=N zgm^mae|b53M;sZi6`jcIxTR_9*7)#<+~bLDk`TMaRv?7J=MnnJ1X!Xevs8JjQ=++` zv0?ymS|nGUJ}MJ=tvicFqmfqL+6#M1faWAWA!3(Yv!8 z8OJig_+4Es*7gVKy(#Ek6O2wUzGt*87|Mwdnot)#Xy{sb!)1*Q^agF)jw+Tw)lH%NK9cE5h8g#~ZVLC&|0wWO_>9@%bD}VY$0h;KO4Q`Y`*Uv1gQl@<_M5`H)(Q1}`Dxrr2U^B2K;GA!u(@J%}YtT7jix?l_-Z`V2 zS19g9cc1;k$m_$BPwWMW3rjD&*7y1yFBTkXoo)d)owNBe+BIcIc5MgEYBx=HsZ22; z8n=~K=M2`)0zmSTbkGDB#wgke39Q4y@@MpjT-2e3_nN(WdTXIcpuR;;d-ehD}!XkWSj+7Xkl(Hj@FQeSU$D0ltg?$rJ>|WN>l7 zxYv@$mm3PF_7xEw{AK-p4=ehb0Yi@9G^aGe4b9YcS}CC>U@_0w%xzqCSMKReSH(<< zd_)RruD_T@Ie5c01bBd3Y&SI*UpV0QD(Ew9o}yS5B4E-&Nq7L_4xrtcERyIk|F@$x zYOd>&J&ZiNYKzd96LMBMKhXhA+t%F|ik6x~F|1wRvjnOeKen^e*o>qI42hCH`uN7U;zr110CB%mf%$|@hsM%U|8Kbe)ukd|9i>0E)u zo=6!(Y$ZzT*3Ms}Up32W1qN`tA{f*>Wk{Z>DZZLQUj5>YOpYt9?MRE0oLPU&9QNo( z7gu)WuJ<5!nf$pEtG~L9dM%j8C3c-Kt+?YHa_rYRcAx4gq=);)!;HVUXjlZ4!5RGg zJuuN=+h*Wky3JN=ZK-llqFZ6QgFFxH=^CG-frY@X_Yq#)r5iSC|0?%DsY@Ags|vQ3 zL%#%GXgNzTy;7ly*jHS;Bq-A=a~(`Ogc$NzdUZFyHlf(I**kqko`rqz;o5%<)F^e6 zD+d#G%MTv+gQWRD$Kh;~)mwtP{Q5nLZxXM>NkH0Z>=!Qw8d)>{LQYGt?@I;(>a9X; zsvMJqI6(&a+Vp7zkto?q;%TGPQA$=s^2w>SN5=V$KI?6^FjMhA+mPhj-PMUeZiPDy^D$ z(BE9sdM_7p)_z-&hDQv&Yma1lG!1&Lh)W?EO|4tj^U-I%;W+;Tj!7z9GUAL@8pr_a z+PUgf8L*h}@eR6aIzR|=Gqg|QKgV|HvejWPLN{Zzq$}ts#6W=CaT3SH`~xXqg{Fl3 z0+tX(7UNRsA}$lyU#W%)!3bdiyJ_T1$Ojsj@N)k~5Tgaw8H0Do3TRB2&qcvk+y0;7 zU`gZ9S50J9Xv?!kofoBitMMM{T+lzBl8yt^2CE6qtu#B=pO}HmYYG-8Sk8eX8B2c! zSL%(w=^Bpd`8}=qk(#*$+00Cz8}%PX3nXo!q`+UXEW{)Utu)CUjd?8PVe3XHku$zi z?rf46z+Q1ACp<+~xD(G{H+J#$Q^U?)Cu);@r=FY4OLz=olJ~elZmfjuJEk=EI97@? z-YEF9rss_h&IXZG!&90=*?2lNv1sp?L6CUZ`J7N~@U(NA-QOF2yWteV-<%yZE$=Y@ zwf~yBtJ$hVdC8UZ>Ijo3Zyb2xr{C>~NM;El@prNOx>$5^j9tp>7B<(@QlBS5XNR(2 za_@um7Pu$iQpy@7S9aW!%zL8F8MrMZOiqC2T0w#(K2Y1hyo1y*> zhRDS)6QioF#hRiL$z(i|r^G0VIy7U4)3;4mxJ%&J1xU0Qv!o^`-ijI{Ik0mnM;T5v zn2(YbibV&y`Rhje^3mB?=P>woHUA|fmbzd$u+er z0Vm8rIX$|`IB?MwpqU_7n{MvtT;Y0EbH_+j7lcY?D@ppo z^7|{zee|1zJ;dTO`XWkw(#GMWKxa_*x6A+A1%UYxJG>E#Ux&Hi?-Xt+Al^qKNj_?^ zkPjy%K1#II zie^?JQW4SquoYX^6HBMQFwJLljy1b6nylY>`<~m69LD1>RI0wl-dt4}klX1zXW?pm zS@7-jr8Ju}S*|KZssfvPZ_wN7tlu*qVl+=Vm7bIw0y1;2#Bxxr00PNVnj9DpHX=ZE z7wISBW}SOErYKu{R~6)vfYf1d7JU0Pp{-|vychb!r^Kbf8mYw7)neh}T+`dVAveC> zQrWTt2FbLl$N?JhZ3kmL9Gr^`j4DZmTYDB80g5V$|7I+sq(oUdx+b& z@<723x~!83f%^&^AWI%n$B?E-dnNl?Dk|nkJy$(!P8O8lI`k9D)gm5sBX|)|G8*-y zfKcI+dOkE)Z6JVad{zE{Qb+*YLV{6u_NAV(_@rz}C^`^ts2c(3G^l}$Bq4jj-zR1 zF9m|uwwgQ?7gQ4Viq( ztokPA@>L9G9YB{=F>$GuWCCk1+%Snn{xR_l(0NiaW7WumMvD<9s$AzUWHun~c_cAO zg^fW7TYrP;W)*7_$@_)#YfMm{$w`FZeb;9AM9lju6GJnD@0Nv9h-NYY)aPX{*>0r@ z$Y zpTGjir?l72S$(Ja`mz;Xb7ELZC)SU!$xWAf{0_Mx^1gjG8SiLAA0JbIV=2|+QKC0< z;@=*A=gB{(sjMrrNm}xh8JcBuhUck!ub@!J(YC zkc8m7yu|XjCfL{^2zceQ_YO{6uVG z-y}HDS8=|)mHN6qVO+vM_ZACwj=qU%BUBAYKbI$Z6IzdpLBTs*@qLv_EQ2o6f3?Nw z!hu3ZN5gf7+gorON$q(xf@tIDw?hvNIFlxfl(7IX&NH#gMN$n?+vg?}Ihx$y+H%n| zN0o{Ef9tV@SZ{G?mQ4JGY$Nk3rH&QRv!Rbl2YsU_?R=`$uU<`y3Xb)=FHe`2*m(uV zW=7jwrm4EpO&$6^MoXWW4^WuhqR}z|q{emW|0tOH=a4jn8No7*uWUk^I-=)z(ggM4 zf`Jf#tFMl6&m^-5)mwwnNzl7=zENj_ffqRm9YP75;(;Pwwv_M6XuZ71fy0+3OBp;5 zA7EI@57Mf`JpA5FmgyR9q$E1}@rV_yDo0MwE*3I|p2%JThBxt=4C~PH ze0weDxd#B{y>EY-Iq;9QC&r!S>92*7m|XMI zPA`GlP0FL2ALESP2G$OdzCW8Zrz#(ML*7~h2ms0`K1za(-#_N3ssH>qaw2T`4xHPY5d*k~`CUw5jwaJ@(&P=6eXzQ)m~GQ%~E9k>5-xw~Fl0(Dcbu0d>j3!7_R znD4nVtt8{q6i#xYhetHFP2#S3&uHmvJaGu1i$h_5Exlz&CQQ{PUnqn?1et{ZQt34f zpd~p+aCej`JqCuMxOeywF%9^amv27&JlT;WzTkT^1(H0Aj?o+Gc-fIvxR1W3A)wMe z2kHgjcYkCvV2N+s8HED|EBEf~m|x$`XmnPFz&8B1ssUFc8mqA6d_M zrOLT2Yn9A5ZhsErRXxKXSu!1(mo)p0xtH}y7RxN;U`%;KiY*xv<7Yxbk6lX3l#BcT zN+tOdWNk3qoY)%Q=T(hvmJs{miO9x@RKcM?A|fF}?~i?W^!FYFSK($wTV+FFV)#IrDa974TRN)TjW6iygO8;}0F^Cy_#?4f zb2aR#VWp1~xSV=9J&vJs5sya3E$bY{j*#0#-th;r z1N*S=Ob$K9_JKbQ#ADL8Dq; zlzYcGp>M}ts2WS_I!5ws>RrcYVw6r7W4N(2es|W={goHM4NckYfpzT6O`hZxp0JFc zeh}B;(q;KW^T6_>L%3)UT?>=h5b_2+p~8d(P9k^UP&vWf)BwR8DRA6X(t-NoFZ&|h z?E-!HJmgKXVhiG<)}ll-VWgvWP~4l0Y?Kl5^H`Y|jB>FePU*iXT>@}wC-By9^0_l( z%Dzs*5-umRS+&qvz^GM|*6m*K+?4{N$wd##7CZo}`}xRnyxuhykhe4exM?Bnqkl^H zZGsVyf8r&az{PZvo_qC>W=-|je{Pk(X(XRD$H( zn%6!Kcrux7d9420EB?=(b^99X4oO^x#DCiqXxlHVEyvQ%wdW|vFi_-<%d!!wv(GrP zn}3Ob1{v;)?*yE&Nl=T$lVFTf|Gi!({3V`Y2m(s_l~*|%UwW}rC;eqkvE7jE$Exg4 z6jA>IMFb$uABlDTIw#cH>nPDP+G-=%7%lkG{kn!gs2)3kPs1+>5;Q$xH`BzEEX+OC z))Sz37=1Sj9v3)1;En7mR%w1rdALu2|FKTQ&|Hekemdnur028FzUe^tCZ{*ZAJU(^ z^IeNi%!SQ9T;UOh8k4@jsaLeHBx=}37S_t<)d5u_>Q3`#eo;EBwpA|&;{7WK>K}NH zXyV^F51zz_UCVg4+YqhHSpDDv4$AJ-=ve*0S*OEsuD^I~HH#|PCgbAUWaOB8W8*TG z$G(lOF6eufvbI=#}0^%KN+Zd++acG1I77ER}PJ{na((B>RLR zka}ohGr{VFFiUyGqlj9HHnRW#0LJl4; zcmevux2|n0Hr;7Ln%Qi7TK|pq+oAV8M(N4j6HY?yiMu|tASjaq92n3w6C>RH@?`#H z9~u5=S8^acKXOV?pr)O;KC?sthuZLo?SY$lO20m#4GrX}{(=S2CXg$?`Jt~DbIbc< zY?vyK?prxsi4x(d`Ay-Ul4{UZ`XB<>81+k2{5irbE9ck>C%n0tMN2T8yYGv$kJRMa zh1hqnFs-ChuTC@woqZ`Rjl<_0k{$!sT226tzj9R+u{^~Kw42CSxuBl!Z<4$jVO*uA z)8OZ9-8%qSVHZxU%oMa z-)njF{HEf!n`(u;0(|!7zHC(+PB1e&?U+5os^U@*(-b*SZ!-;wa2pGiIv$@-Q|n%D)WHL%l1=3V3T@1_t)6a3^y_Z7a6quo6s6_vmhcel2x6zJnkb z*G6v5QTQP>5H&CK_29<`MW)kmF6(rjwJK(d%@49Px?yd7o!J*ow>tqy8k^n`hh!E! zfasf?cmMP%#^0JyRIlMIWgzT<*AGdu`a@C>GLujxyBCMbEeEn<=F)AM-T;{Kq)(Mo zkJs!?R2S6rGHb15ZC{QfzHES-iAD(;@Cc%BqBmVAwo6en^PGpG-_CBqII+k%VKRMt zcY=zq6Af!*Fc9+@?P~e{Wj)wboXw83-yVGn&_;FC)I=Vl*ggRpe~)%U>}YD);tqm< zsgE~rXZUOt_lbLs!n{$l%gjtrZGTJzyEh>q>T1`PyG#PRNR23CDqQaRr12xcb7fSH zHy-RINr1%IiM144(~5hHMQyq7yQZIzvNiY<5_Z3kfiN67xD&ZX$uSqY!V#;k?-5}ElW^**nb-yaW}>R9VI+yTs;*A6uI zvja>Sm|41RD00G)m#1X0^yd+^kMhaEw8p3!`>W|aKHx#M_vms@6J=?+`j zX>)H-dvYB4NmFU<5C56R&AQGr{6(8On8lY4DV$?=)=jo3FLhLI#xD^<6~(=3?`u(* z;YQ5(=A1;TENAzmeF}V`w9QW7MUl`}{D)zhQ~#p1k|Jd6C28s?NJzw`?Mc4}XLZ7L zXR0D#8@-B5f$>d?xP!>!;c{Ouv5=8p6brs0)IR1!L?>Y<&Q7ne$1VHrywiNmn3-GDNPo%8gjL~U zQ?31l$1zjR8(t5ZN@(4`x`NsFwwt*-k((&WHLpg!o8&gScj~ml3h`Q|24?jM573Dq zKYr6)*y#G=q(`~s=usw>Zx32;Fooxlv!%5w@|TayG@c0gaF>}U*s##yh%U-X@2@cW+YsouW$Q>R1WZsO9fNp_sTvoz}P@LJVeQ&}rq56&Y!su=`N>5zi&NpgHs zSnMWUk6avy3K!XtKK>Wx)Jy)pHLAA32bSq1nxi3sGpUzt)91G5x>1|+{*M_fZe3XN zZ66soT&w~b``+#AAe1U3Iyaz{_1BM{2ww6{JaD>42bwd5yXVe^ysMoiVD>!M(Bn8u z=;%XSoAq9{AD|a2i6i!}>x~iOTvKdK#7sjUsn|OvVfbk8TN+Pu<xNNt0cm=cyQ}Z%y#Qx(jC_Gdj*}YQ{Vgkwz6vVQiLKsR*f1 z1S!y!rAb_}zf~5e601_K5(oF1%pykZEO0EVF~h)24hcDNAV3bZ-Jq z0Z;$iKU*ngZV2cjCwY!QvXe3AQ$q7U!b|5Ia`Z^Pq%#b%_xm6XaPS{*i_uG@neru8 zRE-)Ecd|@5uW%p_4_du@#T;f336k(3WQ^aaqRdXUwGO)+eR>hqgVHZ3y>J8IVdtBv?yeM(C+b52J(kA;fM(A#m`@ryjxnPPo=&S9#=PTy_zoxLZ;C*qVDZ%3>F z7xSJ}-2~Z+L?C}c8${hszl&{YC|tjC&Pn$m+(oqkmyqE zCytGo{)pPK^+4o8a12X^QBi>JuOn(^aDko&FK>x#?=|!mYx32Mb$OLHPACZ?#y(J` zYrXbJu!^h)q>JF_OBlT&jD_?WQEliLs|+2cLI&f}zqmNCq0rFmi1_`=0uP z`goI0{*oAWi9lAj)$B|E?m5NDFg8}S_eUrIuhX3aZ4S^TOZa6aD`=8IO)EFx{5{~#?#;_J}Bk6}P`}`O@Zj9SZ?b(iCQP`I=mI3`|`3WIr}_eYEr`Jzm_! za#k(@!VJi}jRei0AbOsOh-84~;hsg1m5ew#jap^%HzIWTP92EB*&N-Ncdb6|x>x?Q!V7>n>21jV+W zb9?FvLYi~%2YD>S)d;YmgA_U%LM%0WG9<*>ud$S;%oFeN?M_8IRWCpaK@Lw zs=4Q7*INsucWG@TRO1z3dehyB)jP4{FNVOUc1=J^?P11)uQ+Yby3hZmuD-}?14Xkn zLUXOPO<1=IOm0wWzjS=Qw9++5(G36(@H2&DuYzv4cvyS}@j0*ZgNM$4eXy0Ra-4ej ziWI%29l9z*Fq+rH*pU&Xr)v9BT5xGyGjg~|{n+Jt12S$0>A)1Ndh4cWnMNr9%BDgh z+*bzhM%8G0ECWBhtpz~>X)XqY(=~m*E9n?r)$_GDWoRn=StYS3B6(s@vVExTU*J{I z^t)vTCHmSw$i=0H+6&E;K%}*`fylP?3GC%6YmT*sVUYI6Os0KUl>t?I1|s;f3dvIr zF=j)q9kP>t1Y2E*H5ULBmfumndor$lU`vs=GQqyVFCW`@Q>ELml7H9{+psQPiiaH> zX8}!V3&uuWwy-fV*2s8z6rN|hS$KUJqJl2qC}g4cI4Lx}x7taKjXE@+XO>4U5Z#7h zIe^7i*1ddm*iwdC-onK<#Ag;Udc!$>rT^qfxC&eqUw!;M7NS)|-e0D-;gI_(uWxP^ z`+WgO%k-$Rw}$~4pn8ujN{LX5S|RDHAR6wQpm>Lu7mM6%b=>d5R1ie5n&>rU zDO>J(Q3Qq5_z7Zbq}C%!ayRkb2s+Z#f?)|%D9Sglcq*lw_^aqXQu3{ z`dgJ%ziII9RS+jPbTRG1h53dX?gSl2U8(BPq{Z-**ypaA>)ho{CDCrRW7l0X2lrdn zC%XdqWoBl6;#p-_nf{T4;UmgI9P*w@`m1`6Eh&b;8A05=PCYl40ka$R7Dy3vq#2gO zGjzxp&DNchi^8p$j>1vR@{}uix1GpwKzN*nnd$mfuHpdtCx=@0V3}4@8x_b2{QTT| zKMf0-Sqcn4`-cl!oydzsa!?&?tOM{5ag9Ge!1%eC&p?a1J%4%#`Zsst zyr9Biwa@dRdQfk3MIe@gO)@*f`y!GE7K-=Q-0~sqm@tUMZ1*`elm5R8g4SHNAckp$ z!Sx*cTeF;5?I1~i*yqH}S(Gp*d#;57(2KgqjEk)?ouMR#xNq+2>1__5lz@M(o3Lz9 z?YM4^RAZKCe)EJ_+yxQ3OpE4g*T&wkIg$U$T=YI-Besx{(O95IkFW%|Us9Y#)n%zn zQkO-Ln_t3Via~+x`Lzf#awWJXj?QG{bLX9r@P+5>{E`iG{Bf0s>yF=&W8#Wh?V3@y z@%1wPl~E`AF6+x;OsDgaUrh3fAlQ0=gyfT`x`rXE?=kTk+D#Ij?+;}_sF2s~=(_Cp zA`Y0Xw_z7>^|IsfRp!6)TqQ4h0xk4dl*#j1XQS4_7g|(a=10+YSXRx1lhoXjO#hSu z#2_WmCuIe68}Gk(-4beFn8&R%lB^wmvX^9PG6B2)#h2|Z*EbSL2Ah3)r5=s zs<=H6O1~*;;Zi(7+XU?;0$1mWX|;Gy-YqlpOO!u;bVZdL<{(mTJ;C|103e zRm?T(_`QkiL#hUJ&4wQxY{A-c7=<`zrVZP3(Y*v%N$+K;CYSMtDR_aUgv3IHStxRv zjvRGsu;?vw1PV~^jl<4Ro#sP+7#j^#scwP0_ViMA2gByQB^_%yAjnR4;|$5H$&JvN zad0!RgI}?|4h|3XGpDogG^xt|;1xK0LoKTk&Ts$(;p@?`P);?|5(u4s4|jSoZ)WVGjg+{|31(}F3}D{+y)gB4)#RL38rXZ z*Pg4+h`b-p)FC_p2dUS<;`51{$tHnoz5P>^upOfRM|H5=;o6j%Xvp>;0~#mZ${$k} zK9D6b@!@;Ym_%ntmr(FYr@FkEGt)6oVIUMwqihT7OZWt?G}Xen1VdbS%}{@tZsQsB ziO{oPT(b8I{bg&}K2z7`QgdHEeM59DEuaepyARhvwr&u@i}Sk8?h&u^K1DYnuG7zSIu&wOXS2EKhhSW{kq1$s0z{+ zKXuhA$0u8@Zqa>>u9-3#<)EIcvXwwaKxbT!Q<-D9qh%mb>aLZHM-e^wGqIR4x;%-T z@QEnprymvS9g??|I?FQK|D@Lcf*u~WZw^-${q_VwvQ0u#hg#EDu2;6G^7d`CUiCTP0KTPFOEK9V(mmxC&kAZ(gJT2_;%g=q|K}nnqlVmP6al0ta4(-6B^r z#%ghqa%V?zg<{aq=H*(Y$6GZI%0-?E1wO!d70bnu0+IUqL7`PdZP3JFN7m`JU>aFM zb7>X&_i#OuH`@eo0k)Sehp|Z|OYf;b$l8;0N5|Vu zrKILvywI9>@;%R2b?)>|HF}hJ?=#gXiQ7(-bpRS9z>_b_BETau9|N+Kj)x9xa^T{S zLyI6GY7Vnah>Z*U-so~E!b)fRF}UE+q+x4Je;aq(wABX<%!r70WT2Z7d zH8cK=k<@aGCo1xEAwci#zj(yPcs_*8cVxT7;12Z|^GOas7y%%r;eILk`rexnNibhv zk2ljk#N2W4&9NZ907SY+VoHTuG6rM{0&5cqnPGST+@*ur(wU-KguX%wPZQs|OZ?3v zs0#Q}=PaJMh1Uz<3#!hZPNBMKvU8e08?*R zi+iXB9CfaZj7U~@JWk;YXuaQ(Jk}nAFO<9SvyE&}hizNfg&=(Kt1U@qgH&T_q`;X& zlc4%al7n(!wk6_yRyBR{1Fjqv-k!^)yxTAoL@*4whYBr6W@3u8Tu5|;$8-H#A}7>C zKyDnxanH@ zbFEUK;9oh8Yoq%BQ~W>U%q8c)MQVgi0urb;=ZY3>D`*jpbN=KU6xue_A9*9{Y9xo7 z%ZO3c#AOT5VM>=5fgW$+sK$sDn#q6xZYAWp`@MdS=f~ji&$po$%N!F>*wH4$_{g`7 z&RmWSzauV*+hfLiyXOm=msyd+C@kYQNirMw@)9?v|F+7>SM8~%COfa~YI&$2J{iBA zvoqrk_M5+&(0S&`7BL7KK$CWz9^GuY-N=M%lX3Z4;LGI{d+b!V`o{(Fh@Dh`x^Y0T z6rW+J>gz&+uuvoeV^1DpmEqF0!Y69Ebg?tUt_@G~kqlTm%~jLD!n@mK+ip0s^7WTI z0((9?`ksBBiFAXpH1he%o2!GIQ)|sz{yg>{<`dK&orwG;Ml34aLK18*AVr4|P3)TH zV<-_XB#Xqc;cH@Y`J+aVWVL2c(& z{Yx_vA|JXmPfP#r9HkyIwhNHsYf;h7JPvU(G(-s>l*F!_ss`ofk{o2`onIk7o|`%| zMkDlv?zmEEWCqe)jaB={|ZtaqKWoI1Oq@0xaymtXx-?2$P%5+*sdq2HnMK zsa!p*2V7DBS4!_jdbS$lSe^r4;MCeGJ%(d``CX-(uD4y&K}YG|S3;b+gjOYlgKAt} zS+*hu%jm+a^?ec@^r#gHECC-Zyl))c-xlgzdKjHy5wM}TRNvR$`)6HTkswW*?*y=D z(NjAcGYcZXpyNMCvtrh--G%%7spRR>0cubylS2|7em5$W!-Ur*?*xh*uedzB)t&>` zGC#Z9EF3T%By;X}{e0i0@8E3shxqFBSOS!dzLbiFbd}rOH?|&+R$5z$X_wB#PLk`$ zSZY)fI%Wvh>WaLYrQl@1PI36V*U$LWU4eu|WzY3iC^R18M=}g4s}tYVF{L|W8}sX? z-Q|0nGGJ-iKO4!W*&P#me=HVyw?}#BH|KTloZ^Am;YWE5CV-T6>F(hz5_Po;!TdxD z``v@yOG3SI<4LbjQ4y8o;D6|_5}VEQav|xp3M}2wI)QJAVjXWCsis_+E53k2AIXW# z$lo($sv?mnYFDzla9OSnFEV2OcXTIiaYQm2obpVSz!UEoU98xjy38srj%M<=7o8PB z=A+fbJ=+VpCGpmg_OAOD8sx^kSrz@Lo~JS zACa$aSvNScD{$?esB|Mt-DV@PJAAK=fOAI^v#!hAd~*9nNNAKN#C{Glrt!6E@BWi4 zx*;Cw0h_-VA(vd&P|o$+RA`I6nNMZ~SFdwt|8D7TUkr$L)NpAhAoIZ~Cf!-H_H1Sr zW4|DD8}`5%P$O3Eh{9oraMOJhw6NP!B60@0Xur))bqs!-YRY2X;e?quGcCEk?o5w2 zE;k)l(yc|wv)oG!r<)J1i?U|>-}f&_Yg1ZD{ezW;w=2kiD`Iy^k7PNW8^(u^fD&VT zJ4C|ECiS(wJ9I^<{NbxI-|-S-=-3r6I=xH@-2;F0M$hW+tp|%D}m} zStJe10}tFgRy3(M8Tl_0AtM3uVXqsu?<569wPwCM>*7cK*6J94zU7%UowNO-M?>Q+ zifqRy=tE33vF$o3D7lNaED=lc0U=<$|9+D2hvqSOP0;%HaH-lx?L%=bu~Z7J6XTL_ zfWl)Sr}$FE;>9jO++H51AQwYI#iI+n;nrwP)sjS}(rn z5~PHp>2mZd%AyJFsdK=%S*`wTr07#=?)DOnuf3%n($BAn#;X6++pFt$tG^VE=_8E& z0tR`UQ{!Ri)OwOyaa-TR#%9&t+!tawuU8)9H|Z` zy4z$7Bj6n_d(gqJPh{#RN_a-OG8@!hJoyucFkyCAoKT82H=HXZ92y^*AU}fl=X!#B zSqwaqT=~0S(PHL?4BIZsD>mAtD#W|4;j8R0A)w-j(DVg~Xm`B1ic{_Eoj}Ysb8P_I ztf|ruo|)a#xYQ0(a~#)v@xI3VtV>Mu{+E;*wi)P&kFK8U81E#9VND^dvfO zfvl7fzmKLNdMQVvURIJnoH)ikGuaToT1p-YuYGstJ3D;LmlX*lMe{~jpfS@Lr#9h} z0+Jqq_d|#t&8)%ii*m@jqr1m#TDV65GzefVYR3aA-{}0l5AxJr1rb;4jauMtXm_8P zKKJAWR^SYz0d|^2B~6WK=E>p0NESTNW{LKHZZpSH0Ickxp)YzQe;HzZ(jPL%z>?%Y z5>9{#A={X}+$qG5k~ycc@xu0b7ltgmbI#%Qj+j+zxAU;*`LB^rf&r)D*Um^wHvI7; zcZ@84Lc~E&JIHZ=j{RwNbs)vVK&g;gpN*^VZ4qf!><V-ia|DME(2uk+cY%`MP;yLRekuXFLwLX*^9pd)3 zE`%WzEDf$$4W-RG`PY-{sx41~;9#dB#nw}DAFBDMfrlUtIj^Ipe1Cm#B9(p7pL%%# z6C~-}0wx>b`>#_F59XoNv28JuM?WzOQ2E-jeN&|$ZWowKUvJOdj0p|;od4sSm?OLL z_dB+(6DcaG5mXy&X#Yp=Dn0+nedrjf{WoVEI+2KRU{J&eHsVf}Mu=&=;4-tg1y|Ma zHr)WShld_z+z{N`EGhA)9{crQ*CR-d`3|kMIwzTZEB_Eyl%yQ+n5FO;pomQ^r>aCZ z9u@7`3~#>qovUrNSM&onWs5pWBVK)2i^u7h8H9%bx0|O>4$$=P6$nx>^QYH{zO;fh zNWs0V@d_FPKmYi43N1V&eeP6Wa%6Y#>ecS}7S^yW{A%iUe!Ienq?NjCb5jbX@h^HB z*ey?~+EBZOdyyK2>ofj9?k?zJqGE}t#k%h+3sRwqQELg6MYsLA*Z3}JSMIs@jY6|N z%Tx(`NvcNife1KuAIg=Ku~;*2r8?Nq_nBH2r; z+5x!4J0g*Ag>cVJd%V1hUwq4WF}#=`M(Sc9;&%;=I^| z7d2Bp@Qtega--}quZ{H?87VxL*HaTMI7D&oU)&tSB+ohAN%}x$`MsV~0O|yB<>h6) zM!I*0bkHb39`i>xn}lS1yzTUb_Pu|g#z@TJsQdH9m#b^?!nL?7@v%FKO7g>2PX7&k zQv&&y&c-?OanWl54x!q>O{fx-)_JVfkCt>iZ#k7Jzhw}#wtt+g_BIxDc2s>a=8;(G zBVDlDen#Y3lFMZZ7>QIjML%PL;G7ir(0Nn!Njc>^*rbUH?7lZ;#k zSptFsxBmbe4h52tVJq&Yf#IE$nV+|5wB|g6S4^9WvkOdZPYa} z)%bH+DrO`(4LmQBT`ZgD3%2>6`9|dyTju$~CL*NF|Mc)6kR+-~<#D>f@6)4HNSlOD zXoAdOmRhfls+`g|^7Vr}|0(@zC=2l9>iYX+I4ZFNoQ$V)aKODq&0K8a|H|Lip^@Sp zfwT^kg94RR4QCeOc&L!L{rA3ttSd0jPX?sl#BBbp_)bl7<;S}vY9GrXG5$D{C4N_< zmPv4kXMBX(vk&47pKM0sL^s;3eI%>&uv!wVsm%Xi9>Zl5f;Y;eos|&gRSSqrC_uRH6)}_EoyjG=$0=P z_2t6`ooJ_hw1+%!m?|bJuqW3dZ0~#!WtolN5e+74Vt_a!wgPb=c}V3kF9B9oTSu0O zma!if)9#GC;leBBZkL7OioJrCicd+BwX?)a=lib&LYnH)ueF;=8t7fuBmAYJgjAk{ zg~FRHk#JDj(Jk=;M554tc80i+H)oRakEy$#4UC`?RGipZNtmdu`9$EOTB4==i5r97 z@c}3g!;;kC_3R%s1VwAf`H9VO`CaJ6gQZqw)?XWLUSsYy7%vXr#)5U!-$qsU{BgU* zpDiyU&NRrhb62V^xHQ_mDT+w)2W*Dj`6ecA_TM@$3gB|csr#*YvCguo9oa`9V@X?& z5%jjU*Go+a`2}oI|NK>+l%*5ifyZ)j&yL%?`um^PaNf%6an$)@2dzb@qw|F$PtVkZ zD*N8Alj@^AH*3&}?KR`@9m!=!TeA=yOyjIEqmsc`a zZ9#`VILPhK8cO!Wde)68{H2$5BL7$+Ng>&wa@*h%eDNC!$sA#@+}M2zRO!PSrP&h8 zG+{0=+!aJ1grVbZgJk$#oL)^0M>TNo;kLdpq@pEke3L7@N{}BhyS%UPsZ+n(Np|y? z8(o7|6z3=7O!{XM%6#yzB1)6D#@6{iP zzMfwDX`$3%$QK8A_a=B_=g%K$oCJIgFs&Wu^6i?qS;BLJ*JLYILs40-kfhK) zRnSwQEjsz#TJ@%9S&i1NW>2gLkMy;V+K|WOD*dnfe7vwo#8d+MIfeM|l_!eS}fNnMYJ&uCoO zSkmh_v4XgW}^ke z3VHpW+NR=(60o1l=&w&=VM8;+ww3L_M)Hj|iUSj3a{dbAE%hs=)h*c-8F@41|4KFk z9yd#I32Ha;T*Xz_b-%LsFiI1=ODPV}DUW!M1Nwp!F8a5u%;rJiy88j{#~v2`^J_|0 zVT96|@iuHqZ3*3Y1%|onA)M&OsGy%S1a#)B8Syj~wU^kBt?9*kUy>$^`}BCJIlHU) zX?izf4(3`4zm#Cq)vZ-89qGv%3Ce?IAD+yf2q_%U7wV;Ur^EQHscZ$+2fjLTguXvP zx4SOxy5jwM3oD!}3B>v|VubzkS?fwcnIMf<{4RWWaOUYlCN8KG+jgDnsI_*it%(3l z%xyqkq%WYM-m-;TG9tvAQW@`V%t6&*HdAsSW|W$g1gKJYn0w@qj2orEPC2VfwLw;8 zgi}m@JCQ_>m_#5UB~ZoJlmb#gooOHpy}xX5#D?YK!mKck)HsH>Xu^CsY8w9)ttUvm z1hwCK;|~s;^D)zEfsVf9@%QzXj? z#srW62b8+0Hm7J(CSm@=bg>{aT5Pv$ZRz3LE=mY<*_gp=joA5uM^LPzT}xy1LpM`raVC#@YIc#f1pG(c}aC!*M04bA|z04L_>?z z%bIc-v}O<=@`K6kTF<`pRf4S$N)936pYc^vnDs`<_cSdxXF_HnFUeVE4T4zE_Q&sc z#%FPlA_KRtRSNZlxa9(Z-MUK{RoU#tC%tkdN?J-`ezS;RCGqg?5kHk6W%Gws-`ELz z2BKy*FlVf`ot8a{F73=ziK86>9U8OmuUB>Bdz}e90y6%=em!dBq1~QRbwfK?^~?$Y z!hqYEf!Lexw4K)ch&iCAyN;zf{w6f=&NwP!mn+eHJ^S*wJjKsmfjSJyqxJDvekhNf z+mqmss49kdV&DG`IBK()H2v*;GO+2&b& zI(RsUoNscpKIB3q#|8x1P#At@G)XYzmi+W~J$s&5kuYT5ebmKIiw;T|Abcb|D|FP> z!~TsU4K;TBj*<*_0Y~!(o2fB=FoJZ{GQX=>_gIJ%BA?1`!Z-qdV1T}b7KFnl6!8VV z9KJzgf8+6QM*)298Pk-fo`ZBo65xmAitAEwZK9e=Z1S+{ zDSbw=Le~-)l=Mi(XfLkaM2$H6qL8jqeCvYj9P|>>NFDtKx$fQN2X-pZKx=E_p1eh( zsfoy6LEQ!~UbleXXk{GUuX5PG+aV`fk#WF1yW_Lo9tdL$+v0V=+RS&gh^XCw95HK! z7cNCTBOq|!?d!=;kc43vMMb4?_h6f^*sjoPdL)b5owKx z-0|n};fT>qYM#&hK4Y5lKQQ$8qz964G^vBL9lR}SkS(;_!xohAGT5PgFDYlw4@K0x;*J}vA$!&bCHAi{a)e%pKPoJ z=bJV8>6vY4CdFxN8c+^1kx)jfRZWMa4tU1wC_FnFr{M8)KjmnYD+y4tl6JJUlpW*z zJVP2NylT5YL$&PgUU-dP_OZnhQIF;9jv5xAb^XwrW7FbKWeBo|<$m}A&(+s-ro6eM zuFjBhXs9LktK89WLUJH(8+5V%Ha6ew-?nPlZ<_(9PqW#F7YM(SxvCRAS1rho#vgWv za73}^O8k`wh?0xgD;|L#k30rWd3rftedd;wab>1sEgFicC?Ov%m{k2sBmuaZ*n8WQ zrrVjJ&&jOM&+ncqk=M7q<$h1LQir5jh@%1<5u3*KkU#yJwVUmP*$nCnYAGWml2+yWN(Q7VADu7fRv< z$@;&{3MTda-qKEpN=S=j*m_Y_AZSry)I_mS(L*jEL9`@05Z8JMH6*8#} z$l5M<;{7QF3M)Lh;y@IOi!^^H*8x-bC9o9LfAxaYgk3qgWP=kD$3WweO~0m#$v%!2 z%ij2_{#46x^F5HSZx^`V0&|$jARt=z=QMdsta~)AT;t^oDWv>WD9q9c3oRz4qRqfn zK&Kd;KVs`FH~LL}gc#B=b8SxQ92~NVBa{%f-8R^#@P6aZhX+cDjV@-^*8>FXX(pzg z9&`)x*@@JR+6djsI(#}vZ;Niv@xI^o%o;IDoyNZLb%`XI8?Jt*>x+XZ4xVP?zq4VI znLalRiF(`+nz^k?MyDiV?sL%gm3->rv-cdWQ42pbjy2~BJ<%z}c)kCqS=Ez8zmL4{ zHrvjoR`s4r?wi&*UaYu?&BrOJ0ikI^wC-X&Zp#+!emaffzAtmBh~X-0_V2y##^8le zz8}{7so~SNPUd<02he)ZM!4s*qG*s5C0ET;*V4arR(!~gbsC;y_BQxYlk=5ecR27{ zgW?g%c7qRoPsSvlWc7oRpk)0yilgGjUczq971`wOS|Q^0W4kxzkk9*zKjd4*qHS*w zFOheaP}EU?&y3{5q~7TP)kgskg8HPv_7-E7iK6f$4p#m*Z8jD@2%tTUgZm$RXM5^C z1J@Rl0q>}yoN=%cq%kx$xyW+PW>+>d)u`0Rq@aO3`i?kf-M!dyB=jc(eg%aYw|02M zPJoN$iYac44%86o=yOGh+%G0qVVDVdkRBN$u;5J?YnwgAz=~5{F&L!t*k&pXa_-N@ zyK6wVuo=y#{)6J7YogmqS~JRsV$$Qf)u;VCh6W|tHR8gF&djFgXS%5xQoHGhK91#AM%Of@XPi!!R+__hbU9_ zI$3wgX*5rcr!1I4mZiS~sPsk3?1XXBO^W|O*p|^8P8a0*PaZzzcGc9N#?6__E8O<> z!KjH6BfoIl^@WT4k@;i8oARA+UfexFzB6Kn$#1qb4nU-cm<~-Rt=E6nrf-Pajn543 z0p?AnyFQfYbe`vf&RENCZy{G)wkW!S&S-Mp01Ic|~;={EwR0sAfYH zOEbW}Z+U{d^FxYg#aHT42A+NhO1|Ym4}Y8Mk(Sl)xhD#MUhWhlQ^9CD^F5p`{SLBO zAd8`8fN_;>;B6a=TfhZt623(>tGb%SfscU>A75r(&ezAlPj(Ii;Fq%W26{BxOWzyo ze@UI77)A1JNi%#a{}qQ#qfGOc+KwUAT>}1$ehgfgtYJ~L-g<^-a8k308~dUb{Wn&e z_^TzBx1O&2?<67u=Pb%bL*_Hd8oNOp6o}Zqd>LA0i+-PT#Gul~?+m~2SkPUZ*-N249_1nt(u2f?VrEvtb1U1Yu)IS}CZj*3JI1I* z@@HGbeaRQ(i2L+CJqMkFSzNhph1i_Oi_FO8#F9$F)7LysyhSJvF{@OJVZ5+EX2D_a zd6KMv4SXdamg|qhy??X}%O zf~CBpU0HF{+<5r&2I3CmFq^=$s4=880WqXF`A&Bc@hgGx6y69KyFQsd$LN7qFN!Pc zd3A3Luy>{)^sXcUkujJ2#qD;6K0FaC$1s^B)yK~>eiYadci(KM)hiOu1PdHt_}c+0 zsOo5D2n0AUpj&lv4w$W=Qn~-`?60rDOo1Pe>W`K)tM@c8_{IV7f?%v_4A9Uq*_)#Z zONoB&_Y^oe@gq_ZR4UZHW4gIGKNk?u?5;*WB_hQ%bDW&?V> zo3HxufQu28<-%9H1V3eHT;Iss%2lYmJzGbgyMw@%h-KYRwp%mJ7tO9QI@pd{LzJ#R zYKCI)$93iVKO8C{sO(M};6h8?zuU>Ew)U570!{1ONVNnSRc($|_{z0%7VU7^>90Wks|I2O z!iW-*8^!yDi?#*983K|49dXbogZ$3F10(Ig8pjER8Z9s#`S9+o!PRi0V4yBwU`DOM9iix1(!j42%L(u>ncqh*I#1)=f|{|w zpmdeDhy`p3azB{&c1nYbY*|kttn?idf zpxSm_}^04;w#ilr;A(dWT6`~`OThB+cI%a&+fZ- z3lybJJf%6kwYZ3A8Z{Yn7!7MYB-3EXmpa8=wv96~O)`HB;}jkszV@eF{&)Pik5YwD z@VPN}-5xh5XRHq85H`SGZviI+;i!`khgm^^4d_L|+nD#Cu3YX;po)OUQe4{izWFAW z+>(+V7y+g)wgm!Oe*Y>7?<1pNw{Q@+;^AKWfs`tyYesO0D7Ki?-=EWes%G(n;a0#<~#Sjv{!hRczHlYj8ZQREjaht zX4=LBPtI5Z@;l5+9J=s@exQ8y&revD*Vd;rMbz`1X}rxgbbr%!%MsgeL2ReE*gS8{X5Jt0mn0#YvaU=|G?mcbja@(NQL2 zPlKLB3Ujh(@NCj5nlI47wFHihiPi9(&(+7YfS+{}otXs@ zI?(Y9vwpju)33(6%t+HuPgTZEl<#uR>n6ptk=|jW&`}+fu0k(USHq>pxtm*bK z;OG`v)Qq5J!GzLl9=bbp<`(6YxjW5mMi_?aN7=&f? zykwc*2g;zb;h$?EzRp713NpU_#BwiNx*kY(K#R$wZ>(bj^=DBcwMwjC;~s8W6_cMx1Mzez zHHEd6+%?4tMdz<6LU`aa`;IKzLGYRSCM;$L#w=(4@I>{u6r5a(i-(N&B1O8kknWRG zZDiPEHRf|&ZDT_-AM2=H69XsB)xbqEAp2vOB?s+7*z>ik>pis^8Dp_0HAR{qMubSC zR#MLGuJX|xWjER~#;ZCqDH4D`_8$V~u0H!(iVmUdeNIM4(i`Y?&N-{R2=w>2`8z)AouI7a!67S3y#k8hRWf!npmqUHB01imGewo?z{kfYyRe?31- z9!VUw&0Q+0Ogid69>n52MW6m?%FyuhvC$5sUo6{ur|iDrfrlHh{C@w}^L5;Lo6|C= zWv$oUYja4Z0)q)-YM%cZE9NaidIfBksPv3C0sAG^8 zBw;$-aPn+AuP1))f^?QdJJ;zv@o6v{GhnU!+;r4wQ3h)RSo)RazXt$tV zDWZ>)%|FCXPF1Y=Eq`b6vcllua&&F{<%3dz@pRp7zC1%SVRTY~B4OFCBZ~V9Q@c&> zN3L^XoQU=EopL*>9InVa9zLbaQZK(-V8HZ5anl8v#19s&DSnXo`)qG=N3*G8h)nr? zW`?P~I)P3hMztyDU^4EjlPzfTb*;vJASMmy3o$J7HqYu;SpjqH^`$1C>O49RNBg8I zMoSEE6BX^NI7W{diBkj+hBed}44xwWI$XWDNvyYj;=M5`VDQ~x1y$#GZ~4ZjB&zIv zn3a6d(BuH4Z)E14rjbPjQ|sTj0hEykT&~m#Z`Lg2`g!f8i4_}vL=;E3?uq$Jg`j%< zKXkt0?*k$H8$Kp*cWt{rV(UFYQ9T>cU1*~+346df4_tDlW@4 zRr!+32wK#uK%jHz3)aaLJ9n7I_{s|4+v;}v_xzV-#&AsBRjRkqQLP0rcp zR>nX$7sfpQ?H670>WMw~_uyTtyV9+Y6Gi^+o}lNM;0Oh@KRuq1Z;1&_2dJr2j|pxd zq4zzN;XYUf6kqZ$T+{#QYTjA8|14VCqkGdYfau$ypx61_0wA^sv#retV6(o@28 zEme79+dK1Wzs@s2hd=CU%S&6FUBt#McTtI*P$PnWKHt>r%hJ8zT*l{*`50T8Q={6B z^1`;_q3B_Jnv+56A8RRMl_D(T8-nv)j35x+odX&x6d^>qc(}20d*9ES{Jzx*3~5iIKP*`&E(GMs%Fb0sm_ptO?leq0Tj9tcHq{(;qFsKHP zZhP>@H|Qe2TZH30+>d;e5x%43x>inzmsxOzhpXIsV_I}$xhHNXsTAbeW2h-Ef#BZ~ z_=<0K-1o^wyk#ai&P5JfKK+~Nc=dxZD%^lpGZK7vB0Wi>Xt$8K2={f2OaB*`qosNc zdViO_LCB|unh`G&a4V36lV#}!L(}v9s4@xuXnrP?fxDM`(36a*f}IzX@4G0$(o7uc z%Y2ey#Zu(cOB4~)G->wlVr|*Hw)DEtSU^02z)Wc7;SOy)=+vvaQJ3keXUF#SyXt?d z>S-Eb1svZh#>qrM@6TMG@8tl6$_o5>ql#=M;7zMkZNvXh!OTXFbuTCW+zS#tX7VBTER*R?^|h@Z1`jB1NH78Qu(zD1wF{zN;P zmE*-Y-{W`JnjvxbM%!vRp^4&XX8Liz)3wUchdik3wYXQZN!im4Iq+kMv_GZ8l#9%8 zCSWC1_V77nh3BO$Z@g4?hLQOlZdYF8ixH1T6a7Sxag)7N#NkX>g z^UiqNQ~mF;MRw@8kDEs5^q$waT_yM7h5CtWH0=_Jy79*H%Ov*Wl1SgnKdf=m_+4dI z4SUSQW{C6#FW1VOeO9jgIN<)OpYa*GA`=M%ftRjLQl6bPSI>ItL&E;Il&e#^KA17Wqm(|!GUbX^Q`!v3UqOiR1S+85$8m_qwz`RVH5PdMd( zNOM;soA#X)+A}po1r5|xRffRUz2JFi9NQMw^?j8EaR&4O!s3toG-XxBWxA{1K-6#TLVV+wTk1Dc?b^7H|fiaD9))-Eqc~F zAaxh^%Q<+JbnS<}vvGw$7dgeZ1JOFB^8ad#dO2AK73A=20g!z`kPl$Wk!%dFQxNmHu}w!_xh|k z{M@}LWA2fpEuK*AYJ54`G-1HLv_st`1xBbeJ)IK%#BV)pPm%mu&aEMUf<@_g^8J&Z z>GsbZfc&6bWxiE-%}q&1FXUVGzP~);h|qpI_m$8Iix>vu!(cFtx^6ovyP)KB^ZGO8 z&G43R-NKnq6fB~Vp=tG^7@Zhs_ypFfz-#mYjDtZC04MscU13a#(C5|i%6pa^Jv-;~ zy7kowl_#j|%)^BAOro_N${V!FA$MkVp+8!Y49)$}5O96VC8b(OWN}5kyI&CgXYiTE zL)W_zAK+p@s$9Y6Bfj|YwuU};fnx-u6Nb^g*uGH74IU&T3rO_8r??61j(pGjr7726(LK0TB<${jKS*NA9CYno zoR7jEU73Q)!S1GKZ^Rxp7=(|5Hkqb!gih#g9G6Wk8|Y2%(4a%@VodyxZ^XHIJS$p2 zCdS>7VA);nVJhw@5dD7`xR&%$h~sUzF=b4ikX%Y<;iHH}(6>BAVT3U8?= zHl;c>rTVl_{5eX8CAY}GXN?{^g^G%iDr(2@>}+40)h^**qg!BA1P1b`RJN7EVRMo5 zehMy;Ca9s&qRvReQEAmVHDi?dXVC49EaOfZOp-0(d-2xh?91uU`OCVdWOdBAEf*Zxn1k?u zX)Tvyeq$=Q2+k5l>sn`x1{%q}ZRmXo)?p+A3gCM($Q-Qt)GN?EaPaoEtWQMiC(fCc793Agl=!1kk~sMOhM|OJDA`~;U~6n?IMy#g-{y6e;>VIpqH(Qpu#r?h zrYtB1JuIayjspBmR~0?;iIWxRrs|oW_tZGf9(wDKfA1{r)Ix#FgEEZO7z_I9P?kv3 zL_P?5IoJ<+lt4#iVGjPRFV#Y)Cp}=h69_|NHE(*CNF>Ax994*-I#5M5pmzSihGK>q zCOd=sE%XCfSFpI)ls#|Ywr~2XFEC^tv`8IsNUvs{EqeY7bChQdJ4GoKl5d|%P$(&) z4kxg-F1(ta!{!$sM7b#E=KNa9PL?M}t5PjohAzUmKbP)k$rpgNCYObs6EXVmo9Ii! zD|--||AVu2q*Eao><7%*TmD+;duXU+D!y(vc`7_D4TMDhul{Vez|2nF+0;*gRpeZ^ z5P-P7{mLM}hVA-HA5SVRTy`md!^xpt81n)@GQVCZ7VbIfM9O-LJL|>ZWp)NT=AbFB zhIokwZ`=Ay-*&l1aH!_G8}kH|xl2^Iov(zpd1f7a`aGC?eK)6&OcwjyU)r9iLhH_v zxjNZcO{3hq;1^G4U_#H1QAGZL%=GyU{Vniq*c-8PfBkJoXwm&xWs4Xq5UTs%jTnpC zxbfM;n@*TK+;@Pu=NESIbGs5xWgY>aPJzt!``-n*qY~NJV@bc~bT# zF_JIMdau9T<#RLE5W}pq4irDX2G=H#{KclYUTab(E5nO|{}Pd2_8ui>1L%>otxnK~ zEzqd`9vJ5ydBV8`Y9-$P#UA>n7-AN-0AZ+^bj=e4-PM&M*aMG9FSkjJp%3H89fOcaP4hSP zIg_JcBztwAs-$bfPlAGnNbm6IgswNe-mZO8_vwSFINd^S{d$}WJQsxmucU_|VuaD5 z3H=?yTxZy+AW1~?@Gkf`sQSP2XBDehAfK31CmwZEz~9pSB*2Vs8Ge1pa%1cA1D~J^ z=y=sBF(w_H@7>y(y=??YoJ)yo3Y?EX9=nQ^+C*Qmr7P4Ykw;2W)7#xqH>)AoRglQ@ z!Q^cYx})&lh7oaUvu{@w(fBtTp44+1%E${Xl`EJ0w>e*7lGXf3?IBUE_SZM)1<~%G-ONQAA9z9K|Lv#x z58>zIei7ntBZfurzqF)sS+O7>bi%*GS>3s83WynO)50-M*|nDW{h82Pf@4o=Oq1&* zUI;U+nH3n#@PVZd8~%YrqwaUvtE{Nl&v*2*m~cK4Y!dmIZgxCpU!FA&oTk&Eb_x$8 z+uq%vSN>Ds!%%{9c#ON$oFlI4#>5$oa?_p|x*mc6Fp`_3tNn44QmaB~{k`Lw-q ztDZvg>6(2bfS$%G?eUG^p#7!qs|y8f&fRQUEq?`-3g&cF;@`ug$T*cV=c^{6;D&_Y z9sd40s;@WD}=cEaiUra^~NCvT%FD5-W=X4UzkI_LaisS2WMhau~R8 zIFQ8C|9Nre0R8S&h77aZ;hvg(US+ZT47N7i6xbn@CFM^(5;>*m7e(tSP=s0c=yx&J zeF6`i9g^FRk5j{Ge=P4^WV{J#Z`{TBM#HH%;L@+Q6$<^w*QignB%glNY@l1Pd#>KU z++ioO2;?TL?0Ni8UcjzWA<{HH!+-c_fTD|B4gK6%n}Z~(5)`g2AI{vHOd-_imzDTH zuuKA5FZ(3Wd-v13Jm`5fli#)S6rk;ieEG&a)!65b&XB*F#Bn|4&dB*sos5;;z3l0- zdw>Fc&0Sp*p!;A1DV-5B8kAPoyr*R*AHF&)=~tX@5(G9k`ZZK%JYv~0$qIy7QMZ?k z-$g~c;Eyw1%Zw7-)A=iO`(^!i+C1~iSn}kF7(4=;DfLiOSCKqk;Fc)0qM_}Wtnbxn zLJVFL$JA@|<^3?3;4^dmIg9)cSAR%nhRw#gR=AXkeb|_If@tj9j0p1>4gSTpZE??Y zE`TGWbNK&gx(c?a+NUofAt@zYf~3+NOCwz(-K{i8FCpC_Ey&U(urw?wjnqnmbS#TB zyYvz-KL6|e2IoF!?m6>|nQ7C)ZVaFu+xKG1URtCZRBEmJY$% zheyV>}Vs$|CDSLB4|Ln$rxf7ERtj z`mO+>RH2?A1;P`V{4xB}@UpGjjz+rA)|YY2+Df<0&1C^4h1;{Y;!Mx&N45V^9i=3E z=WjVa5F+<`@MCzP8UubnSSLfxhJnob3#M~&g{b70(%m5X6OZJr!L^GJ>O+einS>EI zGQJ8{5nE42^xWTK5=NExx7IZa{r+VQ;qvCNQ)-2=(DE$==Cs2MOl5TB}UFj@QWNM z`B>kYt-X+|jh3*P!V=>6elHlYL2Hj=$v*$3%HgTgcrKCIZ&0s9yLR$fe85CW-aLgj z9l;Kt4Fcx@X{|PFIIs*b6Q0BFBlGu83io36gu;i@HJR5%F}gfob~TvB?2BC-yQ(o3 zies7{zcKtv7zuU$bHan=xlMoH*4YD@S?W~Y1Z#$Q;%oL9g^(R>t= z3UH3Y<|}1M-vINv_aExIz)*<$X_B>I>BCPE`;ss}6;KXC7MyPfM9Te3s{**IYRL<* zouIDo7&yOLRcps`X7-a*;GtT{kE7AAh#&4VWc?E9I(x^n#L&puL0a%hjV3tB9AQgX zx0(1(mudAHd3k)A7nr%XMCLv2=ED%L^GeiufRI4BgDM!Fjfp%CIG;=Jzo|wKOJKahH9+&DE4S)AV#}dg-{W_D&w#V`wZwDGbAj-sSRJCP zjwAhh`y4G1{f)+qvO+&446aBqOpG%%icDeRhO^y5f}H_4wC^hO+O=SA%l;1PBV6@n z2;B|abo-l49B5pJy%74M!I5rTO!e1p8dTuhwjbvFti+$E*|B|+ce88LLYSS6=uyi! zrAroSF>6fwodn!UyV9Sq524x{nk+TdStGwM{;&>_?3~n4ij4GSOzoZ! zT`jZ78Nmk%IDkhJznkyaZRD4==@@Rh5AO|RX)crA(%a!Y=3<j>PWg!hMmiKiq>z*GCHLS;pvXi95 zz1&fPT>yM*&&1LDv+59)*VbIWI^%O@2ZD0xVYaNP6oo%WMcp9yIAvgtYqqs z)qPaD##TOC#ouwqynz7xC?- z!fu}b>ZVhPVvCS1u<(#tE=x*uROl_v+iDX^?8JA}1C2>M(->v8!>IhF=kgc!bxe4x z6sufftONUxrCU9IgcSudvpnhEjU7V6;~MlqD1G}<)lam~9wTB4!%RrCJ5yFZ3VGwB zc%3H5wQ{d(R}8tgxo}%1U2?@b3oS}Hm2R8=0{XC{lcD)Ka%+b&@H9_K<#PGhe;o76 zJBnOxKYti6`QyoWIb{D!#vGtAt^0vbhsm}}EK*)B*(?Ac3>`bM1S6rX!fbtvxBV)p5G^ z3BC(|ZYE-=!Nig4xZ9p{ay6>Md5ZGXYRfPq>4w6zJQUfM zVbHH%MbV`kWeqO9Sh7Ez8DgMmDm3yMn4bn>%EnUn+qX!*%=9<=7Y+kc>(S|yI*Qfe z7_W>5$G?H%X8cT4etRW*bsd`JcxZi0uY7-G#o?`f&^jx@`JK$>GK~ZohS>=iUain- zjA6#g$r3$wwxS(uEjOzCnC>qc_R5wVw)p)B_Tr)4nI!U$QU~8RKH1zj4>s3l)tsiP z;O7~=nmHc;i?2G9VSn;|U&LQKH=Pm_psDV(6xPFo6qR1G?;UaayT zHSwFsTz^h1>TC>E2uL2#cZP_6o}!`YXYmS|%XS8zg}DWYIaP|Ar7#f_vcatGqd;ZC z6ow{ZEb~#9QkP)D^WXq+s%e{3Pl~5viKxMI7{=-S@@IAsyY&V24Xr{C#P(b&U@g&@+q}B35qg|G4r*e|#-t08tv$ zzoMymzS;fAr}a1}VYFs9JNQK)@z3IIaJj6c;rj_3^UQRwn+p^_}V8MqIco498G$gDE z6XBkUt8QXf88=Yn)KGGUhz8n2fJ@T^;P z@vsSmdy|Vi3*+f-Rpd>}ht?vF=q*1wh@Xrxz6smHWuUGDU6 zMvmi9E&*@2ntcA1D{MD%GW*ndL;&>tzl}sM#;LO}KaHkZ9-0^3a&0}Mt13izVY}{; zh*Q9SZM|4~81L?uOvlgymleh(%>nmy1a^$s*};Di zkCwc>rN4jsw{}h)^pxr{S#$wKCyP^Vh4=Fd1$Ch38f9jWw0zucF}^$jcQlOk7P|ai zP375?H<*ny^*LA5*A@ijJQlO_A1pjibvBTL`#l|y(Er(z83~->;G)hh3#h4V>^f>c zc)LxwbQbx5_y(4Ag9^Z+W@#KgXPa29g zDfa^gp|0WwFI5rY^ZGrV**$wUV%c4Fbq~3?8=mh{_Sq>Hj;FH_loX6x=i?`f`^HBg z7|8tJ&w&@)x7rMAY^VLpCE+DA1WTh{3Cq|`@z6=&(o+pPDqaNJb&L9Tuaab8fAQj{ zgWgqbXjFl;P91LmGarto?pcz+0cmxBs`*wHC`PA#xPw~(X`xdb)=-1|CCa$5O80v> zvfr%9bkl#PZ4)Bh?=i{X!vUAL5WUZ4fBEZ=8PknVfebo2e6N4MWiyvn=X4uxfaMq- zA<2|kyW5EW5A~4tJ$cVGysif@Pp(p@Mk7+31kPCeQXatm0?9l5d8e@(eqQ@mV>RE{ zWcl_>KXK(o^SEUSan|sdRRy;DT)$(w=K%Px&jZuK+kc!s9XCJ*^$A0u|nXkQUek zV7W7BHGTjr z*J*N$UXfPU$ZfCMqm*#;9rasi%UQR59qjF`7gJGW^yC+O$@X4}F-EvML=e5^=>9Y> zN@Cqur=$A`sFM+$i9U_9!i?Sq^Vj9}HI8Ei3e>;9X!BsyBWu#yuuwbm8`z}f(7^_J z6y2^V-)W&GMagLa1l80EwD6v&HAvTgmnI%UP0M=kud!YHY&9=%IWaH&$wucT8;_}W zf6BWs^Nk>7MDEJ(gy-yTknnA6^h_V5)Ei%AP0y_P;;>85MDFcK`_28rq zC%~PzQ={NpRD(L(EAzAm1VS@8IBU0L(L8nH9rnfjA%Um6Sem9#RaL}k=1@b~B*R@4 zc`918$7_0WsnPMCwxw<4?5MTmQhxn%TEsVHk&7?KBMbumzr3ZVN}`BW+hrfsPTY}c zRzRfq^}d(YUFswAi<5dp20OkzFWpO{BKtk=Vk&YXSANLsFBvoWiQvt^yze68b3rWu zEP^%c?GNyP>+DQ^wPGY-v<3D0-k)-~#Eh#<-iLksEb!3lt|9X_4}FZs2^5>&6E4>- z7tjI@dD~6d(}V`&-+39ePkU!?iVJ)9C-~@-Dc(GS`8a>aNk($%+};r{0Z;{#b}6ub1;yU7e`at!l{KvjXVF z$`@)Y*bVT}`Y70+jRn$BQ6rOBK8E~K=Eofw@+`n_)7E>9&uNNo*}Gqf0^j_uE`SeP ze$}FAKs}=Y$f#tbqn;zPLkHff2+)iT@){*fYZ=hh^tkDygho3yg*b%(tMTiKHOK(M z)I&0_53*xU?|09GBeh|kpLdH9hKexHtPZhnWk=fClEP`J?(l#`(l_gYY@iniN>9n| zrvbxkdjm3A>>2v*7R(-w)c6UT=VzROM(B=wPg2yUX^HV zo~FXpTPopTHEkf3|I&*oBfHB8d|E=BRKeDTy)FPp9_;z68cElI_rz;%HCe;puaIPo zaIF>z?JTXGzTX#&nG|VKIyXDJpHfdc3;;b`CGjk=>=}m1IK4d9d~ounWFY=AKE6p_gQ>T`0=w)V9x!zh1S;OqG?;F8U^vL*gNU?9}p?x2jG8+ zG0?geV_ckJ{b*6=MM0>~IOfUur+i6oO7Cfam_1%pW5gw)059du77M8!_wte&LvHPq z)$3^QKhiScwDc7ziQ8`u9}6pO;)_e2sxC*o*_hAc^ld{CN9-V6o@2~Q;2#^8ph%U7 z#)o(WKtrgre$e9#Pv=ZZ1xQyaDp29;ai(JO{^ID`40Xg=IY1>F4UU0+UAYQhX1*lk zZV^_ZDAamPzah|9t>!C>7WZW(Y}w0meLKvO4MB^^4P4fN1tjag$K67Fe-q~fpuVpS zKY0o@Ak_t2^8Wh5KHbwFTdKvpQgnCTNR}tO{Q)pltfD4vrqy+v)Q|Fn(A4XHJ!J<~ z)KijvOOaq4e za>J&^MY)=9Usa29Rwu-HhI#X))H)X67}ggaQV|WAK}DoA`Lcq=V+9k3g_l|G8@NM` z^Bj--sEF{e2$(qUPiCi<3QLQ(=lD@NYh&GAaov%B8j`9hf;cnGTVEb^%^p`Ty@?!{ zNuTvda6kb&3!QQoXnXHGwR$rQ<)ZVQRQboy=wsYt5g9CVM8-URwdE?I5kA#oM}A|4 zXs*WGLJ z#yj!MwpN9u7R)%^4?nu^dsT%2C`R>vBPkb?bJ&}{`U}m+TrRyUspE?s4l;RBV!l&Z>=PH?z47hV zj4N&9MxO*hQnds%7vA|TGX@@W*sxJJFpJz5+-bQt&;f+ONzzehlAxbYoJY%g;PCB3 zg(TQKu?PPVHw57P419cKZk}};j8s$;dNsHYsiS>IV>B^X@cZRjq-e$xRq20Kv&x$0{JJOl z>*e+v{OnYb$R+pXxnZ&_)+cgNmk2PJ_m`MB@c;?Nknm1p(#4aIHA~)^c#mMjE|~4V z%s&}69eP4@ipJmOVFbZGlFa&gWgE*pCTh#ATI>`zB#RE;_o4v)?1#tBgP3)1A%<^S zgW!0ySFs2~RS7I3OTD1`8S&T$lpIO#>*A+kd%yawF6PJjyGCP%R7l@fikkDbHBo|`3z4kZO zNfC;MXtZ9~EYzX|VFAC)ujQfk5+_}&>u8^A;hBE!IoI>%#A{5FX6ki=d$hD#U1J|oqY`(> zpjV3&1h=CjZaNmsJrwb*2NeL~BW1~dg0NUm1-5VVk^%)IYwBGF6ZE$ho<OE4z9#sintP3w1m^}!~r`7*QLVr3$$@wbw3rf&iRNT)1IHuB!d zsrc!ix!f!#RZ56HK*dSH4)$G3*z&QsyY2`$RMB#WW4WgK9*-u>O01M(Y9 zX{CSGo-lhZ8DS74M2_Lq&66ZJ*t`HW1fXnotsVS$`{pb(P;NUUu~gCQNnLguy5rr~ z7Q7!o9p|~d^{yWe!DELuu5jPp_dCO$L?_u|X(;+DWF+H%Fm(T3J|skhZc9g@GHL9a9vnz5 z*H1}_pFFTFC47l^?@M6U=&T`=&3c^hsO2yb^lZbIhKh0Dukw{6l%HSQ5CLCpS19vk zYWs_45^?mAtQI}Jk=sKy$FlfnUgH%j8OwzCGURFI+7m{(r|3r$XL{gloy(H!;ds8C zVmLUbUg^ZO&hC?dS|_NfQ?O>a?Z&tT|GWP<5o&AoM~qhBF-LPp@1%auW&L;wan201 zh|hXa$i;-mWrF{k3s9;BN3;}|tM@Y0$@ioCxop6XDik9zw~1YH!r$nc^&F~|)02WQ zJo(*;g%>rDn+@7%k}=WtN<A8(Us38_{Uj!wAL`2={*lL;nqW~ql<#ZS=+K*3saYj=Z10AlL9vW9rmPBG*b67VOXJOtkaaIVdA0h$y*!R6=bF_UQYTriQe?Iqd9BP|V|K^@Fjj(auJJ4se5P@H8;%6G9$Z>u^oN4M7d zKbJ5?%+Z81bk5!f=WDa8gXLjIUtqD`s(Y1kE|^|!6?}5(M$Tk7vJ`D*359p68R>Q& z2Fd;h)EmPFw&kGJht8ta>3yopn9{Uy0o3oJoThOQjIaa z0}m5}(|h+67(!n=|Fgg{to%@<=04d*QHc%_G-BK5O|3^%m&V;h4|Gk;%X=NJA`T4Q zv#KcvS{VeKSFKe@Iws<}eJA?!d~5is1Elt>x#_tXSGH$XWwvnC|B2AB8@-8n-M}WV$6p&CsIu={o0hCdg^lD#AXrHCmljC zF8G0S)m1M3tL{kAa>)Sv(bUj$A+nnP&W(NaCGX4B*<<{s(=22|EaW|VAa_25pNo^u zf3X@j+&K8f>&QPYIc)+(!1`C7V(|@s^#IOatwOeVD7L(XD+B`tw!kexIlN;x0k$3U zRTQ!R3!YvUf5qs%c9|+oQBc?onMB_v0nWh(RV*T<2G=H) zv{sx&5yC(mMO zq;2}VGn;`>LwwrQyZ9?eAEa7YMG>OqzZ7SCYDSIy|e* zD~W97Kr_>Xx99&@{^pR6;*;2s_OA@M#obu;>`0hl&Fm5DH?`~K zDm9}go58+iG)Bn*O1DJr7&d*EEy&_xCdl^?Hptm|_GN|nz>mhCI-%UPV2=vt31MjF zPll|JXBNVQW?|M-VJZ&qmSwlVosKC55jIkhw|W51%j0qPmWT`B=Q z#fs@-C;F`!H6O?I$3}XL=R8w*sypvm=J^^|28O(}VIHfvBgGjwW2o5EqBKs5IInPw zy#Daaz;z4dS?>XCN-RwC5EIaG!Kg=(TzuO=JLe#YVZhW+Rz%ZTsFd4_vZ!6fPUYFU z@EO}A3%&@XlS5alVm@eo?*;la0w;EA0crsV;u(~(rXt`!RL_DGxo58L{e*-l0Q@7O zv#(+N7pJ0;F@2AZ%OQT2yT|W5G{4z3_;U7TUV=_S!@6y7eNR(FcE~&axkxnVImt#g zLI<$baTiv=XGqyx@c5DmhKDN(m+NCkl5Ij)qJ#D=%~Lg)FQqvk!m~IIpA>?aKZ~?> zi7%Z_IVWMw+~G%lDj0Z;Rr^{hSywu*Y(G?AEs;=H+WdQb+5I0h)sIfc;NUX%g?rDM zH#8H0xfLV?%6+osclr#LntDwVsN>7l=)%{>?lbTr6D7z@tUdsJLwl!0uL_lyqS$$# zM>fAT-{-kwu+`9W%BwT1X;G=Vq^JMX_D8@yoUpk41u*fz0R{RgOHztJx zhb779f|xyWivtNSLxqt+8GivnFN^!dL0~~0{Sq@h*j2c*Kv|fo%xg056MeQHQ)IAb z>6$vk;7h0*YnY0G`Jwd4K=Zx7-{6P>hso2eoYIMV6-dV{R0=J4{#=19fuL0}*I`fP zl1;kg-SSJb`!v@Ivd6A&!OFjat%&O&D*hE(ZqE23c{_X}w-4P?&{05S$9K|+Z!Ntx zDUDztXt%w2iRz!vUN(i?&2;Fjq3~A5`7k%Ull#cs{Z3L}x5=UX-1w=tZ-+l@h?DSd zPyQjnzWIVWz4)Ju;EVaUmLYI$J%!Lwj_^K|=;!0V4cnX<3v7=KFGBp$AEJ6WMvVg? zugqaqDeIw#Ed_x;w`yOS&Wx^5*BWR0v4I4z%*t!B;W}9^PM+&ToD5md)(QK(JomBm z2QgUYrS(DmYwBOI2+rTDqU=0%Irj6J@srrps3XVa9$~8~{ z$nvike(V7x{ftTAI3=n6&42a~snd2@(6`frIo()F{Ai0t&^=(_H}-sP>6><2@)cPH z4+{P9{!zy8Bgo5D6MQbS;|Ef1FTy%;`UJlxSlLDEN`F3LpPMhrL0(Y{N2bYNH~z{B zkgGOt|6TUuyyYyY>v#M&U$&<3C59YM^Oakb443zKUv! zPSEI$29nE7LNB^egmQ1Hlueg!=MG^%En6Pg2j#c||2bs~h6y|97{jjHH&@qLqJYD( z(Y(grpEKg~@JB5Se_>`+LOHHLLU#*((3(PJB=YjO;R!;LZb2b8JuFzQ%}d@*-k`8B zM9IBjGjqoL>e7?vwxMt&_{8v<6NEwb;y%T~HI-P&o+~=ab^d%x!K){Nv=dl_+gXyl zqfqSN+|o1U{8%Y}tlM#g#L#oY?QU|NC>na#hafpwj#9Xm!)&*d?g{Nv=H0ts6tS|Q z72AP@0Wo!Mp7a(YND1pdNv|tkK){E;Tj){kVD32n{NYXQ>Y%+?A8B!L)5@N;VoJD= zB#Th8+(1LX_pw+if*GxP8&x?cBT640-u|x$gx-YTX9#D0ledrkiRT%Kx9UOM7ZdqM zH5YZQmtvc)nQNT%@^E?_(gf_beh4>#9pXVY5Tc_g|Bi4U) z)^?l#6;fF+%3vOXMY?lY|~3fcS!F;b3y2D6Ms2r9Q<;#7o?!(16`#NNRQS$=SUhWPeNM%RO=$%y>- z36%2MPeq?1nT&9uA;(a6ARZVv=#3|62_`vQzVKA2$gHhby zV<-eOp2sK2Id}G(NfH-(pt)~EJuoD*vtxNtcWzn5ef2AoV{YzJ7ABh6#29|qT_~Zt zc+RVKtH1w|C>@N8$T$yH?)sxZF2}z-p#?1liOwuJQ%Ouw>cjzrNwiCbqq3i32>s+E z+R0!v-oL(0Ueug~Ih+MsIMtn*bS(qk+O~*sT=QY>V{v$%XZD)V-JoN9vqp7ZEXI^4rutHkToo|VngcFX0E}!zA?}9<@?+C zMGB0P0!yebXxgaEiSmUbWNEoy(6Xoe9|O*IgDyH;d49I&j*l)EBus0o!y~(=>Za$k zY5}6dbwMACpxw+1n0D}i zV}#%G7A694bD^=`-dRL>)`CYv$5s_?*ZwE|bTaOnsr3~) z3sk;xRZAnI*C)4Iy3)3O7-t9120V@BR=+bMTip-?T_`HxJFci^vO&g(nTRRCJ{~RL zhgbqU8ooPsyQf);&vgdvsE|>pQ`TB=Zi>9a6DqhJe0KsIq-vrUCs)mJ z2MOxW77-}BWZ>M#CyCRo^E-C(@BdjvK4ZCqWH#HPdT(X}2@-r2rH|nx>tiBR^@DGc zceXo;sa}zf`b*IYn{xtC`&nD;O57|MKqUj*k#nKaSC<7{#ymx1XzG-MzvY4;-APNc z(LW-CHB?6we9|;^I!ty`6Y!wmpP#Awju5}DsUrGMiT?iXD|OQh^8=~N?tInhSImGk zTHsO3UdI!v-Hi!ABz4idYC&_#FJ4X6i3k+nCPp-fBpYmoTOd94~26W z(-ESGjv5Y+6T)KRDFV7FKeXuxB{Rx2SN6Q5lPJqA3=-3rJ6qP*x@uV&8AnG|htz5q zPhLIX|9QG(p&Q6X3f;T$c|W`FsCC+J&;0c(0S8FP7XXuKSzZYjOK_-gd;q+Yq^|=L zj`AD_FipSdkMH`p=r|=5k8$t@%T&*`L1*)t)X=hBQ?gWkq zyLp^yo!Xn;g`AySxcTl z;IkL}1)zc)+D!)8kI2bmI%YONhL2ZP5yK4Z?kbV{16v^Ih;}W=NP5pg1a9Ob%$KV{ z^L61b!dJ#_(wp^c%~E2a*UldlPU-!%2a7{XdS%t(R|Zxb3rpeHDJf2VzzdowA*z(2 zCktw$uDWZPtOaW74sSxA>b+&bWvM=%9~h`J-|#Oh5?Rno!8bsk<^-L#dzf@nod81- z9~sLelTO1#FXsIhd$y&8()esVW6FA0mRlZ})NRb~8-pL5gYUk$LXU6e*AU<}2iY^l z%IKOBvCcjN&~$*G{;W47&8R*!+t@$sv9x?;U))sWx;a0yMkV26ungieutu%CU+h7I z+8k%Go!F5W;BZIDAxws90I~&~LerL9?zvt!ty2+%vt^aBbA8G(r^>}a;)n}BQ+b30a zwLChpIJ4u(dkDs>86zBzBE5ZIM9>RGxUhkw!?il|-oR4dHcFKWw!9s{z^Cpp7zme* zx<*0rjv+XRu(=KgKiuY1k z7MjGUnI%jbbV1FXBs3NucV3HXf2ZNPNZ-Xtt|P@9f72xcKJAb2Wq*AA3T+n;;<+SW z+F9ZP>(`K>%ce_d1Wxn^BoiaWIiu zV~r2URsF*$^7(RY1Bomz8dn@Ru7i8xTxvYFXR7D(@=z3R?UOjN8y$ih?vw=#hLB?$ zwcXX<@s3#~)w}|eM3g>Pr0&50d74=5A6F$7Wu?&b3QiiJGSrqwi=SRH`f24v@YFGI z^L=glJcBhJ?nj&kbqQaoJQ3OKs~#J2d^&|ROnX3|q=qCAru1!?x%^gHn)m#QxYoED z>-g8&hZ9y%u@xyGG`Ng>Ur_BTVBpyN(EN@3fqL+9d3TxLVr*U$Jx1ElU#|SIos`wW ze=uuT?03OSXgpzl8fMNfv8Btl1D;o~C6+u&77No13^4lh=(pTouqOJ5m-aUpb}ATt z%tHE|;yzzb<0*Iaz|b{9dw@m5f<~3yupZUHaj5~Nr}^&N7-TU~fEHp5j?U*h+_#IP zrKRRcld)SxX;C*&yK3Ozd>H%3s$CkLKn=2(-~QpTz?w3uGhiY~D}f<{O)YHbV?tj5 zjRgErHs!EhNw83t8hSX$_)Xslj_80N?MiL=pVA&CYW|0^=IgRHZb@ouELF@VG>OeXY_5#zp6-}b z;hBnfP)j1|tviFMT4MQ1rV4pD;lswy&eR^c0OZ!z+jZ>`!)qXfQujI@d2Gvr=usmngpF+bipzh7Qb@FZGnlT7=59b1TRY})`{nj0B_xO#Q z`lOG15~HJ08T>O1sQqmgr0NP{(>@*%_o@+m;G)O$j!W{ zyohuD-C1SO*MtB`p7na$`%;z+y4aH1KXjl+P?910UFuavfB||63mboLIbWUw+vAdS zi@#*d74eS7`kqoLS4Y)nCf_l2CXIc3nBwZZBfg3d`wpWYZmCbpv!p(&@rk1Q%_Ad4 zSb)9%Ma_ZWnW3m$d!)b566MIL6OTzf{flYVNE(es1iPx_SZE7|p|JgcBVOE5q=C_` zxoQfzdVI+Y^4jhyQCSz@ezYU6#}6IpYH#UzvFrYXux=SU=cbSn97 z`30{|3DAs-f^sP@rxK{ae+3NLSECr+$IDpm;UffkztG0&=l(*5Irk-0tgm~zu9$*} zrugc8BVk2U`L!@nnfhwo@A5Tbz=b9N-ESYLRxI0{eWYh!{tn=+SB^MvQ~Q2~Bg z6|ZPVf{`AaB))PuR^Kunq#l<~?q7W|oD{VPyebdr!krWSY}DB4dcj0->RkbnYk5}W z_znqJR3Srr;96I2XQB=DlgM}jMNLXi<9pgF?X%Elt?q!ypZ=Y3RcC`)tRzOh{pM)Y zV&;+1m)R?lB@cT~msKb5E5@vum!i^sg?yg&OZRaag7R7RQjk;hY4aEKUuTbYGBcyq z9wol-bD+_I-`dn^P(H=kc&gn%OQXB@coRA9jjCF1wrmiu0E#!~^_zjytJFu=_5zQM zUyp&PLC$8fybk;HrfsN-S0MV{LNtN0wmG$^>dP+LEODbg1vE`Md)N3+vQ_# zW}oPy!>yU)Hybg1Hod2Z*@DOR`mZG16Wu=zhN-0jDXp=H^uyg4nW>DL4ivdUiwO;G zwuVA=-*x77hE#ta?x6VN%*4I)xRtxia5OSDV~NZYkp0(_xX&f!0}0`8R*#3YW$wAa z7}Ba96{SX|j*$D+(U+KHzbz*pv9wj^FoLHI-j$b{r6adwDzDh*jWSQOLX5yggcQvh zY6njm`X%F+sN)s$38~aj1|O>%e>S~9Jp}*d|KDK&HurWiuP@vVmq$mVfZZVL-}$-; zxI|2+^w6W zgpn9tn#tZRuF)iGb4tPeeqVTg*b$Q8=|z8)Tm@ zTETsxZ7jIQCYg+V44#eh^&Y1N6b+_E5_;w)Q;xn}Se{v5Er_a=7%DF{!$l`c5K73p zwMz6$x%KQweO)Kh>u|xsJ9zaaFUPwi{xG(Wd{jM{;OsvCQs)4`Y5p~v*m~kqphIMr zHzN)0-urf;c%FJq?u*Ojbi?tSq)U1fB5N=B{otv${NpL*t!kgHM)o@I1k-h-=u_CK zCB+u0UyukyUx*3S9f`?LekiyqPv(ktTlvumEPlmi{i=u}amm|1$qJE7b+U$GT`NA; z!p?4r{bjAcQQ=mUhk5BEb81XfX0veDsyLclnDsk@mLD>Y=)x5tPPKAUxu0nqz? z8qxf_tISSTt$6cVJA1EoJ#)ny(mZAl47D{m z?Pw0tzDKzcYN|f0t;nQ|3b0Q?Dvgb56+Bx6ihp?;&9KQFyk1Y3(Y-DMr&f!c7UT>m zbk)l9_`u|WMu0G-YTJ74V23mvH!-wlZA*uG63M7<;P3F8ef9}blB)vxojw#!V|~$ScBVpbaQbihj-WU zSby_@E{@3?o-q5K>i`j;A`0`-vd2ou*TjMlr%}k8_?aCddgcAbUYc@+pS&9sL_WAW zY33q>EMs_8*KDlK%f8-;6rs3WISnd}M8R1jza229>W2A*2zQoNn-)0%{X&+;l{9Ot z>MdzGLA%!ngRQ24Ci-L9jkOYABtl0M949QXokAZ3RxCR)6iV9GE~%LlK3d&-{4Iy~ z`oI*F$c8uq09fM*#eB*ieuZI712%q#S}HtHFm*Plf06vYFyvZTPTOeK((rN^a2F>7 z^AwB|pbsSof3StVcieiP4vj%C73_z27GqCmGVX2B`5?q!qx&XnscecycINNTpeh{j zw(mY)Zu7ziEqy<#oTwprr`e|p!Zq4&D|*zycVVhv+__Lo@GoIJ_PlRQJY?(WOMv{2 zZMR()7ZdW?R=}dgclq|-R*g?hZK?T^e=hT?SmrFVf_)!szxAmb9Bakc?o2Cx08E~| zApPF`6F#1>ofkkZkb66vkC@#qjV`D><+;Ey!6 zp@rtcQV;NMGAj18PwcO4aQDW|iirK639?M2e$71VO-d4C8-YCK~apn(7p|$%spEMp6mqQ@Ovy141WS^Gip z4E-AV))FZ6(@G68zR-d~UbeaOFL5#QZ7+Q9hba6wP|ldEU-_B!tp^aV()b?csgqpl z&_OmAdv56GA3YRCp`=aOIx?DyKQ}SZBwav3`tb-(C&;P@@U(*X^=gCkQI`fNNn{69 zmPW5SfXRu^*I>MTa^DPEc-y8NllsTSbU@^%D8rZBeD%;2qWJw!GS_azF6~pT8Cz>@ zs95N}Y`{9><-D0tY4V7r8NA&j=?$<~`@S_*sNr$S3&8^*4Vjmxaw!n+}(R0oClIjgSg zGCM|V9VkaP25+}^me*LM(`Xz-x~rTn8a4ZQn!o4Vame+B=*co5cX9}McHhp_W3CW2#xp*55=*wKz#?J0j6RZ0G<9G+_Dk>1A zi{LYBHy-pnUwq5AN*grzWc&$!rIFqCc%6{4zg_TD;f1UFYD~G}T0%WnLZU8s7a@pW zd=o`y_D1_SO5seel-&EbS#mq#V=7fy66@3NGFr(SJz)5e`3bG_jx;XRo&le|B|qrU z$2!f1>GWLg_FU}h06$xMy9jG82Jx;lewOlN$Ho5t0Mp<3;x`K(;MVX7o zmLd*wZey_X_ealXf5oqJ65d?nB66jFy_M*{UfV-h@XGhXXXih!`QQ_-_c2X`Xa?l2 zd?w7OZqMO7pN{8f;T(K^n}!DrnM3dAYYm0W_PAciwS_$$k1)aGS&bX2517OFM&%dV z`~b?s?!{2Y#^5de|6K~7(Q?!Rd9IHoVh-J7yAL}1xfgfq>?f4ZBILJqsji_SYao$T zJnOy=##tBA5aXT`=kb}sS=4rmE`!8FQhrG^blVNtOGC$d#k!uP>F3;U(P$>kogUe zWB1X7OE+f2 zYxrgfnHyG=mx%|+y^%TBvwH7#H5v|-LMo3zaV*@;t30}*ygkUnd_V8*uTS#V7y92F z?Ef~f-o4GgKFNwp?D8F;Dm%sX-U+u3qn5ZCK=zkXuxc3mAQ1m{JuP^w( zwz-$TgY~EF1KXhE8bdt7!FAJtH&*rr?-CD=ohUyOYnsOAe+K1m4?R9e`FswvMUI|N z?3=q2^WMPEOMU_H03 znoTU}z4aX${KA<11wCiG&!x)eB!ctXo^Oa5JNL7nlk?$B(`Lk#VlshbJ#nr30w{F( zdp{*Jx^)jWO&RYS2P+BTx-U%Zu2{ZcL#*!kWNKvfdNTL``XJvf7x?S%{q+(P4{VT+ z^s7nQ?Nc|&;vx|#p}tKj~+rF_N^axt#U zL(MQr<4G>J>xM!eY4tHz?zwOXZ$SBkbI(0F?Lmym1Wt2*!je zpNi%|=RdD}#(tLdaWfS`U}oJ{8rvfj3Iwfj)gHPRjJiOjrfn12p2n@*h9MpID^r5YJcddIbJVSqL9xAKx`mOkxu5Dw9DxZ@GF5UG)VdThX zPOUT^icxund4 z#|=XB+-YfEV{VPyBKYvRFL*9DK<>~yu!_o1JpNhlWIgjWnKhh$wE*KOgpD2U-UJJ2^QIcTo^}YT>?&`eYU{21>&xJK@^2Fi ziM8bsFgBV|KI2&1J+m;)bS^dK`4qM9it>T6Jsm3CZF@g)tj}`fMb+nlb0FlNJ=i~g zC`}TKihc~Z^Ekpn_&*`;`YP){R0y@4N=O5Nv6U<_IL2vdACU%pKQ64MCbMMZqk40C2sC{}|!Llxzdt8vGAQl9g~f{ql=Q2QGUAI=7q zm#Oj;g|LO|GtGlqN>K3>6x(k2oWV&1TQx%&lp77#!W(y=r8%WB{I_mBDmh1OAWs1< z6v2CXW;#}~mXxHVD4%7T@OmObzGUteCgZ$C*Q8-_t=l+W<|ZYMh64~vx1 z{9W)}9j=3$onRZ{m<{3WoA6pRXvjPrc%DNDWCE_&xRaWj!GC7OzN}?eP13Sm%X&dk4zID z;D9bDpV0sq3R>TRJif#CKZmp1DsSZ)_`aMs&n^j)wBh>tG}FXpkGY~nd4S=%hN^rj znuWz&_(h~-ZO^OK$D(>Z72^PTKdb9|V4mczFX4Xl|4deTQgp*&0oBjdZZ>C`gr=oeVVQM>r^=b1m$}JY!FP$o%iqRwC&Ip8sVGKH1Zm|71 zv3Os?v+t>mMUOQCDtQsYgMu45^Kc8c#%+L-AxCpMSYG20 z>f3(69OU2aNgn>yCYtXpM zYP|!30Oy}MFw`~7;D{lh*4^G;(fgTO8+1u95(kY2A$sGkag4b&Lq{!8UD}G2EshUW zJ{3(PW%I*sYF5#R$RY%Z>cF`;AzW+nx(c?@hQbSr?4io0$Tl0$YbA zBASPZo6T8^mt`n^?`2~#7}{>le1S}h*4^6o^*=>>w%w;o_3;MqY99iJn?aS&AU}f7 z&0YDNAF0 zICHhuKpuySo=-b~^2zy)UovrX$~BZ6y}j)9Bn5GZx}M9o3o_om-{5@D-t$?tPpA!h zX9%etZsD{J4_P~yqN)#<+guRJrvv4);mra)>qQlUeYN=BoX0|bV#(`?C8SQHwH8_A zhwm$lT6qwBuZGBjX6LU_XSP95Q!ZmU84!z~5oX40f zbf&mD;vxNeRQoT_23&w}TMWay#LLZ1(_Vo|1s;S#n^|{Nh6ipbxSDW>hb$ej^nBR}5Ghq2f;3;EJwWtt+^jd$zXZ9w+0+}7XFRY2{ZtM$9)^>lBB z&R?rx7CnF&V1x4ccWBF;4%~9GprSZ<&L=AvCm1fw-u|;KHLfl7Lm<`JnDRVFK^adW zr*1b=H1ZCuniu_dAF#|1Tk{f#HC$9adEIOKSy9HNeB!zgQWr3HWfqkEoX124;*i;P zUX%lh?6ww4BQGKh$)i%;YuocghTPh6U%0WHy&%%19lRCW8TESh4i4ko%n!ON z^AEeNu7{dI!*02p#+T_c+kdX*pEq7#V@6G$#f*lx^KEn;m$_-Z4OX7_alGyUmiY#h z&+5>;gO_Wd4f2@_lyBumlk>^#Aoc*aU;KVI3kp@PAw)R{mxy8y(Fb@>ZJ14vmCryH zaUpzPOXD>$PMj(XtlJS_1-gov_>U=7M=U0hmlEWVA)V5lKPF$Qoh{ys1U^VFZB zkrWN2-!vFK)}Hd|;-Nks!m!|Y&Ik0c@!|a)YX(tDrWpk?rv{5hdA67=8T9LN8;W}l z-1h*UPYPB03MjHUj%_~Rhp^Hr*T#+3pu#M=H}i4<+()j_4hyMg$vuG%7{efU<&(?H zTsAV#X8@HXA`9*(;roGYI>Qj6_Js+CED;QyYS4>ZK*U9pKxH<5N4s^4txORpUu|$7 zR^_w%pq$T;np6HES&Q-&p?rezN5`UK9Kc8c>$Wl>N{JmhIqsWt5XlfoTG!Ej)lS2e zGW^WNjV05V<;3e*5z*X_EUt>)fMJ}~22;WT#$~R2mX9)nms&v&#K&u42e}D`4SjN; zXYCiL$izkSJ2g*6eu8x<AVV|SI$|Px%*oI9bCGC3& z>nR!TmzGkO!hC)(5yiFBa75p}SLW_wtbsTSp-%fz_^6_H@S+nIm|w&JnX~d)jmbxw zLD+8N^P=(@>loVXl+Ohbhktf7rj*T;W>~##aKU^zSnFmpCYX_7es7KUJ!G=HrCO&@ zY9%w}(*o&FQJ!v4Q6A-CfY%08aNYvXuE{OkYJ?}_c=C7$L9+S?fZKPJS}03{-u|{aeKIhq*r9m0IeGh;s87>sR6WCVrY zU0BPx&CjAcTH#RJG)iRugxPi+V8vhy|J|3tJtsF>jfNXwyu7nLW@t&NZ5P@^>rnZ8Po@jPEGSf`vSo8z2U$|S z0!!PU^Yi>I(N^(V5^2^ji)I>Tn&b12U-_)s#fi$tKe+1dz z$Z*r~Dxcu}bpKC8D=nDO_6HLT#pe&#ooQXx!|3Dym7OR*hB4L+<En@j_dn^_^$K36oy&& zanI!NUqy_}iyRXBGG9W5k!0M*pEn%NJ?6$@57>PI}omIpo$lsO<^L@;Jb`9pUwva347zGVtEcf_1AY z#|&>}&ncK4oI06dJ<#ey3dtW#YAMO=YZIw1?y(c&<3j zw5EJ=Na72{z|O6qa6;hXw~v`7D($8rL#-{;zRX+s4EOeLl>5;4^E$L39xNta4r9E2 zSR8-ZAQ|Et>Y#Fax7{|&2`Yxa^W%0?Gwg=PmS(>WmVd5&M-I}S@|m;`)dSnh@F5iQ zlyjI%qY(LA7%lM+FMAp!KN~dx)aw1hVUZkm*j#_Gw*72g^4cupYDqZK{c{}0ANerE&}n=qjtV9+C< zD^STqPg#6_8!x;2*M}P3i_kG3OI?k3oyCw{i)*7>ANQo{cfk{Sm>?%&MP?e6(86)# z8s~lHc%H&D&K17zZVP+-7*iOfmR^)Ufq|CK!8{dQSl&hpi!yEv1`3s^`W+RH95YoiFi=ifPC-%TSzrg3fHNV_Lf#7KT5j&MJfVc|Yz9ChW>Mk2DITX?y`k^Ck|Jp6?N_`OXr-~{2Cg)b7}W9>g{T*PrhKM49`{MK69 zEZn1bvCLG7;QI=sV>=BzCivO&Rz8Cs}=+`|bCE>(0tPzugM20pSJuQjDs9KIO+V2ulF>A8mh;IG_3hEwdV-!JSRMjxwW}$YZ)2x zFMrQZ6`UgM)tx33RK9I{QyFMoj^unIjnVB1=f5$YJ$dl&Vra9Lw=m_fZ<(({>eU=uvMm><| z=m&rHyp>P(zJ1F`meV#7*9}xaXxYV)001BWNkl%l1JhF zJN%ls5#@L09!8cBAfbWQ-PgoD^8^0%NnU>HU;o<6U;XRr#C*EmODMB;ikD;j>*tz~ z+sei4F)w_E+Cee-u*9f*EJOrs$lE9hkrx(}Pn%)bEi>D01jd|$MW}p^Ud~?E(YS{4 z-g%Uv)PN~lGh~EJQGSwAIP%&DIpwQxZ!*K4qXuXo^mx1%Zb({vGY}`e9RKk5x*aSk zTHAA2pf}K#hnoD#kD%Z}cA3A&ttmmjUj*gT5>X0%Zu`&5?9I`u)mEW)+90Y;;ymzt z#!Cq)H%+o)C%MTmtQk&g=H@V4ntid6tgFL`3t9SIEYxuDil|i z5ZEFXYpE?-E zWM)wViRbepW~|Dm6$b}fSv(=XD5J$CVK8$iBn*Fw;lO!9{~_`!^XYqB$l|!X%=i6P zW?;`Jg_l1H##Ii=r=0x%ZQ5k#i?rY~uqJ#1?kU&JklW3cFD8%Apx^^~7$X-%MJXrc z(_z@{NoK4YL=Q*~Q|KjexAxc1iD%%NbR3S`*0@1J5*$NvjGyD>=|(D@SdOY|`wc$> z)(l)5L*PWXtn}n2%4xMP2rp*`pI^}o*og5aFo12ykT^xoZ(O$@nblfp<-CI^iun3% zVvTHbZEUa)X#d2u^$@Y1PEYtP>M6E-2(&{EXHFsDaEg2KiDs-MuCzh9&HNYsA;WMp zX_*f1pG<>zS_bea!B)-O7+_hfW6x(%4z7IiLhwkF*Fu1Kwg=I{uMM#B71o1e;hu8z zgtOuhy=(trhE>`nExav%C=4;}KWil!E1vl4}dJrdH`<7bk6!he+qg z4-M^oV^KaG9>{kxqbN>2v{Z)_VEl5I`k!rK230;3i@^)QOQ4N&q=UxE`WG+T7$pAa z|5;PdXAa6I6>hE;=eTPYuHm}ln@s2{<1sPfq_ zWUis5y#*sHE)vg##nORs)j=WiMj~!R9;XbebzCxqJUH%~{u;`YFo}?@g{vwQ(+tjA zdo#?he3eft$O$dvE048q;Zp5KYvLNiMxV!4&!(U*WdYPy*Vl2 z)3CM{;#rIGROs*7%=#I~0YeROJR^@o`Q(ju?~KDPaqxcFKPN~>l+S>~yC%Y{thD!&VT>imLSvN&{Ks%Aq~_8%%Oa9KDqwnwSEo{&Wzt&+o4exYcmJN=pTstt=I5u zyZxH)kGMvo5j*A;qM>-w%Os-bJ?=9f=04AeQ-^syF7o%aIT??~&^WlTylRQb(6-=V z0rwK(o224XJ#kAh0TFHJFo)r`FxcNUYs?PrCF?*c)~Rul@?7PuDb zVKF8!#AA2c5LzH#Fn0ps9Xp~fQZ6`fnoA`VAKQN@P7lb^x#<$;oquak^ zNby5hA)oMbydi1}tp?cQox2pP*n7>E9=Lhi!qGukXw4p3y?dB6B{YH*jK= zPlq9*`LW&h3h4>8B`bP1L^70n`RkGX`V%i#({m^FDN&)Uy{F$N?G@?)pW%P@asT>x zBK(fMno${^{KJnzF)X+g-vQYxpG8K>Cr5w)xls8jxW^mBeNIxI=hA|TmZj2YC&Su5 z9qTWppSaz4jAnJF68GZnWX7X>ChT^nW=67slM-2O-)SUUmZBN3^7%+O+~w!#s=OOg z`5aI|iv{Atbq6uo+J07iwllL}m1G6|Rwjl5HQ1h5)Zo@1{c02P{M_R3Y;Y%Yo#&C*XYr15|rqw;WjkHGr4f zQT2;_<_FV0FzHc@?D^i#%RfziCG139S$A)^*AbI+F^zhNL%$ThJQw9dG88UE=CUbq z)sGVvYG2y&(Y3{~?f#d7O2Ds%QqY)bZU^y7I5j&!KF_KrBxbb*;U@NIY`o6Pb;65;u`kgWyCxE$Ki-bKp(<0lY|Lwy{v* zWp_?;;OrOd)w@$|oVEFUs6c(0mCrUkpA-(c&fm-bWfl#wcwEE{?JN%G9I)+DFWD)X zJ+~xRdbgPr3i`mW>OG zj1g_$_2hzc)}GDlVrFLq-V@MJdbyXI)4D#sw!(D^Bg#Sq(IupK#ptp;+ipDjm@J#O zCCul^u3W(-t-|#Lc>bJf<+842-7}3Ogc=#xGP6J2#B3&t2Z!87Z`^@q5)WKCfG5Qr zOj--C?J*z)si1!{ly{Jyb$kDuH<}`gXGP`n{WQkg3_~GrQ?+1zm)gJmF|b%r`HYnH z!{vh~%BTCW$Zcx>ISb+WEZk9MTGm48{j4jUiKkPEf+h;7m$NQ`G5P+csA@GY_J}K* z2d}Mrfbx`+*QPG0+*|?%tT8K}iK5}hsyiFjZ7yS&#~Hh=eM~AkPa^N|+p-d-q)6UaJ(;pHN+79DP+r)k`Z#fx68MEQvW+QfVr*>%#_>27{|D}c70-OzZJffT6G{1;aN{8>p9jO3$mvWa zIVIi>sV?hA*%)%c{&H7$harG(Xg_*&d8i!MKfT}=YvH$LSAPC7TnLH@;NS#I7evU-uYU%kM+c8 zo1am?rM(Q&sB9>IC8Ap<89aw}6A^bgjR!pAVFcc~(ajsq?FvfW*>Nzq_QP&1O;QX2 zWmYUj^QZ_vD&_M|Vw2BlQUpOIfR)cd7As=A1?4l2c~w5^;0+WaA~Gt!lnPk6-R1rs zhpSITZC|Z5$JhF%ZBgY@F+Jei&esYr!JN1vK?akx74A0Rom*4wXEvR{x4Q>wAVLh@zqx!H9|qkGdET zb3hbCK~WSWiR|vo?7zZE)ss5h?mBm-&i9?Kdv<5KZ>3Ww{!Xvi*YKUG@jj3!qTcv) zTT=S=qzO|M)4ttT%nxMnRl_s8&r&(vm7Z@7XLV&~HBwepb7TLy0miRoPsqsUab}$C z!oeoP0a~EDu8Hu!ji$-KobU=XG-+ZGo}j#64D(;wAj_E}P+u^;F$}aU^68TC*{jCq z0`r8m;4cJ+gkIw_yG3JgcTCXYPOil z+Nb@B&JGLTFY7$Z&x3Hvev2QAGa}m#g9Ced**!4tVv~7-nFV_P7ixvq0=!ojmGDlMe7|cLQ?YTF+RD^=bKD5J}a#hqEuUq97Ubv*zEi* zR}N%l8ZNZ7z@E6&Bi5~-TK(TjBQ`z*DB|rqLl_Ca!|XQ_&L0+Pxk6!j(j@NuX-}`lBe6=SD@$58GR1hIV!8Obe}-h00B)x zZS_#+ZnS5K>lDBHWJ*U}>1UFi6!#Q;#C7bE*t<7A(@zXzeoSBzxG*}r>QKV-&3?IG zoSo@8D@~5j!;yMZ{XiUw@&|$$QV!i)32bE~;}fHvub^xo?++EDsc#LXNjA7zDn6S!dmHb{BvzR!N@1oScHP?KZ&}ovIm4w zZoftF%k`3&EOCFTzzxiQX@e|hR=nS8Q1Kq+U|1pK(CJcotT;C7!1z> zs*n#0al6K+MYP-IV`)v47@t{2h&yyu05nuu*+jA~-t$4u{2KQ9hQ572icDptIT)bW zLd?3?8mpiyOvqrAMrBtXsy1^##v zZt1`5U+|@+Cqbs%z8nt3`W5dDDNT48V>FP3Xz9Zsn2b+G`W(6DlRTE+htDoOR{Z|2 z(19;4ge|pUy0(8k7v`z7d{~HEG(Ke%CW88e&)qnMF)Yt1JqpqgtMOT><0OrO#3#dE zXLQ@~6?kcY&QM*bbtm}O>j+u9#;gX#cO2q%+S>D3ik*?^K1~@-r%x>MN!SrIFF#P) zf<{IzQHKh~#UuIIMJ7NB_&kK}dYeT++kQ6u?BDtCStZ7&K)elm2KQ_EeX==aip2LJ zt$sT*G2=5RS!tu)n>IpOZ;iYtf|q75N{^{DSz`F-FyG$?1Xv{p0+ODi{f8D>ptdy7yIX8PW2(TG+qozIlMSA2ro^E@XI~ z=b!gB2JbqH?H17y6M$yo|2=vNb)TqDG-7|XyH46Dmo;DPTbr`X_Fr<o=}35|K}; zvpA#=ovY;FaWnoZBGX~9c%{h_d%VJa_^#5LPefvV79ll{JXSI=KHUf9Uy3o+{M(#r zUU=Wj8jN1^!@l#WiQ6+iri#ds5>1s`JwLtz5OC-32J_w6ek#-}B4A$+bs`hVMr z^e5E$?|)uI4R# za0*5~8GS4K{8?C>^0jZPfqD%KqiB$6IuOKYd_J3=chs?3Lh|~I$%S(%MpVYLjTR4J zK2Kj+00cw}w`+XHb_`8wKUIy-N|o9rmT%DZq&Yn8afkAK((N5EyGr&1{ey|hmUu1= zGFTIF7R)tcjh^PnC*wmLYbJ%E(1SkXJ$F~JpL9h%^B}^-o^NeXcS2{vym5h1ZJ`d^ zHkT$xL+d3s62ssmgOS(O5NzVoo|nM*wdhrBd|EFL?IeuPwDB;<`!h<~tl%?*S2Qq2 z1C^;XJn1vY`WcOY@r=(vq+q~UOB>oK*sVLqs4+gVA#!{@QJ04<4|zuRNE8*4*zx!m{YzTzlU7=F$}1-h|)uv|4GjmB5#UN{1UGY<1;k{2UO(dd4#lBsZv*n>njma`Zytf zH&0mx_tnF>&5%{_0#dqGL+gh@$%=LBHK&2YptR1o7-K{Yjhgn1&)j*kGa!RvD=ZCn zOrs1p1V7YAEV~w_YSR3 zvoD>UR*3;-u4w|&RPv^mOQA@Ib_T5OAFZ1FZ%xES(4U)#uo-KA#8)r^+@au|9wYKe z#^+~Mc%Ha+=AV9CyFeX=0^^e+0B?tLs>dP0ygH1}94zHvQzM_1x_~h1Q!uV`y4Q&<~e>viH7*veNnc zxVhi8sy3n)!i$!oTq@GA<)Of+4|?&&NxQ|%M!Y zJ{fT62)GpV7@y=Rb_bX$BP(@uVuu6wcRAggim{SMq#G{YMzX5lp7)B7ra!IYmGr@~PJN+z2xBZGi2t zu9dXgWW?c}_yBUAl-8f+8R9IeaJKfMXC9_=L~eY3ctY7>=;R5XdozQ;P^*DZmZURv zHq3{Hvor_$IlO=5WIzoqslx*Uj_)tyv_l0oZ>x#e(0D`I6RM(Ia*sT~ zjH`HCs%3mbs`XJZR`garV(js?MV5^8rznsUi}9q4&mMd(f+Cb>DCiaAMFkc!J=7rV~jn7_MJGZ`-$hC~#TX!sc zSLv)N-V|{Q&Rn0J3=PRdvQJ%EU&TB@M=>o8xtHlZt$jq45Hd zK2g&6oPpx^S>B@DQzlQ?kU-=3wRF~2vrdv5 zB>g~9+8EdFH6Y8|0kYw8wVgcw!|?r6dJkh;6EExRmip!}?$K&p<=O2u=fUT;U6Y8;_II1r=G@88()-e0Dz1ZWo`Uh& z09u#p@9|l3!01(ZV*3NGG!Stew!GnXo~CGlQuqONWIsb3SV5x(CF*6 z)!bZ7kHghQ{q=pSqFkb&-+IM++~&8Oc6+FTv~y$x-1?Sj8ytze|)iI5JXVQ*C9vr=~`uk*z066ruJf1Z|Ryl*ywY@33C>ab3?CCA2UBCf@KF74SQYYOtjjZdn@*v2y|l%?|4CAv~5?%!gpLsMyVVo%H= z0K%gq-7ptcSNmt%(~Mi3PVo5-fOIsB)nVOpGCr*3iz%z4Wl{ARtk5v zC5(l!m#9<3nTC&rc~PKeOupt5Jd$oF|9Vl{1g>N%-6jz5pEVMaz0!1vqk&I@&8H*X z5CvA+r~mfPb<4C*+DNTzo(g-f{J~GaHsSpj=^V5H4?hmc)H&<48lU()XT*pnW_658 zdX3M(h=_dO$-tmjs?-8;+MeiR=d`q>Sc);bMuH&z&2Vbq>eWrq*_G~s*QmKS`#Bn8 zZU#~rpK97rp!0k16odDUEg7kD9Q90Vfmjji$GQWvmO9OeFsE&=Gde9kM(1iZ8lP$G z4~F%dEnfOHHRIE|olW^P7@11;N;*8HmG0F@?1_1zLE)sh&s)nKrT%(0*fsY)OoudrYoOm*fT%+nDrW;b4e+VHE4HHvqvgb>L&{g z?QH};xdI}e8c;!(K3}~?^wW+1_6g5h87x&=4SGqAQjA7dkgMx~(Mf#{%#kh(fUH)x zc`_Jc2%I-BhpG&<=+dI4Id?kJESq8xs zS6eze>MFLm)vUF<001BWNklO3M)GZub(cp)bC3l!XbLO&rGcV+;~c&X5*93 zKytv?Dl01~Bt~-FU&yvON)s%9mgb)=*TpC2UBSjDr$|df6AiAMQv`Gu z|Nc^#FP+9`dVjDP8yO$FL&W)cG2AtnrBsliJx6+u|H&fL;}D)*>+T%Cr_F4Ilp-wa zRBvlm>pjN$_N_f{fOTB)#wRM?4^11Q^(!=}$R~Mk^?)l;O_ck!f4|kpNOf(JOo_4XeWEQ>>HQ#i^%$R)&H&auuf9vW zl78Yk@tYb%%goUnHKpH*XQ5ib6B)5rLGAq{2z#lcam8{EjLi7Db(A$Wruhd)?KAz) z&+)&1wup$8UcZIpBxb`LOye7sa+F(6xh)Sg1X(b_8R>Qh<9IxWHKOdNIeQ^|S9|w; zUi!w;Z}Ql2B~DreOrZOm)}4^<%q+iXwcQfe*aSa5H2r`vPRhDlk6LV{EJO zSxGrbr&X`HtKYMKrnAZbgBlD_fuc@^=Xb=jkDtb`kvPh^j+Flt+1<|cVo&FQP<)b~ zlk-h-cJ<#?vgKCkHC$*-A&ba8nOX~uK3CXo>}H-fz}U<0U2M%3>L%%)9@AN!@A=QC z?`ieEpG)m&;`#r8S#2#=Byl#uHl8nr`6=zpk%;6i8=n@Czmmu62>6mx{blAv6eWSI zpx33+^ofPeJxJ-cMGt~xJP;S9!|KKZm60jN>2oz07{d5;+dvvkd+R&eJPA)|^Wyk? zDw-i@+^+FSQE~S~NWastH#VC*`VYpZtHx&~eS}#XEN6ExQAws$#Z3$B>*=#4r)GK{ z>wf3?T4tphp1dYlZ)Q^0gV<6dAlP1*&k?LwN|y|Cv=LYso@yM_az9}S%OPXcd?Lbe zFALUeDhr%NsjK+?`3!_H7wNm~xMiPwt(&lFrzmlyw~;=bR$rv+c;I zZ7{_meCYe>1n!f#odw)>&t>C`+a36C#}1=JsMEYPneOPzL0|tzkttpUsxQhT^*5S^tKSD8j3esHQyf8KT6e?AhVheIXdt zl8(_6*0znc4dn*Rs8>PY-Oj95)GI9%1wq^!p|;`5zBMY$=$&>gMLwyI)jjA8l#k}& zTwmt-CT3hvrM3ur+x43LAWB@`5X-r303FF4|NFm34xlyd8KjGt}AceTZAe7=OV8Bk#N&`PojdvW?=`t0 zAtG7|vN~FqlWq>~sk_sBj53#&+Ke4bV0&eq)Lg0-pQ+*2DC6%PbX0I{YrE%=gH7Sw z%Ph>*NK)3=<_9o0<&95XqkTp`JBtrE@>YJpf0>APV{pd2^&cCC_HJjKm4+uyyVY!b z{>2~Ity(cKlHlImzrS3EK}CiA0d{*gqbKr-Xn!~Kd`TbDp$2Z-_~e=|>keZ@b*hn> ze#SIGR6Ooa&snKbS4g(<2vNqA1{zTAA6oF6G~yyo}8V)o*ZWHN;J|3nKn{xE$tf& zKAa9?ZPO5%gQ#(M|5Je=Jl3Oknq=CsbzczYv-H^suK@#P@3B(W7a4HiaG?G{2dc~< zaiTxD>b)Qu2n*}2yH12yw~G3Bu^{}R!Dip%MLsdbBpBLP@SZF>PRs=G#;4m2o==1E zDU`+L0xH_kL|Ayks$5%<|KB2qGK1GFFL17+rTwM>;Nl_YdDTM0(w4mC0j zxBasw(@ODs9syYn-A%V;S+&-19oen?&!>RgSZF>=-*wZGnWGw?S@hW5r!PCIBsw#s z+&XUz2UO-30DCYkIqjYON$+bP=K%0s+&c`R+^%}#6ZI8|zf=0`;9kE&+iABlweqUI zFP!Efk`w(}H~_0R|62pGk#SAWh=8ZX$UtS`dztrq^s%DHsT!Zl&lM_);q^y->!ER*rSG_DupH+-%_zpF?3>wZ z-VUFI;Ftx+1-(73`-CCq%~*O+zY+9xPA_gP8!V65T5sT@!P~Vn*CrumL)v4XNpt1O z8=py5{LAwVAu8UI4$7&O0a6^A2Nyv3O#QX6*#AlGLi$!3iCCe%mfv*e7Ea0T=NSc4v@ss~=pmv^P^6Q=wn07NvPLf^a3iSvc!IpY{l3^0^rY;aVe!ri@d z#72Wevfb5$`qcyqm&Q7O{HuXw^afk!40n&p%oi)bU`iw6b8EtbOdHX|bndXd%Dp)1 z*(UOIOrJ+R@;v{38_Hf=&6G!+kB40oDq6@K_VD3vhfKWtuAzTqw&p-VL6wXGStUsSo(AOb&vj zVO$|-baOMV&dhog>V4le*h>^2Z)-! z5{C*8bQt8W73o$1abK|DdHx+723^Ldjm>!3Fc_6s;NHmd-~0AtDb{Ix2I{%>p!C=U z(of5>g>)#}e2L)OTN}4bOLD0AeN4zsiGn*$R0f#P$7SoEPergNQWPjvr?p{Ls#Kh0 zG|!TJKG3ArQz&!fnHlnI;T;muJX56AHr)aklJ)l}k9zLiW`569MQzfi&eHh2fx%v< z1J5zESV{8s1q(!xOWbj3|E6_5llH+l89wRn@m_y4r1Q4iO2#E;5o2~d!l2VXYRucZs@vYcrq#} z&dc>Yp9+q*S;MWmR!eQ?Qg=dlO~z-h8BT$gkvTL9veq<(#uN>cxW31jaZ_${bXy2E zK-4pz!#36eqwxPQv4?04G)2nwZP;fTjL-NQO3_-5e6pwG+3+PBTMn@g%IJkW-Lzp$ zR2rX>f{TaYd)YdbXFQajrb9cf*DsAXq!^#0q`p}gsplpx^7)DIbFx0ovb*IjgQvRI?9=N-i*mjJ@HwP%>3S@F|#<>{P_(WNI zZO?xMgAecKQukbVMaSeb%{VFJTu!nc&e*%)dpNbdt#!c9O>=jQX+w8gDa1XG!~5g= z)}R!lTn#$NR;D$b13fxPae7t!66-b=5Lg_ou+U}&jh;&7C>;W&#-~F8b{r@s{OP~)(oplnPAJTN) z3_LTWQGwBEUC1_gisvm20ba-&xGEnjts;_jpzMfwjX3{OS(dU${*1EW5`WIHya!8< zN{?`PLV07Ov5YtcPcn>3xe?MOS9`QmGR}=KK8H!WrD)Ux4BpG-qscOYcmUlEqwJ^T zd|3}?;XXWPSr$%P&y2V(SDDaLy|z?j!eCEYkI$N1rj=n%kN%ly6$PB&qvPv42sot7 zATbT*O$O^P>V_;!Jup5~dgTvbt&|v_v`>#Ck5OA`x7Hh<36{PZpNkP0Lv9-rkdV{a zEmbcrSva!XOTdve*?JO=%CK;@&At5V3C2=-U%$M=etTe~!q1^^YOnc-=X)FK(TBz@ zrrC8sNv>3B62#|W4WEzZ@gmy+&l@YwoN7BmXRp`X!%(ec(~UEg)tl4%SBWt#W_+)9 zX5-Vk8w^#qmi7k9^|wHVN}1BMoYC;~xOM~QT9;DYCrPqyS529ln*sggWWzG2rNMIK^Ud&OC5%r|r{$h&u)d>GS;{ZEZ|FD- z#F%n&91GBKj87+1YtE(AnzCb5Y|fvD=k&q;{kEi3X9jHr6slAyl2n2?4fjqaD9+rs zlj}fjR=XDXF@1kqdPK_;XIZQh&aR{Ap3sB9s*f`~5r4lA12}}nK$`y_!slqvfv_y& zk7m?}lx;AAj%VqsX}-{b)24wvFN%6cgC!)D5@mAD{RjderS}^4kv-8+JGV9*bv=>Z z8W0=t%ceiTIUyh(VR}H%>ApynbCok|f|#>3dltqi%V2 z%+wjik!LBj`Bwh#01rh)N;9{b<2z@FJ%wrO?QYw1Qpqf>Xu6o)l3JNel$cE-~_L}&R}XSMm{T5 z8iiP~1i9#7Z^bO9b^J5Eb{D(~TcgC*Pjsd}5oJJ%cw$Ow=!N(Q`2Y2$E9vXpPk0?T zsJ8R3r^2}M2ygK_SuM{(CR4z2xP}?D<`W~$X$=l0kRKg$Jp<44O@nO-2R*-Z?*MwV zZC<#*{oQVzXWr&#A5(Sw`NU49E&TeN&3m`#K0|P}_n218A!V^|ulZd3k}{DkEJ6;R z${U+e^4BZ1Px<~hwrEZ8Ja%{}-k5p6MXSn~?`k4G@4-QG3Cvqb<5L2`zA>GL zw#p%~NqO3YC&6YZp>X2_2e6H8(;%zyS)6)8NLcVD>k+;i;X*mm-~~PISlQ4%9lk?> z@d*und+sJioAF5(ncK=UDn%uupWHaU*ZgFpbfij^xz z00;AXKb2eypNL%V6Z zL!tV`#Rv<~W3M@vQs?t$pZ0v=_aA1^Q&(k4rIkQvSmm{7$oqNzu>beJaWsS4`D~iU zmR|Gw-n#GlSCBQLy-(MuKh3x+GGKnHZHRcDWn>S}8u1*KF?tjX_^k)p59q*1`oN>% z?@K#YCF4E!AtN2<{lr-S+{?Dtyf*%Aj;7l7on*j%BoOR@1|#e(4OXHv{;F8CC!*5D*W-=!x>hPnnF7-E`h;FdPR3^vo)bvBb)SI( z{IZvg%^Wj#p=Z=YoVFjDcVC>I)s^V?IY%gjN#WifQjIEVcBSqUBOzln5C82^{{46Q z&cY1HX-EH)u&OC@}bz310!3QDt7uuB59w0Yj{~&<^RO7Qe$;hW|dXToI zMF7KP9Qq?RNx+UjUOfCy>oYz})-VEqj=Qr_8TmwKQM_1=p-X!DDI+{rz2-vC+nEYn zR;la628l$c3_m~6zy3h%e>5OjVX*_BKVgWvjhv?2Jd10@TB@C9qdBDjTGt*YeWsg0 zUK|9#zUwK~HaS=~iuJ69=djF%+P4`Uc_8Bx_2cireWn1-ofspE-!+_SE^Aa}$yDIG z_<#E~{4MA;)HbH=XOoEYVg5e}&xH6P(>YUJBa4XL&C}ETMOj?h_{8tOjlr%Gtq?=3 zU)LmsZ8La5rzjY*RJm8f0jkjo4V0(d_8>Z~!T6MW=1>r9jq&!l}aI< z6Bj2KpXwr?3`&(!|H88-1$erGQ|^h6(_Gbyu2PpNm%)K=?)UVU)7^>D7$^_GI>1rR zoiuD@Dz0trH}4rnrM%21Pl;`xgQ32r6X&0w8Rs~l+H#F&*?VXuFdAy#HquaAilQ?k z>J>Zq-~AIf0ZO;Mkc@S#XU|J7mv!Jtr+KXa7MgT>9?Z1BUfUt4wWC2taLuAvn6N}B z$;DSg$;8G9tk2+_*OlMAW#f}JXb^T6(x#s30JG5ii&`@zDz!r#)j9;$NQ?0~19h2C zCE$&5iTmP(_b0#sM6|EzUHnOr+|1{~{ZIgmw6Lfxlk^f>_q}YNOrvIjQVMCU9%E3L zSE|%C>bX86ilUERDQW%%`+mmA5}9@YXy)K7Z6^6@Lk($jJ%h^QIL2IVa9$S>ymxJl zZRDH!XS}9iBV(=U2^3(BMCsJ=HK6_f8stA__f*4ktowoPQ4#rEW-p}v%;9w}Fx+&l z0jJDfWRm_K_RbchC#19XDF1uEg1wZ^G@bJajD=;;{B&EaVb*#EOB2hg@czGH?n>7f z;~op;R5viKW|HA$64BJW@oBR!oEE3(PBJ7OONHK*bP#)E9|r=atT%>*9PF8xqR@`< znZ^sfE1SEE12_j@I@1sY@EviC8{qvjjP#6aBv$b53zzjwOA7JeG9>Md0H?ooXMs{G zt!`rDY^{i1gnIAP>LK0HQYo2m+8p-g6Zi6{GAJpZ*b3!K1frAIp^nZL`y#tP`k!Cn zUvJ9uNhz(mYFKlFJSgbj&J9nhpDTOkcAG`o?SSpKSnqj?z(P^94o;kZcSpnfJQy$s z#&ldpxSq7Uz~?~S1*7%PaCpA69+>I)$4cFL&* zdF1nY9@wze*&zLOxq~KXndykPcv;sxpHCoUigj;xsaWd@NVXW0|>wKG{YGR zdJU>P{q{Jxe5TQlF0U`?H7}(#>{88FrAl0nhIRJg{eRIO57-EJKTqDVGuQVW_b?Ka zZ4{#DX?*=Md~VwShjLCrlsFi<|KVS^A{lDqGptKxM+N06uCYaATXzIJ_XaT*MFvl2 znY$^-n#jcn(esl*@K*TS(ov{|_Bk3Shxok{vJ?K(^H1ZyarT0Uc23ZV!H#)+rZXZA z2Z13e)myZXOq;gNkNfs*sr`jI_D@Xf4g~Aa_$&)J#NWBMsm7-+;!XENSflchPwGDu z-n*w0P(vGJrFT9evz-bDaDx!A?WDMIUFVz_lbm1w-420sMpyc#L6~}*q8dB+_ZRf- zmq{p6_<0xw4}A?e^+@x4RjMS3>$cDk31{d;0{`hzt^M4D&Qc${T$!}Z7g!FBs7O-X zSCb;2Js20(tG2}qzJy~5^7|bB{>}b90%u^V+d3N4w6i4$Q8m8a(WE*)xwe{&o$fM6 zkWPU6ed)Ut9TaK5euZnR6^tck+#jJ&@0H@;F(toEeP#LQuyhZH=ea4>2-c|Q^27m# zZM{7BbDGcMHO9E-PXSq(BPx$KU;-QpO-=tbLG-I7IBSn^+jfguD~(NTe2QLI#nXVm zD--w3(^{+f41|hFxS*0DwUz(;Z;9{D)5HctAj}mCRxqF?f@tYtsnx-22)(Wg0(@R$ z^yUtp&l7XD8OGPf-jQD1Swqe%_aIOpYpbS8-Jsq)Lnyr7&hsBcTB>Y`FiqJjzb`~x z_keRgTI!W;q>=^3XX{FRzww4GXQb>nB|0qw5DLqCa5lQ>ffV8QMpRPjvtF`K@=9e) z13lWvI_f3YrGdMjS`f}E(0ls#`R44IQc2V_jZX0#Sd7cPkTY zvEn^Gos6u1Hp>QRZNNzY?rq8mJxC*JF7|vQQ=8E0BHkld1F0Yt2)x_rLV18`J6bO5 zuK4|{VV|O)-vm5kxV?eoSwN1SjcAm~z}yJYO<`!d&HO$pAmMv+3Ug z%d+hiRv- z1;%G)0Pklek*dvx6xUluCyo1*Nogfm%+CfXvR&kT&OyNpAR@u5^kUC<5Sa)pjJjfY zBK78_4_?c^enX5qkK_#F-Q(XyuNZJ#jwWwJB z!pPo%LyxzSI>)C3c+zCYV5L)#@B&b=LfH~}rXKG3#zr~>0@;>jO72wL!^j%X?irq? z_vavtPMl+m9l-dsDL%zt?=z|Nh7P>l>j)H9Yf;{QE6U7X2Va zbVxKn2><{f07*naR86O&cUd%tVBcTjUoVU6$4ciWlOn`<{c8@{E`Oe-zoE}@uOR4r ztYNQINjp)htpmB@o=MIuEGZZ)rGK)V*Q1Aj`wvkMKf;))b%bBOOT^QZs+wD4SvD5p6-22vZBi+rNv z_aL1}x5arO!!vgP*Rq$v32VR8>zlzIDhqH$pq|iCqD@?tNIHy9L{$1^1Pf`~%UEeV zV&ii^A#h3yV)+dF8$?>2>^$IHa5@(E3=1&Sd-&H|_}5#++NhK|yJhtBbM59rybgFR z3GJ1D(kdgz{Qf2;DV_gVK+w&a1RRu%()5aoO-gIdqsS+jUFcR-KOctVCjCE9?;o0blZ9$aKy9!81L1 zkSaz*493oSBMnB0uxiD7j{L2KzX3y22& z@rwT!Ujt(0QHC52nIc!^MkW1}rP{_~Jb5dl9d0j@xx+_4*Tdhw4?a(W zVvp(jT;m%5J<6Z^XKAuyt$oAyLy}#mi^!VBbr(!%!a^~Q^YaD&`X>NLnW5h;{=6BZ zgX3dxUoUQa=FWll_x=59=G^hX&Iat|Df?88cTQFtar>XG{W+Rv3#ZY8+b0+}86${QE;a|EK4dnAo$-y}-Xd%+Ke;{p&vd=WT?6zs4{^T;TnAdcI?gzRAZ*s{Y68GjI$x#t8{S73d)~EuAXpv7CtheM3psx&q+;6gG!b1!`<#yuML&W%h3sp=l( zDa>nA3ZF~$uMvdB$y(TT@H=&lD|L^!mKzPP`zOUN$}p{|iVMixn05)7O3nQY)xi&; zbW*ypI~+ijH1v&L=zc+?E7YOyKDOt7p<2%zY_0T|7oLX{F_d+a-!KWm92^M}JjoqN zvJgyqml>1l420{&d%gfu2iW~ zB~8RB=Afv%{lpzRlgTsvETTy6{bW!L6Y=2M?-#-6Y*HEVC8IFvM7PR-hen}1>iKm; zx{sO&;X-Q-_bm1wbzd-?ak5U-s^Oa6T_0E$rrpN(uQJO=J~4eXlo?&7#MwUmIZHLX z&~5|&-F?Y$M+)xaS+kEuCpt@U&m9BvU)~{S8%(eMykW4-HV3ZC`1}qmKs7!!5nndj zB(IkOVH}kefTOn6_^ec^l0ssXXH?EZs^UMhd#^i&Co-lW{@h69??DL_E%frIdOU@5 z;Lz|2ciqj*xc$d@u5JtKj^Ckh?0q$!$@n-yv>L;ng#8iS$H3TT6z%J|)XK zD&y0Aod#J+5AlT)UjLxP6Ub?|HuT)AX}6UsRZ>KxoP#oJ1F%-8m5g$0qmX0WQEc-R z(W^c0KD6v5L&d#F^taSF2eXi77|n&`cDJHS$@hQYB49 zGLz7mzXOUnrZ8$WJO)uruqSW$`N5=^3_dStsJtY7hFT<11l;(mf87ac+eW)%cpn5K z_M$Y8stmOJZbhd+8vn2SxUUH*Fz7Gi~MEu<#?Z<1G7JEuay7+*2z zHP13w|26pBprLXwe1@hJ&G~nXZQ6)@BFIuggtbm_)H8D~U**S~P;D18Jo7bGXne-! zK;8BrSjQ!dPY11l+*9ChG_?X6cOLL{7UpD=>DT3K%s@O)lnksjqomhY8jKkIo68W& zpB;fo;O+!qc`dgxxOZdgEihpWb?Mv}tFx^KfCDO(V2so&hW{%3@Juf}JkN|nkH z%gXg&tUQ2amP2DklOj6`%ap8V8%)U?lrS1>V{}Dx`Y9TSzx4OaR%VpQ57kIUrArAn2?A*_Ys6w90V_x}U~1^_%%M)-zdjM^d+ zEY^e#o|4rgPyc~JmTR0ByyJdkC~`TZBAx>cz21<%Q+#am*EPP9Q~5mq?Av5_|I%x! z*Z8zfrrkb{)@0#vr2n(9UdcJKX)4b-&{$|rrH+2INoOha4nEZL@t(iw$N9DR+G{@P z-@n_hZD=zSQr+(k;5Ho5WW-`ludR{J$rA?u0&tsc{*|A_g0g^vOW&GYI~^W;sA;$m zQZ1_SS&0cz&XS-yId61mPge3{$FBv#I)MAWMEX9E@kJ& zVMd{ba|4+z0jt2V!?5MSgHaJZA%CUKJ?(*3<5Mq5VP+ddY}6I`tj1@hN|j0xD}C4_ z@IxSQIhl z+p_Tb1%uJ-K@D#0#%ECKQ%8j-ELrmz4ee$f7-_Eqy;OxkZqz|DrwCIY4S% zC->qTZeK8X&07_ZRqoL+=Gz)+d=9s!I*m`R`Ft>qZNYJ9Ha=;6!s|&!My6}zvU`;F z8tT=jrgaTYlH#Qqa9*M<_;@ohn@pw(^_rhk!RvGf%dJ+b@u`n2AaW%m^aG+XxB?;U zzB{>`^h%W~Ra$~LD+Ey?Z|&dz8)OuqN)}fp+EPfuE4GUH0^JM4B4MJTVx4Z|Q>NYa zFg0%Py_!u>rx-%HOtj6+wy@i_}R=Isq4j4n71)yAi+U42xxPL;YxmK<6E zN&7+pzNTTH;rly)aolp7l|Y>T9p3+Ulqz5qI(W$h5 z2ldics#K{`8$@k1pb57PhDyVkAuGl3v{~=R%RTSHV;{B-5|w-RqV##{&_p-$bH#Cg z&Gdu=cHq512J1dFkJ=*Pc{+FiJlU1jb+~h&+xUz~(;<@M*J3GUTEFobp64q6dJ7|E zPo?frln-$Y_k;CSfO0GMS#yQw9Y>M}gH3=$yb4giFbUHfET?dO44$VNpPI;K#%HQ! zDvtn%d-N3Wz}LuU*Qh7ft@aVC)HSkz5@{V8Qy+pazwNYYtrVYLP9ZX`KD7Ro-V%{~ERyP_ywVL9)7Sd~)B}UUQAA z^K_VU6zu<`bEp9YJDiu~Z2WiXf-+g-6Z4LL2nV!G+HL9~StFm?2x}ygqV-{3v!aIt z>v2x0X}29Cf_9Jn#4tLL-q+}Lr7jSsRIUfZ^RYrM>5FiU#&QghZtFg1lFq;_8HObW z9C{LbrWS<9oY}$pB{Qs3JUJ$?oXKT(mLA5oIr#JK$S@nlp`g|H%u#&zF-z8bW+}(7 zgTF7W>i`oL%U?|BtE=7kBpJB~`tE9u*rE(gM(CHsJ}Y}>tUN2t@BJEGV{*E+6$pLS zeI6{{X&*K;K2J{1QH@VkWSvkL9C!l>4XYGm&F86^K&zyi_#zVh#GLFc7WUbi>P)Dl zn({rov*%0tT2N_Gyhr8vhG%NCC2%4}R2~@-_(AZwnhX^&ewQ1c!#KqmMLQJ^YOl0P3t^xj`U1Yvcb@Z_yC|y}C?{p1rM~hd=g}HI$SIn}tmHDg_B95){Z0mrj6( zC{^=$vXPg1B|XHbeV8Ip+W6cADQ=%J=&)EVf~%`!`wdSQTI3w<*X}(3J~YOLI+iRY zMb`yesZ!pUJ@9w??lCP&_b4ol&HzSpHN5{dd%?$uddB&q79IzJ!9ELyQ0cMfOh$({ z%!V;O^XS-oKn zoQ%({vJ$EJjE3mS&tzlArLKDLlyZyr*gIgoCeUUjO@cr&b)SX4R@3$LuxII8Mhfmq zdMJ9bqL6ucTC-?;mOCg|S7qI?P(QT3?it0z7YwADxNZFV@5376x(1Zc9$iv36}OT$ z;%GfO<1A$DV7-n8C3QUIBffXCJw-^rx)F?f9Yr`spF>o<4ip}LZSy9hf?qVlWMt*e zGwk<@;6*x^>LBAYo#T0HGfpa`e&aK|21m-x&2j)LmK^N|L&UnQuEVU)`0P237PC>g zi+}IsVso_TFZ)`8_!?&^BSDZ@Adz8sOLL)zNVRPh^|cMb1olVAfk;L z_Sl>#yX4ybiI7Y)u+2M65=_%hGnj!(=!fhXsZlId6l2*;a8G(PpF-P&eO=t1u`!zf`E(+k~}p3gF<SWg?WLF1;NdV*18sdi{-GkgZnSW?Kn_ z#;0{JgS9H{4Mbz*Gh9v^K=4YXcVkj|V+O`I{QJFxM-@EMD?BBq zl1|EdVuwi4StN_ns{-X=WJZKT2}1Kiao*5D-NHOl&*)o=c~drbP!E~p)Z58PKL}Y$ z9o#cT#4{OJo-M608Z!r&rRpFDTT}hUr)@4VsXlvYt4@~o=1`tb+@i{+2`FMjt zq%_w-CI%gG6J%1(!1K?fe~bFtMuScny7S}s0zlV;#dnOC=C6%Vjs{!Dx^tDC7fesT zz=Sp{)-8Qj#-0c|Y|Sg+0j6tMq{AKF{{o7XSI$OTDa6Xh6JV`M3S_Am99tuwiU|!x z+n_i3QE)lssGt^@_ZHWkTNhdYTrW%USq*g|mGltqGfRr;2gF^8GO4uUFd{oNMp&-e z=A{B?u3hCXg4#rxu!l%h);53gj(LX}ChZnml~@O8zFN>yVO&;3J#F(&(?*|c?Z#(% z^~R^$nLtz)Uq5sn+(GE38pfi-`0TlU!}C$}jF_UFpX>g)gDjEk|5Nr;jyDsKwNo(4 ziaWpSgr!8*?P)kFuR#XN8t{g|qb9n?Frr|aXTle6oN|2v)*k%XKf{i2F-^$Yt~3&{ zpm~fybu4pOEbP(bW&0!;B-QxTM*ZGV>-O-km%%zNcBu=n69W7QYyNlt`a<{|Z1qs< zK`Tw32s8ugJgs{O$e~#?zgVKYB|KA=rceFGXA};_E>!82ev=tgF{m_M!gI{V;+Z60(6+iX+?jZ(^&?Fq!P_1~SN^MiRgi+ZFh|HIoTp28{IE*Jt!z;F~`UORIQ3-E< zJ~5JdE4cqPc>Nc?W77L~f_xd!_{1K@UUAOmRs(0?SXi=x&cSikRI%~tFt{f~J|H$8&?Mq+#g8%&67>=&47w=1tzS2q|+{cz2949ZZkIO3!?!{%QfuG|NkV8JV;8N(nj}l)wSAx%w;G?Ch!4#j zXm1p&W08$;n^)J!r!qp%a*CAiU_vc-TDx&%i>wQqqtvma7+mQ21tvr0bZaUgQKgZI zfU*cYCLpt-F`~;*8vV|dW4X|edHZF-SX!A|k=AJa_oj2KYfdeec0{H6P&0^w6CD-l zKC+^YR)b;*aub1uLW{D7d%TaorkagUymx--$GhdSB^sD{m+JCPP*j&!*7%flm!VA( zIg}?>_dW;phv+=;<96FkMMh16dQ>J9=I?1RMlJQ=DI+4y_c!SbOuUqdFN0h8FTYwm z%yb8yLeLL4y=r`_BlhUt$rLv}vwECY6Dnh+@-)9DT-Te`O+i>M~AAS?gv+xyVAjE2qnajnAyr)OXYV zChUz#tu@wwZUi}TIGnHUWjIM^W~}#&=`ku_-RExr{kFy8ngsj5LDex!!djyt% zy*p+rfl8}~Fy)k^SZ{&|yS6l`an8Q$#+OH9j-2 zp)YtlU`V5ko9kuM z8+fIGi6dEe27>|xLy5y8JhXMmstl=%KW$*JMy=I^(TG8@l$$M0vTmTC%TgWI>PkLcCh_qY7q&>T7G z;C!wbEbSIc4XzjEkEV!j8V}C#4-99hw6vz0jZcSxjbMCkIZ!PdM?N1fKBM$_${3%$ zc~0eHsn#<+&!p$2A1C6jri-{RtV4(X#wo+JyhDTMIK75Q_FmJQU-ozgkHXL3A*Oj5 zNJ0O4QzKdWh-)B1Z#EeLD0NVE~f2j*)wy(2z!)iJF=nK_~gCyV+NvI*7!sx<#jz@2J2aRJkvKmDMId` zWtux4o?+UxiV_g#3$5?pNfQAf#^-*Qn8VV03K`ckfeqmuIQfZbZJp*>z*bD@44!GYZ*=)Nk}`y!2|&!2Fh0=% znqH5DzuP#WXB%}q{?%RO`DWx~X^S))p9K2kP6nsa@?bUTT;SRGu_@o%9OpE=PTBY* znRplkh|noBeNfW04!=qD_|s?w(h_m4XLvmm#-v5&$t;hTiH-r&m>AJG);34ML7lEu zZZVSOoZ*8%g~3-Eh*FAF*eju@;uWU-zD~pJ6{#3Jfi9Fv(?mJfGDkSWBj6 zb2|xcG4LJ#jN2HQUO5O+Enscmvf_wqn(z*k4wTtK4wOlp2YD{fHI#xlWhach-)(cc z(bGp!+%bK|=W^}5Fs(nyiQ}Q}TuWp_Mm>K%ku_Ise3D{)vKcf>O5P8>=JW9Pg^@`e z8=uxq-uO&=8o%d3JfEWF*>vXsu_Mm$&v5PJEbK_jl@M`HGB03ZY~cATo*5w>^})Em z1!ad#XJRt%#+%?lrtP)EgLSs&Yg8pq8FAz@8J}f@j}(40U;rOvYT9iXVkHu589vYl zi(Xo=%4Z0#DD+R{78(OMxHu|?sdei?Uh3xLwP!DXm8T06*B^#G96s=Je_k z$D~}|Jrl;D#W59_(V)ZqX9v`aS|d(3I$R)GO>=VaVEr>i*E-rrcBN8od|oMxixLNj zJ-N2Izv){3|4JZAw(tCGd@$*66m zoOsSqdHyi$nH5&&>ExKcZKT0n!YM(@m^)EK2}{pYKO=D2eQA#@KI#?=JZF&}*-xttWR*Ui36Oqs5BG{6+XX`^i-zlGVo3aEh^y3(;Wz5j) zI1kzO-u}B#Zpd`oa>l21-uQIani@dbxRm4^0yce0>`4vh16r)a{f&4#Q+7x)+TGLO zL1qf%bc4Wldr&%GB^|_3E-&<&v*1!Lb-{o#75C|$aHy;CIZf(G1ia=3eqUSy>j4*} z3cpAr9dJMeCo!&ShVq8>y(^(bTFj-h+zt|adkBTH#@yZhh0%xG$}BHQX% zcQ0_HwVNr_72~rv#Ml|(Kcq@tCFZisIIPr>n>)6i9?2O#xR#F*b0^DaO3eYBCwGp2 z#%pyZ^2s&s*YMAOK8;0BMh&j<(~P_ir#L~l;SLlVeA>n*ejlW{RD(hdA=+P3T8;(d zbJ}R8D1h-&|GVcKndJoqxTi=}I;au2IOKV5gK8$0j;7!oG$;&a|@#=l3<5 z?&MgBVCoL42&T#iL8;Ou{6ND(ea_@X%M<1dZ0ILhI%K8E6B(Y(dT>NMkJ9uRm_>t7 zT}sZNGV(@9sU5)hbldvh`vd%4Xb`Ra zO4&=Y=RN`{ud;`9fqh9%n&X$0Z-J2!@&F z8Bnm}9i!oF$T|IW(&lP&adv@w#jY3hI>NlL$ z(sh1weF{Mk#7AZqM5W0SW+WtGdK>?K16<0pia>^z5xCf_+I`q8=LyFP&brXw_I!|4 zTGHv3V!TuWto!t8`#4S6Ku^6ee`{gStb_M!;xoxw)M+D|V_66HF1`@vOOsc6j6EJ+ zGe_O)4ApW?8&G1Q`6q?!E%1DrdSc3S<$s%jj8Du8Y90nPW-0jxr_Y*l7l`?L67QZr`{&!95MPH~Pm}>Y1Pr7o@9q8TU(@$xfNL7o z677TP2n8I!d4e})H|o|1)WoJmN0u``~H z)kM@*Bkq&yd;T39rVUXcx2+4RWN_kVCJ#OuyBGMMcLaf1_sO&f4TXdRhz;U(rI{_a zr#MRcF0-8R$(KinkevnftXfbkmy)L#?Ksm6+E{($JweeFVPIw{t->g6@}H9;jDNR| z&hn&<(cB|_c(#xA)Z&b~zj>dh@w@}h?R4gL5aP7kw~4!7)4W4Enm0bJTOL<{Q|k_c zIoFa#9PUj-ABXyHFS{qPo?4Ah2DAEr87A#EjSFgdo11$6SMjmMbZ`P&d^n9~*fWi_ zuQC#DT>zu{x1s*VML{L=G3SWQ&osphr6EWH8upr78_qx|Kc|Vs9nm}y91tapPoZRm zbjI{R)3ngRs}nc;S)?#&xF{J?@V%z3bAV@d#t(|7Zh!7f|Pa-2^F~W#P+G}UP9$ekVXKqBU zO-c-U(aFmjUbpjnGm|dfzz2A~r{^90?{1f&2UGfd)^n4UqqYeZuJnCBWskHf18Btk z9U0Syk1?3BqAC3vl^ol=9iCHH+AV?&*(l#`LwC(W)RT@3r))ez(Y4L~t%KCi94IzE zDPk5|femYXN+%jRTgyeRvYK@F6(jGbLF79{JkePa$Mz)u`ZMu8x@z7L=Oc~%a{qc` za0uwe`M{E%biW0{d)1d7q3Osy8e zT2I^j56Fm(iqdkH7PjdXofv=gd`*f7Ejr#zF8(O{49z?V<1=gD5`fki&ax=KexvLF)j%r0Z+vzJCHagn==B($fw=G88wGfsp1J4L`hR%d*({})NoC$P z$M=Ep6=sL%(~XFB5_Sk~FtPiU;B*EgiSQLtt&MLv_^kaVs6VNB2( zWeFL{skUIO`oHbDpC`SI_AKsuEq6LT1D51{$gp#=g^fEw!pLWm9VZFLftGp22>Kb6 zc3lh$fP4FVoDc2P>poGjJCHV6C0#^Dr&JO{{egS2NdPC(U>roC_U{Ay`%6u#S^J>> zozO>e2g6a9vS^K~ke`zlzpg-$wMh3KYvY4{%cJ+KYjY-Yi61d(QOmTyr8$Z8^Jt5Qd z1V^P1C*&nOAvN_@9m(3Q`LzQHZ%VHI{vx2pMU*MpW`Tj#$mRD#mt6Gp_vo^4jB(I(;@sF)}Kh{ z)p;gGMN{;tCmaT&-V1r=#z$2~-iF!RS#%(-$LS{arIijsWp^m2sXmL+(R4+f(Mb~S ztsRz(7;*+snDgHl>~~y#3=*C7(?+IfPHa6D8lN16=BU{)#C;k=*3U2Cvr4Au&c5A03i`uk^nYQtr0_8M8i<6~m7U z_wlznv!?Uc7)uz!&*-%E#t-(uYuH(!jaV^z7K}xg@z3>8A)>$ilIi(;z5)iq-;7mb zd`gg(SHpa-pU8gbg7ImaBS@bZZfr6u5ZYx>#!so}=bVx0-PZlc^DRYLRDTUU%JC5K zMCYll+Rpi7O!J&F2~OlOHTtn&a=qbr$nw!5;{@`&QDHh zx0p^K4^Soj#8DE7ddbD`{YEK6eXmI=3V?c<6y3EZ^WfDzP@JUKF~OY!8YD#)HF-`2 zYN?Zo-~+ghXMlZ$^^IvCeo9;-<;S<=*vB+J^RtSV=tKSZFM{s~bGk_wnQg88Tpy?J zVPp4?hCQ_`BZjF}kq$E~6DZp}ew=yQY&c~&MCqVDae`n?Z4lRdK9|OzYyMGY{K=#? zOG_A^n1lW|Z)BJl3QmiRgmpBBm?s`4X7b`mxb95$b za{`xUl$=*Wb#(i}Lr(uf=0g8}`e)h2V86IZ-J<4`?1~Tni-21q0$ZN2fK+xh#`!h#EoD^;pgp18G!L^=)t2A7z0*>O~?+@;L*BI)((qW)!YBPEU(Bc)Nf zJhEHHXMEP5m|=`h?$fy*#{6vhJe#Fzl|*`+H5>(f7eqg?7wceSOn9IVYjS>}#CXV5>tX^)i>#5iH zv@RK+!H67weEsSAKc`gJ^5ffVI0YAF^9(U%kl^nXf7T_&0PB^WRiLnTC@T(ii~yLa zG3AyWxMv6*uK1+MLgi9D?GV5sC_JB~`mExUQ>jv=NN9kjbVpP=cJcgw@eIe5HB3pG zYN|MKFiG#IP@1GFbj!-)C!Pl-u7E(ZOZb6%9{9G=7MfS1mO{m~NV& z;*%HuC2(&IR_B=4pMPJ>SLv}W&6f7}oX9db!t^?LM{>% zTJcz31%Im{g?J7?yTbcVOni@Y!T9VohtoWaHbyC9p3D0d=ezhgyUgfR!*h40!O{=g zA)rZVuk@Oyi~Xl1B<3ts6h4b}rzs#Hk_v7rJH z7gFfoEY5LKD7j{DiWgY?&VTvWJ;{I^#lx5X?dyuk#L+L9&x7H-c;qG@E2bFlW@6oa z{0wcVh#UdMy=C1#hQZF3*}G1r6l3#moh)-lj;R#Y~#~0Cs0hOuWA`@ z7a8RnloB)#8tdLJMY1-v*L;=sU-|i!^9&^g?m$!Kp1D0sFf`#&-?sQi( z$y$X`+!c;`zKQ}F~ukeS35?%2t_`l!twfKOsl#~7Gq2` z`y9#7r4&yI_?3E;oyy=sQ*#~+x!z7j%uc5@UKYVPQ)-S$^Q5LGXSw|ispRe(hMhla zIs?Rk#0assHrU5c(;l==qUH}HNYe0F)|a(M>1?LKdoO&g?39>;k&{O!ictyydLgiL*V{J>=ze9s*r z=1bog)A;&R$}tG4IRh#P%>mmrRO-qQ0`>Kq(cHej0{Q|jO1#wSMoJ`DzI`Ms3( z45rH8#Y{TF!Re@vgzubH5dB5QbMsI$uJK6@AKJg4qiA>f4lQHu665`X&XOmCZ0lMn zfpko~%;;>(hI+xLK`&A?$CkYO{{bj^o2G8Hr^qKR+UtxJN@S%DelYP3$hg9k7^lalao0UV-moak6_uomue&wG;MuoMcbX5!SeTlv?k6z(%jO*=6& zHs*~3GX~=Cd?)+cvWzL|m-uI#eD)Z%_X(g&E=7NJM0*0W@rllfGB>7dNq?Ur6xdSbWRb4Zj?7?~ z_k-bkSB~*1qn>H)J|V`4%0cO|EWZZ``861m&Em!aj~nl~koKv$W@~|{fK2u5=$*)s zqdol^T&-^YEz}A2norSwT1ZJFB{@2~zGdj_l^z52DLvQowI;e(vaE^bjWB9LBGVLze*mTG>&V;b;GS9mZUVs{+ z2Hefg{y-t%#I)P3h(15f`JS&~x_r@AsR&Gv^Iv}6)7+!6e>_A87T!-7Wl!hmWXQlMZ+tS^ z_)n;=Ym&w%0(e>X2?p>|k#-Bwp7{Pi(^l;(%a6cY_%Z()_KjvomNrHJwLWC&W%}xB zq_p=jo93M`zVdQFG6Q3M8+0UP0X;rYLD-%P4_o3=;KOU1z3G`MRjQ<)tYgJYMrnHP zZ40L14u4rQNI|-|LUI4COp?;uYF93nH$HJq$l>U|nXQYSnyuycf~7RW zKbT}tF0H(zbV;mF{uqoG4Gt|V&&AdLS@$rg=yxd{Z6UIR(7UbY^I+}t7@sVgK5dqY zr02@=w;`oXL)tC&`Tfe0&)?2k%5=jY2@syrbI`w*4>N57FQxHf>iYrk9SC^W1;<@! zo)eCWaBd!Fwja8qdLtVb8ADg%u#v)vWt2JZy=)WtnPp zh-p)3RH{^II+QuHD8)0RM*b5N&W*yz8Suh(=rNrW7ubRD`R%78%C->n{c0|i#duKT z6Vv4$*eC0?kFWo(5YOxGK+*4|_NB#|Nw4%+QTM4MZLUA6{~nV8XlYU!Mj&nvv%Tj( z!kG0KpOzdj#~Vt!UDWtoW3X)xoxRe}Ptn&8^7Bu~VS&!8p1Y2J{hO+_O!y)AEcZ68 z8lM#LMj4tqMD$!&N)}4;Tpu7$US8KV=Nba{^qR-Qcof~E4l|j;&tY%goaR~;$>Mt3 z91R1QK6)FY#)a4SLn`p(ymyrv^8L#rW*p&u{7WGC1}fJzqr8H!TrgPAd<9 zCc7Jz3d4vL_G6L@+ZoNqXU~0VNx&hFdzqMwR1+ zbhf7()afQgT$WI-J>SyjD7*$;av#%n`4*Kf5MbNgMC$%r-)m**T(*Qx|6d@3y9c6{ zoVb|PbsNJDG)?!YaMZ`vVhU4kktjORJPI~RskB>M$N>F+Q?rshzm+PjM&h;v3<%U~ z{=*BxOW>>vBw0#tW$+tB%uT<0$~b||J}0$~EX%(l*0J;)$hk<*WL^8lC(eOvG1hB(@SWpe8mvUl z(?3%y$CIP+X>M=GKwG$spg5t&*t*+B!?T<~mHj>+ zVV1fCDpjh~4Wimlh&&~OG@xsrCIn_sU}hKKjQ~z?UaT?7kZmVj)70$d`EqzhO;MWp z%yRQ{FgJNR6Dy2&W?8GI-f4H9&2{eVNn0g;IwbW{B%uA}PbH+s^Y}U|fp!Kj=~^8vjGX zz>lS8ZxLco&b8tOp$RS2?=!u=!K}0kxKgFnN*n=&G+es0-;yqCw}335_gDJ=-?Pu_ zIKgMd)Vf%AcZI=*;^i-vr5J10zF;Ww33Ft#c{@6jvwAMgQ7>9dRsHgkwR%X1C6Hck z>3{d%^jRg1Pg&EPz@S!Q1=QO^1J543~Gr<8PAXG*@15qA(JWLHdc&XG|Jh+YNSE4Fas?=@5bQ|j=8g6KrvakR7j{fydiCuUN zKZgd+ySCoTb17m4^JXTsbjdGKos34V1LU^$?-Hv01KE zgHyk;-slbSvutt1N@;w))GQT!>mntE4fo-hX`IR;pXvN8ANkZ~d@{OgaFpF-*)uTG z`Z?AS6DK{%sWz*nm*6^@=4ML!k- z#QSs@m!AC}k)E@<fbs3-G)w=(efpg6thd$%82R(1C^Twy! z%_JkSW#bc4+SB=ZxXD@-6(4^-7wI+BflnScgln1CgRDJVpzY3?mEq(Ylm)m@mWujf zLnU+_m1h!U%DVfcF`{v;X8(&j#C0I$Hc+~R0g=+Z3W( zIxd!6V>HTT!+19fX?vvNS7uI1^4EOhk;TblF`O!2- zlVCYU=~Oz5&whuyS5Td59K#o2Z0PjVvbM4v-4TRupq|(}{z!3%OI^U|nSU?WD`~dg zD^;qrVu;hrf0~A59rgR8erVR1geG2xhM&t7-MxLK}qA*Ef@nd?Ils557MM90IGs0F`5tXZopG21gguZIRe< zb{ivml$SpH$kxd<$Ww0B6K{}P(E!R^z;mKtJB5zXvs9^4rAm_~u4@XZRDTBHuH5)+ z7B)W9<&Tl$6F?!-l3Fh4Xz8K%xY_Y@VP*cmB-Mz;Ov0XV_#q{B64*w zKCcJaHIp|!$><~`_G=ibZO(cLYn!ieSoZLoGwi?#xB?F~lxj<*GZSBiiBUvRkLTfo zu)h#xUC(;j20NAf$aKosXQ8@-=L`5C7Xcl@?+i$Uwclr@N|mNZEVzRr@w<+o-7XUO zbh0<$3F&uK0llL!NKjj?uSn)jdV(KbV-+gemCbCkcN}VPKkqC;*DTQU>puD<`&kQZr z9Ry0}@;#y%>J;E2;Ssia({3x3OLl-4mmDTGMSe!}3J<9jSq2><^<&s!S2f4T}TB*`{%E#D}>r1YGD9HSugE55nuRKPAz z>p2z{sUYB$8*Bn_ zNM8QZao1~3gx^;_mXR69^=(77t^@2Nbh>gx@l7z71)~*NIvb{V1^%faAU=obVBnco zY=~kiblQ`zfw5>YKIb?J>z+txw+j*VDs|rYbQ{DP72fx8f1E0epBC1O0J#tcM3>UN z@VVhAuys341#qaJ=E+_E95EF#8l4*qw<1wIkBgiWjDE+`1d4?J#lL@qxHtJ8?=oSh zjdZ4N;NSlf=0Q``6VD^2+@1vTsbeiF`SP`CQ^hcDDdQ7z_uaYv6}>5?XQ)!8)kAoB z;ALvvgt(CxHr9!hQ>f)wqe2&Dl5T^|Qq9^sj5Izi^!rTzhJZs_l>RoypQF@TcXwFB z!2lP?*+7x4FTm$u3!CX1pgD-dY&4K8DSY4XulsPSpYl}PTp53zaBi31J9!G>y$!Z@ zT6i3=KSD}pEDPFf$}6HMn@%N}InEwnFfNQ#e+NFl1IA}F15vo&i0qZo=VF{W%pHH% z_IwKMdnyx9pN5+Q*~D^ytS0`wp0^bNqHY7DNkY{4bRJ#-V=fIyw;1D^JTu#OogqFb zkM0{#nGH`1?CxbcgWOc9(h8wG{q$h}`aaL0mB%|;<6e9XpBa#?pX|Q}S_MG#p+uV{ zsl*4x%XR>yCr0Ta5W*YaxwkZ|JZ|s*@7n%%WUH0(&pa7M<>0?T5g+^#&f9^6`THr) zt+%_;ST&H_4CDWfpH|4@3)Z2xOCK;fCF z>|hg@0YnbjCAT&5uBP#JJmMJ$Ta+aSW^f$*$uRbVrnO3ey0o7z@y~oiSd+oBe$)`w zkXX03*mUJ4nu@gDk=Y@xRH@SBDfixNC+#dALIGtcrIyo@&z-@j&H^wPG*&FJ69 zCRwBg9Az;^#o#x7uC^D7S7cY;P*a;8JiC@N)ff3}7LS+{=#$&p|K8c~_oa=` zS*S((ix~%Sh~%wf2ZnV&HW>hyc6P$}6d60Eh|i>KH}Wju(AvoRr$BbaLT3RpF2ZZN z_jrF>cY3Ug=WLp=->{Wexp{7zP>!ZM$zze-hsS2-mGf5HKO#8F!9Lm(< zgwo1u`!)Z1Gt+}Qx1jKruAi2a>czwBQ{b65PGEk0Xp`<5NQlDB}kJNLZZb(1-E#w0?9JX8UTrr+o&Xd?8D%#VGA5 zo*!YPLElLuX8^*eXL2-M8^GT1oNI6p$TbsoQUJ>XCtv4CrrBBdi@w8LW@4?wl(Jh> z4bMv4@RcfQqg)aHnMglvQ}~KrVKL1o2zX)W#qS2AgZaJHWR`KZRD8=J@%e& zo7j^+S>b&V!hxPXkJs~Q$rgj+LN)((E5?UUb2XP9N&lG z^EVkr^ew&T2bl}3`TRBQc?}Ucjw-WbEA6xA`RBWUvx?&Vx(U*UXHBYM-DDEND!$?! z%n{1rNoVVM zeqF9HR?2-*lHLsKBsfLM3Eu<;=*xKHD-b4?Dy?*4XH+si`Es1ZIhU8=W)P~V_<&;3 z{K}vI7y0+s;fpW;>a;8qvIsz@j8Cl55fNlcLmO5}=_=191uc#r!57w#6#dIuCNzh^ z=d%%Cem>bjo7P@LL7Q**pLaEsHcy`X_Rh($lu)uwtRGMFx6$ZO=A=S?7qe94la+9; z`DBMg8Rp)W7no6MekCwj%9i+~;g%8|b6AnQJInAL(b5KPfq4I{6*ZDOngsIsdohkh zUYpIZHsL)Qr~`70XwHx!n-EfG=Y4+4ayr8E?jrjsL~V70nzcdL*E7k=?M=#{fiqrQ z-uKHaQGVgxZO}gIB&EZE8|?Kk$dXFe92Yse@6e%LsT;piB~4_fYJ4svSn>U)zV8k7 ziveZtHjM7*gpxg`!XZ)add=%N`=a=TGr+tF4>~HPRz)q*G#L?U-zR{phTjJq1;RV= zt>W|1Nupt1Wh(A0flr0j0JeFO;Rq0C4wN81Q-?rCgO)Re#@iMCnRYkWVqxJiAaCJ+ z@8>Y*rRyQ_oL}l+0dQo1RP(&1KfH!afwR(Q3B$9zlVuo&)cDxiL`T|fKS@xi7^x;X z6F|@ zKH0y2wP!AK;k_a2RZGv_WGO!nZ-n`gfODnyH!_2=ruDrGW%+b=jmY?PvM!_4q>Ge1 z7t)Dt0?*cw=Bbq`b(q+5ydEyYY4^L7sfAeEut{8|;orXG`2l1ox8?0-Mfp|m{aO^| zLFO!5j$B^pp9gAYmoPrD4OFlBrqO}gI|~Lyc>bGG^kylNMs#}JTNo-EMaD__ z^%-t0G3(<5BhRfy%4G}oR7JxytjmqElzC3w4bkZvdw#9wKbREd{p}JQ{{MF-Ml{{G zJb%u=f2aTK=lR!rnuzhz^vgTIR_J01=NQCtKJ@XuL@B~;I+vVc{)24oI!jnrW!=5h zaBtiZ6s^&FM050k6|zKdm7GWV8wSD#Kz|Vs^%=EDu?%>718cyskBu>!i=w9gU=|9iy`N6e=|_cD)dth zX~rQk#x7Bv_Z1rg%{M#UxKzM-Pg#03@OhFe68#wFFn-MA}a;tm?)E&^hrqQ*bebww0c z+;Ep5sNjMyZ)V=VmUHTyy3;e$Gt=F-y8HWnzw^62J?~BTty^{KoI2-x2LMI~TR5Mm zRpflO^g?ttE~od|`P{mx&D3&qs5zQGV|x`Tf}WmhZDZ%r~n0kcK%<E8*`5utK z#7|6IxNKclR`blM{^4yiLs*q|k{+n*LW6~iuCgPwUXIQyT{9pq>#o&|U zq!Ugxy(;RP`YB`454Jfqlf-N)@=2-vz2>1tjGDSOp`q$n$C0wY>cLYe5)Q52I&O3j;F~ z_WZ_=!`@_|uN*~?)I9D1TtiAewODdT8Sc%Tzi&3Kb;@;M^_@1yGYC7Mr<&SpK7l&G znK8);J-D?NYFiJiGZ!dZ;c%n(q=|;^L)3H6BZG6k^HYB&k+6a3YfPIZ0L(IMBQ-P8 zsdG9tt1gL=$w)$Uni)!@%WWki?%`x8Ppk8(N!?V7mK;gu!^cUAgi5J~Z9Zl+)9Yp- zX^Tt{;+>V|XNDWaOFz(>#z;Lgr?Z$|WW+$9+b}WHpooXs(XqR+AE!U7@7DGBtglsx zuwlNC{$ICgx5wEcmVYJl5f?GWA9Np&eQ4XjZtph3sUKp=GNTj{%amh8Gp{F0Gq^@=! zd@%J)`Ws!>e9FA*HE%G<>AI51Re{%-RTCHkWs~UoVep{8!?1xlHG>WSmBAJfo_Dm;3oDah zJD*(t;qGISQB#Bd8~$dd^{REh^7nh7;o6|&h+N&j4iTQqTQ$Gk9!Rbw+&;rLm&EoH z!zN^qIx2BMt@}BBcEv`0erB2p_XUPYYDRg2o}0JF=kZ4}q$+Se^P%=&&L`J~+2-N& zyt_Y`%8^g^{`~z*M$=pQ?|Y^qq2hb4aE@+Dc&4pE zh00QDuJEsKWO!ej8b62$eYn=Ej$T$v%AhD~GoV}mVE8Ee0=|yc;cPgcLdJ6ILI-tz zpF`BAQJ3Zj*o8)zK7#>1m!5rQQ@pW>?Q9xJaqhYlV>QtvEWPGXvl;{FMjGM<(1Lx_{^Msux( zgQ-P&j^P00v0fhH<-uN_l({>kW}m-n-3Le;6JB?(%~2uPhd@6td01M@M-}s@zRVup zM|gh!x5@f?nz(P$i4hr{?nUaMbWJC&C&$yMKzMV+A^-rajO={6<7wT^hVv;=phNR! zRNscQSzXG9dEt6Hdd^~e%c&|y_rmYaqVeeZFmiP%qqL9Cb#TLm^v$E5iE$h+qtC6} z0i|beb2``KO)h5{LHeykKCkWNclD&*s=lyc{@XR2PtgrGQIW(7o-d^jTPN@7*Gy7U z&G#LNFw6C84N9|sm7tlBZL^z~pVE5K1bbc2WxbBmnzh`=*8MH*I}_g9vmbKWS@Xbj z^A*%QSw$q#YrZJqa!N4)0ARR~mLqSVbvJ9y=k28Ky|N8yb9z)ekWb4|?tX^1u5Yx> zp1BUR4##07(G2M?Oy7M(8#Pn)%Yp4}yJY7;@OpcVLE0_Q54^{* zjtjlKnJ}(gOEro1eZCuOx<^eA*BLVVox7R|8->k^tsdf`UUQeCKMw!^!$ovHqj9aA z&l-)F5jdY|le&c|+l^FkubbS&%8m9Ellz3NphKm;k)xu|qW{}d)9F)1p6joa4YPmR>WImRrE|f!j%@eeEv|mjJ}{`$`X) zHQz=e4U+@msf0v7-&0wmbw1sC-Wx8!heGJi?bbz-yE2LGc{*H*u^#^39YBO%bM4njfvgkoWLDdow; zpZ#~cA#E0OIN<_-Aw!(c7vwa;Iu4*(GW5tNGk%9Yj+{bS;eD@j6Dw0epHz}ct)V}; ze#$oYC0$$t(aI|K$^>=pdtP?S`@|?AX`9?D`?jVX0j)6wSDcA?T1Ou+(t>3;V^c;x zFG!zPiSwD(#hF5|wWjmgGG43B0vOF)DGn~0U;26TGe35L@aU)hXC~en_n7eE=sy{q zi2wirTql|Kg4*Qw3&Uu=#~tF=uWAF4XMaiWX9C)?`^HU zBJ?i3R%S;ZHEdHdMJFTYvU1<5&H>e_n*1G~Zgkz;X7^V~R}I&%R1-05N5}`^kdVm9 zv+4hKe=tAJd7|$*GNHR&yJ~-0L>8lsA3q^1EJN zZQaB=nTUp(dzu+>K2;x_=3E+(?um!Wy3as|iVy$*+Q@o(T5r{)-nV2FkD@mCpbF=m)ymHM~4JUkj zO3UBnSd&@wruj4g0LBb4vi>oz|0>xMhwgl`lHbK&&r^hJ72NAOB|a~w*lpc=4WFL! zy$%9yD-!Er-4E&S*E=S;9xcv``=)yylk*wSTjqeaQgAtPT+w>6%bbgIjYPaRKOPcw zIJ2V2C)*JpqVKr&AvQ-IdQHd*n}*DYLD$oc$fBE`-TD6Y?&NfGdmf(aC$z?PT;GvM zS=^IJU%~kV_&{lnYR*Hj>L+wAyW-1*Idl_FXc-}M^*Eo|xO?Zo z1ctH}cJ|jF(f?np$2JN*7WrZYsdro?yq!YQN1^Qs01O$q-pd_B#rd=0 zd`fytihRa{w~2H9*_16k&%ojmvxJ?^ik>;+)XEK5dT7j2pQRXeJ>F z4(K20xv;TZj{|Bc8k@gUJaj&k?qTD#MrCT|8T5?ma6Xd}dXix#+d-U9i3p#p)`kqxJD+THVWt*rU?cJ0zTj*K=<$IR&Ck+gx^dG|5)Ad4ubCYAZQA3~o%5+v z6m9c3`i^iuXBk2=w1sr=2PK2cb-~6wm@pqe+!JD2{{i{%Z>C_$+qSW`k`+q#4=p!2 z&dtOhLlX?Wod94M5M%M)qzEf*uQ7tiCvRN6=CkxU-A8HGCuRC%I6d8L&4@TpPc}8} z1uNe_8^2QL+ST5W*x|=U{X3*_gdw; zdz;%{b+>nQ1~EVnra>w5|2tKRF+GU;bbTvs?4xcb4gj+P%W0PGKD6d4t!o;I^V!Py zs3JTz3&SkA)F ztB(DZ4f?dUF3odj%JwUaz3Lj`6PW#4Tkc1^df!dm|pa1V*1-$R*3HP zDNbjF^C1f#OrB$g#oD@A6b4aF3;S1^2OZecfF=U5hz&*oh+KRdricC21v z){~l@Q*>jt)hYRYYEDDn*z;#2_;>zZuWdMOzyFwY?0nK;n{~u)J!XP2pdN6UNb+5t zL77_<&{~Cw0ps`mywOB$GeI<@QL>mFuhL~|cz~_8EAAab>q`azvkoy9XVCe~QK|`b zK6BmP75;i7s)yfr)HBV8IU;u3)61Xgs#EMMY&d`4%ash*@^%ezK<5lc5qr%O)%O+$ zwA;w?QcJ>nhZ!d3S5v4NO^9CI$FI-dsCH>x>(sU8F!?jl`Fxa_`CyvO5s<^zhoJG^-B`0EPfblRKQ&SEXr|BWbn5hSa<1b0)?4Y}M+y6V0%q0K!(f zOYZeqGYhb!9be+*s-}j>C!=J4<+=7i^_}IEzFQ(2o=*#uTKXlUPvZv#w>wA<%)ijw zti$&M?rpHqXOJeWR|XB4gn<&?)w&j-aO-gAwSUX2yb37W6zI|k?T zYG$>R!7flbpxlb(wqAZ8zd!e&?B1c_)@H3bq;Vav%fZhBr1G&W&}p~(*WFHFgwAKLd3!~M@*sLpB2?Dh-ej8gA#7l})kd#* zt zPmPLv##G>BGYot`?3Bgpb^P^rRA*gjhRDEUB23xV-K9tkU;X)Z=zQk!zQW6a>zXHUamHV3h#ZHu%q(1+*)Or8<-fF$K=necU;8iuqL5%u$uhoh8+J;izoztp`a*a5lh) z>2KAX4Y0CUih4?<=tCy6`VLTcR)_N$4ij#Q$mfiqY^`!7KWBfCbxhX>cZ295`F@xC zb++G72m+@D!p;}2pHcNbT|YSe0F%+?$yWdXAOJ~3K~%y^lkEkhfDruzfQ>+EC&c-z zQi+cw^2tn=|CIGgmG|D-z-%T7d8p}e?fVeZc5LqP_aOS*#X6(mc}#eZdXSlfIxy+~ z$q~>aiszfC_&XYJr|SSu&E+_Q9`1^B@`&8Bt^3F)8>f%hFiDMWWM9@n*SaoNd%pCY zU8u)Bph&eJd>pzV9E$0}(fK^c)Sl%43=iUTQf5W-T+)-1lmbsSjC)Jb&I&M`V!}6tlQULFC{(6dsEHpP_?p(-}$f1FiT~o20}V?FexfMcwIk4Q9${`!@a=d z6A?T}09Y4fz2AuXPU%g)A{nXk`CO$_D!g~C_cBSyF=kZ#!9p5us;RlIVN#r`$Ax>Q zHUE%n*Cqv-O*PKx&nkzlt1*}8diwcq^E?~qezGI;C|Xks6|miMkDdC<^ ze|u6|JLvDohgTP+nqI1DUGErlUGr%X`J5SK#_*i_{@!BlRaqvqY~ArX`B0v>@K;)p z6WMUe@J$-9no@6fq`DM}09bcXY7f&0TN?lXgMsU%ZL^n&BqNRPomi2K)cHJ`?t7uy zNQNyUeBn9mNgML;>)oaF;%fdgeq8UIX!vk+p03B5^|sRJ8te>l+W@(zj_0A{F@3$s zhaBsOj9K@9-1NQs9;Rf!xJR1JIiK8)?t1?9?~QJ1-}O3J`*|)Y63K9Vve9XbgO5S? zk3QFu4(QUlt0yaSwK+>X8nIpEU*~xXU!{ejA6fI#oO)ZAf^9`V zn-`jmC{h5Jb!3Aorq}&S8B|@b@s^C#`8; zOZ1tQ9YCtF;RuvA0uwrC#-7iTTcuw3cKL60&2}rjA@5)|8!Z#(`r!EYZI!lB`~LNHM=Gfru(e7X z-9|onU%J?@^IZ))(7<$p59UH9OX~0WidLpet!u8-J-yr(?e1n02=O`vpL!<>|8LO1 zRc4sAnyuTwd`lA*xzqqK7;+JR( zgoYRQQtP?bSJ?BpEj%|~ljp`H8Kq@C6Ce0?ozAIiCGS3PixOeazFjsDyR{p%V|cqw zx8h+ZoDXIsGi-;cZ+$E&JBbfydZujkv%dSU!TGe!Z~S$)+_ngqPUJREIg^4j9$BZ< zw%*!$C#{d9L(ic5L22Ns&?#LZ^>+M9W<3v>PZchT(NENV0>I$lwUW|qFQBzFE6yjA zE!{KUca6>`*L&JXEq@;~j?+`A-FxOlIG^cyf~2rc&;eu`=Ph*Ld*_PgA`^NXGr05V zcun0t&)@EyXmLI_8~IG+C*)weJJ6b3R1wgw*FyW=!*#yw3%rSxznYv+L_Vh*y@CZN;+h7R4_0lUlIR*O_9&dw&!5xP0<}E(>?MWtVMtD_gJ8Qh?n@+ z*E8%qZ!~M7Yv(iRqTqa9*}(anPV_S00ME6T(DR?KmyN&g+T*qHX~`r-t>@a1eCwV4 zVEv#H=DL0lS+hX?*2{J1v;@&l09XsM&ck8TIVKw{ov-bdjHKq1Qv`2j*tn^4W8+QC zn)NV`ZU#Ah(h+e?Ji)DTY-D__H;A>-G6`T~go(dw^GTZL-IHHM=QDnn)6;i!YoFRn zN@^g4`7`~kTAa^R^BLCt=ARiK&i|E>n$lY8Kk4)HA!4}R#gw(h8@%_fBcE}cgPn)S z=d_}nr>P9V7Hhfd^|ki;vs5>qewJF#Njenm3`|L$Joe)|P&Dg!&`x@8S$BL6)!SzD z5dr|1WQg+_*34IE4b6u0DF)=tC^}G^^C=YVsrTc}$hjIlO?!4C-2SHiUY`@}e5&VZ zn?q@?bFa;=$2I8z>pqvi=UUFE&8?gEG3O4qtSr8Ip7TU6iM_0Xb(0@9&?AQI9kgGzTwcXxM( zG}4j-0}=yDcY`7wLw86HLka_oGt@i3|8u=x;Ou?YIoG~pt-WrbvGLlIJzN0ix9kFF z(O+n}sZQe_X5Q@65IGmfcjalg3i7UfZPAOKE=Q*B`tOB6f~ZbTGJ_3&fqG4EhR!^6 z>ZJmA45ieWSx~z#I@#4{(1@?0X0KLH$DQf;x7n$UTR-S&e|S@PTVA}&cO6wjDg*2l zl0zH$fBpvK(sj`tK0pWOe6MYRCU+p@ad&Vo~EVmqtyz`vath2SK~ zO4?!Tw)E_?sb96z00)81``GD$ZVe5<6w@-m7N+fT@oD5WNF8Y5v&hHs)hV_T`qR=7 zWhDdoVnN<$Y(y)CSPO*779-imP{(`{L7*tov6Ik4MQ-g^+^2sc4qxp}ZPS(~3k{?_ zIt%Uy8Fw#GcX`dU%)C#F5YQp8v&0PPvI`?Vn);3p6FAnMNwYv8alJ{eg`8WK&%Pf@ zu(PkX7?Zy_jOQA^dP%$_%rBF3<=Zo=SO*G3?Xy7yw~BGzn^_aE6taeuHIL}Avcw1T zFV8eH8~LKE#6eIkaP+~%1Tp!~FE|~pJuo%MOw41LY$m46Yb^17jv=VnoN8&ch{b=V z)ROW=@eVXdPdWLXBlh0qiL8r*IbL0RD&eW^06{Qzhgpa2F7}CjW-S3UOrQURj3e=; zN73L(N0&J@a;+MXyT85ccq|g8{vP=UCq0v}p)<`n->~8RLL*7^mT!&$fk3ROtxu<_ z!KD!cO6F#6tG|4Wx`R;>P(kV$Nxv|nmqAuNJwp8zv8<6`Zg0#e^@9W^AQkHmH4{cz z`>W*ZJ2W{;Hwt&Z6%W$_sq=xBQ>9*R%6l$2(pae(5Ib$Z7l=b}AX|Q9pS>EYjU2X9 z>Re|>!s#iicA`4}iu2apSL9@r_`Ua`q2SZ%+(a$j{1ATL-x${64XjQGPENd{qn7kH z%UD7B&3f4~W*c5^0lel2`?;CCe?Ba|a8~PntQqO1+yA>Yoq2yle8j#p3Tuo4P(`%L zJL{s){@^m`qCv!ksX@OLKs%VhirMG;H~blde+CbNFJJ~pF4`Lu-^N3rwI@hj(Z-hL zp5$`f$r&{1v}O6QUXwA4(Ch9s9?AnjYn-A7+=;!AhPF9r(0eF?l1;P&#PNdQx@6{= zOxsdjC=vH3SKHCdKgH`caPf=WeR5{-EVhBvY6a1jLcjufnxj$8fNA2^f^HYpr<9NN z9brO>#fyR1lN`cTPo-Gye2OXn<}^)_$3je>e3VUU_x^Vde%YH+J6x3$?yfm&T^n|G z)sQUAG{Q$JpSH_u$du`JOF2wJY`t#PoHphKd)_^KWIgF{sIJ;-yYgH)sR_Lg?!|^_ zuhcCsjrscvfzgG{jdtr>r9W1nJ~_~qua0!JTVh|6VRcT-5`MrPp(fmXft_(&EIAy8 z^J5{AzfuB?=yW5RdG1Mex(O)}ldGl-!HUk(`pQ(eF?4aI01Dbxd$wnac;h*_ zAHUbqQol#^jhCP{OYhz)c>ys~<708=Lw5v&qy3wH@FncjzBcs8)t<^c2!*+Q|N~9+3 zL(a~aI7FQi3ZdJQ20e{l_bK&>Y$xH9+94RoVoz_VdGuS@-QBE7D;_!EfO;7iDlPC` zXLXxV;!E&_UC5L@kktHQYLfCms9V=T-loI-tI&v-z{w)hs8_}r`4X0DTiijV@d%uz)2{y(rcH&KUItlZ7Lro=uO|=XIz)SHFi2 z;77JJLJy!9;_~STnOFsXkAxo^x?^Xhtt#$nw}PqvBIlj1Z< zSn%20tD^R@>@!NQ`8Vv|C(^OL+;yS_@E+iHG(U?R^|`fsR+3Ay9@JOGO9aZo_t(h? z*0=IBCZq<@MF7uD-|7xx5X~u6!L8cznaUPnXAsyR%dNx{`K3m8(_)(!b7!}mMkM5Dv<(D( z{Q&j3`m@N#XZdDpY*sQ!lp7DgMr_&EHIVsbrqi@vNsbb=8}z_5?O?L$l+1HK_51ZQ zpxL(sKt9eYzkL}vQt<}!%FlK}U=f!EoOWK`5}u_a9gtlQlPBHVMd+}D2R{+J#@ zbYBUXmeuD&#amY_Y8D9zw-CZu2N_yOMzBj6x~}$s_H^tn=AyO72=}NvDY915C)68t^b%0taMgQ=|d$U3rXjI1!vuepov|)x5IRXdXsil zh{T<{LV8ryTh%5tn82cxr%~KEn+cL54DNrw5_Z;YZ%mL#ye%$5np-QZz&ZT^vG^mU^b7g>slt$yCzD>8 zr8DsvERF9pPYaLSirN70%e30{M)C@u!L*sl&iF>A;7cg)mEjKcg?5t{t;rf*EQMNr zl2loWA(N1~Z9e5=ZS>QtPc4Iwi{pxSS}3C=T+%IXebGkGMZu@D2}Jfy(9i*ok&tLu z`d!*cP?JYZe9vy)Ve|<6`0pQM=5{u+w5zn@n8OhR=v>v4n+fGIqdY6(?8}#jVjuN^gnqH9%oUkzg`ZhO>*aL> zO?%~@6s>-F1aOQHHLs;8GhDUh^@JgaWebdubgO%8O``AwXNAF7hIq)xT7}x88>FLc zN3qrKDA;yLfSjmIS7-#qI+J@isKI*WWfOZJ5YSC5UY@RtyuLIx#+$SocQ%K)H9^Ck z#<9@TS8)GOF!^#gptyfrpNi+l{LJn|gMe#QRpQkmCE5jVd5=ncS043E2{t>w7mS$?z2}o?`5QR*5Zusf z`qB!V8-U|6)AbDE9dQ|#h4*ae!Bz2I%~+rou~={sL4Vvb627lnH<1s2YH143KfT)c z^9!Bkbj{?r#28^p!zXy2>ZAVVdGI{B1IL>#!ErE+oiJ;3Izt`Rv|m0G*Tro6XEbMF zl$o%&vi%>viW$^9X+F}FQxx>EU~c-vXTuNIhzsk7ajAn^sq5a(;GHA!$pR*n9TjLY zpH^%t4T^IZU7Fem^v8z3pSU#X1Ukdz(D!g4&`jnXAJY(EOzdHzu-qAFijdjX7TkEW zndKx^{}QW_$fJ)@e$XOny zEuF$5J_-L@Dc#K?@@j|aaN87S78^M60Nb-;d)j=NH??yPyGL#cr=_)_+8#t+ieFnl zpj%9R(^NX!)cKY*7yU@9Vj`D?)`Ev~>I^5e!J#n{F;?Ee$AN6%Gp3_7&nFRQ8 zhIQI*t>E~|oSA#GQUPqAZ3hF>h?y}IAQ^(3><;;?wrv) zGRX1u`92gqa8wY{{_oaHaIU#PCpjh{WaijP>!w(;L3)|ZY?L*7&Ze ze*D)S6#SL(G1zgAQ`fEG9KG962B6n4A2iSX+8FTBly078j3qhP5ScVN>#E%=u<_^A z<)3x4vVB9GDI(&X+`4Q7TCsH!LJi&ZZkJavcbV1tF#$D6JQxTx7l>FEIB@eRQ@^|e zeMS1x^QSP4mE`Ug338!BL_rxuA@=i58+kt7)gUaVc>3RsF7EUviK`k%%XsOLe^L?C z2^ zGHGHShO8s$MTG&p-tH?+Pm@QsGLES*aD|Gq!s{rSB{xemJ!W40r5Yq1IfH;s^+hKq zVw}L{E*Hhfsb3Zg&>DFvz#u`Tkv}fSS~Qv@Rc<$Ug&x&K1+PsmfcmF|U3!*u{q!MD zPC~9}6TAKPXz4&=Cc!jiz6*0bY}lUDy0;iO$5yQya^1H8~hDF7&;hwb#lHs0tmGU)dgTki#+N# z%g-XV{*gA}=el(GN-oLko9*Gip$V=s9WKba-08#A;08Xv{2Jv%78)IxY{I=E5fDI4 z^&6`*@tJf}!hNT$Qjt=q-kP@rL`LC59GIPME&eS9#r; zuW&kFdIc0)X1eoXIZE?pilxP^coWH+8GS?(Frzy7*~pQPtY^&{y{kkd1)vuCjp`Dp zj#~Br?rofvJ&F~#+#gSangz6z%|nUyghisq)s~Ns_FAjY45PgN1RpkJq?*#+P@Kl8 z8F%Qmgrb#lwQSefiO7Gt?_7RimK}Y*Qx+7GCvw^4UE8}QFZ=IIbE5j@OIUZdq9zSJ z7fv7Vi)4sx%bkklm~T}E`^%@zc_g`z8?l$!%CH>OdwLug93@3LI_j#a{C@N2%=sQ>-@|^;SgVi+a+OAgehNc)JaJ!k5kNn`T#=N=hKss2=8r*Z2T(VYuAU+G?IxH zx(R)keCV*@$2oF9OiTmu;uGSt*}cFML#T_2$aNft1Y7~$ZZcL#^wgOpA0vTNBu#yC z$8Le0Mcfi}&KReFok5)AdC6Zq&M;#BB}{#$cX7L&A-YnsA4_OHvjM{b?cU&v#*^#mlK8=?hpHe)K7yrCSjE*#4LTa&ASCMHvC;ws9<%N_a_8ShZMAigOAUB2C`yv5dG2{sG<(HKzA zja}lU5d}5QYyyZ3MskU`h5ER@V6p17>AzgLzmk1(!G9mL+oE1MSXx8DG<~8D4QxP& zrP*9g+SOQ$L-&{xAN^%5TP=6$4C(uKE#~{NjQvGesHl5;MA(Dxeb8t06f6)PK-g@} z9w5e-;8Sb|8@s&%cinbp8=)S8PE@8o@jfdF#s|b;SKishoaLhz!%DlIKEQw0_^jFb zurRUpd^_+XV$kB48605$6=oBdr(ph3*k)C!xA|1x(0TQO;|)NCt~8}Y6g+>mNBe1a zc0zLwmUr)Vp8%}o2A(W1C*7>60I>pFgi6$=MkIQ+#Vv0lD+aEMglnO*Uo^YcY-5^9j0Srcw)nX%i}GE zVP2@;>UWYSc|H^xVl!+XVw}AiE+_I+SJZ{uxV4)^IPS8Jf-$6Z`LlF6|Dx=%gFj^r zSK=7*w_y9!;g@Y5u(o8_juGLW*9ESOXO-O_E{+j73fv#IFM#s<2pB`lp?e)ghJzN| zTgQxywP7PWpQI(VU00vNR&-yj#%X_4bk}Ei2uQQq4O)>Ln$h;y0p z{=XKWy{T#jy$T?w&;R=Jz&L9su>4a~C)Nm~G_&_Cubo0x?`fnlTw6`> zGWZ@DI`!XyfNmC%YPZc9W3q+rb)RRO{?brn|($ z7Qdo-lU3#AV+(TU&$5w)s_RZ_B36=NO`@yhum9M1Y1VpM-eqPrM%06F3@6LR|dbwr%|%Bh|9cAn$LR?4%iUw6`G`A zCFsw;=qj~Y*Ni#@idma()pQ}?l)9hJckx-@CF(es5%WTE@cY~U(S6d1rKf3t=~ALMJCYX1eeO4SpZ}2O{9w3 zfpn9QPgTC%`z4nFLNY)p%g@n%uUk7DE6JwS-C^=yo>2Jl`K3A$0Ki7;`Dd`>Of7d>m~2c{tNrJTAi0g!Usr#OYp~Wu zUnx{d1{(s~o53Ka!ox&S{&Ud`;^&JYQLccc*GsQe^Pytg{mo=FHY+YYNNqTxqth>c zgcPVRIw({G6P3JqdwZq+_23+HQK-voUG?s6#No$G&4|*oEonqIUm6(z@E%|nAj6Z9 z<4H?GmFpvU61~pEPohYlL8Pe;-ES+U`?BETZ93b<_Gjl^X3xCwm`R)a zZk*lUxa3qh8ukR^x{GpAB40Ec{*#rgH!Vo0bWZHtKmRV7`y zMkaWhDYk~m>Q8vQ5D9s$W}FY3>Q{%5m}Go%w!J7PzULH^2Pql>%x6;7?%Pfg&Urf+ z8S~+a_mOFu)Q=xGP3;q7i{F26E|yU&gnS6uzI+WaiPLkAl-D;7A1Q69f>A9Ox06oy?Rzi#U zdV^;gFS1Q*K5RONQ}^;X$h%A|bVR{qe=w8l~N zjmeYGIa~VZ!c~cy*tIr9CB~MLxGSyjXKBH$GPEO;CpdlFsjeOe@cvI!1tU{i$JFW# zU8#II^gQ!MpOv|H?Cxq%ZuPJ)vqVKTBr+jXjU-q4ff!6Y|CYLv;o}!#Ua{ATerlQo z(k8WhuUI^RIHmi0@s|OJopuP&(hEAO+`ZPP0}HlgxNn6Ac&jnCiovu`Vab;wGj}SJ zg>$FU45Nm=wKb;HfN)of#*k6*x1xn+dNf>B>TI&eYH6u`;DkDVUN|w@1HX^GZU%`k zs#f(PD_b8nI+XI*CQ^AkQ%s0-zpb6rR=*j2U7+6j1q}j50BbvSv|d_t{tAOcUHp8{ zohqFmt%&q-sd64i?M8j{nCVdqv-)ti{&@e+(d$)8H)B-)>u*>j*Z=_8@9X_In5z;@ z6|&>-HKdS4N&Qu9#u!&e=$pPJ4PIqoQjW@FcF!5eKwe<@#s0%nZBW&VJIV@rN%m6K zh3;C}M$`Clh26#^>-BN>Kn?Dvmfw&5*=!qFjpEEf{Fun-I@3_bMZS7I!Z2$M02Dc1 zdJb+;UZK5Loc0lg0)*mjl0n#Z(fZ8EjiGLTaO7nq?I>gmzH}fMU&%=;y?Jdk7J?Nd-GVL$#ND-W(G$V6OK$>QFRj@J<@BfN=i8FdSofE#!N&lJIn z4Do93q9<8x<#T8Ypi_Bl@YC5hIh;p+KE_Q<`;DpG!%Y>^$Nqm4U?M%N`*-FQ(VwlGFli!!TroFDmd#1}< zFOcTqIxy$48ZgNe$K(BK|BxpIzcg}!E!B$j_=*0}Zb*#xVc|K-wNskC_X=nMLA}qA zY*9UwFvPiZ@1n)~!K3BOz3Fa5u4yd;2agdkC{uf!o#k-Z^~Z(s+aOxdAr9c_ixwd} ze!Sv1cJd6NjFk;{pYatX|M9gJKL$?PnfebHPy2BJBw=7ni^Vw|MqJ1QsYS4Dn zoK#pN&ji42Nt@GN?TVWjvKv8JHpzW!GG)=v@*NG)OkOS;XK2S@}>LR?5L7i)s_cm{&L2D^H2WudIe#1}#Zz+JGvg$Y+Y;5te#-yggZ)Uz8xHKCgR zvE6&|sOKBnb+C(pr`_GzN$*T!BmVTgvVt9&hJL4StMTTV(DU=^hdgk8pojg)bN|Q) z_W5@@e=4-58%=5*2HSfZJwg`q95Bu$*q*A^tQxfMEm3Hb8hi2;M$=NyJ>wEF{~~kB zYmW7%F;_11f@&f?;W5|D2vLTm^O&X?;D9WP`qM00qNQw{Gfh(-xYK=RlkU;m?+sI_ ztoMWLRd}lgMmjmnz%RtUyEf1<(AC5jp!UVE>&OxwMcjO*J)=d^h|OpBKef0Vz+wZ8 z^RSK@T%W51TCOmtFC?bx(&zN%D&xm`_PwtQ_9U+*fQ{Hd*w8dJGVgcqclXL)-3bsq zDzZ{ISxO5Lu6=A>I>|mZY06UyJ?2SgcX7Rk@bWlD)^UVZJm@l1-UpVQZ%X!V zN2xii+jvPqcP`do>CXWGTT&NYBh2e}NUv0?^xSo=04rCmqeCYahpn*lX{jG+y_mSW zHdTYbyW-daup9{TzJQp}H=VR)v|hclHDGMsvASgVFw-Yz^Z8+Y5Y$8!IcfKFL!*~g zJJRXL$t+!Ptr#$LarcE!F=P=ITz&?vY`qC+?@B4G`A|A3V4^NW2JZ{S0yHKFw`2cxNlJ4NHbG@v{8tz!XJz~nAd76J2twT%RA|^mXrY6Aa zi;y(P~#;h3K5vVcwPViyg^gXpp1}}?{RiB13m}!)5l*x#NTcLfFnhj z#7h(jg*FpW2i{RZb*gAfL#=B2sKZwC* z?J#!(#MP!r)rKZNU32V+>l`tv1a|!B7{P=wtnJ{9!u|R5N(=C`0slzcZFM#s^(6u~ zd|7Vw{J2tQ)fk!MV}KWQ{rXChDY=tekv%e)cnMe3xbR47U4DeO0;UtF9fJq)6&naY zDm1z@zzydyk7t&xyypB69n1@x zR18cL`1mInJ3pd^y@3bx&oqlNYsb_%qo>V~sO|iUCGNc?T^wt;+6&FEET7+(m(#Xs zE(Y7q#Jruc^MwVkR8jHp3Q2(D54NwBz+b|8a3Lbiu*bqKTbwiJ$KVYj-^a)aem~RS5TPXFm0NO-+ff1JpU};tkD!q{)-xMawOUJvylA z+Ix|n;nO6qDJgh);+}=tr9m??#1 z45-4NF0lD6G2C0x!l!Ii0XEc{ew^IqI7D9E1~AwC891_^c_Y~sTyQzSHSgbY^d}`M z6jv^mB6@3q(@&d2(dVf&k#tt8x!C3=tZ?tw$M4U1@#7EyIeGcdtLxKRG5%qPy@pN= zN5shY+7QGDSJxuKlW-z8Ss~A}dY_KtmCIi=>T(>Wvwn7dal3xNT%;>y)tYMX#s%Sj z8IB)LBQJqdw`e>uCSp(86?rLV6Lk6d`oqFc*TR{kO=a;OAf>;#(u>5Dg1Xi*R&NQF zPgnN&2F7FP_K=ay&9AJlh}w_)s9$)U)B(L3v1wkdR;%@1<{P2MF)E}Zl2Vu!1mRGE z2yj5x6!7A{mHk#ED3UDFagH`e7Sn5ZehfOrMX$cZ?yz5hTDJv)dxKJk%J_ULEU?23 zV)hnZYBEK4Jh$1{<+)qcyaaUZr4ra8n1{Y!sESKWR5MG)rP3H4bVzo;F;TZj6RR=MvLw9k!{yM0|qBS z>EoEQ5yeASC|(I{$Qr;iQ~dehuo=l@vRdgK1R6WLZ1B3Dq$EfJ@Oq^(&U&H#RKXaF zy@#*&I;eL>$l1UUf;4%D`Vs>WV@el+Z7VB^M6b zSU;vxH=13;bi@SKAC%)fnlPE;-^=bdNx_B*WGnlZ|4dv6x-G;)gwn3)U4(anFG2{P z@PHf42F8p$U2I3YrqwDI*3mSM)3|c5pn#lU%He2$Ia^vuftpR55L7GB`U5=Mq25bx z6NyK2TWd?Q44(@^6V+^dsf|9Ji8cH?%e-9ow7wb>E{GSFSgxBPO(9*O|WD zaq!BT8S>R-E}{VbmH*@#t9)=6!VM}HiR(Wdlr(j$TD$Yg8rL|TE(;i377>>Dux?Nd z-Be2-j^8e}P%$!lp&3i<;cN=4m7oD?m@f=o%~fCncu{q#mGazht!b)RN@D|~>}&&h z2(`y>Mj>u^eH4|QApW-XZpMLwa_@Yz@5~K%>E_-?Z%{gpG(LII)f#cvZN&Z-kr+66 zmeEWJylnDcm%zK%PgqDCjO9t~?+mPFY-O}H$@ShXmS*^YX+d8(Q<+0ey(2df&gO3?Y9KCxFCzbaP?^ZvXR)4f?`c&Oq9HNS8vjKjUtN#9|*?Jotb~mxm z)7Y=lJG;Db)Yc+&0F_ikeq+U|0CYvHI$y385Y5O66u?^(82AdmnQhm`=A>h_9YL^F zaQ^f8Jj|76og0^;g@btIgwI6*pUiqkDeChiR60!eE3Sl+tJ!f`Y&9$*JL5-o$1@FCszO*0t#xj z(tXys5)Y|$3?Cb$W~cj?LvS%O#jSgF4JlH8XCOZbds-6EA32`;B6)w@e@Mk}J2UUEL=e>DwPORx7RrjH^B_>l1pmm#hE~x0Dfdy z57_(VV@G)xyfxCh5L1bisOVxGXY4${&knOohl{oPq$O06RVr!I^<~%t^9+Z|t$+12BZLM8pV6hRuy1IF5pFEL;;AjpEz9R~` z$Fy~bVl|DJSj%S3Dr<==TWwvy>W(8pdsh}6ur_abz|%W|k6h0BHwa{Nj(bd*CaWS{dd zl06vjiJSe5(sbhFwZZ*&`l$q#SMLi_8Dm~X-fJ65V{V<`>#yrowU=jur(qEL!qV$n zy;^(bm!S+GcF94v)XOTuQR}C|igYPv}Bya&n*pS4$E1OPyI z&5NsoUGG6KI49_yGFMRBF2APdVWfELoz3%*4(hj=$ynrg4!ysKp=a_LA)4HO9gKE6 z@Ni|{m*8|{q;+6(S)056jkgl7cd^gVr|vgq)EL|i&N>l{6zBjGO47~xa}87_>}EQ3 zHyHQIuyZaZq&HId%=l(77f4i`vahY$-39sSfV*D_K-92HsrD%qMG}Q_z-9GIX{TcR z5frL2}FQ2_w6@xFa;ijI_GAF#lltwBW62#V;b+^_0g{gdNb zH)fM>aTDKI#Fz@c&r#Y$3}PIylfU6I$V{saJ&1^^hg~cpbN`eY?EN)VGAn5E`JoN* zo@-frx3oE?H~eh#_Q-|ZI=kQ8>8jXINyZM2kI zz4|!#g&yt?CO!A`rOkLvkLTJb>1fg2Z7ymFdX;>_3IFqq9R>g-F)hQrwKkWXTwy-X z&Yoe$CB#QRF6ims1zz#g4R0u?rONd!vatXuxiH%U<6gwmn-(UGe?w_4mOr;rBFA!(lR=Fb#o;RUSGK#n8$LP z1GqvxI}XROAR!!|jClZ?5QkWwu&f^d(@sgO`{No9=GEtj#^MoG)nyOzL zUDA}BZEXP!q`C&DKcGYsQ1!w4%O8B0{w`+wiw!87BSVwM7pa9}p5Xxc{8QVX8Naz| z$TdGWQ3~TDN7hl#u&XXH+R!n}07*+E0ngOUAE$khREuzTD<6?6IMMs9VWpMfUCS}B z#nrpy$FU-;qU?=F&C`T%7(sz#e-%dzzFwq`5t2=|R&FSvy?F`=D;e_7Dk^aMab&n7 zdU{fu@>lOHuA>%xR93IUT*eW$-0PQlyZUP@`y8YTV*rGAXwX;KusfQ)H7laM)=}!a zI-bpS5sBk|b1l6MY@1$^^g%vwcB^P^c4d5~J3D)d|7ay4 zE}mu3NJjKKkqJJakGg1iST>tsE3Ai=+?b8dc}Qm^JBkoln-%4BbZUtE9$@Y`?V9~m zt-Pu;ld}I~y+XNqo9P>l{>u&ZTc`-PHlsN;&SM+yZAhFTL7KX`_v<5v*6$q}3^ohn z?IvMXm_7}$>|kPs;ecrs+>RiT#1SG`#}~KG0Uw|^PujVNbM`aD1%?}h@9udy{tn6J zh=orKoXzTum~5ME=6%CkO{y`%32$gQ=kmP76z?Um$&BoF-aPg4AEhwv2`@*rp0KHR zW^IN6Wp6YcZ+=S_Ko-mC=QgZ$SO21?<;eN5`o`a@O)q0f@<>>ZQB5?(v%OrY0ma`a zO1+Vx0DOc8-@gT^W0*1XcYeDn|6dDWt2u{+(Ov}wqI_Cd%Ele?Tt?Sn71y)*Up{)nWo%f9LUS43}1SE-xk^j9r?q7)&f zf(^sCp#iA*_|tMH$r5YLz8T7B)>;ht>f!}iQ(c!?>3X^%kSOEr=O=`sg?(Hl*$mZ1 zI=%vuj$}+MkrPeV4?2&T!77ysSx1#Rt=#ql{5!)=tgf`|xm`aO8iX;pV4lt*<4W+H zkh49^&b;xCVmV0}^_Dw-3|Gw(rhk4$`J{6 z*Fik?&En19!k`iZwaK}wS?rE*ZuHNdG~pc7vxy<%NB;+qOlrTss^>M};r>+<=>(^Q zM+^hhwtZ*W>E7rWpNsTwasc&Mkbq>ux57m3=$X51#)3!FWbz?Fr`C=hMFof&FeR^R zrqfQlEy{Ma*%{IvWLWqEvu!{fjs3+ypDpLz>lAjnG~}6mP zsT2GU@g>nJ=I3PhiBY#VW{^8u&1QO|ybH4Gd8B!M6qSQY`j@|F%cjRa&vC=QYJxmv z#e8BO#bq*kNF0PNW8Kwr6q3RMyK0@X$0{)ac6?6R`xvP7Es zu;hGi5A%xri14>=H#Vb+xbD}&;kJEYg|s5yuReD_0^GfP97}v+a(k7}jpIj2p}PD; zkYh=?Yi)pnqfK-qkLHq}<#PTm<|1E|eYEM41m<_f47NtQ$cM zm-mC(albW-RFX3uk6Bd6BLI$c9==-%MN(&C{SoE-_K_i0lJ?IE)1uR8Hi%9*p&wfx zRNMrtPN$0O2C~3$!Yf+zS&B;A0*4Kbtib#qQ?R68(Uz}_ z$zn+PFbsQsYi<4iK*ElcS^T+054E-Lg zmr2LrE5A7M@m`9%%qI*8_g*ZnY8;O0Dq2Kf=ZW*4U|a}dwQxa-v4h=W0<$k9dYL9S zNn@G*LrZDumGp@1`AzPP?Wy*%Hn+|n?^BJWo(|$oG1HpHq~{pM_T_uEVbQ(6-|t}v z`|}Ah93EwGQ{s}wzcjgo%jsDM+MkfTi{MQ;0zSQps2qLmas z(+S632EMc#X)syr5?tUepIZrdvzH^(>H6G5S!dx}pkr*6h~M*g`u+`^aLl#7H{}~@ zL~RZpJg=`CA5#qI%ZTV~)XeCZI_kGSQ4LsBC#7b~`6!w0+0L0il@Q0EAt@y%h75G3 zZ{s{@l&W5^Uu603Kc0*9em#;5)BS!<%HJ?L;0*ltmxR{G#ukHp#cgD@eGQJ(}${9&l%<;3e?8!;P?b0pYO8 z+BphD5z6+p=I_bK^c#}r1&DRo+KJ48jE8oQamNMzL-jxb20AwI0Q(25K=?DNx0`Y} zBwTrKCOt13143G0sayB}t6vS2T&L3x9$M?G$7PQ8cwe>n)A=8Im@;~mAc>k=&^<#9 z^9zdt$8Iw4(T3^dIO5l!y?^S!3?cWSoG#d?B}eZztRHKr3+*R$1rB2|%(h42VAfV> zYMiiMb#k@yY!W!*_?-ttaO?c8Nwli38rTqcLZ*iM9AG|v@H`DnWgR8Kz49~Z$RYir zG_@d#^Hx-{O1;4RKZNnUL)_FH91D-l9+I>y{VHDDDA*asT?tmIi5j=&Gm2F@L@ASL z2hl&c7KZjN<#}xt!CdY)O-vZvUkqRjOUxHu-b{l;3teH<&E)b4-wIq86j&C?MtB?A zW9^p4n3RG}C^Mo6m)x+-yY$tn5DQs5LWx2+;tkD`y>9u76%*!k^q)B*t+9tW?BC8s zbo3%?H_yN~DPv;Wz7+w}b|mc#nJcqrNDG$R@4Y=-a`PWtF-JB=LBHPX^Q&jY3wbFO z2EL}|U9NHL-Z9&f%1aZWVPGGI#oNf(zry zb;4FQ$4mi3kjmKEl6&32rpAM?2#&gQ^b5-Wg7IjGtYPTon$_*qV(!x!@p#`~@MF8i z^QCd^g=xL6nfG8yuEY@Z2x<)t)&ub4{E%b6$fOg9w+}<(v))xSPLB_!hM4 za2wL|syV)r@9sNB_a&;fFyBc18km8z!)>TvxKrixu!{kp!N^64r~HZdOYOaK#afi* z37AjoZN64Adn@5by4mq}H)MG)Sb$U+s6}GQCa7j8bNa}0nHU5Venw&LINd!z`Jf>c zleYtq0)edajKdvli(LFs*KL#ia^~)E{R`Q7UR8&>LR;bHZRdTSakY>RbzUGd1~EYQ z$$3&VZb67Ze@tgSyo7||MXF}C%;j@jy_uKWWC}oaT)?;_OCt$@+am1i?--;L9bQo2 zrGtBZi5KROd9=ts!cF)=T$=Qf(BY9uVC>#pD$&SPnEGJd9PII)(XsSn&@Z+1Y9In7 z4lK>XM@SmBfd|)&v4$BaUp%=Cqn(>eYpT`8--i%cAD^qVFEhg{=U(grK#d!;jAWnZ z=m^92y3wqHTFhkaIREBeR(%JJq!$ApM&a^5&`W*sX>+vS1ENoJvP=Hk|6X(vE7PEgg6qLks z20SU3=8c+&uoGhFS8NxaLnn$`4QlmkeHa_)^($DJmWjlYJoK6+}{DLI`OyZiRRRH*SY>Mx~w6G!SFY9z>RD` z)X7ZhGN=u_Pd}sX+4P$p9TcC#HBUDK?k9)WY2ihfEJq*{Mm7H2me`xk@7StOmb8<( z$!o<3O8yw_Ao9wSJ@hBv0r`3Ww+#j^$ZF1~6*ym>Rd>oYsnwt@g`C%<%+(bXb_xq+ zi~Zg3j$Ka!0=%kfU7|u~-WlI%4D1hh-eE`eeCemCT`?OdoX$KOgMX9V&IzFxYEl1^a{!Wvz zijqD6_dm*70aO`Ew24^1SH}F-{D4PY;hF1rLk>fJi8Ue5YZErNy`j(Uv0?J%R1m1Gf&u2DF%QYWIHHaN!o3DXBA+JTI8S#w)!AU4yC~Ee4`*XMheyFhTcd`G zR#ydjKGA{pRo7mCx)>*LRJ~yB&+&#@I^W=XG}G)o>+ie?Oc5e>{@aYu(32AXZ`S%Qa9PrgtKbAxyYW+W&baqKFT z;ChV6ND1x12ajGmj3J8Z>DuN52-?kyI=CL%Q@3jlEd><%+t|jN)6ub|?cTk2Y zn^V!(C9b+nN}sb90tj|Y?%G!U1X4raHW%_T@=KusRV62=rSg}J72ROTm(;1Fy zVa}TF?FaEPKN(PGvPk0{+6j1GM6RB3$*bO0#}Xx^t_P3?#Cc2HABwTN5EubkND?`;p;VzerE6yQTWy4S>A^ zN`1cL%YysYqVA_8tR2p5R*hh$B=yD`C9m~y2jJQ0&#y~y#wU(UnaV(Ja0KVuV6q9c zBoYaa!WyF2-_L$-rA<3arVqDY-;LiQqmwR}1<44M=>fXzc@rT^42>SjcRoU>>zPc* z@Fc%-nRM}NP0&=LKm-e%((0PyUUBHh8%`>a%fAXM8 zWj+oul9{r@yzCUJZ^X(kc4g+3Va>SC^Y^7Y&)lp5?BrbHO;Hs!@xy)NoOem7?m821 zm41*UaaLMW;NsHcm*iZ{kDnpWoh9P%A1r&#$MV%#TrGwQ(H^2b!}HUk1dFy`sb)L` z+ty-Aq=y<1hv6LmD*X;TIY#y=d^Ov$MSw;upY|f%;iW1T)^AT})GbdJJ_J*S6Y)(A zGnwYA;w}mQbRyO%AzqHJdE@{A{vO~gi4+q#noKLmY`eZB->o(-c(Nx2v8GBmd~<#v zRp{#0B=tMlMCgyH*eaHCntk{%zWZIA?Sc$OXDBe)m8=<*B&j6}#Fg-?7 zaF@sc&>CbSRdc6qw~_6th`MH>Z9Gy{Rvp>wUOy{!`1ZFo(&N56=4MhR<>2XijhCQ+ zu&?a-W&IPQ&O;m$Y!mBF%svja8~usfm+2pLoFWpeZKne*cj9Z4ySpZ0b?tlz;N|x$=bRlsx zSNcT4{5FF9U{)t?-<5)`WEmr|16_ZLHpJaf=2@p3SiMB4LFS*SOMT3rt zK?T@^gm*y@p{xaztPK_(LV$vcQ8YyCdR|49H{ghD^*j>5wFT;-Y{N`HS1Yzom6wyF z&3G2`L*9ag2mVb!27)x=pFezf`VI;$->&~gEJuZSn2s(PgM#)O^diZvpSSnNn5a|a zMxK@6Yl}eP!ntUpQqq#0s39oI>W*tsrAV4;3BW`=%A8VZi)LI0b-r^KQHG(b1A2-> zOYRKp7>B*}##}%DT7TB+i}|m3l2w$XUBM5)m|6!8cZi!hOBZPu?j9z9Kw~L!ToBn$ zi4L=K@`u~kP?N)xdo^DAIHV7MhAbG^5mxD(p6IDZzLHlnbtOIwPJ~vvptwboFsmg+ z#_l#wCpGt_6x3{Q%rJYntXH&GYE7^10_=0~bG`9x zqZNHTN$*b*sD8x-Tvpo0LNKd+eA|V#UsN>BlFT26I-x24qRY*$5rd6cp9CL)Qnf;< z5^QCs2A5&r9f2gg5(Of0vK?JsjuuwJm2w(ssqu?>!04LiZ4K7pLO^04WI>5Kya7Us z8ICj@9~SfSMS&aXLMqA;BT%%9J!j&Qa?KK@qzur! z15%K2E?GJ+@iUfmgTivc{qiFAE;~<=uxZpix!apnUdUEg;wuo4l}_C{$P-{8Xj$D- zhgy-mJ;!77SHEj1O6HPTsp0c{ujrhkEF$#NH8o}asL!a%Jp46H;vg`%GubNH(2PGx z8^u<7lf0!*4$Xlg@6>0nHMzM5Ta51ehNGhR^OjW&cHrxw0GqpEc}Tbb_c-VeSsx z=&Eu>-#xsKoEc~9Oex;bEzUn#g%w`H9!GVd4{%~51xERHWKB7_qiF%K!!#HKBqk{& z>zGTgwc3(1lh6JArlD=9tEzj2*I_Ll^!AbZnk)+QTtL>l$@P1+>djA(k_Fp>gF{5^ z{hbQI`CZvcTH!41N;Iqqey4qTFk|rA>9j5-uC!6u449A!89g+7S5TE!Xd&CCcRj!Z z#z6bC_l-u?sDq0KHsZ$fw%!{k8S_D)l`Px&bCYYheC>W3z|8E613a1C>zjU=dY8{- z5pt+i*;}Na#txvCS*Z=P-32e^Ar}kTxcK_}9h?3guqBmdc|4LEK>K#}cV`rj+EC|( z-W$qa@e0wO*RQZXo$7l&2=1Nc$r^(kac${#{PFjzP5IfoZr`gqwJ8k@v}-B$`UZ9obTMLGvmzY+r zJe}`ECyY_k`wPZ2cj;MUZs^u6BH{3lH7aw|nOmerC36fXx1t+}37>!2LXW$40W2hB z83HGh&?2{t{R4RCa|? zarRPrWH(&}cqLnxZ%ut`!FoR-nQH0NO58083GeEb7H#Igi{x7Fp|Z|Cnb)AM#1DIX zEjlN2%bb#-OI678EdWB^U5KGr6DFvAheEuE*4-A+_VKjli7v&IzjiDSE5Z&G#)U0> z^bTBsm0S^54%&`4jjom?KDw0mvXicw)_Z?G_@)S-g(i@aj$!8bso4Dy+{kF%7!{Sm zl!7s7#;vIw1YjU7My7HGm+;ca?@^X^;o)H-+C;_$iI8IAF{!`L@4qe;QOg;GqCIZ` zr$KZ4eI+$W8w7W!AN*FgP(Pa=A_U4W*UIqj+Ub1?iM3b{uT@P)97xoTWbdzOQNqae zY8^H3)Kw6_>X_4`8z6!*8;GTnP|(66%U4w8MJas9Sq7OikTy;FUARuKIW+0(pxbTT(Du!0V{>JNVnfcyY zi}Cdu4BqJ%l;TTm$TBbgO`w*h`BV2G2MDzBTnLLsPnBp=p><#Iemf-f1L2IF-(t9< zi^y+}1UtTNbs?fZkV=j4)-j~F*AIop)i;;Si3z|IH8B_4z09zxtG5yU^6QE!s`hgU zw1@Yu5ogQ<`lusyww!YkPdRW~OQ)k9kB&+ZnaTJwkjcydL%m}(#PqCe#opsoY^~ck zhKu85_LgG59&g=1DM+04e7#}#?BjeZ5$D2cUo}s+(ayZr_Y|hMyB=5-#swW9dh+6W zR6p&1&^jLQGWnc6&9Z0UJ5}AF22Z&wK>qRNDW8em%J_-l7UVDCxGxb&+XDV}hUDb) zz9LOXrT%8Xnaurp!R>wmkbh1Gn>|ofQyx62!GzA5E7;`>P44|YMclVMzYi2C(=7eI z-zy482K$$ZI97R!majSo+mp1N))Vm-g1xL}JgeF05pI&_auB!L6qPG~6f;}%Wwj?~ zk@$f7PkjdUk98k`b(#p?3C(3|I-_~1;DUj2Izm*Vwou>=V^qtG83zp)S#FXA#X<_L z#>}ZJ+*M`Yjr|&vjgQ?06z&JOq9BbYE3t6(Yl|O{OJesP;pzeV-$BY9JL$y5Rcp$X zXdV;De{0!Dgvh-o>UT9-+HzBo$z)M0^SRJW&2m~&56Gp2 z|6O8A#LZ6mVY!>h3!JgAlscV~DCoFEv^9L|>-}XjJI&X_%ts9506Hf2uu@UAHmBso zQq{?wa|=OaK<0Jd!onAb45`gNl!(QB#0DGy*lk-%h*wJJb}$y{G4jXj47X` z;Vf_*Q1h}H*fNv7ys&qLG{cVf=lZA5P1A7roG97RixnYs)6wuB_D&oM&s%zi7w^|P z7mZP4!}peYE86WYhB`m;9q~Z4Z)rI6C@akZb9)ve?NE%gNzPAA>!-`kHQxE+Uf}(@ zD_*x&&PWVFd(|t_1uN^^L3}9|{!y4{FC_$sy(L&(qGeLLQk@1PYM8$15@h?|`q%(M%pm*0T-o2>hzi1}W*G%EDzJ$ZG z)1&+A0c8BZnTA=p|l%4TOIlEU21*Q4ZE1%&h{|c?fD|DjCi`8`9^*zNfd*& z{lXaHGOq3wXhVEg$x;50nOHAI+Sb=T%*7XV?F4II9^Sr%5+EAcb`v9Hgfe(9oux<; zckx&^OxiwVj`6dlBfSL_$fStVtxRejMia^Z-0SPWSdSst_TLBzW`QUs6a*sOla~_L zbYN93S@>WnsqhASpTAP!(x$-f_DX`y>a*7~o-na4V^3Z|pxQ-Ml)D%ng~L`jJz#)k zeC5wrKJ~g1O!)o{dseu2c=G;S2$pF!wZ0KeNw(H6x8*|}FVArEzC43WkJ6Bh+9MzJ z754YX%o58x;k}XaDxC-aQuQsh0#6BVec&Q;-)6#;88t=1=wmV@CC93`OnToVU2N8xw(cVv~9h+3xdmxUF6I=Xgci z&Aw>-{k-X9!${Te-ILw5((1AJ?*Aw$XRuyq+qa*Ko#-v4m^x&UI8wAWMY*0V%q?CoKi>tbXgV`4`fc zo*e}~dC5?87-{>a;IKR^romWF<}dON*|Akk=k1m3j}*Q4yt%&g;P5RdY(+#cg+;|~ zJyYUbVyI0=r!OvN(??_e;(I}R@0q83Ds3dXN5h}4!>nIoGpfeYtdN(K4u&OD)Khtj zAqjSsb{o^Jm7AR;F@R_ssD@!dNvS(S>3!~Jf5AKIjiN%mklM$3^3>jMUK^H?fp?eZ zICwe@prbk9a+>SZ6dgdTq)fhJ{s?0c3Y3~ z{Niw#95y(eG!ik_m^D*b#9ziTiy{YchkHoibvG!_)6-2JhS(Azld zDLViNfzX<4h?_qCJ|_2_ZuYP|)=)PY<$qGJ&|Q)pH)mY?=OXdi9rNMQR2=C^;T0`B-4uSVSdL7 z>GP9r%-X*KOxv&O|0<9AZsGk7DyUB(-M zFa0ygZvQw$%AZp3gJE0zWLPcWKPAYq6n>0kZ9anXE*+`Nf>~9X&M@M_-g-06UiQp) z6c%NDD1nmBZC^yR_TqEIgdZjR@(k_ecYlZVF_FqMTKGaHjIeZ7?l{TIcQVzyaF2AV z`;Qy~#lW_=)81{*53bl4v?gQEC01E^3Z`{mEf}MK=TDN~_uFt0b5rV@br2>BD3}ez z9-uIr3+$o5o4EM}O3Za9LX_`_Z<;y% zlNYtbJ{sI>UrxEC{b%&5sMS#EYH@{%wxR12U$`g}TxZ~OUZhpH5u2cT_C`h85mWqN zF1$O4m*W+Yf|<=Yu+DXR~eZxLXfZ zjwCb0HfoXJYvn|2Jsnq$pXZf!ojQbR*7`$&uu|;^bPG10vyo224x|d-xqs1x+*pJ- z0CmH`YFt-YYJK|A$;V84GK=^$rs~18h8xm`F6&eX0gT|??_t3M?cP<_0xN$#xYd1s zTzi_MSZKYM?&Z(a;>JnNjD92_7LNN#z84%l`=xEBLTU{V^@B26D-UXf4%#y{%X@^{uN!;0W@J!L~!E* z?^zIFoFcFzDrS5p_!;~P!YZnFi+AZfs+@v2<0OaG80Iy%(`>0`5qs@Jsm@Eei#_Ay z=*O>(crQ!so!Gmr-96J5(CIp@ zaJ3U2BThu^VHN(0dEolaZKJ90?M>^uGD_iVUsd?sWvQ2N&MNYsz(UofUeI{ymO=7( zbd4@|+#Z|XKf8hNf=8Y6{&Z^yci6Y=w0M0W{!^1r4=x>Mw7bZ+XX6tSd$gMCvdb&u zB-tAGCOSep`#Pad`&cOFwHjZ_>q_l8MElG&iev7yK`{pEVAXFlZn7q~#^lbc`7#=J z5lsr!{2AH(fhlw8&Gs>a5!Kf44aXVz?1j*&jkDeD9XX0Q`TFL|gjoe^Z3$ zB2?Yiw}kRNQ+2tSLh4E$8xR7@q=wi==cASy<#v>+u@{oUoyq|k#5pLnGgz+kXxb*m zuFWBdZm#ues>!lFcMyN`%+-zmM7*9ie3>$^D_M<2KhG^(~T(czpZ7 zw%P;`BGtsqiRBpxQQjO$9xHL)u_fGFfhhhkmYt&1M6+~9%-`(d;JMnCm?liMB2?U>tG{}+aj+^fJXn;>$!48_&RFOgWl9{pjiFZ(J}Kdt4zHES zAb@!fiumB5Dwb4!ZlkjE&81*f)p4Q)x%TPRGoUYP^%IA~cPhE4#dK>;P%zh8i7oi|3kWEcG+b}Zc!V(!LW6knV?tPD#OFU;Tl1`DXAw*^|U*udHf&&Do&W*d5I=gzwQHD4uk4x>Rn%m`pZQ0jY^F~t%8G&L6eb|c0cF@Vw21sh?V`+4XAbiE^jwx?}`tPSWf>y&Yxkh=lXF=8p5Am;cZkbY~>y}8q1&x>3 zWMBTf(idGmj2}D8f)IaR0Bz5D3z1a7q#<95Hkv*Q#8kbt(|D8@KfKEhgxEpJZ?B6* zUsC)i=a188^3FK8k#U;Jt=Qa?e=31a(Lhtyk?F`fLsY{`_G%-lA1Wa0Sp6n#+9@Hh z8&Eto5`^cBn{x(}1yVYp1oSJ_zfmiVZ+f%L-(E6RRN5rn;z%qYD( zbS}1nl_^+qqe8UCa)ZhIDg$ghrVer{Lk0lLT|~wq)G_!96E-3B0n}Z`p!SeXF`x4GfrNV&wc2~=?(M*T7xhIo-z{W50RwnRISu< z`YGVS8+#?*v>KC;s{zedrzjd5ArA0_>G`Ms;+Jui6Ao9v9V+H*RtFqWAwVz!)D*~{ z_P1i*PAQ|lK4-_k%f~e>vRCUbVenhvYVaP|JlR{~8^G!x&#M+GV(Kq8&my9lPI1_` zBQSYe$rR2$jg|gV^aaX(g90q%SyU6X8(guPIFCQ4?Wj-spDXNbhrN;k5CB|U=gH-? z-R|c*_PnLon0156eCAc0hQsmu>jzQkGUb}7qOnEux+PAFy^XS8Tf@tvhe?tJ15H_A zK+`70Fo9c+KpIxc>zQynDY`Jf)rMEm4RXLH29(6kkqBmKces5BVmsH>rlg=k4^VYsd5vXV znL`^5W3j&g-USVRZ4DGneAk+#WFMXAOE7TJneswojIWN>OX`=46o(9sgtfu>bt$|c za@*xz_l#&!RIA@AV-KO}mHAoV0n}PJliv}0ca>#-5@$;s9B)G$gKc^=>9m|r@G7>n zo#=sev~H~Eg5+lOGC`a21WK z%HR3*L?gPCtJcXHQtPzTJR_PPv`rbL9kN8}(6l-FYmUCDjQw6@(jp&sbEzf5CISuo z?bauU{G&!6r2WBTsrgg8c#|fQ53YUXfAD@$RPsz<<1}F@O!r8Z&#GSpq$naUg`U@^ zTCM~~^oXC*u;hu1BTwU~L`zmnxDTvP+#A9KoX%DFugkMvTW#B=kj_1f&Cnt$psdN`<(XXBM}-)8GXoy%Ui3 z2V4YgG~7v)3~vsWXBNi6<(pzs4i%;NN?xRAcNGm1-$~&};8xzBGi*7|l}2Cqz*i_X z5S$%GRZeXg>P6a@8)pm{m}U=RV^U!q@wTYE#n7;?n&~bibd{o2+0D4xKTBy#A$6&} z8{iq1N|)n?A0p~484h{xtI?$9hj|W|iHw;yE*P}(j0hy}Ez30@cn1_AbslOd*)WP5 zwFEvBoXiR9(4uu|Aq;VM?IU!c4ZvfSKzG0`=u=$vMS# znc`V4Mp2`M0bA=(&>!0)FWO7#CbI~K*|x9;I0e-N>CVdJetvE+&a`*Ixtd|pb~$tb zKFJK(m#S%C7`W0d{}fk&s}O`eHFX!#XvKy1;Z+>|(!^N-Tk3_LfL|3URIf})NR!z* z@pNVS9OGepw6Swct^JW&;}{9;cZhaesgwvu`BjxHr$zy-2?uDzpSRN1jdmKX%JgPj zL6c)8eT=Z&bKJ#y9f5oDMbV|+nE=1m4^gW?)(L!w`qfeAMx5740Ko_&dc4JJnv0Cfo zJigG77k}9>Df5u(0{Z?TaDCUMXnnSwFg2!rOeJQx(DspC04%gHha`+PD@)qE~=QYt+srbN9G;frqN%4@V_?X ztV;Mb&bc(f+;53~8RM1VCFb=X7pq#kO1O6HoP9XX&xsq{reILIAcU!@zT92ewkn6G`z&*8eu1XsMu zLfpE%2CkO_84bk!QIlz@e0!R@hA+!V+;0Y?&N1?_hMLB&uARB^qRPDrnm%g}5J_7* z7vj68Gd8p|TaL}zqvrFwcL~Cd-WbxgejtCxh8l)yS6kr9WVrGsSS4isM_Sk3&8QUo zmT}|hOr(l>n~2iLBO#TuXOpPjm#N_WZ&76^q7GEv z&CzI{kLaMkHk-_lLL00-gns+tBIn1bne4*LV)P&F&*e5QFqfUIjIvplj87|8q0zCv zB_!|qtyZuUlSbm~=w^9?cE^fqKD@1p;0V{Qbb}`BjYd+`bI8_Xq(z1I7qbywyj?_X zb7nJdL`d0zNno)k72jyfp?M{W2K;K;how;>ws;K3V-HWztq>{bc5Q95@6>G0P)nEuO>Z2i?y$@W5R&N@oA zg9(6)xE<z>-5!18XTm!y2B;iN$(wz=^7T9 z6?xe=$GWmb>!Ugx4IWGQxW~)j#2~|v{uHB;i-?zVfeUgn=8`~?{M$3cN$&p z>n(gBWtt+k?di50^yl*<{r@q0S9oFY-WK}`4;ZH)E}j3^sSi_#@f(GA`Ba1n2Y$?>*Jk4z=));rNn^uX37POTQ1lwdA8!@vC}ln3K`@Yj$VZ z#D`}Wn{48)V@K+0F=Tk7r1>gMaPK`~I)@wYre#I`htE8Kz5scyVT8;FGl?@ZsMnts-@3uSOSAowa2^8)`$?@ z4XnP^0TfWS0V4I=guX~>^^^I`BuAx1gk9~G1O47n{<1BNI%xV=T=hxZ}v#04dsm_OD(@* zhkLZ*sQV5LZ1jijO>k_MT1o>MDoePx8_Hb!z2m)+6A&W*ZmF2vGD;GrFRgawH`*KU z9%h5v(&ns4HIf-F&4@T+3@!bof!}Ib=mm9z$yZ!^{=wdP;?3ww1}Cui2JG^eO6d8bsr@mm=9jC?Z5l@X|WGNXxFcN-83gfBlurZk;RHib!m@Sj_UW#@cs?r$hW~ zKK~Tao&esl+Q;O}18V4hD?3d_6FwE7o2Grjr5TLbGw^WS0Mf;=X47B?NvKTmh;uYF zvy5==krZWBjkIO#fCM~(4ur(}HOxE5XWKOURl=)M4oRff2v)3Ia{4K#8j1OT_E$JS z9I2@oNh-@irv_$Yf7^eSu0FU8aKp)TAY%N!6v9lHZ(yv$jlS)@WNnLS!8@}7#l{%E zz5Q}okIYh%DdJ@|TYrb#?O6F|lsad~avhuLnoTN1L!6xV_|%U!$fd2Uzor4!7nz<@ z#wgVGZ>6r>iByEQ8peek*N?;#9^y3w+i$khkMwIYh zVaji_?DF|$L#&KwVmfV2MfWZdEthCtXIo`0eB8vJXl)Zg4$EBid0kG&%hHiVo)L8V zF9jOc%YU)}djm~S+=Z}N=&yg~h3VYG+GH=hu!{KZea96$3IB>uz5}2cco?ZaC1c@< zE1Orl>tB!U@s49{OuXx`V1yeaXyQ<@xPR;+HV>dXWBRgM3DYSpR?3h-)aneejDYzF z_o4aO_+b;lRn3~!fB@Q%s9Lk~neC#VA$NA`8lEAucg_x{*O8U^t=r#aX{=QT`L#E9 zUA@_{9TvY=#}b@nJOUqlmD7t%6WrHrtA!Ij7}X~Mo?s|_l9FS?DwI^ z(giXrH_}$rR40}BI)g30s3lKw|8=+vQUC1JmLcEw6)-XIHZApV)QFF`DV$hvEXTX- zhCY}hfQ2od08N)<_5EjYoLtGlfn@U?P&LnF-48cQ+ z&;9a51|E0vkAJd)K&ybA+|H+OUCmSX3N}Z^cmiX@lB>3vKO>%J{nvbs8q2#ZT0?S% z=)lzz8Htiams>ZV&=qiQ8_-e#rRRXpM4Dq0qmsq4PCc|_TE_08Y0F^tyPx|S@AuED zPh{ZvrB2k2>pU1*v~&I`jy!Kp= Date: Tue, 2 May 2023 17:30:56 -0400 Subject: [PATCH 4718/6505] Add files via upload --- misc/images/monitor.png | Bin 0 -> 139846 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/monitor.png diff --git a/misc/images/monitor.png b/misc/images/monitor.png new file mode 100644 index 0000000000000000000000000000000000000000..8b280dfd05a334af25c6679653a966dd934c0829 GIT binary patch literal 139846 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

    UXhM{f>7d4mNi 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 tLKimM`S%{AwYx_)@fMo-pWgV)>E!rVPdL- Date: Wed, 3 May 2023 10:27:14 -0400 Subject: [PATCH 4719/6505] Delete monitor-lxcs.sh --- misc/monitor-lxcs.sh | 114 ------------------------------------------- 1 file changed, 114 deletions(-) delete mode 100644 misc/monitor-lxcs.sh diff --git a/misc/monitor-lxcs.sh b/misc/monitor-lxcs.sh deleted file mode 100644 index 4218e53a..00000000 --- a/misc/monitor-lxcs.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE -# Proxmox VE LXC Monitor -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/monitor-lxcs.sh)" - -clear -cat <<"EOF" - __ ___ _ __ __ _ ________ - / |/ /___ ____ (_) /_____ _____ / / | |/ / ____/ - / /|_/ / __ \/ __ \/ / __/ __ \/ ___/ / / | / / - / / / / /_/ / / / / / /_/ /_/ / / / /___/ / /___ -/_/ /_/\____/_/ /_/_/\__/\____/_/ /_____/_/|_\____/ - -EOF - -add() { -while true; do - read -p "This script will add Monitor LXC to Proxmox VE. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -echo '#!/usr/bin/env bash - -# Read excluded containers from command line arguments -excluded_containers=("$@") -echo "Excluded containers: ${excluded_containers[@]}" - -while true -do - # Get the list of containers - containers=$(pct list | tail -n +2 | cut -f1 -d" ") - - for container in $containers - do - # Skip excluded containers - if [[ " ${excluded_containers[@]} " =~ " ${container} " ]]; then - continue - fi - - # Skip containers based on templates - template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") - if [ "$template" == "true" ]; then - continue - fi - - # Get the IP address of the container - IP=$(pct exec $container ip a s dev eth0 | awk '\''/inet / {print $2}'\'' | cut -d/ -f1) - - # Ping the container - if ! ping -c 1 $IP >/dev/null 2>&1; then - # If the container can'\''t be pinged, stop and start it - echo "$(date): Container $container is not responding, restarting..." - pct stop $container >/dev/null 2>&1 - sleep 5 - pct start $container >/dev/null 2>&1 - fi - done - - # Wait for 5 minutes. (Edit to your needs) - echo "$(date): Sleeping for 5 minutes..." - sleep 300 -done >> /var/log/ping-containers.log 2>&1' >/usr/local/bin/ping-containers.sh - -# Change file permissions to executable -chmod +x /usr/local/bin/ping-containers.sh - -# Create ping-containers.service -echo '[Unit] -Description=Pings containers every 5 minutes and restarts if necessary - -[Service] -Type=simple -# Include the container ID at the end of the line where ExecStart=/usr/local/bin/ping-containers.sh is specified, -# to indicate which container should be excluded. Example: ExecStart=/usr/local/bin/ping-containers.sh 100 102 -ExecStart=/usr/local/bin/ping-containers.sh -Restart=always -StandardOutput=file:/var/log/ping-containers.log -StandardError=file:/var/log/ping-containers.log - -[Install] -WantedBy=multi-user.target' >/etc/systemd/system/ping-containers.service - -# Reload daemon, enable and start ping-containers.service -systemctl daemon-reload -systemctl enable -q --now ping-containers.service -clear -echo -e "\n To view Monitor LXC logs: cat /var/log/ping-containers.log" -} - -remove() { - systemctl stop ping-containers.service - systemctl disable ping-containers.service &>/dev/null - rm /etc/systemd/system/ping-containers.service - rm /usr/local/bin/ping-containers.sh - rm /var/log/ping-containers.log - echo "Removed Monitor LXC from Proxmox VE" -} - -if [ "$1" == "add" ]; then - add -elif [ "$1" == "remove" ]; then - remove -else - echo "Usage: $0 [ -s add | -s remove ]" - exit 1 -fi From aee12a7ede36568fc31f57e7a558d543579f33f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 May 2023 10:03:04 -0400 Subject: [PATCH 4720/6505] Update influxdb.sh fix check source list closes https://github.com/tteck/Proxmox/issues/1391 --- ct/influxdb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 1505020a..7408d33c 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { header_info -if [[ ! -f /etc/apt/sources.list.d/influxdb.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -f /etc/apt/sources.list.d/influxdata.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" wget -q https://repos.influxdata.com/influxdata-archive_compat.key cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null From e72c28c3244bcdb77c2697e528a4628df004bd9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 04:24:18 -0400 Subject: [PATCH 4721/6505] Update build.func validate IPv4 CIDR address --- misc/build.func | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/misc/build.func b/misc/build.func index 3a80c03b..1f3afaf9 100644 --- a/misc/build.func +++ b/misc/build.func @@ -247,16 +247,25 @@ advanced_settings() { exit-script fi - if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + while true; do + NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) + exit_status=$? + if [ $exit_status -eq 0 ]; then + if [ "$NET" = "dhcp" ]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + break + else + if [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then + echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + break + else + whiptail --msgbox "$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'" 8 58 + fi + fi else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" + exit-script fi - else - exit-script - fi + done if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then @@ -376,7 +385,7 @@ install_script() { arch_check pve_check if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service + systemctl stop ping-instances.service fi NEXTID=$(pvesh get /cluster/nextid) timezone=$(cat /etc/timezone) @@ -512,6 +521,6 @@ description() { ### https://tteck.github.io/Proxmox/ " if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service + systemctl start ping-instances.service fi } From 6312591e588d562c9c0d04d2d3e2f48961c6d677 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 05:04:50 -0400 Subject: [PATCH 4722/6505] Update build.func if a static IP was used, check for gateway IP --- misc/build.func | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/misc/build.func b/misc/build.func index 1f3afaf9..d76e1a7c 100644 --- a/misc/build.func +++ b/misc/build.func @@ -267,17 +267,32 @@ advanced_settings() { fi done - if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" + while true; do + GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) + exit_status=$? + if [ $exit_status -eq 0 ]; then + if [ -z "$GATE1" ]; then + if [ "$NET" = "dhcp" ]; then + GATE1="Default" + GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + break + else + whiptail --msgbox "Since a static IP was used, a gateway IP address is mandatory." 8 58 + fi + else + if [[ "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + break + else + whiptail --msgbox "Invalid IP address. Please enter a valid IP address." 8 58 + fi + fi else - GATE=",gw=$GATE1" + exit-script fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - else - exit-script - fi + done if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" From 13ae767e7f394d8b90deca3c1543780744619ddc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 07:30:41 -0400 Subject: [PATCH 4723/6505] Update monitor-all.sh code refactoring --- misc/monitor-all.sh | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 3b616b31..a72300c6 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -118,11 +118,24 @@ remove() { echo "Removed Monitor All from Proxmox VE" } -if [ "$1" == "add" ]; then +# Define options for the whiptail menu +OPTIONS=(Add "Add Monitor-All to Proxmox VE" \ + Remove "Remove Monitor-All from Proxmox VE") + +# Show the whiptail menu and save the user's choice +CHOICE=$(whiptail --title "Monitor-All for Proxmox VE" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +# Check the user's choice and perform the corresponding action +case $CHOICE in + "Add") add -elif [ "$1" == "remove" ]; then + ;; + "Remove") remove -else - echo "Usage: $0 [ -s add | -s remove ]" - exit 1 -fi + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac From 2c247bc58832cfe81e1bca39964df7447e7009e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 17:08:36 -0400 Subject: [PATCH 4724/6505] Update build.func add error message --- misc/build.func | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index d76e1a7c..46069435 100644 --- a/misc/build.func +++ b/misc/build.func @@ -28,7 +28,10 @@ error_handler() { local line_number="$1" local command="$2" local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" + echo -e "\n$error_message" + if [[ "$line_number" -eq 22 ]]; then + echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" + fi } msg_info() { From 353e74f86b55db96407efe02f1e6a9b42890dbe7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 17:09:28 -0400 Subject: [PATCH 4725/6505] Update install.func add error message --- misc/install.func | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index a2fa99e0..d4bf0af0 100644 --- a/misc/install.func +++ b/misc/install.func @@ -36,7 +36,10 @@ error_handler() { local line_number="$1" local command="$2" local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" + echo -e "\n$error_message" + if [[ "$line_number" -eq 22 ]]; then + echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" + fi } msg_info() { From 67df4100199225968cb0b489e225758925149755 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 17:10:17 -0400 Subject: [PATCH 4726/6505] Update create_lxc.sh add error message --- ct/create_lxc.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index f8326f55..c9e09a7b 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -22,7 +22,10 @@ function error_handler() { local line_number="$1" local command="$2" local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" + echo -e "\n$error_message" + if [[ "$line_number" -eq 22 ]]; then + echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" + fi } function msg_info() { local msg="$1" From 5e7a808fb9bbae411ed2b6434fbc7a09ca3143e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 17:17:37 -0400 Subject: [PATCH 4727/6505] Update build.func revert add error message, no silent function used --- misc/build.func | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index 46069435..d76e1a7c 100644 --- a/misc/build.func +++ b/misc/build.func @@ -28,10 +28,7 @@ error_handler() { local line_number="$1" local command="$2" local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message" - if [[ "$line_number" -eq 22 ]]; then - echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" - fi + echo -e "\n$error_message\n" } msg_info() { From 9c3fb90eb87d8cde426698468dca997f98bc77ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 May 2023 17:19:12 -0400 Subject: [PATCH 4728/6505] Update create_lxc.sh revert add error message, silent function not used --- ct/create_lxc.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index c9e09a7b..f8326f55 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -22,10 +22,7 @@ function error_handler() { local line_number="$1" local command="$2" local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message" - if [[ "$line_number" -eq 22 ]]; then - echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" - fi + echo -e "\n$error_message\n" } function msg_info() { local msg="$1" From 1c1f986cee64ffdc3c71d88191cf6c8fa70dea53 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 10:39:56 -0400 Subject: [PATCH 4729/6505] Update unifi-install.sh Code refactoring --- install/unifi-install.sh | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 530fcd0d..8ccddd57 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -17,24 +17,31 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" -read -r -p "Local Controller? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - LOCAL="--local-controller" -else - LOCAL="" -fi +msg_info "Installing OpenJDK" +$STD apt-get install -y openjdk-11-jre-headless +$STD apt-mark hold openjdk-11-* +msg_ok "Installed OpenJDK" -msg_info "Installing UniFi Network Application (Patience)" -wget -qL https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh -$STD bash unifi-latest.sh --skip --add-repository $LOCAL +msg_info "Installing MongoDB" +wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb +$STD dpkg -i mongodb-org-server_3.6.23_amd64.deb +msg_ok "Installed MongoDB" + +msg_info "Installing UniFi Network Application" +wget -qO /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ui.com/unifi/unifi-repo.gpg +echo 'deb https://www.ui.com/downloads/unifi/debian stable ubiquiti' >/etc/apt/sources.list.d/100-ubnt-unifi.list +$STD apt-get update +$STD apt-get install -y unifi msg_ok "Installed UniFi Network Application" motd_ssh root msg_info "Cleaning up" +rm -rf dpkg -i mongodb-org-server_3.6.23_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 29f34c8b51409b5ce4ca4a3618879630c01b9e6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 10:44:54 -0400 Subject: [PATCH 4730/6505] Update unifi-install.sh tweak --- install/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 8ccddd57..9f297731 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -41,7 +41,7 @@ motd_ssh root msg_info "Cleaning up" -rm -rf dpkg -i mongodb-org-server_3.6.23_amd64.deb +rm -rf mongodb-org-server_3.6.23_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 6f2f334a81655cf80a474b68964cb9883c4d5c42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 10:52:17 -0400 Subject: [PATCH 4731/6505] Update unifi.sh fix update --- ct/unifi.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/unifi.sh b/ct/unifi.sh index cb8f2e68..d3876aa6 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -54,8 +54,8 @@ function update_script() { header_info if [[ ! -d /usr/lib/unifi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" -wget -qL https://get.glennr.nl/unifi/update/unifi-update.sh -bash unifi-update.sh +apt-get update +apt-get install -y unifi msg_ok "Updated Successfully" exit } From 7cd2ca29704754452ddc360db666a2fae59bc201 Mon Sep 17 00:00:00 2001 From: Samuel Burkhard Date: Sun, 7 May 2023 21:01:15 +0200 Subject: [PATCH 4732/6505] Refactor homebridge lxc install (#1401) * simplify homebridge install --- install/homebridge-install.sh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh index 573acf8f..463b7ab8 100644 --- a/install/homebridge-install.sh +++ b/install/homebridge-install.sh @@ -18,24 +18,19 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y avahi-daemon +$STD apt-get install -y gnupg2 msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs gcc g++ make python net-tools -msg_ok "Installed Node.js" +msg_info "Setting up Homebridge Repository" +curl -sSf https://repo.homebridge.io/KEY.gpg | gpg --dearmor >/etc/apt/trusted.gpg.d/homebridge.gpg +echo 'deb [signed-by=/etc/apt/trusted.gpg.d/homebridge.gpg] https://repo.homebridge.io stable main' >/etc/apt/sources.list.d/homebridge.list +msg_ok "Set up Homebridge Repository" msg_info "Installing Homebridge" -$STD npm install -g --unsafe-perm homebridge homebridge-config-ui-x +$STD apt update +$STD apt-get install -y homebridge msg_info "Installed Homebridge" -msg_info "Creating Service" -$STD hb-service install --user homebridge -msg_ok "Created Service" - motd_ssh root From 78a34078efd3701702e5dd191ca7f6fcf983a4e8 Mon Sep 17 00:00:00 2001 From: Samuel Burkhard Date: Sun, 7 May 2023 21:04:08 +0200 Subject: [PATCH 4733/6505] add fhem container script (#1400) --- ct/fhem.sh | 69 +++++++++++++++++++++++++++++++++++++++++ install/fhem-install.sh | 40 ++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 ct/fhem.sh create mode 100644 install/fhem-install.sh diff --git a/ct/fhem.sh b/ct/fhem.sh new file mode 100644 index 00000000..13c042d7 --- /dev/null +++ b/ct/fhem.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ + / ____/ /_ ___ ____ ___ + / /_ / __ \/ _ \/ __ `__ \ + / __/ / / / / __/ / / / / / +/_/ /_/ /_/\___/_/ /_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Fhem" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/fhem.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Successfully" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8083${CL} \n" diff --git a/install/fhem-install.sh b/install/fhem-install.sh new file mode 100644 index 00000000..caf99993 --- /dev/null +++ b/install/fhem-install.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y avahi-daemon +$STD apt-get install -y gnupg2 +msg_ok "Installed Dependencies" + +msg_info "Setting up Fhem Repository" +curl -sSf https://debian.fhem.de/archive.key | gpg --dearmor >/etc/apt/trusted.gpg.d/debianfhemde-archive-keyring.gpg +echo 'deb [signed-by=/etc/apt/trusted.gpg.d/debianfhemde-archive-keyring.gpg] https://debian.fhem.de/nightly/ /' >/etc/apt/sources.list.d/fhem.list +msg_ok "Set up Fhem Repository" + +msg_info "Installing Fhem" +$STD apt-get update +$STD apt-get install -y fhem +msg_info "Installed Fhem" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 5fbe9ae8841c735d861d25590b887f9882a8e7f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 15:13:39 -0400 Subject: [PATCH 4734/6505] Update homebridge.sh fix update --- ct/homebridge.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 36281e8e..6c751496 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -55,7 +55,7 @@ header_info if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +apt-get install -y homebridge &>/dev/null msg_ok "Updated Successfully" exit } From e52df1c02a8b7432924d37aa67d9436f900f045c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 15:15:37 -0400 Subject: [PATCH 4735/6505] Update homebridge.sh fix file check --- ct/homebridge.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 6c751496..efd2b36e 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -f /etc/apt/sources.list.d/homebridge.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get install -y homebridge &>/dev/null From 0d977e3881202ae82b25d643f78b14404f60d780 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 16:00:20 -0400 Subject: [PATCH 4736/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index cbe73016..2aede023 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-05-07 + +### Changed + +- **FHEM LXC** + - NEW Script + ## 2023-05-01 ### Changed From 3486bba827b2b1b9a6a4027e551abc19e14e7693 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 16:10:15 -0400 Subject: [PATCH 4737/6505] Update microcode.sh add CPU Vendor check --- misc/microcode.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/misc/microcode.sh b/misc/microcode.sh index 07b2fff5..2758138a 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -23,12 +23,14 @@ cat <<"EOF" EOF +RD=$(echo "\033[01;31m") YW=$(echo "\033[33m") GN=$(echo "\033[1;92m") CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" set -euo pipefail shopt -s inherit_errexit nullglob @@ -43,6 +45,20 @@ msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +msg_info "Checking CPU Vendor" +cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') +if [ "$cpu" == "GenuineIntel" ]; then + msg_ok "${cpu} was detected" +else + msg_error "${cpu} is not supported" + exit +fi + msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" apt-get install -y iucode-tool &>/dev/null msg_ok "Installed iucode-tool" From bbf27909542b3ce05f5204729357e42777b8b454 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 20:23:14 -0400 Subject: [PATCH 4738/6505] Create microcode2.sh automatically identifies the processor vendor (Intel/AMD) and installs the appropriate microcode --- misc/microcode2.sh | 111 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 misc/microcode2.sh diff --git a/misc/microcode2.sh b/misc/microcode2.sh new file mode 100644 index 00000000..fbb74988 --- /dev/null +++ b/misc/microcode2.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +clear +while true; do + read -p "Install the latest Processor Microcode (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +clear +cat <<"EOF" + ____ __ ____ __ + / __ \_________ ________ ______________ _____ / |/ (_)_____________ _________ ____/ /__ + / /_/ / ___/ __ \/ ___/ _ \/ ___/ ___/ __ \/ ___/ / /|_/ / / ___/ ___/ __ \/ ___/ __ \/ __ / _ \ + / ____/ / / /_/ / /__/ __(__ |__ ) /_/ / / / / / / / /__/ / / /_/ / /__/ /_/ / /_/ / __/ +/_/ /_/ \____/\___/\___/____/____/\____/_/ /_/ /_/_/\___/_/ \____/\___/\____/\__,_/\___/ + +EOF + +RD=$(echo "\033[01;31m") +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +intel() { + msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" + apt-get install -y iucode-tool &>/dev/null + msg_ok "Installed iucode-tool" + + msg_info "Downloading the latest Intel Processor Microcode Package for Linux" + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230214.1_amd64.deb + msg_ok "Downloaded the latest Intel Processor Microcode Package" + + msg_info "Installing the Intel Processor Microcode (Patience)" + dpkg -i intel-microcode_3.20230214.1_amd64.deb &>/dev/null + msg_ok "Installed the Intel Processor Microcode" + + msg_info "Cleaning up" + rm intel-microcode_3.20230214.1_amd64.deb + msg_ok "Cleaned" + + echo -e "\n To apply the changes, the system will need to be rebooted.\n" +} + +amd() { + msg_info "Installing amd-ucode: a tool for updating AMD processor microcode" + apt-get install -y amd-ucode &>/dev/null + msg_ok "Installed amd-ucode" + + msg_info "Downloading the latest AMD Processor Microcode Package for Linux" + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230414.1_amd64.deb + msg_ok "Downloaded the latest AMD Processor Microcode Package" + + msg_info "Installing the AMD Processor Microcode (Patience)" + dpkg -i amd64-microcode_3.20230414.1_amd64.deb &>/dev/null + msg_ok "Installed the AMD Processor Microcode" + + msg_info "Cleaning up" + rm amd64-microcode_3.20230414.1_amd64.deb + msg_ok "Cleaned" + + echo -e "\n To apply the changes, the system will need to be rebooted.\n" +} + +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} Proxmox Virtual Environment Not Detected" + echo -e "Exiting..." + sleep 2 + exit +fi + +msg_info "Checking CPU Vendor" +cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') +if [ "$cpu" == "GenuineIntel" ]; then + msg_ok "${cpu} was detected" + intel +elif [ "$cpu" == "AuthenticAMD" ]; then + msg_ok "${cpu} was detected" + amd +else + msg_error "${cpu} is not supported" + exit +fi From 82743f68daadbcea429c2521c51a9eade8645181 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 May 2023 21:23:52 -0400 Subject: [PATCH 4739/6505] Add files via upload --- misc/images/processor.png | Bin 0 -> 42886 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/processor.png diff --git a/misc/images/processor.png b/misc/images/processor.png new file mode 100644 index 0000000000000000000000000000000000000000..75af60a9eef9cf6d853a91042fa9703293eeadf3 GIT binary patch literal 42886 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

    QtLhS@KSJ$-yNmB?2s{MWU9Tn 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 GHEIAlQaybD literal 0 HcmV?d00001 From c72475b1f7651f89cfd929cd470bacc8ec687b09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 09:13:34 -0400 Subject: [PATCH 4740/6505] Update microcode.sh Code refactoring --- misc/microcode.sh | 94 +++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 2758138a..fbb74988 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -6,7 +6,7 @@ clear while true; do - read -p "Install the latest Intel Processor Microcode (y/n)?" yn + read -p "Install the latest Processor Microcode (y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; @@ -15,11 +15,11 @@ while true; do done clear cat <<"EOF" - ____ __ __ __ ____ __ - / _/___ / /____ / / / |/ (_)_____________ _________ ____/ /__ - / // __ \/ __/ _ \/ / / /|_/ / / ___/ ___/ __ \/ ___/ __ \/ __ / _ \ - _/ // / / / /_/ __/ / / / / / / /__/ / / /_/ / /__/ /_/ / /_/ / __/ -/___/_/ /_/\__/\___/_/ /_/ /_/_/\___/_/ \____/\___/\____/\__,_/\___/ + ____ __ ____ __ + / __ \_________ ________ ______________ _____ / |/ (_)_____________ _________ ____/ /__ + / /_/ / ___/ __ \/ ___/ _ \/ ___/ ___/ __ \/ ___/ / /|_/ / / ___/ ___/ __ \/ ___/ __ \/ __ / _ \ + / ____/ / / /_/ / /__/ __(__ |__ ) /_/ / / / / / / / /__/ / / /_/ / /__/ /_/ / /_/ / __/ +/_/ /_/ \____/\___/\___/____/____/\____/_/ /_/ /_/_/\___/_/ \____/\___/\____/\__,_/\___/ EOF @@ -36,13 +36,13 @@ set -euo pipefail shopt -s inherit_errexit nullglob msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } msg_error() { @@ -50,30 +50,62 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +intel() { + msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" + apt-get install -y iucode-tool &>/dev/null + msg_ok "Installed iucode-tool" + + msg_info "Downloading the latest Intel Processor Microcode Package for Linux" + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230214.1_amd64.deb + msg_ok "Downloaded the latest Intel Processor Microcode Package" + + msg_info "Installing the Intel Processor Microcode (Patience)" + dpkg -i intel-microcode_3.20230214.1_amd64.deb &>/dev/null + msg_ok "Installed the Intel Processor Microcode" + + msg_info "Cleaning up" + rm intel-microcode_3.20230214.1_amd64.deb + msg_ok "Cleaned" + + echo -e "\n To apply the changes, the system will need to be rebooted.\n" +} + +amd() { + msg_info "Installing amd-ucode: a tool for updating AMD processor microcode" + apt-get install -y amd-ucode &>/dev/null + msg_ok "Installed amd-ucode" + + msg_info "Downloading the latest AMD Processor Microcode Package for Linux" + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230414.1_amd64.deb + msg_ok "Downloaded the latest AMD Processor Microcode Package" + + msg_info "Installing the AMD Processor Microcode (Patience)" + dpkg -i amd64-microcode_3.20230414.1_amd64.deb &>/dev/null + msg_ok "Installed the AMD Processor Microcode" + + msg_info "Cleaning up" + rm amd64-microcode_3.20230414.1_amd64.deb + msg_ok "Cleaned" + + echo -e "\n To apply the changes, the system will need to be rebooted.\n" +} + +if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + echo -e "${CROSS} Proxmox Virtual Environment Not Detected" + echo -e "Exiting..." + sleep 2 + exit +fi + msg_info "Checking CPU Vendor" cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') if [ "$cpu" == "GenuineIntel" ]; then msg_ok "${cpu} was detected" + intel +elif [ "$cpu" == "AuthenticAMD" ]; then + msg_ok "${cpu} was detected" + amd else - msg_error "${cpu} is not supported" + msg_error "${cpu} is not supported" exit -fi - -msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" -apt-get install -y iucode-tool &>/dev/null -msg_ok "Installed iucode-tool" - -msg_info "Downloading the latest Intel Processor Microcode Package for Linux" -release=$(curl -s https://api.github.com/repos/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/latest | awk -F'"' '/tag_name/{print $4}' | tr -cd '[:digit:]') -wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.${release}.1_amd64.deb -msg_ok "Downloaded the latest Intel Processor Microcode Package" - -msg_info "Installing the Intel Processor Microcode (Patience)" -dpkg -i intel-microcode_3.${release}.1_amd64.deb &>/dev/null -msg_ok "Installed the Intel Processor Microcode" - -msg_info "Cleaning up" -rm intel-microcode_3.${release}.1_amd64.deb -msg_ok "Cleaned" - -echo -e "\n To apply the settings, the system will need to be rebooted.\n" +fi From 44398fbfc2b33e405bfa00acbed2150aa85c5199 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 09:13:56 -0400 Subject: [PATCH 4741/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 2aede023..1dda2d61 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,14 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-05-08 + +### Changed + +- **Proxmox VE Intel Processor Microcode** + - Renamed to **Proxmox VE Processor Microcode** + - Automatically identifies the processor vendor (Intel/AMD) and installs the appropriate microcode. + ## 2023-05-07 ### Changed From 0efa38825e0abcaa0b12916afe19ebbe3ee576ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 09:16:00 -0400 Subject: [PATCH 4742/6505] Delete intel.png --- misc/images/intel.png | Bin 130540 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/intel.png diff --git a/misc/images/intel.png b/misc/images/intel.png deleted file mode 100644 index 97b53a678cc69d6850865c839ea391a012eebe89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130540 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 Date: Mon, 8 May 2023 09:16:39 -0400 Subject: [PATCH 4743/6505] Delete microcode2.sh --- misc/microcode2.sh | 111 --------------------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 misc/microcode2.sh diff --git a/misc/microcode2.sh b/misc/microcode2.sh deleted file mode 100644 index fbb74988..00000000 --- a/misc/microcode2.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -clear -while true; do - read -p "Install the latest Processor Microcode (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -cat <<"EOF" - ____ __ ____ __ - / __ \_________ ________ ______________ _____ / |/ (_)_____________ _________ ____/ /__ - / /_/ / ___/ __ \/ ___/ _ \/ ___/ ___/ __ \/ ___/ / /|_/ / / ___/ ___/ __ \/ ___/ __ \/ __ / _ \ - / ____/ / / /_/ / /__/ __(__ |__ ) /_/ / / / / / / / /__/ / / /_/ / /__/ /_/ / /_/ / __/ -/_/ /_/ \____/\___/\___/____/____/\____/_/ /_/ /_/_/\___/_/ \____/\___/\____/\__,_/\___/ - -EOF - -RD=$(echo "\033[01;31m") -YW=$(echo "\033[33m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" - -set -euo pipefail -shopt -s inherit_errexit nullglob - -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -intel() { - msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" - apt-get install -y iucode-tool &>/dev/null - msg_ok "Installed iucode-tool" - - msg_info "Downloading the latest Intel Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230214.1_amd64.deb - msg_ok "Downloaded the latest Intel Processor Microcode Package" - - msg_info "Installing the Intel Processor Microcode (Patience)" - dpkg -i intel-microcode_3.20230214.1_amd64.deb &>/dev/null - msg_ok "Installed the Intel Processor Microcode" - - msg_info "Cleaning up" - rm intel-microcode_3.20230214.1_amd64.deb - msg_ok "Cleaned" - - echo -e "\n To apply the changes, the system will need to be rebooted.\n" -} - -amd() { - msg_info "Installing amd-ucode: a tool for updating AMD processor microcode" - apt-get install -y amd-ucode &>/dev/null - msg_ok "Installed amd-ucode" - - msg_info "Downloading the latest AMD Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230414.1_amd64.deb - msg_ok "Downloaded the latest AMD Processor Microcode Package" - - msg_info "Installing the AMD Processor Microcode (Patience)" - dpkg -i amd64-microcode_3.20230414.1_amd64.deb &>/dev/null - msg_ok "Installed the AMD Processor Microcode" - - msg_info "Cleaning up" - rm amd64-microcode_3.20230414.1_amd64.deb - msg_ok "Cleaned" - - echo -e "\n To apply the changes, the system will need to be rebooted.\n" -} - -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} Proxmox Virtual Environment Not Detected" - echo -e "Exiting..." - sleep 2 - exit -fi - -msg_info "Checking CPU Vendor" -cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') -if [ "$cpu" == "GenuineIntel" ]; then - msg_ok "${cpu} was detected" - intel -elif [ "$cpu" == "AuthenticAMD" ]; then - msg_ok "${cpu} was detected" - amd -else - msg_error "${cpu} is not supported" - exit -fi From 8047265b2bbb653a9005300c30927c36fea23d60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 12:10:34 -0400 Subject: [PATCH 4744/6505] Update microcode.sh tweak --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index fbb74988..453feb9b 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -72,7 +72,7 @@ intel() { amd() { msg_info "Installing amd-ucode: a tool for updating AMD processor microcode" - apt-get install -y amd-ucode &>/dev/null + apt-get install -y amd64-microcode &>/dev/null msg_ok "Installed amd-ucode" msg_info "Downloading the latest AMD Processor Microcode Package for Linux" From 22a20617023edd67dfcd951d08e900021fe3d2b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 13:28:06 -0400 Subject: [PATCH 4745/6505] Update microcode.sh fix for AMD --- misc/microcode.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 453feb9b..30218ee9 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -51,11 +51,8 @@ msg_error() { } intel() { - msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" - apt-get install -y iucode-tool &>/dev/null - msg_ok "Installed iucode-tool" - msg_info "Downloading the latest Intel Processor Microcode Package for Linux" + apt-get install -y iucode-tool &>/dev/null wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230214.1_amd64.deb msg_ok "Downloaded the latest Intel Processor Microcode Package" @@ -71,10 +68,6 @@ intel() { } amd() { - msg_info "Installing amd-ucode: a tool for updating AMD processor microcode" - apt-get install -y amd64-microcode &>/dev/null - msg_ok "Installed amd-ucode" - msg_info "Downloading the latest AMD Processor Microcode Package for Linux" wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230414.1_amd64.deb msg_ok "Downloaded the latest AMD Processor Microcode Package" From 36a0528b99fc1b1cfcd894f9f2439e8024d4864d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 13:37:09 -0400 Subject: [PATCH 4746/6505] Update microcode.sh set AMD to verbose --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 30218ee9..1eb68105 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -57,7 +57,7 @@ intel() { msg_ok "Downloaded the latest Intel Processor Microcode Package" msg_info "Installing the Intel Processor Microcode (Patience)" - dpkg -i intel-microcode_3.20230214.1_amd64.deb &>/dev/null + dpkg -i intel-microcode_3.20230214.1_amd64.deb msg_ok "Installed the Intel Processor Microcode" msg_info "Cleaning up" From 62bc6600580a0ab15914517e29f0ea7b224e8618 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 13:37:49 -0400 Subject: [PATCH 4747/6505] Update microcode.sh --- misc/microcode.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 1eb68105..ba80a7ce 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -57,7 +57,7 @@ intel() { msg_ok "Downloaded the latest Intel Processor Microcode Package" msg_info "Installing the Intel Processor Microcode (Patience)" - dpkg -i intel-microcode_3.20230214.1_amd64.deb + dpkg -i intel-microcode_3.20230214.1_amd64.deb &>/dev/null msg_ok "Installed the Intel Processor Microcode" msg_info "Cleaning up" @@ -73,7 +73,7 @@ amd() { msg_ok "Downloaded the latest AMD Processor Microcode Package" msg_info "Installing the AMD Processor Microcode (Patience)" - dpkg -i amd64-microcode_3.20230414.1_amd64.deb &>/dev/null + dpkg -i amd64-microcode_3.20230414.1_amd64.deb msg_ok "Installed the AMD Processor Microcode" msg_info "Cleaning up" From 5b9709c93446a664ab643f9c020c0d008c718d05 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 May 2023 14:24:29 -0400 Subject: [PATCH 4748/6505] Update microcode.sh tweak --- misc/microcode.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index ba80a7ce..b30e3fc7 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -51,8 +51,11 @@ msg_error() { } intel() { - msg_info "Downloading the latest Intel Processor Microcode Package for Linux" + msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" apt-get install -y iucode-tool &>/dev/null + msg_ok "Installed iucode-tool" + + msg_info "Downloading the latest Intel Processor Microcode Package for Linux" wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230214.1_amd64.deb msg_ok "Downloaded the latest Intel Processor Microcode Package" From 9c2f48c2656fa3a8b7da90043feb42c469e14caa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 May 2023 00:01:07 -0400 Subject: [PATCH 4749/6505] Update monitor-all.sh spelling --- misc/monitor-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index a72300c6..fed2652a 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -93,7 +93,7 @@ Description=Ping instances every 5 minutes and restarts if necessary [Service] Type=simple # Include the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified, -# to indicate which CT/VN should be excluded. Example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 +# to indicate which CT/VM should be excluded. Example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 ExecStart=/usr/local/bin/ping-instances.sh Restart=always StandardOutput=file:/var/log/ping-instances.log From 8b1a1f201b1f2f550c9582dcb3204bdf77b3f87a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 May 2023 00:23:37 -0400 Subject: [PATCH 4750/6505] Update monitor-all.sh clarify exclusion instructions --- misc/monitor-all.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index fed2652a..236016ee 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -92,8 +92,9 @@ Description=Ping instances every 5 minutes and restarts if necessary [Service] Type=simple -# Include the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified, -# to indicate which CT/VM should be excluded. Example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 +# To specify which CT/VM should be excluded, add the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified. +# For example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 +# Virtual machines without the QEMU guest agent installed must be excluded. ExecStart=/usr/local/bin/ping-instances.sh Restart=always StandardOutput=file:/var/log/ping-instances.log From a3dfc8f41de5093bee868ee14044ab9b91a874db Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 May 2023 04:43:43 -0400 Subject: [PATCH 4751/6505] Update microcode.sh remove AMD verbose confirmed working --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index b30e3fc7..4fc7c8d9 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -76,7 +76,7 @@ amd() { msg_ok "Downloaded the latest AMD Processor Microcode Package" msg_info "Installing the AMD Processor Microcode (Patience)" - dpkg -i amd64-microcode_3.20230414.1_amd64.deb + dpkg -i amd64-microcode_3.20230414.1_amd64.deb &>/dev/null msg_ok "Installed the AMD Processor Microcode" msg_info "Cleaning up" From 5afa9e37cbfe303229cdad0dfa6ffcd97f767ff8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 May 2023 08:29:51 -0400 Subject: [PATCH 4752/6505] Update build.func add tags --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index d76e1a7c..de385eeb 100644 --- a/misc/build.func +++ b/misc/build.func @@ -476,6 +476,7 @@ build_container() { export PCT_OPTIONS=" -features $FEATURES -hostname $HN + -tags proxmox-helper-scripts $SD $NS -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU From 1de6cc4cb866b17ff92ab7dec812329d6b8f3f44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 May 2023 10:10:46 -0400 Subject: [PATCH 4753/6505] Update nginxproxymanager.sh using `RELEASE` to obtain the latest version for updating --- ct/nginxproxymanager.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 4425570c..b460da3f 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -74,18 +74,18 @@ function update_script() { /var/cache/nginx &>/dev/null msg_ok "Cleaned Old Files" - msg_info "Downloading NPM v2.10.2" - wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.10.2 -O - | tar -xz &>/dev/null - cd nginx-proxy-manager-2.10.2 - msg_ok "Downloaded NPM v2.10.2" + msg_info "Downloading NPM v${RELEASE}" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null + cd nginx-proxy-manager-${RELEASE} + msg_ok "Downloaded NPM v${RELEASE}" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx - sed -i "s+0.0.0+2.10.2+g" backend/package.json - sed -i "s+0.0.0+2.10.2+g" frontend/package.json + sed -i "s+0.0.0+${RELEASE}+g" backend/package.json + sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do @@ -124,8 +124,8 @@ function update_script() { mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global - wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-noarch.tar.xz" - wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-x86_64.tar.xz" + wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-noarch.tar.xz" + wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-x86_64.tar.xz" tar -C / -Jxpf s6-overlay-noarch.tar.xz tar -C / -Jxpf s6-overlay-x86_64.tar.xz python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null @@ -163,7 +163,7 @@ EOF msg_ok "Initialized Backend" msg_info "Starting Services" - sed -i -e 's/^pid/#pid/' -e 's/npmuser/root/' /usr/local/openresty/nginx/conf/nginx.conf + sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg systemctl enable -q --now openresty systemctl enable -q --now npm From 0038a8b74f88810a2ab9185bd43167c046c7dbb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 May 2023 10:13:58 -0400 Subject: [PATCH 4754/6505] Update nginxproxymanager-install.sh using RELEASE to obtain the latest version. update s6 fix user --- install/nginxproxymanager-install.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 05194c8f..8d797267 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -66,10 +66,10 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v2.10.2" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.10.2 -O - | tar -xz -cd ./nginx-proxy-manager-2.10.2 -msg_ok "Downloaded Nginx Proxy Manager v2.10.2" +msg_info "Downloading Nginx Proxy Manager v${RELEASE}" +wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz +cd ./nginx-proxy-manager-${RELEASE} +msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python @@ -77,8 +77,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+2.10.2+g" backend/package.json -sed -i "s+0.0.0+2.10.2+g" frontend/package.json +sed -i "s+0.0.0+${RELEASE}+g" backend/package.json +sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") @@ -124,8 +124,8 @@ fi mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global -wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-noarch.tar.xz" -wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.4.1/s6-overlay-x86_64.tar.xz" +wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-noarch.tar.xz" +wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-x86_64.tar.xz" tar -C / -Jxpf s6-overlay-noarch.tar.xz tar -C / -Jxpf s6-overlay-x86_64.tar.xz msg_ok "Set up Enviroment" @@ -185,7 +185,7 @@ motd_ssh root msg_info "Starting Services" -sed -i -e 's/^pid/#pid/' -e 's/npmuser/root/' /usr/local/openresty/nginx/conf/nginx.conf +sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg $STD systemctl enable --now openresty $STD systemctl enable --now npm From 1263944d40e95e28c81c7e6d5571877ef6666780 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 May 2023 22:40:49 -0400 Subject: [PATCH 4755/6505] Update build.func add instructional tip --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index de385eeb..fd0b6369 100644 --- a/misc/build.func +++ b/misc/build.func @@ -112,6 +112,7 @@ exit-script() { } advanced_settings() { + whiptail --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 whiptail --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n" 8 58 if [ "$var_os" != "alpine" ]; then var_os="" From 9e9b8286ad52f75d1a2b26f686e74bcc8c72528a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 May 2023 23:20:05 -0400 Subject: [PATCH 4756/6505] Update haos-vm.sh add tag --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 199dabaa..27c8e64e 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -414,7 +414,7 @@ done msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ - -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ From 71eecd1efcf9f4331c5131d96efcd874f21c5147 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 May 2023 14:04:12 -0400 Subject: [PATCH 4757/6505] Update build.func improve whiptail menu --- misc/build.func | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/misc/build.func b/misc/build.func index fd0b6369..28e09eb0 100644 --- a/misc/build.func +++ b/misc/build.func @@ -268,32 +268,23 @@ advanced_settings() { fi done +if [ "$NET" != "dhcp" ]; then while true; do - GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3) - exit_status=$? - if [ $exit_status -eq 0 ]; then - if [ -z "$GATE1" ]; then - if [ "$NET" = "dhcp" ]; then - GATE1="Default" - GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - break - else - whiptail --msgbox "Since a static IP was used, a gateway IP address is mandatory." 8 58 - fi - else - if [[ "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - break - else - whiptail --msgbox "Invalid IP address. Please enter a valid IP address." 8 58 - fi - fi + GATE1=$(whiptail --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) + if [ -z "$GATE1" ]; then + whiptail --msgbox "Gateway IP address cannot be empty" 8 58 + elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + whiptail --msgbox "Invalid IP address format" 8 58 else - exit-script + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + break fi done +else + GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" +fi if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" @@ -363,12 +354,17 @@ advanced_settings() { exit-script fi - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" + if [[ "$PW" == -password* ]]; then + if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + SSH="yes" + else + SSH="no" + fi + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" else SSH="no" + echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then From 325071c2f1e853aaefa789dd29ce74b34f706c8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 May 2023 14:15:10 -0400 Subject: [PATCH 4758/6505] Update build.func shfmt --- misc/build.func | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/misc/build.func b/misc/build.func index 28e09eb0..115ba768 100644 --- a/misc/build.func +++ b/misc/build.func @@ -268,23 +268,23 @@ advanced_settings() { fi done -if [ "$NET" != "dhcp" ]; then - while true; do - GATE1=$(whiptail --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) - if [ -z "$GATE1" ]; then - whiptail --msgbox "Gateway IP address cannot be empty" 8 58 - elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --msgbox "Invalid IP address format" 8 58 - else - GATE=",gw=$GATE1" - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" - break - fi - done -else - GATE="" - echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" -fi + if [ "$NET" != "dhcp" ]; then + while true; do + GATE1=$(whiptail --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) + if [ -z "$GATE1" ]; then + whiptail --msgbox "Gateway IP address cannot be empty" 8 58 + elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + whiptail --msgbox "Invalid IP address format" 8 58 + else + GATE=",gw=$GATE1" + echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" + break + fi + done + else + GATE="" + echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" + fi if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" From e1f561ae748a261e458a6f23596c6987be1fdac5 Mon Sep 17 00:00:00 2001 From: MrTylerjet Date: Fri, 12 May 2023 10:50:39 -0600 Subject: [PATCH 4759/6505] add Bazarr LXC script (#1418) * add bazzar LXC script (https://www.bazarr.media/) --- ct/bazarr.sh | 69 +++++++++++++++++++++++++++++++++++++++ install/bazarr-install.sh | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100755 ct/bazarr.sh create mode 100755 install/bazarr-install.sh diff --git a/ct/bazarr.sh b/ct/bazarr.sh new file mode 100755 index 00000000..97c6b375 --- /dev/null +++ b/ct/bazarr.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ + / __ )____ _____ ____ ___________ + / __ / __ `/_ / / __ `/ ___/ ___/ + / /_/ / /_/ / / /_/ /_/ / / / / +/_____/\__,_/ /___/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Bazarr" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET=dhcp + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var/lib/bazarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6767${CL} \n" \ No newline at end of file diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh new file mode 100755 index 00000000..bd395f66 --- /dev/null +++ b/install/bazarr-install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +$STD apt-get install -y python3-pip +msg_ok "Installed Dependencies" + +msg_info "Installing Bazarr" +mkdir -p /var/lib/bazarr/ +wget -q https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip +unzip -qq bazarr -d /opt/bazarr +chmod 775 /opt/bazarr /var/lib/bazarr/ +python3 -m pip install -q -r /opt/bazarr/requirements.txt +msg_ok "Installed Bazarr" + +msg_info "Creating Service" +cat </etc/systemd/system/bazarr.service +[Unit] +Description=Bazarr Daemon +After=syslog.target network.target + +[Service] +WorkingDirectory=/opt/bazarr/ +UMask=0002 +Restart=on-failure +RestartSec=5 +Type=simple +ExecStart=/usr/bin/python3 /opt/bazarr/bazarr.py +KillSignal=SIGINT +TimeoutStopSec=20 +SyslogIdentifier=bazarr + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now bazarr +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +rm -rf bazarr.zip +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" \ No newline at end of file From 3d4dc6d0a4b987f419b06fef68b9f4ecdfc349b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 May 2023 16:05:17 -0400 Subject: [PATCH 4760/6505] Update CHANGELOG.MD --- CHANGELOG.MD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 1dda2d61..69068747 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-05-12 + +### Changed + +- **Bazarr LXC** + - NEW Script + ## 2023-05-08 ### Changed From adf4ffddb30aea96c7737c1a8607d9d032169d1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 May 2023 16:17:32 -0400 Subject: [PATCH 4761/6505] Rename CHANGELOG.MD to CHANGELOG.md --- CHANGELOG.MD => CHANGELOG.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CHANGELOG.MD => CHANGELOG.md (100%) diff --git a/CHANGELOG.MD b/CHANGELOG.md similarity index 100% rename from CHANGELOG.MD rename to CHANGELOG.md From 825a55152192836d1eb2df8f2fc8ba26026493cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 06:34:33 -0400 Subject: [PATCH 4762/6505] Update create_lxc.sh change menu message --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index f8326f55..427d7ee3 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -85,7 +85,7 @@ function select_storage() { local STORAGE while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\nTo make a selection, use the Spacebar.\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || exit "Menu aborted." done From f5a8f4ca732dc33fc3d74d8a9306e66332d00305 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 07:19:25 -0400 Subject: [PATCH 4763/6505] Update create_lxc.sh tweak --- ct/create_lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 427d7ee3..6fd83826 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -85,7 +85,7 @@ function select_storage() { local STORAGE while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\nTo make a selection, use the Spacebar.\n" \ + "Which storage pool you would like to use for ${APPLICATION}?\nTo make a selection, use the Spacebar.\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || exit "Menu aborted." done From 7680982315274c598d0e487288c014f6f2c3f0a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 07:31:12 -0400 Subject: [PATCH 4764/6505] Update haos-vm.sh change storage menu message --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 27c8e64e..46c4bc08 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -369,7 +369,7 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the HAOS VM?\n\n" \ + "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done From c542221883f18d5d70b3406248995f9d33fbc37f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 10:02:02 -0400 Subject: [PATCH 4765/6505] Update homeassistant-core-install.sh update `homeassistant.service` --- install/homeassistant-core-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index d42b53b5..f7cc1c9c 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -91,6 +91,7 @@ After=network-online.target Type=simple WorkingDirectory=/root/.homeassistant ExecStart=/srv/homeassistant/bin/hass -c "/root/.homeassistant" +Restart=always RestartForceExitStatus=100 [Install] WantedBy=multi-user.target From 41ed6d8df92f4965a559bdb456e6d0e2e629b091 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 14:09:34 -0400 Subject: [PATCH 4766/6505] Update clean-lxcs.sh tweak --- misc/clean-lxcs.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index a3465dc1..447d8076 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -24,7 +24,6 @@ CM='\xE2\x9C\x94\033' GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info -echo -e "\n ${RD} USE AT YOUR OWN RISK. Deleting logs/cache may result in some apps/services broken!${CL} \n" while true; do read -p "This Will Clean logs, cache and update apt lists on all LXC Containers. Proceed(y/n)?" yn case $yn in From a35d823b1ff268d21deffd6f6d0ec0991dbaac75 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 20:39:18 -0400 Subject: [PATCH 4767/6505] Create tautulli.sh --- ct/tautulli.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/tautulli.sh diff --git a/ct/tautulli.sh b/ct/tautulli.sh new file mode 100644 index 00000000..b8d052c4 --- /dev/null +++ b/ct/tautulli.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ __ _____ + /_ __/___ ___ __/ /___ __/ / (_) + / / / __ `/ / / / __/ / / / / / / + / / / /_/ / /_/ / /_/ /_/ / / / / +/_/ \__,_/\__,_/\__/\__,_/_/_/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Tautulli" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/Tautulli/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8181${CL} \n" From f4fe0353474f7cfec30cde12e2231345417c477b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 20:41:46 -0400 Subject: [PATCH 4768/6505] Create tautulli-install.sh --- install/tautulli-install.sh | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 install/tautulli-install.sh diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh new file mode 100644 index 00000000..ca918615 --- /dev/null +++ b/install/tautulli-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y pip +msg_ok "Installed Dependencies" + +msg_info "Installing Tautulli" +cd /opt +git clone https://github.com/Tautulli/Tautulli.git +python3 -m pip install -q -r /opt/Tautulli/requirements.txt +msg_ok "Installed Tautulli" + +msg_info "Creating Service" +cat </etc/systemd/system/tautulli.service +[Unit] +Description=Tautulli +After=syslog.target network.target + +[Service] +WorkingDirectory=/opt/Tautulli/ +Restart=on-failure +RestartSec=5 +Type=simple +ExecStart=/usr/bin/python3 /opt/Tautulli/Tautulli.py +KillSignal=SIGINT +TimeoutStopSec=20 +SyslogIdentifier=tautulli + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now tautulli +msg_ok "Created Service" + +motd_ssh +root + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 81f1443a83f50df019fd89c3a2b286bdadb29dce Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 20:47:32 -0400 Subject: [PATCH 4769/6505] Update tautulli-install.sh tweak --- install/tautulli-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index ca918615..43a6a316 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -23,7 +23,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Tautulli" cd /opt -git clone https://github.com/Tautulli/Tautulli.git +$STD git clone https://github.com/Tautulli/Tautulli.git python3 -m pip install -q -r /opt/Tautulli/requirements.txt msg_ok "Installed Tautulli" From 1aa74d4ec631b2de6439c981960022fbc881bb89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 21:05:33 -0400 Subject: [PATCH 4770/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69068747..90582703 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-05-13 + +### Changed + +- **Tautulli LXC** + - NEW Script + ## 2023-05-12 ### Changed From d7d4d296e50340c38b64a2cb5e1863b247ef9be5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 May 2023 21:22:09 -0400 Subject: [PATCH 4771/6505] tweak --- ct/adguard.sh | 2 +- ct/alpine-adguard.sh | 2 +- ct/alpine-docker.sh | 2 +- ct/alpine-grafana.sh | 2 +- ct/alpine-vaultwarden.sh | 2 +- ct/alpine-whoogle.sh | 2 +- ct/alpine-zigbee2mqtt.sh | 2 +- ct/alpine.sh | 2 +- ct/archlinux.sh | 2 +- ct/audiobookshelf.sh | 2 +- ct/autobrr.sh | 2 +- ct/bazarr.sh | 2 +- ct/blocky.sh | 2 +- ct/casaos.sh | 2 +- ct/changedetection.sh | 2 +- ct/cloudflared.sh | 2 +- ct/cronicle.sh | 2 +- ct/daemonsync.sh | 2 +- ct/dashy.sh | 2 +- ct/debian.sh | 2 +- ct/deconz.sh | 2 +- ct/deluge.sh | 2 +- ct/devuan.sh | 2 +- ct/docker.sh | 2 +- ct/emby.sh | 2 +- ct/emqx.sh | 2 +- ct/esphome.sh | 2 +- ct/fhem.sh | 2 +- ct/go2rtc.sh | 2 +- ct/grafana.sh | 2 +- ct/grocy.sh | 2 +- ct/heimdalldashboard.sh | 2 +- ct/homeassistant-core.sh | 2 +- ct/homeassistant.sh | 2 +- ct/homebridge.sh | 2 +- ct/homepage.sh | 2 +- ct/homer.sh | 2 +- ct/hyperion.sh | 2 +- ct/influxdb.sh | 2 +- ct/iobroker.sh | 2 +- ct/jackett.sh | 2 +- ct/jellyfin.sh | 2 +- ct/k0s.sh | 2 +- ct/kavita.sh | 2 +- ct/keycloak.sh | 2 +- ct/lidarr.sh | 2 +- ct/magicmirror.sh | 2 +- ct/mariadb.sh | 2 +- ct/meshcentral.sh | 2 +- ct/motioneye.sh | 2 +- ct/mqtt.sh | 2 +- ct/n8n.sh | 2 +- ct/navidrome.sh | 2 +- ct/nextcloudpi.sh | 2 +- ct/nginxproxymanager.sh | 2 +- ct/nocodb.sh | 2 +- ct/node-red.sh | 2 +- ct/octoprint.sh | 2 +- ct/omada.sh | 2 +- ct/omv.sh | 2 +- ct/openhab.sh | 2 +- ct/paperless-ngx.sh | 2 +- ct/photoprism.sh | 2 +- ct/pihole.sh | 2 +- ct/plex.sh | 2 +- ct/podman-homeassistant.sh | 2 +- ct/podman.sh | 2 +- ct/postgresql.sh | 2 +- ct/prometheus.sh | 2 +- ct/prowlarr.sh | 2 +- ct/qbittorrent.sh | 2 +- ct/radarr.sh | 2 +- ct/readarr.sh | 2 +- ct/rockylinux.sh | 2 +- ct/rstptoweb.sh | 2 +- ct/sabnzbd.sh | 2 +- ct/scrypted.sh | 2 +- ct/shinobi.sh | 2 +- ct/sonarr.sh | 2 +- ct/syncthing.sh | 2 +- ct/tdarr.sh | 2 +- ct/technitiumdns.sh | 2 +- ct/transmission.sh | 2 +- ct/trilium.sh | 2 +- ct/ubuntu.sh | 2 +- ct/umbrel.sh | 2 +- ct/unifi.sh | 2 +- ct/uptimekuma.sh | 2 +- ct/vaultwarden.sh | 2 +- ct/whisparr.sh | 2 +- ct/whoogle.sh | 2 +- ct/wikijs.sh | 2 +- ct/wireguard.sh | 2 +- ct/yunohost.sh | 2 +- ct/zigbee2mqtt.sh | 2 +- ct/zwave-js-ui.sh | 2 +- 96 files changed, 96 insertions(+), 96 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index 4c7db3a7..a0cab6e7 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh index 248aa7f2..929708a5 100644 --- a/ct/alpine-adguard.sh +++ b/ct/alpine-adguard.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index a7b08ba6..d3d4c8ca 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 7cb26ae6..254cead3 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 3783d633..525f1404 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh index b2e2eaa7..02dec1f1 100644 --- a/ct/alpine-whoogle.sh +++ b/ct/alpine-whoogle.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 55df4544..b7d87edb 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/alpine.sh b/ct/alpine.sh index a3348a9f..42c9546a 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/archlinux.sh b/ct/archlinux.sh index a28cfed3..55067dab 100644 --- a/ct/archlinux.sh +++ b/ct/archlinux.sh @@ -100,7 +100,7 @@ function default_settings() { echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET=dhcp + NET="dhcp" echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" GATE="" echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 558dbc44..86d51e68 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/autobrr.sh b/ct/autobrr.sh index b92412f0..c3f79c42 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/bazarr.sh b/ct/bazarr.sh index 97c6b375..cf85c64c 100755 --- a/ct/bazarr.sh +++ b/ct/bazarr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/blocky.sh b/ct/blocky.sh index 08e769e8..049f979d 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/casaos.sh b/ct/casaos.sh index c98a025d..52e9f880 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 80748b5e..e114edc3 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/cloudflared.sh b/ct/cloudflared.sh index b4fa4518..fafb6595 100644 --- a/ct/cloudflared.sh +++ b/ct/cloudflared.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 8eb6aaa5..f5227c32 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index d13e5b40..c134ce41 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/dashy.sh b/ct/dashy.sh index 69385bd4..3bd3284d 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/debian.sh b/ct/debian.sh index b67a0a26..ee23d6c5 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/deconz.sh b/ct/deconz.sh index 6195bd10..ccf279d1 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/deluge.sh b/ct/deluge.sh index 0b3ce6c4..163fe125 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/devuan.sh b/ct/devuan.sh index db48bf4e..25bdc96f 100644 --- a/ct/devuan.sh +++ b/ct/devuan.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/docker.sh b/ct/docker.sh index 1805787c..ecbc4892 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/emby.sh b/ct/emby.sh index 63abf748..1491a55c 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/emqx.sh b/ct/emqx.sh index 7c0ffcd9..fb198fce 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/esphome.sh b/ct/esphome.sh index 2bbd3d4d..d7d4f753 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/fhem.sh b/ct/fhem.sh index 13c042d7..075d4b45 100644 --- a/ct/fhem.sh +++ b/ct/fhem.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 58b82f5c..ba243dc3 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/grafana.sh b/ct/grafana.sh index e1164a01..bb50c557 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/grocy.sh b/ct/grocy.sh index 6e0a66d9..cfe213d5 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index c06501f3..1a2b701a 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 858433c2..8f612cb5 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index ac667247..3a67b1fc 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/homebridge.sh b/ct/homebridge.sh index efd2b36e..7522a7f4 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/homepage.sh b/ct/homepage.sh index 13b4fca6..d133e7a8 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/homer.sh b/ct/homer.sh index 34bf6620..fcdc17ac 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 51108e46..fbd17687 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 7408d33c..8f660810 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/iobroker.sh b/ct/iobroker.sh index d715199a..8feef540 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/jackett.sh b/ct/jackett.sh index f895f4d7..892e2da2 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index 88eb4d8d..5c8018fd 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/k0s.sh b/ct/k0s.sh index 1d64a0ce..0591912e 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/kavita.sh b/ct/kavita.sh index 8410daa7..4d86cd74 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 218f56f4..83895ba7 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/lidarr.sh b/ct/lidarr.sh index 6bc88997..17114c71 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index 2554bd1b..c3078bc3 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 03e24726..b955a589 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index a9288d90..03b3efd2 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/motioneye.sh b/ct/motioneye.sh index e46e9fd4..8ec8f6a2 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 0eb3c974..f4f0bed7 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/n8n.sh b/ct/n8n.sh index 58e56db7..906d46c1 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/navidrome.sh b/ct/navidrome.sh index 10c308c3..258c0acd 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index 8e18cc2a..1b63695c 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index b460da3f..72bffcac 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/nocodb.sh b/ct/nocodb.sh index bcfcdc7b..3c400a1e 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/node-red.sh b/ct/node-red.sh index 3dba9183..0555b6b4 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/octoprint.sh b/ct/octoprint.sh index c0f14e37..3d4cb3e0 100644 --- a/ct/octoprint.sh +++ b/ct/octoprint.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/omada.sh b/ct/omada.sh index 3b02947e..c355622e 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/omv.sh b/ct/omv.sh index 7b31de75..063bc49b 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/openhab.sh b/ct/openhab.sh index d4c33704..7841d610 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 09d46d45..7a5483f4 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 231f7d1e..31dd6735 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/pihole.sh b/ct/pihole.sh index d5233719..b6ba11a6 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/plex.sh b/ct/plex.sh index bcc7d96d..a24fa465 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index fbdc906e..a1c8c4fc 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -41,7 +41,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/podman.sh b/ct/podman.sh index b313e673..bd048a08 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 700ad409..06212e1a 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 571a18bb..3ee8a3de 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index 2c323541..c53b162b 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 83cc8526..8615ae2d 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/radarr.sh b/ct/radarr.sh index a379e8ac..6282e685 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/readarr.sh b/ct/readarr.sh index bea527d0..eb6466e5 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index 38700c95..02a0a090 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/rstptoweb.sh b/ct/rstptoweb.sh index 1c1bb453..b0e68ab9 100644 --- a/ct/rstptoweb.sh +++ b/ct/rstptoweb.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index ea75032d..1b198e99 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/scrypted.sh b/ct/scrypted.sh index f4b7d0ee..474f3af3 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/shinobi.sh b/ct/shinobi.sh index bc5572e6..58882700 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/sonarr.sh b/ct/sonarr.sh index ac6f2399..0ed45a21 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/syncthing.sh b/ct/syncthing.sh index 4df4d33a..b45fcfd8 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 994ae3db..de386554 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index 7c9d30f4..6b538f6a 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/transmission.sh b/ct/transmission.sh index 94e654d6..fd8a5c2d 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/trilium.sh b/ct/trilium.sh index 350a945e..a54e36a4 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index bc2f0cc6..1804b96b 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 46ed1aa2..8babfc1b 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/unifi.sh b/ct/unifi.sh index d3876aa6..c44b0182 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index d7d1cc0f..2f82fc3b 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index f74ef4fe..2d326b6c 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/whisparr.sh b/ct/whisparr.sh index c616282a..4304d4aa 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/whoogle.sh b/ct/whoogle.sh index bb4257ec..c6054537 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/wikijs.sh b/ct/wikijs.sh index 416e54ee..a8f58ce8 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/wireguard.sh b/ct/wireguard.sh index d6a6b48e..60156f2e 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 22198999..b024d239 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 21562435..a9634918 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -38,7 +38,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 2255e299..c4217d3e 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -37,7 +37,7 @@ function default_settings() { CORE_COUNT="$var_cpu" RAM_SIZE="$var_ram" BRG="vmbr0" - NET=dhcp + NET="dhcp" GATE="" DISABLEIP6="no" MTU="" From 58909e197a2005c066155d2b9334df04d31d6f46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 May 2023 11:43:17 -0400 Subject: [PATCH 4772/6505] Update build.func add Tdarr to Hardware Acceleration Support --- misc/build.func | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index 115ba768..2aac2b0a 100644 --- a/misc/build.func +++ b/misc/build.func @@ -467,6 +467,7 @@ build_container() { export VERBOSE="$VERB" export SSH_ROOT="${SSH}" export CTID="$CT_ID" + export CTTYPE="$CT_TYPE" export PCT_OSTYPE="$var_os" export PCT_OSVERSION="$var_version" export PCT_DISK_SIZE="$DISK_SIZE" @@ -487,7 +488,7 @@ build_container() { LXC_CONFIG=/etc/pve/lxc/${CTID}.conf if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" ]]; then + if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" && "$APP" != "Tdarr" ]]; then cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: @@ -503,7 +504,7 @@ EOF fi if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" ]]; then + if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Tdarr" ]]; then cat <>$LXC_CONFIG lxc.cgroup2.devices.allow: a lxc.cap.drop: From 66aef55ab0bf7e94454263ab508937932e272f60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 May 2023 11:44:18 -0400 Subject: [PATCH 4773/6505] Update tdarr-install.sh Hardware Acceleration --- install/tdarr-install.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index 212df862..02a7baa8 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -20,6 +20,19 @@ $STD apt-get install -y mc $STD apt-get install -y unzip msg_ok "Installed Dependencies" +if [[ "$CTTYPE" == "0" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + intel-opencl-icd + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + msg_info "Installing Tdarr" mkdir -p /opt/tdarr cd /opt/tdarr From 3a3f00e522fe8bbb7e5139347d8ae38848c2ef2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 May 2023 11:45:22 -0400 Subject: [PATCH 4774/6505] Update tdarr.sh default privileged --- ct/tdarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/tdarr.sh b/ct/tdarr.sh index de386554..cff3d7fc 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="1" + CT_TYPE="0" PW="" CT_ID=$NEXTID HN=$NSAPP From 08235d8ac250852d684e906684d789ce4a9aa2d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 May 2023 12:04:15 -0400 Subject: [PATCH 4775/6505] Update plex.sh change wording --- ct/plex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex.sh b/ct/plex.sh index a24fa465..ac09683a 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -54,7 +54,7 @@ function update_script() { if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ "1" "Update LXC" ON \ - "2" "Run plexupdate" OFF \ + "2" "Install plexupdate" OFF \ 3>&1 1>&2 2>&3) header_info From b09f213c842a1d511efad2f473139cabb89a0618 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 05:53:35 -0400 Subject: [PATCH 4776/6505] Update build.func export PASSWORD --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index 2aac2b0a..39438910 100644 --- a/misc/build.func +++ b/misc/build.func @@ -464,6 +464,7 @@ build_container() { fi export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" + export PASSWORD="$PW" export VERBOSE="$VERB" export SSH_ROOT="${SSH}" export CTID="$CT_ID" From c12f2773e70248cc33ee205cf6ae025987230f05 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 07:39:30 -0400 Subject: [PATCH 4777/6505] Code refactoring --- install/adguard-install.sh | 2 +- install/alpine-adguard-install.sh | 2 +- install/alpine-docker-install.sh | 2 +- install/alpine-grafana-install.sh | 2 +- install/alpine-vaultwarden-install.sh | 2 +- install/alpine-whoogle-install.sh | 2 +- install/alpine-zigbee2mqtt-install.sh | 2 +- install/audiobookshelf-install.sh | 2 +- install/autobrr-install.sh | 2 +- install/bazarr-install.sh | 3 +-- install/blocky-install.sh | 2 +- install/casaos-install.sh | 3 +-- install/changedetection-install.sh | 2 +- install/cloudflared-install.sh | 2 +- install/cronicle-install.sh | 2 +- install/daemonsync-install.sh | 2 +- install/dashy-install.sh | 2 +- install/debian-install.sh | 2 +- install/deconz-install.sh | 2 +- install/deluge-install.sh | 2 +- install/devuan-install.sh | 2 +- install/docker-install.sh | 2 +- install/emby-install.sh | 4 ++-- install/emqx-install.sh | 2 +- install/esphome-install.sh | 2 +- install/fhem-install.sh | 2 +- install/go2rtc-install.sh | 2 +- install/grafana-install.sh | 2 +- install/grocy-install.sh | 3 +-- install/heimdalldashboard-install.sh | 2 +- install/homeassistant-core-install.sh | 2 +- install/homeassistant-install.sh | 2 +- install/homebridge-install.sh | 2 +- install/homepage-install.sh | 2 +- install/homer-install.sh | 3 +-- install/hyperion-install.sh | 2 +- install/influxdb-install.sh | 2 +- install/iobroker-install.sh | 2 +- install/jackett-install.sh | 2 +- install/jellyfin-install.sh | 4 ++-- install/k0s-install.sh | 2 +- install/kavita-install.sh | 2 +- install/keycloak-install.sh | 2 +- install/lidarr-install.sh | 2 +- install/magicmirror-install.sh | 2 +- install/mariadb-install.sh | 2 +- install/meshcentral-install.sh | 2 +- install/motioneye-install.sh | 2 +- install/mqtt-install.sh | 2 +- install/n8n-install.sh | 2 +- install/navidrome-install.sh | 2 +- install/nextcloudpi-install.sh | 2 +- install/nginxproxymanager-install.sh | 2 +- install/nocodb-install.sh | 2 +- install/node-red-install.sh | 2 +- install/octoprint-install.sh | 2 +- install/omada-install.sh | 2 +- install/omv-install.sh | 2 +- install/openhab-install.sh | 2 +- install/paperless-ngx-install.sh | 4 ++-- install/photoprism-install.sh | 3 +-- install/pihole-install.sh | 2 +- install/plex-install.sh | 4 ++-- install/podman-homeassistant-install.sh | 2 +- install/podman-install.sh | 2 +- install/postgresql-install.sh | 2 +- install/prometheus-install.sh | 2 +- install/prowlarr-install.sh | 2 +- install/qbittorrent-install.sh | 2 +- install/radarr-install.sh | 2 +- install/readarr-install.sh | 2 +- install/rstptoweb-install.sh | 2 +- install/sabnzbd-install.sh | 3 +-- install/scrypted-install.sh | 2 +- install/shinobi-install.sh | 2 +- install/sonarr-install.sh | 2 +- install/syncthing-install.sh | 2 +- install/tautulli-install.sh | 2 +- install/tdarr-install.sh | 3 +-- install/technitiumdns-install.sh | 2 +- install/transmission-install.sh | 2 +- install/trilium-install.sh | 2 +- install/ubuntu-install.sh | 2 +- install/umbrel-install.sh | 2 +- install/unifi-install.sh | 2 +- install/uptimekuma-install.sh | 2 +- install/vaultwarden-install.sh | 2 +- install/whisparr-install.sh | 2 +- install/whoogle-install.sh | 2 +- install/wikijs-install.sh | 2 +- install/wireguard-install.sh | 2 +- install/yunohost-install.sh | 2 +- install/zigbee2mqtt-install.sh | 2 +- install/zwave-js-ui-install.sh | 3 +-- misc/alpine-install.func | 8 ++------ misc/build.func | 2 +- misc/install.func | 8 ++------ 97 files changed, 103 insertions(+), 119 deletions(-) diff --git a/install/adguard-install.sh b/install/adguard-install.sh index fb490e06..124f2e68 100644 --- a/install/adguard-install.sh +++ b/install/adguard-install.sh @@ -29,7 +29,7 @@ rm install.sh msg_ok "Installed AdGuard Home" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/alpine-adguard-install.sh b/install/alpine-adguard-install.sh index 33df28ab..b43c55ce 100644 --- a/install/alpine-adguard-install.sh +++ b/install/alpine-adguard-install.sh @@ -33,4 +33,4 @@ $STD /opt/AdGuardHome/AdGuardHome -s start msg_ok "Installed Alpine-AdGuard" motd_ssh -root +customize diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh index 4ed450e5..368a4d3f 100644 --- a/install/alpine-docker-install.sh +++ b/install/alpine-docker-install.sh @@ -59,4 +59,4 @@ if echo "$prompt" | grep -Eq "^(y|yes)$"; then fi motd_ssh -root \ No newline at end of file +customize \ No newline at end of file diff --git a/install/alpine-grafana-install.sh b/install/alpine-grafana-install.sh index d20a7aca..09dc91ef 100644 --- a/install/alpine-grafana-install.sh +++ b/install/alpine-grafana-install.sh @@ -29,4 +29,4 @@ $STD rc-update add grafana default msg_ok "Installed Grafana" motd_ssh -root \ No newline at end of file +customize \ No newline at end of file diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index f048745b..9d8b628d 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -37,4 +37,4 @@ $STD rc-update add vaultwarden default msg_ok "Installed Alpine-Vaultwarden" motd_ssh -root \ No newline at end of file +customize \ No newline at end of file diff --git a/install/alpine-whoogle-install.sh b/install/alpine-whoogle-install.sh index b85e76d0..d6cfcc69 100644 --- a/install/alpine-whoogle-install.sh +++ b/install/alpine-whoogle-install.sh @@ -49,4 +49,4 @@ rc-update add -q whoogle default msg_ok "Installed Alpine-Whoogle" motd_ssh -root +customize diff --git a/install/alpine-zigbee2mqtt-install.sh b/install/alpine-zigbee2mqtt-install.sh index 4abf334e..322e6e5f 100644 --- a/install/alpine-zigbee2mqtt-install.sh +++ b/install/alpine-zigbee2mqtt-install.sh @@ -26,4 +26,4 @@ $STD apk add zigbee2mqtt msg_ok "Installed Alpine-Zigbee2MQTT" motd_ssh -root \ No newline at end of file +customize \ No newline at end of file diff --git a/install/audiobookshelf-install.sh b/install/audiobookshelf-install.sh index 5586918e..0de9f082 100644 --- a/install/audiobookshelf-install.sh +++ b/install/audiobookshelf-install.sh @@ -28,7 +28,7 @@ $STD apt install audiobookshelf msg_ok "Installed audiobookshelf" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/autobrr-install.sh b/install/autobrr-install.sh index dbf1cea3..5a50883d 100644 --- a/install/autobrr-install.sh +++ b/install/autobrr-install.sh @@ -49,7 +49,7 @@ systemctl enable --now -q autobrr.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh index bd395f66..9e847172 100755 --- a/install/bazarr-install.sh +++ b/install/bazarr-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y unzip $STD apt-get install -y python3-pip msg_ok "Installed Dependencies" @@ -53,7 +52,7 @@ systemctl enable -q --now bazarr msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm -rf bazarr.zip diff --git a/install/blocky-install.sh b/install/blocky-install.sh index 3f0409bf..6ef5abcc 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -282,7 +282,7 @@ $STD systemctl enable --now blocky msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/casaos-install.sh b/install/casaos-install.sh index cf4ee609..c0a068d0 100644 --- a/install/casaos-install.sh +++ b/install/casaos-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y unzip msg_ok "Installed Dependencies" msg_info "Installing CasaOS (Patience)" @@ -37,7 +36,7 @@ $STD bash <(curl -fsSL https://get.casaos.io) msg_ok "Installed CasaOS" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 53c78041..34e0bcca 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -43,7 +43,7 @@ $STD systemctl enable --now changedetection msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/cloudflared-install.sh b/install/cloudflared-install.sh index d75c0191..921da7cd 100644 --- a/install/cloudflared-install.sh +++ b/install/cloudflared-install.sh @@ -28,7 +28,7 @@ $STD apt-get install -y cloudflared msg_ok "Installed Cloudflared" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/cronicle-install.sh b/install/cronicle-install.sh index 281a6f19..9f9073c3 100644 --- a/install/cronicle-install.sh +++ b/install/cronicle-install.sh @@ -48,7 +48,7 @@ $STD update-rc.d cronicled defaults msg_ok "Installed Cronicle Primary Server" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/daemonsync-install.sh b/install/daemonsync-install.sh index dead1801..8118f42b 100644 --- a/install/daemonsync-install.sh +++ b/install/daemonsync-install.sh @@ -26,7 +26,7 @@ $STD dpkg -i daemonsync_2.2.0.0059_amd64.deb msg_ok "Installed Daemon Sync Server" motd_ssh -root +customize msg_info "Cleaning up" rm -rf daemonsync_2.2.0.0059_amd64.deb diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 089fcdde..6bb812f7 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -57,7 +57,7 @@ systemctl start dashy msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/debian-install.sh b/install/debian-install.sh index 0e4905fb..af84fbb8 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/deconz-install.sh b/install/deconz-install.sh index 068cf5f3..eab4d521 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -50,7 +50,7 @@ $STD systemctl enable --now deconz msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/deluge-install.sh b/install/deluge-install.sh index 1a55fb27..b42e24f6 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -65,7 +65,7 @@ systemctl enable --now -q deluge-web.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/devuan-install.sh b/install/devuan-install.sh index eb2b237b..64e6f242 100644 --- a/install/devuan-install.sh +++ b/install/devuan-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/docker-install.sh b/install/docker-install.sh index c2a33444..8240ed8f 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -69,7 +69,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then fi motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/emby-install.sh b/install/emby-install.sh index 668222f7..52fc3af6 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -19,7 +19,7 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then +if [[ "$CTTYPE" == "0" ]]; then msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install \ va-driver-all \ @@ -43,7 +43,7 @@ $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb msg_ok "Installed Emby" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/emqx-install.sh b/install/emqx-install.sh index 74b3c2d3..a1d69324 100644 --- a/install/emqx-install.sh +++ b/install/emqx-install.sh @@ -26,7 +26,7 @@ $STD systemctl enable --now emqx msg_ok "Installed EMQX" motd_ssh -root +customize msg_info "Cleaning up" apt-get autoremove >/dev/null diff --git a/install/esphome-install.sh b/install/esphome-install.sh index fe8e8e46..ce0224f0 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -46,7 +46,7 @@ systemctl start esphomeDashboard msg_ok "Installed ESPHome Dashboard" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/fhem-install.sh b/install/fhem-install.sh index caf99993..e3ce0f67 100644 --- a/install/fhem-install.sh +++ b/install/fhem-install.sh @@ -32,7 +32,7 @@ $STD apt-get install -y fhem msg_info "Installed Fhem" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/go2rtc-install.sh b/install/go2rtc-install.sh index 75211aeb..a5092fd8 100644 --- a/install/go2rtc-install.sh +++ b/install/go2rtc-install.sh @@ -43,7 +43,7 @@ systemctl enable -q --now go2rtc msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/grafana-install.sh b/install/grafana-install.sh index 1ab76079..6f5a3efc 100644 --- a/install/grafana-install.sh +++ b/install/grafana-install.sh @@ -35,7 +35,7 @@ systemctl enable --now -q grafana-server.service msg_ok "Installed Grafana" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/grocy-install.sh b/install/grocy-install.sh index b51cfbcc..47da262c 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -18,7 +18,6 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y apache2 -$STD apt-get install -y unzip $STD apt-get install -y apt-transport-https $STD apt-get install -y lsb-release msg_ok "Installed Dependencies" @@ -63,7 +62,7 @@ systemctl reload apache2 msg_ok "Installed grocy" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index df8e7cc2..78d3be90 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -58,7 +58,7 @@ $STD sudo systemctl enable --now heimdall.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index f7cc1c9c..663e5e99 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -100,7 +100,7 @@ $STD systemctl enable --now homeassistant msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index ab92e64a..789ec5ea 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -84,7 +84,7 @@ $STD docker run -d \ msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh index 463b7ab8..ed071136 100644 --- a/install/homebridge-install.sh +++ b/install/homebridge-install.sh @@ -32,7 +32,7 @@ $STD apt-get install -y homebridge msg_info "Installed Homebridge" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 7cabc3c3..3f5c85d9 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -58,7 +58,7 @@ $STD systemctl enable --now homepage msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/homer-install.sh b/install/homer-install.sh index 197af604..f4a8d3eb 100644 --- a/install/homer-install.sh +++ b/install/homer-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y unzip $STD apt-get install -y pip msg_ok "Installed Dependencies" @@ -46,7 +45,7 @@ $STD systemctl enable --now homer msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh index f8a3df3c..17971c57 100644 --- a/install/hyperion-install.sh +++ b/install/hyperion-install.sh @@ -31,7 +31,7 @@ $STD systemctl enable --now hyperion@root.service msg_ok "Installed Hyperion" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove >/dev/null diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh index 8167b01f..b1683824 100644 --- a/install/influxdb-install.sh +++ b/install/influxdb-install.sh @@ -55,7 +55,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then fi motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/iobroker-install.sh b/install/iobroker-install.sh index 5146abea..ae553a46 100644 --- a/install/iobroker-install.sh +++ b/install/iobroker-install.sh @@ -24,7 +24,7 @@ $STD bash <(curl -fsSL https://iobroker.net/install.sh) msg_ok "Installed ioBroker" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/jackett-install.sh b/install/jackett-install.sh index b4982d3c..e54858d5 100644 --- a/install/jackett-install.sh +++ b/install/jackett-install.sh @@ -46,7 +46,7 @@ systemctl enable -q --now jackett.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index 98d427b0..1477ef87 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y gnupg $STD apt-get install -y mc msg_ok "Installed Dependencies" -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then +if [[ "$CTTYPE" == "0" ]]; then msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install \ va-driver-all \ @@ -59,7 +59,7 @@ $STD apt-get install -y jellyfin msg_ok "Installed Jellyfin" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/k0s-install.sh b/install/k0s-install.sh index 7e772932..323bbebe 100644 --- a/install/k0s-install.sh +++ b/install/k0s-install.sh @@ -35,7 +35,7 @@ $STD bash <(curl -sSLf https://raw.githubusercontent.com/helm/helm/main/scripts/ msg_ok "Installed Helm" fi motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/kavita-install.sh b/install/kavita-install.sh index eaf48992..b3fe9267 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -46,7 +46,7 @@ systemctl enable --now -q kavita.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh index 0dcf8c8f..ba9d4198 100644 --- a/install/keycloak-install.sh +++ b/install/keycloak-install.sh @@ -43,7 +43,7 @@ $STD systemctl enable --now keycloak.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/lidarr-install.sh b/install/lidarr-install.sh index a7ec14d2..e03c7680 100644 --- a/install/lidarr-install.sh +++ b/install/lidarr-install.sh @@ -51,7 +51,7 @@ systemctl enable --now -q lidarr msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm -rf Lidarr.master.*.tar.gz diff --git a/install/magicmirror-install.sh b/install/magicmirror-install.sh index 249f46a6..f262b885 100644 --- a/install/magicmirror-install.sh +++ b/install/magicmirror-install.sh @@ -148,7 +148,7 @@ $STD systemctl enable --now magicmirror msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index a3326a35..3fefa9b1 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -35,7 +35,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then fi motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh index 3defc5eb..bd76b239 100644 --- a/install/meshcentral-install.sh +++ b/install/meshcentral-install.sh @@ -35,7 +35,7 @@ $STD node node_modules/meshcentral --install msg_ok "Installed MeshCentral" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index cbb1a732..5ebe8fc7 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -51,7 +51,7 @@ systemctl enable -q --now motioneye msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 135abf56..71e0ef9a 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -31,7 +31,7 @@ $STD apt-get -y install mosquitto-clients msg_ok "Installed Mosquitto MQTT Broker" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 7e735a09..0c2c1cd2 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -46,7 +46,7 @@ $STD systemctl enable --now n8n msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh index 67f255a2..d1a890db 100644 --- a/install/navidrome-install.sh +++ b/install/navidrome-install.sh @@ -75,7 +75,7 @@ $STD systemctl enable --now navidrome.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh index a2ac437c..912e5ad6 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-install.sh @@ -28,7 +28,7 @@ service apache2 restart msg_ok "Installed NextCloudPi" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 8d797267..1300266d 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -182,7 +182,7 @@ EOF msg_ok "Created Service" motd_ssh -root +customize msg_info "Starting Services" sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh index 63bf1ca6..8435fc06 100644 --- a/install/nocodb-install.sh +++ b/install/nocodb-install.sh @@ -53,7 +53,7 @@ systemctl enable --now nocodb.service &>/dev/null msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/node-red-install.sh b/install/node-red-install.sh index fd2760f4..8e4d803b 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -56,7 +56,7 @@ $STD systemctl enable --now nodered.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh index b871219a..132eedd1 100644 --- a/install/octoprint-install.sh +++ b/install/octoprint-install.sh @@ -69,7 +69,7 @@ systemctl enable -q --now octoprint.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/omada-install.sh b/install/omada-install.sh index 6a359884..adcfe5aa 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -30,7 +30,7 @@ $STD dpkg -i Omada_SDN_Controller_v5.9.31_Linux_x64.deb msg_ok "Installed Omada Controller" motd_ssh -root +customize msg_info "Cleaning up" rm -f Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb diff --git a/install/omv-install.sh b/install/omv-install.sh index be058e99..90911799 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -42,7 +42,7 @@ omv-confdbadm populate msg_ok "Installed OpenMediaVault" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/openhab-install.sh b/install/openhab-install.sh index 43d5454b..f87848f3 100644 --- a/install/openhab-install.sh +++ b/install/openhab-install.sh @@ -41,7 +41,7 @@ $STD systemctl enable --now openhab.service msg_ok "Installed openHAB" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 55820dbb..ca2679af 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -27,7 +27,7 @@ $STD apt-get install -y --no-install-recommends \ redis \ postgresql \ build-essential \ - imagemagick \ + imagemagick \ fonts-liberation \ optipng \ gnupg \ @@ -192,7 +192,7 @@ $STD systemctl enable --now paperless-consumer paperless-webserver paperless-sch msg_ok "Created Services" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 92c00afb..df63bd6e 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -23,7 +23,6 @@ $STD apt-get install -y git $STD apt-get install -y gnupg $STD apt-get install -y make $STD apt-get install -y zip -$STD apt-get install -y unzip $STD apt-get install -y exiftool $STD apt-get install -y ffmpeg msg_ok "Installed Dependencies" @@ -119,7 +118,7 @@ WantedBy=multi-user.target" >$service_path msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/pihole-install.sh b/install/pihole-install.sh index 8cf049f7..9006ae2f 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -46,7 +46,7 @@ $STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended msg_ok "Installed Pi-hole" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/plex-install.sh b/install/plex-install.sh index 127d4a11..5e7fda8d 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -19,7 +19,7 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -if [[ -z "$(grep -w "100000" /proc/self/uid_map)" ]]; then +if [[ "$CTTYPE" == "0" ]]; then msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install \ va-driver-all \ @@ -46,7 +46,7 @@ $STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver msg_ok "Installed Plex Media Server" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/podman-homeassistant-install.sh b/install/podman-homeassistant-install.sh index 70351f5e..a0fb4f5e 100644 --- a/install/podman-homeassistant-install.sh +++ b/install/podman-homeassistant-install.sh @@ -46,7 +46,7 @@ $STD systemctl enable --now homeassistant msg_ok "Installed Home Assistant" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/podman-install.sh b/install/podman-install.sh index 8c248463..951da53b 100644 --- a/install/podman-install.sh +++ b/install/podman-install.sh @@ -26,7 +26,7 @@ echo -e 'unqualified-search-registries=["docker.io"]' >> /etc/containers/registr msg_ok "Installed Podman" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/postgresql-install.sh b/install/postgresql-install.sh index 53fb2a25..5f455031 100644 --- a/install/postgresql-install.sh +++ b/install/postgresql-install.sh @@ -142,7 +142,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then fi motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/prometheus-install.sh b/install/prometheus-install.sh index 118241fd..f2aad6fd 100644 --- a/install/prometheus-install.sh +++ b/install/prometheus-install.sh @@ -55,7 +55,7 @@ $STD sudo systemctl enable --now prometheus msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/prowlarr-install.sh b/install/prowlarr-install.sh index 638d93c1..b999d9b5 100644 --- a/install/prowlarr-install.sh +++ b/install/prowlarr-install.sh @@ -49,7 +49,7 @@ systemctl enable --now -q prowlarr msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm -rf Prowlarr.master.*.tar.gz diff --git a/install/qbittorrent-install.sh b/install/qbittorrent-install.sh index 6995f6bb..1a6147d2 100644 --- a/install/qbittorrent-install.sh +++ b/install/qbittorrent-install.sh @@ -38,7 +38,7 @@ systemctl enable -q --now qbittorrent-nox msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/radarr-install.sh b/install/radarr-install.sh index 4c736895..f9e88aa5 100644 --- a/install/radarr-install.sh +++ b/install/radarr-install.sh @@ -49,7 +49,7 @@ systemctl enable --now -q radarr msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm -rf Radarr.master.*.tar.gz diff --git a/install/readarr-install.sh b/install/readarr-install.sh index 9452caa3..43897970 100644 --- a/install/readarr-install.sh +++ b/install/readarr-install.sh @@ -49,7 +49,7 @@ systemctl enable --now -q readarr msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm -rf Readarr.develop.*.tar.gz diff --git a/install/rstptoweb-install.sh b/install/rstptoweb-install.sh index 76c3792d..d345a102 100644 --- a/install/rstptoweb-install.sh +++ b/install/rstptoweb-install.sh @@ -53,7 +53,7 @@ systemctl enable -q --now rtsptoweb msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index b779e31d..6c53de93 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y unzip $STD apt-get install -y par2 $STD apt-get install -y p7zip-full wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_6.0.3-1+deb11u1_amd64.deb @@ -54,7 +53,7 @@ systemctl enable --now -q sabnzbd.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index dd766825..b1df07e1 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -110,7 +110,7 @@ $STD systemctl enable --now scrypted.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index d6682ba3..3d8801dd 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -82,7 +82,7 @@ $STD pm2 list msg_ok "Installed Shinobi" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index db1a7bf4..099257b0 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -29,7 +29,7 @@ DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" inst msg_ok "Installed Sonarr" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh index 14cd1b99..3e8eef08 100644 --- a/install/syncthing-install.sh +++ b/install/syncthing-install.sh @@ -33,7 +33,7 @@ systemctl restart syncthing@root.service msg_ok "Installed Syncthing" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index 43a6a316..80ee51f7 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -50,7 +50,7 @@ systemctl enable -q --now tautulli msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index 02a7baa8..5e097586 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y unzip msg_ok "Installed Dependencies" if [[ "$CTTYPE" == "0" ]]; then @@ -90,7 +89,7 @@ systemctl enable --now -q tdarr-node.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm -rf Tdarr_Updater.zip diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index a795fa37..4f3f6c98 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -35,7 +35,7 @@ $STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) msg_ok "Installed Technitium DNS" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/transmission-install.sh b/install/transmission-install.sh index 1c7c6f0c..969e6aea 100644 --- a/install/transmission-install.sh +++ b/install/transmission-install.sh @@ -28,7 +28,7 @@ systemctl start transmission-daemon msg_ok "Installed Transmission" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/trilium-install.sh b/install/trilium-install.sh index 02ab6d0f..da811245 100644 --- a/install/trilium-install.sh +++ b/install/trilium-install.sh @@ -50,7 +50,7 @@ systemctl enable --now -q trilium msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/ubuntu-install.sh b/install/ubuntu-install.sh index eb2b237b..64e6f242 100644 --- a/install/ubuntu-install.sh +++ b/install/ubuntu-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/umbrel-install.sh b/install/umbrel-install.sh index 4ec349db..ea4d17ba 100644 --- a/install/umbrel-install.sh +++ b/install/umbrel-install.sh @@ -38,7 +38,7 @@ $STD systemctl enable --now umbrel-startup.service msg_ok "Installed Umbrel" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 9f297731..11515d90 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -38,7 +38,7 @@ $STD apt-get install -y unifi msg_ok "Installed UniFi Network Application" motd_ssh -root +customize msg_info "Cleaning up" rm -rf mongodb-org-server_3.6.23_amd64.deb diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh index d5af2231..c78a890e 100644 --- a/install/uptimekuma-install.sh +++ b/install/uptimekuma-install.sh @@ -53,7 +53,7 @@ $STD systemctl enable --now uptime-kuma.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/vaultwarden-install.sh b/install/vaultwarden-install.sh index fe0edc19..65061b80 100644 --- a/install/vaultwarden-install.sh +++ b/install/vaultwarden-install.sh @@ -111,7 +111,7 @@ $STD systemctl enable --now vaultwarden.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/whisparr-install.sh b/install/whisparr-install.sh index 64b757f5..422ae576 100644 --- a/install/whisparr-install.sh +++ b/install/whisparr-install.sh @@ -49,7 +49,7 @@ systemctl enable --now -q whisparr msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm -rf Whisparr.develop.*.tar.gz diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index 943c59ad..1eb492f2 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -42,7 +42,7 @@ $STD systemctl enable --now whoogle.service msg_ok "Installed Whoogle" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index 4bea8690..32152da6 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -70,7 +70,7 @@ $STD systemctl enable --now wikijs msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh index f63333c9..a133b2df 100644 --- a/install/wireguard-install.sh +++ b/install/wireguard-install.sh @@ -41,7 +41,7 @@ $STD bash <(curl -fsSL https://install.pivpn.io) --unattended options.conf msg_ok "Installed WireGuard" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/yunohost-install.sh b/install/yunohost-install.sh index 48e7bbd6..aaeadc1b 100644 --- a/install/yunohost-install.sh +++ b/install/yunohost-install.sh @@ -30,7 +30,7 @@ $STD bash <(curl -fsSL https://install.yunohost.org) -a msg_ok "Installed YunoHost" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index ca4e2905..eb10fdd6 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -69,7 +69,7 @@ $STD systemctl enable zigbee2mqtt.service msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh index 67862f1f..a9a05c3e 100644 --- a/install/zwave-js-ui-install.sh +++ b/install/zwave-js-ui-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y unzip msg_ok "Installed Dependencies" msg_info "Installing Z-Wave JS UI" @@ -45,7 +44,7 @@ $STD systemctl enable zwave-js-ui msg_ok "Created Service" motd_ssh -root +customize msg_info "Cleaning up" rm zwave-js-ui-${RELEASE}-linux.zip diff --git a/misc/alpine-install.func b/misc/alpine-install.func index a7d282d9..ce38abed 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -117,13 +117,9 @@ motd_ssh() { } customize() { + if [[ "$PASSWORD" == "" ]]; then msg_info "Customizing Container" bash -c "passwd -d root" >/dev/null 2>&1 msg_ok "Customized Container" -} - -root() { - if ! getent shadow root | grep -q '^root:[^:]*:\?\$'; then - customize fi -} +} \ No newline at end of file diff --git a/misc/build.func b/misc/build.func index 39438910..2b426d1f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -169,7 +169,7 @@ advanced_settings() { if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then PW1="Automatic Login" - PW=" " + PW="" else PW="-password $PW1" fi diff --git a/misc/install.func b/misc/install.func index d4bf0af0..df2c9cd6 100644 --- a/misc/install.func +++ b/misc/install.func @@ -116,6 +116,7 @@ motd_ssh() { } customize() { + if [[ "$PASSWORD" == "" ]]; then msg_info "Customizing Container" GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" mkdir -p $(dirname $GETTY_OVERRIDE) @@ -127,10 +128,5 @@ EOF systemctl daemon-reload systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" -} - -root() { - if ! getent shadow root | grep -q "^root:[^\!*]"; then - customize fi -} +} \ No newline at end of file From 9933ff371173a56eab3436a0ddf1910d228e3b46 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 09:25:03 -0400 Subject: [PATCH 4778/6505] Update paperless-ngx-install.sh shfmt --- install/paperless-ngx-install.sh | 80 ++++++++++++++++---------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index ca2679af..87db1282 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -15,52 +15,52 @@ update_os msg_info "Installing Python3" $STD apt-get install -y --no-install-recommends \ - python3 \ - python3-pip \ - python3-dev \ - python3-setuptools \ - python3-wheel + python3 \ + python3-pip \ + python3-dev \ + python3-setuptools \ + python3-wheel msg_ok "Installed Python3" msg_info "Installing Dependencies (Patience)" $STD apt-get install -y --no-install-recommends \ - redis \ - postgresql \ - build-essential \ - imagemagick \ - fonts-liberation \ - optipng \ - gnupg \ - libpq-dev \ - libmagic-dev \ - mime-support \ - libzbar0 \ - poppler-utils \ - default-libmysqlclient-dev \ - automake \ - libtool \ - pkg-config \ - git \ - curl \ - libtiff-dev \ - libpng-dev \ - libleptonica-dev \ - sudo \ - mc + redis \ + postgresql \ + build-essential \ + imagemagick \ + fonts-liberation \ + optipng \ + gnupg \ + libpq-dev \ + libmagic-dev \ + mime-support \ + libzbar0 \ + poppler-utils \ + default-libmysqlclient-dev \ + automake \ + libtool \ + pkg-config \ + git \ + curl \ + libtiff-dev \ + libpng-dev \ + libleptonica-dev \ + sudo \ + mc msg_ok "Installed Dependencies" msg_info "Installing OCR Dependencies (Patience)" $STD apt-get install -y --no-install-recommends \ - unpaper \ - ghostscript \ - icc-profiles-free \ - qpdf \ - liblept5 \ - libxml2 \ - pngquant \ - zlib1g \ - tesseract-ocr \ - tesseract-ocr-eng + unpaper \ + ghostscript \ + icc-profiles-free \ + qpdf \ + liblept5 \ + libxml2 \ + pngquant \ + zlib1g \ + tesseract-ocr \ + tesseract-ocr-eng msg_ok "Installed OCR Dependencies" msg_info "Installing JBIG2" @@ -76,7 +76,7 @@ msg_ok "Installed JBIG2" msg_info "Installing Paperless-ngx (Patience)" Paperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) cd /opt -$STD wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz +$STD wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz $STD tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ mv paperless-ngx paperless rm paperless-ngx-$Paperlessngx.tar.xz From 1a553a30c93dd16fd9dc7aa91b65fd853d3f7473 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 15:09:54 -0400 Subject: [PATCH 4779/6505] Create CODE-AUDIT.md --- CODE-AUDIT.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 CODE-AUDIT.md diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md new file mode 100644 index 00000000..a3f07aa1 --- /dev/null +++ b/CODE-AUDIT.md @@ -0,0 +1,9 @@ +In the case of the < app > LXC, the process involves running multiple scripts for each application or service.
    +Initially, the `.sh` script is executed to collect system parameters.
    +Next, the `build.func` script adds user settings and integrates all the collected information.
    +Then, the `create_lxc.sh` script constructs the LXC container.
    +Following that, the `-install.sh` script is executed, which utilizes the functions exported from the `install.func` script for installing the required applications.
    +Finally, the process returns to the `.sh` script to display the completion message.
    + +Thoroughly evaluating the `-install.sh` script is crucial to gain a better understanding of the application installation process.
    +Every application installation utilizes the same set of reusable scripts: `build.func`, `create_lxc.sh`, and `install.func`. These scripts are not specific to any particular application.
    From 287a0837d3cabb8328e9a4ed622de8ebff03933e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 15:21:15 -0400 Subject: [PATCH 4780/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc889b20..062073eb 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,5 @@

    Proxmox VE Helper Scripts

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    - +

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.

    Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.
    From 9192b8b076e250d90dd135404d6c58c6523fcb67 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 18:33:04 -0400 Subject: [PATCH 4781/6505] Update install.func added code descriptions --- misc/install.func | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index df2c9cd6..cb835a1d 100644 --- a/misc/install.func +++ b/misc/install.func @@ -1,3 +1,4 @@ +# This function sets color variables for formatting output in the terminal color() { YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -14,6 +15,7 @@ color() { HOLD="-" } +# This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to "yes" verb_ip6() { if [ "$VERBOSE" = "yes" ]; then set -x @@ -26,11 +28,13 @@ verb_ip6() { fi } +# This function sets error handling options and defines the error_handler function to handle errors catch_errors() { set -Eeuo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } +# This function handles errors error_handler() { local exit_code="$?" local line_number="$1" @@ -42,21 +46,25 @@ error_handler() { fi } +# This function prints an informational message msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } +# This function prints a success message msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +# This function prints an error message msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection setting_up_container() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen @@ -79,6 +87,7 @@ setting_up_container() { msg_ok "Network Connected: ${BL}$(hostname -I)" } +# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected network_check() { set +e trap - ERR @@ -98,6 +107,7 @@ network_check() { trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } +# This function updates the Container OS by running apt-get update and upgrade update_os() { msg_info "Updating Container OS" $STD apt-get update @@ -105,6 +115,7 @@ update_os() { msg_ok "Updated Container OS" } +# This function modifies the message of the day (motd) and SSH settings motd_ssh() { echo "export TERM='xterm-256color'" >>/root/.bashrc echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" >/etc/motd @@ -115,6 +126,7 @@ motd_ssh() { fi } +# This function customizes the container by modifying the getty service and enabling auto-login for the root user customize() { if [[ "$PASSWORD" == "" ]]; then msg_info "Customizing Container" @@ -129,4 +141,4 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi -} \ No newline at end of file +} From 3a06811e01dfc5132c4bcef68557224d9055c680 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 18:55:53 -0400 Subject: [PATCH 4782/6505] Update build.func added code descriptions --- misc/build.func | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index 2b426d1f..dce870e0 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1,9 +1,10 @@ variables() { - NSAPP=$(echo ${APP,,} | tr -d ' ') - var_install="${NSAPP}-install" - INTEGER='^[0-9]+([.][0-9]+)?$' + NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. } +# This function sets various color variables using ANSI escape codes for formatting text in the terminal. color() { YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -18,11 +19,13 @@ color() { HOLD="-" } +# This function enables error handling in the script by setting options and defining a trap for the ERR signal. catch_errors() { set -Eeuo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR } +# This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { local exit_code="$?" local line_number="$1" @@ -31,21 +34,25 @@ error_handler() { echo -e "\n$error_message\n" } +# This function displays an informational message with a yellow color. msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } +# This function displays a success message with a green color. msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +# This function displays an error message with a red color. msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" @@ -56,6 +63,7 @@ pve_check() { fi } +# This function checks the system architecture and exits if it's not "amd64". arch_check() { if [ "$(dpkg --print-architecture)" != "amd64" ]; then echo -e "\n ${CROSS} This script will not work with PiMox! \n" @@ -65,6 +73,7 @@ arch_check() { fi } +# This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. ssh_check() { if command -v pveversion >/dev/null 2>&1; then if [ -n "${SSH_CLIENT:+x}" ]; then @@ -78,6 +87,7 @@ ssh_check() { fi } +# This function displays the default values for various settings. echo_default() { echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}" echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" @@ -105,12 +115,14 @@ echo_default() { echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } +# This function is called when the user decides to exit the script. It clears the screen and displays an exit message. exit-script() { clear echo -e "⚠ User exited script \n" exit } +# This function allows the user to configure advanced settings for the script. advanced_settings() { whiptail --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 whiptail --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n" 8 58 @@ -433,6 +445,7 @@ start() { fi } +# This function collects user settings and integrates all the collected information. build_container() { if [ "$VERB" == "yes" ]; then set -x; fi @@ -485,6 +498,7 @@ build_container() { -unprivileged $CT_TYPE $PW " + # This executes create_lxc.sh and creates the container and .conf file bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf @@ -519,6 +533,7 @@ EOF fi fi +# This starts the container and executes -install.sh msg_info "Starting LXC Container" pct start "$CTID" msg_ok "Started LXC Container" @@ -530,6 +545,7 @@ EOF } +# This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) pct set "$CTID" -description "# ${APP} LXC From caea206144c8b9f03c241ea2b9a12ced884ee288 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 19:15:26 -0400 Subject: [PATCH 4783/6505] Update create_lxc.sh added code descriptions --- ct/create_lxc.sh | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 6fd83826..4cf41103 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -5,7 +5,10 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE +# This sets verbose mode if the global variable is set to "yes" if [ "$VERBOSE" == "yes" ]; then set -x; fi + +# This function sets color variables for formatting output in the terminal YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -15,8 +18,12 @@ CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" HOLD="-" + +# This sets error handling options and defines the error_handler function to handle errors set -Eeuo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR + +# This function handles errors function error_handler() { local exit_code="$?" local line_number="$1" @@ -24,20 +31,26 @@ function error_handler() { local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" echo -e "\n$error_message\n" } + +# This function prints an informational message function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } +# This function prints a success message function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + +# This function prints an error message function msg_error() { local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +# This checks for the presence of valid Container Storage and Template Storage locations msg_info "Validating Storage" VALIDCT=$(pvesm status -content rootdir | awk 'NR>1') if [ -z "$VALIDCT" ]; then @@ -50,6 +63,7 @@ if [ -z "$VALIDTMP" ]; then exit 1 fi +# This function is used to select the storage class and determine the corresponding storage content type and label. function select_storage() { local CLASS=$1 local CONTENT @@ -65,7 +79,8 @@ function select_storage() { ;; *) false || exit "Invalid storage class." ;; esac - + + # This Queries all storage locations local -a MENU while read -r line; do local TAG=$(echo $line | awk '{print $1}') @@ -78,7 +93,8 @@ function select_storage() { fi MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') - + + # Select storage location if [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} else @@ -93,32 +109,40 @@ function select_storage() { fi } +# Test if required variables are set [[ "${CTID:-}" ]] || exit "You need to set 'CTID' variable." [[ "${PCT_OSTYPE:-}" ]] || exit "You need to set 'PCT_OSTYPE' variable." +# Test if ID is valid [ "$CTID" -ge "100" ] || exit "ID cannot be less than 100." +# Test if ID is in use if pct status $CTID &>/dev/null; then echo -e "ID '$CTID' is already in use." unset CTID exit "Cannot use ID that is already in use." fi +# Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage." +# Get container storage CONTAINER_STORAGE=$(select_storage container) || exit msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage." +# Update LXC template list msg_info "Updating LXC Template List" pveam update >/dev/null msg_ok "Updated LXC Template List" +# Get LXC template string TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-} mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) [ ${#TEMPLATES[@]} -gt 0 ] || exit "Unable to find a template when searching for '$TEMPLATE_SEARCH'." TEMPLATE="${TEMPLATES[-1]}" +# Download LXC template if needed if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_info "Downloading LXC Template" pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || @@ -126,12 +150,14 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then msg_ok "Downloaded LXC Template" fi +# Combine all options DEFAULT_PCT_OPTIONS=( -arch $(dpkg --print-architecture)) PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) [[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) +# Create container msg_info "Creating LXC Container" pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || exit "A problem occured while trying to create container." From eda9208477f7b8d3a0894d83b0999d3e88b0bb8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 May 2023 19:26:16 -0400 Subject: [PATCH 4784/6505] Update CODE-AUDIT.md --- CODE-AUDIT.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md index a3f07aa1..3515e28a 100644 --- a/CODE-AUDIT.md +++ b/CODE-AUDIT.md @@ -1,9 +1,9 @@ -In the case of the < app > LXC, the process involves running multiple scripts for each application or service.
    -Initially, the `.sh` script is executed to collect system parameters.
    -Next, the `build.func` script adds user settings and integrates all the collected information.
    -Then, the `create_lxc.sh` script constructs the LXC container.
    -Following that, the `-install.sh` script is executed, which utilizes the functions exported from the `install.func` script for installing the required applications.
    -Finally, the process returns to the `.sh` script to display the completion message.
    +In the case of the AdGuard Home LXC, the process involves running multiple scripts for each application or service.
    +Initially, the [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) script is executed to collect system parameters.
    +Next, the [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func) script adds user settings and integrates all the collected information.
    +Then, the [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh) script constructs the LXC container.
    +Following that, the [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh) script is executed, which utilizes the functions exported from the [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func) script for installing the required applications.
    +Finally, the process returns to the [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) script to display the completion message.
    -Thoroughly evaluating the `-install.sh` script is crucial to gain a better understanding of the application installation process.
    -Every application installation utilizes the same set of reusable scripts: `build.func`, `create_lxc.sh`, and `install.func`. These scripts are not specific to any particular application.
    +Thoroughly evaluating the [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh) script is crucial to gain a better understanding of the application installation process.
    +Every application installation utilizes the same set of reusable scripts: [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func), [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh), and [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func). These scripts are not specific to any particular application.
    From 92babeac2322b24f6ad590a28573adc24f8cb6cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 May 2023 00:27:25 -0400 Subject: [PATCH 4785/6505] Update update-lxcs.sh add information about the boot disk, which provides an easy way to determine if you need to expand the disk. --- misc/update-lxcs.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 3590bb84..8a89ee73 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -39,7 +39,9 @@ function update_container() { container=$1 header_info name=$(pct exec "$container" hostname) - echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} \n" + disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') + read -ra disk_info_array <<< "$disk_info" + echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\n" os=$(pct config "$container" | awk '/^ostype/ {print $2}') case "$os" in alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; From c9006a67d60f30e8d83b84cb0f4994e8d013d2cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 May 2023 00:32:39 -0400 Subject: [PATCH 4786/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90582703..59fe70b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-05-16 + +### Changed + +- **Proxmox VE LXC Updater** + - Add information about the boot disk, which provides an easy way to determine if you need to expand the disk. + ## 2023-05-13 ### Changed From 51ee45e88f93a85f3d8dc3c7fd8a52f88c63445c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 May 2023 03:10:49 -0400 Subject: [PATCH 4787/6505] Update kernel-clean.sh add warning for opt-in kernels --- misc/kernel-clean.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 053215af..30660b67 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -8,11 +8,11 @@ function header_info { cat <<"EOF" __ __ __ ________ - / //_/__ _________ ___ / / / ____/ /__ ____ _____ + / //_/__ _________ ___ / / / ____/ /__ ____ _____ / ,< / _ \/ ___/ __ \/ _ \/ / / / / / _ \/ __ `/ __ \ / /| / __/ / / / / / __/ / / /___/ / __/ /_/ / / / / -/_/ |_\___/_/ /_/ /_/\___/_/ \____/_/\___/\__,_/_/ /_/ - +/_/ |_\___/_/ /_/ /_/\___/_/ \____/_/\___/\__,_/_/ /_/ + EOF } set -euo pipefail @@ -69,9 +69,9 @@ function other_kernel() { echo -e "\nAn Active PVE Kernel is required to use Kernel Clean\n" exit 1 fi - if [[ "$current_kernel" == *"6.1"* ]]; then + if [[ "$current_kernel" == *"6.1"* || "$current_kernel" == *"6.2"* ]]; then echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" - echo -e "\nAs 5.15 is the current default kernel in PVE 7.3 the package management directly depends on it, it's not possible to use this script while running 6.1 kernels. (the script tries to remove ALL old kernels) \n" + echo -e "\nThe script cannot be used when running opt-in kernels. \nProxmox VE's package management relies directly on the current default kernel, which is 5.15. \nTherefore, it is not possible to utilize this script. In this case, you should use autoremove instead. \n`apt-get autoremove`\n" exit 1 fi } From ce1e4b7d29fd4f5fe8691424e5494ed8e68143af Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 May 2023 11:20:28 -0400 Subject: [PATCH 4788/6505] Update microcode.sh new microcode --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 4fc7c8d9..6f45e82c 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -56,7 +56,7 @@ intel() { msg_ok "Installed iucode-tool" msg_info "Downloading the latest Intel Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230214.1_amd64.deb + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230512.1_amd64.deb msg_ok "Downloaded the latest Intel Processor Microcode Package" msg_info "Installing the Intel Processor Microcode (Patience)" From bfa0728054017b8dfd388e4675906fe995ff5469 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 May 2023 11:24:40 -0400 Subject: [PATCH 4789/6505] Update microcode.sh --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 6f45e82c..24315f3b 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -60,7 +60,7 @@ intel() { msg_ok "Downloaded the latest Intel Processor Microcode Package" msg_info "Installing the Intel Processor Microcode (Patience)" - dpkg -i intel-microcode_3.20230214.1_amd64.deb &>/dev/null + dpkg -i intel-microcode_3.20230512.1_amd64.deb &>/dev/null msg_ok "Installed the Intel Processor Microcode" msg_info "Cleaning up" From d7b762398a381250b48c34fc4d6947819bc6d84f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 May 2023 11:48:36 -0400 Subject: [PATCH 4790/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59fe70b5..0ade68a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - **Proxmox VE LXC Updater** - Add information about the boot disk, which provides an easy way to determine if you need to expand the disk. +- **Proxmox VE Processor Microcode** + - [Intel microcode-20230512 Release](https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/tag/microcode-20230512) ## 2023-05-13 From c62e3f7ed40ea985423901f1800d69a208285a3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 May 2023 11:50:55 -0400 Subject: [PATCH 4791/6505] Update microcode.sh --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 24315f3b..5d799b81 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -64,7 +64,7 @@ intel() { msg_ok "Installed the Intel Processor Microcode" msg_info "Cleaning up" - rm intel-microcode_3.20230214.1_amd64.deb + rm intel-microcode_3.20230512.1_amd64.deb msg_ok "Cleaned" echo -e "\n To apply the changes, the system will need to be rebooted.\n" From f480487b12f643dfcd3dac51aa2c3f87f9b45434 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 May 2023 09:15:06 -0400 Subject: [PATCH 4792/6505] Update CODE-AUDIT.md --- CODE-AUDIT.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md index 3515e28a..f1c40e9b 100644 --- a/CODE-AUDIT.md +++ b/CODE-AUDIT.md @@ -1,3 +1,5 @@ +

    Exploring the Scripts and Steps Involved in an Application LXC Installation

    + In the case of the AdGuard Home LXC, the process involves running multiple scripts for each application or service.
    Initially, the [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) script is executed to collect system parameters.
    Next, the [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func) script adds user settings and integrates all the collected information.
    From 9ca7ef55ddfa076b9ff57515b8624dd299cc86ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 May 2023 15:01:30 -0400 Subject: [PATCH 4793/6505] Remove Alpine applications that are not installed through the Alpine package manager. --- ct/alpine-adguard.sh | 90 ------------------------------- ct/alpine-whoogle.sh | 88 ------------------------------ install/alpine-adguard-install.sh | 36 ------------- install/alpine-whoogle-install.sh | 52 ------------------ 4 files changed, 266 deletions(-) delete mode 100644 ct/alpine-adguard.sh delete mode 100644 ct/alpine-whoogle.sh delete mode 100644 install/alpine-adguard-install.sh delete mode 100644 install/alpine-whoogle-install.sh diff --git a/ct/alpine-adguard.sh b/ct/alpine-adguard.sh deleted file mode 100644 index 929708a5..00000000 --- a/ct/alpine-adguard.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { - clear - cat <<"EOF" - ___ __ __ - / | ____/ /___ ___ ______ __________/ / - / /| |/ __ / __ / / / / __ / ___/ __ / - / ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / -/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/ - /____/ Alpine - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-AdGuard" -var_disk="0.3" -var_cpu="1" -var_ram="256" -var_os="alpine" -var_version="3.17" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET="dhcp" - GATE="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { - if ! apk -e info newt >/dev/null 2>&1; then - apk add -q newt - fi - while true; do - CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ - "1" "Update LXC OS" \ - "2" "Manually Update AdGuardHome" 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - clear - exit-script - fi - header_info - case $CHOICE in - 1) - apk update && apk upgrade - exit - ;; - 2) - header_info - echo "In the process of creating a method to update" - exit - ;; - esac - done -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" diff --git a/ct/alpine-whoogle.sh b/ct/alpine-whoogle.sh deleted file mode 100644 index 02dec1f1..00000000 --- a/ct/alpine-whoogle.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { - clear - cat <<"EOF" - _ ____ __ -| | / / /_ ____ ____ ____ _/ /__ -| | /| / / __ \/ __ \/ __ \/ __ `/ / _ \ -| |/ |/ / / / / /_/ / /_/ / /_/ / / __/ -|__/|__/_/ /_/\____/\____/\__, /_/\___/ - Alpine /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="Alpine-Whoogle" -var_disk="0.3" -var_cpu="1" -var_ram="256" -var_os="alpine" -var_version="3.17" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET="dhcp" - GATE="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { - if [[ ! -f /usr/bin/whoogle-search ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - while true; do - CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ - "1" "Check for Whoogle Updates" 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - clear - exit-script - fi - header_info - case $CHOICE in - 1) - msg_info "Updating Whoogle" - pip3 install whoogle-search --upgrade &>/dev/null - rc-service -q whoogle restart - msg_ok "Updated Successfully!" - exit - ;; - esac - done -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" diff --git a/install/alpine-adguard-install.sh b/install/alpine-adguard-install.sh deleted file mode 100644 index b43c55ce..00000000 --- a/install/alpine-adguard-install.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" - -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apk add newt -$STD apk add curl -$STD apk add nano -$STD apk add mc -$STD apk add openssh -msg_ok "Installed Dependencies" - -msg_info "Installing Alpine-AdGuard" -VER=$(curl --silent -qI https://github.com/AdguardTeam/AdGuardHome/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); -$STD wget -q "https://github.com/AdguardTeam/AdGuardHome/releases/download/$VER/AdGuardHome_linux_amd64.tar.gz" -$STD tar -xvf AdGuardHome_linux_amd64.tar.gz >/dev/null 2>&1 -$STD mv AdGuardHome /opt -$STD rm AdGuardHome_linux_amd64.tar.gz -$STD chmod +x /opt/AdGuardHome/AdGuardHome -$STD /opt/AdGuardHome/AdGuardHome -s install -$STD /opt/AdGuardHome/AdGuardHome -s start -msg_ok "Installed Alpine-AdGuard" - -motd_ssh -customize diff --git a/install/alpine-whoogle-install.sh b/install/alpine-whoogle-install.sh deleted file mode 100644 index d6cfcc69..00000000 --- a/install/alpine-whoogle-install.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" - -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apk add newt -$STD apk add curl -$STD apk add openssh -$STD apk add nano -$STD apk add mc -msg_ok "Installed Dependencies" - -msg_info "Installing pip3 Package Manager" -$STD apk add py3-pip -msg_ok "Installed pip3 Package Manager" - -msg_info "Installing Alpine-Whoogle" -$STD pip3 install brotli -$STD pip3 install whoogle-search - -echo "#!/sbin/openrc-run -description=\"Whoogle-Search\" -pidfile=\"/run/whoogle.pid\" - -start() { - /usr/bin/whoogle-search --host 0.0.0.0 & - echo \$! > \$pidfile -} - -stop() { - kill \$(cat \$pidfile) - rm \$pidfile -}" >/etc/init.d/whoogle - -chmod 755 /etc/init.d/whoogle -rc-service -q whoogle start -rc-update add -q whoogle default -msg_ok "Installed Alpine-Whoogle" - -motd_ssh -customize From ad65c825b890c010c12ff480edff8bdcbd4858e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 May 2023 15:30:20 -0400 Subject: [PATCH 4794/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ade68a1..7699e2c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ # Change Log All notable changes to this project will be documented in this file. +## 2023-05-17 + +### Changed + +- **Alpine-AdGuard Home LXC** + - Removed, it wasn't installed through the Alpine package manager. +- **Alpine-Whoogle LXC** + - Removed, it wasn't installed through the Alpine package manager. + ## 2023-05-16 ### Changed From c71f204e263f9ba80017b8377d638dc5571b5b5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 May 2023 17:52:16 -0400 Subject: [PATCH 4795/6505] Update update-lxcs.sh add no disk info message --- misc/update-lxcs.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 8a89ee73..8fc2a38f 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -10,10 +10,10 @@ clear cat <<"EOF" __ __ __ __ __ _ ________ / / / /___ ____/ /___ _/ /____ / / | |/ / ____/ - / / / / __ \/ __ / __ `/ __/ _ \ / / | / / -/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___ -\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/ - /_/ + / / / / __ \/ __ / __ `/ __/ _ \ / / | / / +/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___ +\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/ + /_/ EOF } @@ -39,10 +39,14 @@ function update_container() { container=$1 header_info name=$(pct exec "$container" hostname) - disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') - read -ra disk_info_array <<< "$disk_info" - echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\n" os=$(pct config "$container" | awk '/^ostype/ {print $2}') + if [[ "$os" == "ubuntu" || "$os" == "debian" ]]; then + disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') + read -ra disk_info_array <<< "$disk_info" + echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\n" + else + echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} ${YW}[No disk info for ${os}]${CL}\n" + fi case "$os" in alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm";; From bb0f9e7a0a6eb6c4fbe5905d7e3005d90df5680a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 May 2023 17:56:11 -0400 Subject: [PATCH 4796/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 8fc2a38f..4c293179 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -45,7 +45,7 @@ function update_container() { read -ra disk_info_array <<< "$disk_info" echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\n" else - echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} ${YW}[No disk info for ${os}]${CL}\n" + echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}[No disk info for ${os}]${CL}\n" fi case "$os" in alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; From f80821cf7bb2aef072677c9596c0f175355b4795 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 May 2023 06:33:09 -0400 Subject: [PATCH 4797/6505] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7699e2c9..5dd961db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Change Log -All notable changes to this project will be documented in this file. +**All notable changes to this project will be documented in this file.**
    + +- All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. ## 2023-05-17 From db8d22f721ceed662517c4a2766c9ae09988bc19 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 May 2023 17:06:08 -0400 Subject: [PATCH 4798/6505] Update haos-vm.sh code refactoring --- vm/haos-vm.sh | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 46c4bc08..8709ebc6 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -10,9 +10,9 @@ function header_info { cat <<"EOF" __ __ ___ _ __ __ ____ _____ / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ - / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ EOF } @@ -168,17 +168,14 @@ function advanced_settings() { if VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z "$VMID" ]; then VMID="$NEXTID" - echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" - break - else - if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then - echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" - sleep 2 - continue - fi - echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" - break fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break else exit-script fi From e861c41e163b791750d9dd3750de21624cb1f773 Mon Sep 17 00:00:00 2001 From: diemade Date: Sun, 21 May 2023 14:17:52 +0200 Subject: [PATCH 4799/6505] Update README.md (#1433) 1 grammar fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 062073eb..b096cadb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Contributing to Proxmox VE Helper Scripts

    -These script's allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine. +These scripts allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine.

    Proxmox VE Helper Scripts

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    From fcce5d0570420728f677ff38729f9d55ac775132 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 May 2023 08:18:42 -0400 Subject: [PATCH 4800/6505] Update README.md more grammar fixes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b096cadb..49968ca7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Contributing to Proxmox VE Helper Scripts

    -These scripts allows for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command and the script collects and validates the user's input to generate the final configuration of the container or virtual machine. +These scripts allow for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command, and the script collects and validates the user's input to generate the final configuration of the container or virtual machine.

    Proxmox VE Helper Scripts

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    From 6a108a06cea25ac5d9960ff0f88c7f74ab7e82fb Mon Sep 17 00:00:00 2001 From: "Jon \"The Nice Guy\" Spriggs" Date: Mon, 22 May 2023 11:54:10 +0100 Subject: [PATCH 4801/6505] Add script to create an OpenWRT virtual machine (#1434) --- vm/openwrt-vm.sh | 425 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 vm/openwrt-vm.sh diff --git a/vm/openwrt-vm.sh b/vm/openwrt-vm.sh new file mode 100644 index 00000000..4cf592e7 --- /dev/null +++ b/vm/openwrt-vm.sh @@ -0,0 +1,425 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# Jon Spriggs (jontheniceguy) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Based on work from https://i12bretro.github.io/tutorials/0405.html + +function header_info { + cat <<"EOF" + _______ ________ __ + | |.-----.-----.-----.| | | |.----.| |_ + | - || _ | -__| || | | || _|| _| + |_______|| __|_____|__|__||________||__| |____| + |__| W I R E L E S S F R E E D O M + ----------------------------------------------------- + +EOF +} +clear +header_info +echo -e "Loading..." +GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +GEN_MAC_LAN=$(echo '00 60 2e'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +NEXTID=$(pvesh get /cluster/nextid) +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +trap cleanup EXIT +function error_exit() { + trap - ERR + local reason="Unknown failure occurred." + local msg="${1:-$reason}" + local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" + echo -e "$flag $msg" 1>&2 + [ ! -z ${VMID-} ] && cleanup_vmid + exit $EXIT +} +function cleanup_vmid() { + if $(qm status $VMID &>/dev/null); then + if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then + qm stop $VMID + fi + qm destroy $VMID + fi +} +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} +function send_line_to_vm() { + echo -e "${DGN}Sending line: ${YW}$1${CL}" + for ((i=0; i<${#1}; i++)); do + character=${1:i:1} + case $character in + " ") character="spc";; + "-") character="minus";; + "=") character="equal";; + ",") character="comma";; + ".") character="dot";; + "/") character="slash";; + "'") character="apostrophe";; + ";") character="semicolon";; + '\') character="backslash";; + '`') character="grave_accent";; + "[") character="bracket_left";; + "]") character="bracket_right";; + "_") character="shift-minus";; + "+") character="shift-equal";; + "?") character="shift-slash";; + "<") character="shift-comma";; + ">") character="shift-dot";; + '"') character="shift-apostrophe";; + ":") character="shift-semicolon";; + "|") character="shift-backslash";; + "~") character="shift-grave_accent";; + "{") character="shift-bracket_left";; + "}") character="shift-bracket_right";; + "A") character="shift-a";; + "B") character="shift-b";; + "C") character="shift-c";; + "D") character="shift-d";; + "E") character="shift-e";; + "F") character="shift-f";; + "G") character="shift-g";; + "H") character="shift-h";; + "I") character="shift-i";; + "J") character="shift-j";; + "K") character="shift-k";; + "L") character="shift-l";; + "M") character="shift-m";; + "N") character="shift-n";; + "O") character="shift-o";; + "P") character="shift-p";; + "Q") character="shift-q";; + "R") character="shift-r";; + "S") character="shift-s";; + "T") character="shift-t";; + "U") character="shift-u";; + "V") character="shift-v";; + "W") character="shift-w";; + "X") character="shift=x";; + "Y") character="shift-y";; + "Z") character="shift-z";; + "!") character="shift-1";; + "@") character="shift-2";; + "#") character="shift-3";; + '$') character="shift-4";; + "%") character="shift-5";; + "^") character="shift-6";; + "&") character="shift-7";; + "*") character="shift-8";; + "(") character="shift-9";; + ")") character="shift-0";; + esac + qm sendkey $VMID "$character" + done + qm sendkey $VMID ret +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then + echo "⚠ This version of Proxmox Virtual Environment is not supported" + echo "Requires PVE Version: 7.XX" + echo "Exiting..." + sleep 3 + exit +fi +if (whiptail --title "OpenWRT VM" --yesno "This will create a New OpenWRT VM. Proceed?" 10 58); then + echo "User selected Yes" +else + clear + echo -e "⚠ User exited script \n" + exit +fi + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} +function default_settings() { + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" + VMID=$NEXTID + echo -e "${DGN}Using Hostname: ${BGN}openwrt${CL}" + HN=openwrt + echo -e "${DGN}Allocated Cores: ${BGN}1${CL}" + CORE_COUNT="1" + echo -e "${DGN}Allocated RAM: ${BGN}256${CL}" + RAM_SIZE="256" + echo -e "${DGN}Using WAN Bridge: ${BGN}vmbr0${CL}" + BRG="vmbr0" + echo -e "${DGN}Using WAN VLAN: ${BGN}Default${CL}" + VLAN="" + echo -e "${DGN}Using WAN MAC Address: ${BGN}$GEN_MAC${CL}" + MAC=$GEN_MAC + echo -e "${DGN}Using LAN MAC Address: ${BGN}$GEN_MAC_LAN${CL}" + LAN_MAC=$GEN_MAC_LAN + echo -e "${DGN}Using LAN Bridge: ${BGN}vmbr0${CL}" + LAN_BRG="vmbr0" + echo -e "${DGN}Using LAN VLAN: ${BGN}999${CL}" + LAN_VLAN=",tag=999" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + MTU="" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + echo -e "${BL}Creating a OpenWRT VM using the above default settings${CL}" +} +function advanced_settings() { + VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" + else + exit + fi + VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 openwrt --title "HOSTNAME" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + exit + fi + CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + exit + fi + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + exit + fi + BRG=$(whiptail --inputbox "Set a WAN Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + exit + fi + LAN_BRG=$(whiptail --inputbox "Set a LAN Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + echo -e "${DGN}Using Bridge: ${BGN}$LAN_BRG${CL}" + else + exit + fi + MAC1=$(whiptail --inputbox "Set a WAN MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + MAC="$MAC1" + echo -e "${DGN}Using WAN MAC Address: ${BGN}$MAC1${CL}" + else + exit + fi + MAC2=$(whiptail --inputbox "Set a LAN MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + LAN_MAC="$MAC2" + echo -e "${DGN}Using LAN MAC Address: ${BGN}$MAC2${CL}" + else + exit + fi + VLAN1=$(whiptail --inputbox "Set a WAN VLAN tag(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN1 ]; then + VLAN1="Default" VLAN="" + echo -e "${DGN}Using WAN VLAN tag: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using WAN VLAN tag: ${BGN}$VLAN1${CL}" + fi + fi + VLAN2=$(whiptail --inputbox "Set a LAN VLAN tag(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $VLAN2 ]; then + VLAN2="Default" LAN_VLAN="" + echo -e "${DGN}Using LAN VLAN tag: ${BGN}$VLAN2${CL}" + else + LAN_VLAN=",tag=$VLAN2" + echo -e "${DGN}Using LAN VLAN tag: ${BGN}$VLAN2${CL}" + fi + fi + MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus = 0 ]; then + if [ -z $MTU1 ]; then + MTU1="Default" MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + fi + if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start OpenWRT VM when completed?" 10 58); then + echo -e "${DGN}Start OpenWRT VM when completed: ${BGN}yes${CL}" + START_VM="yes" + else + echo -e "${DGN}Start OpenWRT VM when completed: ${BGN}no${CL}" + START_VM="no" + fi + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create OpenWRT VM?" 10 58); then + echo -e "${RD}Creating OpenWRT VM using the above advanced settings${CL}" + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +function start_script() { + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + clear + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + clear + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} +start_script +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}" + echo -e "Exiting..." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the OpenWRT VM?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Getting URL for OpenWRT Disk Image" + +regex='Current Stable Release - OpenWrt ([^/]*)<\/strong>' && response=$(curl -s https://openwrt.org) && [[ $response =~ $regex ]] && stableVersion="${BASH_REMATCH[1]}" +URL=https://downloads.openwrt.org/releases/$stableVersion/targets/x86/64/openwrt-$stableVersion-x86-64-generic-ext4-combined.img.gz + +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}$FILE${CL}" +gunzip -f $FILE >/dev/null 2>/dev/null || true +NEWFILE="${FILE%.*}" +FILE="$NEWFILE" +mv $FILE ${FILE%.*} +qemu-img resize -f raw ${FILE%.*} 512M >/dev/null 2>/dev/null +msg_ok "Resized ${CL}${BL}$FILE${CL}" +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in +nfs | dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_FORMAT="subvol" + DISK_IMPORT="-format raw" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done +msg_ok "Extracted OpenWRT Disk Image" +msg_info "Creating OpenWRT VM" +qm create $VMID -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci --tablet 0 +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -scsi0 ${DISK1_REF},size=512M \ + -boot order=scsi0 \ + -description "# OpenWRT VM +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null +msg_ok "OpenWRT VM ${CL}${BL}(${HN})" +qm start $VMID +sleep 15 +send_line_to_vm "" +send_line_to_vm "uci delete network.@device[0]" +send_line_to_vm "uci set network.wan=interface" +send_line_to_vm "uci set network.wan.device=eth0" +send_line_to_vm "uci set network.wan.proto=dhcp" +send_line_to_vm "uci delete network.lan" +send_line_to_vm "uci set network.lan=interface" +send_line_to_vm "uci set network.lan.device=eth1" +send_line_to_vm "uci set network.lan.proto=static" +send_line_to_vm "uci set network.lan.ipaddr=192.0.2.1" +send_line_to_vm "uci set network.lan.netmask=255.255.255.0" +send_line_to_vm "uci set firewall.@zone[1].input='ACCEPT'" +send_line_to_vm "uci set firewall.@zone[1].forward='ACCEPT'" +send_line_to_vm "uci commit" +send_line_to_vm "halt" +msg_ok "Pre-configured network interfaces" +until qm status $VMID | grep -q "stopped" +do + sleep 2 +done +qm set $VMID \ + -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \ + -net1 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}$MTU >/dev/null 2>/dev/null +msg_ok "Added bridge interface" +if [ "$START_VM" == "yes" ]; then + msg_info "Starting OpenWRT VM" + qm start $VMID + msg_ok "Started OpenWRT VM" +fi +VLAN_FINISH="" +if [ "$VLAN" == "" ] && [ "$LAN_VLAN" != "999" ]; then + VLAN_FINISH=" Please remember to adjust the VLAN tags to suit your network." +fi +msg_ok "Completed Successfully!\n${VLAN_FINISH:-}" From 7e5206239ae219a8f751142bd0dbf7fb2eb1f449 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 May 2023 07:25:27 -0400 Subject: [PATCH 4802/6505] Update openwrt-vm.sh tweak --- vm/openwrt-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/openwrt-vm.sh b/vm/openwrt-vm.sh index 4cf592e7..dc855fb9 100644 --- a/vm/openwrt-vm.sh +++ b/vm/openwrt-vm.sh @@ -209,7 +209,7 @@ function advanced_settings() { else exit fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) + RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 256 --title "RAM" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" From c5ee4993c8aab480c6e7126db1cddfe52b614ab6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 May 2023 07:36:05 -0400 Subject: [PATCH 4803/6505] Update openwrt-vm.sh tweak --- vm/openwrt-vm.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vm/openwrt-vm.sh b/vm/openwrt-vm.sh index dc855fb9..2ad04848 100644 --- a/vm/openwrt-vm.sh +++ b/vm/openwrt-vm.sh @@ -387,6 +387,7 @@ qm set $VMID \ ### https://github.com/tteck/Proxmox [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null msg_ok "OpenWRT VM ${CL}${BL}(${HN})" +msg_info "Pre-configuring network interfaces" qm start $VMID sleep 15 send_line_to_vm "" @@ -409,6 +410,7 @@ until qm status $VMID | grep -q "stopped" do sleep 2 done +msg_info "Adding bridge interface" qm set $VMID \ -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \ -net1 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}$MTU >/dev/null 2>/dev/null From 6a7cd6b956b1220110c8a709437646e52cc0e2d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 May 2023 07:40:19 -0400 Subject: [PATCH 4804/6505] Update openwrt-vm.sh shfmt --- vm/openwrt-vm.sh | 123 +++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 62 deletions(-) diff --git a/vm/openwrt-vm.sh b/vm/openwrt-vm.sh index 2ad04848..9e91441d 100644 --- a/vm/openwrt-vm.sh +++ b/vm/openwrt-vm.sh @@ -66,68 +66,68 @@ function cleanup() { } function send_line_to_vm() { echo -e "${DGN}Sending line: ${YW}$1${CL}" - for ((i=0; i<${#1}; i++)); do + for ((i = 0; i < ${#1}; i++)); do character=${1:i:1} case $character in - " ") character="spc";; - "-") character="minus";; - "=") character="equal";; - ",") character="comma";; - ".") character="dot";; - "/") character="slash";; - "'") character="apostrophe";; - ";") character="semicolon";; - '\') character="backslash";; - '`') character="grave_accent";; - "[") character="bracket_left";; - "]") character="bracket_right";; - "_") character="shift-minus";; - "+") character="shift-equal";; - "?") character="shift-slash";; - "<") character="shift-comma";; - ">") character="shift-dot";; - '"') character="shift-apostrophe";; - ":") character="shift-semicolon";; - "|") character="shift-backslash";; - "~") character="shift-grave_accent";; - "{") character="shift-bracket_left";; - "}") character="shift-bracket_right";; - "A") character="shift-a";; - "B") character="shift-b";; - "C") character="shift-c";; - "D") character="shift-d";; - "E") character="shift-e";; - "F") character="shift-f";; - "G") character="shift-g";; - "H") character="shift-h";; - "I") character="shift-i";; - "J") character="shift-j";; - "K") character="shift-k";; - "L") character="shift-l";; - "M") character="shift-m";; - "N") character="shift-n";; - "O") character="shift-o";; - "P") character="shift-p";; - "Q") character="shift-q";; - "R") character="shift-r";; - "S") character="shift-s";; - "T") character="shift-t";; - "U") character="shift-u";; - "V") character="shift-v";; - "W") character="shift-w";; - "X") character="shift=x";; - "Y") character="shift-y";; - "Z") character="shift-z";; - "!") character="shift-1";; - "@") character="shift-2";; - "#") character="shift-3";; - '$') character="shift-4";; - "%") character="shift-5";; - "^") character="shift-6";; - "&") character="shift-7";; - "*") character="shift-8";; - "(") character="shift-9";; - ")") character="shift-0";; + " ") character="spc" ;; + "-") character="minus" ;; + "=") character="equal" ;; + ",") character="comma" ;; + ".") character="dot" ;; + "/") character="slash" ;; + "'") character="apostrophe" ;; + ";") character="semicolon" ;; + '\') character="backslash" ;; + '`') character="grave_accent" ;; + "[") character="bracket_left" ;; + "]") character="bracket_right" ;; + "_") character="shift-minus" ;; + "+") character="shift-equal" ;; + "?") character="shift-slash" ;; + "<") character="shift-comma" ;; + ">") character="shift-dot" ;; + '"') character="shift-apostrophe" ;; + ":") character="shift-semicolon" ;; + "|") character="shift-backslash" ;; + "~") character="shift-grave_accent" ;; + "{") character="shift-bracket_left" ;; + "}") character="shift-bracket_right" ;; + "A") character="shift-a" ;; + "B") character="shift-b" ;; + "C") character="shift-c" ;; + "D") character="shift-d" ;; + "E") character="shift-e" ;; + "F") character="shift-f" ;; + "G") character="shift-g" ;; + "H") character="shift-h" ;; + "I") character="shift-i" ;; + "J") character="shift-j" ;; + "K") character="shift-k" ;; + "L") character="shift-l" ;; + "M") character="shift-m" ;; + "N") character="shift-n" ;; + "O") character="shift-o" ;; + "P") character="shift-p" ;; + "Q") character="shift-q" ;; + "R") character="shift-r" ;; + "S") character="shift-s" ;; + "T") character="shift-t" ;; + "U") character="shift-u" ;; + "V") character="shift-v" ;; + "W") character="shift-w" ;; + "X") character="shift=x" ;; + "Y") character="shift-y" ;; + "Z") character="shift-z" ;; + "!") character="shift-1" ;; + "@") character="shift-2" ;; + "#") character="shift-3" ;; + '$') character="shift-4" ;; + "%") character="shift-5" ;; + "^") character="shift-6" ;; + "&") character="shift-7" ;; + "*") character="shift-8" ;; + "(") character="shift-9" ;; + ")") character="shift-0" ;; esac qm sendkey $VMID "$character" done @@ -406,8 +406,7 @@ send_line_to_vm "uci set firewall.@zone[1].forward='ACCEPT'" send_line_to_vm "uci commit" send_line_to_vm "halt" msg_ok "Pre-configured network interfaces" -until qm status $VMID | grep -q "stopped" -do +until qm status $VMID | grep -q "stopped"; do sleep 2 done msg_info "Adding bridge interface" From d37bbe628db7892857a9b5b749fa4f3654971ecf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 May 2023 04:13:26 -0400 Subject: [PATCH 4805/6505] Update README.md tweak --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49968ca7..0098eea6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Contributing to Proxmox VE Helper Scripts

    -These scripts allow for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. The options are presented in a dialog box format using the whiptail command, and the script collects and validates the user's input to generate the final configuration of the container or virtual machine. +These scripts allow for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. Using the whiptail command, the options are displayed in a dialog box format. The script then gathers and verifies the user's input in order to generate the final configuration of the container or virtual machine.

    Proxmox VE Helper Scripts

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    From 86286fdb5fcbdc690e2fef58cdd129b9e5fc7a82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 May 2023 07:36:27 -0400 Subject: [PATCH 4806/6505] Update openwrt-vm.sh code refactoring --- vm/openwrt-vm.sh | 367 +++++++++++++++++++++++++++++------------------ 1 file changed, 226 insertions(+), 141 deletions(-) diff --git a/vm/openwrt-vm.sh b/vm/openwrt-vm.sh index 9e91441d..c9cf3c3e 100644 --- a/vm/openwrt-vm.sh +++ b/vm/openwrt-vm.sh @@ -8,21 +8,21 @@ # Based on work from https://i12bretro.github.io/tutorials/0405.html function header_info { + clear cat <<"EOF" - _______ ________ __ - | |.-----.-----.-----.| | | |.----.| |_ - | - || _ | -__| || | | || _|| _| - |_______|| __|_____|__|__||________||__| |____| - |__| W I R E L E S S F R E E D O M - ----------------------------------------------------- + ____ _ __ __ + / __ \____ ___ ____| | / /____/ /_ + / / / / __ \/ _ \/ __ \ | /| / / ___/ __/ +/ /_/ / /_/ / __/ / / / |/ |/ / / / /_ +\____/ .___/\___/_/ /_/|__/|__/_/ \__/ + /_/ W I R E L E S S F R E E D O M EOF } -clear header_info echo -e "Loading..." -GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') -GEN_MAC_LAN=$(echo '00 60 2e'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]') +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +GEN_MAC_LAN=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') NEXTID=$(pvesh get /cluster/nextid) YW=$(echo "\033[33m") BL=$(echo "\033[36m") @@ -35,35 +35,33 @@ CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR +CROSS="${RD}✗${CL}" +set -Eeuo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT -function error_exit() { - trap - ERR - local reason="Unknown failure occurred." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - [ ! -z ${VMID-} ] && cleanup_vmid - exit $EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid } + function cleanup_vmid() { - if $(qm status $VMID &>/dev/null); then - if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then - qm stop $VMID - fi - qm destroy $VMID + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null fi } + function cleanup() { popd >/dev/null rm -rf $TEMP_DIR } + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null function send_line_to_vm() { echo -e "${DGN}Sending line: ${YW}$1${CL}" for ((i = 0; i < ${#1}; i++)); do @@ -136,179 +134,265 @@ function send_line_to_vm() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: 7.XX" - echo "Exiting..." - sleep 3 - exit -fi -if (whiptail --title "OpenWRT VM" --yesno "This will create a New OpenWRT VM. Proceed?" 10 58); then - echo "User selected Yes" + +if (whiptail --title "OpenWrt VM" --yesno "This will create a New OpenWrt VM. Proceed?" 10 58); then + : else - clear - echo -e "⚠ User exited script \n" - exit + header_info && echo -e "⚠ User exited script \n" && exit fi function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." } + function msg_ok() { local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function pve_check() { + if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function ssh_check() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + function default_settings() { - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}openwrt${CL}" HN=openwrt - echo -e "${DGN}Allocated Cores: ${BGN}1${CL}" CORE_COUNT="1" - echo -e "${DGN}Allocated RAM: ${BGN}256${CL}" RAM_SIZE="256" - echo -e "${DGN}Using WAN Bridge: ${BGN}vmbr0${CL}" BRG="vmbr0" - echo -e "${DGN}Using WAN VLAN: ${BGN}Default${CL}" VLAN="" - echo -e "${DGN}Using WAN MAC Address: ${BGN}$GEN_MAC${CL}" MAC=$GEN_MAC - echo -e "${DGN}Using LAN MAC Address: ${BGN}$GEN_MAC_LAN${CL}" LAN_MAC=$GEN_MAC_LAN - echo -e "${DGN}Using LAN Bridge: ${BGN}vmbr0${CL}" LAN_BRG="vmbr0" - echo -e "${DGN}Using LAN VLAN: ${BGN}999${CL}" LAN_VLAN=",tag=999" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" MTU="" - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using WAN Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using WAN VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using WAN MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using LAN MAC Address: ${BGN}${LAN_MAC}${CL}" + echo -e "${DGN}Using LAN Bridge: ${BGN}${LAN_BRG}${CL}" + echo -e "${DGN}Using LAN VLAN: ${BGN}999${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" echo -e "${BL}Creating a OpenWRT VM using the above default settings${CL}" } + function advanced_settings() { - VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" + while true; do + if VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + exit-script + fi + done + + if VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 openwrt --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="openwrt" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi else - exit + exit-script fi - VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 openwrt --title "HOSTNAME" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - HN=$(echo ${VM_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + + if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="1" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi else - exit + exit-script fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + + if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 256 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="256" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi else - exit + exit-script fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 256 --title "RAM" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + + if BRG=$(whiptail --inputbox "Set a WAN Bridge" 8 58 vmbr0 --title "WAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using WAN Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using WAN Bridge: ${BGN}$BRG${CL}" + fi else - exit + exit-script fi - BRG=$(whiptail --inputbox "Set a WAN Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + + if LAN_BRG=$(whiptail --inputbox "Set a LAN Bridge" 8 58 vmbr0 --title "LAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $LAN_BRG ]; then + LAN_BRG="vmbr0" + echo -e "${DGN}Using LAN Bridge: ${BGN}$LAN_BRG${CL}" + else + echo -e "${DGN}Using LAN Bridge: ${BGN}$LAN_BRG${CL}" + fi else - exit + exit-script fi - LAN_BRG=$(whiptail --inputbox "Set a LAN Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - echo -e "${DGN}Using Bridge: ${BGN}$LAN_BRG${CL}" + + if MAC1=$(whiptail --inputbox "Set a WAN MAC Address" 8 58 $GEN_MAC --title "WAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using WAN MAC Address: ${BGN}$MAC${CL}" + else + MAC="$MAC1" + echo -e "${DGN}Using WAN MAC Address: ${BGN}$MAC1${CL}" + fi else - exit + exit-script fi - MAC1=$(whiptail --inputbox "Set a WAN MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - MAC="$MAC1" - echo -e "${DGN}Using WAN MAC Address: ${BGN}$MAC1${CL}" + + if MAC2=$(whiptail --inputbox "Set a LAN MAC Address" 8 58 $GEN_MAC_LAN --title "LAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC2 ]; then + LAN_MAC="$GEN_MAC_LAN" + echo -e "${DGN}Using LAN MAC Address: ${BGN}$LAN_MAC${CL}" + else + LAN_MAC="$MAC2" + echo -e "${DGN}Using LAN MAC Address: ${BGN}$MAC2${CL}" + fi else - exit + exit-script fi - MAC2=$(whiptail --inputbox "Set a LAN MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then - LAN_MAC="$MAC2" - echo -e "${DGN}Using LAN MAC Address: ${BGN}$MAC2${CL}" - else - exit - fi - VLAN1=$(whiptail --inputbox "Set a WAN VLAN tag(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + + if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "WAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then - VLAN1="Default" VLAN="" - echo -e "${DGN}Using WAN VLAN tag: ${BGN}$VLAN1${CL}" + VLAN1="Default" + VLAN="" + echo -e "${DGN}Using WAN Vlan: ${BGN}$VLAN1${CL}" else VLAN=",tag=$VLAN1" - echo -e "${DGN}Using WAN VLAN tag: ${BGN}$VLAN1${CL}" + echo -e "${DGN}Using WAN Vlan: ${BGN}$VLAN1${CL}" fi + else + exit-script fi - VLAN2=$(whiptail --inputbox "Set a LAN VLAN tag(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + + if VLAN2=$(whiptail --inputbox "Set a LAN Vlan" 8 58 999 --title "LAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VLAN2 ]; then - VLAN2="Default" LAN_VLAN="" - echo -e "${DGN}Using LAN VLAN tag: ${BGN}$VLAN2${CL}" + VLAN2="999" + LAN_VLAN=",tag=$VLAN2" + echo -e "${DGN}Using LAN Vlan: ${BGN}$VLAN2${CL}" else LAN_VLAN=",tag=$VLAN2" - echo -e "${DGN}Using LAN VLAN tag: ${BGN}$VLAN2${CL}" + echo -e "${DGN}Using LAN Vlan: ${BGN}$VLAN2${CL}" fi + else + exit-script fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus = 0 ]; then + + if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then - MTU1="Default" MTU="" + MTU1="Default" + MTU="" echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" else MTU=",mtu=$MTU1" echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi + else + exit-script fi - if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start OpenWRT VM when completed?" 10 58); then - echo -e "${DGN}Start OpenWRT VM when completed: ${BGN}yes${CL}" + + if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" else - echo -e "${DGN}Start OpenWRT VM when completed: ${BGN}no${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create OpenWRT VM?" 10 58); then - echo -e "${RD}Creating OpenWRT VM using the above advanced settings${CL}" + + if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create OpenWrt VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a OpenWrt VM using the above advanced settings${CL}" else - clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings fi } + function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then - clear + if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings else - clear header_info echo -e "${RD}Using Advanced Settings${CL}" advanced_settings fi } + +arch_check +pve_check +ssh_check start_script + msg_info "Validating Storage" while read -r line; do TAG=$(echo $line | awk '{print $1}') @@ -331,14 +415,14 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the OpenWRT VM?\n\n" \ + "Which storage pool you would like to use for the OpenWrt VM?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for OpenWRT Disk Image" +msg_info "Getting URL for OpenWrt Disk Image" regex='Current Stable Release - OpenWrt ([^/]*)<\/strong>' && response=$(curl -s https://openwrt.org) && [[ $response =~ $regex ]] && stableVersion="${BASH_REMATCH[1]}" URL=https://downloads.openwrt.org/releases/$stableVersion/targets/x86/64/openwrt-$stableVersion-x86-64-generic-ext4-combined.img.gz @@ -354,7 +438,7 @@ NEWFILE="${FILE%.*}" FILE="$NEWFILE" mv $FILE ${FILE%.*} qemu-img resize -f raw ${FILE%.*} 512M >/dev/null 2>/dev/null -msg_ok "Resized ${CL}${BL}$FILE${CL}" +msg_ok "Extracted & Resized OpenWrt Disk Image ${CL}${BL}$FILE${CL}" STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in nfs | dir) @@ -365,7 +449,6 @@ nfs | dir) btrfs) DISK_EXT=".raw" DISK_REF="$VMID/" - DISK_FORMAT="subvol" DISK_IMPORT="-format raw" ;; esac @@ -374,22 +457,24 @@ for i in {0,1}; do eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} done -msg_ok "Extracted OpenWRT Disk Image" -msg_info "Creating OpenWRT VM" + +msg_info "Creating OpenWrt VM" qm create $VMID -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci --tablet 0 pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ + -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=512M \ -boot order=scsi0 \ - -description "# OpenWRT VM + -description "# OpenWrt VM ### https://github.com/tteck/Proxmox [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null -msg_ok "OpenWRT VM ${CL}${BL}(${HN})" -msg_info "Pre-configuring network interfaces" +msg_ok "OpenWrt VM ${CL}${BL}(${HN})" +msg_info "OpenWrt is being started in order to configure the network interfaces." qm start $VMID sleep 15 +msg_ok "Network interfaces are being configured as OpenWrt initiates." send_line_to_vm "" send_line_to_vm "uci delete network.@device[0]" send_line_to_vm "uci set network.wan=interface" @@ -405,22 +490,22 @@ send_line_to_vm "uci set firewall.@zone[1].input='ACCEPT'" send_line_to_vm "uci set firewall.@zone[1].forward='ACCEPT'" send_line_to_vm "uci commit" send_line_to_vm "halt" -msg_ok "Pre-configured network interfaces" +msg_ok "Network interfaces have been successfully configured." until qm status $VMID | grep -q "stopped"; do sleep 2 done -msg_info "Adding bridge interface" +msg_info "Bridge interfaces are being added." qm set $VMID \ - -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \ - -net1 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}$MTU >/dev/null 2>/dev/null -msg_ok "Added bridge interface" + -net0 virtio,bridge=${BRG},macaddr=${MAC}${VLAN}${MTU} \ + -net1 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}${MTU} >/dev/null 2>/dev/null +msg_ok "Bridge interfaces have been successfully added." if [ "$START_VM" == "yes" ]; then - msg_info "Starting OpenWRT VM" + msg_info "Starting OpenWrt VM" qm start $VMID - msg_ok "Started OpenWRT VM" + msg_ok "Started OpenWrt VM" fi VLAN_FINISH="" -if [ "$VLAN" == "" ] && [ "$LAN_VLAN" != "999" ]; then +if [ "$VLAN" == "" ] && [ "$VLAN2" != "999" ]; then VLAN_FINISH=" Please remember to adjust the VLAN tags to suit your network." fi -msg_ok "Completed Successfully!\n${VLAN_FINISH:-}" +msg_ok "Completed Successfully!\n${VLAN_FINISH}" From 299fc5c82705739ccdb32d9bab05b5e327189596 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 May 2023 07:45:13 -0400 Subject: [PATCH 4807/6505] Rename openwrt-vm.sh to openwrt.sh --- vm/{openwrt-vm.sh => openwrt.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename vm/{openwrt-vm.sh => openwrt.sh} (100%) diff --git a/vm/openwrt-vm.sh b/vm/openwrt.sh similarity index 100% rename from vm/openwrt-vm.sh rename to vm/openwrt.sh From 1c3e107f4aa9e9460ea52de7bc00aa856de42564 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 May 2023 08:03:11 -0400 Subject: [PATCH 4808/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dd961db..11ed4695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-05-23 + +### Changed + +- **OpenWrt VM** + - NEW Script + ## 2023-05-17 ### Changed From 8d0a731090b034b98a1d5f0d0da983a1136ba011 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 May 2023 05:29:58 -0400 Subject: [PATCH 4809/6505] Update go2rtc.sh create app update --- ct/go2rtc.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index ba243dc3..982a03b3 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -53,11 +53,13 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +if [[ ! -d /opt/go2rtc ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +cd /opt/go2rtc +rm go2rtc_linux_amd64 +wget -q https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64 +chmod +x go2rtc_linux_amd64 +msg_ok "Updated $APP" exit } From 7a3530b24656d73dcb407c21d163524022ea5670 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 May 2023 05:50:57 -0400 Subject: [PATCH 4810/6505] Update go2rtc.sh tweak --- ct/go2rtc.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 982a03b3..89c7405b 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -55,10 +55,12 @@ function update_script() { header_info if [[ ! -d /opt/go2rtc ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating $APP" +systemctl stop go2rtc cd /opt/go2rtc rm go2rtc_linux_amd64 wget -q https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64 chmod +x go2rtc_linux_amd64 +systemctl start go2rtc msg_ok "Updated $APP" exit } From 767899c4f2262f5ede309b3b909dc775d7358799 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 May 2023 22:11:16 -0400 Subject: [PATCH 4811/6505] Update tautulli-install.sh add pyopenssl --- install/tautulli-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index 80ee51f7..502e4536 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -25,6 +25,7 @@ msg_info "Installing Tautulli" cd /opt $STD git clone https://github.com/Tautulli/Tautulli.git python3 -m pip install -q -r /opt/Tautulli/requirements.txt +$STD pip install pyopenssl msg_ok "Installed Tautulli" msg_info "Creating Service" From d5c38b978a922994cc40b3e069e231880e6fbe8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 May 2023 07:22:03 -0400 Subject: [PATCH 4812/6505] Update install.func tweak --- misc/install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index cb835a1d..ca112b9e 100644 --- a/misc/install.func +++ b/misc/install.func @@ -41,7 +41,7 @@ error_handler() { local command="$2" local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" echo -e "\n$error_message" - if [[ "$line_number" -eq 22 ]]; then + if [[ "$line_number" -eq 24 ]]; then echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" fi } From 3b6f82feacaff796251b4aec38f9c61c77976629 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 May 2023 07:23:30 -0400 Subject: [PATCH 4813/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 1157d709..3e4a30b9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -7,7 +7,7 @@ body: **IMPORTANT:** Before submitting: - Please search through the closed issues to see if the issue you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. - Switching Linux distributions without verifying that the default settings function properly, may lead to immediate closure. - - Failing to run the script in verbose mode to determine the actual issue, while encountering the error message `[ERROR] in line 22: exit code *: while executing command "$@" > /dev/null 2>&1`, may lead to immediate closure. + - Failing to run the script in verbose mode to determine the actual issue, while encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, may lead to immediate closure. - If you have requests for features or scripts, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: textarea id: bug From 72c805b0814964068397b5b384fccd6d7cb9b74b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 May 2023 01:27:33 -0400 Subject: [PATCH 4814/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 3e4a30b9..d39cb67c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -4,11 +4,11 @@ body: - type: markdown attributes: value: | - **IMPORTANT:** Before submitting: - - Please search through the closed issues to see if the issue you are reporting has already been reported and resolved. If you find a closed issue that addresses your problem, please leave a comment on that issue instead of opening a new one. - - Switching Linux distributions without verifying that the default settings function properly, may lead to immediate closure. - - Failing to run the script in verbose mode to determine the actual issue, while encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, may lead to immediate closure. - - If you have requests for features or scripts, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) + **IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure. + - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. + - Changing Linux distributions without confirming the proper functioning of default settings. + - When encountering the error message `[ERROR] on line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. + - For questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: textarea id: bug attributes: From b973d42760fdff000a4d969f76d1d6a956479ad3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 May 2023 01:31:06 -0400 Subject: [PATCH 4815/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index d39cb67c..af213103 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -7,7 +7,7 @@ body: **IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure. - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. - Changing Linux distributions without confirming the proper functioning of default settings. - - When encountering the error message `[ERROR] on line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. + - When encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. - For questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: textarea id: bug From e43ec5423ec11f40d824eea9dbf81c99ca0757a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 May 2023 09:39:16 -0400 Subject: [PATCH 4816/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index fadae182..6db16420 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -15,3 +15,5 @@ [Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html) [Proxmox: Plex LXC with Alder Lake Transcoding](https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html) + +[How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/) From fed3fd387a5566d0b59d101cf189eb709fb15fe7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 May 2023 21:59:30 -0400 Subject: [PATCH 4817/6505] Update post-pve-install.sh If an Intel N-series processor is detected, the script provides options to install both the Proxmox 6.2 kernel and the Intel microcode. --- misc/post-pve-install.sh | 151 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 79 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index e8fae97f..a2e162f5 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -10,10 +10,10 @@ header_info() { cat <<"EOF" ____ _ _____________ ____ __ ____ __ ____ / __ \ | / / ____/__ / / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / - / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / - / ____/| |/ / /___ / / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / -/_/ |___/_____/ /_/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ - + / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / + / ____/| |/ / /___ / / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/ /_/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + EOF } @@ -30,13 +30,13 @@ set -euo pipefail shopt -s inherit_errexit nullglob msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } msg_error() { @@ -44,23 +44,12 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } -exit_script() { - clear - echo -e "⚠ User exited script \n" - exit -} start_routines() { - header_info - CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - exit_script - fi + header_info + CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Disabling 'pve-enterprise' repository" @@ -72,15 +61,9 @@ start_routines() { ;; esac - CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 7 server.\n \nCorrect Proxmox VE 7 sources?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - exit_script - fi + CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 7 server.\n \nCorrect Proxmox VE 7 sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Correcting Proxmox VE 7 Sources" @@ -96,15 +79,9 @@ EOF ;; esac - CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - exit_script - fi + CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Enabling 'pve-no-subscription' repository" @@ -118,15 +95,9 @@ EOF ;; esac - CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - exit_script - fi + CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Adding 'pvetest' repository and set disabled" @@ -140,15 +111,9 @@ EOF ;; esac - CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - exit_script - fi + CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Disabling subscription nag" @@ -161,36 +126,64 @@ EOF ;; esac - CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "\nUpdate Proxmox VE 7 now?" 11 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - exit_script - fi + CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "\nUpdate Proxmox VE 7 now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Updating Proxmox VE 7 (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null - msg_ok "Updated Proxmox VE 7 (Reboot recommended)" + msg_ok "Updated Proxmox VE 7" ;; no) msg_error "Selected no to Updating Proxmox VE 7" ;; esac - CHOICE=$( - whiptail --title "Proxmox VE 7 Post Install" --menu "\nReboot Proxmox VE 7 now?" 11 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3 - ) - exit_status=$? - if [ $exit_status == 1 ]; then - exit_script + microcode="" + cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') + if [ "$cpu" == "GenuineIntel" ]; then + if lscpu | awk '/Model name:.*N/ {exit 0} END {exit 1}'; then + CHOICE=$(whiptail --title "N-SERIES PROCESSOR DETECTED" --menu "\nTo ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install the Proxmox 6.2 kernel.\n\nInstall the Proxmox 6.2 kernel now?" 16 58 2 \ + "yes" " " \ + "no" " " 3>&1 1>&2 2>&3) + case $CHOICE in + yes) + msg_info "Installing Proxmox 6.2 kernel" + apt install pve-kernel-6.2 + microcode="need" + msg_ok "Installed Proxmox 6.2 kernel" + ;; + no) + msg_error "Selected no to Installing the Proxmox 6.2 kernel" + ;; + esac + fi fi + + if [ "$microcode" == "need" ]; then + CHOICE=$(whiptail --title "INTEL MICROCODE" --menu "\nMicrocode updates can fix hardware bugs, improve performance, and enhance security features of the processor.\n\nInstall the Intel Microcode now?" 16 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Installing Intel Microcode" + apt-get install -y iucode-tool &>/dev/null + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230512.1_amd64.deb + dpkg -i intel-microcode_3.20230512.1_amd64.deb &>/dev/null + rm intel-microcode_3.20230512.1_amd64.deb + msg_ok "Installed Intel Microcode" + ;; + no) + msg_error "Selected no to Installing the Intel Microcode" + ;; + esac + fi + + CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "\nReboot Proxmox VE 7 now? (recommended)" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Rebooting Proxmox VE 7" @@ -199,7 +192,7 @@ EOF reboot ;; no) - msg_error "Selected no to Rebooting Proxmox VE 7" + msg_error "Selected no to Rebooting Proxmox VE 7 (Reboot recommended)" msg_ok "Completed Post Install Routines" ;; esac @@ -211,7 +204,7 @@ while true; do read -p "Start the Proxmox VE 7 Post Install Script (y/n)?" yn case $yn in [Yy]*) break ;; - [Nn]*) exit_script ;; + [Nn]*) clear; exit ;; *) echo "Please answer yes or no." ;; esac done From f0ab5c9cccaac7f800f8b13f102748b479162b55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 May 2023 22:06:41 -0400 Subject: [PATCH 4818/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11ed4695..3387a338 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-05-27 + +### Changed + +- **Proxmox VE 7 Post Install** + - If an Intel N-series processor is detected, the script provides options to install both the Proxmox 6.2 kernel and the Intel microcode. + ## 2023-05-23 ### Changed From d3cfb2c3a749907011ecb64faa7010651379e9b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 May 2023 22:08:35 -0400 Subject: [PATCH 4819/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index a2e162f5..0b87e94c 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -151,7 +151,7 @@ EOF case $CHOICE in yes) msg_info "Installing Proxmox 6.2 kernel" - apt install pve-kernel-6.2 + apt install pve-kernel-6.2 &>/dev/null microcode="need" msg_ok "Installed Proxmox 6.2 kernel" ;; From a85205cb80b5d0b9568f43fe4abf7ae329b7f332 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 May 2023 22:10:12 -0400 Subject: [PATCH 4820/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 0b87e94c..b9e737ee 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -151,7 +151,7 @@ EOF case $CHOICE in yes) msg_info "Installing Proxmox 6.2 kernel" - apt install pve-kernel-6.2 &>/dev/null + apt-get install -y pve-kernel-6.2 &>/dev/null microcode="need" msg_ok "Installed Proxmox 6.2 kernel" ;; From f2c54ba6defd0d68a9d4f63b402829bcb9f873ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 May 2023 13:03:05 -0400 Subject: [PATCH 4821/6505] Update post-pve-install.sh tweak the N-series processor detection --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index b9e737ee..93f4959d 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -144,7 +144,7 @@ EOF microcode="" cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') if [ "$cpu" == "GenuineIntel" ]; then - if lscpu | awk '/Model name:.*N/ {exit 0} END {exit 1}'; then + if lscpu | grep -qP 'Model name:.*N'; then CHOICE=$(whiptail --title "N-SERIES PROCESSOR DETECTED" --menu "\nTo ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install the Proxmox 6.2 kernel.\n\nInstall the Proxmox 6.2 kernel now?" 16 58 2 \ "yes" " " \ "no" " " 3>&1 1>&2 2>&3) From c7796d0fd20ee42bd4a26845bee2a05156e92c98 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 May 2023 13:38:52 -0400 Subject: [PATCH 4822/6505] Update post-pve-install.sh Code refactoring --- misc/post-pve-install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 93f4959d..5a624b88 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -142,9 +142,7 @@ EOF esac microcode="" - cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') - if [ "$cpu" == "GenuineIntel" ]; then - if lscpu | grep -qP 'Model name:.*N'; then + if lscpu | grep -qP 'Vendor ID:.*GenuineIntel' && lscpu | grep -qP 'Model name:.*N'; then CHOICE=$(whiptail --title "N-SERIES PROCESSOR DETECTED" --menu "\nTo ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install the Proxmox 6.2 kernel.\n\nInstall the Proxmox 6.2 kernel now?" 16 58 2 \ "yes" " " \ "no" " " 3>&1 1>&2 2>&3) @@ -159,7 +157,6 @@ EOF msg_error "Selected no to Installing the Proxmox 6.2 kernel" ;; esac - fi fi if [ "$microcode" == "need" ]; then From 69bdd6419375e0641d435604ede8d06ef632aaf7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 May 2023 09:40:56 -0400 Subject: [PATCH 4823/6505] Update changedetection-install.sh Code refactoring --- install/changedetection-install.sh | 126 ++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 34e0bcca..193e5373 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -13,37 +13,145 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y pip +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y \ + curl \ + sudo \ + mc \ + git \ + build-essential \ + dumb-init \ + gconf-service \ + ffmpeg \ #can find no need + libappindicator1 \ #can find no need + libappindicator3-1 \ #can find no need + libasound2 \ #can find no need + libatk-bridge2.0-0 \ + libatk1.0-0 \ + libcairo2 \ + libcups2 \ + libdbus-1-3 \ + libexpat1 \ + libgbm-dev \ + libgbm1 \ + libgconf-2-4 \ + libgdk-pixbuf2.0-0 \ + libglib2.0-0 \ + libgtk-3-0 \ + libnspr4 \ + libnss3 \ + libpango-1.0-0 \ + libpangocairo-1.0-0 \ + qpdf \ + xdg-utils \ + xvfb msg_ok "Installed Dependencies" +msg_info "Installing Python3" +$STD apt-get install -y \ + python3-dev \ + python3-pip +msg_ok "Installed Python3" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + msg_info "Installing Change Detection" mkdir /opt/changedetection $STD pip3 install changedetection.io $STD python3 -m pip install dnspython==2.2.1 msg_ok "Installed Change Detection" -msg_info "Creating Service" +msg_info "Installing Browserless & Playwright" +mkdir /opt/browserless +$STD python3 -m pip install playwright +$STD git clone https://github.com/browserless/chrome /opt/browserless +$STD npm install --prefix /opt/browserless +$STD npm run build --prefix /opt/browserless +$STD npm prune production --prefix /opt/browserless +msg_ok "Installed Browserless & Playwright" + +msg_info "Installing Font Packages" +$STD apt-get install -y \ + fontconfig \ + libfontconfig1 \ + fonts-freefont-ttf \ + fonts-gfs-neohellenic \ + fonts-indic fonts-ipafont-gothic \ + fonts-kacst fonts-liberation \ + fonts-noto-cjk \ + fonts-noto-color-emoji \ + msttcorefonts \ + fonts-roboto \ + fonts-thai-tlwg \ + fonts-wqy-zenhei +msg_ok "Installed Font Packages" + +msg_info "Installing X11 Packages" +$STD apt-get install -y \ + libx11-6 \ + libx11-xcb1 \ + libxcb1 \ + libxcomposite1 \ + libxcursor1 \ + libxdamage1 \ + libxext6 \ + libxfixes3 \ + libxi6 \ + libxrandr2 \ + libxrender1 \ + libxss1 \ + libxtst6 +msg_ok "Installed X11 Packages" + +msg_info "Creating Services" cat </etc/systemd/system/changedetection.service [Unit] Description=Change Detection After=network-online.target +After=network.target browserless.service +Wants=browserless.service [Service] Type=simple WorkingDirectory=/opt/changedetection Environment="WEBDRIVER_URL=http://127.0.0.1:4444/wd/hub" +Environment="PLAYWRIGHT_DRIVER_URL=ws://127.0.0.1:3000/?stealth=1&--disable-web-security=true" ExecStart=changedetection.io -d /opt/changedetection -p 5000 [Install] WantedBy=multi-user.target EOF -$STD systemctl enable --now changedetection -msg_ok "Created Service" + +cat </etc/systemd/system/browserless.service +[Unit] +Description=browserless service +After=network.target +[Service] +Environment=APP_DIR=/opt/browserless +Environment=PLAYWRIGHT_BROWSERS_PATH=/opt/browserless +Environment=CONNECTION_TIMEOUT=60000 +Environment=HOST=127.0.0.1 +Environment=LANG="C.UTF-8" +Environment=NODE_ENV=production +Environment=PORT=3000 +Environment=WORKSPACE_DIR=/opt/browserless/workspace +WorkingDirectory=/opt/browserless +ExecStart=/opt/browserless/start.sh +SyslogIdentifier=browserless +[Install] +WantedBy=default.target +EOF + +systemctl enable -q --now browserless +systemctl enable -q --now changedetection +msg_ok "Created Services" motd_ssh -customize +root msg_info "Cleaning up" $STD apt-get autoremove From a68786a63b982e796f49498f975751a2d40c5691 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 May 2023 16:47:56 -0400 Subject: [PATCH 4824/6505] Update homeassistant-core-install.sh code refactoring --- install/homeassistant-core-install.sh | 38 ++++++++++----------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 663e5e99..3a9d5691 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -15,46 +15,36 @@ update_os msg_info "Installing Dependencies (Patience)" $STD apt-get install -y \ - make \ + git \ + curl \ + sudo \ + mc \ build-essential \ - libjpeg-dev \ - libpcap-dev \ libssl-dev \ zlib1g-dev \ libbz2-dev \ libreadline-dev \ libsqlite3-dev \ - libmariadb-dev-compat \ - autoconf \ - git \ - curl \ - sudo \ - mc \ - llvm \ libncursesw5-dev \ xz-utils \ - tzdata \ - bluez \ tk-dev \ + llvm \ libxml2-dev \ libxmlsec1-dev \ libffi-dev \ + liblzma-dev \ + bluez \ + libmariadb-dev-compat \ + libjpeg-dev \ + autoconf \ libopenjp2-7 \ libtiff5 \ libturbojpeg0-dev \ - liblzma-dev + liblapack3 \ + liblapack-dev \ + libatlas-base-dev msg_ok "Installed Dependencies" -msg_info "Installing Linux D-Bus Message Broker" -cat <>/etc/apt/sources.list -deb http://deb.debian.org/debian bullseye-backports main contrib non-free -deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free -EOF -$STD apt-get update -$STD apt-get -t bullseye-backports install -y dbus-broker -$STD systemctl enable --now dbus-broker.service -msg_ok "Installed Linux D-Bus Message Broker" - msg_info "Installing pyenv" $STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv set +e @@ -64,7 +54,7 @@ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path) msg_ok "Installed pyenv" . ~/.bashrc set -e -msg_info "Installing Python 3.11.2" +msg_info "Installing Python 3.11.2 (Patience)" $STD pyenv install 3.11.2 pyenv global 3.11.2 msg_ok "Installed Python 3.11.2" From 2c8341e72946dbe4c7d7e938dc62a8248548f01e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 May 2023 16:53:07 -0400 Subject: [PATCH 4825/6505] Update homeassistant-core-install.sh add dbus-broker --- install/homeassistant-core-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 3a9d5691..2cf3b410 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -33,6 +33,7 @@ $STD apt-get install -y \ libxmlsec1-dev \ libffi-dev \ liblzma-dev \ + dbus-broker \ bluez \ libmariadb-dev-compat \ libjpeg-dev \ From b612d7a69a4ca41af66782655476cfbf5065de3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 May 2023 01:02:14 -0400 Subject: [PATCH 4826/6505] Update influxdb.sh tweak --- ct/influxdb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 8f660810..3c7bda46 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { header_info -if [[ ! -f /etc/apt/sources.list.d/influxdata.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -f /etc/apt/sources.list.d/influxdb.list || ! -f /etc/apt/sources.list.d/influxdata.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" wget -q https://repos.influxdata.com/influxdata-archive_compat.key cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null From 5ceb5cffbed04b84526edd8ff45560682d40492f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 May 2023 01:06:37 -0400 Subject: [PATCH 4827/6505] Update changedetection-install.sh fix calling incorrect variable --- install/changedetection-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 193e5373..43180ac3 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -151,7 +151,7 @@ systemctl enable -q --now changedetection msg_ok "Created Services" motd_ssh -root +customize msg_info "Cleaning up" $STD apt-get autoremove From d82f01b5e5fbda32b7e1a09b2ca0bed37603f0a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 May 2023 11:27:48 -0400 Subject: [PATCH 4828/6505] Update changedetection-install.sh fix dependencies --- install/changedetection-install.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 43180ac3..e1673b15 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -22,10 +22,6 @@ $STD apt-get install -y \ build-essential \ dumb-init \ gconf-service \ - ffmpeg \ #can find no need - libappindicator1 \ #can find no need - libappindicator3-1 \ #can find no need - libasound2 \ #can find no need libatk-bridge2.0-0 \ libatk1.0-0 \ libcairo2 \ From 9be893b12dce04384465c98443b9a91abd3b4732 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 May 2023 11:43:31 -0400 Subject: [PATCH 4829/6505] Update changedetection.sh add storage --- ct/changedetection.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index e114edc3..23759e5a 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -19,7 +19,7 @@ EOF header_info echo -e "Loading..." APP="Change Detection" -var_disk="2" +var_disk="6" var_cpu="1" var_ram="512" var_os="debian" From 620f135666bf603c4288e902a2032a43b2a29a1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 May 2023 11:52:17 -0400 Subject: [PATCH 4830/6505] Update changedetection.sh add vCPU --- ct/changedetection.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 23759e5a..96068d88 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -20,7 +20,7 @@ header_info echo -e "Loading..." APP="Change Detection" var_disk="6" -var_cpu="1" +var_cpu="2" var_ram="512" var_os="debian" var_version="11" From 1cfc47e519123d44962e828a9baf75f09619375c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 May 2023 11:54:24 -0400 Subject: [PATCH 4831/6505] Update changedetection.sh add storage --- ct/changedetection.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 96068d88..9e7fc982 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -19,7 +19,7 @@ EOF header_info echo -e "Loading..." APP="Change Detection" -var_disk="6" +var_disk="8" var_cpu="2" var_ram="512" var_os="debian" From d797b2714a8e1bd4de2c17e3126c39340b007994 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 May 2023 11:58:33 -0400 Subject: [PATCH 4832/6505] Update changedetection.sh add RAM --- ct/changedetection.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 9e7fc982..8f938dd5 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="Change Detection" var_disk="8" var_cpu="2" -var_ram="512" +var_ram="1024" var_os="debian" var_version="11" variables From afbbb011d6e7534ed1e4e0f9711d62e873b9e230 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 31 May 2023 16:59:14 -0400 Subject: [PATCH 4833/6505] Update homeassistant-core-install.sh add libpcap-dev --- install/homeassistant-core-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 2cf3b410..daa4d4d2 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y \ libssl-dev \ zlib1g-dev \ libbz2-dev \ + libpcap-dev \ libreadline-dev \ libsqlite3-dev \ libncursesw5-dev \ From e6deb6c79a6048e3f8e52ca68ae87ebf97afb07e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 2 Jun 2023 11:55:20 -0400 Subject: [PATCH 4834/6505] Update post-pve-install.sh give the option to disable high availability in a non-clustered environment --- misc/post-pve-install.sh | 63 +++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 5a624b88..ecf8d2de 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -47,7 +47,7 @@ msg_error() { start_routines() { header_info - CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ + CHOICE=$(whiptail --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -61,7 +61,7 @@ start_routines() { ;; esac - CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 7 server.\n \nCorrect Proxmox VE 7 sources?" 14 58 2 \ + CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 7 server.\n \nCorrect Proxmox VE 7 sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -79,7 +79,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ + CHOICE=$(whiptail --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -95,7 +95,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ + CHOICE=$(whiptail --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -111,22 +111,45 @@ EOF ;; esac - CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Disabling subscription nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script - apt --reinstall install proxmox-widget-toolkit &>/dev/null - msg_ok "Disabled subscription nag (Delete browser cache)" - ;; - no) - msg_error "Selected no to Disabling subscription nag" - ;; - esac + if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then + CHOICE=$(whiptail --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling subscription nag" + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + apt --reinstall install proxmox-widget-toolkit &>/dev/null + msg_ok "Disabled subscription nag (Delete browser cache)" + ;; + no) + msg_error "Selected no to Disabling subscription nag" + ;; + esac + fi - CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "\nUpdate Proxmox VE 7 now?" 11 58 2 \ + if systemctl is-active --quiet pve-ha-lrm; then + CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling high availability" + systemctl stop pve-ha-lrm + systemctl disable pve-ha-lrm &>/dev/null + systemctl stop pve-ha-crm + systemctl disable pve-ha-crm &>/dev/null + systemctl stop corosync + systemctl disable corosync &>/dev/null + msg_ok "Disabled high availability" + ;; + no) + msg_error "Selected no to Disabling high availability" + ;; + esac + fi + + CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE 7 now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -178,7 +201,7 @@ EOF esac fi - CHOICE=$(whiptail --title "Proxmox VE 7 Post Install" --menu "\nReboot Proxmox VE 7 now? (recommended)" 11 58 2 \ + CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE 7 now? (recommended)" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From 2a80ed71842ddadbbdc98530c069a58704ad986b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 2 Jun 2023 11:57:34 -0400 Subject: [PATCH 4835/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3387a338..b8ea88b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-06-02 + +### Changed + +- **Proxmox VE 7 Post Install** + - In a non-clustered environment, you can choose to disable high availability, which helps save system resources. + ## 2023-05-27 ### Changed From 89e933e85ea40dff377013db78fd86efe4d0ff0d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 3 Jun 2023 06:43:28 -0400 Subject: [PATCH 4836/6505] Update openwrt.sh set network.lan.ipaddr=192.168.2.1 --- vm/openwrt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index c9cf3c3e..f5bae843 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -484,7 +484,7 @@ send_line_to_vm "uci delete network.lan" send_line_to_vm "uci set network.lan=interface" send_line_to_vm "uci set network.lan.device=eth1" send_line_to_vm "uci set network.lan.proto=static" -send_line_to_vm "uci set network.lan.ipaddr=192.0.2.1" +send_line_to_vm "uci set network.lan.ipaddr=192.168.2.1" send_line_to_vm "uci set network.lan.netmask=255.255.255.0" send_line_to_vm "uci set firewall.@zone[1].input='ACCEPT'" send_line_to_vm "uci set firewall.@zone[1].forward='ACCEPT'" From 11e0f3a8edd08f384154fd431dba6c55cfeec0f4 Mon Sep 17 00:00:00 2001 From: Rani Hod <59210462+raenye@users.noreply.github.com> Date: Sat, 3 Jun 2023 18:29:30 +0300 Subject: [PATCH 4837/6505] Changes to openwrt.sh (#1460) * Update openwrt.sh Compactify script and fix text (WAN Vlan). * Update openwrt.sh Switch network devices to match OpenWrt defaults (eth0 is lan, eth1 is wan). --- vm/openwrt.sh | 47 ++++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index f5bae843..e3eee268 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -243,11 +243,10 @@ function advanced_settings() { if VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 openwrt --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VM_NAME ]; then HN="openwrt" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" else HN=$(echo ${VM_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" fi + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" else exit-script fi @@ -255,10 +254,8 @@ function advanced_settings() { if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $CORE_COUNT ]; then CORE_COUNT="1" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" fi + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" else exit-script fi @@ -266,10 +263,8 @@ function advanced_settings() { if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 256 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $RAM_SIZE ]; then RAM_SIZE="256" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" fi + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" else exit-script fi @@ -277,10 +272,8 @@ function advanced_settings() { if BRG=$(whiptail --inputbox "Set a WAN Bridge" 8 58 vmbr0 --title "WAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $BRG ]; then BRG="vmbr0" - echo -e "${DGN}Using WAN Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using WAN Bridge: ${BGN}$BRG${CL}" fi + echo -e "${DGN}Using WAN Bridge: ${BGN}$BRG${CL}" else exit-script fi @@ -288,10 +281,8 @@ function advanced_settings() { if LAN_BRG=$(whiptail --inputbox "Set a LAN Bridge" 8 58 vmbr0 --title "LAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $LAN_BRG ]; then LAN_BRG="vmbr0" - echo -e "${DGN}Using LAN Bridge: ${BGN}$LAN_BRG${CL}" - else - echo -e "${DGN}Using LAN Bridge: ${BGN}$LAN_BRG${CL}" fi + echo -e "${DGN}Using LAN Bridge: ${BGN}$LAN_BRG${CL}" else exit-script fi @@ -299,11 +290,10 @@ function advanced_settings() { if MAC1=$(whiptail --inputbox "Set a WAN MAC Address" 8 58 $GEN_MAC --title "WAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then MAC="$GEN_MAC" - echo -e "${DGN}Using WAN MAC Address: ${BGN}$MAC${CL}" else MAC="$MAC1" - echo -e "${DGN}Using WAN MAC Address: ${BGN}$MAC1${CL}" fi + echo -e "${DGN}Using WAN MAC Address: ${BGN}$MAC${CL}" else exit-script fi @@ -311,24 +301,22 @@ function advanced_settings() { if MAC2=$(whiptail --inputbox "Set a LAN MAC Address" 8 58 $GEN_MAC_LAN --title "LAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MAC2 ]; then LAN_MAC="$GEN_MAC_LAN" - echo -e "${DGN}Using LAN MAC Address: ${BGN}$LAN_MAC${CL}" else LAN_MAC="$MAC2" - echo -e "${DGN}Using LAN MAC Address: ${BGN}$MAC2${CL}" fi + echo -e "${DGN}Using LAN MAC Address: ${BGN}$LAN_MAC${CL}" else exit-script fi - if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "WAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VLAN1=$(whiptail --inputbox "Set a WAN Vlan (leave blank for default)" 8 58 --title "WAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN="" - echo -e "${DGN}Using WAN Vlan: ${BGN}$VLAN1${CL}" else VLAN=",tag=$VLAN1" - echo -e "${DGN}Using WAN Vlan: ${BGN}$VLAN1${CL}" fi + echo -e "${DGN}Using WAN Vlan: ${BGN}$VLAN1${CL}" else exit-script fi @@ -337,11 +325,10 @@ function advanced_settings() { if [ -z $VLAN2 ]; then VLAN2="999" LAN_VLAN=",tag=$VLAN2" - echo -e "${DGN}Using LAN Vlan: ${BGN}$VLAN2${CL}" else LAN_VLAN=",tag=$VLAN2" - echo -e "${DGN}Using LAN Vlan: ${BGN}$VLAN2${CL}" fi + echo -e "${DGN}Using LAN Vlan: ${BGN}$VLAN2${CL}" else exit-script fi @@ -350,22 +337,20 @@ function advanced_settings() { if [ -z $MTU1 ]; then MTU1="Default" MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" else MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" else exit-script fi if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" else - echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" fi + echo -e "${DGN}Start VM when completed: ${BGN}$START_VM${CL}" if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create OpenWrt VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a OpenWrt VM using the above advanced settings${CL}" @@ -478,11 +463,11 @@ msg_ok "Network interfaces are being configured as OpenWrt initiates." send_line_to_vm "" send_line_to_vm "uci delete network.@device[0]" send_line_to_vm "uci set network.wan=interface" -send_line_to_vm "uci set network.wan.device=eth0" +send_line_to_vm "uci set network.wan.device=eth1" send_line_to_vm "uci set network.wan.proto=dhcp" send_line_to_vm "uci delete network.lan" send_line_to_vm "uci set network.lan=interface" -send_line_to_vm "uci set network.lan.device=eth1" +send_line_to_vm "uci set network.lan.device=eth0" send_line_to_vm "uci set network.lan.proto=static" send_line_to_vm "uci set network.lan.ipaddr=192.168.2.1" send_line_to_vm "uci set network.lan.netmask=255.255.255.0" @@ -496,8 +481,8 @@ until qm status $VMID | grep -q "stopped"; do done msg_info "Bridge interfaces are being added." qm set $VMID \ - -net0 virtio,bridge=${BRG},macaddr=${MAC}${VLAN}${MTU} \ - -net1 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}${MTU} >/dev/null 2>/dev/null + -net0 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}${MTU} \ + -net1 virtio,bridge=${BRG},macaddr=${MAC}${VLAN}${MTU} >/dev/null 2>/dev/null msg_ok "Bridge interfaces have been successfully added." if [ "$START_VM" == "yes" ]; then msg_info "Starting OpenWrt VM" From c735748faaf00134a9eb13b389cbf539ab70ae61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Jun 2023 04:14:33 -0400 Subject: [PATCH 4838/6505] Update and rename rstptoweb-install.sh to rtsptoweb-install.sh fix spelling --- install/{rstptoweb-install.sh => rtsptoweb-install.sh} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename install/{rstptoweb-install.sh => rtsptoweb-install.sh} (95%) diff --git a/install/rstptoweb-install.sh b/install/rtsptoweb-install.sh similarity index 95% rename from install/rstptoweb-install.sh rename to install/rtsptoweb-install.sh index d345a102..c692c568 100644 --- a/install/rstptoweb-install.sh +++ b/install/rtsptoweb-install.sh @@ -27,14 +27,14 @@ $STD ln -s /usr/local/go/bin/go /usr/local/bin/go rm -rf go1.20.1.linux-amd64.tar.gz msg_ok "Installed Golang" -msg_info "Installing RSTPtoWEB" +msg_info "Installing RTSPtoWwb" $STD git clone https://github.com/deepch/RTSPtoWeb /opt/rtsptoweb cat <>/opt/rtsptoweb/start #!/bin/bash cd /opt/rtsptoweb && GO111MODULE=on go run *.go EOF chmod +x /opt/rtsptoweb/start -msg_ok "Installed RSTPtoWEB" +msg_ok "Installed RTSPtoWeb" msg_info "Creating Service" service_path="/etc/systemd/system/rtsptoweb.service" From 87ff31bb8de47e7d07225ec6a52d6e94d799ee11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Jun 2023 04:18:03 -0400 Subject: [PATCH 4839/6505] Update and rename rstptoweb.sh to rtsptoweb.sh fix spelling --- ct/{rstptoweb.sh => rtsptoweb.sh} | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) rename ct/{rstptoweb.sh => rtsptoweb.sh} (75%) diff --git a/ct/rstptoweb.sh b/ct/rtsptoweb.sh similarity index 75% rename from ct/rstptoweb.sh rename to ct/rtsptoweb.sh index b0e68ab9..ce040eb5 100644 --- a/ct/rstptoweb.sh +++ b/ct/rtsptoweb.sh @@ -8,17 +8,17 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ _______________ __ _ ____________ - / __ \/ ___/_ __/ __ \/ /_____| | / / ____/ __ ) - / /_/ /\__ \ / / / /_/ / __/ __ \ | /| / / __/ / __ | - / _, _/___/ // / / ____/ /_/ /_/ / |/ |/ / /___/ /_/ / -/_/ |_|/____//_/ /_/ \__/\____/|__/|__/_____/_____/ - + ____ ___________ ____ __ _ __ __ + / __ \/_ __/ ___// __ \/ /_____| | / /__ / /_ + / /_/ / / / \__ \/ /_/ / __/ __ \ | /| / / _ \/ __ \ + / _, _/ / / ___/ / ____/ /_/ /_/ / |/ |/ / __/ /_/ / +/_/ |_| /_/ /____/_/ \__/\____/|__/|__/\___/_.___/ + EOF } header_info echo -e "Loading..." -APP="RSTPtoWEB" +APP="RTSPtoWeb" var_disk="4" var_cpu="2" var_ram="2048" From c23de06e363959b92d4c55d43100717f72155589 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Jun 2023 04:24:09 -0400 Subject: [PATCH 4840/6505] Update rtsptoweb-install.sh fix fat finger --- install/rtsptoweb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/rtsptoweb-install.sh b/install/rtsptoweb-install.sh index c692c568..583137be 100644 --- a/install/rtsptoweb-install.sh +++ b/install/rtsptoweb-install.sh @@ -27,7 +27,7 @@ $STD ln -s /usr/local/go/bin/go /usr/local/bin/go rm -rf go1.20.1.linux-amd64.tar.gz msg_ok "Installed Golang" -msg_info "Installing RTSPtoWwb" +msg_info "Installing RTSPtoWeb" $STD git clone https://github.com/deepch/RTSPtoWeb /opt/rtsptoweb cat <>/opt/rtsptoweb/start #!/bin/bash From 3f61e0739398de81e017ea7ba5e1a485b38e10b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Jun 2023 15:23:36 -0400 Subject: [PATCH 4841/6505] Update jellyfin-install.sh modify jellyfin source --- install/jellyfin-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index 1477ef87..e21e158f 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -37,7 +37,7 @@ if [[ "$CTTYPE" == "0" ]]; then fi msg_info "Installing Jellyfin" -VERSION="$( awk -F'=' '/^UBUNTU_CODENAME=/{ print $NF }' /etc/os-release )" +VERSION="$( awk -F'=' '/^(UBUNTU_CODENAME|VERSION_CODENAME)=/{ print $NF }' /etc/os-release )" # If the keyring directory is absent, create it if [[ ! -d /etc/apt/keyrings ]]; then mkdir -p /etc/apt/keyrings From b5eb945f4d4985cb9e8790950d8bd486bb66a42d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Jun 2023 15:58:39 -0400 Subject: [PATCH 4842/6505] Update jellyfin-install.sh tweak --- install/jellyfin-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index e21e158f..787b0ab2 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -37,7 +37,7 @@ if [[ "$CTTYPE" == "0" ]]; then fi msg_info "Installing Jellyfin" -VERSION="$( awk -F'=' '/^(UBUNTU_CODENAME|VERSION_CODENAME)=/{ print $NF }' /etc/os-release )" +VERSION="$( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release )" # If the keyring directory is absent, create it if [[ ! -d /etc/apt/keyrings ]]; then mkdir -p /etc/apt/keyrings From c81589ce433454c8a7267e925323fd4f40c8824c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Jun 2023 18:51:04 -0400 Subject: [PATCH 4843/6505] Update homeassistant-core-install.sh Python 3.11.3 --- install/homeassistant-core-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index daa4d4d2..5df4d607 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -56,10 +56,10 @@ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path) msg_ok "Installed pyenv" . ~/.bashrc set -e -msg_info "Installing Python 3.11.2 (Patience)" -$STD pyenv install 3.11.2 -pyenv global 3.11.2 -msg_ok "Installed Python 3.11.2" +msg_info "Installing Python 3.11.3 (Patience)" +$STD pyenv install 3.11.3 +pyenv global 3.11.3 +msg_ok "Installed Python 3.11.3" msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant From d0a0caa55451b5946270eba9acdfdbfe5e60400f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 04:49:11 -0400 Subject: [PATCH 4844/6505] Update alpine-zigbee2mqtt.sh change default settings to privileged --- ct/alpine-zigbee2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index b7d87edb..f870b965 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -21,7 +21,7 @@ header_info echo -e "Loading..." APP="Alpine-Zigbee2MQTT" var_disk="0.3" -var_cpu="1" +var_cpu="0" var_ram="256" var_os="alpine" var_version="3.17" From db398c3e627a0e5c28cf18d1f43f26d7b0d6ea92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 04:50:20 -0400 Subject: [PATCH 4845/6505] Update alpine-zigbee2mqtt.sh fix my goof --- ct/alpine-zigbee2mqtt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index f870b965..23561b92 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -21,7 +21,7 @@ header_info echo -e "Loading..." APP="Alpine-Zigbee2MQTT" var_disk="0.3" -var_cpu="0" +var_cpu="1" var_ram="256" var_os="alpine" var_version="3.17" @@ -30,7 +30,7 @@ color catch_errors function default_settings() { - CT_TYPE="1" + CT_TYPE="0" PW="" CT_ID=$NEXTID HN=$NSAPP From 8af136338afa4e6563e1acf04d57ee3c214c5194 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 06:30:37 -0400 Subject: [PATCH 4846/6505] Update build.func Prepare for Proxmox Virtual Environment 8 --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index dce870e0..e7be8ae6 100644 --- a/misc/build.func +++ b/misc/build.func @@ -54,7 +54,7 @@ msg_error() { # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then + if ! pveversion | grep -Eq "pve-manager/(7\.[0-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 7.0 or higher" echo -e "Exiting..." From f0d066b6ed8157b44c6798555dc4e453bb653d58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 07:27:55 -0400 Subject: [PATCH 4847/6505] Update alpine-docker.sh Alpine 3.18 --- ct/alpine-docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index d3d4c8ca..9806f568 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -24,7 +24,7 @@ var_disk="2" var_cpu="1" var_ram="1024" var_os="alpine" -var_version="3.17" +var_version="3.18" variables color catch_errors From 6df18b2bf58a68f8975763688b464738d8ee4695 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 07:31:41 -0400 Subject: [PATCH 4848/6505] Update alpine-grafana.sh Alpine 3.18 --- ct/alpine-grafana.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 254cead3..6b82788a 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -24,7 +24,7 @@ var_disk="0.5" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.17" +var_version="3.18" variables color catch_errors From bf96e4b7aa3ccdf0c0831a1eafb571d8e03af33c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 07:32:04 -0400 Subject: [PATCH 4849/6505] Update alpine-vaultwarden.sh Alpine 3.18 --- ct/alpine-vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 525f1404..32b9f946 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -24,7 +24,7 @@ var_disk="0.3" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.17" +var_version="3.18" variables color catch_errors From 36048c4e9157c52f7e36df4c03937cabdb0f14b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 07:32:28 -0400 Subject: [PATCH 4850/6505] Update alpine-zigbee2mqtt.sh Alpine 3.18 --- ct/alpine-zigbee2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 23561b92..d00fcf4c 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -24,7 +24,7 @@ var_disk="0.3" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.17" +var_version="3.18" variables color catch_errors From 3efff3572ef4f15b8e3cf365b676273f513a45f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 07:32:50 -0400 Subject: [PATCH 4851/6505] Update alpine.sh Alpine 3.18 --- ct/alpine.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine.sh b/ct/alpine.sh index 42c9546a..3be89e7b 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -24,7 +24,7 @@ var_disk="0.1" var_cpu="1" var_ram="512" var_os="alpine" -var_version="3.17" +var_version="3.18" variables color catch_errors From fb3502c0bda6b41a9305c93124e17d93fc52168e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 09:07:03 -0400 Subject: [PATCH 4852/6505] Update build.func add Ubuntu 23.04 remove Ubuntu 22.10 --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index e7be8ae6..06e34b59 100644 --- a/misc/build.func +++ b/misc/build.func @@ -153,7 +153,7 @@ advanced_settings() { if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "20.04" "Focal" OFF \ "22.04" "Jammy" OFF \ - "22.10" "Kinetic" OFF \ + "23.04" "Lunar" OFF \ 3>&1 1>&2 2>&3); then if [ -n "$var_version" ]; then echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" From 7b20f5aef8c44126c55409644734e6a28b396fdc Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 12:43:07 -0400 Subject: [PATCH 4853/6505] Update haos-vm.sh PVE 8 ready --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 8709ebc6..06d15d21 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -85,7 +85,7 @@ function msg_error() { } function pve_check() { - if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 7.2 or higher" echo -e "Exiting..." From edd2c4100f8634d28d952a51fdaeed07b0b2c578 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 12:50:12 -0400 Subject: [PATCH 4854/6505] Create pve8-post-install.sh --- misc/pve8-post-install.sh | 210 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 misc/pve8-post-install.sh diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh new file mode 100644 index 00000000..d505d980 --- /dev/null +++ b/misc/pve8-post-install.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +header_info() { + clear + cat <<"EOF" + ____ _ ____________ ____ __ ____ __ ____ + / __ \ | / / ____( __ ) / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / | / / __/ / __ | / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / + / ____/| |/ / /___/ /_/ / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/\____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + +EOF +} + +RD=$(echo "\033[01;31m") +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + + +start_routines() { + header_info + CHOICE=$(whiptail --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling 'pve-enterprise' repository" + sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list + msg_ok "Disabled 'pve-enterprise' repository" + ;; + no) + msg_error "Selected no to Disabling 'pve-enterprise' repository" + ;; + esac + + CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 8 server.\n \nCorrect Proxmox VE 8 sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Correcting Proxmox VE 8 Sources" + cat </etc/apt/sources.list +deb http://ftp.debian.org/debian bookworm main contrib +deb http://ftp.debian.org/debian bookworm-updates main contrib +deb http://security.debian.org/debian-security bookworm-security main contrib +EOF + msg_ok "Corrected Proxmox VE 8 Sources" + ;; + no) + msg_error "Selected no to Correcting Proxmox VE 8 Sources" + ;; + esac + + CHOICE=$(whiptail --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'pve-no-subscription' repository" + cat <>/etc/apt/sources.list +deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription +EOF + msg_ok "Enabled 'pve-no-subscription' repository" + ;; + no) + msg_error "Selected no to Enabling 'pve-no-subscription' repository" + ;; + esac + + CHOICE=$(whiptail --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Adding 'pvetest' repository and set disabled" + cat <>/etc/apt/sources.list +# deb http://download.proxmox.com/debian/pve bookworm pvetest +EOF + msg_ok "Added 'pvetest' repository" + ;; + no) + msg_error "Selected no to Adding 'pvetest' repository" + ;; + esac + + if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then + CHOICE=$(whiptail --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling subscription nag" + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + apt --reinstall install proxmox-widget-toolkit &>/dev/null + msg_ok "Disabled subscription nag (Delete browser cache)" + ;; + no) + msg_error "Selected no to Disabling subscription nag" + ;; + esac + fi + + if systemctl is-active --quiet pve-ha-lrm; then + CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling high availability" + systemctl stop pve-ha-lrm + systemctl disable pve-ha-lrm &>/dev/null + systemctl stop pve-ha-crm + systemctl disable pve-ha-crm &>/dev/null + systemctl stop corosync + systemctl disable corosync &>/dev/null + msg_ok "Disabled high availability" + ;; + no) + msg_error "Selected no to Disabling high availability" + ;; + esac + fi + + CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE 8 now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Updating Proxmox VE 8 (Patience)" + apt-get update &>/dev/null + apt-get -y dist-upgrade &>/dev/null + msg_ok "Updated Proxmox VE 8" + ;; + no) + msg_error "Selected no to Updating Proxmox VE 8" + ;; + esac + + CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE 8 now? (recommended)" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Rebooting Proxmox VE 8" + sleep 2 + msg_ok "Completed Post Install Routines" + reboot + ;; + no) + msg_error "Selected no to Rebooting Proxmox VE 8 (Reboot recommended)" + msg_ok "Completed Post Install Routines" + ;; + esac +} + +header_info +echo -e "\nThis script will Perform Post Install Routines.\n" +while true; do + read -p "Start the Proxmox VE 8 Post Install Script (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) clear; exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +if ! command -v pveversion >/dev/null 2>&1; then + header_info + msg_error "\n No PVE Detected!\n" + exit +fi + +if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then + header_info + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e " Requires PVE Version: 8.XX" + echo -e "\nExiting..." + sleep 3 + exit +fi + +start_routines From 53af603acef550ff691d297eb45f3600fb6dd3b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 16:41:41 -0400 Subject: [PATCH 4855/6505] Update pve8-post-install.sh --- misc/pve8-post-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index d505d980..13338466 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -192,12 +192,6 @@ while true; do esac done -if ! command -v pveversion >/dev/null 2>&1; then - header_info - msg_error "\n No PVE Detected!\n" - exit -fi - if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then header_info msg_error "This version of Proxmox Virtual Environment is not supported" From 1dcc7df1e875b3225f58d5bf3e6dadcf152e63eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 16:50:13 -0400 Subject: [PATCH 4856/6505] Update pve8-post-install.sh --- misc/pve8-post-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index 13338466..2437d19b 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -192,13 +192,4 @@ while true; do esac done -if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - header_info - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e " Requires PVE Version: 8.XX" - echo -e "\nExiting..." - sleep 3 - exit -fi - start_routines From 9d7170d7a25928a6d4592ead5757d9cf8d8de24d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 18:12:13 -0400 Subject: [PATCH 4857/6505] Update pve8-post-install.sh --- misc/pve8-post-install.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index 2437d19b..d505d980 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -192,4 +192,19 @@ while true; do esac done +if ! command -v pveversion >/dev/null 2>&1; then + header_info + msg_error "\n No PVE Detected!\n" + exit +fi + +if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then + header_info + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e " Requires PVE Version: 8.XX" + echo -e "\nExiting..." + sleep 3 + exit +fi + start_routines From 34674317b399ba21f04143d1b4b54b99e06d8a6b Mon Sep 17 00:00:00 2001 From: 5olu7ion <113297102+5olu7ion@users.noreply.github.com> Date: Sat, 10 Jun 2023 00:38:17 +0200 Subject: [PATCH 4858/6505] Case insensitive User Input (#1475) * Always lower User input --- install/alpine-docker-install.sh | 4 ++-- misc/alpine-install.func | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh index 368a4d3f..eacbe6b0 100644 --- a/install/alpine-docker-install.sh +++ b/install/alpine-docker-install.sh @@ -34,7 +34,7 @@ PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") read -r -p "Would you like to add Portainer? " prompt -if echo "$prompt" | grep -Eq "^(y|yes)$"; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null $STD docker run -d \ @@ -49,7 +49,7 @@ if echo "$prompt" | grep -Eq "^(y|yes)$"; then fi read -r -p "Would you like to add Docker Compose? " prompt -if echo "$prompt" | grep -Eq "^(y|yes)$"; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins diff --git a/misc/alpine-install.func b/misc/alpine-install.func index ce38abed..96d1f849 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -86,7 +86,7 @@ network_check() { if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected" read -r -p "Would you like to continue anyway? " prompt - if echo "$prompt" | grep -Eq "^(y|yes)$"; then + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else echo -e " 🖧 Check Network Settings" From 50621a5dfc3da9095b677068b3cc1e0dd63ad8b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 21:17:17 -0400 Subject: [PATCH 4859/6505] Update pve8-post-install.sh add Ceph Package Repositories --- misc/pve8-post-install.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index d505d980..b542867d 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -95,6 +95,23 @@ EOF ;; esac + CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'ceph package repositories'" + cat </etc/apt/sources.list.d/ceph.list +# deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise +deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription +EOF + msg_ok "Enabled 'ceph package repositories'" + ;; + no) + msg_error "Selected no to Enabling 'ceph package repositories'" + ;; + esac + CHOICE=$(whiptail --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) From 063b52f804a9529067ef469c7199209f0b042ab1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 21:27:00 -0400 Subject: [PATCH 4860/6505] Update pve8-post-install.sh tweak 'pve-enterprise' repository --- misc/pve8-post-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index b542867d..04ebf134 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -53,7 +53,9 @@ start_routines() { case $CHOICE in yes) msg_info "Disabling 'pve-enterprise' repository" - sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list + cat </etc/apt/sources.list.d/pve-enterprise.list +# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise +EOF msg_ok "Disabled 'pve-enterprise' repository" ;; no) From 773062b743a9a426a1292eed98a81a78a064f26d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 21:36:50 -0400 Subject: [PATCH 4861/6505] Update pve8-post-install.sh more tweaks --- misc/pve8-post-install.sh | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index 04ebf134..ea440ec6 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -47,21 +47,6 @@ msg_error() { start_routines() { header_info - CHOICE=$(whiptail --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Disabling 'pve-enterprise' repository" - cat </etc/apt/sources.list.d/pve-enterprise.list -# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise -EOF - msg_ok "Disabled 'pve-enterprise' repository" - ;; - no) - msg_error "Selected no to Disabling 'pve-enterprise' repository" - ;; - esac CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 8 server.\n \nCorrect Proxmox VE 8 sources?" 14 58 2 \ "yes" " " \ @@ -81,13 +66,29 @@ EOF ;; esac + CHOICE=$(whiptail --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling 'pve-enterprise' repository" + cat </etc/apt/sources.list.d/pve-enterprise.list +# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise +EOF + msg_ok "Disabled 'pve-enterprise' repository" + ;; + no) + msg_error "Selected no to Disabling 'pve-enterprise' repository" + ;; + esac + CHOICE=$(whiptail --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Enabling 'pve-no-subscription' repository" - cat <>/etc/apt/sources.list + cat </etc/apt/sources.list.d/pve-install-repo.list deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" @@ -120,7 +121,7 @@ EOF case $CHOICE in yes) msg_info "Adding 'pvetest' repository and set disabled" - cat <>/etc/apt/sources.list + cat </etc/apt/sources.list.d/pve-test-repo.list # deb http://download.proxmox.com/debian/pve bookworm pvetest EOF msg_ok "Added 'pvetest' repository" From f38a1afb89ebc322c9cd103640b1d489cd69feae Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Jun 2023 22:08:45 -0400 Subject: [PATCH 4862/6505] Create pve8-install.sh --- misc/pve8-install.sh | 191 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 misc/pve8-install.sh diff --git a/misc/pve8-install.sh b/misc/pve8-install.sh new file mode 100644 index 00000000..d0f032df --- /dev/null +++ b/misc/pve8-install.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +header_info() { + clear + cat <<"EOF" + ____ _ ____________ ____ __ ____ + / __ \ | / / ____( __ ) / _/___ _____/ /_____ _/ / / + / /_/ / | / / __/ / __ | / // __ \/ ___/ __/ __ `/ / / + / ____/| |/ / /___/ /_/ / _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/\____/ /___/_/ /_/____/\__/\__,_/_/_/ + +EOF +} + +RD=$(echo "\033[01;31m") +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + + +start_routines() { + header_info + + CHOICE=$(whiptail --title "PVE8 SOURCES" --menu "This will set the correct sources to update and install Proxmox VE 8.\n \nChange to Proxmox VE 8 sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Changing to Proxmox VE 8 Sources" + cat </etc/apt/sources.list +deb http://ftp.debian.org/debian bookworm main contrib +deb http://ftp.debian.org/debian bookworm-updates main contrib +deb http://security.debian.org/debian-security bookworm-security main contrib +EOF + msg_ok "Changed to Proxmox VE 8 Sources" + ;; + no) + msg_error "Selected no to Correcting Proxmox VE 8 Sources" + ;; + esac + + CHOICE=$(whiptail --title "PVE8-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling 'pve-enterprise' repository" + cat </etc/apt/sources.list.d/pve-enterprise.list +# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise +EOF + msg_ok "Disabled 'pve-enterprise' repository" + ;; + no) + msg_error "Selected no to Disabling 'pve-enterprise' repository" + ;; + esac + + CHOICE=$(whiptail --title "PVE8-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'pve-no-subscription' repository" + cat </etc/apt/sources.list.d/pve-install-repo.list +deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription +EOF + msg_ok "Enabled 'pve-no-subscription' repository" + ;; + no) + msg_error "Selected no to Enabling 'pve-no-subscription' repository" + ;; + esac + + CHOICE=$(whiptail --title "PVE8 CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'ceph package repositories'" + cat </etc/apt/sources.list.d/ceph.list +# deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise +deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription +EOF + msg_ok "Enabled 'ceph package repositories'" + ;; + no) + msg_error "Selected no to Enabling 'ceph package repositories'" + ;; + esac + + CHOICE=$(whiptail --title "PVE8 TEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Adding 'pvetest' repository and set disabled" + cat </etc/apt/sources.list.d/pve-test-repo.list +# deb http://download.proxmox.com/debian/pve bookworm pvetest +EOF + msg_ok "Added 'pvetest' repository" + ;; + no) + msg_error "Selected no to Adding 'pvetest' repository" + ;; + esac + + CHOICE=$(whiptail --title "PVE8 UPDATE" --menu "\nUpdate to Proxmox VE 8 now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Updating to Proxmox VE 8 (Patience)" + apt-get update &>/dev/null + apt-get -y dist-upgrade &>/dev/null + msg_ok "Updated to Proxmox VE 8" + ;; + no) + msg_error "Selected no to Updating to Proxmox VE 8" + ;; + esac + + CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE 8 now? (recommended)" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Rebooting Proxmox VE 8" + sleep 2 + msg_ok "Completed Install Routines" + reboot + ;; + no) + msg_error "Selected no to Rebooting Proxmox VE 8 (Reboot recommended)" + msg_ok "Completed Install Routines" + ;; + esac +} + +header_info +while true; do + read -p "Start the Update to Proxmox VE 8 Script (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) clear; exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +if ! command -v pveversion >/dev/null 2>&1; then + header_info + msg_error "\n No PVE Detected!\n" + exit +fi + +if [ $(pveversion | grep "pve-manager/7.4-13" | wc -l) -ne 1 ]; then + header_info + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e " Requires PVE Version: 7.4-13" + echo -e "\nExiting..." + sleep 3 + exit +fi + +start_routines From ed5d4b273938fb9e645db887b2ce2d18984377ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Jun 2023 09:50:52 -0400 Subject: [PATCH 4863/6505] Update pve8-post-install.sh add Support Subscriptions --- misc/pve8-post-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index ea440ec6..acc04a21 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -137,12 +137,14 @@ EOF "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) + whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_info "Disabling subscription nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled subscription nag (Delete browser cache)" ;; no) + whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_error "Selected no to Disabling subscription nag" ;; esac From a527849c7e0fdcc8af34642c1eb189dbbe8c2a58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Jun 2023 21:20:01 -0400 Subject: [PATCH 4864/6505] Update pve8-install.sh tweak --- misc/pve8-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/pve8-install.sh b/misc/pve8-install.sh index d0f032df..703abd13 100644 --- a/misc/pve8-install.sh +++ b/misc/pve8-install.sh @@ -89,7 +89,7 @@ EOF yes) msg_info "Enabling 'pve-no-subscription' repository" cat </etc/apt/sources.list.d/pve-install-repo.list -deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription +# deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" ;; @@ -121,8 +121,8 @@ EOF case $CHOICE in yes) msg_info "Adding 'pvetest' repository and set disabled" - cat </etc/apt/sources.list.d/pve-test-repo.list -# deb http://download.proxmox.com/debian/pve bookworm pvetest + cat </etc/apt/sources.list.d/pvetest-for-beta.list +deb http://download.proxmox.com/debian/pve bookworm pvetest EOF msg_ok "Added 'pvetest' repository" ;; From b9c564c01d6ca916ed3c7fa13850858a97b97521 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Jun 2023 21:23:15 -0400 Subject: [PATCH 4865/6505] Update pve8-post-install.sh tweak --- misc/pve8-post-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pve8-post-install.sh b/misc/pve8-post-install.sh index acc04a21..c1913dda 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve8-post-install.sh @@ -121,7 +121,7 @@ EOF case $CHOICE in yes) msg_info "Adding 'pvetest' repository and set disabled" - cat </etc/apt/sources.list.d/pve-test-repo.list + cat </etc/apt/sources.list.d/pvetest-for-beta.list # deb http://download.proxmox.com/debian/pve bookworm pvetest EOF msg_ok "Added 'pvetest' repository" From 4ca1a73de21a7fad0794dc3327f7bffcfb2d374e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Jun 2023 21:34:31 -0400 Subject: [PATCH 4866/6505] Update pve8-install.sh tweak --- misc/pve8-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/pve8-install.sh b/misc/pve8-install.sh index 703abd13..0c45f6ff 100644 --- a/misc/pve8-install.sh +++ b/misc/pve8-install.sh @@ -137,8 +137,8 @@ EOF case $CHOICE in yes) msg_info "Updating to Proxmox VE 8 (Patience)" - apt-get update &>/dev/null - apt-get -y dist-upgrade &>/dev/null + apt-get update + apt-get -y dist-upgrade msg_ok "Updated to Proxmox VE 8" ;; no) From e8ff5b6540b34963f989ac5d12ae337c81f4993f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Jun 2023 21:50:20 -0400 Subject: [PATCH 4867/6505] Update pve8-install.sh tweak --- misc/pve8-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pve8-install.sh b/misc/pve8-install.sh index 0c45f6ff..e2786205 100644 --- a/misc/pve8-install.sh +++ b/misc/pve8-install.sh @@ -115,7 +115,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PVE8 TEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ + CHOICE=$(whiptail --title "PVE8 TEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd 'pvetest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From 9e27e197463e69d577abe2a2560f00f78c22f23e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Jun 2023 22:49:42 -0400 Subject: [PATCH 4868/6505] Update and rename pve8-post-install.sh to pve-post-install.sh combine pve7 & pve8 post install scripts --- ...e8-post-install.sh => pve-post-install.sh} | 88 +++++++++---------- 1 file changed, 42 insertions(+), 46 deletions(-) rename misc/{pve8-post-install.sh => pve-post-install.sh} (71%) diff --git a/misc/pve8-post-install.sh b/misc/pve-post-install.sh similarity index 71% rename from misc/pve8-post-install.sh rename to misc/pve-post-install.sh index c1913dda..8e5aa0df 100644 --- a/misc/pve8-post-install.sh +++ b/misc/pve-post-install.sh @@ -8,11 +8,11 @@ header_info() { clear cat <<"EOF" - ____ _ ____________ ____ __ ____ __ ____ - / __ \ | / / ____( __ ) / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / - / /_/ / | / / __/ / __ | / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / - / ____/| |/ / /___/ /_/ / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / -/_/ |___/_____/\____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + ____ _ ________ ____ __ ____ __ ____ + / __ \ | / / ____/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / | / / __/ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / + / ____/| |/ / /___ / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ EOF } @@ -44,25 +44,28 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } - start_routines() { header_info + VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" + if lscpu | grep -qP 'Vendor ID:.*GenuineIntel' && lscpu | grep -qP 'Model name:.*N' && [[ "$VERSION" == "bullseye" ]]; then + whiptail --msgbox --title "N-SERIES PROCESSOR DETECTED" "To ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install Proxmox Virtual Environment 8" 10 58 + fi - CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 8 server.\n \nCorrect Proxmox VE 8 sources?" 14 58 2 \ + CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - msg_info "Correcting Proxmox VE 8 Sources" + msg_info "Correcting Proxmox VE Sources" cat </etc/apt/sources.list -deb http://ftp.debian.org/debian bookworm main contrib -deb http://ftp.debian.org/debian bookworm-updates main contrib -deb http://security.debian.org/debian-security bookworm-security main contrib +deb http://ftp.debian.org/debian $(VERSION) main contrib +deb http://ftp.debian.org/debian $(VERSION)-updates main contrib +deb http://security.debian.org/debian-security $(VERSION)-security main contrib EOF - msg_ok "Corrected Proxmox VE 8 Sources" + msg_ok "Corrected Proxmox VE Sources" ;; no) - msg_error "Selected no to Correcting Proxmox VE 8 Sources" + msg_error "Selected no to Correcting Proxmox VE Sources" ;; esac @@ -73,7 +76,7 @@ EOF yes) msg_info "Disabling 'pve-enterprise' repository" cat </etc/apt/sources.list.d/pve-enterprise.list -# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise +# deb https://enterprise.proxmox.com/debian/pve $(VERSION) pve-enterprise EOF msg_ok "Disabled 'pve-enterprise' repository" ;; @@ -89,7 +92,7 @@ EOF yes) msg_info "Enabling 'pve-no-subscription' repository" cat </etc/apt/sources.list.d/pve-install-repo.list -deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription +deb http://download.proxmox.com/debian/pve $(VERSION) pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" ;; @@ -98,22 +101,24 @@ EOF ;; esac - CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Enabling 'ceph package repositories'" - cat </etc/apt/sources.list.d/ceph.list + if [[ "$(VERSION)" == "bookworm" ]]; then + CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'ceph package repositories'" + cat </etc/apt/sources.list.d/ceph.list # deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription EOF - msg_ok "Enabled 'ceph package repositories'" - ;; - no) - msg_error "Selected no to Enabling 'ceph package repositories'" - ;; - esac + msg_ok "Enabled 'ceph package repositories'" + ;; + no) + msg_error "Selected no to Enabling 'ceph package repositories'" + ;; + esac + fi CHOICE=$(whiptail --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ @@ -122,7 +127,7 @@ EOF yes) msg_info "Adding 'pvetest' repository and set disabled" cat </etc/apt/sources.list.d/pvetest-for-beta.list -# deb http://download.proxmox.com/debian/pve bookworm pvetest +# deb http://download.proxmox.com/debian/pve $(VERSION) pvetest EOF msg_ok "Added 'pvetest' repository" ;; @@ -171,33 +176,33 @@ EOF esac fi - CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE 8 now?" 11 58 2 \ + CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - msg_info "Updating Proxmox VE 8 (Patience)" + msg_info "Updating Proxmox VE (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null - msg_ok "Updated Proxmox VE 8" + msg_ok "Updated Proxmox VE" ;; no) - msg_error "Selected no to Updating Proxmox VE 8" + msg_error "Selected no to Updating Proxmox VE" ;; esac - CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE 8 now? (recommended)" 11 58 2 \ + CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE now? (recommended)" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - msg_info "Rebooting Proxmox VE 8" + msg_info "Rebooting Proxmox VE" sleep 2 msg_ok "Completed Post Install Routines" reboot ;; no) - msg_error "Selected no to Rebooting Proxmox VE 8 (Reboot recommended)" + msg_error "Selected no to Rebooting Proxmox VE (Reboot recommended)" msg_ok "Completed Post Install Routines" ;; esac @@ -206,7 +211,7 @@ EOF header_info echo -e "\nThis script will Perform Post Install Routines.\n" while true; do - read -p "Start the Proxmox VE 8 Post Install Script (y/n)?" yn + read -p "Start the Proxmox VE Post Install Script (y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) clear; exit ;; @@ -220,13 +225,4 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - header_info - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e " Requires PVE Version: 8.XX" - echo -e "\nExiting..." - sleep 3 - exit -fi - start_routines From ac0de26515ff935118378305b7962f4114e25b12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Jun 2023 22:58:34 -0400 Subject: [PATCH 4869/6505] Update post-pve-install.sh combine pve7 & pve8 post install scripts --- misc/post-pve-install.sh | 147 +++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 83 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index ecf8d2de..8e5aa0df 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -8,11 +8,11 @@ header_info() { clear cat <<"EOF" - ____ _ _____________ ____ __ ____ __ ____ - / __ \ | / / ____/__ / / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / - / /_/ / | / / __/ / / / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ / / / - / ____/| |/ / /___ / / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / -/_/ |___/_____/ /_/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + ____ _ ________ ____ __ ____ __ ____ + / __ \ | / / ____/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / | / / __/ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / + / ____/| |/ / /___ / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ |___/_____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ EOF } @@ -44,16 +44,40 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } - start_routines() { header_info + VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" + if lscpu | grep -qP 'Vendor ID:.*GenuineIntel' && lscpu | grep -qP 'Model name:.*N' && [[ "$VERSION" == "bullseye" ]]; then + whiptail --msgbox --title "N-SERIES PROCESSOR DETECTED" "To ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install Proxmox Virtual Environment 8" 10 58 + fi + + CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Correcting Proxmox VE Sources" + cat </etc/apt/sources.list +deb http://ftp.debian.org/debian $(VERSION) main contrib +deb http://ftp.debian.org/debian $(VERSION)-updates main contrib +deb http://security.debian.org/debian-security $(VERSION)-security main contrib +EOF + msg_ok "Corrected Proxmox VE Sources" + ;; + no) + msg_error "Selected no to Correcting Proxmox VE Sources" + ;; + esac + CHOICE=$(whiptail --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Disabling 'pve-enterprise' repository" - sed -i 's/^deb/#deb/g' /etc/apt/sources.list.d/pve-enterprise.list + cat </etc/apt/sources.list.d/pve-enterprise.list +# deb https://enterprise.proxmox.com/debian/pve $(VERSION) pve-enterprise +EOF msg_ok "Disabled 'pve-enterprise' repository" ;; no) @@ -61,32 +85,14 @@ start_routines() { ;; esac - CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE 7 server.\n \nCorrect Proxmox VE 7 sources?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Correcting Proxmox VE 7 Sources" - cat </etc/apt/sources.list -deb http://ftp.debian.org/debian bullseye main contrib -deb http://ftp.debian.org/debian bullseye-updates main contrib -deb http://security.debian.org/debian-security bullseye-security main contrib -EOF - msg_ok "Corrected Proxmox VE 7 Sources" - ;; - no) - msg_error "Selected no to Correcting Proxmox VE 7 Sources" - ;; - esac - CHOICE=$(whiptail --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Enabling 'pve-no-subscription' repository" - cat <>/etc/apt/sources.list -deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription + cat </etc/apt/sources.list.d/pve-install-repo.list +deb http://download.proxmox.com/debian/pve $(VERSION) pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" ;; @@ -95,14 +101,33 @@ EOF ;; esac + if [[ "$(VERSION)" == "bookworm" ]]; then + CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'ceph package repositories'" + cat </etc/apt/sources.list.d/ceph.list +# deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise +deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription +EOF + msg_ok "Enabled 'ceph package repositories'" + ;; + no) + msg_error "Selected no to Enabling 'ceph package repositories'" + ;; + esac + fi + CHOICE=$(whiptail --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) msg_info "Adding 'pvetest' repository and set disabled" - cat <>/etc/apt/sources.list -# deb http://download.proxmox.com/debian/pve bullseye pvetest + cat </etc/apt/sources.list.d/pvetest-for-beta.list +# deb http://download.proxmox.com/debian/pve $(VERSION) pvetest EOF msg_ok "Added 'pvetest' repository" ;; @@ -117,12 +142,14 @@ EOF "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) + whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_info "Disabling subscription nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled subscription nag (Delete browser cache)" ;; no) + whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_error "Selected no to Disabling subscription nag" ;; esac @@ -149,70 +176,33 @@ EOF esac fi - CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE 7 now?" 11 58 2 \ + CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - msg_info "Updating Proxmox VE 7 (Patience)" + msg_info "Updating Proxmox VE (Patience)" apt-get update &>/dev/null apt-get -y dist-upgrade &>/dev/null - msg_ok "Updated Proxmox VE 7" + msg_ok "Updated Proxmox VE" ;; no) - msg_error "Selected no to Updating Proxmox VE 7" + msg_error "Selected no to Updating Proxmox VE" ;; esac - microcode="" - if lscpu | grep -qP 'Vendor ID:.*GenuineIntel' && lscpu | grep -qP 'Model name:.*N'; then - CHOICE=$(whiptail --title "N-SERIES PROCESSOR DETECTED" --menu "\nTo ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install the Proxmox 6.2 kernel.\n\nInstall the Proxmox 6.2 kernel now?" 16 58 2 \ - "yes" " " \ - "no" " " 3>&1 1>&2 2>&3) - case $CHOICE in - yes) - msg_info "Installing Proxmox 6.2 kernel" - apt-get install -y pve-kernel-6.2 &>/dev/null - microcode="need" - msg_ok "Installed Proxmox 6.2 kernel" - ;; - no) - msg_error "Selected no to Installing the Proxmox 6.2 kernel" - ;; - esac - fi - - if [ "$microcode" == "need" ]; then - CHOICE=$(whiptail --title "INTEL MICROCODE" --menu "\nMicrocode updates can fix hardware bugs, improve performance, and enhance security features of the processor.\n\nInstall the Intel Microcode now?" 16 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Installing Intel Microcode" - apt-get install -y iucode-tool &>/dev/null - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230512.1_amd64.deb - dpkg -i intel-microcode_3.20230512.1_amd64.deb &>/dev/null - rm intel-microcode_3.20230512.1_amd64.deb - msg_ok "Installed Intel Microcode" - ;; - no) - msg_error "Selected no to Installing the Intel Microcode" - ;; - esac - fi - - CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE 7 now? (recommended)" 11 58 2 \ + CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE now? (recommended)" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - msg_info "Rebooting Proxmox VE 7" + msg_info "Rebooting Proxmox VE" sleep 2 msg_ok "Completed Post Install Routines" reboot ;; no) - msg_error "Selected no to Rebooting Proxmox VE 7 (Reboot recommended)" + msg_error "Selected no to Rebooting Proxmox VE (Reboot recommended)" msg_ok "Completed Post Install Routines" ;; esac @@ -221,7 +211,7 @@ EOF header_info echo -e "\nThis script will Perform Post Install Routines.\n" while true; do - read -p "Start the Proxmox VE 7 Post Install Script (y/n)?" yn + read -p "Start the Proxmox VE Post Install Script (y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) clear; exit ;; @@ -235,13 +225,4 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then - header_info - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e " Requires PVE Version: 7.XX" - echo -e "\nExiting..." - sleep 3 - exit -fi - start_routines From 1144c614c2ede8462d400d7eded2fc1b2e8ae5c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Jun 2023 22:58:56 -0400 Subject: [PATCH 4870/6505] Delete pve-post-install.sh --- misc/pve-post-install.sh | 228 --------------------------------------- 1 file changed, 228 deletions(-) delete mode 100644 misc/pve-post-install.sh diff --git a/misc/pve-post-install.sh b/misc/pve-post-install.sh deleted file mode 100644 index 8e5aa0df..00000000 --- a/misc/pve-post-install.sh +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -header_info() { - clear - cat <<"EOF" - ____ _ ________ ____ __ ____ __ ____ - / __ \ | / / ____/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / - / /_/ / | / / __/ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / - / ____/| |/ / /___ / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / -/_/ |___/_____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ - -EOF -} - -RD=$(echo "\033[01;31m") -YW=$(echo "\033[33m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" - -set -euo pipefail -shopt -s inherit_errexit nullglob - -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -start_routines() { - header_info - VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" - if lscpu | grep -qP 'Vendor ID:.*GenuineIntel' && lscpu | grep -qP 'Model name:.*N' && [[ "$VERSION" == "bullseye" ]]; then - whiptail --msgbox --title "N-SERIES PROCESSOR DETECTED" "To ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install Proxmox Virtual Environment 8" 10 58 - fi - - CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Correcting Proxmox VE Sources" - cat </etc/apt/sources.list -deb http://ftp.debian.org/debian $(VERSION) main contrib -deb http://ftp.debian.org/debian $(VERSION)-updates main contrib -deb http://security.debian.org/debian-security $(VERSION)-security main contrib -EOF - msg_ok "Corrected Proxmox VE Sources" - ;; - no) - msg_error "Selected no to Correcting Proxmox VE Sources" - ;; - esac - - CHOICE=$(whiptail --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Disabling 'pve-enterprise' repository" - cat </etc/apt/sources.list.d/pve-enterprise.list -# deb https://enterprise.proxmox.com/debian/pve $(VERSION) pve-enterprise -EOF - msg_ok "Disabled 'pve-enterprise' repository" - ;; - no) - msg_error "Selected no to Disabling 'pve-enterprise' repository" - ;; - esac - - CHOICE=$(whiptail --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Enabling 'pve-no-subscription' repository" - cat </etc/apt/sources.list.d/pve-install-repo.list -deb http://download.proxmox.com/debian/pve $(VERSION) pve-no-subscription -EOF - msg_ok "Enabled 'pve-no-subscription' repository" - ;; - no) - msg_error "Selected no to Enabling 'pve-no-subscription' repository" - ;; - esac - - if [[ "$(VERSION)" == "bookworm" ]]; then - CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Enabling 'ceph package repositories'" - cat </etc/apt/sources.list.d/ceph.list -# deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise -deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription -EOF - msg_ok "Enabled 'ceph package repositories'" - ;; - no) - msg_error "Selected no to Enabling 'ceph package repositories'" - ;; - esac - fi - - CHOICE=$(whiptail --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Adding 'pvetest' repository and set disabled" - cat </etc/apt/sources.list.d/pvetest-for-beta.list -# deb http://download.proxmox.com/debian/pve $(VERSION) pvetest -EOF - msg_ok "Added 'pvetest' repository" - ;; - no) - msg_error "Selected no to Adding 'pvetest' repository" - ;; - esac - - if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then - CHOICE=$(whiptail --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 - msg_info "Disabling subscription nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script - apt --reinstall install proxmox-widget-toolkit &>/dev/null - msg_ok "Disabled subscription nag (Delete browser cache)" - ;; - no) - whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 - msg_error "Selected no to Disabling subscription nag" - ;; - esac - fi - - if systemctl is-active --quiet pve-ha-lrm; then - CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Disabling high availability" - systemctl stop pve-ha-lrm - systemctl disable pve-ha-lrm &>/dev/null - systemctl stop pve-ha-crm - systemctl disable pve-ha-crm &>/dev/null - systemctl stop corosync - systemctl disable corosync &>/dev/null - msg_ok "Disabled high availability" - ;; - no) - msg_error "Selected no to Disabling high availability" - ;; - esac - fi - - CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Updating Proxmox VE (Patience)" - apt-get update &>/dev/null - apt-get -y dist-upgrade &>/dev/null - msg_ok "Updated Proxmox VE" - ;; - no) - msg_error "Selected no to Updating Proxmox VE" - ;; - esac - - CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE now? (recommended)" 11 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Rebooting Proxmox VE" - sleep 2 - msg_ok "Completed Post Install Routines" - reboot - ;; - no) - msg_error "Selected no to Rebooting Proxmox VE (Reboot recommended)" - msg_ok "Completed Post Install Routines" - ;; - esac -} - -header_info -echo -e "\nThis script will Perform Post Install Routines.\n" -while true; do - read -p "Start the Proxmox VE Post Install Script (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) clear; exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -if ! command -v pveversion >/dev/null 2>&1; then - header_info - msg_error "\n No PVE Detected!\n" - exit -fi - -start_routines From 63f90bd080b938c67dace1e420566c71a4694c63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Jun 2023 23:19:19 -0400 Subject: [PATCH 4871/6505] Update post-pve-install.sh correct code --- misc/post-pve-install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 8e5aa0df..fcf634df 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -58,9 +58,9 @@ start_routines() { yes) msg_info "Correcting Proxmox VE Sources" cat </etc/apt/sources.list -deb http://ftp.debian.org/debian $(VERSION) main contrib -deb http://ftp.debian.org/debian $(VERSION)-updates main contrib -deb http://security.debian.org/debian-security $(VERSION)-security main contrib +deb http://ftp.debian.org/debian ${VERSION} main contrib +deb http://ftp.debian.org/debian ${VERSION}-updates main contrib +deb http://security.debian.org/debian-security ${VERSION}-security main contrib EOF msg_ok "Corrected Proxmox VE Sources" ;; @@ -76,7 +76,7 @@ EOF yes) msg_info "Disabling 'pve-enterprise' repository" cat </etc/apt/sources.list.d/pve-enterprise.list -# deb https://enterprise.proxmox.com/debian/pve $(VERSION) pve-enterprise +# deb https://enterprise.proxmox.com/debian/pve ${VERSION} pve-enterprise EOF msg_ok "Disabled 'pve-enterprise' repository" ;; @@ -92,7 +92,7 @@ EOF yes) msg_info "Enabling 'pve-no-subscription' repository" cat </etc/apt/sources.list.d/pve-install-repo.list -deb http://download.proxmox.com/debian/pve $(VERSION) pve-no-subscription +deb http://download.proxmox.com/debian/pve ${VERSION} pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" ;; @@ -101,7 +101,7 @@ EOF ;; esac - if [[ "$(VERSION)" == "bookworm" ]]; then + if [[ "${VERSION}" == "bookworm" ]]; then CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) @@ -127,7 +127,7 @@ EOF yes) msg_info "Adding 'pvetest' repository and set disabled" cat </etc/apt/sources.list.d/pvetest-for-beta.list -# deb http://download.proxmox.com/debian/pve $(VERSION) pvetest +# deb http://download.proxmox.com/debian/pve ${VERSION} pvetest EOF msg_ok "Added 'pvetest' repository" ;; From b8e3af815a2e268d14fe6050646e34151ea05e1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Jun 2023 23:23:40 -0400 Subject: [PATCH 4872/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ea88b4..c6ec7014 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-06-11 + +### Changed + +- **Proxmox VE Post Install** + - The Proxmox VE Post Install script is now compatible with both Proxmox Virtual Environment 7 (PVE7) and Proxmox Virtual Environment 8 (PVE8). + ## 2023-06-02 ### Changed From 5eaf4131713996951af78705b9065415e32b0a27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Jun 2023 23:56:21 -0400 Subject: [PATCH 4873/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6ec7014..933730fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ ### Changed - **Proxmox VE Post Install** - - The Proxmox VE Post Install script is now compatible with both Proxmox Virtual Environment 7 (PVE7) and Proxmox Virtual Environment 8 (PVE8). + - Now compatible with both Proxmox Virtual Environment 7 (PVE7) and Proxmox Virtual Environment 8 (PVE8). ## 2023-06-02 From 5dbac97e7a83ba9f741b3abfa6f7b9854bd2c50e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Jun 2023 11:42:12 -0400 Subject: [PATCH 4874/6505] Update kernel-clean.sh compatible with PVE8 --- misc/kernel-clean.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 30660b67..81bc0e63 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -63,7 +63,9 @@ function check_root() { fi } + VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" function other_kernel() { + if [[ "${VERSION}" == "bullseye" ]]; then if [[ "$current_kernel" == *"edge"* ]]; then echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" echo -e "\nAn Active PVE Kernel is required to use Kernel Clean\n" @@ -74,6 +76,7 @@ function other_kernel() { echo -e "\nThe script cannot be used when running opt-in kernels. \nProxmox VE's package management relies directly on the current default kernel, which is 5.15. \nTherefore, it is not possible to utilize this script. In this case, you should use autoremove instead. \n`apt-get autoremove`\n" exit 1 fi + fi } function kernel_info() { From 808b748617456f029244802b8bcd2357fcdb5c97 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Jun 2023 12:23:25 -0400 Subject: [PATCH 4875/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 933730fa..8ff803a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-06-12 + +### Changed + +- **Proxmox VE Edge Kernel** + - Removed, with the Proxmox opt-in kernels and the upcoming Proxmox Virtual Environment 8, edge kernels are no longer needed. + ## 2023-06-11 ### Changed From bba46e59973a383ca8c70d92f7c335ce26bba674 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Jun 2023 12:26:26 -0400 Subject: [PATCH 4876/6505] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ff803a2..60a3e0b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,9 @@ ### Changed - **Proxmox VE Edge Kernel** - - Removed, with the Proxmox opt-in kernels and the upcoming Proxmox Virtual Environment 8, edge kernels are no longer needed. + - Removed, with the Proxmox opt-in kernels and the upcoming Proxmox Virtual Environment 8, edge kernels are no longer needed. +- **Proxmox VE Kernel Clean** + - Now compatible with PVE8. ## 2023-06-11 From ad38e305794593318eeb5c5a6b4a8a6f1a8a9586 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Jun 2023 14:25:01 -0400 Subject: [PATCH 4877/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 6db16420..a08acd7b 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -17,3 +17,5 @@ [Proxmox: Plex LXC with Alder Lake Transcoding](https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html) [How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/) + +[Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html) From 5d5c8572a6a382689a7bdad46277c3e3ae53edbd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 07:41:48 -0400 Subject: [PATCH 4878/6505] Update esphome-install.sh change command order --- install/esphome-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index ce0224f0..6f2a8c28 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -36,7 +36,7 @@ echo "[Unit] Description=ESPHome Dashboard After=network.target [Service] -ExecStart=/usr/local/bin/esphome /root/config/ dashboard +ExecStart=/usr/local/bin/esphome dashboard /root/config/ Restart=always User=root [Install] From f791577124e50bf59d05afe3a82d5cb3eff353da Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 13:03:40 -0400 Subject: [PATCH 4879/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0098eea6..466cfa26 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

    Contributing to Proxmox VE Helper Scripts

    -These scripts allow for the creation of a Linux container or virtual machine in an interactive manner, with options for both basic and advanced configurations. The basic setup uses default settings, while the advanced setup offers the possibility to modify the default settings. Using the whiptail command, the options are displayed in a dialog box format. The script then gathers and verifies the user's input in order to generate the final configuration of the container or virtual machine. +These scripts enable users to build a Linux container or virtual machine in an interactive manner, offering options for both basic and advanced configurations. The basic setup utilizes default settings, whereas the advanced setup empowers users to alter these default settings. Through the use of the whiptail command, options are presented to users in a dialog box format. After the user makes their selections, the script collects and verifies the user's input in order to generate the final configuration for the container or virtual machine.

    Proxmox VE Helper Scripts

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    From 3b7c98b0ce6418394bf003e0da800134113f6206 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 13:12:21 -0400 Subject: [PATCH 4880/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index af213103..736aaed3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -8,7 +8,7 @@ body: - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. - Changing Linux distributions without confirming the proper functioning of default settings. - When encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. - - For questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) + - For suggestions, questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: textarea id: bug attributes: From a7157c64da0ca0074583fd845b9635cd61a40b88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 13:31:55 -0400 Subject: [PATCH 4881/6505] Update alpine-vaultwarden.sh revert to 3.17 --- ct/alpine-vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 32b9f946..525f1404 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -24,7 +24,7 @@ var_disk="0.3" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.18" +var_version="3.17" variables color catch_errors From e1037834d7e5cd02cf599223e2be5ddc95f75ce2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 13:58:00 -0400 Subject: [PATCH 4882/6505] Update alpine-vaultwarden-install.sh https://git.alpinelinux.org/aports/tree/testing/vaultwarden/vaultwarden.post-upgrade --- install/alpine-vaultwarden-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 9d8b628d..74049c3d 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -27,7 +27,7 @@ msg_info "Installing Alpine-Vaultwarden" $STD apk add vaultwarden cat </etc/conf.d/vaultwarden export DATA_FOLDER=/var/lib/vaultwarden -export WEB_VAULT_FOLDER=/var/lib/vaultwarden/web-vault +export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/ export WEB_VAULT_ENABLED=true export ADMIN_TOKEN='' export ROCKET_ADDRESS=0.0.0.0 @@ -37,4 +37,4 @@ $STD rc-update add vaultwarden default msg_ok "Installed Alpine-Vaultwarden" motd_ssh -customize \ No newline at end of file +customize From 46b8a2c529e558e50e93dd34e8fdfea7cd6370d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 13:58:32 -0400 Subject: [PATCH 4883/6505] Update alpine-vaultwarden.sh 3.18 --- ct/alpine-vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 525f1404..32b9f946 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -24,7 +24,7 @@ var_disk="0.3" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.17" +var_version="3.18" variables color catch_errors From 9a99cb682728ee38a1f9dab94d4ec360b4e633aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 14:44:28 -0400 Subject: [PATCH 4884/6505] Update alpine-vaultwarden-install.sh comment `/etc/conf.d/vaultwarden` --- install/alpine-vaultwarden-install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 74049c3d..d80655ab 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -25,13 +25,13 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Vaultwarden" $STD apk add vaultwarden -cat </etc/conf.d/vaultwarden -export DATA_FOLDER=/var/lib/vaultwarden -export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/ -export WEB_VAULT_ENABLED=true -export ADMIN_TOKEN='' -export ROCKET_ADDRESS=0.0.0.0 -EOF +#cat </etc/conf.d/vaultwarden +#export DATA_FOLDER=/var/lib/vaultwarden +#export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/ +#export WEB_VAULT_ENABLED=true +#export ADMIN_TOKEN='' +#export ROCKET_ADDRESS=0.0.0.0 +#EOF $STD rc-service vaultwarden start $STD rc-update add vaultwarden default msg_ok "Installed Alpine-Vaultwarden" From 3acae959c660c9ccd1591f686ebe6c2e00e1a14e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 15:01:56 -0400 Subject: [PATCH 4885/6505] Update alpine-vaultwarden-install.sh fix `/etc/conf.d/vaultwarden` --- install/alpine-vaultwarden-install.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index d80655ab..7442a2ab 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -25,12 +25,9 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Vaultwarden" $STD apk add vaultwarden -#cat </etc/conf.d/vaultwarden -#export DATA_FOLDER=/var/lib/vaultwarden -#export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/ -#export WEB_VAULT_ENABLED=true -#export ADMIN_TOKEN='' -#export ROCKET_ADDRESS=0.0.0.0 +cat <>/etc/conf.d/vaultwarden +export ADMIN_TOKEN='' +export ROCKET_ADDRESS=0.0.0.0 #EOF $STD rc-service vaultwarden start $STD rc-update add vaultwarden default From 5e2605526495bf7cd535b030eec62ad2a6a5c883 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 15:04:38 -0400 Subject: [PATCH 4886/6505] Update alpine-vaultwarden-install.sh --- install/alpine-vaultwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 7442a2ab..0c6731fa 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -28,7 +28,7 @@ $STD apk add vaultwarden cat <>/etc/conf.d/vaultwarden export ADMIN_TOKEN='' export ROCKET_ADDRESS=0.0.0.0 -#EOF +EOF $STD rc-service vaultwarden start $STD rc-update add vaultwarden default msg_ok "Installed Alpine-Vaultwarden" From 0442562ce0ba9eddda95bdca2034aa604ad6a120 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 16:33:25 -0400 Subject: [PATCH 4887/6505] Update alpine-vaultwarden-install.sh fix installation --- install/alpine-vaultwarden-install.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 0c6731fa..502720d9 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -25,13 +25,23 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Vaultwarden" $STD apk add vaultwarden -cat <>/etc/conf.d/vaultwarden -export ADMIN_TOKEN='' -export ROCKET_ADDRESS=0.0.0.0 -EOF +sudo sed -i -e 's/# export ADMIN_TOKEN=.*/export ADMIN_TOKEN='\'''\''/' -e '/^# export ROCKET_ADDRESS=0\.0\.0\.0/s/^# //' -e 's|export WEB_VAULT_FOLDER=.*|export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/web-vault/|' -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden +msg_ok "Installed Alpine-Vaultwarden" + +WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz +mkdir -p /usr/share/webapps/vaultwarden-web/ + +msg_info "Downloading Web-Vault ${WEBVAULT}" +$STD curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz +$STD tar -xzf bw_web_$WEBVAULT.tar.gz -C /usr/share/webapps/vaultwarden-web/ +rm bw_web_$WEBVAULT.tar.gz +msg_ok "Downloaded Web-Vault ${WEBVAULT}" + +msg_info "Starting Alpine-Vaultwarden" $STD rc-service vaultwarden start $STD rc-update add vaultwarden default -msg_ok "Installed Alpine-Vaultwarden" +msg_info "Started Alpine-Vaultwarden" motd_ssh customize From e9069b928c26029ee61b77cd71d24295e5cc6e51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 16:35:38 -0400 Subject: [PATCH 4888/6505] Update alpine-vaultwarden-install.sh tweak --- install/alpine-vaultwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 502720d9..9aba978f 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -25,7 +25,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Vaultwarden" $STD apk add vaultwarden -sudo sed -i -e 's/# export ADMIN_TOKEN=.*/export ADMIN_TOKEN='\'''\''/' -e '/^# export ROCKET_ADDRESS=0\.0\.0\.0/s/^# //' -e 's|export WEB_VAULT_FOLDER=.*|export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/web-vault/|' -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden +sed -i -e 's/# export ADMIN_TOKEN=.*/export ADMIN_TOKEN='\'''\''/' -e '/^# export ROCKET_ADDRESS=0\.0\.0\.0/s/^# //' -e 's|export WEB_VAULT_FOLDER=.*|export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/web-vault/|' -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden msg_ok "Installed Alpine-Vaultwarden" WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From 5841b20b1f32b56d11f467c819002a737603edfc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 16:57:01 -0400 Subject: [PATCH 4889/6505] Update alpine-vaultwarden-install.sh Code refactoring --- install/alpine-vaultwarden-install.sh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 9aba978f..f62f6b32 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -25,18 +25,12 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Vaultwarden" $STD apk add vaultwarden -sed -i -e 's/# export ADMIN_TOKEN=.*/export ADMIN_TOKEN='\'''\''/' -e '/^# export ROCKET_ADDRESS=0\.0\.0\.0/s/^# //' -e 's|export WEB_VAULT_FOLDER=.*|export WEB_VAULT_FOLDER=/usr/share/webapps/vaultwarden-web/web-vault/|' -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden +sed -i -e 's/# export ADMIN_TOKEN=.*/export ADMIN_TOKEN='\'''\''/' -e '/^# export ROCKET_ADDRESS=0\.0\.0\.0/s/^# //' -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden msg_ok "Installed Alpine-Vaultwarden" -WEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz -mkdir -p /usr/share/webapps/vaultwarden-web/ - -msg_info "Downloading Web-Vault ${WEBVAULT}" -$STD curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz -$STD tar -xzf bw_web_$WEBVAULT.tar.gz -C /usr/share/webapps/vaultwarden-web/ -rm bw_web_$WEBVAULT.tar.gz -msg_ok "Downloaded Web-Vault ${WEBVAULT}" +msg_info "Installing Web-Vault" +$STD apk add vaultwarden-web-vault +msg_ok "Installed Web-Vault" msg_info "Starting Alpine-Vaultwarden" $STD rc-service vaultwarden start From bbb57624579bfc2e7be1cea8a85985d68e2ffe47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Jun 2023 17:24:09 -0400 Subject: [PATCH 4890/6505] Update alpine-vaultwarden-install.sh --- install/alpine-vaultwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index f62f6b32..c66c36b3 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -35,7 +35,7 @@ msg_ok "Installed Web-Vault" msg_info "Starting Alpine-Vaultwarden" $STD rc-service vaultwarden start $STD rc-update add vaultwarden default -msg_info "Started Alpine-Vaultwarden" +msg_ok "Started Alpine-Vaultwarden" motd_ssh customize From 591491d5fb9ba7b48a04eb1ba40985f65efbeed2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Jun 2023 11:31:31 -0400 Subject: [PATCH 4891/6505] Update omada-install.sh - change dependencies to utilize Debian 11 - Ubuntu 20.04 has been removed from the Proxmox VE 8 container template index --- install/omada-install.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index adcfe5aa..3acc7c8e 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -18,11 +18,21 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y gnupg -$STD apt-get install -y openjdk-8-jre-headless $STD apt-get install -y jsvc +msg_ok "Installed Dependencies" + +msg_info "Installing Azul Zulu" +$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 +wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb +$STD apt-get install ./zulu-repo_1.0.0-3_all.deb +$STD apt-get update +$STD apt-get -y install zulu8-jdk +msg_ok "Installed Azul Zulu" + +msg_info "Installing MongoDB" wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb -msg_ok "Installed Dependencies" +msg_ok "Installed MongoDB" msg_info "Installing Omada Controller v5.9.31" wget -qL https://static.tp-link.com/upload/software/2023/202303/20230321/Omada_SDN_Controller_v5.9.31_Linux_x64.deb @@ -33,7 +43,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -f Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb +rm -f Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From e40593c058fd00258e3046c411dac477078a5ec3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Jun 2023 11:32:22 -0400 Subject: [PATCH 4892/6505] Update omada.sh switch to Debian --- ct/omada.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/omada.sh b/ct/omada.sh index c355622e..a5df6f9b 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -22,8 +22,8 @@ APP="Omada" var_disk="8" var_cpu="2" var_ram="2048" -var_os="ubuntu" -var_version="20.04" +var_os="debian" +var_version="11" variables color catch_errors From 557f8dcf463a7058b2143a52732d81b529791216 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Jun 2023 13:12:40 -0400 Subject: [PATCH 4893/6505] Update monitor-all.sh Use the first given IP in a VM --- misc/monitor-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 236016ee..483acd48 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -46,7 +46,7 @@ while true; do else # It is a virtual machine config_cmd="qm config" - IP=$(qm guest cmd $instance network-get-interfaces | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -E "192\.|10\.") + IP=$(qm guest cmd $instance network-get-interfaces | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -E "192\.|10\." | head -n 1)) fi # Skip instances based on templates From 72f3648730de3db97a0b564942b80321d85a0222 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Jun 2023 13:52:07 -0400 Subject: [PATCH 4894/6505] Update monitor-all.sh --- misc/monitor-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 483acd48..9eec0d1a 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -46,7 +46,7 @@ while true; do else # It is a virtual machine config_cmd="qm config" - IP=$(qm guest cmd $instance network-get-interfaces | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -E "192\.|10\." | head -n 1)) + IP=$(qm guest cmd $instance network-get-interfaces | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -E "192\.|10\." | head -n 1) fi # Skip instances based on templates From ca4a3ecef281590b6fac3c98339f7ac91e57f27c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Jun 2023 07:48:54 -0400 Subject: [PATCH 4895/6505] Update build.func add option to choose Debian version --- misc/build.func | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index 06e34b59..9d59ada1 100644 --- a/misc/build.func +++ b/misc/build.func @@ -143,8 +143,19 @@ advanced_settings() { fi if [ "$var_os" == "debian" ]; then - var_version="11" - echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" + var_version="" + while [ -z "$var_version" ]; do + if var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ + "11" "Bullseye" OFF \ + "12" "Bookworm" OFF \ + 3>&1 1>&2 2>&3); then + if [ -n "$var_version" ]; then + echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" + fi + else + exit-script + fi + done fi if [ "$var_os" == "ubuntu" ]; then From 0d5754de1249cc509087863bb1db22f448993c63 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Jun 2023 08:17:07 -0400 Subject: [PATCH 4896/6505] Update pve8-install.sh tweak --- misc/pve8-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pve8-install.sh b/misc/pve8-install.sh index e2786205..b9ff380b 100644 --- a/misc/pve8-install.sh +++ b/misc/pve8-install.sh @@ -138,7 +138,7 @@ EOF yes) msg_info "Updating to Proxmox VE 8 (Patience)" apt-get update - apt-get -y dist-upgrade + DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y msg_ok "Updated to Proxmox VE 8" ;; no) From 8c2a3cc4d774fa13d17f695d6bdf9a4deedb1372 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Jun 2023 14:11:38 -0400 Subject: [PATCH 4897/6505] Update monitor-all.sh Skip instances based on onboot and templates --- misc/monitor-all.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 9eec0d1a..65dbca92 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -49,9 +49,14 @@ while true; do IP=$(qm guest cmd $instance network-get-interfaces | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -E "192\.|10\." | head -n 1) fi - # Skip instances based on templates + # Skip instances based on onboot and templates + onboot=$($config_cmd $instance | grep onboot | grep -q "onboot: 0" && echo "true" || echo "false") template=$($config_cmd $instance | grep template | grep -q "template:" && echo "true" || echo "false") - if [ "$template" == "true" ]; then + + if [ "$onboot" == "true" ]; then + echo "Skipping $instance because it is set not to boot" + continue + elif [ "$template" == "true" ]; then echo "Skipping $instance because it is a template" continue fi From 61118ab83b0f91d9fb267e3878c537cd11bb860a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Jun 2023 14:33:58 -0400 Subject: [PATCH 4898/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60a3e0b7..6595c4ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-06-16 + +### Changed + +- **Proxmox VE Monitor-All** + - Skip instances based on onboot and templates. [8c2a3cc](https://github.com/tteck/Proxmox/commit/8c2a3cc4d774fa13d17f695d6bdf9a4deedb1372). + ## 2023-06-12 ### Changed From e80dbb4aade8467995a108dc8c80e8359deca584 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Jun 2023 16:42:46 -0400 Subject: [PATCH 4899/6505] Update homeassistant-core-install.sh add bookworm --- install/homeassistant-core-install.sh | 125 ++++++++++++++++---------- 1 file changed, 76 insertions(+), 49 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 5df4d607..f260b76c 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -13,53 +13,82 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y \ - git \ - curl \ - sudo \ - mc \ - build-essential \ - libssl-dev \ - zlib1g-dev \ - libbz2-dev \ - libpcap-dev \ - libreadline-dev \ - libsqlite3-dev \ - libncursesw5-dev \ - xz-utils \ - tk-dev \ - llvm \ - libxml2-dev \ - libxmlsec1-dev \ - libffi-dev \ - liblzma-dev \ - dbus-broker \ - bluez \ - libmariadb-dev-compat \ - libjpeg-dev \ - autoconf \ - libopenjp2-7 \ - libtiff5 \ - libturbojpeg0-dev \ - liblapack3 \ - liblapack-dev \ - libatlas-base-dev -msg_ok "Installed Dependencies" +if [[ "$PCT_OSVERSION" == "12" ]]; then + msg_info "Installing Dependencies, Bookworm (Patience)" + $STD apt-get install -y \ + git \ + curl \ + sudo \ + mc \ + python3 \ + python3-dev \ + python3-venv \ + python3-pip \ + bluez \ + libffi-dev \ + libssl-dev \ + libjpeg-dev \ + zlib1g-dev \ + autoconf \ + build-essential \ + libopenjp2-7 \ + libturbojpeg0-dev \ + tzdata \ + ffmpeg \ + liblapack3 \ + liblapack-dev \ + libatlas-base-dev + $STD systemctl disable systemd-networkd-wait-online.service + msg_ok "Installed Dependencies" +else + msg_info "Installing Dependencies, Bullseye (Patience)" + $STD apt-get install -y \ + git \ + curl \ + sudo \ + mc \ + build-essential \ + libssl-dev \ + zlib1g-dev \ + libbz2-dev \ + libpcap-dev \ + libreadline-dev \ + libsqlite3-dev \ + libncursesw5-dev \ + xz-utils \ + tk-dev \ + llvm \ + libxml2-dev \ + libxmlsec1-dev \ + libffi-dev \ + liblzma-dev \ + dbus-broker \ + bluez \ + libmariadb-dev-compat \ + libjpeg-dev \ + autoconf \ + libopenjp2-7 \ + libtiff5 \ + libturbojpeg0-dev \ + liblapack3 \ + liblapack-dev \ + libatlas-base-dev + msg_ok "Installed Dependencies" -msg_info "Installing pyenv" -$STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv -set +e -echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc -echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc -echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >> ~/.bashrc -msg_ok "Installed pyenv" -. ~/.bashrc -set -e -msg_info "Installing Python 3.11.3 (Patience)" -$STD pyenv install 3.11.3 -pyenv global 3.11.3 -msg_ok "Installed Python 3.11.3" + msg_info "Installing pyenv" + $STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv + set +e + echo 'export PYENV_ROOT="$HOME/.pyenv"' >>~/.bashrc + echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >>~/.bashrc + echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >>~/.bashrc + msg_ok "Installed pyenv" + . ~/.bashrc + set -e + msg_info "Installing Python 3.11.3 (Patience)" + $STD pyenv install 3.11.3 + pyenv global 3.11.3 + msg_ok "Installed Python 3.11.3" +fi msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant @@ -68,8 +97,6 @@ python3 -m venv . source bin/activate $STD pip install --upgrade pip $STD python3 -m pip install wheel -$STD pip install mysqlclient -$STD pip install psycopg2-binary $STD pip install homeassistant mkdir -p /root/.homeassistant msg_ok "Installed Home Assistant-Core" From 4c752c9d5001583694ea3bc8d0c944dc5d739ec6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 05:52:43 -0400 Subject: [PATCH 4900/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6595c4ee..18dcaed8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ ### Changed - **Proxmox VE 7 Post Install** - - If an Intel N-series processor is detected, the script provides options to install both the Proxmox 6.2 kernel and the Intel microcode. + - If an Intel N-series processor is detected, ~the script provides options to install both the Proxmox 6.2 kernel and the Intel microcode.~ and using PVE7, recommend using PVE8 ## 2023-05-23 From 2101583d1a07f3a22eced4b41d95b2b0139e68dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 10:42:01 -0400 Subject: [PATCH 4901/6505] Update mqtt-install.sh use standard Debian packages --- install/mqtt-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 71e0ef9a..9534db5a 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -17,15 +17,9 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Installing Mosquitto MQTT Broker" -$STD wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key -$STD apt-key add mosquitto-repo.gpg.key -cd /etc/apt/sources.list.d/ -$STD wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list -$STD apt-get update $STD apt-get -y install mosquitto $STD apt-get -y install mosquitto-clients msg_ok "Installed Mosquitto MQTT Broker" From 9ef8a4ae4fe9c9d59fc8af06a48e3670ccadcd6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 18:22:23 -0400 Subject: [PATCH 4902/6505] Update unifi-install.sh Debian 12 compatible --- install/unifi-install.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 11515d90..4ce0e417 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -20,12 +20,19 @@ $STD apt-get install -y mc $STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" +if [[ "$PCT_OSVERSION" == "12" ]]; then + echo -e "deb http://ftp.debian.org/debian bullseye main" >/etc/apt/sources.list.d/openjdk-11-jre-headless.list + $STD apt-get update +fi + msg_info "Installing OpenJDK" $STD apt-get install -y openjdk-11-jre-headless $STD apt-mark hold openjdk-11-* msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" @@ -41,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf mongodb-org-server_3.6.23_amd64.deb +rm -rf mongodb-org-server_3.6.23_amd64.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 28f5363737e96155e2758071091ce5dd6d91ae15 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 18:23:50 -0400 Subject: [PATCH 4903/6505] Update omada-install.sh Debian 12 compatible --- install/omada-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index 3acc7c8e..f6bb625d 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -30,6 +30,8 @@ $STD apt-get -y install zulu8-jdk msg_ok "Installed Azul Zulu" msg_info "Installing MongoDB" +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" @@ -43,7 +45,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -f Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb +rm -f Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 59110997d51a2d4d1bd3ba0605da841ceb52fdcf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 18:30:05 -0400 Subject: [PATCH 4904/6505] Update install.func Tweak for Debian 12 --- misc/install.func | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/install.func b/misc/install.func index ca112b9e..34b3d07d 100644 --- a/misc/install.func +++ b/misc/install.func @@ -124,6 +124,9 @@ motd_ssh() { sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config systemctl restart sshd fi + if [[ "$PCT_OSVERSION" == "12" ]]; then + $STD systemctl disable systemd-networkd-wait-online.service + fi } # This function customizes the container by modifying the getty service and enabling auto-login for the root user From a66326f613795223c4db0783987e7ac84333db70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 19:01:38 -0400 Subject: [PATCH 4905/6505] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18dcaed8..d47c4a7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-06-17 + +### Changed + +- **UniFi Network Application LXC** + - Now distribution agnostic. +- **Omada Controller LXC** + - Now distribution agnostic. ## 2023-06-16 ### Changed From 86c04bfe22ba9af54c0a1ab72c6c56d222c1659b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 19:22:15 -0400 Subject: [PATCH 4906/6505] Update homeassistant-core-install.sh moved to install.func --- install/homeassistant-core-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index f260b76c..fca134f3 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -38,7 +38,6 @@ if [[ "$PCT_OSVERSION" == "12" ]]; then liblapack3 \ liblapack-dev \ libatlas-base-dev - $STD systemctl disable systemd-networkd-wait-online.service msg_ok "Installed Dependencies" else msg_info "Installing Dependencies, Bullseye (Patience)" From 9520eebb349eff0b20e66feef898efe15fad34b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Jun 2023 22:51:19 -0400 Subject: [PATCH 4907/6505] Update grocy-install.sh Debian 12 compatible --- install/grocy-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 47da262c..19146413 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -17,14 +17,13 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y apache2 $STD apt-get install -y apt-transport-https -$STD apt-get install -y lsb-release msg_ok "Installed Dependencies" msg_info "Installing PHP 8.1" +VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg -sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' +echo -e "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main" >/etc/apt/sources.list.d/php.list $STD apt-get update $STD apt-get install -y php8.1 $STD apt-get install -y libapache2-mod-php8.1 From 0273034e2880a4bb715104f875659f75e7ec2e38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 07:35:55 -0400 Subject: [PATCH 4908/6505] Update pihole-install.sh distribution agnostic fixes https://github.com/tteck/Proxmox/issues/1505 --- install/pihole-install.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/install/pihole-install.sh b/install/pihole-install.sh index 9006ae2f..881cb233 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -22,9 +22,6 @@ $STD apt-get install -y ntp msg_ok "Installed Dependencies" msg_info "Installing Pi-hole" -systemctl stop systemd-resolved -echo "DNSStubListener=no" >>/etc/systemd/resolved.conf -ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf mkdir -p /etc/pihole/ cat </etc/pihole/setupVars.conf PIHOLE_INTERFACE=eth0 @@ -41,8 +38,8 @@ DNSMASQ_LISTENING=local WEBPASSWORD=$(openssl rand -base64 48) BLOCKING_ENABLED=true EOF - -$STD bash <(curl -fsSL https://install.pi-hole.net) /dev/stdin --unattended +# View script https://install.pi-hole.net +$STD bash <(curl -fsSL https://install.pi-hole.net) --unattended msg_ok "Installed Pi-hole" motd_ssh From 5e3e3efe5697c6967fbb21c801a86152d95140a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 09:52:04 -0400 Subject: [PATCH 4909/6505] Update homeassistant-core-install.sh add libpcap-dev dependency, Debian 12 fixes https://github.com/tteck/Proxmox/issues/1506 --- install/homeassistant-core-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index fca134f3..7b0dd835 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -37,6 +37,7 @@ if [[ "$PCT_OSVERSION" == "12" ]]; then ffmpeg \ liblapack3 \ liblapack-dev \ + libpcap-dev \ libatlas-base-dev msg_ok "Installed Dependencies" else From e9b18f88a56d0c7de8ba8c4e1285b6937df5acde Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 16:44:29 -0400 Subject: [PATCH 4910/6505] Update nginxproxymanager-install.sh Debian 12 compatible fixes https://github.com/tteck/Proxmox/issues/1507 --- install/nginxproxymanager-install.sh | 41 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 1300266d..980902eb 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -21,41 +21,41 @@ $STD apt-get -y install \ curl \ gnupg \ make \ - g++ \ gcc \ + g++ \ ca-certificates \ apache2-utils \ logrotate \ build-essential \ - python3-dev \ - git \ - lsb-release + git msg_ok "Installed Dependencies" msg_info "Installing Python" -$STD apt-get install -y -q --no-install-recommends python3 python3-pip python3-venv -$STD pip3 install --upgrade setuptools -$STD pip3 install --upgrade pip +$STD apt-get install -y \ +python3 \ +python3-dev \ +python3-pip \ +python3-venv \ +python3-cffi \ +python3-certbot \ +python3-certbot-dns-cloudflare $STD python3 -m venv /opt/certbot/ -if [ "$(getconf LONG_BIT)" = "32" ]; then - $STD python3 -m pip install --no-cache-dir -U cryptography==3.3.2 -fi -$STD python3 -m pip install --no-cache-dir cffi certbot certbot-dns-cloudflare msg_ok "Installed Python" +VERSION="$( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release )" + msg_info "Installing Openresty" -$STD apt-key add <(curl -fsSL https://openresty.org/package/pubkey.gpg) -sh -c 'echo "deb http://openresty.org/package/debian $(lsb_release -cs) openresty" > /etc/apt/sources.list.d/openresty.list' -$STD apt-get -y update -$STD apt-get -y install --no-install-recommends openresty +wget -qO - https://openresty.org/package/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg +echo -e "deb http://openresty.org/package/debian bullseye openresty" >/etc/apt/sources.list.d/openresty.list +$STD apt-get update +$STD apt-get -y install openresty msg_ok "Installed Openresty" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh) +source ~/.bashrc +$STD nvm install 16 +ln -sf /root/.nvm/versions/node/v16.20.0/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Yarn" @@ -117,7 +117,6 @@ chown root /tmp/nginx echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -en "${GN} Generating dummy SSL Certificate... " openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null fi From 12b51b866f4189cfaff2d328c6dae63b2af27222 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 17:39:04 -0400 Subject: [PATCH 4911/6505] Update homeassistant-core-install.sh cleanup --- install/homeassistant-core-install.sh | 43 ++++++++------------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 7b0dd835..85e9393d 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -13,8 +13,7 @@ setting_up_container network_check update_os -if [[ "$PCT_OSVERSION" == "12" ]]; then - msg_info "Installing Dependencies, Bookworm (Patience)" + msg_info "Installing Dependencies, (Patience)" $STD apt-get install -y \ git \ curl \ @@ -33,49 +32,30 @@ if [[ "$PCT_OSVERSION" == "12" ]]; then build-essential \ libopenjp2-7 \ libturbojpeg0-dev \ - tzdata \ ffmpeg \ liblapack3 \ liblapack-dev \ + dbus-broker \ libpcap-dev \ + libmariadb-dev-compat \ libatlas-base-dev msg_ok "Installed Dependencies" -else - msg_info "Installing Dependencies, Bullseye (Patience)" + +if [[ "$PCT_OSVERSION" == "11" ]]; then + msg_info "Installing pyenv" $STD apt-get install -y \ - git \ - curl \ - sudo \ - mc \ - build-essential \ - libssl-dev \ - zlib1g-dev \ - libbz2-dev \ - libpcap-dev \ + make \ libreadline-dev \ libsqlite3-dev \ + libncurses5-dev \ libncursesw5-dev \ xz-utils \ tk-dev \ llvm \ + libbz2-dev \ libxml2-dev \ libxmlsec1-dev \ - libffi-dev \ - liblzma-dev \ - dbus-broker \ - bluez \ - libmariadb-dev-compat \ - libjpeg-dev \ - autoconf \ - libopenjp2-7 \ - libtiff5 \ - libturbojpeg0-dev \ - liblapack3 \ - liblapack-dev \ - libatlas-base-dev - msg_ok "Installed Dependencies" - - msg_info "Installing pyenv" + liblzma-dev $STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv set +e echo 'export PYENV_ROOT="$HOME/.pyenv"' >>~/.bashrc @@ -83,6 +63,7 @@ else echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >>~/.bashrc msg_ok "Installed pyenv" . ~/.bashrc + set -e msg_info "Installing Python 3.11.3 (Patience)" $STD pyenv install 3.11.3 @@ -98,6 +79,8 @@ source bin/activate $STD pip install --upgrade pip $STD python3 -m pip install wheel $STD pip install homeassistant +$STD pip install mysqlclient +$STD pip install psycopg2-binary mkdir -p /root/.homeassistant msg_ok "Installed Home Assistant-Core" From 4110e60f1b691aa7a670da7bdc088224b536d85c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 17:52:51 -0400 Subject: [PATCH 4912/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 980902eb..ab1e760e 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -53,7 +53,7 @@ msg_ok "Installed Openresty" msg_info "Installing Node.js" $STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh) -source ~/.bashrc +. ~/.bashrc $STD nvm install 16 ln -sf /root/.nvm/versions/node/v16.20.0/bin/node /usr/bin/node msg_ok "Installed Node.js" From 61017e13cec7fb72c55b7638a8cb0630243bd6f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 21:38:27 -0400 Subject: [PATCH 4913/6505] Create openobserve-install.sh --- install/openobserve-install.sh | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 install/openobserve-install.sh diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh new file mode 100644 index 00000000..487864b4 --- /dev/null +++ b/install/openobserve-install.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing OpenObserve" +mkdir -p /opt/openserve/data +LATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +$STD tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve + +cat </opt/openobserve/data/.env +ZO_ROOT_USER_EMAIL = "admin@example.com" +ZO_ROOT_USER_PASSWORD = "$(openssl rand -base64 18 | cut -c1-13)" +ZO_DATA_DIR = "/opt/openobserve/data" +ZO_HTTP_PORT = "5080" +EOF +msg_ok "Installed OpenObserve" + +msg_info "Creating Service" +cat </etc/systemd/system/openobserve.service +[Unit] +Description=OpenObserve +After=syslog.target network-online.target remote-fs.target nss-lookup.target +Wants=network-online.target + +[Service] +Type=simple +EnvironmentFile=/opt/openobserve/data/.env +ExecStart=/opt/openobserve/openobserve +ExecStop=killall -QUIT openobserve +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From c6e3cd1e6544698c6dfb7b33f2dee96a265cbfb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 21:41:09 -0400 Subject: [PATCH 4914/6505] Create openobserve.sh --- ct/openobserve.sh | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 ct/openobserve.sh diff --git a/ct/openobserve.sh b/ct/openobserve.sh new file mode 100644 index 00000000..7cdd431e --- /dev/null +++ b/ct/openobserve.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + + ____ ____ __ + / __ \____ ___ ____ / __ \/ /_ ________ ______ _____ + / / / / __ \/ _ \/ __ \/ / / / __ \/ ___/ _ \/ ___/ | / / _ \ +/ /_/ / /_/ / __/ / / / /_/ / /_/ (__ ) __/ / | |/ / __/ +\____/ .___/\___/_/ /_/\____/_.___/____/\___/_/ |___/\___/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="OpenObserve" +var_disk="3" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/openobserve/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +systemctl stop openobsecure +LATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve +systemctl start openobsecure +msg_ok "Updated $APP" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5080${CL} \n" From fb8620bab1c1fae6ac72b6900746198bcfd6e287 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 21:57:54 -0400 Subject: [PATCH 4915/6505] Add files via upload --- misc/images/openobsecure.svg | Bin 0 -> 45295 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/openobsecure.svg diff --git a/misc/images/openobsecure.svg b/misc/images/openobsecure.svg new file mode 100644 index 0000000000000000000000000000000000000000..52bbc9707d2eff299bf0c03c5f5a76ab51d3d8dc GIT binary patch literal 45295 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 literal 0 HcmV?d00001 From 0b904a8d7a533503831a15a5fe2f8c95a6400387 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 22:00:06 -0400 Subject: [PATCH 4916/6505] Add files via upload --- misc/images/openobsecure.png | Bin 0 -> 45295 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/openobsecure.png diff --git a/misc/images/openobsecure.png b/misc/images/openobsecure.png new file mode 100644 index 0000000000000000000000000000000000000000..52bbc9707d2eff299bf0c03c5f5a76ab51d3d8dc GIT binary patch literal 45295 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 literal 0 HcmV?d00001 From 15dd9bc0575fd2d930008ab2c607e3e2bf43c01f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 22:00:34 -0400 Subject: [PATCH 4917/6505] Delete openobsecure.svg --- misc/images/openobsecure.svg | Bin 45295 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/openobsecure.svg diff --git a/misc/images/openobsecure.svg b/misc/images/openobsecure.svg deleted file mode 100644 index 52bbc9707d2eff299bf0c03c5f5a76ab51d3d8dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45295 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 From 03836684db36656d2953a485a8ab74e225e208f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 22:06:08 -0400 Subject: [PATCH 4918/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d47c4a7a..1b363e6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-06-18 + +### Changed + +- **OpenObserve LXC** + - NEW Script + ## 2023-06-17 ### Changed From 57531c1d0a46c3d8ff410d258e4dfcfd3ea1e8c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 22:15:31 -0400 Subject: [PATCH 4919/6505] Update openobserve-install.sh tweak --- install/openobserve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh index 487864b4..2e2552a7 100644 --- a/install/openobserve-install.sh +++ b/install/openobserve-install.sh @@ -22,7 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing OpenObserve" mkdir -p /opt/openserve/data LATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -$STD tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve +tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve &>/dev/null cat </opt/openobserve/data/.env ZO_ROOT_USER_EMAIL = "admin@example.com" From cb2d5b20d66cdf49c26b9fec6e0d646d7845a986 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 22:18:10 -0400 Subject: [PATCH 4920/6505] Update openobserve-install.sh spelling --- install/openobserve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh index 2e2552a7..b62e1c07 100644 --- a/install/openobserve-install.sh +++ b/install/openobserve-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing OpenObserve" -mkdir -p /opt/openserve/data +mkdir -p /opt/openobserve/data LATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '"tag_name":' | cut -d'"' -f4) tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve &>/dev/null From 463a5e3698f6c7614df2a04debc43585884b908a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 22:24:00 -0400 Subject: [PATCH 4921/6505] Update openobserve-install.sh start service --- install/openobserve-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh index b62e1c07..8da292bf 100644 --- a/install/openobserve-install.sh +++ b/install/openobserve-install.sh @@ -49,6 +49,7 @@ Restart=on-failure [Install] WantedBy=multi-user.target EOF +systemctl enable -q --now openobserve msg_ok "Created Service" motd_ssh From e924af362f5103d05cdd09f780b2cab3afaf9f7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Jun 2023 23:06:44 -0400 Subject: [PATCH 4922/6505] Update openobserve-install.sh tweak --- install/openobserve-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh index 8da292bf..f00ad8ea 100644 --- a/install/openobserve-install.sh +++ b/install/openobserve-install.sh @@ -36,8 +36,7 @@ msg_info "Creating Service" cat </etc/systemd/system/openobserve.service [Unit] Description=OpenObserve -After=syslog.target network-online.target remote-fs.target nss-lookup.target -Wants=network-online.target +After=network.target [Service] Type=simple From c335d393503551a9e20870edbc2e0108bfa69bfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Jun 2023 18:06:08 -0400 Subject: [PATCH 4923/6505] Update homeassistant-install.sh Debian 12 compatible fixes https://github.com/tteck/Proxmox/issues/1514 --- install/homeassistant-install.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 789ec5ea..40eb9ba3 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -20,8 +20,17 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing runlike" -$STD apt-get install -y python3-pip -$STD pip3 install runlike +$STD apt-get install -y \ +python3 \ +python3-dev \ +python3-pip \ +python3-venv +if [[ "$PCT_OSVERSION" == "12" ]]; then + $STD apt-get install -y pipx + $STD pipx install runlike +else + $STD pip3 install runlike +fi msg_ok "Installed runlike" get_latest_release() { From 46a2b14b09f8fbde6d888c78d019da75805fc48e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Jun 2023 19:16:29 -0400 Subject: [PATCH 4924/6505] Update and rename pve8-install.sh to pve8-upgrade.sh --- misc/{pve8-install.sh => pve8-upgrade.sh} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename misc/{pve8-install.sh => pve8-upgrade.sh} (93%) diff --git a/misc/pve8-install.sh b/misc/pve8-upgrade.sh similarity index 93% rename from misc/pve8-install.sh rename to misc/pve8-upgrade.sh index b9ff380b..c1afc29b 100644 --- a/misc/pve8-install.sh +++ b/misc/pve8-upgrade.sh @@ -8,11 +8,11 @@ header_info() { clear cat <<"EOF" - ____ _ ____________ ____ __ ____ - / __ \ | / / ____( __ ) / _/___ _____/ /_____ _/ / / - / /_/ / | / / __/ / __ | / // __ \/ ___/ __/ __ `/ / / - / ____/| |/ / /___/ /_/ / _/ // / / (__ ) /_/ /_/ / / / -/_/ |___/_____/\____/ /___/_/ /_/____/\__/\__,_/_/_/ + ____ _ ____________ __ ______ __________ ___ ____ ______ + / __ \ | / / ____( __ ) / / / / __ \/ ____/ __ \/ | / __ \/ ____/ + / /_/ / | / / __/ / __ | / / / / /_/ / / __/ /_/ / /| | / / / / __/ + / ____/| |/ / /___/ /_/ / / /_/ / ____/ /_/ / _, _/ ___ |/ /_/ / /___ +/_/ |___/_____/\____/ \____/_/ \____/_/ |_/_/ |_/_____/_____/ EOF } From bbd7ad39f6e6f74b2410725f90bf85aa764d715a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 09:06:25 -0400 Subject: [PATCH 4925/6505] Update esphome-install.sh Debian 12 compatible --- install/esphome-install.sh | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 6f2a8c28..f1997067 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -20,17 +20,25 @@ $STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" +msg_info "Updating Python3" +$STD apt-get install -y \ +python3 \ +python3-dev \ +python3-pip \ +python3-venv +msg_ok "Updated Python3" msg_info "Installing ESPHome" -$STD pip3 install esphome +if [[ "$PCT_OSVERSION" == "12" ]]; then + $STD pip install esphome --break-system-packages + $STD pip install tornado esptool --break-system-packages +else + $STD pip install esphome + $STD pip install tornado esptool +fi msg_ok "Installed ESPHome" -msg_info "Installing ESPHome Dashboard" -$STD pip3 install tornado esptool - +msg_info "Creating Service" service_path="/etc/systemd/system/esphomeDashboard.service" echo "[Unit] Description=ESPHome Dashboard @@ -41,9 +49,8 @@ Restart=always User=root [Install] WantedBy=multi-user.target" >$service_path -$STD systemctl enable esphomeDashboard.service -systemctl start esphomeDashboard -msg_ok "Installed ESPHome Dashboard" +systemctl enable -q --now esphomeDashboard.service +msg_ok "Created Service" motd_ssh customize From ddd5b89be467cbbcdf0a07357537d6272e41dd72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 09:09:09 -0400 Subject: [PATCH 4926/6505] Update homeassistant-install.sh tweak --- install/homeassistant-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 40eb9ba3..7df28ffb 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -26,10 +26,9 @@ python3-dev \ python3-pip \ python3-venv if [[ "$PCT_OSVERSION" == "12" ]]; then - $STD apt-get install -y pipx - $STD pipx install runlike + $STD pip install runlike --break-system-packages else - $STD pip3 install runlike + $STD pip install runlike fi msg_ok "Installed runlike" From 551a9a708cf309d659ed86234ce568760ea77357 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 09:44:48 -0400 Subject: [PATCH 4927/6505] Update homeassistant-install.sh tweak --- install/homeassistant-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 7df28ffb..35c15466 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -19,17 +19,17 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Installing runlike" +msg_info "Updating Python3" $STD apt-get install -y \ python3 \ python3-dev \ python3-pip \ python3-venv -if [[ "$PCT_OSVERSION" == "12" ]]; then - $STD pip install runlike --break-system-packages -else - $STD pip install runlike -fi +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" + +msg_info "Installing runlike" +$STD pip install runlike msg_ok "Installed runlike" get_latest_release() { From 8ff4c713bee283722bafb04a8daf27617b8a4e49 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 09:46:16 -0400 Subject: [PATCH 4928/6505] Update esphome-install.sh tweak --- install/esphome-install.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index f1997067..b7ea34c6 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -26,16 +26,11 @@ python3 \ python3-dev \ python3-pip \ python3-venv +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing ESPHome" -if [[ "$PCT_OSVERSION" == "12" ]]; then - $STD pip install esphome --break-system-packages - $STD pip install tornado esptool --break-system-packages -else - $STD pip install esphome - $STD pip install tornado esptool -fi + $STD pip install esphome tornado esptool msg_ok "Installed ESPHome" msg_info "Creating Service" From b90925f5537d2eef9859f8f83ba858ea710d7c2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 10:02:58 -0400 Subject: [PATCH 4929/6505] Update homeassistant-core-install.sh tweak --- install/homeassistant-core-install.sh | 61 +++++++++++++++------------ 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 85e9393d..e72a47e1 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -13,33 +13,38 @@ setting_up_container network_check update_os - msg_info "Installing Dependencies, (Patience)" - $STD apt-get install -y \ - git \ - curl \ - sudo \ - mc \ - python3 \ - python3-dev \ - python3-venv \ - python3-pip \ - bluez \ - libffi-dev \ - libssl-dev \ - libjpeg-dev \ - zlib1g-dev \ - autoconf \ - build-essential \ - libopenjp2-7 \ - libturbojpeg0-dev \ - ffmpeg \ - liblapack3 \ - liblapack-dev \ - dbus-broker \ - libpcap-dev \ - libmariadb-dev-compat \ - libatlas-base-dev - msg_ok "Installed Dependencies" +msg_info "Installing Dependencies, (Patience)" +$STD apt-get install -y \ + git \ + curl \ + sudo \ + mc \ + bluez \ + libffi-dev \ + libssl-dev \ + libjpeg-dev \ + zlib1g-dev \ + autoconf \ + build-essential \ + libopenjp2-7 \ + libturbojpeg0-dev \ + ffmpeg \ + liblapack3 \ + liblapack-dev \ + dbus-broker \ + libpcap-dev \ + libmariadb-dev-compat \ + libatlas-base-dev +msg_ok "Installed Dependencies" + +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip \ + python3-venv +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" if [[ "$PCT_OSVERSION" == "11" ]]; then msg_info "Installing pyenv" @@ -63,7 +68,7 @@ if [[ "$PCT_OSVERSION" == "11" ]]; then echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >>~/.bashrc msg_ok "Installed pyenv" . ~/.bashrc - + set -e msg_info "Installing Python 3.11.3 (Patience)" $STD pyenv install 3.11.3 From c853c24a96a68ae6a59e703d26b9c392333565dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 10:07:02 -0400 Subject: [PATCH 4930/6505] Update homeassistant-install.sh shfmt --- install/homeassistant-install.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 35c15466..0d341e9e 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -21,10 +21,10 @@ msg_ok "Installed Dependencies" msg_info "Updating Python3" $STD apt-get install -y \ -python3 \ -python3-dev \ -python3-pip \ -python3-venv + python3 \ + python3-dev \ + python3-pip \ + python3-venv rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" @@ -44,14 +44,14 @@ msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json + VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + cd /usr/local/bin + curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 + chmod 755 /usr/local/bin/fuse-overlayfs + cd ~ + echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' >/etc/docker/daemon.json else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json + echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json fi $STD sh <(curl -sSL https://get.docker.com) msg_ok "Installed Docker $DOCKER_LATEST_VERSION" @@ -88,7 +88,7 @@ $STD docker run -d \ -v /etc/localtime:/etc/localtime:ro \ --net=host \ homeassistant/home-assistant:stable - mkdir /root/hass_config +mkdir /root/hass_config msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" motd_ssh From 68e3b934ab5e1cc46a2e9117576208493b70f711 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 10:12:16 -0400 Subject: [PATCH 4931/6505] Update esphome-install.sh shfmt --- install/esphome-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index b7ea34c6..c9a67ba4 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -22,15 +22,15 @@ msg_ok "Installed Dependencies" msg_info "Updating Python3" $STD apt-get install -y \ -python3 \ -python3-dev \ -python3-pip \ -python3-venv + python3 \ + python3-dev \ + python3-pip \ + python3-venv rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing ESPHome" - $STD pip install esphome tornado esptool +$STD pip install esphome tornado esptool msg_ok "Installed ESPHome" msg_info "Creating Service" From 5bf0944dd986919908736ef780b8bfead8c01b2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 10:36:49 -0400 Subject: [PATCH 4932/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index ab1e760e..187c6a94 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -30,19 +30,20 @@ $STD apt-get -y install \ git msg_ok "Installed Dependencies" -msg_info "Installing Python" +msg_info "Updating Python" $STD apt-get install -y \ -python3 \ -python3-dev \ -python3-pip \ -python3-venv \ -python3-cffi \ -python3-certbot \ -python3-certbot-dns-cloudflare + python3 \ + python3-dev \ + python3-pip \ + python3-venv \ + python3-cffi \ + python3-certbot \ + python3-certbot-dns-cloudflare +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED $STD python3 -m venv /opt/certbot/ -msg_ok "Installed Python" +msg_ok "Updated Python" -VERSION="$( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release )" +VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" msg_info "Installing Openresty" wget -qO - https://openresty.org/package/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg From bfd51941185dc965652e3b58280e8a1e0d866b7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 15:54:38 -0400 Subject: [PATCH 4933/6505] Update microcode.sh PVE8 compatible --- misc/microcode.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 5d799b81..c31d88d9 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -86,13 +86,11 @@ amd() { echo -e "\n To apply the changes, the system will need to be rebooted.\n" } -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} Proxmox Virtual Environment Not Detected" - echo -e "Exiting..." - sleep 2 +if ! command -v pveversion >/dev/null 2>&1; then + header_info + msg_error "\n No PVE Detected!\n" exit fi - msg_info "Checking CPU Vendor" cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') if [ "$cpu" == "GenuineIntel" ]; then From 7eba5494eaadec7fecf7e1c73d0643fc0411aff4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 16:08:58 -0400 Subject: [PATCH 4934/6505] Update microcode.sh tweak --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index c31d88d9..9c399dbc 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -92,7 +92,7 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi msg_info "Checking CPU Vendor" -cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+') +cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+' | head -n 1) if [ "$cpu" == "GenuineIntel" ]; then msg_ok "${cpu} was detected" intel From 4fc26a08d8bdb23e65b433bcbf2e31b19cd7a4d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 19:37:22 -0400 Subject: [PATCH 4935/6505] Update pve8-upgrade.sh work with 7.4-14 --- misc/pve8-upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index c1afc29b..e7a1625d 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -179,7 +179,7 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if [ $(pveversion | grep "pve-manager/7.4-13" | wc -l) -ne 1 ]; then +if [ $(pveversion | grep -E "pve-manager/(7.4-13|7.4-14)" | wc -l) -ne 1 ]; then header_info msg_error "This version of Proxmox Virtual Environment is not supported" echo -e " Requires PVE Version: 7.4-13" From 64ace368f1f4ebec7f7514cb3934c78ae1d716da Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 19:49:43 -0400 Subject: [PATCH 4936/6505] Update pve8-upgrade.sh tweak --- misc/pve8-upgrade.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index e7a1625d..eee49f87 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -179,10 +179,10 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if [ $(pveversion | grep -E "pve-manager/(7.4-13|7.4-14)" | wc -l) -ne 1 ]; then +if [ $(pveversion | grep -E "pve-manager/(7.4-13|7.4-14|7.4-15)" | wc -l) -ne 1 ]; then header_info msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e " Requires PVE Version: 7.4-13" + echo -e " PVE Version 7.4-13 or higher is required." echo -e "\nExiting..." sleep 3 exit From ef46c15f670b31e985e63506435fbaac928f2df8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 20:01:43 -0400 Subject: [PATCH 4937/6505] Update pve8-upgrade.sh remove -E option --- misc/pve8-upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index eee49f87..db15e016 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -179,7 +179,7 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if [ $(pveversion | grep -E "pve-manager/(7.4-13|7.4-14|7.4-15)" | wc -l) -ne 1 ]; then +if [ $(pveversion | grep "pve-manager/(7.4-13|7.4-14|7.4-15)" | wc -l) -ne 1 ]; then header_info msg_error "This version of Proxmox Virtual Environment is not supported" echo -e " PVE Version 7.4-13 or higher is required." From 6cb81290303a4ebfd6c501705037fc438dd14656 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Jun 2023 20:10:25 -0400 Subject: [PATCH 4938/6505] Update pve8-upgrade.sh fix version check --- misc/pve8-upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index db15e016..9e26ec02 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -179,7 +179,7 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if [ $(pveversion | grep "pve-manager/(7.4-13|7.4-14|7.4-15)" | wc -l) -ne 1 ]; then +if [[ $(pveversion | grep -E "pve-manager/(7.4-13|7.4-14|7.4-15)") ]]; then header_info msg_error "This version of Proxmox Virtual Environment is not supported" echo -e " PVE Version 7.4-13 or higher is required." From a6f8036cf66b7c046c5d8204f8641a30d00721c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Jun 2023 05:15:42 -0400 Subject: [PATCH 4939/6505] Update pve8-upgrade.sh remove pveversion check --- misc/pve8-upgrade.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index 9e26ec02..eaf41ca5 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -179,13 +179,4 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if [[ $(pveversion | grep -E "pve-manager/(7.4-13|7.4-14|7.4-15)") ]]; then - header_info - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e " PVE Version 7.4-13 or higher is required." - echo -e "\nExiting..." - sleep 3 - exit -fi - start_routines From 63dd46bb2d3e666722002cd2a9a2074019f49559 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Jun 2023 06:18:13 -0400 Subject: [PATCH 4940/6505] Update nginxproxymanager-install.sh set node version --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 187c6a94..89eada70 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -55,7 +55,7 @@ msg_ok "Installed Openresty" msg_info "Installing Node.js" $STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh) . ~/.bashrc -$STD nvm install 16 +$STD nvm install 16.20.0 ln -sf /root/.nvm/versions/node/v16.20.0/bin/node /usr/bin/node msg_ok "Installed Node.js" From d8b78777752f8727bc64b0f256b62633934741fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Jun 2023 10:02:07 -0400 Subject: [PATCH 4941/6505] Update sabnzbd-install.sh Debian 12 compatible --- install/sabnzbd-install.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 6c53de93..f70c23a5 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -24,10 +24,14 @@ $STD dpkg -i unrar_6.0.3-1+deb11u1_amd64.deb rm unrar_6.0.3-1+deb11u1_amd64.deb msg_ok "Installed Dependencies" -msg_info "Installing Python3-pip" +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED $STD apt-get install -y python3-setuptools -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" +msg_ok "Updated Python3" msg_info "Installing SABnzbd" RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From 1e1a69e3f11416d0146004fa9b494b39cb9d144b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Jun 2023 10:43:49 -0400 Subject: [PATCH 4942/6505] Code refactoring --- install/bazarr-install.sh | 9 ++++++++- install/changedetection-install.sh | 6 ++++-- install/deluge-install.sh | 10 +++++++--- install/motioneye-install.sh | 16 ++++++++++------ install/octoprint-install.sh | 16 +++++++++------- install/scrypted-install.sh | 15 ++++++++++----- install/tautulli-install.sh | 8 ++++++++ install/whoogle-install.sh | 10 +++++++--- 8 files changed, 63 insertions(+), 27 deletions(-) diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh index 9e847172..1b8beeea 100755 --- a/install/bazarr-install.sh +++ b/install/bazarr-install.sh @@ -17,9 +17,16 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y python3-pip msg_ok "Installed Dependencies" +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" + msg_info "Installing Bazarr" mkdir -p /var/lib/bazarr/ wget -q https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index e1673b15..42d79ba5 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -43,11 +43,13 @@ $STD apt-get install -y \ xvfb msg_ok "Installed Dependencies" -msg_info "Installing Python3" +msg_info "Updating Python3" $STD apt-get install -y \ + python3 \ python3-dev \ python3-pip -msg_ok "Installed Python3" +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" $STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) diff --git a/install/deluge-install.sh b/install/deluge-install.sh index b42e24f6..5dda4f3c 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -19,9 +19,13 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" msg_info "Installing Deluge" $STD pip install deluge[all] diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index 5ebe8fc7..f7364e65 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -21,6 +21,14 @@ $STD apt-get install -y git $STD apt-get install -y cifs-utils msg_ok "Installed Dependencies" +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" + msg_info "Installing Motion" $STD apt-get install -y motion systemctl stop motion @@ -31,22 +39,18 @@ msg_info "Installing FFmpeg" $STD apt-get install -y ffmpeg v4l-utils msg_ok "Installed FFmpeg" -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" - msg_info "Installing MotionEye" $STD apt-get update $STD pip install git+https://github.com/motioneye-project/motioneye.git@dev mkdir -p /etc/motioneye chown -R root:root /etc/motioneye chmod -R 777 /etc/motioneye -cp /usr/local/lib/python3.9/dist-packages/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf +wget -qO /etc/motioneye/motioneye.conf https://raw.githubusercontent.com/motioneye-project/motioneye/dev/motioneye/extra/motioneye.conf.sample mkdir -p /var/lib/motioneye msg_ok "Installed MotionEye" msg_info "Creating Service" -cp /usr/local/lib/python3.9/dist-packages/motioneye/extra/motioneye.systemd /etc/systemd/system/motioneye.service +wget -qO /etc/systemd/system/motioneye.service https://raw.githubusercontent.com/motioneye-project/motioneye/dev/motioneye/extra/motioneye.systemd systemctl enable -q --now motioneye msg_ok "Created Service" diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh index 132eedd1..f6db1393 100644 --- a/install/octoprint-install.sh +++ b/install/octoprint-install.sh @@ -21,14 +21,16 @@ $STD apt-get install -y git $STD apt-get install -y libyaml-dev $STD apt-get install -y build-essential msg_ok "Installed Dependencies" - -msg_info "Installing Python3" + +msg_info "Updating Python3" $STD apt-get install -y \ - python3-pip \ - python3-dev \ - python3-setuptools \ - python3-venv -msg_ok "Installed Python3" + python3 \ + python3-dev \ + python3-pip \ + python3-venv +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +$STD apt-get install -y python3-setuptools +msg_ok "Updated Python3" msg_info "Creating user octoprint" useradd -m -s /bin/bash -p $(openssl passwd -1 octoprint) octoprint diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index b1df07e1..e0015615 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -58,23 +58,28 @@ msg_info "Installing Node.js" $STD apt-get install -y nodejs msg_ok "Installed Node.js" -msg_info "Installing Python3" +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" + +msg_info "Installing Python3 Dependencies" $STD apt-get -y install \ - python3 \ - python3-dev \ python3-gi \ python3-gst-1.0 \ python3-matplotlib \ python3-numpy \ python3-opencv \ python3-pil \ - python3-pip \ python3-setuptools \ python3-skimage \ python3-wheel $STD python3 -m pip install --upgrade pip $STD python3 -m pip install aiofiles debugpy typing_extensions typing -msg_ok "Installed Python3" +msg_ok "Installed Python3 Dependencies" read -r -p "Would you like to add Coral Edge TPU support? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index 502e4536..f0eb77b3 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -21,6 +21,14 @@ $STD apt-get install -y git $STD apt-get install -y pip msg_ok "Installed Dependencies" +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" + msg_info "Installing Tautulli" cd /opt $STD git clone https://github.com/Tautulli/Tautulli.git diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index 1eb492f2..1381f662 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -19,9 +19,13 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Installing Python3-pip" -$STD apt-get install -y python3-pip -msg_ok "Installed Python3-pip" +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Updated Python3" msg_info "Installing Whoogle" $STD pip install brotli From 4c8a31f48547ccea08dee58675fd91b83092c096 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Jun 2023 10:37:22 -0400 Subject: [PATCH 4943/6505] Update pve8-upgrade.sh out of beta --- misc/pve8-upgrade.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index eaf41ca5..7442c799 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -89,7 +89,7 @@ EOF yes) msg_info "Enabling 'pve-no-subscription' repository" cat </etc/apt/sources.list.d/pve-install-repo.list -# deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription +deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" ;; @@ -122,7 +122,7 @@ EOF yes) msg_info "Adding 'pvetest' repository and set disabled" cat </etc/apt/sources.list.d/pvetest-for-beta.list -deb http://download.proxmox.com/debian/pve bookworm pvetest +# deb http://download.proxmox.com/debian/pve bookworm pvetest EOF msg_ok "Added 'pvetest' repository" ;; From f1319f44fe7c603e9a8938911d3eaf58899386dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Jun 2023 15:55:39 -0400 Subject: [PATCH 4944/6505] Update openwrt.sh add pve 8 fixes https://github.com/tteck/Proxmox/issues/1528 --- vm/openwrt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index e3eee268..3b9952af 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -157,7 +157,7 @@ function msg_error() { } function pve_check() { - if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 7.2 or higher" echo -e "Exiting..." From 3624b67302001f29d7284e7ee9cd87412caf4134 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Jun 2023 16:32:58 -0400 Subject: [PATCH 4945/6505] Update pve8-upgrade.sh add check for PVE Version 7.4-13 or higher --- misc/pve8-upgrade.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index 7442c799..cca0f041 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -179,4 +179,13 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi +if ! pveversion | grep -Eq "pve-manager/(7\.4-(13|14|15|16))"; then + header_info + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e " PVE Version 7.4-13 or higher is required." + echo -e "\nExiting..." + sleep 3 + exit +fi + start_routines From c2738aa83fac36b2cf777bb5f2e8fefc6de7a033 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 07:23:20 -0400 Subject: [PATCH 4946/6505] Update omv-install.sh apt-key - Deprecated --- install/omv-install.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/install/omv-install.sh b/install/omv-install.sh index 90911799..872e9c28 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -21,10 +21,9 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Installing OpenMediaVault (Patience)" -wget -q -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key -$STD apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" &>/dev/null +wget -qO- https://packages.openmediavault.org/public/archive.key | gpg --dearmor >"/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.gpg" -cat <>/etc/apt/sources.list.d/openmediavault.list +cat </etc/apt/sources.list.d/openmediavault.list deb https://packages.openmediavault.org/public shaitan main # deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main ## Uncomment the following line to add software from the proposed repository. @@ -35,9 +34,12 @@ deb https://packages.openmediavault.org/public shaitan main # deb https://packages.openmediavault.org/public shaitan partner # deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner EOF + +export LANG=C.UTF-8 +export DEBIAN_FRONTEND=noninteractive +export APT_LISTCHANGES_FRONTEND=none $STD apt-get update -apt-get -y install openmediavault-keyring &>/dev/null -DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy openmediavault &>/dev/null +apt-get -y --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends --option DPkg::Options::="--force-confdef" --option DPkg::Options::="--force-confold" install openmediavault-keyring openmediavault &>/dev/null omv-confdbadm populate msg_ok "Installed OpenMediaVault" From 63ed687b2c46cc359672f76f406e29067226a1c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 07:43:40 -0400 Subject: [PATCH 4947/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index a08acd7b..af7843ed 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -19,3 +19,5 @@ [How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/) [Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html) + +[Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/) From 22b77fdb768c30e15ac6722e737ea722df9a342d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 13:12:18 -0400 Subject: [PATCH 4948/6505] Update esphome.sh update the installation of either standard or venv --- ct/esphome.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index d7d4f753..f858d198 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -52,13 +52,16 @@ function default_settings() { function update_script() { header_info -if [[ ! -f /usr/local/bin/esphome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -f /etc/systemd/system/esphomeDashboard.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Stopping ESPHome" systemctl stop esphomeDashboard msg_ok "Stopped ESPHome" msg_info "Updating ESPHome" -pip3 install esphome --upgrade &>/dev/null +if [[ -d /srv/esphome ]]; then + source /srv/esphome/bin/activate &>/dev/null +fi +pip3 install -U esphome &>/dev/null msg_ok "Updated ESPHome" msg_info "Starting ESPHome" From 46518271512ba46236a20ad666214a5f7136ba07 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 13:17:03 -0400 Subject: [PATCH 4949/6505] Update esphome-install.sh install esphome in a python virtual environment --- install/esphome-install.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index c9a67ba4..5b6cb0b7 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -30,20 +30,27 @@ rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing ESPHome" +mkdir /srv/esphome +cd /srv/esphome +python3 -m venv . +source bin/activate $STD pip install esphome tornado esptool msg_ok "Installed ESPHome" msg_info "Creating Service" -service_path="/etc/systemd/system/esphomeDashboard.service" -echo "[Unit] +cat </etc/systemd/system/esphomeDashboard.service +[Unit] Description=ESPHome Dashboard After=network.target + [Service] -ExecStart=/usr/local/bin/esphome dashboard /root/config/ +ExecStart=/srv/esphome/bin/esphome dashboard /root/config/ Restart=always User=root + [Install] -WantedBy=multi-user.target" >$service_path +WantedBy=multi-user.target +EOF systemctl enable -q --now esphomeDashboard.service msg_ok "Created Service" From dfb79fbc4efa3ea109c843edcabbf061cd5fe449 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 13:20:55 -0400 Subject: [PATCH 4950/6505] Update esphome.sh default Debian 12 --- ct/esphome.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index f858d198..a752b0d3 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 53e5964633f4460870457d8ed005fe089c7447ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 13:34:16 -0400 Subject: [PATCH 4951/6505] Update changedetection-install.sh add libasound2 fixes https://github.com/tteck/Proxmox/issues/1535 --- install/changedetection-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 42d79ba5..a23a0fca 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y \ dumb-init \ gconf-service \ libatk-bridge2.0-0 \ + libasound2 \ libatk1.0-0 \ libcairo2 \ libcups2 \ From 697b40960036ee39075296a6e0c979f9647732ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 21:33:35 -0400 Subject: [PATCH 4952/6505] Update esphome-install.sh revert to standard install --- install/esphome-install.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 5b6cb0b7..67e0e137 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -30,10 +30,10 @@ rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing ESPHome" -mkdir /srv/esphome -cd /srv/esphome -python3 -m venv . -source bin/activate +#mkdir /srv/esphome +#cd /srv/esphome +#python3 -m venv . +#source bin/activate $STD pip install esphome tornado esptool msg_ok "Installed ESPHome" @@ -44,7 +44,8 @@ Description=ESPHome Dashboard After=network.target [Service] -ExecStart=/srv/esphome/bin/esphome dashboard /root/config/ +#ExecStart=/srv/esphome/bin/esphome dashboard /root/config/ +ExecStart=/usr/local/bin/esphome dashboard /root/config/ Restart=always User=root From 01975a17a2b83230d3f03dd0743b0100597dc9ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Jun 2023 21:34:16 -0400 Subject: [PATCH 4953/6505] Update esphome.sh revert to Debian 11 --- ct/esphome.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index a752b0d3..f858d198 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="12" +var_version="11" variables color catch_errors From 5cad663da23f647ce397bc0423324614960a93d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Jun 2023 09:05:06 -0400 Subject: [PATCH 4954/6505] Update pve8-upgrade.sh tweak --- misc/pve8-upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index cca0f041..a65cb302 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -115,7 +115,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PVE8 TEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd 'pvetest' repository?" 14 58 2 \ + CHOICE=$(whiptail --title "PVE8 TEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From 7c6e700eafbcf8643668afd0fafd605bd88b47ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Jun 2023 13:56:53 -0400 Subject: [PATCH 4955/6505] Update USER_SUBMITTED_GUIDES.md How-to: Proxmox VE 7.4 to 8.0 Upgrade --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index af7843ed..ab1eed2e 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -21,3 +21,5 @@ [Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html) [Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/) + +[How-to: Proxmox VE 7.4 to 8.0 Upgrade](https://www.derekseaman.com/2023/06/how-to-proxmox-7-4-to-8-0-upgrade.html) From 4e6c68f164df284a9789b4eb8f0f118ad994df6f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Jun 2023 16:39:55 -0400 Subject: [PATCH 4956/6505] Update adguard-install.sh Code refactoring --- install/adguard-install.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/install/adguard-install.sh b/install/adguard-install.sh index 124f2e68..eb262cf0 100644 --- a/install/adguard-install.sh +++ b/install/adguard-install.sh @@ -20,12 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" -systemctl stop systemd-resolved -echo "DNSStubListener=no" >>/etc/systemd/resolved.conf -ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -wget -qL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh -$STD bash install.sh -rm install.sh +$STD bash <(curl -fsSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh) msg_ok "Installed AdGuard Home" motd_ssh From 7450250f03108745ed888857c1839b31b36cd225 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Jun 2023 16:40:59 -0400 Subject: [PATCH 4957/6505] Update adguard.sh default Debian 12 fixes https://github.com/tteck/Proxmox/issues/1538 --- ct/adguard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index a0cab6e7..807800c3 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -24,7 +24,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 606634b25a95a0ae42ddd9172790863acd77f1cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Jun 2023 16:44:10 -0400 Subject: [PATCH 4958/6505] Update homeassistant-core.sh default Debian 12 --- ct/homeassistant-core.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 8f612cb5..48065814 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From f0a8502c96a2f11d024d011e5ec271b0b7c80860 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 00:00:32 -0400 Subject: [PATCH 4959/6505] Update install.func tweak --- misc/install.func | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/misc/install.func b/misc/install.func index 34b3d07d..4d044af3 100644 --- a/misc/install.func +++ b/misc/install.func @@ -83,6 +83,7 @@ setting_up_container() { echo -e " 🖧 Check Network Settings" exit 1 fi + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" } @@ -132,16 +133,16 @@ motd_ssh() { # This function customizes the container by modifying the getty service and enabling auto-login for the root user customize() { if [[ "$PASSWORD" == "" ]]; then - msg_info "Customizing Container" - GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" - mkdir -p $(dirname $GETTY_OVERRIDE) - cat <$GETTY_OVERRIDE + msg_info "Customizing Container" + GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" + mkdir -p $(dirname $GETTY_OVERRIDE) + cat <$GETTY_OVERRIDE [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM EOF - systemctl daemon-reload - systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') - msg_ok "Customized Container" + systemctl daemon-reload + systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') + msg_ok "Customized Container" fi } From 5ceda0657550f954b6b67c84e9c047373cad0164 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 00:13:23 -0400 Subject: [PATCH 4960/6505] Code refactoring --- install/bazarr-install.sh | 2 +- install/changedetection-install.sh | 2 +- install/deluge-install.sh | 2 +- install/esphome-install.sh | 2 +- install/homeassistant-core-install.sh | 2 +- install/homeassistant-install.sh | 2 +- install/motioneye-install.sh | 2 +- install/nginxproxymanager-install.sh | 2 +- install/octoprint-install.sh | 2 +- install/sabnzbd-install.sh | 2 +- install/scrypted-install.sh | 2 +- install/tautulli-install.sh | 2 +- install/whoogle-install.sh | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh index 1b8beeea..b5d3f921 100755 --- a/install/bazarr-install.sh +++ b/install/bazarr-install.sh @@ -24,7 +24,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing Bazarr" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index a23a0fca..46a70f05 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -49,7 +49,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" diff --git a/install/deluge-install.sh b/install/deluge-install.sh index 5dda4f3c..1aac5a84 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -24,7 +24,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing Deluge" diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 67e0e137..7dbbbc18 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -26,7 +26,7 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing ESPHome" diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index e72a47e1..cbb10ed5 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -43,7 +43,7 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" if [[ "$PCT_OSVERSION" == "11" ]]; then diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 0d341e9e..309f6bd3 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -25,7 +25,7 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing runlike" diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index f7364e65..fe3e5d23 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -26,7 +26,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing Motion" diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 89eada70..6a13f95f 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -39,7 +39,7 @@ $STD apt-get install -y \ python3-cffi \ python3-certbot \ python3-certbot-dns-cloudflare -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + $STD python3 -m venv /opt/certbot/ msg_ok "Updated Python" diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh index f6db1393..3121387c 100644 --- a/install/octoprint-install.sh +++ b/install/octoprint-install.sh @@ -28,7 +28,7 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + $STD apt-get install -y python3-setuptools msg_ok "Updated Python3" diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index f70c23a5..5cf49ea7 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -29,7 +29,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + $STD apt-get install -y python3-setuptools msg_ok "Updated Python3" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index e0015615..0c39a396 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -63,7 +63,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing Python3 Dependencies" diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index f0eb77b3..8674c1da 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -26,7 +26,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing Tautulli" diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index 1381f662..24455125 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -24,7 +24,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + msg_ok "Updated Python3" msg_info "Installing Whoogle" From e9c7ec22e58d0df9ab7901ed659719064803bb62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 00:18:40 -0400 Subject: [PATCH 4961/6505] Update sabnzbd.sh default Debian 12 --- ct/sabnzbd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index 1b198e99..be10fb72 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From c72b91a4ad274a94a6263eae79c4808ececf36f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 00:23:30 -0400 Subject: [PATCH 4962/6505] tweak --- install/bazarr-install.sh | 1 - install/changedetection-install.sh | 1 - install/deluge-install.sh | 1 - install/motioneye-install.sh | 1 - install/sabnzbd-install.sh | 1 - install/scrypted-install.sh | 1 - install/tautulli-install.sh | 1 - install/whoogle-install.sh | 1 - 8 files changed, 8 deletions(-) diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh index b5d3f921..a8f07da9 100755 --- a/install/bazarr-install.sh +++ b/install/bazarr-install.sh @@ -24,7 +24,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - msg_ok "Updated Python3" msg_info "Installing Bazarr" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 46a70f05..7bae8084 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -49,7 +49,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" diff --git a/install/deluge-install.sh b/install/deluge-install.sh index 1aac5a84..1fde3caa 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -24,7 +24,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - msg_ok "Updated Python3" msg_info "Installing Deluge" diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index fe3e5d23..227cffd0 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -26,7 +26,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - msg_ok "Updated Python3" msg_info "Installing Motion" diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 5cf49ea7..6c97bd07 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -29,7 +29,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - $STD apt-get install -y python3-setuptools msg_ok "Updated Python3" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 0c39a396..78a4638d 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -63,7 +63,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - msg_ok "Updated Python3" msg_info "Installing Python3 Dependencies" diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index 8674c1da..da91ab84 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -26,7 +26,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - msg_ok "Updated Python3" msg_info "Installing Tautulli" diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index 24455125..e513288d 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -24,7 +24,6 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip - msg_ok "Updated Python3" msg_info "Installing Whoogle" From ad8d7fce242d520f8a85765bb07ad4fc858b6692 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 00:31:16 -0400 Subject: [PATCH 4963/6505] Update install.func tweak --- misc/install.func | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/misc/install.func b/misc/install.func index 4d044af3..11fc647c 100644 --- a/misc/install.func +++ b/misc/install.func @@ -84,6 +84,7 @@ setting_up_container() { exit 1 fi rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + $STD systemctl disable systemd-networkd-wait-online.service msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" } @@ -125,9 +126,6 @@ motd_ssh() { sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config systemctl restart sshd fi - if [[ "$PCT_OSVERSION" == "12" ]]; then - $STD systemctl disable systemd-networkd-wait-online.service - fi } # This function customizes the container by modifying the getty service and enabling auto-login for the root user From 2caee65b10ddd0f0f7fae4818738d04d2029313d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 00:44:22 -0400 Subject: [PATCH 4964/6505] Update install.func tweak --- misc/install.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/install.func b/misc/install.func index 11fc647c..9841ca1e 100644 --- a/misc/install.func +++ b/misc/install.func @@ -84,6 +84,7 @@ setting_up_container() { exit 1 fi rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + systemctl stop systemd-networkd-wait-online.service $STD systemctl disable systemd-networkd-wait-online.service msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" From 4d50c275524679a993fca90dc4589c078829c2dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 00:45:40 -0400 Subject: [PATCH 4965/6505] Update debian.sh default Debian 12 --- ct/debian.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/debian.sh b/ct/debian.sh index ee23d6c5..f684369d 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors @@ -64,4 +64,4 @@ start build_container description -msg_ok "Completed Successfully!\n" \ No newline at end of file +msg_ok "Completed Successfully!\n" From 87f537981194eb8acbbd169b68df934ee8ca07e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 01:19:56 -0400 Subject: [PATCH 4966/6505] Update esphome.sh default Debian 12 --- ct/esphome.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/esphome.sh b/ct/esphome.sh index f858d198..a752b0d3 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From e5d5c86c76be5a98554e7c530fa47f8739a26dab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 01:25:34 -0400 Subject: [PATCH 4967/6505] Update docker.sh default Debian 12 --- ct/docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/docker.sh b/ct/docker.sh index ecbc4892..db176aec 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 0b76e1fadc64f19a14ebe81482de23d9644fc4d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 04:37:39 -0400 Subject: [PATCH 4968/6505] Update homeassistant.sh default Debian 12 --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 3a67b1fc..759eca18 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -23,7 +23,7 @@ var_disk="16" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 0b4104441d0984922fa49f67a5c8c438a488eb70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 04:39:11 -0400 Subject: [PATCH 4969/6505] Update homeassistant-install.sh tweak --- install/homeassistant-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 309f6bd3..715f8a4f 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -25,7 +25,6 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv - msg_ok "Updated Python3" msg_info "Installing runlike" From 92eb05c8364fa8949dc9cabfcff954d60f3162a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 13:06:10 -0400 Subject: [PATCH 4970/6505] Update nginxproxymanager.sh default Debian 12 --- ct/nginxproxymanager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 72bffcac..5a5dd685 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 049806d703d94c13f2e08d871f17269023ca96a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 13:15:05 -0400 Subject: [PATCH 4971/6505] Update mqtt.sh default Debian 12 --- ct/mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index f4f0bed7..79273287 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From d6d1b86ad19bba595a631d515125da43b319ab1c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 13:18:05 -0400 Subject: [PATCH 4972/6505] Update unifi.sh default Debian 12 --- ct/unifi.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/unifi.sh b/ct/unifi.sh index c44b0182..5f20a0ed 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 1e8add89e2f84614e4d33d5cd238c0310007cebc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 13:23:26 -0400 Subject: [PATCH 4973/6505] Update omada.sh default Debian 12 --- ct/omada.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omada.sh b/ct/omada.sh index a5df6f9b..f8d485aa 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From b733b451d83c91ca8be58d16ea2a476941f03159 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 18:11:35 -0400 Subject: [PATCH 4974/6505] Update postgresql-install.sh distribution agnostic --- install/postgresql-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/install/postgresql-install.sh b/install/postgresql-install.sh index 5f455031..309b2d50 100644 --- a/install/postgresql-install.sh +++ b/install/postgresql-install.sh @@ -21,8 +21,9 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up PostgreSQL Repository" -sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main" > /etc/apt/sources.list.d/pgdg.list' -$STD apt-key add <(curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc) +VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" +echo "deb http://apt.postgresql.org/pub/repos/apt ${VERSION}-pgdg main" >/etc/apt/sources.list.d/pgdg.list +curl -sSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor --output /etc/apt/trusted.gpg.d/postgresql.gpg msg_ok "Setup PostgreSQL Repository" msg_info "Installing PostgreSQL" @@ -136,8 +137,8 @@ read -r -p "Would you like to add Adminer? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Adminer" $STD apt install -y adminer - $STD sudo a2enconf adminer - $STD systemctl reload apache2 + $STD a2enconf adminer + systemctl reload apache2 msg_ok "Installed Adminer" fi From 45c2641a36f969524ea28ca9781288a025f83658 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 25 Jun 2023 18:12:49 -0400 Subject: [PATCH 4975/6505] Update postgresql.sh default Debian 12 fixes https://github.com/tteck/Proxmox/issues/1542 --- ct/postgresql.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 06212e1a..b3b9106e 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From c06b861971b96fa4de2e5c965b6561e3970e956f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Jun 2023 05:05:51 -0400 Subject: [PATCH 4976/6505] Update nginxproxymanager-install.sh nvm v0.39.3 node v16.20.1 --- install/nginxproxymanager-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 6a13f95f..e9ee8df0 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -53,10 +53,10 @@ $STD apt-get -y install openresty msg_ok "Installed Openresty" msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh) +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) . ~/.bashrc -$STD nvm install 16.20.0 -ln -sf /root/.nvm/versions/node/v16.20.0/bin/node /usr/bin/node +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Yarn" From 0101449dda7cb46c2f936a96798980f3e99d9b24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Jun 2023 13:11:20 -0400 Subject: [PATCH 4977/6505] Code refactoring --- install/cronicle-install.sh | 9 ++++----- install/magicmirror-install.sh | 9 ++++----- install/meshcentral-install.sh | 9 ++++----- install/n8n-install.sh | 9 ++++----- install/wikijs-install.sh | 9 ++++----- 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/install/cronicle-install.sh b/install/cronicle-install.sh index 9f9073c3..a38bcf06 100644 --- a/install/cronicle-install.sh +++ b/install/cronicle-install.sh @@ -23,12 +23,11 @@ $STD apt-get install -y g++ $STD apt-get install -y gcc msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Cronicle Primary Server" diff --git a/install/magicmirror-install.sh b/install/magicmirror-install.sh index f262b885..52d480b0 100644 --- a/install/magicmirror-install.sh +++ b/install/magicmirror-install.sh @@ -20,12 +20,11 @@ $STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Setting up MagicMirror Repository" diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh index bd76b239..ec191bdc 100644 --- a/install/meshcentral-install.sh +++ b/install/meshcentral-install.sh @@ -19,12 +19,11 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing MeshCentral" diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 0c2c1cd2..95a86e73 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -19,12 +19,11 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing n8n (Patience)" diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index 32152da6..f6a93f50 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -20,12 +20,11 @@ $STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Wiki.js" From eea2d7e9ac2d8e2a2e6dae31d5776c4437a0ae83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Jun 2023 13:19:53 -0400 Subject: [PATCH 4978/6505] Code refactoring --- install/dashy-install.sh | 12 +++++++----- install/homepage-install.sh | 9 ++++----- install/nocodb-install.sh | 12 +++++++----- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 6bb812f7..50078550 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -18,14 +18,16 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs git make g++ gcc +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Yarn" diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 3f5c85d9..129195e4 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -20,12 +20,11 @@ $STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node $STD npm install -g pnpm msg_ok "Installed Node.js" diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh index 8435fc06..23713d69 100644 --- a/install/nocodb-install.sh +++ b/install/nocodb-install.sh @@ -18,14 +18,16 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - msg_info "Installing Node.js" -$STD sudo apt-get install -y nodejs git make g++ gcc +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing NocoDB" From fcfd9a77c8259de2b88d95ee69e464c1f7625e2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Jun 2023 10:29:50 -0400 Subject: [PATCH 4979/6505] Update node-red.sh default Debian 12 --- ct/node-red.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index 0555b6b4..f95388a1 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From b6cba4f64216980bfd2da7707360482e98d58c89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 06:07:29 -0400 Subject: [PATCH 4980/6505] Update pihole.sh default Debian 12 --- ct/pihole.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pihole.sh b/ct/pihole.sh index b6ba11a6..9417013d 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 2f798b24f2a3c33138e340c56bf2498d5867cc87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 06:08:12 -0400 Subject: [PATCH 4981/6505] Update grocy.sh default Debian 12 --- ct/grocy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/grocy.sh b/ct/grocy.sh index cfe213d5..020971cb 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 7525666f6bfd7467fbc4eb4ddb4bbd6d12985e6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 09:09:49 -0400 Subject: [PATCH 4982/6505] Update build.func add Proxmox VE 7 warning regarding Debian 12 LXCs --- misc/build.func | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/misc/build.func b/misc/build.func index 9d59ada1..b77cd463 100644 --- a/misc/build.func +++ b/misc/build.func @@ -437,6 +437,10 @@ install_script() { } start() { + if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then + whiptail --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters." 10 58 + fi + if command -v pveversion >/dev/null 2>&1; then if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then clear From 72051ef30c758106e8b6b021eaef719590a0f23e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 09:32:14 -0400 Subject: [PATCH 4983/6505] Update build.func fix indent --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index b77cd463..4d7dca0e 100644 --- a/misc/build.func +++ b/misc/build.func @@ -437,7 +437,7 @@ install_script() { } start() { - if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then + if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then whiptail --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters." 10 58 fi From 94c9d4a3315e23b77bfb239ff8c9d863d1feece7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 09:54:46 -0400 Subject: [PATCH 4984/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 4d7dca0e..e8478a7f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -438,7 +438,7 @@ install_script() { start() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - whiptail --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters." 10 58 + whiptail --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters. \n Default distribution for $APP LXC is ${var_os} ${var_version}" 10 58 fi if command -v pveversion >/dev/null 2>&1; then From da0a6524fbe0d1205a890e884520ea3975b47d24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 10:45:39 -0400 Subject: [PATCH 4985/6505] Create pbs3-upgrade.sh --- misc/pbs3-upgrade.sh | 172 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 misc/pbs3-upgrade.sh diff --git a/misc/pbs3-upgrade.sh b/misc/pbs3-upgrade.sh new file mode 100644 index 00000000..eb519ab9 --- /dev/null +++ b/misc/pbs3-upgrade.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +header_info() { + clear + cat <<"EOF" + ____ ____ __________ __ ______ __________ ___ ____ ______ + / __ \/ __ ) ___/__ / / / / / __ \/ ____/ __ \/ | / __ \/ ____/ + / /_/ / __ \__ \ /_ < / / / / /_/ / / __/ /_/ / /| | / / / / __/ + / ____/ /_/ /__/ /__/ / / /_/ / ____/ /_/ / _, _/ ___ |/ /_/ / /___ +/_/ /_____/____/____/ \____/_/ \____/_/ |_/_/ |_/_____/_____/ + +EOF +} + +RD=$(echo "\033[01;31m") +YW=$(echo "\033[33m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + + +start_routines() { + header_info + CHOICE=$(whiptail --title "PBS 2 BACKUP" --menu "\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Backing up Proxmox Backup Server 2" + tar czf "pbs2-etc-backup-$(date -I).tar.gz" -C "/etc" "proxmox-backup" + msg_ok "Backed up to Proxmox Backup Server" + ;; + no) + msg_error "Selected no to Backing up Proxmox Backup Server 2" + ;; + esac + + CHOICE=$(whiptail --title "PBS 3 SOURCES" --menu "This will set the correct sources to update and install Proxmox Backup Server 3.\n \nChange to Proxmox Backup Server 3 sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Changing to Proxmox Backup Server 3 Sources" + cat </etc/apt/sources.list +deb http://deb.debian.org/debian bookworm main contrib +deb http://deb.debian.org/debian bookworm-updates main contrib +deb http://security.debian.org/debian-security bookworm-security main contrib +EOF + msg_ok "Changed to Proxmox Backup Server 3 Sources" + ;; + no) + msg_error "Selected no to Correcting Proxmox Backup Server 3 Sources" + ;; + esac + + CHOICE=$(whiptail --title "PBS3-ENTERPRISE" --menu "The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pbs-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling 'pbs-enterprise' repository" + cat </etc/apt/sources.list.d/pbs-enterprise.list +# deb https://enterprise.proxmox.com/debian/pbs bookworm pbs-enterprise +EOF + msg_ok "Disabled 'pbs-enterprise' repository" + ;; + no) + msg_error "Selected no to Disabling 'pbs-enterprise' repository" + ;; + esac + + CHOICE=$(whiptail --title "PBS3-NO-SUBSCRIPTION" --menu "The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\n \nEnable 'pbs-no-subscription' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'pbs-no-subscription' repository" + cat </etc/apt/sources.list.d/pbs-install-repo.list +deb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription +EOF + msg_ok "Enabled 'pbs-no-subscription' repository" + ;; + no) + msg_error "Selected no to Enabling 'pbs-no-subscription' repository" + ;; + esac + + CHOICE=$(whiptail --title "PBS3 TEST" --menu "The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pbstest' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Adding 'pbstest' repository and set disabled" + cat </etc/apt/sources.list.d/pbstest-for-beta.list +# deb http://download.proxmox.com/debian/pbs bookworm pbstest +EOF + msg_ok "Added 'pbstest' repository" + ;; + no) + msg_error "Selected no to Adding 'pbstest' repository" + ;; + esac + + CHOICE=$(whiptail --title "PBS 3 UPDATE" --menu "\nUpdate to Proxmox Backup Server 3 now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Updating to Proxmox Backup Server 3 (Patience)" + apt-get update + DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y + msg_ok "Updated to Proxmox Backup Server 3" + ;; + no) + msg_error "Selected no to Updating to Proxmox Backup Server 3" + ;; + esac + + CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox Backup Server 3 now? (recommended)" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Rebooting Proxmox Backup Server 3" + sleep 2 + msg_ok "Completed Install Routines" + reboot + ;; + no) + msg_error "Selected no to Rebooting Proxmox Backup Server 3 (Reboot recommended)" + msg_ok "Completed Install Routines" + ;; + esac +} + +header_info +while true; do + read -p "Start the Update to Proxmox Backup Server 3 Script (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) clear; exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +start_routines From 7f388de17a050dd13f975002e8132ec50e6979c8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 10:53:33 -0400 Subject: [PATCH 4986/6505] Update pbs3-upgrade.sh tweak --- misc/pbs3-upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pbs3-upgrade.sh b/misc/pbs3-upgrade.sh index eb519ab9..83da6e95 100644 --- a/misc/pbs3-upgrade.sh +++ b/misc/pbs3-upgrade.sh @@ -54,7 +54,7 @@ start_routines() { yes) msg_info "Backing up Proxmox Backup Server 2" tar czf "pbs2-etc-backup-$(date -I).tar.gz" -C "/etc" "proxmox-backup" - msg_ok "Backed up to Proxmox Backup Server" + msg_ok "Backed up Proxmox Backup Server 2" ;; no) msg_error "Selected no to Backing up Proxmox Backup Server 2" From f7b56041b359ff6b7e5f252b253904c252431f7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 10:58:04 -0400 Subject: [PATCH 4987/6505] Update pbs3-upgrade.sh tweak --- misc/pbs3-upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/pbs3-upgrade.sh b/misc/pbs3-upgrade.sh index 83da6e95..6b389e97 100644 --- a/misc/pbs3-upgrade.sh +++ b/misc/pbs3-upgrade.sh @@ -47,7 +47,7 @@ msg_error() { start_routines() { header_info - CHOICE=$(whiptail --title "PBS 2 BACKUP" --menu "\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?" 11 58 2 \ + CHOICE=$(whiptail --title "PBS 2 BACKUP" --menu "\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From 2c5da2e770c94e1a62705d023e90c13ce6ea8301 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 16:41:46 -0400 Subject: [PATCH 4988/6505] Update build.func tweak --- misc/build.func | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index e8478a7f..fced35ed 100644 --- a/misc/build.func +++ b/misc/build.func @@ -54,6 +54,9 @@ msg_error() { # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { + if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then + whiptail --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters. \n Default distribution for $APP LXC is ${var_os} ${var_version}" 10 58 + fi if ! pveversion | grep -Eq "pve-manager/(7\.[0-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 7.0 or higher" @@ -437,10 +440,6 @@ install_script() { } start() { - if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - whiptail --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters. \n Default distribution for $APP LXC is ${var_os} ${var_version}" 10 58 - fi - if command -v pveversion >/dev/null 2>&1; then if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then clear From 825070b914e42f91255e9f5182cb87577cecd342 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 19:55:52 -0400 Subject: [PATCH 4989/6505] Update homepage-install.sh Fix install Debian 12 compatible --- install/homepage-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 129195e4..f0c221e5 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -20,11 +20,12 @@ $STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +$STD apt-get install -y nodejs git make g++ gcc $STD npm install -g pnpm msg_ok "Installed Node.js" From b18a844c9835b6682ba5cf1e786bc427a410e7aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Jun 2023 19:56:23 -0400 Subject: [PATCH 4990/6505] Update homepage.sh default Debian 12 --- ct/homepage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homepage.sh b/ct/homepage.sh index d133e7a8..eba11d3c 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -23,7 +23,7 @@ var_disk="3" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 9487e5930365f732e1dd80113d027377be371a89 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 02:35:15 -0400 Subject: [PATCH 4991/6505] Update photoprism.sh default Dwbian 12 --- ct/photoprism.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 31dd6735..0fffa7f2 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="4" var_ram="4096" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 4c9a67a40a0903338316da5a66a8b14fbd2a22aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 09:29:54 -0400 Subject: [PATCH 4992/6505] Update tautulli.sh default Debian 12 --- ct/tautulli.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/tautulli.sh b/ct/tautulli.sh index b8d052c4..5baf342d 100644 --- a/ct/tautulli.sh +++ b/ct/tautulli.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From d67160437aa1e56b479ec358055bb271db141636 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 09:31:21 -0400 Subject: [PATCH 4993/6505] Update radarr.sh default Debian 12 --- ct/radarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/radarr.sh b/ct/radarr.sh index 6282e685..8a1d5972 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From c6902c2ab4d869ae5d62aac00741ff43ac00c96a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 09:32:07 -0400 Subject: [PATCH 4994/6505] Update readarr.sh default Debian 12 --- ct/readarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/readarr.sh b/ct/readarr.sh index eb6466e5..1a1eb7c2 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From c48420acfc3f113afc94443e2068b690e38fe809 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 09:32:54 -0400 Subject: [PATCH 4995/6505] Update prowlarr.sh default Debian 12 --- ct/prowlarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index c53b162b..09c3bdd5 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 2e64312114d09cf4b2651f73cf6ecf1a860221f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 09:33:25 -0400 Subject: [PATCH 4996/6505] Update bazarr.sh default Debian 12 --- ct/bazarr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/bazarr.sh b/ct/bazarr.sh index cf85c64c..be9cc53a 100755 --- a/ct/bazarr.sh +++ b/ct/bazarr.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors @@ -66,4 +66,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:6767${CL} \n" \ No newline at end of file + ${BL}http://${IP}:6767${CL} \n" From f13b111c5600a8ba47b646aa3928fc9c53b2a871 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 09:39:16 -0400 Subject: [PATCH 4997/6505] Update qbittorrent.sh default Debian 12 --- ct/qbittorrent.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 8615ae2d..40cfa24d 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -24,7 +24,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From fced2347fde033c98c8ed19858d7aad1a3c057f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 10:11:46 -0400 Subject: [PATCH 4998/6505] Update dashy-install.sh fix install Debian 12 compatible --- install/dashy-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 50078550..c83907fb 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -23,11 +23,13 @@ $STD apt-get install -y g++ $STD apt-get install -y gcc msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +$STD apt-get install -y nodejs +$STD npm install -g pnpm msg_ok "Installed Node.js" msg_info "Installing Yarn" From c2c4ac8f0319bfe479c89665ab896f4de50a091e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 10:20:55 -0400 Subject: [PATCH 4999/6505] Update dashy-install.sh node 17 --- install/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index c83907fb..602146af 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -24,7 +24,7 @@ $STD apt-get install -y gcc msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_17.x) msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From eb9f50901ca56a94a026c98d435408f58be35aca Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 10:27:01 -0400 Subject: [PATCH 5000/6505] Update dashy-install.sh node 16.20.1 --- install/dashy-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 602146af..8bab8c27 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -24,11 +24,11 @@ $STD apt-get install -y gcc msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_17.x) +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -$STD apt-get install -y nodejs +$STD apt-get install -y nodejs 16.20.1 $STD npm install -g pnpm msg_ok "Installed Node.js" From d9b9e7a851a76dd0ad07e2d0d18e08e1d425e904 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 10:35:00 -0400 Subject: [PATCH 5001/6505] Update dashy-install.sh tweak --- install/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 8bab8c27..f8fa07c4 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -28,7 +28,7 @@ $STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -$STD apt-get install -y nodejs 16.20.1 +$STD apt-get install -y nodejs=16.20.1 $STD npm install -g pnpm msg_ok "Installed Node.js" From 6b02a5ec0c3e0576b15d390d4169b2a654446657 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 11:23:39 -0400 Subject: [PATCH 5002/6505] Update dashy-install.sh fixed install closes https://github.com/tteck/Proxmox/issues/1564 --- install/dashy-install.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index f8fa07c4..44d85f86 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -18,22 +18,20 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git -$STD apt-get install -y make -$STD apt-get install -y g++ -$STD apt-get install -y gcc msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get install -y nodejs=16.20.1 +msg_info "Installing Node.js (Patience)" +$STD apt-get install -y npm +$STD npm cache clean -f +$STD npm install -g n +$STD n 16.20.1 $STD npm install -g pnpm +ln -sf /usr/local/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Yarn" $STD npm install --global yarn +ln -sf /usr/local/bin/yarn /usr/bin/yarn msg_ok "Installed Yarn" msg_info "Installing Dashy (Patience)" From bc103fa66d686429fc293893852f432c345617cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 11:24:13 -0400 Subject: [PATCH 5003/6505] Update dashy.sh default Debian 12 --- ct/dashy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index 3bd3284d..64016d38 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -23,7 +23,7 @@ var_disk="6" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From e4dff2c808035b5a8ea787b06e7b1c6a923527d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 12:55:10 -0400 Subject: [PATCH 5004/6505] Update paperless-ngx-install.sh Debian 12 compatible --- install/paperless-ngx-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 87db1282..50f749f5 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -81,6 +81,7 @@ $STD tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ mv paperless-ngx paperless rm paperless-ngx-$Paperlessngx.tar.xz cd /opt/paperless +sed -i 's/scipy==1.8.1/scipy==1.10.1/g' requirements.txt ## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt $STD pip install --upgrade pip From 834b9002a5819b22eb63703eecefc988fc52d7d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 12:55:55 -0400 Subject: [PATCH 5005/6505] Update paperless-ngx.sh default Debian 12 --- ct/paperless-ngx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 7a5483f4..a5c91a83 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -24,7 +24,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From d5ac9ed5b7f0de3b8148043dc4cb8c8f07b712e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 29 Jun 2023 13:01:34 -0400 Subject: [PATCH 5006/6505] Update paperless-ngx.sh fix update --- ct/paperless-ngx.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index a5c91a83..c58a3004 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -80,6 +80,7 @@ function update_script() { cp -r /opt/paperless/paperless.conf paperless-ngx/ cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless + sed -i 's/scipy==1.8.1/scipy==1.10.1/g' requirements.txt sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt pip install -r requirements.txt &>/dev/null cd /opt/paperless/src From 34e22223f51efb9409e73696777f104516527edc Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 06:04:35 -0400 Subject: [PATCH 5007/6505] Update nginxproxymanager-install.sh Code refactoring --- install/nginxproxymanager-install.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index e9ee8df0..9a79ea4d 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -52,15 +52,17 @@ $STD apt-get update $STD apt-get -y install openresty msg_ok "Installed Openresty" -msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +msg_info "Installing Node.js (Patience)" +$STD apt-get install -y npm +$STD npm cache clean -f +$STD npm install -g n +$STD n 16.20.1 +ln -sf /usr/local/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Yarn" -$STD npm install --global yarn +$STD npm install -g yarn +ln -sf /usr/local/bin/yarn /usr/bin/yarn msg_ok "Installed Yarn" RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | From ecfb57a91937278a654632597b24a394028ab3c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 06:51:35 -0400 Subject: [PATCH 5008/6505] Update yunohost-install.sh apt-key is deprecated --- install/yunohost-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/yunohost-install.sh b/install/yunohost-install.sh index aaeadc1b..80fd97c4 100644 --- a/install/yunohost-install.sh +++ b/install/yunohost-install.sh @@ -18,14 +18,13 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y gnupg -$STD apt-key adv --fetch-keys 'https://packages.sury.org/php/apt.gpg' $STD apt-get install -y apt-transport-https $STD apt-get install -y lsb-release $STD apt-get install -y ca-certificates msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" -wget -q -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg +curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg $STD bash <(curl -fsSL https://install.yunohost.org) -a msg_ok "Installed YunoHost" From 43ed3ffcaa6d6cf106ac9ca73cf00346845f05fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 07:28:34 -0400 Subject: [PATCH 5009/6505] Update nginxproxymanager-install.sh revert --- install/nginxproxymanager-install.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 9a79ea4d..418962d3 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -53,16 +53,14 @@ $STD apt-get -y install openresty msg_ok "Installed Openresty" msg_info "Installing Node.js (Patience)" -$STD apt-get install -y npm -$STD npm cache clean -f -$STD npm install -g n -$STD n 16.20.1 -ln -sf /usr/local/bin/node /usr/bin/node +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +. ~/.bashrc +$STD nvm install 16.20.1 +ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Yarn" $STD npm install -g yarn -ln -sf /usr/local/bin/yarn /usr/bin/yarn msg_ok "Installed Yarn" RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | From de76bf329dacb14a9fce7461a741138af61aa71c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 08:08:16 -0400 Subject: [PATCH 5010/6505] Update sonarr-install.sh change repo --- install/sonarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index 099257b0..1b11b265 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -23,7 +23,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Sonarr" $STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 -sh -c 'echo "deb https://apt.sonarr.tv/debian buster-develop main" > /etc/apt/sources.list.d/sonarr.list' +sh -c 'echo "deb https://apt.sonarr.tv/debian testing-main main" > /etc/apt/sources.list.d/sonarr.list' $STD apt-get update DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy sonarr &>/dev/null msg_ok "Installed Sonarr" From 341405cf61b5d9e48180e87cb9287e808cc0821a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 08:15:00 -0400 Subject: [PATCH 5011/6505] Update sonarr.sh default Debian 12 --- ct/sonarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/sonarr.sh b/ct/sonarr.sh index 0ed45a21..cbcf3e34 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 41f44f4c284c54d8c35621b4b0c007d77f695cf5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 08:23:27 -0400 Subject: [PATCH 5012/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 418962d3..640227d9 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -52,7 +52,7 @@ $STD apt-get update $STD apt-get -y install openresty msg_ok "Installed Openresty" -msg_info "Installing Node.js (Patience)" +msg_info "Installing Node.js" $STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) . ~/.bashrc $STD nvm install 16.20.1 From 54347d6ffd512865687eaafc1118289f306545e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 08:30:05 -0400 Subject: [PATCH 5013/6505] Update lidarr.sh default Debian 12 --- ct/lidarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/lidarr.sh b/ct/lidarr.sh index 17114c71..9f2bbb5d 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From f5267a7e432755e2a0711345e48407b16fac2619 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 30 Jun 2023 21:25:52 -0400 Subject: [PATCH 5014/6505] Update wikijs-install.sh fix to work with Debian 11 --- install/wikijs-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index f6a93f50..32152da6 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -20,11 +20,12 @@ $STD apt-get install -y mc $STD apt-get install -y git msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +msg_ok "Set up Node.js Repository" + msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +$STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Installing Wiki.js" From d027e36d844874464e8ce202dffea215220c8b3a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 13:05:09 -0400 Subject: [PATCH 5015/6505] Update mariadb.sh default Debian 12 --- ct/mariadb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mariadb.sh b/ct/mariadb.sh index b955a589..dcf59e0d 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 301058696b73216733a92bac2b46729bc93c14ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 16:43:35 -0400 Subject: [PATCH 5016/6505] Update n8n-install.sh fix node --- install/n8n-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 95a86e73..6f36c40b 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -19,11 +19,12 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +$STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Installing n8n (Patience)" From fa696474d539126e1157e002ab394502e8e48e68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 16:47:58 -0400 Subject: [PATCH 5017/6505] Update n8n.sh default Debian 12 --- ct/n8n.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/n8n.sh b/ct/n8n.sh index 906d46c1..fbf697a8 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -24,7 +24,7 @@ var_disk="3" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 2cd7e87f0c4e9da9fab9db4021cd8888ef4d7244 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 17:19:01 -0400 Subject: [PATCH 5018/6505] Update zigbee2mqtt.sh default Debian 12 --- ct/zigbee2mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index a9634918..14b75066 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From d8521347eb28553a96cd2e25b1e19e42ba18a2fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 17:26:59 -0400 Subject: [PATCH 5019/6505] Update cloudflared-install.sh Debian 12 compatible --- install/cloudflared-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/cloudflared-install.sh b/install/cloudflared-install.sh index 921da7cd..d19fa2b7 100644 --- a/install/cloudflared-install.sh +++ b/install/cloudflared-install.sh @@ -21,8 +21,9 @@ msg_ok "Installed Dependencies" msg_info "Installing Cloudflared" mkdir -p --mode=0755 /usr/share/keyrings +VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null -echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared bullseye main' | tee /etc/apt/sources.list.d/cloudflared.list >/dev/null +echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $VERSION main' | tee /etc/apt/sources.list.d/cloudflared.list >/dev/null $STD apt-get update $STD apt-get install -y cloudflared msg_ok "Installed Cloudflared" From 8e3af578e85de6fc7c85649501f254e47c281ff4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 17:27:40 -0400 Subject: [PATCH 5020/6505] Update cloudflared.sh default Debian 12 --- ct/cloudflared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/cloudflared.sh b/ct/cloudflared.sh index fafb6595..59634450 100644 --- a/ct/cloudflared.sh +++ b/ct/cloudflared.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 4544974c7301073cc4b851385c3f364eeed7ffe4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 17:41:24 -0400 Subject: [PATCH 5021/6505] Update uptimekuma.sh default Debian 12 --- ct/uptimekuma.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 2f82fc3b..108a004a 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 04638c27ada9cb3aa7679fe6bb7296c767f033ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 18:12:17 -0400 Subject: [PATCH 5022/6505] Update adguard-install.sh eliminate outside bash script --- install/adguard-install.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/install/adguard-install.sh b/install/adguard-install.sh index eb262cf0..ae016e90 100644 --- a/install/adguard-install.sh +++ b/install/adguard-install.sh @@ -20,9 +20,33 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh) +tar zxvf <(curl -fsSL https://static.adtidy.org/adguardhome/release/AdGuardHome_linux_amd64.tar.gz) -C /opt &>/dev/null msg_ok "Installed AdGuard Home" +msg_info "Creating Service" +cat </etc/systemd/system/AdGuardHome.service +[Unit] +Description=AdGuard Home: Network-level blocker +ConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome +After=syslog.target network-online.target + +[Service] +StartLimitInterval=5 +StartLimitBurst=10 +ExecStart=/opt/AdGuardHome/AdGuardHome "-s" "run" +WorkingDirectory=/opt/AdGuardHome +StandardOutput=file:/var/log/AdGuardHome.out +StandardError=file:/var/log/AdGuardHome.err +Restart=always +RestartSec=10 +EnvironmentFile=-/etc/sysconfig/AdGuardHome + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now AdGuardHome.service +msg_ok "Created Service" + motd_ssh customize From 173e132e39846b46034f3323996eb3a2aa63a0a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 21:25:15 -0400 Subject: [PATCH 5023/6505] Update cloudflared-install.sh tweak --- install/cloudflared-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/cloudflared-install.sh b/install/cloudflared-install.sh index d19fa2b7..3d41a7b9 100644 --- a/install/cloudflared-install.sh +++ b/install/cloudflared-install.sh @@ -22,8 +22,8 @@ msg_ok "Installed Dependencies" msg_info "Installing Cloudflared" mkdir -p --mode=0755 /usr/share/keyrings VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" -curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null -echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $VERSION main' | tee /etc/apt/sources.list.d/cloudflared.list >/dev/null +curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg >/usr/share/keyrings/cloudflare-main.gpg +echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $VERSION main" >/etc/apt/sources.list.d/cloudflared.list $STD apt-get update $STD apt-get install -y cloudflared msg_ok "Installed Cloudflared" From 3d22cec8814529dd464110d81a0b09af77c28f31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 21:26:22 -0400 Subject: [PATCH 5024/6505] Update openobserve-install.sh tweak --- install/openobserve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh index f00ad8ea..48a03e31 100644 --- a/install/openobserve-install.sh +++ b/install/openobserve-install.sh @@ -22,7 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing OpenObserve" mkdir -p /opt/openobserve/data LATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve &>/dev/null +$STD tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve cat </opt/openobserve/data/.env ZO_ROOT_USER_EMAIL = "admin@example.com" From 563c9f41e8b4e08c23b3ac5aeb1532dcb270b931 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 1 Jul 2023 21:27:32 -0400 Subject: [PATCH 5025/6505] Update adguard-install.sh tweak --- install/adguard-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/adguard-install.sh b/install/adguard-install.sh index ae016e90..4b03cb71 100644 --- a/install/adguard-install.sh +++ b/install/adguard-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing AdGuard Home" -tar zxvf <(curl -fsSL https://static.adtidy.org/adguardhome/release/AdGuardHome_linux_amd64.tar.gz) -C /opt &>/dev/null +$STD tar zxvf <(curl -fsSL https://static.adtidy.org/adguardhome/release/AdGuardHome_linux_amd64.tar.gz) -C /opt msg_ok "Installed AdGuard Home" msg_info "Creating Service" From 0cbc4751a08d13e67d767942ac6f7e5363532f84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jul 2023 02:19:36 -0400 Subject: [PATCH 5026/6505] Update sonarr-install.sh tweak --- install/sonarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index 1b11b265..fb18ab3a 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -23,7 +23,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Sonarr" $STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 -sh -c 'echo "deb https://apt.sonarr.tv/debian testing-main main" > /etc/apt/sources.list.d/sonarr.list' +echo "deb https://apt.sonarr.tv/debian testing-main main" >/etc/apt/sources.list.d/sonarr.list $STD apt-get update DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy sonarr &>/dev/null msg_ok "Installed Sonarr" From 4133d38062af6ac39c8b4b0c2f212bc27107fc7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jul 2023 02:54:37 -0400 Subject: [PATCH 5027/6505] Update post-pve-install.sh add Enable high availability --- misc/post-pve-install.sh | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index fcf634df..b3fb1bf6 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -162,12 +162,9 @@ EOF case $CHOICE in yes) msg_info "Disabling high availability" - systemctl stop pve-ha-lrm - systemctl disable pve-ha-lrm &>/dev/null - systemctl stop pve-ha-crm - systemctl disable pve-ha-crm &>/dev/null - systemctl stop corosync - systemctl disable corosync &>/dev/null + systemctl disable -q --now pve-ha-lrm + systemctl disable -q --now pve-ha-crm + systemctl disable -q --now corosync msg_ok "Disabled high availability" ;; no) @@ -176,6 +173,24 @@ EOF esac fi + if ! systemctl is-active --quiet pve-ha-lrm; then + CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "Enable high availability?" 10 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling high availability" + systemctl enable -q --now pve-ha-lrm + systemctl enable -q --now pve-ha-crm + systemctl enable -q --now corosync + msg_ok "Enabled high availability" + ;; + no) + msg_error "Selected no to Enabling high availability" + ;; + esac + fi + CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) From 2fbac0383af2d249d546e49aeef091adf2a5edf2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jul 2023 03:51:07 -0400 Subject: [PATCH 5028/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index b3fb1bf6..7b1fcf7c 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -155,24 +155,6 @@ EOF esac fi - if systemctl is-active --quiet pve-ha-lrm; then - CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) - msg_info "Disabling high availability" - systemctl disable -q --now pve-ha-lrm - systemctl disable -q --now pve-ha-crm - systemctl disable -q --now corosync - msg_ok "Disabled high availability" - ;; - no) - msg_error "Selected no to Disabling high availability" - ;; - esac - fi - if ! systemctl is-active --quiet pve-ha-lrm; then CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "Enable high availability?" 10 58 2 \ "yes" " " \ @@ -191,6 +173,24 @@ EOF esac fi + if systemctl is-active --quiet pve-ha-lrm; then + CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling high availability" + systemctl disable -q --now pve-ha-lrm + systemctl disable -q --now pve-ha-crm + systemctl disable -q --now corosync + msg_ok "Disabled high availability" + ;; + no) + msg_error "Selected no to Disabling high availability" + ;; + esac + fi + CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) From 4d6a9b777d7d3321f85aad908f4d9a9698a86959 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jul 2023 10:33:51 -0400 Subject: [PATCH 5029/6505] Update mariadb-install.sh fix Debian 12 install closes https://github.com/tteck/Proxmox/issues/1580 --- install/mariadb-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index 3fefa9b1..e7af61e1 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -20,8 +20,6 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing MariaDB" -$STD bash <(curl -fsSL https://r.mariadb.com/downloads/mariadb_repo_setup) -$STD apt-get update $STD apt-get install -y mariadb-server msg_ok "Installed MariaDB" From 345ba6932db3e2dd0ee11f445e99d7d06f07a71f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jul 2023 10:49:58 -0400 Subject: [PATCH 5030/6505] Update trilium.sh default Debian 12 --- ct/trilium.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/trilium.sh b/ct/trilium.sh index a54e36a4..7216f249 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 5f6478e0dd600dd1936f9d1fcfee7e4b521d6f6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jul 2023 11:15:52 -0400 Subject: [PATCH 5031/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index ab1eed2e..de4685ae 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -2,7 +2,7 @@ In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. -[Installing Home Assistant OS using Proxmox 7](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-7/201835) +[Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-7/201835) [How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/) From aabaa091ad85535ac07af5baeea71bfa169d7972 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jul 2023 11:17:25 -0400 Subject: [PATCH 5032/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index de4685ae..cd680d1a 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -2,7 +2,7 @@ In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. -[Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-7/201835) +[Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835) [How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/) From 6acacbf8c875ee2c765d30c9d7b2ae93a8ae35f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 3 Jul 2023 13:12:11 -0400 Subject: [PATCH 5033/6505] Update technitiumdns-install.sh Debian 12 compatible --- install/technitiumdns-install.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index 4f3f6c98..f2b67d39 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -28,9 +28,6 @@ $STD apt-get install -y aspnetcore-runtime-7.0 msg_ok "Installed ASP.NET Core Runtime" msg_info "Installing Technitium DNS" -systemctl stop systemd-resolved -echo "DNSStubListener=no" >>/etc/systemd/resolved.conf -ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf $STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) msg_ok "Installed Technitium DNS" From 7a9f9c0c2eb9c1efe1e9182427d071d7d97d2e80 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 3 Jul 2023 13:17:17 -0400 Subject: [PATCH 5034/6505] Update technitiumdns.sh default Debian 12 --- ct/technitiumdns.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index 6b538f6a..c43d54e4 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors @@ -62,10 +62,7 @@ if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then apt-get install -y aspnetcore-runtime-7.0 rm packages-microsoft-prod.deb fi -wget -q https://download.technitium.com/dns/DnsServerPortable.tar.gz -tar -zxf DnsServerPortable.tar.gz -C /etc/dns/ &>/dev/null -rm -rf DnsServerPortable.tar.gz -systemctl restart dns.service +$STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) msg_ok "Updated Successfully" exit } From 77cb0b356d9606380ecae9b1f52b274d7a9a8ad2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 3 Jul 2023 15:20:57 -0400 Subject: [PATCH 5035/6505] Update post-pbs-install.sh compatible with both PBS 2 and PBS 3 --- misc/post-pbs-install.sh | 265 ++++++++++++++++++++++++--------------- 1 file changed, 162 insertions(+), 103 deletions(-) diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index 39a0a320..aebddb14 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -5,28 +5,175 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -set -euo pipefail -shopt -s inherit_errexit nullglob -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") +header_info() { + clear + cat <<"EOF" + ____ ____ _____ ____ __ ____ __ ____ + / __ \/ __ ) ___/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / + / /_/ / __ \__ \ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / + / ____/ /_/ /__/ / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / +/_/ /_____/____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ + +EOF +} + RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") +YW=$(echo "\033[33m") GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -clear -echo -e "${BL}This script will Perform Post Install Routines.${CL}" -while true; do - read -p "Start the PBS Post Install Script (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; + +set -euo pipefail +shopt -s inherit_errexit nullglob + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + + +start_routines() { + header_info + VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" + CHOICE=$(whiptail --title "PBS SOURCES" --menu "This will set the correct sources to update and install Proxmox Backup Server.\n \nChange to Proxmox Backup Server sources?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Changing to Proxmox Backup Server Sources" + cat </etc/apt/sources.list +deb http://deb.debian.org/debian ${VERSION} main contrib +deb http://deb.debian.org/debian ${VERSION}-updates main contrib +deb http://security.debian.org/debian-security ${VERSION}-security main contrib +EOF + msg_ok "Changed to Proxmox Backup Server Sources" + ;; + no) + msg_error "Selected no to Correcting Proxmox Backup Server Sources" + ;; + esac + + CHOICE=$(whiptail --title "PBS-ENTERPRISE" --menu "The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pbs-enterprise' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Disabling 'pbs-enterprise' repository" + cat </etc/apt/sources.list.d/pbs-enterprise.list +# deb https://enterprise.proxmox.com/debian/pbs ${VERSION} pbs-enterprise +EOF + msg_ok "Disabled 'pbs-enterprise' repository" + ;; + no) + msg_error "Selected no to Disabling 'pbs-enterprise' repository" + ;; + esac + + CHOICE=$(whiptail --title "PBS-NO-SUBSCRIPTION" --menu "The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\n \nEnable 'pbs-no-subscription' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Enabling 'pbs-no-subscription' repository" + cat </etc/apt/sources.list.d/pbs-install-repo.list +deb http://download.proxmox.com/debian/pbs ${VERSION} pbs-no-subscription +EOF + msg_ok "Enabled 'pbs-no-subscription' repository" + ;; + no) + msg_error "Selected no to Enabling 'pbs-no-subscription' repository" + ;; + esac + + CHOICE=$(whiptail --title "PBS TEST" --menu "The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pbstest' repository?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Adding 'pbstest' repository and set disabled" + cat </etc/apt/sources.list.d/pbstest-for-beta.list +# deb http://download.proxmox.com/debian/pbs ${VERSION} pbstest +EOF + msg_ok "Added 'pbstest' repository" + ;; + no) + msg_error "Selected no to Adding 'pbstest' repository" + ;; + esac + + if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then + CHOICE=$(whiptail --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + msg_info "Disabling subscription nag" + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + apt --reinstall install proxmox-widget-toolkit &>/dev/null + msg_ok "Disabled subscription nag (Delete browser cache)" + ;; + no) + whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + msg_error "Selected no to Disabling subscription nag" + ;; esac + fi + + CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox Backup Server now?" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Updating Proxmox Backup Server (Patience)" + apt-get update &>/dev/null + apt-get -y dist-upgrade &>/dev/null + msg_ok "Updated Proxmox Backup Server" + ;; + no) + msg_error "Selected no to Updating Proxmox Backup Server" + ;; + esac + + CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox Backup Server now? (recommended)" 11 58 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + case $CHOICE in + yes) + msg_info "Rebooting Proxmox Backup Server" + sleep 2 + msg_ok "Completed Post Install Routines" + reboot + ;; + no) + msg_error "Selected no to Rebooting Proxmox Backup Server (Reboot recommended)" + msg_ok "Completed Post Install Routines" + ;; + esac +} + +header_info +echo -e "\nThis script will Perform Post Install Routines.\n" +while true; do + read -p "Start the Proxmox Backup Server Post Install Script (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) clear; exit ;; + *) echo "Please answer yes or no." ;; + esac done if command -v pveversion >/dev/null 2>&1; then @@ -34,92 +181,4 @@ if command -v pveversion >/dev/null 2>&1; then exit 1 fi -function header_info { - cat <<"EOF" - ____ ____ _____ ____ __ ____ __ ____ - / __ \/ __ ) ___/ / __ \____ _____/ /_ / _/___ _____/ /_____ _/ / / - / /_/ / __ \__ \ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ `/ / / - / ____/ /_/ /__/ / / ____/ /_/ (__ ) /_ _/ // / / (__ ) /_/ /_/ / / / -/_/ /_____/____/ /_/ \____/____/\__/ /___/_/ /_/____/\__/\__,_/_/_/ - -EOF -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -clear -header_info -read -r -p "Disable Enterprise Repository? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Disabling Enterprise Repository" - sleep 2 - sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pbs-enterprise.list - msg_ok "Disabled Enterprise Repository" -fi - -read -r -p "Add/Correct PBS Sources (sources.list)? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Adding or Correcting PBS Sources" - cat </etc/apt/sources.list -deb http://ftp.debian.org/debian bullseye main contrib -deb http://ftp.debian.org/debian bullseye-updates main contrib -deb http://security.debian.org/debian-security bullseye-security main contrib -EOF - sleep 2 - msg_ok "Added or Corrected PBS Sources" -fi - -read -r -p "Enable No-Subscription Repository? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Enabling No-Subscription Repository" - cat <>/etc/apt/sources.list -deb http://download.proxmox.com/debian/pbs bullseye pbs-no-subscription -EOF - sleep 2 - msg_ok "Enabled No-Subscription Repository" -fi - -read -r -p "Add (Disabled) Beta/Test Repository? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Adding Beta/Test Repository and set disabled" - cat <>/etc/apt/sources.list -# deb http://download.proxmox.com/debian/pbs bullseye pbstest -EOF - sleep 2 - msg_ok "Added Beta/Test Repository" -fi - -read -r -p "Disable Subscription Nag? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Disabling Subscription Nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script - apt --reinstall install proxmox-widget-toolkit &>/dev/null - msg_ok "Disabled Subscription Nag" -fi - -read -r -p "Update Proxmox Backup Server now? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Updating Proxmox Backup Server (Patience)" - apt-get update &>/dev/null - apt-get -y dist-upgrade &>/dev/null - msg_ok "Updated Proxmox Backup Server (⚠ Reboot Recommended)" -fi - -read -r -p "Reboot Proxmox Backup Server now? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Rebooting Proxmox Backup Server" - sleep 2 - msg_ok "Completed Post Install Routines" - reboot -fi - -sleep 2 -msg_ok "Completed Post Install Routines" +start_routines From 0b5d71b8411a626911f37a1adb8842d620997fdd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Jul 2023 04:34:53 -0400 Subject: [PATCH 5036/6505] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b363e6c..7f295bbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-07-05 + +### Changed + +- There have been more than 110 commits since June 18th, although not all of them are significant, with a majority focused on ensuring compatibility with Proxmox VE 8 and Debian 12. + ## 2023-06-18 ### Changed From bc98c1ed80bbc3cccb9f5f744a352e15928ebcf6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Jul 2023 06:17:21 -0400 Subject: [PATCH 5037/6505] Update webmin.sh version 2.021 --- misc/webmin.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index 0095a911..b4375267 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -27,16 +27,16 @@ apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip sh echo -e "${CM}${CL} \r" echo -en "${GN} Downloading Webmin... " -wget http://prdownloads.sourceforge.net/webadmin/webmin_2.000_all.deb &>/dev/null +wget http://prdownloads.sourceforge.net/webadmin/webmin_2.021_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Installing Webmin... " -dpkg --install webmin_2.000_all.deb &>/dev/null +dpkg --install webmin_2.021_all.deb &>/dev/null echo -e "${CM}${CL} \r" echo -en "${GN} Setting Default Webmin usermame & password to root... " /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /root/webmin_2.000_all.deb +rm -rf /root/webmin_2.021_all.deb echo -e "${CM}${CL} \r" IP=$(hostname -I | cut -f1 -d ' ') echo -e "Successfully Installed!! Webmin should be reachable by going to https://${IP}:10000" From b03bb8c1fc5f49874f4c76cf0cf2a18fe0952750 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Jul 2023 18:35:38 -0400 Subject: [PATCH 5038/6505] Update fhem.sh default Debian 12 --- ct/fhem.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/fhem.sh b/ct/fhem.sh index 075d4b45..7f9c8ecf 100644 --- a/ct/fhem.sh +++ b/ct/fhem.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From e2257ed9d7e6046e76e4a64c83fd3059588a8399 Mon Sep 17 00:00:00 2001 From: Michel R Date: Thu, 6 Jul 2023 01:35:43 +0200 Subject: [PATCH 5039/6505] Change homeassistant container url (#1594) As of https://www.home-assistant.io/blog/2023/07/05/release-20237/#breaking-changes the image from ghcr.io should be used --- install/homeassistant-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 715f8a4f..0c19ca6c 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -72,7 +72,7 @@ $STD docker run -d \ msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" -$STD docker pull homeassistant/home-assistant:stable +$STD docker pull ghcr.io/home-assistant/home-assistant:stable msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" msg_info "Installing Home Assistant $CORE_LATEST_VERSION" @@ -86,7 +86,7 @@ $STD docker run -d \ -v hass_config:/config \ -v /etc/localtime:/etc/localtime:ro \ --net=host \ - homeassistant/home-assistant:stable + ghcr.io/home-assistant/home-assistant:stable mkdir /root/hass_config msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" From 5e75bba028edcf09dd4fec490f0a781f2cc00b77 Mon Sep 17 00:00:00 2001 From: crawlingcity Date: Fri, 7 Jul 2023 04:49:28 +0100 Subject: [PATCH 5040/6505] Add rdtclient LXC script (#1595) * add rdtclient (https://github.com/rogerfar/rdt-client) LXC --- ct/rdtclient.sh | 69 ++++++++++++++++++++++++++++++++++++ install/rdtclient-install.sh | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100755 ct/rdtclient.sh create mode 100644 install/rdtclient-install.sh diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh new file mode 100755 index 00000000..3b500549 --- /dev/null +++ b/ct/rdtclient.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ ___ __ + _________/ / /______/ (_)__ ____ / /_ + / ___/ __ / __/ ___/ / / _ \/ __ \/ __/ + / / / /_/ / /_/ /__/ / / __/ / / / /_ +/_/ \__,_/\__/\___/_/_/\___/_/ /_/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="RdtClient" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/rdtclient/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:6500${CL} \n" diff --git a/install/rdtclient-install.sh b/install/rdtclient-install.sh new file mode 100644 index 00000000..5d9cc1a8 --- /dev/null +++ b/install/rdtclient-install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing ASP.NET Core Runtime" +wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb +$STD dpkg -i packages-microsoft-prod.deb +rm packages-microsoft-prod.deb +$STD apt-get update +$STD apt-get install -y dotnet-sdk-6.0 +msg_ok "Installed ASP.NET Core Runtime" +msg_info "Installing rdtclient" +wget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebridClient.zip +unzip -qq RealDebridClient.zip -d /opt/rdtc +rm RealDebridClient.zip +mkdir -p /data/db/ # defaults for rdtclient +mkdir -p /data/downloads # defaults for rdtclient +msg_info "Installed rdtclient" +msg_info "Creating Service" +cat </etc/systemd/system/rdtc.service +[Unit] +Description=RdtClient Service + +[Service] + +WorkingDirectory=/opt/rdtc +ExecStart=/usr/bin/dotnet RdtClient.Web.dll +SyslogIdentifier=RdtClient +User=root + +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl daemon-reload +$STD systemctl enable -q --now rdtc +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 12952cb399fca77f632f0bad5d8070594f96ad96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Jul 2023 23:53:23 -0400 Subject: [PATCH 5041/6505] Update rdtclient-install.sh --- install/rdtclient-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/rdtclient-install.sh b/install/rdtclient-install.sh index 5d9cc1a8..b0d7122a 100644 --- a/install/rdtclient-install.sh +++ b/install/rdtclient-install.sh @@ -27,20 +27,21 @@ rm packages-microsoft-prod.deb $STD apt-get update $STD apt-get install -y dotnet-sdk-6.0 msg_ok "Installed ASP.NET Core Runtime" + msg_info "Installing rdtclient" wget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebridClient.zip unzip -qq RealDebridClient.zip -d /opt/rdtc rm RealDebridClient.zip -mkdir -p /data/db/ # defaults for rdtclient -mkdir -p /data/downloads # defaults for rdtclient +mkdir -p /data/db/ +mkdir -p /data/downloads msg_info "Installed rdtclient" + msg_info "Creating Service" cat </etc/systemd/system/rdtc.service [Unit] Description=RdtClient Service [Service] - WorkingDirectory=/opt/rdtc ExecStart=/usr/bin/dotnet RdtClient.Web.dll SyslogIdentifier=RdtClient @@ -49,7 +50,6 @@ User=root [Install] WantedBy=multi-user.target EOF -$STD systemctl daemon-reload $STD systemctl enable -q --now rdtc msg_ok "Created Service" From 37eff0eb6a122f681665b9cff8e6985296be9947 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Jul 2023 00:43:15 -0400 Subject: [PATCH 5042/6505] Update rdtclient-install.sh tweak --- install/rdtclient-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install/rdtclient-install.sh b/install/rdtclient-install.sh index b0d7122a..67eac42a 100644 --- a/install/rdtclient-install.sh +++ b/install/rdtclient-install.sh @@ -32,9 +32,10 @@ msg_info "Installing rdtclient" wget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebridClient.zip unzip -qq RealDebridClient.zip -d /opt/rdtc rm RealDebridClient.zip -mkdir -p /data/db/ -mkdir -p /data/downloads -msg_info "Installed rdtclient" +cd /opt/rdtc +mkdir -p /data/db/ /data/downloads +sed -i 's#/data/db/#/opt/rdtc&#g' /opt/rdtc/appsettings.json +msg_ok "Installed rdtclient" msg_info "Creating Service" cat </etc/systemd/system/rdtc.service From e71384153267fe1957d311138317442eba5ffaf8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Jul 2023 01:02:55 -0400 Subject: [PATCH 5043/6505] Update rdtclient-install.sh tweak --- install/rdtclient-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/rdtclient-install.sh b/install/rdtclient-install.sh index 67eac42a..8de86327 100644 --- a/install/rdtclient-install.sh +++ b/install/rdtclient-install.sh @@ -33,7 +33,7 @@ wget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebr unzip -qq RealDebridClient.zip -d /opt/rdtc rm RealDebridClient.zip cd /opt/rdtc -mkdir -p /data/db/ /data/downloads +mkdir -p data/db/ data/downloads sed -i 's#/data/db/#/opt/rdtc&#g' /opt/rdtc/appsettings.json msg_ok "Installed rdtclient" From d8c71d9ca83071ac4e50eba932bd8e6c32636e5b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Jul 2023 01:39:45 -0400 Subject: [PATCH 5044/6505] Update rdtclient.sh tweak --- ct/rdtclient.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh index 3b500549..3e70c3dd 100755 --- a/ct/rdtclient.sh +++ b/ct/rdtclient.sh @@ -8,17 +8,17 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ____ ___ __ - _________/ / /______/ (_)__ ____ / /_ - / ___/ __ / __/ ___/ / / _ \/ __ \/ __/ - / / / /_/ / /_/ /__/ / / __/ / / / /_ -/_/ \__,_/\__/\___/_/_/\___/_/ /_/\__/ + ____ __ ____ __ _ __ ______ __ _________ __ + / __ \___ ____ / / / __ \___ / /_ _____(_)___/ / /_ __/___ _____________ ____ / /_ / ____/ (_)__ ____ / /_ + / /_/ / _ \/ __ `/ /___/ / / / _ \/ __ \/ ___/ / __ / / / / __ \/ ___/ ___/ _ \/ __ \/ __/ / / / / / _ \/ __ \/ __/ + / _, _/ __/ /_/ / /___/ /_/ / __/ /_/ / / / / /_/ / / / / /_/ / / / / / __/ / / / /_ / /___/ / / __/ / / / /_ +/_/ |_|\___/\__,_/_/ /_____/\___/_.___/_/ /_/\__,_/ /_/ \____/_/ /_/ \___/_/ /_/\__/ \____/_/_/\___/_/ /_/\__/ EOF } header_info echo -e "Loading..." -APP="RdtClient" +APP="RDTClient" var_disk="4" var_cpu="1" var_ram="1024" From be3f2328609913e6f89852f78a3067077e20ed2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 7 Jul 2023 08:48:26 -0400 Subject: [PATCH 5045/6505] Update CHANGELOG.md Real-Debrid Torrent Client LXC --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f295bbc..90fc8ee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-07-07 + +### Changed + +- **Real-Debrid Torrent Client LXC** + - NEW Script + ## 2023-07-05 ### Changed From 1da852ca43ae8d49abf13f658432e2810d54b9c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 09:48:03 -0400 Subject: [PATCH 5046/6505] Update audiobookshelf-install.sh apt-key is deprecated --- install/audiobookshelf-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/audiobookshelf-install.sh b/install/audiobookshelf-install.sh index 0de9f082..b0abeca6 100644 --- a/install/audiobookshelf-install.sh +++ b/install/audiobookshelf-install.sh @@ -21,8 +21,8 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing audiobookshelf" -$STD apt-key add <(curl -s --compressed "https://advplyr.github.io/audiobookshelf-ppa/KEY.gpg") -sh -c 'echo "deb https://advplyr.github.io/audiobookshelf-ppa ./" > /etc/apt/sources.list.d/audiobookshelf.list' +curl -fsSL https://advplyr.github.io/audiobookshelf-ppa/KEY.gpg >/etc/apt/trusted.gpg.d/audiobookshelf-ppa.asc +echo "deb [signed-by=/etc/apt/trusted.gpg.d/audiobookshelf-ppa.asc] https://advplyr.github.io/audiobookshelf-ppa ./" >/etc/apt/sources.list.d/audiobookshelf.list $STD apt-get update $STD apt install audiobookshelf msg_ok "Installed audiobookshelf" From 1342aa36d89c45aab9c9914a4f050745924d547c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 09:48:38 -0400 Subject: [PATCH 5047/6505] Update audiobookshelf.sh default Debian 12 --- ct/audiobookshelf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 86d51e68..8c1de6f2 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 296f07388d6d4a758dfef4ca5da619685a2e9807 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 10:56:20 -0400 Subject: [PATCH 5048/6505] Update deconz-install.sh code refactoring --- install/deconz-install.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/install/deconz-install.sh b/install/deconz-install.sh index eab4d521..4338b1cc 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -17,22 +17,24 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting Phoscon Repository" -$STD apt-key add <(curl -fsSL http://phoscon.de/apt/deconz.pub.key) -sh -c "echo 'deb [arch=amd64] http://phoscon.de/apt/deconz $(lsb_release -cs) main' > /etc/apt/sources.list.d/deconz.list" +VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" +curl -fsSL http://phoscon.de/apt/deconz.pub.key >/etc/apt/trusted.gpg.d/deconz.pub.asc +echo "deb [arch=amd64] http://phoscon.de/apt/deconz $VERSION main" >/etc/apt/sources.list.d/deconz.list msg_ok "Setup Phoscon Repository" msg_info "Installing deConz" +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb $STD apt-get update $STD apt-get install -y deconz msg_ok "Installed deConz" msg_info "Creating Service" -service_path="/lib/systemd/system/deconz.service" -echo "[Unit] +cat </lib/systemd/system/deconz.service +[Unit] Description=deCONZ: ZigBee gateway -- REST API Wants=deconz-init.service deconz-update.service StartLimitIntervalSec=0 @@ -45,8 +47,9 @@ RestartSec=30 AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME [Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now deconz +WantedBy=multi-user.target +EOF +systemctl enable -q --now deconz msg_ok "Created Service" motd_ssh From 8317090c16ae0c0b050691e8385550cc02b55713 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 10:57:17 -0400 Subject: [PATCH 5049/6505] Update deconz.sh default Debian 12 --- ct/deconz.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/deconz.sh b/ct/deconz.sh index ccf279d1..2c59fa20 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -22,8 +22,8 @@ APP="deCONZ" var_disk="4" var_cpu="2" var_ram="1024" -var_os="ubuntu" -var_version="20.04" +var_os="debian" +var_version="12" variables color catch_errors From dc3c0356ba410a1aa53b62c353b6a10b02b7692c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 11:06:25 -0400 Subject: [PATCH 5050/6505] Update deconz-install.sh tweak --- install/deconz-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/deconz-install.sh b/install/deconz-install.sh index 4338b1cc..54631139 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -56,6 +56,7 @@ motd_ssh customize msg_info "Cleaning up" +rm -rf libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 1ca0522bceefb17c5eccc7c61d953b688e3bd7a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 12:19:45 -0400 Subject: [PATCH 5051/6505] Update sonarr-install.sh apt-key is deprecated --- install/sonarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index fb18ab3a..e2857b87 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -22,7 +22,7 @@ $STD apt-get install -y ca-certificates msg_ok "Installed Dependencies" msg_info "Installing Sonarr" -$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 +wget -qO /etc/apt/trusted.gpg.d/sonarr-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2009837cbffd68f45bc180471f4f90de2a9b4bf8" echo "deb https://apt.sonarr.tv/debian testing-main main" >/etc/apt/sources.list.d/sonarr.list $STD apt-get update DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy sonarr &>/dev/null From f0ae6a89d1d25558f2f75d19029cc5c48fe839ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 12:21:50 -0400 Subject: [PATCH 5052/6505] Update omada-install.sh apt-key is deprecated --- install/omada-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index f6bb625d..dc05b709 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -22,9 +22,9 @@ $STD apt-get install -y jsvc msg_ok "Installed Dependencies" msg_info "Installing Azul Zulu" -$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 +wget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb -$STD apt-get install ./zulu-repo_1.0.0-3_all.deb +$STD dpkg -i zulu-repo_1.0.0-3_all.deb $STD apt-get update $STD apt-get -y install zulu8-jdk msg_ok "Installed Azul Zulu" @@ -45,7 +45,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -f Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +rm -rf Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 006b29fc552f59df701c23f47ef4b97857823149 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 12:24:25 -0400 Subject: [PATCH 5053/6505] Update openhab-install.sh apt-key is deprecated --- install/openhab-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/openhab-install.sh b/install/openhab-install.sh index f87848f3..d856c13f 100644 --- a/install/openhab-install.sh +++ b/install/openhab-install.sh @@ -22,9 +22,9 @@ $STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" msg_info "Installing Azul Zulu" -$STD apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 +wget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb -$STD apt-get install ./zulu-repo_1.0.0-3_all.deb +$STD dpkg -i zulu-repo_1.0.0-3_all.deb $STD apt-get update $STD apt-get -y install zulu11-jdk msg_ok "Installed Azul Zulu" From 7797589a7eacdde9ac49e35a32c66596cfc5e49d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 12:28:52 -0400 Subject: [PATCH 5054/6505] Update openhab-install.sh --- install/openhab-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/openhab-install.sh b/install/openhab-install.sh index d856c13f..1f52572a 100644 --- a/install/openhab-install.sh +++ b/install/openhab-install.sh @@ -33,11 +33,11 @@ msg_info "Installing openHAB" curl -fsSL "https://openhab.jfrog.io/artifactory/api/gpg/key/public" | gpg --dearmor >openhab.gpg mv openhab.gpg /usr/share/keyrings chmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg -sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main" > /etc/apt/sources.list.d/openhab.list' +echo "deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main" > /etc/apt/sources.list.d/openhab.list $STD apt update $STD apt-get -y install openhab systemctl daemon-reload -$STD systemctl enable --now openhab.service +systemctl enable -q --now openhab.service msg_ok "Installed openHAB" motd_ssh From 9e2a5129e835180a6d26348396a57f1c1bd5e910 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 8 Jul 2023 12:35:52 -0400 Subject: [PATCH 5055/6505] Update scrypted-install.sh apt-key is deprecated --- install/scrypted-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 78a4638d..e03f71e3 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -83,8 +83,8 @@ msg_ok "Installed Python3 Dependencies" read -r -p "Would you like to add Coral Edge TPU support? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Adding Coral Edge TPU Support" -$STD apt-key add <(curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg) -sh -c 'echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list' +wget -qO /etc/apt/trusted.gpg.d/coral-repo.asc "https://packages.cloud.google.com/apt/doc/apt-key.gpg" +echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" >/etc/apt/sources.list.d/coral-edgetpu.list $STD apt-get -y update $STD apt-get -y install libedgetpu1-std msg_ok "Coral Edge TPU Support Added" From c495bdd5c40bef5f7324c350cc714afc4865e666 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 9 Jul 2023 08:51:10 -0400 Subject: [PATCH 5056/6505] Update pimox-haos-vm.sh PVE 8 compatible --- vm/pimox-haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index fff2fa52..9fc13f2c 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -79,7 +79,7 @@ else exit fi function PVE_CHECK() { - if [ $(pveversion | grep -c "pve-manager/7\.[2-9]") -eq 0 ]; then + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 7.2 or higher" echo -e "Exiting..." From 3fc897f887989d3ac1cc2c710d584223deb4f513 Mon Sep 17 00:00:00 2001 From: slaclau <77557628+slaclau@users.noreply.github.com> Date: Mon, 10 Jul 2023 21:14:53 +0100 Subject: [PATCH 5057/6505] Update docker-install.sh (#1602) Add Portainer agent --- install/docker-install.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/install/docker-install.sh b/install/docker-install.sh index 8240ed8f..fb62433d 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -25,6 +25,7 @@ get_latest_release() { DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") +PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent") DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") msg_info "Installing Docker $DOCKER_LATEST_VERSION" @@ -58,6 +59,19 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" fi +read -r -p "Would you like to add the Portainer Agent? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION" + $STD docker run -d \ + -p 9001:9001 \ + --name portainer_agent \ + --restart=always + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /var/lib/docker/volumes:/var/lib/docker/volumes \ + portainer/agent + msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" +fi + read -r -p "Would you like to add Docker Compose? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" From 39ebf79a6dc2fbacef9e0113298c981b6694525b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 10 Jul 2023 16:18:49 -0400 Subject: [PATCH 5058/6505] Update docker-install.sh restrict the installation to either portainer-ce or the portainer-agent --- install/docker-install.sh | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/install/docker-install.sh b/install/docker-install.sh index fb62433d..810def23 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -48,7 +48,7 @@ read -r -p "Would you like to add Portainer? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null - $STD docker run -d \ + $STD docker run -d \ -p 8000:8000 \ -p 9000:9000 \ --name=portainer \ @@ -57,21 +57,20 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then -v portainer_data:/data \ portainer/portainer-ce:latest msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" +else + read -r -p "Would you like to add the Portainer Agent? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION" + $STD docker run -d \ + -p 9001:9001 \ + --name portainer_agent \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /var/lib/docker/volumes:/var/lib/docker/volumes \ + portainer/agent + msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" + fi fi - -read -r -p "Would you like to add the Portainer Agent? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION" - $STD docker run -d \ - -p 9001:9001 \ - --name portainer_agent \ - --restart=always - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /var/lib/docker/volumes:/var/lib/docker/volumes \ - portainer/agent - msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" -fi - read -r -p "Would you like to add Docker Compose? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" From 9189e12e48462093e08825d0c4df319fcce060ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 10 Jul 2023 19:17:30 -0400 Subject: [PATCH 5059/6505] Update docker-install.sh shfmt --- install/docker-install.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/install/docker-install.sh b/install/docker-install.sh index 810def23..37575f46 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 catch_errors @@ -32,20 +32,20 @@ msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json + VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + cd /usr/local/bin + curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 + chmod 755 /usr/local/bin/fuse-overlayfs + cd ~ + echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' >/etc/docker/daemon.json else -echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json + echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json fi $STD sh <(curl -sSL https://get.docker.com) msg_ok "Installed Docker $DOCKER_LATEST_VERSION" read -r -p "Would you like to add Portainer? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null $STD docker run -d \ @@ -59,7 +59,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" else read -r -p "Would you like to add the Portainer Agent? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION" $STD docker run -d \ -p 9001:9001 \ @@ -72,7 +72,7 @@ else fi fi read -r -p "Would you like to add Docker Compose? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins From 6501d0f43f81516ee78eb0a0af1ee9d3197f9dbb Mon Sep 17 00:00:00 2001 From: Victor Caldas Date: Tue, 11 Jul 2023 12:16:46 +0200 Subject: [PATCH 5060/6505] Make IP and NETMASK configurable (#1605) * Make IP and NETMASK configurable Users can now customize IP and Netmask of the router --- vm/openwrt.sh | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 3b9952af..66bccd19 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -204,6 +204,8 @@ function default_settings() { MAC=$GEN_MAC LAN_MAC=$GEN_MAC_LAN LAN_BRG="vmbr0" + LAN_IP_ADDR="192.168.1.1" + LAN_NETMASK="255.255.255.0" LAN_VLAN=",tag=999" MTU="" START_VM="yes" @@ -217,6 +219,8 @@ function default_settings() { echo -e "${DGN}Using LAN MAC Address: ${BGN}${LAN_MAC}${CL}" echo -e "${DGN}Using LAN Bridge: ${BGN}${LAN_BRG}${CL}" echo -e "${DGN}Using LAN VLAN: ${BGN}999${CL}" + echo -e "${DGN}Using LAN IP Address: ${BGN}${LAN_IP_ADDR}${CL}" + echo -e "${DGN}Using LAN NETMASK: ${BGN}${LAN_NETMASK}${CL}" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" echo -e "${BL}Creating a OpenWRT VM using the above default settings${CL}" @@ -287,6 +291,24 @@ function advanced_settings() { exit-script fi + if LAN_IP_ADDR=$(whiptail --inputbox "Set a router IP" 8 58 $LAN_IP_ADDR --title "LAN IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $LAN_IP_ADDR ]; then + LAN_IP_ADDR="192.168.1.1" + fi + echo -e "${DGN}Using LAN IP ADDRESS: ${BGN}$LAN_IP_ADDR${CL}" + else + exit-script + fi + + if LAN_NETMASK=$(whiptail --inputbox "Set a router netmmask" 8 58 $LAN_NETMASK --title "LAN NETMASK" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $LAN_NETMASK ]; then + LAN_NETMASK="255.255.255.0" + fi + echo -e "${DGN}Using LAN NETMASK: ${BGN}$LAN_NETMASK${CL}" + else + exit-script + fi + if MAC1=$(whiptail --inputbox "Set a WAN MAC Address" 8 58 $GEN_MAC --title "WAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then MAC="$GEN_MAC" @@ -469,8 +491,8 @@ send_line_to_vm "uci delete network.lan" send_line_to_vm "uci set network.lan=interface" send_line_to_vm "uci set network.lan.device=eth0" send_line_to_vm "uci set network.lan.proto=static" -send_line_to_vm "uci set network.lan.ipaddr=192.168.2.1" -send_line_to_vm "uci set network.lan.netmask=255.255.255.0" +send_line_to_vm "uci set network.lan.ipaddr=${LAN_IP_ADDR}" +send_line_to_vm "uci set network.lan.netmask=${LAN_NETMASK}" send_line_to_vm "uci set firewall.@zone[1].input='ACCEPT'" send_line_to_vm "uci set firewall.@zone[1].forward='ACCEPT'" send_line_to_vm "uci commit" From 231f02ca018188cbce70f667a6902bb1e0b6dcc3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jul 2023 17:38:19 -0400 Subject: [PATCH 5061/6505] Update build.func Code refactoring --- misc/build.func | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/misc/build.func b/misc/build.func index fced35ed..ee0ff47d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1,7 +1,7 @@ variables() { - NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. + NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. } # This function sets various color variables using ANSI escape codes for formatting text in the terminal. @@ -517,8 +517,8 @@ build_container() { LXC_CONFIG=/etc/pve/lxc/${CTID}.conf if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" && "$APP" != "Tdarr" ]]; then - cat <>$LXC_CONFIG + cat <>$LXC_CONFIG +# USB passthrough lxc.cgroup2.devices.allow: a lxc.cap.drop: lxc.cgroup2.devices.allow: c 188:* rwm @@ -529,14 +529,12 @@ lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create= lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file EOF - fi fi if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Tdarr" ]]; then + if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" ]]; then cat <>$LXC_CONFIG -lxc.cgroup2.devices.allow: a -lxc.cap.drop: +# VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm @@ -547,7 +545,7 @@ EOF fi fi -# This starts the container and executes -install.sh + # This starts the container and executes -install.sh msg_info "Starting LXC Container" pct start "$CTID" msg_ok "Started LXC Container" From 40725a0451cf92a1f982d186d2ccae570744aaae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jul 2023 17:41:23 -0400 Subject: [PATCH 5062/6505] Update scrypted-install.sh VAAPI hardware transcoding + USB passthrough --- install/scrypted-install.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index e03f71e3..b8707308 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" $STD apt-get -y install software-properties-common apt-utils $STD apt-get -y update $STD apt-get -y upgrade @@ -36,7 +36,19 @@ $STD apt-get -y install \ mc msg_ok "Installed Dependencies" -msg_info "Installing GStreamer" +if [[ "$CTTYPE" == "0" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + intel-opencl-icd + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi +msg_info "Installing GStreamer (Patience)" $STD apt-get -y install \ gstreamer1.0-tools \ libgstreamer1.0-dev \ @@ -92,7 +104,7 @@ fi msg_info "Installing Scrypted" $STD sudo -u root npx -y scrypted@latest install-server -msg_info "Installed Scrypted" +msg_ok "Installed Scrypted" msg_info "Creating Service" service_path="/etc/systemd/system/scrypted.service" From a1ccf3987eb38fbd8953249ca7321d12e64c7a3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jul 2023 17:42:12 -0400 Subject: [PATCH 5063/6505] Update scrypted.sh default Debian 12 --- ct/scrypted.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/scrypted.sh b/ct/scrypted.sh index 474f3af3..e3c15644 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -24,7 +24,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From e62958f1c52b246b71c7c5d567cba1a8730aa753 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jul 2023 17:48:21 -0400 Subject: [PATCH 5064/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90fc8ee7..a3ecfd9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-07-11 + +### Changed + +- **Scrypted LXC** + - Add VAAPI hardware transcoding + ## 2023-07-07 ### Changed From cf20993b8601904bf625ca851385f4f16e575af6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jul 2023 13:28:53 -0400 Subject: [PATCH 5065/6505] Update technitiumdns.sh fix unbound variable fixes https://github.com/tteck/Proxmox/issues/1608 --- ct/technitiumdns.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index c43d54e4..fa139dc1 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -56,13 +56,13 @@ if [[ ! -d /etc/dns ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then - wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb - dpkg -i packages-microsoft-prod.deb - apt-get update - apt-get install -y aspnetcore-runtime-7.0 + wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb + dpkg -i packages-microsoft-prod.deb &>/dev/null + apt-get update &>/dev/null + apt-get install -y aspnetcore-runtime-7.0 &>/dev/null rm packages-microsoft-prod.deb fi -$STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh) +bash <(curl -fsSL https://download.technitium.com/dns/install.sh) &>/dev/null msg_ok "Updated Successfully" exit } From 4f154a2bf12cc955dd313e61e7017aa6b4778a0e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jul 2023 01:11:03 -0400 Subject: [PATCH 5066/6505] Update keycloak-install.sh openjdk 17 closes https://github.com/tteck/Proxmox/issues/1618 --- install/keycloak-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh index ba9d4198..e5081b8e 100644 --- a/install/keycloak-install.sh +++ b/install/keycloak-install.sh @@ -17,7 +17,8 @@ msg_info "Installing Dependencies (Patience)" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y openjdk-11-jdk +$STD apt-get install -y ca-certificates-java +$STD apt-get install -y openjdk-17-jre-headless msg_ok "Installed Dependencies" RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From 96a40997ca4487ad2c13e763da9c3846502bf4ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 15 Jul 2023 01:11:37 -0400 Subject: [PATCH 5067/6505] Update keycloak.sh default Debian 12 --- ct/keycloak.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 83895ba7..5d9215b8 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 3d4804241ae6ee43c9fb2eacd5df54df0a7ae912 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 16 Jul 2023 16:38:53 -0400 Subject: [PATCH 5068/6505] Update pve8-upgrade.sh replace the yes/no box with a message box in the menus. --- misc/pve8-upgrade.sh | 69 +++++--------------------------------------- 1 file changed, 7 insertions(+), 62 deletions(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index a65cb302..53eff2cc 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -44,15 +44,10 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } - start_routines() { header_info - CHOICE=$(whiptail --title "PVE8 SOURCES" --menu "This will set the correct sources to update and install Proxmox VE 8.\n \nChange to Proxmox VE 8 sources?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) + whiptail --msgbox --title "PVE8 SOURCES" "This will set the correct sources to update and install Proxmox VE 8." 10 58 msg_info "Changing to Proxmox VE 8 Sources" cat </etc/apt/sources.list deb http://ftp.debian.org/debian bookworm main contrib @@ -60,91 +55,41 @@ deb http://ftp.debian.org/debian bookworm-updates main contrib deb http://security.debian.org/debian-security bookworm-security main contrib EOF msg_ok "Changed to Proxmox VE 8 Sources" - ;; - no) - msg_error "Selected no to Correcting Proxmox VE 8 Sources" - ;; - esac - CHOICE=$(whiptail --title "PVE8-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) + whiptail --msgbox --title "PVE8-ENTERPRISE" "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription." 10 58 msg_info "Disabling 'pve-enterprise' repository" cat </etc/apt/sources.list.d/pve-enterprise.list # deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise EOF msg_ok "Disabled 'pve-enterprise' repository" - ;; - no) - msg_error "Selected no to Disabling 'pve-enterprise' repository" - ;; - esac - CHOICE=$(whiptail --title "PVE8-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) + whiptail --msgbox --title "PVE8-NO-SUBSCRIPTION" "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE." 10 58 msg_info "Enabling 'pve-no-subscription' repository" cat </etc/apt/sources.list.d/pve-install-repo.list deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" - ;; - no) - msg_error "Selected no to Enabling 'pve-no-subscription' repository" - ;; - esac - CHOICE=$(whiptail --title "PVE8 CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) + whiptail --msgbox --title "PVE8 CEPH PACKAGE REPOSITORIES" "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories." 10 58 msg_info "Enabling 'ceph package repositories'" cat </etc/apt/sources.list.d/ceph.list # deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription EOF msg_ok "Enabled 'ceph package repositories'" - ;; - no) - msg_error "Selected no to Enabling 'ceph package repositories'" - ;; - esac - CHOICE=$(whiptail --title "PVE8 TEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) + whiptail --msgbox --title "PVE8 TEST" "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released (Disabled)." 10 58 msg_info "Adding 'pvetest' repository and set disabled" cat </etc/apt/sources.list.d/pvetest-for-beta.list # deb http://download.proxmox.com/debian/pve bookworm pvetest EOF msg_ok "Added 'pvetest' repository" - ;; - no) - msg_error "Selected no to Adding 'pvetest' repository" - ;; - esac - CHOICE=$(whiptail --title "PVE8 UPDATE" --menu "\nUpdate to Proxmox VE 8 now?" 11 58 2 \ - "yes" " " \ - "no" " " 3>&2 2>&1 1>&3) - case $CHOICE in - yes) + whiptail --msgbox --title "PVE8 UPDATE" "Updating to Proxmox VE 8" 10 58 msg_info "Updating to Proxmox VE 8 (Patience)" apt-get update DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y msg_ok "Updated to Proxmox VE 8" - ;; - no) - msg_error "Selected no to Updating to Proxmox VE 8" - ;; - esac CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE 8 now? (recommended)" 11 58 2 \ "yes" " " \ @@ -179,7 +124,7 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if ! pveversion | grep -Eq "pve-manager/(7\.4-(13|14|15|16))"; then +if ! pveversion | grep -Eq "pve-manager/(7\.4-(13|14|15|16|17))"; then header_info msg_error "This version of Proxmox Virtual Environment is not supported" echo -e " PVE Version 7.4-13 or higher is required." From 12dc7162a95023be71262f0c4b8ffe8221fee944 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 17:37:35 -0400 Subject: [PATCH 5069/6505] Create update-lxcs-cron.sh --- misc/update-lxcs-cron.sh | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 misc/update-lxcs-cron.sh diff --git a/misc/update-lxcs-cron.sh b/misc/update-lxcs-cron.sh new file mode 100644 index 00000000..f3d4a499 --- /dev/null +++ b/misc/update-lxcs-cron.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +echo "$(date)" +excluded_containers=("$@") +function update_container() { + container=$1 + name=$(pct exec "$container" hostname) + os=$(pct config "$container" | awk '/^ostype/ {print $2}') + if [[ "$os" == "ubuntu" || "$os" == "debian" ]]; then + disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') + read -ra disk_info_array <<< "$disk_info" + echo -e "\n[Info] Updating $container : $name - Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]" + else + echo -e "\n[Info] Updating $container : $name - [No disk info for ${os}]" + fi + case "$os" in + alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; + archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm";; + fedora|rocky|centos|alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; + ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; + esac +} + +for container in $(pct list | awk '{if(NR>1) print $1}'); do + excluded=false + for excluded_container in "${excluded_containers[@]}"; do + if [ "$container" == "$excluded_container" ]; then + excluded=true + break + fi + done + if [ "$excluded" == true ]; then + header_info + echo -e "[Info] Skipping $container" + sleep 1 + else + status=$(pct status $container) + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then + echo -e "[Info] Starting $container" + pct start $container + echo -e "[Info] Waiting For $container To Start" + sleep 5 + update_container $container + echo -e "[Info] Shutting down $container" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + update_container $container + fi + fi +done +wait + +echo -e "Finished, All Containers Updated. \n" From abee2dfb1b016564065383de0bbb1414454321e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 17:39:22 -0400 Subject: [PATCH 5070/6505] Create cron-update-lxcs.sh --- misc/cron-update-lxcs.sh | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 misc/cron-update-lxcs.sh diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh new file mode 100644 index 00000000..9fbdb54a --- /dev/null +++ b/misc/cron-update-lxcs.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +clear +cat <<"EOF" + __ __ __ __ __ _ ________ ______ + / / / /___ ____/ /___ _/ /____ / / | |/ / ____/____ / ____/________ ____ + / / / / __ \/ __ / __ `/ __/ _ \ / / | / / / ___/ / / / ___/ __ \/ __ \ +/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___(__ ) / /___/ / / /_/ / / / / +\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/____/ \____/_/ \____/_/ /_/ + /_/ + +EOF + +add() { +while true; do + read -p "This script will add a cron job to update all LXCs at midnight. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +(crontab -l 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed '$!N; /^\(.*\)\n\1$/!P; D' >>/var/log/update-lxcs-cron.log +clear +echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" +} + +remove() { + (crontab -l | grep -v "github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh") | crontab - + rm /var/log/update-lxcs-cron.log + echo "Removed Update LXCs Cron from Proxmox VE" +} + +# Define options for the whiptail menu +OPTIONS=(Add "Add Update LXCs Cron to Proxmox VE" \ + Remove "Remove Update LXCs Cron from Proxmox VE") + +# Show the whiptail menu and save the user's choice +CHOICE=$(whiptail --title "Update LXCs Cron for Proxmox VE" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +# Check the user's choice and perform the corresponding action +case $CHOICE in + "Add") + add + ;; + "Remove") + remove + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac From f0742abb2e6febe407015d90a9c63d8988765a2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 17:48:39 -0400 Subject: [PATCH 5071/6505] Update cron-update-lxcs.sh tweak --- misc/cron-update-lxcs.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 9fbdb54a..0a3c98b9 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -26,7 +26,8 @@ while true; do esac done -(crontab -l 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed '$!N; /^\(.*\)\n\1$/!P; D' >>/var/log/update-lxcs-cron.log +sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | crontab -u root -' >>/var/log/update-lxcs.log + clear echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" } From 71bece9d276d41ae8144cf7f29e8af6dea7f2058 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 17:58:06 -0400 Subject: [PATCH 5072/6505] Update cron-update-lxcs.sh tweak --- misc/cron-update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 0a3c98b9..f7f8377f 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -26,7 +26,7 @@ while true; do esac done -sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | crontab -u root -' >>/var/log/update-lxcs.log +sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | crontab -u root -' >>/var/log/update-lxcs-cron.log clear echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" From 86bb11f25f5001e94b2cd8a5cd7b589e0cec475c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 18:16:54 -0400 Subject: [PATCH 5073/6505] Update cron-update-lxcs.sh tweak --- misc/cron-update-lxcs.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index f7f8377f..63fb34bd 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -26,8 +26,7 @@ while true; do esac done -sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | crontab -u root -' >>/var/log/update-lxcs-cron.log - +sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh >>/var/log/update-lxcs-cron.log 2>&1)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | crontab -u root -' clear echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" } From 3d8d8fc867cac8c619638ad0e6b102653b0782c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 18:41:44 -0400 Subject: [PATCH 5074/6505] Update cron-update-lxcs.sh tweak --- misc/cron-update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 63fb34bd..9a1f3b7b 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -26,7 +26,7 @@ while true; do esac done -sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh >>/var/log/update-lxcs-cron.log 2>&1)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | crontab -u root -' +sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | sudo crontab -u root - >> /var/log/update-lxcs.log' clear echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" } From 054a4b89207aa88b6f9a40bfc9e73963d15161c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 18:50:19 -0400 Subject: [PATCH 5075/6505] Delete cron-update-lxcs.sh --- misc/cron-update-lxcs.sh | 60 ---------------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 misc/cron-update-lxcs.sh diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh deleted file mode 100644 index 9a1f3b7b..00000000 --- a/misc/cron-update-lxcs.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -clear -cat <<"EOF" - __ __ __ __ __ _ ________ ______ - / / / /___ ____/ /___ _/ /____ / / | |/ / ____/____ / ____/________ ____ - / / / / __ \/ __ / __ `/ __/ _ \ / / | / / / ___/ / / / ___/ __ \/ __ \ -/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___(__ ) / /___/ / / /_/ / / / / -\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/____/ \____/_/ \____/_/ /_/ - /_/ - -EOF - -add() { -while true; do - read -p "This script will add a cron job to update all LXCs at midnight. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\"") | sed "$!N; /^\(.*\)\n\1$/!P; D" | sudo crontab -u root - >> /var/log/update-lxcs.log' -clear -echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" -} - -remove() { - (crontab -l | grep -v "github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh") | crontab - - rm /var/log/update-lxcs-cron.log - echo "Removed Update LXCs Cron from Proxmox VE" -} - -# Define options for the whiptail menu -OPTIONS=(Add "Add Update LXCs Cron to Proxmox VE" \ - Remove "Remove Update LXCs Cron from Proxmox VE") - -# Show the whiptail menu and save the user's choice -CHOICE=$(whiptail --title "Update LXCs Cron for Proxmox VE" --menu "Select an option:" 10 58 2 \ - "${OPTIONS[@]}" 3>&1 1>&2 2>&3) - -# Check the user's choice and perform the corresponding action -case $CHOICE in - "Add") - add - ;; - "Remove") - remove - ;; - *) - echo "Exiting..." - exit 0 - ;; -esac From 891bf6fe9f801a45877f05a5c8f65a2c499dd5db Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 21:09:55 -0400 Subject: [PATCH 5076/6505] Create cron-update-lxcs.sh --- misc/cron-update-lxcs.sh | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 misc/cron-update-lxcs.sh diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh new file mode 100644 index 00000000..38ea40ca --- /dev/null +++ b/misc/cron-update-lxcs.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +clear +cat <<"EOF" + __ __ __ __ __ _ ________ ______ + / / / /___ ____/ /___ _/ /____ / / | |/ / ____/____ / ____/________ ____ + / / / / __ \/ __ / __ `/ __/ _ \ / / | / / / ___/ / / / ___/ __ \/ __ \ +/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___(__ ) / /___/ / / /_/ / / / / +\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/____/ \____/_/ \____/_/ /_/ + /_/ + +EOF + +add() { +while true; do + read -p "This script will add a cron job to update all LXCs at midnight. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -' +clear +echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" +} + +remove() { + (crontab -l | grep -v "github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh") | crontab - + rm /var/log/update-lxcs-cron.log + echo "Removed Update LXCs Cron from Proxmox VE" +} + +# Define options for the whiptail menu +OPTIONS=(Add "Add Update LXCs Cron to Proxmox VE" \ + Remove "Remove Update LXCs Cron from Proxmox VE") + +# Show the whiptail menu and save the user's choice +CHOICE=$(whiptail --title "Update LXCs Cron for Proxmox VE" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +# Check the user's choice and perform the corresponding action +case $CHOICE in + "Add") + add + ;; + "Remove") + remove + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac From ba966fdff88d15938920cc06441403fb420744f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 17 Jul 2023 22:03:18 -0400 Subject: [PATCH 5077/6505] Update cron-update-lxcs.sh This script is designed to schedule a cron job that updates all LXCs every Sunday at midnight. --- misc/cron-update-lxcs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 38ea40ca..1e9221a9 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -18,14 +18,14 @@ EOF add() { while true; do - read -p "This script will add a cron job to update all LXCs at midnight. Proceed(y/n)?" yn + read -p "This script will schedule a cron job that updates all LXCs every Sunday at midnight. Proceed(y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; *) echo "Please answer yes or no." ;; esac done -sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * * PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -' +sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -' clear echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" } From 3a920bbcebb759513ed96f8c3345e6494f2df13a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jul 2023 04:28:46 -0400 Subject: [PATCH 5078/6505] Update update-lxcs-cron.sh shfmt --- misc/update-lxcs-cron.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/update-lxcs-cron.sh b/misc/update-lxcs-cron.sh index f3d4a499..fc245a04 100644 --- a/misc/update-lxcs-cron.sh +++ b/misc/update-lxcs-cron.sh @@ -13,16 +13,16 @@ function update_container() { os=$(pct config "$container" | awk '/^ostype/ {print $2}') if [[ "$os" == "ubuntu" || "$os" == "debian" ]]; then disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') - read -ra disk_info_array <<< "$disk_info" + read -ra disk_info_array <<<"$disk_info" echo -e "\n[Info] Updating $container : $name - Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]" else echo -e "\n[Info] Updating $container : $name - [No disk info for ${os}]" fi case "$os" in - alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; - archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm";; - fedora|rocky|centos|alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; + alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; + archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; + fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; esac } From a5b70669c5181413001f38f0f63afa6e91eba8ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jul 2023 04:38:50 -0400 Subject: [PATCH 5079/6505] Update cron-update-lxcs.sh tweak --- misc/cron-update-lxcs.sh | 72 ++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 1e9221a9..0c471c2c 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -4,56 +4,56 @@ # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/cron-update-lxcs.sh)" clear cat <<"EOF" - __ __ __ __ __ _ ________ ______ - / / / /___ ____/ /___ _/ /____ / / | |/ / ____/____ / ____/________ ____ - / / / / __ \/ __ / __ `/ __/ _ \ / / | / / / ___/ / / / ___/ __ \/ __ \ -/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___(__ ) / /___/ / / /_/ / / / / -\____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/____/ \____/_/ \____/_/ /_/ - /_/ - + ______ __ __ __ __ __ _ ________ + / ____/________ ____ / / / /___ ____/ /___ _/ /____ / / | |/ / ____/____ + / / / ___/ __ \/ __ \ / / / / __ \/ __ / __ `/ __/ _ \ / / | / / / ___/ +/ /___/ / / /_/ / / / / / /_/ / /_/ / /_/ / /_/ / /_/ __/ / /___/ / /___(__ ) +\____/_/ \____/_/ /_/ \____/ .___/\__,_/\__,_/\__/\___/ /_____/_/|_\____/____/ + /_/ EOF +set -euo pipefail +shopt -s inherit_errexit nullglob + add() { -while true; do - read -p "This script will schedule a cron job that updates all LXCs every Sunday at midnight. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -' -clear -echo -e "\n To view Update LXCs Cron logs: cat /var/log/update-lxcs-cron.log" + while true; do + read -p "This script will add a crontab schedule that updates all LXCs every Sunday at midnight. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -' + clear + echo -e "\n To view Cron Update LXCs logs: cat /var/log/update-lxcs-cron.log" } remove() { (crontab -l | grep -v "github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh") | crontab - rm /var/log/update-lxcs-cron.log - echo "Removed Update LXCs Cron from Proxmox VE" + echo "Removed Crontab Schedule from Proxmox VE" } -# Define options for the whiptail menu -OPTIONS=(Add "Add Update LXCs Cron to Proxmox VE" \ - Remove "Remove Update LXCs Cron from Proxmox VE") +OPTIONS=(Add "Add Crontab Schedule" + Remove "Remove Crontab Schedule") -# Show the whiptail menu and save the user's choice -CHOICE=$(whiptail --title "Update LXCs Cron for Proxmox VE" --menu "Select an option:" 10 58 2 \ - "${OPTIONS[@]}" 3>&1 1>&2 2>&3) +CHOICE=$(whiptail --title "Cron Update LXCs" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) -# Check the user's choice and perform the corresponding action case $CHOICE in - "Add") - add - ;; - "Remove") - remove - ;; - *) - echo "Exiting..." - exit 0 - ;; +"Add") + add + ;; +"Remove") + remove + ;; +*) + echo "Exiting..." + exit 0 + ;; esac From 991b0c1c695ff8228f655cecd84714f8a315539c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jul 2023 04:54:43 -0400 Subject: [PATCH 5080/6505] Update cron-update-lxcs.sh tweak --- misc/cron-update-lxcs.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 0c471c2c..3cd4d9be 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -16,9 +16,6 @@ cat <<"EOF" /_/ EOF -set -euo pipefail -shopt -s inherit_errexit nullglob - add() { while true; do read -p "This script will add a crontab schedule that updates all LXCs every Sunday at midnight. Proceed(y/n)?" yn @@ -35,7 +32,7 @@ add() { remove() { (crontab -l | grep -v "github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh") | crontab - - rm /var/log/update-lxcs-cron.log + rm -rf /var/log/update-lxcs-cron.log echo "Removed Crontab Schedule from Proxmox VE" } From 5da67255d6eb99af601770f6903c2a83729fe2e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jul 2023 06:28:30 -0400 Subject: [PATCH 5081/6505] Update archlinux.sh update PVE_CHECK fixes https://github.com/tteck/Proxmox/issues/1625 --- ct/archlinux.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ct/archlinux.sh b/ct/archlinux.sh index 55067dab..f7b8e6cc 100644 --- a/ct/archlinux.sh +++ b/ct/archlinux.sh @@ -65,13 +65,13 @@ function msg_error() { } function PVE_CHECK() { -if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" - echo -e "Exiting..." - sleep 2 -exit -fi + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi } function ARCH_CHECK() { if [ "$(dpkg --print-architecture)" != "amd64" ]; then From c7e46be613b221b4908c39c44fe705b512340a8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 18 Jul 2023 11:07:03 -0400 Subject: [PATCH 5082/6505] Update CHANGELOG.md Proxmox VE Cron LXC Updater --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3ecfd9f..603b74ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-07-18 + +### Changed + +- **Proxmox VE Cron LXC Updater** + - NEW Script + ## 2023-07-11 ### Changed From 954beef6bf4615c50d40cd82e396506d23deee28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 20 Jul 2023 08:42:41 -0400 Subject: [PATCH 5083/6505] Update grocy-install.sh download from GitHub instead of an unreliable website (https://releases.grocy.info/latest ) fixes https://github.com/tteck/Proxmox/issues/1629 https://github.com/tteck/Proxmox/issues/1634 --- install/grocy-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 19146413..33f2e31d 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -34,8 +34,9 @@ $STD apt-get install -y php8.1-mbstring msg_ok "Installed PHP 8.1" msg_info "Installing grocy" -wget -q https://releases.grocy.info/latest -$STD unzip latest -d /var/www/html +latest=$(curl -s https://api.github.com/repos/grocy/grocy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q https://github.com/grocy/grocy/releases/download/v${latest}/grocy_${latest}.zip +$STD unzip grocy_${latest}.zip -d /var/www/html chown -R www-data:www-data /var/www/html cp /var/www/html/config-dist.php /var/www/html/data/config.php chmod +x /var/www/html/update.sh @@ -66,5 +67,5 @@ customize msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean -rm -rf /root/latest +rm -rf /root/grocy_${latest}.zip msg_ok "Cleaned" From 4e6e6f66b371e8dbc083220b9514695a9d902f56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jul 2023 13:45:33 -0400 Subject: [PATCH 5084/6505] Update update-lxcs-cron.sh non interactive --- misc/update-lxcs-cron.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs-cron.sh b/misc/update-lxcs-cron.sh index fc245a04..82184365 100644 --- a/misc/update-lxcs-cron.sh +++ b/misc/update-lxcs-cron.sh @@ -22,7 +22,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y" ;; esac } From 9948c7c410225283218e9191e5f64ecbbaeed5e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jul 2023 08:34:20 -0400 Subject: [PATCH 5085/6505] Update install.func tweak --- misc/install.func | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/misc/install.func b/misc/install.func index 9841ca1e..24fd8533 100644 --- a/misc/install.func +++ b/misc/install.func @@ -84,8 +84,7 @@ setting_up_container() { exit 1 fi rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED - systemctl stop systemd-networkd-wait-online.service - $STD systemctl disable systemd-networkd-wait-online.service + systemctl disable -q --now systemd-networkd-wait-online.service msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(hostname -I)" } From 7e6d35f0ce654521e8c36e4732aa42772b42cf8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jul 2023 19:47:24 -0400 Subject: [PATCH 5086/6505] Create zoraxy-install.sh --- install/zoraxy-install.sh | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 install/zoraxy-install.sh diff --git a/install/zoraxy-install.sh b/install/zoraxy-install.sh new file mode 100644 index 00000000..5e23e065 --- /dev/null +++ b/install/zoraxy-install.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Installing Golang" +set +o pipefail +RELEASE=$(curl -s https://go.dev/dl/ | grep -o "go.*\linux-amd64.tar.gz" | head -n 1) +wget -q https://golang.org/dl/$RELEASE +$STD tar -xzf $RELEASE -C /usr/local +$STD ln -s /usr/local/go/bin/go /usr/local/bin/go +set -o pipefail +msg_ok "Installed Golang" + +msg_info "Installing Zoraxy (Patience)" +$STD git clone https://github.com/tobychui/zoraxy /opt/zoraxy +cd /opt/zoraxy/src +$STD go mod tidy +$STD go build +msg_ok "Installed Zoraxy" + +msg_info "Creating Service" +cat </etc/systemd/system/zoraxy.service +[Unit] +Description=General purpose request proxy and forwarding tool +After=syslog.target network-online.target + +[Service] +ExecStart=/opt/zoraxy/src/./zoraxy +WorkingDirectory=/opt/zoraxy/src/ +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now zoraxy.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf $RELEASE +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From f79b88b8cfa6baaa1a0c8e434cf7f252953e7ec3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jul 2023 19:49:16 -0400 Subject: [PATCH 5087/6505] Create zoraxy.sh --- ct/zoraxy.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/zoraxy.sh diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh new file mode 100644 index 00000000..b0b0f358 --- /dev/null +++ b/ct/zoraxy.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ +/__ / ____ _________ __ ____ __ + / / / __ \/ ___/ __ `/ |/_/ / / / + / /__/ /_/ / / / /_/ /> /dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL} \n" From 2eaeac823f7390040282edcdf9f2418f575add04 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jul 2023 20:06:33 -0400 Subject: [PATCH 5088/6505] Update CHANGELOG.md Zoraxy LXC --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 603b74ca..f8db50c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-07-23 + +### Changed + +- **Zoraxy LXC** + - NEW Script + ## 2023-07-18 ### Changed From ede93f7c31ea396a69ee7e2a38357f8218ab3303 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jul 2023 13:21:05 -0400 Subject: [PATCH 5089/6505] Update zoraxy.sh tweak --- ct/zoraxy.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh index b0b0f358..354a4434 100644 --- a/ct/zoraxy.sh +++ b/ct/zoraxy.sh @@ -53,10 +53,7 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/zoraxy/src ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +msg_error "There is currently no update path available." exit } From 73bf8379be9210bfa477de00025eaf8c89c17e58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jul 2023 14:13:36 -0400 Subject: [PATCH 5090/6505] Create ombi-install.sh --- install/ombi-install.sh | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 install/ombi-install.sh diff --git a/install/ombi-install.sh b/install/ombi-install.sh new file mode 100644 index 00000000..99a0a554 --- /dev/null +++ b/install/ombi-install.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Ombi" +LATEST=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +# wget -q https://github.com/Ombi-app/Ombi/releases/download/${LATEST}/linux-x64.tar.gz +wget -q https://github.com/Ombi-app/Ombi/releases/download/v4.43.2/linux-x64.tar.gz +mkdir -p /opt/ombi +tar -xzf linux-x64.tar.gz -C /opt/ombi +msg_ok "Installed Ombi" + +msg_info "Creating Service" +cat </etc/systemd/system/ombi.service +[Unit] +Description=Ombi +After=syslog.target network-online.target + +[Service] +ExecStart=/opt/ombi/./Ombi +WorkingDirectory=/opt/ombi +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now ombi.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 19a060355b24d9f717987574663f9a725d0afd8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jul 2023 14:14:52 -0400 Subject: [PATCH 5091/6505] Create ombi.sh --- ct/ombi.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/ombi.sh diff --git a/ct/ombi.sh b/ct/ombi.sh new file mode 100644 index 00000000..156d7507 --- /dev/null +++ b/ct/ombi.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ _ + / __ \____ ___ / /_ (_) + / / / / __ `__ \/ __ \/ / +/ /_/ / / / / / / /_/ / / +\____/_/ /_/ /_/_.___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Ombi" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/ombi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" From 75635418d2393c7bad714f639cc42d699d3eb211 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 24 Jul 2023 14:23:24 -0400 Subject: [PATCH 5092/6505] Update CHANGELOG.md Ombi LXC --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8db50c7..9add39e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-07-24 + +### Changed + +- **Ombi LXC** + - NEW Script + ## 2023-07-23 ### Changed From dfb6ca572b7655ced6433e9e0d059537ab78c0e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jul 2023 06:57:00 -0400 Subject: [PATCH 5093/6505] Update mikrotik-routeros.sh version 7.10.2 PVE 8 --- vm/mikrotik-routeros.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 62930234..3db68ab8 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -62,9 +62,9 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if [ $(pveversion | grep "pve-manager/7" | wc -l) -ne 1 ]; then + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo "Requires PVE Version: 7.XX" + echo -e "Requires PVE Version 7.2 or higher" echo "Exiting..." sleep 3 exit @@ -234,7 +234,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Mikrotik RouterOS Disk Image" -URL=https://download.mikrotik.com/routeros/7.7/install-image-7.7.zip +URL=https://download.mikrotik.com/routeros/7.10.2/install-image-7.10.2.zip sleep 2 msg_ok "${CL}${BL}${URL}${CL}" From 14bf09bed3772e0f726eb252eb5182a71ac88a28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jul 2023 13:57:31 -0400 Subject: [PATCH 5094/6505] Update microcode.sh update AMD microcode to 3.20230719.1 --- misc/microcode.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 9c399dbc..fa427cb0 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -72,15 +72,15 @@ intel() { amd() { msg_info "Downloading the latest AMD Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230414.1_amd64.deb + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230719.1_amd64.deb msg_ok "Downloaded the latest AMD Processor Microcode Package" msg_info "Installing the AMD Processor Microcode (Patience)" - dpkg -i amd64-microcode_3.20230414.1_amd64.deb &>/dev/null + dpkg -i amd64-microcode_3.20230719.1_amd64.deb &>/dev/null msg_ok "Installed the AMD Processor Microcode" msg_info "Cleaning up" - rm amd64-microcode_3.20230414.1_amd64.deb + rm amd64-microcode_3.20230719.1_amd64.deb msg_ok "Cleaned" echo -e "\n To apply the changes, the system will need to be rebooted.\n" From 96d88e3b2e97538f8a7d6aafc82afa4718c5c0e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Jul 2023 20:38:05 -0400 Subject: [PATCH 5095/6505] Create alpine-install.sh --- install/alpine-install.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 install/alpine-install.sh diff --git a/install/alpine-install.sh b/install/alpine-install.sh new file mode 100644 index 00000000..72830ebb --- /dev/null +++ b/install/alpine-install.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +msg_ok "Installed Dependencies" + +motd_ssh +customize From 0aa9ffee332aaa081b26f4b5ac6cf1ad278fecf3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 12:08:09 -0400 Subject: [PATCH 5096/6505] Update filebrowser.sh New release issues, revert to 2.23.0 --- misc/filebrowser.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index 02545b48..81958d23 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -67,7 +67,8 @@ function msg_ok() { } msg_info "Installing ${APP}" -bash <(curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh) &>/dev/null +RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') +curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null From b3db1a3e1c123934bb341cebd79db90b3c9fcf0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 15:01:54 -0400 Subject: [PATCH 5097/6505] Create overseerr-install.sh --- install/overseerr-install.sh | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 install/overseerr-install.sh diff --git a/install/overseerr-install.sh b/install/overseerr-install.sh new file mode 100644 index 00000000..67c03a79 --- /dev/null +++ b/install/overseerr-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Yarn" +$STD npm install -g yarn +msg_ok "Installed Yarn" + +msg_info "Installing overseerr (Patience)" +git clone -q https://github.com/sct/overseerr.git /opt/overseerr +cd /opt/overseerr +$STD yarn install +$STD yarn build +msg_ok "Installed overseerr" + +msg_info "Creating Service" +cat </etc/systemd/system/overseerr.service +[Unit] +Description=Overseerr Service +After=network.target + +[Service] +Type=exec +WorkingDirectory=/opt/overseerr +ExecStart=/usr/bin/yarn start + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now overseerr.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 2f06e4df336bd9f2d23529c04ba43dd314943035 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 15:03:16 -0400 Subject: [PATCH 5098/6505] Create overseerr.sh --- ct/overseerr.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/overseerr.sh diff --git a/ct/overseerr.sh b/ct/overseerr.sh new file mode 100644 index 00000000..bec9f790 --- /dev/null +++ b/ct/overseerr.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ + / __ \_ _____ _____________ ___ __________ + / / / / | / / _ \/ ___/ ___/ _ \/ _ \/ ___/ ___/ +/ /_/ /| |/ / __/ / (__ ) __/ __/ / / / +\____/ |___/\___/_/ /____/\___/\___/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Overseerr" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/overseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5055${CL} \n" From 80e4f96d25d8779cf1a33a66c99651c54a3bdfe2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 15:33:33 -0400 Subject: [PATCH 5099/6505] Create jellyseerr-install.sh --- install/jellyseerr-install.sh | 65 +++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 install/jellyseerr-install.sh diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh new file mode 100644 index 00000000..e81c682e --- /dev/null +++ b/install/jellyseerr-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Yarn" +$STD npm install -g yarn +msg_ok "Installed Yarn" + +msg_info "Installing Jellyseerr (Patience)" +git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr +cd /opt/lellyseerr +$STD yarn install +$STD yarn build +msg_ok "Installed Jellyseerr" + +msg_info "Creating Service" +cat </etc/systemd/system/jellyseerr.service +[Unit] +Description=jellyseerr Service +After=network.target + +[Service] +Type=exec +WorkingDirectory=/opt/jellyseerr +ExecStart=/usr/bin/yarn start + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now jellyseerr.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From d041785691de2704fa9f4bdf5e689e7540094cfa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 15:34:40 -0400 Subject: [PATCH 5100/6505] Create jellyseerr.sh --- ct/jellyseerr.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/jellyseerr.sh diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh new file mode 100644 index 00000000..a05b82bf --- /dev/null +++ b/ct/jellyseerr.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ____ + / /__ / / /_ __________ ___ __________ + __ / / _ \/ / / / / / ___/ _ \/ _ \/ ___/ ___/ +/ /_/ / __/ / / /_/ (__ ) __/ __/ / / / +\____/\___/_/_/\__, /____/\___/\___/_/ /_/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Jellyseerr" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/overseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5055${CL} \n" From 671a99da40214ef9f9b26cc7d7c1e801c4b5a34e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 15:54:29 -0400 Subject: [PATCH 5101/6505] Update CHANGELOG.md Overseerr LXC Jellyseerr LXC --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9add39e1..a7418e19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-08-01 + +### Changed + +- **Overseerr LXC** + - NEW Script +- **Jellyseerr LXC** + - NEW Script + ## 2023-07-24 ### Changed From ed4b2ef2376ecdf8b7031ec63bc048ca20f928cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 16:30:07 -0400 Subject: [PATCH 5102/6505] Update jellyseerr.sh tweak --- ct/jellyseerr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index a05b82bf..9f8bdf70 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /opt/overseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -d /opt/jellyseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_error "There is currently no update path available." exit } From b0543ab8ae6f0482a86487692c10fc994aa6769f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 1 Aug 2023 16:31:06 -0400 Subject: [PATCH 5103/6505] Update overseerr-install.sh tweak --- install/overseerr-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/overseerr-install.sh b/install/overseerr-install.sh index 67c03a79..bb62febe 100644 --- a/install/overseerr-install.sh +++ b/install/overseerr-install.sh @@ -32,12 +32,12 @@ msg_info "Installing Yarn" $STD npm install -g yarn msg_ok "Installed Yarn" -msg_info "Installing overseerr (Patience)" +msg_info "Installing Overseerr (Patience)" git clone -q https://github.com/sct/overseerr.git /opt/overseerr cd /opt/overseerr $STD yarn install $STD yarn build -msg_ok "Installed overseerr" +msg_ok "Installed Overseerr" msg_info "Creating Service" cat </etc/systemd/system/overseerr.service From 9b9a56bf92890570bf39308a461662a03ba194b7 Mon Sep 17 00:00:00 2001 From: Jackson Holle Date: Wed, 2 Aug 2023 03:53:47 -0500 Subject: [PATCH 5104/6505] Update jellyseerr-install.sh (#1658) fix typo --- install/jellyseerr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index e81c682e..c5b5e646 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -34,7 +34,7 @@ msg_ok "Installed Yarn" msg_info "Installing Jellyseerr (Patience)" git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr -cd /opt/lellyseerr +cd /opt/jellyseerr $STD yarn install $STD yarn build msg_ok "Installed Jellyseerr" From 117023984e2073a07908c613240a3903afb1ec26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Aug 2023 20:10:12 -0400 Subject: [PATCH 5105/6505] Update homeassistant.sh New release issues, revert to 2.23.0 --- ct/homeassistant.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 759eca18..51a46299 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -100,7 +100,8 @@ function update_script() { if [ "$UPD" == "4" ]; then IP=$(hostname -I | awk '{print $1}') msg_info "Installing FileBrowser" - curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null + RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') + curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null From 34b16c861e8714ae6795bd8ac4b895506942a5cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 2 Aug 2023 20:11:58 -0400 Subject: [PATCH 5106/6505] Update homeassistant-core.sh New release issues, revert to 2.23.0 fixes https://github.com/tteck/Proxmox/issues/1660 --- ct/homeassistant-core.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 48065814..ed069489 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -107,7 +107,8 @@ function update_script() { fi if [ "$UPD" == "3" ]; then msg_info "Installing FileBrowser" - curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null + RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') + curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null From 79fb2c309811e3d4fdb25d0f9194e7d9176e4c55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Aug 2023 11:59:39 -0400 Subject: [PATCH 5107/6505] Update overseerr.sh add update path --- ct/overseerr.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ct/overseerr.sh b/ct/overseerr.sh index bec9f790..7efeab1b 100644 --- a/ct/overseerr.sh +++ b/ct/overseerr.sh @@ -53,7 +53,21 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/overseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +msg_info "Updating $APP" +systemctl stop overseerr +cd /opt/overseerr +output=$(git pull) +git pull &>/dev/null +if echo "$output" | grep -q "Already up to date." +then + msg_info " $APP is already up to date." + systemctl start overseerr + exit +fi +yarn install &>/dev/null +yarn build &>/dev/null +systemctl start overseerr +msg_ok "Updated $APP" exit } From 1ae673692e5eb6919a3be5f4ff364e2366d76764 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Aug 2023 12:03:02 -0400 Subject: [PATCH 5108/6505] Update jellyseerr.sh add update path --- ct/jellyseerr.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index 9f8bdf70..721d0ae9 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -53,7 +53,21 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/jellyseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +msg_info "Updating $APP" +systemctl stop jellyseerr +cd /opt/jellyseerr +output=$(git pull) +git pull &>/dev/null +if echo "$output" | grep -q "Already up to date." +then + msg_info " $APP is already up to date." + systemctl start jellyseerr + exit +fi +yarn install &>/dev/null +yarn build &>/dev/null +systemctl start jellyseerr +msg_ok "Updated $APP" exit } From 26bbc9a18d4fd09531a50775879055bcfdb16a71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Aug 2023 12:07:15 -0400 Subject: [PATCH 5109/6505] Update jellyseerr.sh tweak --- ct/jellyseerr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index 721d0ae9..ef320216 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -60,7 +60,7 @@ output=$(git pull) git pull &>/dev/null if echo "$output" | grep -q "Already up to date." then - msg_info " $APP is already up to date." + msg_ok " $APP is already up to date." systemctl start jellyseerr exit fi From 0d9316ae06662d5d58ad66d5392ef20974a7cd42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Aug 2023 12:07:46 -0400 Subject: [PATCH 5110/6505] Update overseerr.sh tweak --- ct/overseerr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/overseerr.sh b/ct/overseerr.sh index 7efeab1b..8f3ce0a1 100644 --- a/ct/overseerr.sh +++ b/ct/overseerr.sh @@ -60,7 +60,7 @@ output=$(git pull) git pull &>/dev/null if echo "$output" | grep -q "Already up to date." then - msg_info " $APP is already up to date." + msg_ok " $APP is already up to date." systemctl start overseerr exit fi From cf6d9bf20078b836da7ff14ee168dc3e1761b193 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 3 Aug 2023 19:54:48 -0400 Subject: [PATCH 5111/6505] Update jellyseerr-install.sh add `jellyseerr.conf` --- install/jellyseerr-install.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index c5b5e646..15711368 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -37,6 +37,12 @@ git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr cd /opt/jellyseerr $STD yarn install $STD yarn build +mkdir -p /etc/jellyseerr/ +cat </etc/jellyseerr/jellyseerr.conf +PORT=5055 +HOST=0.0.0.0 +# JELLYFIN_TYPE=emby +EOF msg_ok "Installed Jellyseerr" msg_info "Creating Service" @@ -46,6 +52,8 @@ Description=jellyseerr Service After=network.target [Service] +EnvironmentFile=/etc/jellyseerr/jellyseerr.conf +Environment=NODE_ENV=production Type=exec WorkingDirectory=/opt/jellyseerr ExecStart=/usr/bin/yarn start From 2408e02425f827b02f2b80619cf23a53b729e153 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 4 Aug 2023 13:08:59 -0400 Subject: [PATCH 5112/6505] Update emqx.sh default Debian 12 --- ct/emqx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/emqx.sh b/ct/emqx.sh index fb198fce..ccfbd747 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 4da3ef9bfda42be39d7e49f0c4d0e56272faabb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 5 Aug 2023 21:17:09 -0400 Subject: [PATCH 5113/6505] Update jellyseerr-install.sh tweak --- install/jellyseerr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 15711368..06803fc0 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -40,7 +40,7 @@ $STD yarn build mkdir -p /etc/jellyseerr/ cat </etc/jellyseerr/jellyseerr.conf PORT=5055 -HOST=0.0.0.0 +# HOST=0.0.0.0 # JELLYFIN_TYPE=emby EOF msg_ok "Installed Jellyseerr" From 80ad523a248138b3067b78bf6b8a57eb4c41ba21 Mon Sep 17 00:00:00 2001 From: spooknik <40317809+spooknik@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:52:42 +0200 Subject: [PATCH 5114/6505] Auto Rebuilt (#1670) Create a systemd service that triggers the rebuilding of Dashy whenever changes are made to the configuration file. --- install/dashy-install.sh | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 44d85f86..ef8106be 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -42,7 +42,7 @@ export NODE_OPTIONS=--max-old-space-size=1000 $STD yarn build msg_ok "Installed Dashy" -msg_info "Creating Service" +msg_info "Creating Services" cat </etc/systemd/system/dashy.service [Unit] Description=dashy @@ -56,7 +56,30 @@ WantedBy=multi-user.target EOF $STD systemctl enable dashy systemctl start dashy -msg_ok "Created Service" + +cat > /etc/systemd/system/dashy-rebuild.service << EOF +[Unit] +Description=Rebuild Dashy on Config Changes + +[Service] +Type=oneshot +ExecStart=/usr/bin/yarn --cwd=/dashy build +EOF + +cat > /etc/systemd/system/dashy-rebuild.path << EOF +[Unit] +Description=Monitor Dashy Config for Changes + +[Path] +PathChanged=/dashy/public/conf.yml + +[Install] +WantedBy=multi-user.target +EOF + +$STD systemctl enable dashy-rebuild +systemctl start dashy-rebuild +msg_ok "Created Services" motd_ssh customize From 7add9d891d36cadc68e4633298468e68aefd06a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 7 Aug 2023 08:56:46 -0400 Subject: [PATCH 5115/6505] Update dashy-install.sh tweak --- install/dashy-install.sh | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index ef8106be..e7de0462 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -54,10 +54,8 @@ ExecStart=/usr/bin/yarn start [Install] WantedBy=multi-user.target EOF -$STD systemctl enable dashy -systemctl start dashy -cat > /etc/systemd/system/dashy-rebuild.service << EOF +cat </etc/systemd/system/dashy-rebuild.service [Unit] Description=Rebuild Dashy on Config Changes @@ -66,7 +64,7 @@ Type=oneshot ExecStart=/usr/bin/yarn --cwd=/dashy build EOF -cat > /etc/systemd/system/dashy-rebuild.path << EOF +cat </etc/systemd/system/dashy-rebuild.path [Unit] Description=Monitor Dashy Config for Changes @@ -76,9 +74,8 @@ PathChanged=/dashy/public/conf.yml [Install] WantedBy=multi-user.target EOF - -$STD systemctl enable dashy-rebuild -systemctl start dashy-rebuild +systemctl -q --now enable dashy +systemctl -q --now enable dashy-rebuild msg_ok "Created Services" motd_ssh From f796767e06dbe7d89a6d3a877dab106fb27dc238 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 7 Aug 2023 14:00:26 -0400 Subject: [PATCH 5116/6505] Update mqtt-install.sh create `/etc/mosquitto/conf.d/default.conf` --- install/mqtt-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 9534db5a..5f66caa7 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -22,6 +22,12 @@ msg_ok "Installed Dependencies" msg_info "Installing Mosquitto MQTT Broker" $STD apt-get -y install mosquitto $STD apt-get -y install mosquitto-clients +cat </etc/mosquitto/conf.d/default.conf +allow_anonymous false +persistence true +password_file /etc/mosquitto/passwd +listener 1883 +EOF msg_ok "Installed Mosquitto MQTT Broker" motd_ssh From daeefafdf9896fb3544cd4a1667a822ef69e6e04 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 7 Aug 2023 14:42:51 -0400 Subject: [PATCH 5117/6505] Update mariadb-install.sh tweak --- install/mariadb-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index e7af61e1..ef154ed0 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -21,6 +21,8 @@ msg_ok "Installed Dependencies" msg_info "Installing MariaDB" $STD apt-get install -y mariadb-server +sed -i 's/^# *\(port *=.*\)/\1/' /etc/mysql/my.cnf +sed -i 's/^bind-address/#bind-address/g' /etc/mysql/mariadb.conf.d/50-server.cnf msg_ok "Installed MariaDB" read -r -p "Would you like to add Adminer? " prompt From 9cd58e5589485c90613e460afe9eaef13d92d51d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 05:18:30 -0400 Subject: [PATCH 5118/6505] Update omada-install.sh get the latest version --- install/omada-install.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index dc05b709..d6029734 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -36,16 +36,19 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" -msg_info "Installing Omada Controller v5.9.31" -wget -qL https://static.tp-link.com/upload/software/2023/202303/20230321/Omada_SDN_Controller_v5.9.31_Linux_x64.deb -$STD dpkg -i Omada_SDN_Controller_v5.9.31_Linux_x64.deb -msg_ok "Installed Omada Controller" +latesturl=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) +latestversion=$(basename "$latesturl" | sed -e 's/.*ller_v//;s/_Li.*//') + +msg_info "Installing Omada Controller v${latestversion}" +wget -qL ${latesturl} +$STD dpkg -i Omada_SDN_Controller_v${latestversion}_Linux_x64.deb +msg_ok "Installed Omada Controller v${latestversion}" motd_ssh customize msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_v5.9.31_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +rm -rf Omada_SDN_Controller_v${latestversion}_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 582088fc90b41476128d94035cba857429ab3e24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 05:20:42 -0400 Subject: [PATCH 5119/6505] Update omada.sh add update path --- ct/omada.sh | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ct/omada.sh b/ct/omada.sh index f8d485aa..0096f435 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -53,11 +53,22 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Successfully" +latesturl=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) +latestversion=$(basename "$latesturl" | sed -e 's/.*ller_v//;s/_Li.*//') +installed_version=$(dpkg -l | grep omada | awk '{print $3}') + +if [ "$installed_version" = "$latestversion" ]; then + echo "Installed version ($installed_version) is the same as the latest version ($latestversion)." + echo "Omada is already up to date" + exit +else + echo -e "Updating Omada Controller to v${latestversion}" + wget -qL ${latesturl} + dpkg -i Omada_SDN_Controller_v${latestversion}_Linux_x64.deb + rm -rf Omada_SDN_Controller_v${latestversion}_Linux_x64.deb + echo -e "Updated Omada Controller to v${latestversion}" exit +fi } start From 60ebfe406e9e0cedf410fbfe125afddff0b3111c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 07:45:13 -0400 Subject: [PATCH 5120/6505] Update omada-install.sh tweak --- install/omada-install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index d6029734..03e2b418 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -36,19 +36,19 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" -latesturl=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) -latestversion=$(basename "$latesturl" | sed -e 's/.*ller_v//;s/_Li.*//') +latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) +latest_version=$(basename "$latest_url" | sed -e 's/.*ller_//;s/_Li.*//') -msg_info "Installing Omada Controller v${latestversion}" -wget -qL ${latesturl} -$STD dpkg -i Omada_SDN_Controller_v${latestversion}_Linux_x64.deb -msg_ok "Installed Omada Controller v${latestversion}" +msg_info "Installing Omada Controller ${latest_version}" +wget -qL ${latest_url} +$STD dpkg -i Omada_SDN_Controller_${latest_version}_Linux_x64.deb +msg_ok "Installed Omada Controller ${latest_version}" motd_ssh customize msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_v${latestversion}_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +rm -rf Omada_SDN_Controller_${latest_version}_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From b1f28071ef17d02a729895a7ae17ddb7dd9d90b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 07:48:14 -0400 Subject: [PATCH 5121/6505] Update omada.sh tweak --- ct/omada.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ct/omada.sh b/ct/omada.sh index 0096f435..a4312278 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -53,20 +53,20 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -latesturl=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) -latestversion=$(basename "$latesturl" | sed -e 's/.*ller_v//;s/_Li.*//') +latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) +latest_version=$(basename "$latest_url" | sed -e 's/.*ller_//;s/_Li.*//') installed_version=$(dpkg -l | grep omada | awk '{print $3}') -if [ "$installed_version" = "$latestversion" ]; then - echo "Installed version ($installed_version) is the same as the latest version ($latestversion)." - echo "Omada is already up to date" +if [ "v${installed_version}" = "${latest_version}" ]; then + echo "Installed version (v${installed_version}) is the same as the latest version (${latest_version})." + echo "Omada Controller is already up to date" exit else - echo -e "Updating Omada Controller to v${latestversion}" - wget -qL ${latesturl} - dpkg -i Omada_SDN_Controller_v${latestversion}_Linux_x64.deb - rm -rf Omada_SDN_Controller_v${latestversion}_Linux_x64.deb - echo -e "Updated Omada Controller to v${latestversion}" + echo -e "Updating Omada Controller to ${latest_version}" + wget -qL ${latest_url} + dpkg -i Omada_SDN_Controller_${latest_version}_Linux_x64.deb + rm -rf Omada_SDN_Controller_${latest_version}_Linux_x64.deb + echo -e "Updated Omada Controller to ${latest_version}" exit fi } From 45455cb169d4a2935b02b8e06bf875742b146c3e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 08:01:15 -0400 Subject: [PATCH 5122/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7418e19..2df7ef2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-08-09 + +### Changed + +- **Omada Controller LXC** + - Update via script + ## 2023-08-01 ### Changed From 4613129d28d263e6d8ebaa7a13454c1046573250 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 12:02:56 -0400 Subject: [PATCH 5123/6505] Update omada.sh tweak --- ct/omada.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ct/omada.sh b/ct/omada.sh index a4312278..31d1e3dd 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -54,7 +54,11 @@ function update_script() { header_info if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; fi latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) -latest_version=$(basename "$latest_url" | sed -e 's/.*ller_//;s/_Li.*//') +latest_version=$(basename "${latest_url}" | sed -e 's/.*ller_//;s/_Li.*//') +if [ -z "${latest_version}" ]; then + echo "It seems that the server (tp-link.com) might be down. Please try again at a later time." + exit +fi installed_version=$(dpkg -l | grep omada | awk '{print $3}') if [ "v${installed_version}" = "${latest_version}" ]; then From 6112e4ae33841f42bbbe90c3f8e2cda8763de1c3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 12:26:07 -0400 Subject: [PATCH 5124/6505] Update omada.sh more tweaks --- ct/omada.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/omada.sh b/ct/omada.sh index 31d1e3dd..3d41116a 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -56,14 +56,15 @@ if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) latest_version=$(basename "${latest_url}" | sed -e 's/.*ller_//;s/_Li.*//') if [ -z "${latest_version}" ]; then - echo "It seems that the server (tp-link.com) might be down. Please try again at a later time." + msg_error "It seems that the server (tp-link.com) might be down. Please try again at a later time." exit fi installed_version=$(dpkg -l | grep omada | awk '{print $3}') if [ "v${installed_version}" = "${latest_version}" ]; then - echo "Installed version (v${installed_version}) is the same as the latest version (${latest_version})." - echo "Omada Controller is already up to date" + msg_info "Installed version (v${installed_version}) is the same as the latest version (${latest_version})" + sleep 2 + msg_ok "Omada Controller is already up to date" exit else echo -e "Updating Omada Controller to ${latest_version}" From 143f1f8518699a62aceadc9be74ebc1aacf84e03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 20:08:56 -0400 Subject: [PATCH 5125/6505] Update microcode.sh update Intel microcode --- misc/microcode.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index fa427cb0..05ae3f7b 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -56,15 +56,15 @@ intel() { msg_ok "Installed iucode-tool" msg_info "Downloading the latest Intel Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230512.1_amd64.deb + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230808.1_amd64.deb msg_ok "Downloaded the latest Intel Processor Microcode Package" msg_info "Installing the Intel Processor Microcode (Patience)" - dpkg -i intel-microcode_3.20230512.1_amd64.deb &>/dev/null + dpkg -i intel-microcode_3.20230808.1_amd64.deb &>/dev/null msg_ok "Installed the Intel Processor Microcode" msg_info "Cleaning up" - rm intel-microcode_3.20230512.1_amd64.deb + rm intel-microcode_3.20230808.1_amd64.deb msg_ok "Cleaned" echo -e "\n To apply the changes, the system will need to be rebooted.\n" From 06229bedb6ab86e25c4c85c00fbc78d528cb4521 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 9 Aug 2023 20:16:36 -0400 Subject: [PATCH 5126/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2df7ef2c..4e3e0c9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - **Omada Controller LXC** - Update via script +- **Proxmox VE Processor Microcode** + - [Intel microcode-20230808 Release](https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/tag/microcode-20230808) ## 2023-08-01 From a4c45beffb404f24bb18ca286fe35e6c7952feba Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Aug 2023 06:11:06 -0400 Subject: [PATCH 5127/6505] Update microcode.sh check for Intel iucode-tool --- misc/microcode.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 05ae3f7b..3227ce77 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -51,9 +51,13 @@ msg_error() { } intel() { - msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" - apt-get install -y iucode-tool &>/dev/null - msg_ok "Installed iucode-tool" + if ! apt -qq list iucode-tool >/dev/null 2>&1; then + msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" + apt-get install -y iucode-tool &>/dev/null + msg_ok "Installed iucode-tool" + else + msg_ok "Intel iucode-tool is already installed" + fi msg_info "Downloading the latest Intel Processor Microcode Package for Linux" wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230808.1_amd64.deb From 0d6aac12018539798ac7c98df750f58e874655ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Aug 2023 06:51:20 -0400 Subject: [PATCH 5128/6505] Update microcode.sh Code refactoring --- misc/microcode.sh | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 3227ce77..4c8cd4a3 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -4,15 +4,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -clear -while true; do - read -p "Install the latest Processor Microcode (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done +function header_info { clear cat <<"EOF" ____ __ ____ __ @@ -22,6 +14,7 @@ cat <<"EOF" /_/ /_/ \____/\___/\___/____/____/\____/_/ /_/ /_/_/\___/_/ \____/\___/\____/\__,_/\___/ EOF +} RD=$(echo "\033[01;31m") YW=$(echo "\033[33m") @@ -50,6 +43,23 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +header_info +current_microcode=$(dmesg | grep -o 'microcode updated early to revision [^,]*, date = [0-9\-]*') +while true; do + if [ -z "${current_microcode}" ]; then + msg_error "Microcode update information not found." + else + msg_ok "Current ${current_microcode}" + fi + read -p "Install the latest Processor Microcode (y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +header_info + intel() { if ! apt -qq list iucode-tool >/dev/null 2>&1; then msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" From 315312c051835f1e426a9a36c7c3751e217d92a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Aug 2023 11:04:33 -0400 Subject: [PATCH 5129/6505] Update audiobookshelf.sh tweak --- ct/audiobookshelf.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 8c1de6f2..4df74961 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -52,11 +52,8 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +if [[ ! -f /etc/apt/trusted.gpg.d/audiobookshelf-ppa.asc ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +echo "This application receives updates through the APT package manager." exit } From e6ce819428dd3886487e6c638648b4a2fca4c9fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Aug 2023 17:33:46 -0400 Subject: [PATCH 5130/6505] Update microcode.sh update AMD microcode --- misc/microcode.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 4c8cd4a3..ad2cdb4e 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -86,15 +86,15 @@ intel() { amd() { msg_info "Downloading the latest AMD Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230719.1_amd64.deb + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230808.1.1_amd64.deb msg_ok "Downloaded the latest AMD Processor Microcode Package" msg_info "Installing the AMD Processor Microcode (Patience)" - dpkg -i amd64-microcode_3.20230719.1_amd64.deb &>/dev/null + dpkg -i amd64-microcode_3.20230808.1.1_amd64.deb &>/dev/null msg_ok "Installed the AMD Processor Microcode" msg_info "Cleaning up" - rm amd64-microcode_3.20230719.1_amd64.deb + rm amd64-microcode_3.20230808.1.1_amd64.deb msg_ok "Cleaned" echo -e "\n To apply the changes, the system will need to be rebooted.\n" From d226b7a2f368abc550127038e8b2928c8187c576 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 10 Aug 2023 17:38:26 -0400 Subject: [PATCH 5131/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e3e0c9b..98ce5cd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-08-10 + +### Changed + +- **Proxmox VE Processor Microcode** + - AMD microcode-20230808 Release + ## 2023-08-09 ### Changed From f38378b79ea9c26cdd6f717a5a2345d25221c3b8 Mon Sep 17 00:00:00 2001 From: iveilleux <57638344+iveilleux@users.noreply.github.com> Date: Fri, 11 Aug 2023 08:22:01 -0400 Subject: [PATCH 5132/6505] Update microcode.sh (#1679) Verify iucode-tool is installed --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index ad2cdb4e..7eceee7d 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -61,7 +61,7 @@ done header_info intel() { - if ! apt -qq list iucode-tool >/dev/null 2>&1; then + if ! apt -qq list --installed iucode-tool >/dev/null 2>&1; then msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" apt-get install -y iucode-tool &>/dev/null msg_ok "Installed iucode-tool" From d9147b073bd118ae403e9b1187fcefbd4d33328e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Aug 2023 11:46:54 -0400 Subject: [PATCH 5133/6505] Update microcode.sh Code refactoring --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 7eceee7d..e0434ea1 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -61,7 +61,7 @@ done header_info intel() { - if ! apt -qq list --installed iucode-tool >/dev/null 2>&1; then + if ! dpkg -s iucode-tool >/dev/null 2>&1; then msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" apt-get install -y iucode-tool &>/dev/null msg_ok "Installed iucode-tool" From dd495b66095e75c4b6d8f7cbb67f836c82859629 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Aug 2023 21:17:51 -0400 Subject: [PATCH 5134/6505] Update microcode.sh test --- misc/microcode.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index e0434ea1..06f7e381 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -25,8 +25,8 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -euo pipefail -shopt -s inherit_errexit nullglob +#set -euo pipefail +#shopt -s inherit_errexit nullglob msg_info() { local msg="$1" From 4fb6313bec93a926f5644fe7d31aacffd764c0e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 11 Aug 2023 21:38:41 -0400 Subject: [PATCH 5135/6505] Update microcode.sh tweak fixes https://github.com/tteck/Proxmox/issues/1680 --- misc/microcode.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 06f7e381..6b3bb5fc 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -25,9 +25,6 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -#set -euo pipefail -#shopt -s inherit_errexit nullglob - msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." From 0ea26d6caec621761b0c1f72d0d9097d1243e1e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Aug 2023 05:25:12 -0400 Subject: [PATCH 5136/6505] Update homeassistant-core.sh update python message --- ct/homeassistant-core.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index ed069489..024b0be5 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -76,7 +76,7 @@ function update_script() { echo -e "${GN}Updating to Stable Version${CL}" BR="" fi - if [[ "$PY" == "python3.9" ]]; then echo -e "⚠️ Python 3.9 is deprecated and will be removed in Home Assistant 2023.2"; fi + if [[ "$PY" == "python3.10" ]]; then echo -e "⚠️ Home Assistant now requires Python 3.11 to run."; fi msg_info "Stopping Home Assistant" systemctl stop homeassistant From f79d31fdcdc50136faddd51c953747f5a4a9289d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Aug 2023 11:56:48 -0400 Subject: [PATCH 5137/6505] Update photoprism.sh tweak --- ct/photoprism.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 0fffa7f2..ae29e486 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -62,6 +62,7 @@ function update_script() { msg_ok "Stopped PhotoPrism" msg_info "Cloning PhotoPrism" + cd ~ git clone https://github.com/photoprism/photoprism.git &>/dev/null cd photoprism git checkout release &>/dev/null From 59b4e28413e638ae57782d6f5c502f7bda8ab726 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Aug 2023 15:12:51 -0400 Subject: [PATCH 5138/6505] Update alpine-install.func add `sysctl -p` command fixes https://github.com/tteck/Proxmox/issues/1688 --- misc/alpine-install.func | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 96d1f849..d1eb439d 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -117,9 +117,10 @@ motd_ssh() { } customize() { + $STD sysctl -p if [[ "$PASSWORD" == "" ]]; then msg_info "Customizing Container" bash -c "passwd -d root" >/dev/null 2>&1 msg_ok "Customized Container" fi -} \ No newline at end of file +} From 88092fa6132dba4d2b94db826220437fb9cc8b2a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 14 Aug 2023 21:23:58 -0400 Subject: [PATCH 5139/6505] Update alpine-install.func tweak disable_ipv6 --- misc/alpine-install.func | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index d1eb439d..3fd39278 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -22,8 +22,9 @@ verb_ip6() { else STD="silent"; fi silent() { "$@" >/dev/null 2>&1; } if [ "$DISABLEIPV6" == "yes" ]; then + $STD sysctl -w net.ipv6.conf.all.disable_ipv6=1 echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf - $STD sysctl -p + $STD rc-update add sysctl default fi } @@ -117,7 +118,6 @@ motd_ssh() { } customize() { - $STD sysctl -p if [[ "$PASSWORD" == "" ]]; then msg_info "Customizing Container" bash -c "passwd -d root" >/dev/null 2>&1 From 276252772e3de4069bb395ef195087c5e23c2a32 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 15 Aug 2023 15:16:20 -0400 Subject: [PATCH 5140/6505] Update mikrotik-routeros.sh version 7.11 --- vm/mikrotik-routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 3db68ab8..39a07919 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -234,7 +234,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Mikrotik RouterOS Disk Image" -URL=https://download.mikrotik.com/routeros/7.10.2/install-image-7.10.2.zip +URL=https://download.mikrotik.com/routeros/7.11/install-image-7.11.zip sleep 2 msg_ok "${CL}${BL}${URL}${CL}" From c1011b5a9337b795ef37ab138ea1982eb7e4ef1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Aug 2023 06:26:18 -0400 Subject: [PATCH 5141/6505] Update heimdalldashboard.sh default Debian 12 --- ct/heimdalldashboard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 1a2b701a..8dd31293 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 783c0c37f4533569e3376ae150418a0b74a5d0ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Aug 2023 08:56:17 -0400 Subject: [PATCH 5142/6505] Create homarr-install.sh --- install/homarr-install.sh | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 install/homarr-install.sh diff --git a/install/homarr-install.sh b/install/homarr-install.sh new file mode 100644 index 00000000..54725ee5 --- /dev/null +++ b/install/homarr-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Yarn" +$STD npm install -g yarn +msg_ok "Installed Yarn" + +msg_info "Installing Homarr (Patience)" +git clone -q https://github.com/ajnart/homarr.git /opt/homarr +cd /opt/homarr +$STD yarn install +$STD yarn build +msg_ok "Installed Homarr" + +msg_info "Creating Service" +cat </etc/systemd/system/homarr.service +[Unit] +Description=Homarr Service +After=network.target + +[Service] +Type=exec +WorkingDirectory=/opt/homarr +ExecStart=/usr/bin/yarn start + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now homarr.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 9dbd0a9f40d48c0ab49737e0bf6c2883e7e4b510 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Aug 2023 08:57:18 -0400 Subject: [PATCH 5143/6505] Create homarr.sh --- ct/homarr.sh | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 ct/homarr.sh diff --git a/ct/homarr.sh b/ct/homarr.sh new file mode 100644 index 00000000..dd06a8ff --- /dev/null +++ b/ct/homarr.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ + / / / /___ ____ ___ ____ ___________ + / /_/ / __ \/ __ `__ \/ __ `/ ___/ ___/ + / __ / /_/ / / / / / / /_/ / / / / +/_/ /_/\____/_/ /_/ /_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Homarr" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/homarr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +systemctl stop homarr +cd /opt/homarr +output=$(git pull) +git pull &>/dev/null +if echo "$output" | grep -q "Already up to date." +then + msg_ok " $APP is already up to date." + systemctl start homarr + exit +fi +yarn install &>/dev/null +yarn build &>/dev/null +systemctl start homarr +msg_ok "Updated $APP" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 28205fbd03a4eb26d7866d6ca71712cd6cc21a1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Aug 2023 09:11:06 -0400 Subject: [PATCH 5144/6505] Update CHANGELOG.md Homarr LXC --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98ce5cd5..1d153f81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-08-16 + +### Changed + +- **Homarr LXC** + - NEW Script + ## 2023-08-10 ### Changed From 25c18fbf9e6e2cc2d9c20addd7ba658cd352e2a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 16 Aug 2023 10:21:13 -0400 Subject: [PATCH 5145/6505] Update nocodb-install.sh create symlink for npm fixes https://github.com/tteck/Proxmox/issues/1699 --- install/nocodb-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh index 23713d69..509bd282 100644 --- a/install/nocodb-install.sh +++ b/install/nocodb-install.sh @@ -28,6 +28,7 @@ $STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/inst . ~/.bashrc $STD nvm install 16.20.1 ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +ln -sf /root/.nvm/versions/node/v16.20.1/bin/npm /usr/bin/npm msg_ok "Installed Node.js" msg_info "Installing NocoDB" From 984d8fc249431aac1735b1926a3ca97f4724a67b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Aug 2023 05:21:36 -0400 Subject: [PATCH 5146/6505] Update node-red-install.sh add `node-red-start`, `node-red-stop`, `node-red-restart` and `node-red-log` commands --- install/node-red-install.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/install/node-red-install.sh b/install/node-red-install.sh index 8e4d803b..22909483 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -30,6 +30,14 @@ msg_ok "Installed Node.js" msg_info "Installing Node-Red" $STD npm install -g --unsafe-perm node-red +echo "journalctl -f -n 100 -u nodered -o cat" >/usr/bin/node-red-log +chmod +x /usr/bin/node-red-log +echo "systemctl stop nodered" >/usr/bin/node-red-stop +chmod +x /usr/bin/node-red-stop +echo "systemctl start nodered" >/usr/bin/node-red-start +chmod +x /usr/bin/node-red-start +echo "systemctl restart nodered" >/usr/bin/node-red-restart +chmod +x /usr/bin/node-red-restart msg_ok "Installed Node-Red" msg_info "Creating Service" From 58ecabe0ea1c6ef0b030292bcc86180b159ed2dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Aug 2023 09:26:44 -0400 Subject: [PATCH 5147/6505] Update build.func tweak --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index ee0ff47d..43925d1b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -491,6 +491,7 @@ build_container() { fi export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" + export app="$NSAPP" export PASSWORD="$PW" export VERBOSE="$VERB" export SSH_ROOT="${SSH}" From cb4097e74c409d6b4b79608280d826c881c75242 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 17 Aug 2023 10:53:23 -0400 Subject: [PATCH 5148/6505] integrate the `update` command --- install/esphome-install.sh | 2 ++ install/homeassistant-core-install.sh | 2 ++ install/homeassistant-install.sh | 2 ++ install/node-red-install.sh | 2 ++ install/omada-install.sh | 4 +++- install/zigbee2mqtt-install.sh | 2 ++ 6 files changed, 13 insertions(+), 1 deletion(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 7dbbbc18..5cb2cb59 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -35,6 +35,8 @@ msg_info "Installing ESPHome" #python3 -m venv . #source bin/activate $STD pip install esphome tornado esptool +echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update +chmod +x /usr/bin/update msg_ok "Installed ESPHome" msg_info "Creating Service" diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index cbb10ed5..0c3a8cff 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -87,6 +87,8 @@ $STD pip install homeassistant $STD pip install mysqlclient $STD pip install psycopg2-binary mkdir -p /root/.homeassistant +echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update +chmod +x /usr/bin/update msg_ok "Installed Home Assistant-Core" msg_info "Creating Service" diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 0c19ca6c..5bfe63d2 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -88,6 +88,8 @@ $STD docker run -d \ --net=host \ ghcr.io/home-assistant/home-assistant:stable mkdir /root/hass_config +echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update +chmod +x /usr/bin/update msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" motd_ssh diff --git a/install/node-red-install.sh b/install/node-red-install.sh index 22909483..b9ca4fd3 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -38,6 +38,8 @@ echo "systemctl start nodered" >/usr/bin/node-red-start chmod +x /usr/bin/node-red-start echo "systemctl restart nodered" >/usr/bin/node-red-restart chmod +x /usr/bin/node-red-restart +echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update +chmod +x /usr/bin/update msg_ok "Installed Node-Red" msg_info "Creating Service" diff --git a/install/omada-install.sh b/install/omada-install.sh index 03e2b418..f2f7a3e5 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -41,7 +41,9 @@ latest_version=$(basename "$latest_url" | sed -e 's/.*ller_//;s/_Li.*//') msg_info "Installing Omada Controller ${latest_version}" wget -qL ${latest_url} -$STD dpkg -i Omada_SDN_Controller_${latest_version}_Linux_x64.deb +$STD dpkg -i Omada_SDN_Controller_${latest_version}_Linux_x64.deb +echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update +chmod +x /usr/bin/update msg_ok "Installed Omada Controller ${latest_version}" motd_ssh diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index eb10fdd6..151d028b 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -48,6 +48,8 @@ if [[ $DEV == "y" ]]; then $STD git checkout dev fi $STD npm ci +echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update +chmod +x /usr/bin/update msg_ok "Installed Zigbee2MQTT" msg_info "Creating Service" From 76d7cc6f71d1123bb637dbad5090fa47514134fc Mon Sep 17 00:00:00 2001 From: Csaba Kos Date: Fri, 18 Aug 2023 19:14:48 -0500 Subject: [PATCH 5149/6505] Update monitor-all.sh to restart virtual machines instead of resetting (#1704) If a virtual machine is not responding or has become unresponsive, perform a forceful restart instead of a soft reset --- misc/monitor-all.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 65dbca92..a60f8dd5 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -73,12 +73,13 @@ while true; do else # It is a virtual machine if qm status $instance | grep -q "status: running"; then - echo "$(date): VM $instance is not responding, resetting..." - qm reset $instance >/dev/null 2>&1 + echo "$(date): VM $instance is not responding, restarting..." + qm stop $instance >/dev/null 2>&1 + sleep 5 else - qm start $instance >/dev/null 2>&1 echo "$(date): VM $instance is not running, starting..." fi + qm start $instance >/dev/null 2>&1 fi fi done From 8db5f6fedff6209978775a03c38468dba60c2fbf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 19 Aug 2023 06:22:12 -0400 Subject: [PATCH 5150/6505] Update create_lxc.sh correct storage menu message --- ct/create_lxc.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 4cf41103..557d88eb 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -95,15 +95,15 @@ function select_storage() { done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 1 ]; then + if [ $((${#MENU[@]}/3)) -eq 1 ]; then printf ${MENU[0]} else local STORAGE while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for ${APPLICATION}?\nTo make a selection, use the Spacebar.\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || exit "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\nTo make a selection, use the Spacebar.\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || exit "Menu aborted." done printf $STORAGE fi From 748b16426cb77a2c7aecadaa89fd610cc6331ef2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Aug 2023 06:04:56 -0400 Subject: [PATCH 5151/6505] Update USER_SUBMITTED_GUIDES.md Running Frigate on Proxmox --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index cd680d1a..57ec2294 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -18,6 +18,8 @@ [How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/) +[Running Frigate on Proxmox](https://www.homeautomationguy.io/blog/running-frigate-on-proxmox) + [Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html) [Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/) From b81ef061615a4388f20ae198c787363503f7e69f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Aug 2023 21:06:31 -0400 Subject: [PATCH 5152/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 7b1fcf7c..e8bc2567 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -102,7 +102,7 @@ EOF esac if [[ "${VERSION}" == "bookworm" ]]; then - CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ + CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From 27d1e0af35ab7d3929e72be2db8d42f85d10558a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 21 Aug 2023 21:14:16 -0400 Subject: [PATCH 5153/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index e8bc2567..ca076582 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -102,7 +102,7 @@ EOF esac if [[ "${VERSION}" == "bookworm" ]]; then - CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nEnable 'ceph package repositories?" 14 58 2 \ + CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nAdd 'ceph package repositories?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From 9b9facf773e6a3c8d4a6a39072399745fe3096e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 05:51:24 -0400 Subject: [PATCH 5154/6505] Update photoprism-install.sh add `HEIF` support --- install/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index df63bd6e..64f303b6 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -25,6 +25,7 @@ $STD apt-get install -y make $STD apt-get install -y zip $STD apt-get install -y exiftool $STD apt-get install -y ffmpeg +$STD apt-get install -y libheif1 msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" From c6e909e73198e41083d39e4c60ad62ae98e76ae2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 06:34:26 -0400 Subject: [PATCH 5155/6505] Update grafana.sh default Debian 12 --- ct/grafana.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/grafana.sh b/ct/grafana.sh index bb50c557..9b61620b 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 9a7973f92f9c3f2f9487a350426cfeed5a35d675 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 06:47:29 -0400 Subject: [PATCH 5156/6505] Update bug_report.yaml Linux distribution --- .github/ISSUE_TEMPLATE/bug_report.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 736aaed3..59b3587c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -15,6 +15,13 @@ body: label: A clear and concise description of the issue. validations: required: true + - type: input + id: distribution + attributes: + label: Which Linux distribution are you employing? + placeholder: 'Debian 11' + validations: + required: true - type: textarea id: screenshot attributes: From d5a4a33f87ee453a1eabc89e8ba3593d51b8fa69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 06:55:25 -0400 Subject: [PATCH 5157/6505] Update bug_report.yaml verify guidelines --- .github/ISSUE_TEMPLATE/bug_report.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 59b3587c..ff003fe8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -9,19 +9,19 @@ body: - Changing Linux distributions without confirming the proper functioning of default settings. - When encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. - For suggestions, questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) + - type: input + id: guidelines + attributes: + label: Please verify that you have read and understood the guidelines. + placeholder: 'yes' + validations: + required: true - type: textarea id: bug attributes: label: A clear and concise description of the issue. validations: required: true - - type: input - id: distribution - attributes: - label: Which Linux distribution are you employing? - placeholder: 'Debian 11' - validations: - required: true - type: textarea id: screenshot attributes: From b6a3e822b1b7903f59c77742b5c3b4f80098386f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 06:58:10 -0400 Subject: [PATCH 5158/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index ff003fe8..e8140933 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -22,6 +22,13 @@ body: label: A clear and concise description of the issue. validations: required: true + - type: input + id: distribution + attributes: + label: Which Linux distribution are you employing? + placeholder: 'Debian 11' + validations: + required: true - type: textarea id: screenshot attributes: From d55d44bc9b3ba7354307f37ecdfbb1ee3c52a3b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 13:25:19 -0400 Subject: [PATCH 5159/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index e8140933..a87207c9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -22,13 +22,19 @@ body: label: A clear and concise description of the issue. validations: required: true - - type: input + - type: dropdown id: distribution - attributes: - label: Which Linux distribution are you employing? - placeholder: 'Debian 11' validations: required: true + attributes: + label: Which Linux distribution are you employing? + options: + - Default Settings + - Debian 11 + - Debian 12 + - Ubuntu 20.04 + - Ubuntu 22.04 + - Ubuntu 23.04 - type: textarea id: screenshot attributes: From 54d791f5c1937b81a54e3e946b215e9d127be560 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 13:28:29 -0400 Subject: [PATCH 5160/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index a87207c9..b9a2964e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -29,6 +29,7 @@ body: attributes: label: Which Linux distribution are you employing? options: + - - Default Settings - Debian 11 - Debian 12 From d56a46bc478b14225195087e707593ddbb67a492 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 13:44:59 -0400 Subject: [PATCH 5161/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index b9a2964e..42fbf591 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -40,6 +40,7 @@ body: id: screenshot attributes: label: If relevant, including screenshots or a code block can be helpful in clarifying the issue. + placeholder: Code blocks commence and conclude with three backticks (```). validations: required: false - type: textarea From 9ce770dec2ec97df29f5f5a5076a87b6ae32ae73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 23 Aug 2023 13:55:02 -0400 Subject: [PATCH 5162/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 42fbf591..7c8d7a5a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -40,7 +40,7 @@ body: id: screenshot attributes: label: If relevant, including screenshots or a code block can be helpful in clarifying the issue. - placeholder: Code blocks commence and conclude with three backticks (```). + placeholder: Code blocks begin and conclude by enclosing the code with three backticks (```) above and below it. validations: required: false - type: textarea From c102780df6eede6781854e778e96659d81b85be0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Aug 2023 11:25:10 -0400 Subject: [PATCH 5163/6505] Update CHANGELOG.md remove qBittorrent LXC --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d153f81..4ba9d7cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-08-24 + +### Changed + +- **qBittorrent LXC** + - Removed from this repository for malicious hidden code https://github.com/tteck/Proxmox/discussions/1725 + ## 2023-08-16 ### Changed From 6f121b91924f5bc8c1269da4a3c005034aaf19b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Aug 2023 11:32:49 -0400 Subject: [PATCH 5164/6505] Delete qbittorrent.sh malicious hidden code --- ct/qbittorrent.sh | 70 ----------------------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 ct/qbittorrent.sh diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh deleted file mode 100644 index 40cfa24d..00000000 --- a/ct/qbittorrent.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ____ _ __ __ __ - ____ _/ __ )(_) /_/ /_____ _____________ ____ / /_ - / __ `/ __ / / __/ __/ __ \/ ___/ ___/ _ \/ __ \/ __/ -/ /_/ / /_/ / / /_/ /_/ /_/ / / / / / __/ / / / /_ -\__, /_____/_/\__/\__/\____/_/ /_/ \___/_/ /_/\__/ - /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="qBittorrent" -var_disk="8" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="12" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET="dhcp" - GATE="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { -header_info -if [[ ! -f /etc/systemd/system/qbittorrent-nox.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -exit -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8090${CL}\n" From 2339505cd4b559334ef7822eb171974ff18b47ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Aug 2023 11:34:07 -0400 Subject: [PATCH 5165/6505] Delete qbittorrent-install.sh malicious hidden code --- install/qbittorrent-install.sh | 46 ---------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 install/qbittorrent-install.sh diff --git a/install/qbittorrent-install.sh b/install/qbittorrent-install.sh deleted file mode 100644 index 1a6147d2..00000000 --- a/install/qbittorrent-install.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing qbittorrent-nox" -$STD apt-get install -y qbittorrent-nox -msg_ok "qbittorrent-nox" - -msg_info "Creating Service" -cat </etc/systemd/system/qbittorrent-nox.service -[Unit] -Description=qBittorrent client -After=network.target -[Service] -ExecStart=/usr/bin/qbittorrent-nox --webui-port=8090 -Restart=always -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now qbittorrent-nox -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" From 8cb72b808ab21adf5e870380caa374371031737e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Aug 2023 13:23:09 -0400 Subject: [PATCH 5166/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ba9d7cd..9eecd6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ ### Changed - **qBittorrent LXC** - - Removed from this repository for malicious hidden code https://github.com/tteck/Proxmox/discussions/1725 + - Removed from this repository for potential malicious hidden code https://github.com/tteck/Proxmox/discussions/1725 ## 2023-08-16 From 55576e712d58fe7addd8cf3b4158976683d672d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Aug 2023 14:56:24 -0400 Subject: [PATCH 5167/6505] Create qbittorrent-install.sh Disable UPnP Password changeme --- install/qbittorrent-install.sh | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 install/qbittorrent-install.sh diff --git a/install/qbittorrent-install.sh b/install/qbittorrent-install.sh new file mode 100644 index 00000000..64c63001 --- /dev/null +++ b/install/qbittorrent-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing qbittorrent-nox" +$STD apt-get install -y qbittorrent-nox +mkdir -p /.config/qBittorrent/ +cat </.config/qBittorrent/qBittorrent.conf +[Preferences] +WebUI\Password_PBKDF2="@ByteArray(amjeuVrF3xRbgzqWQmes5A==:XK3/Ra9jUmqUc4RwzCtrhrkQIcYczBl90DJw2rT8DFVTss4nxpoRhvyxhCf87ahVE3SzD8K9lyPdpyUCfmVsUg==)" +WebUI\Port=8090 +WebUI\UseUPnP=false +WebUI\Username=admin +EOF +msg_ok "qbittorrent-nox" + +msg_info "Creating Service" +cat </etc/systemd/system/qbittorrent-nox.service +[Unit] +Description=qBittorrent client +After=network.target +[Service] +ExecStart=/usr/bin/qbittorrent-nox --webui-port=8090 +Restart=always +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now qbittorrent-nox +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 2e3642dc5b73818297271db5c4b82fc889efca59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Aug 2023 14:57:42 -0400 Subject: [PATCH 5168/6505] Create qbittorrent.sh --- ct/qbittorrent.sh | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ct/qbittorrent.sh diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh new file mode 100644 index 00000000..40cfa24d --- /dev/null +++ b/ct/qbittorrent.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _ __ __ __ + ____ _/ __ )(_) /_/ /_____ _____________ ____ / /_ + / __ `/ __ / / __/ __/ __ \/ ___/ ___/ _ \/ __ \/ __/ +/ /_/ / /_/ / / /_/ /_/ /_/ / / / / / __/ / / / /_ +\__, /_____/_/\__/\__/\____/_/ /_/ \___/_/ /_/\__/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="qBittorrent" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/qbittorrent-nox.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8090${CL}\n" From e1668068e9fbea308c034a8bac4a296e6503757a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 24 Aug 2023 15:11:16 -0400 Subject: [PATCH 5169/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eecd6d8..5f545c36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ ### Changed +- **qBittorrent LXC** + - Added back to repository with UPnP disabled and password changed. + +## 2023-08-24 + +### Changed + - **qBittorrent LXC** - Removed from this repository for potential malicious hidden code https://github.com/tteck/Proxmox/discussions/1725 From b3f21d9eea6047eeab836abffb1da62ca0f69b83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Aug 2023 12:36:55 -0400 Subject: [PATCH 5170/6505] Update openhab-install.sh Java 17 --- install/openhab-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/openhab-install.sh b/install/openhab-install.sh index 1f52572a..532a6506 100644 --- a/install/openhab-install.sh +++ b/install/openhab-install.sh @@ -26,7 +26,7 @@ wget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc "https://keyserver.ubuntu.com/pks/ wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb $STD dpkg -i zulu-repo_1.0.0-3_all.deb $STD apt-get update -$STD apt-get -y install zulu11-jdk +$STD apt-get -y install zulu17-jdk msg_ok "Installed Azul Zulu" msg_info "Installing openHAB" From 09e21f33e1e646a66b891d0fc926d191612358d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 26 Aug 2023 12:46:41 -0400 Subject: [PATCH 5171/6505] Update openhab.sh default Debian 12 --- ct/openhab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/openhab.sh b/ct/openhab.sh index 7841d610..168785b8 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -24,7 +24,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 86d1a388f9287984459bd736bb36796dc3cc8941 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Aug 2023 10:09:11 -0400 Subject: [PATCH 5172/6505] Update mqtt-install.sh reintroduce Mosquitto repositories --- install/mqtt-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 5f66caa7..04ea968a 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -20,6 +20,12 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Mosquitto MQTT Broker" +if [ "$PCT_OSTYPE" == "debian" ]; then + VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" + wget -qO- http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key >/etc/apt/trusted.gpg.d/mosquitto-repo.asc + wget -qO /etc/apt/sources.list.d/mosquitto-${VERSION}.list http://repo.mosquitto.org/debian/mosquitto-${VERSION}.list + $STD apt-get update +fi $STD apt-get -y install mosquitto $STD apt-get -y install mosquitto-clients cat </etc/mosquitto/conf.d/default.conf From f5b629de5175e1669d2376ecb4357410aeaac6b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 27 Aug 2023 10:10:40 -0400 Subject: [PATCH 5173/6505] Update mariadb-install.sh reintroduce MariaDB repositories --- install/mariadb-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index ef154ed0..19787d93 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -20,6 +20,8 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing MariaDB" +$STD bash <(curl -fsSL https://r.mariadb.com/downloads/mariadb_repo_setup) +$STD apt-get update $STD apt-get install -y mariadb-server sed -i 's/^# *\(port *=.*\)/\1/' /etc/mysql/my.cnf sed -i 's/^bind-address/#bind-address/g' /etc/mysql/mariadb.conf.d/50-server.cnf From 98b7b8cb80db34b26f0166ef11c1549ee08c3819 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 08:10:03 -0400 Subject: [PATCH 5174/6505] Create turnkey-fileserver.sh --- misc/turnkey-fileserver.sh | 171 +++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 misc/turnkey-fileserver.sh diff --git a/misc/turnkey-fileserver.sh b/misc/turnkey-fileserver.sh new file mode 100644 index 00000000..b4695144 --- /dev/null +++ b/misc/turnkey-fileserver.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/turnkey-fileserver.sh)" + +# Setup script environment +PASS="$(openssl rand -base64 8)" +TEMPLATE_SEARCH="debian-11-turnkey-fileserver_17.1-1_amd64.tar.gz" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-fileserver + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ _____ __ ____ +/_ __/_ _________ / //_/__ __ __ / __(_) /__ / __/__ _____ _____ ____ + / / / // / __/ _ \/ ,< / -_) // / / _// / / -_) _\ \/ -_) __/ |/ / -_) __/ +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/ /_/_/\__/ /___/\__/_/ |___/\__/_/ + /___/ +EOF +} +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +CTID=$(pvesh get /cluster/nextid) +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-4} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey File Server Password" >>~/turnkey-fileserver.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-fileserver.creds #run `cat turnkey-fileserver.creds` in the Proxmox root directory +info "Proceed to the console to complete the setup." +info "login: root" +info "password: $PASS" From 4bf7a1f743bf6822fa9d1bc39a84d14d38d95726 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 09:34:47 -0400 Subject: [PATCH 5175/6505] create turnkey folder --- {misc => turnkey}/turnkey-fileserver.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) rename {misc => turnkey}/turnkey-fileserver.sh (95%) diff --git a/misc/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh similarity index 95% rename from misc/turnkey-fileserver.sh rename to turnkey/turnkey-fileserver.sh index b4695144..410ef9ec 100644 --- a/misc/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/turnkey-fileserver.sh)" +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-fileserver.sh)" # Setup script environment PASS="$(openssl rand -base64 8)" @@ -147,7 +148,7 @@ TEMPLATE="${TEMPLATES[-1]}" # Download LXC template if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template..." + msg "Downloading LXC template (Patience)..." pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." fi @@ -165,7 +166,7 @@ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." echo "TurnKey File Server Password" >>~/turnkey-fileserver.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-fileserver.creds #run `cat turnkey-fileserver.creds` in the Proxmox root directory -info "Proceed to the console to complete the setup." +echo $PASS >>~/turnkey-fileserver.creds #run `cat turnkey-fileserver.creds` in the Proxmox shell +info "Proceed to the LXC console to complete the setup." info "login: root" info "password: $PASS" From be78b108f290864bbab90058e777c7a4ea2d88e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 09:36:44 -0400 Subject: [PATCH 5176/6505] Create turnkey-gitlab.sh --- turnkey/turnkey-gitlab.sh | 172 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 turnkey/turnkey-gitlab.sh diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh new file mode 100644 index 00000000..e1614f9b --- /dev/null +++ b/turnkey/turnkey-gitlab.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-gitlab.sh)" + +# Setup script environment +PASS="$(openssl rand -base64 8)" +TEMPLATE_SEARCH="debian-11-turnkey-gitlab_17.1-1_amd64.tar.gz" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-gitlab + -tags proxmox-helper-scripts + -onboot 1 + -cores 4 + -memory 4096 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ ______ __ __ __ +/_ __/_ _________ / //_/__ __ __ / ___(_) /_/ / ___ _/ / + / / / // / __/ _ \/ ,< / -_) // / / (_ / / __/ /__/ _ `/ _ \ +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/_/\__/____/\_,_/_.__/ + /___/ +EOF +} +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +CTID=$(pvesh get /cluster/nextid) +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey GitLab Password" >>~/turnkey-gitlab.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-gitlab.creds #run `cat turnkey-gitlab.creds` in the Proxmox shell +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From 3c0e25adeb2205515ef892a0ecdb826f7ff8785a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 09:43:15 -0400 Subject: [PATCH 5177/6505] Create turnkey-core.sh --- turnkey/turnkey-core.sh | 172 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 turnkey/turnkey-core.sh diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh new file mode 100644 index 00000000..a1039114 --- /dev/null +++ b/turnkey/turnkey-core.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-core.sh)" + +# Setup script environment +PASS="$(openssl rand -base64 8)" +TEMPLATE_SEARCH="debian-11-turnkey-core_17.1-1_amd64.tar.gz" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-core + -tags proxmox-helper-scripts + -onboot 1 + -cores 4 + -memory 4096 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ _____ +/_ __/_ _________ / //_/__ __ __ / ___/__ _______ + / / / // / __/ _ \/ ,< / -_) // / / /__/ _ \/ __/ -_) +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/\___/_/ \__/ + /___/ +EOF +} +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +CTID=$(pvesh get /cluster/nextid) +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey Core Password" >>~/turnkey-core.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-core.creds #run `cat turnkey-core.creds` in the Proxmox shell +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From e1953beca4fb5b662dbfcc96e74d9477722b4983 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 09:46:16 -0400 Subject: [PATCH 5178/6505] Update turnkey-core.sh adjust resources --- turnkey/turnkey-core.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index a1039114..494af647 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -14,8 +14,8 @@ PCT_OPTIONS=" -hostname turnkey-core -tags proxmox-helper-scripts -onboot 1 - -cores 4 - -memory 4096 + -cores 2 + -memory 2048 -password $PASS -net0 name=eth0,bridge=vmbr0,ip=dhcp -unprivileged 1 From 12fec28eb7c4782cd79dd93ea5e9b986a512c3e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 14:02:49 -0400 Subject: [PATCH 5179/6505] Create turnkey-owncloud.sh --- turnkey/turnkey-owncloud.sh | 172 ++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 turnkey/turnkey-owncloud.sh diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh new file mode 100644 index 00000000..fd3455ff --- /dev/null +++ b/turnkey/turnkey-owncloud.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-owncloud.sh)" + +# Setup script environment +PASS="$(openssl rand -base64 8)" +TEMPLATE_SEARCH="debian-11-turnkey-owncloud_17.1-1_amd64.tar.gz" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-owncloud + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ _______ __ +/_ __/_ _________ / //_/__ __ __ ___ _ _____ / ___/ /__ __ _____/ / + / / / // / __/ _ \/ ,< / -_) // / / _ \ |/|/ / _ \/ /__/ / _ \/ // / _ / +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/__,__/_//_/\___/_/\___/\_,_/\_,_/ + /___/ +EOF +} +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +CTID=$(pvesh get /cluster/nextid) +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey ownCloud Password" >>~/turnkey-owncloud.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-owncloud.creds #run `cat turnkey-owncloud.creds` in the Proxmox shell +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From 90917966022e293a3aa6c1570d1a68efb7b64337 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 14:13:05 -0400 Subject: [PATCH 5180/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f545c36..17e33791 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-08-29 + +### Changed + +- **TurnKey LXC Template Scripts** + - Primitive [scripts](https://github.com/tteck/Proxmox/tree/main/turnkey) to install [TurnKey LXC templates](https://www.turnkeylinux.org/) using basic settings. + ## 2023-08-24 ### Changed From c927e1737ce70544367bdcbce4f3f322f238e20a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 14:15:05 -0400 Subject: [PATCH 5181/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17e33791..26d95595 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ ### Changed - **TurnKey LXC Template Scripts** - - Primitive [scripts](https://github.com/tteck/Proxmox/tree/main/turnkey) to install [TurnKey LXC templates](https://www.turnkeylinux.org/) using basic settings. + - Primitive [scripts](https://github.com/tteck/Proxmox/tree/main/turnkey) to install [TurnKey LXC templates](https://www.turnkeylinux.org/) using basic settings. [More info](https://github.com/tteck/Proxmox/discussions/1742#discussion-5571966) ## 2023-08-24 From 071984d133002406a981d5215d5ce329510d50eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 15:00:03 -0400 Subject: [PATCH 5182/6505] tweaks --- turnkey/turnkey-core.sh | 8 +++++++- turnkey/turnkey-fileserver.sh | 8 +++++++- turnkey/turnkey-gitlab.sh | 8 +++++++- turnkey/turnkey-owncloud.sh | 8 +++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index 494af647..d850eabe 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -73,7 +73,9 @@ function cleanup_ctid() { pct destroy $CTID fi } -CTID=$(pvesh get /cluster/nextid) +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi function select_storage() { local CLASS=$1 local CONTENT @@ -117,6 +119,7 @@ function select_storage() { } # Test if required variables are set +CTID=$(pvesh get /cluster/nextid) [[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." # Test if ID is valid @@ -167,6 +170,9 @@ pct start "$CTID" info "LXC container '$CTID' was successfully created." echo "TurnKey Core Password" >>~/turnkey-core.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-core.creds #run `cat turnkey-core.creds` in the Proxmox shell +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi info "Proceed to the LXC console to complete the setup." info "login: root" info "password: $PASS" diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 410ef9ec..fea4aa0b 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -73,7 +73,9 @@ function cleanup_ctid() { pct destroy $CTID fi } -CTID=$(pvesh get /cluster/nextid) +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi function select_storage() { local CLASS=$1 local CONTENT @@ -117,6 +119,7 @@ function select_storage() { } # Test if required variables are set +CTID=$(pvesh get /cluster/nextid) [[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." # Test if ID is valid @@ -167,6 +170,9 @@ pct start "$CTID" info "LXC container '$CTID' was successfully created." echo "TurnKey File Server Password" >>~/turnkey-fileserver.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-fileserver.creds #run `cat turnkey-fileserver.creds` in the Proxmox shell +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi info "Proceed to the LXC console to complete the setup." info "login: root" info "password: $PASS" diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index e1614f9b..ffdd3e58 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -73,7 +73,9 @@ function cleanup_ctid() { pct destroy $CTID fi } -CTID=$(pvesh get /cluster/nextid) +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi function select_storage() { local CLASS=$1 local CONTENT @@ -117,6 +119,7 @@ function select_storage() { } # Test if required variables are set +CTID=$(pvesh get /cluster/nextid) [[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." # Test if ID is valid @@ -167,6 +170,9 @@ pct start "$CTID" info "LXC container '$CTID' was successfully created." echo "TurnKey GitLab Password" >>~/turnkey-gitlab.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-gitlab.creds #run `cat turnkey-gitlab.creds` in the Proxmox shell +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi info "Proceed to the LXC console to complete the setup." info "login: root" info "password: $PASS" diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index fd3455ff..56ea54f9 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -73,7 +73,9 @@ function cleanup_ctid() { pct destroy $CTID fi } -CTID=$(pvesh get /cluster/nextid) +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi function select_storage() { local CLASS=$1 local CONTENT @@ -117,6 +119,7 @@ function select_storage() { } # Test if required variables are set +CTID=$(pvesh get /cluster/nextid) [[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." # Test if ID is valid @@ -167,6 +170,9 @@ pct start "$CTID" info "LXC container '$CTID' was successfully created." echo "TurnKey ownCloud Password" >>~/turnkey-owncloud.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-owncloud.creds #run `cat turnkey-owncloud.creds` in the Proxmox shell +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi info "Proceed to the LXC console to complete the setup." info "login: root" info "password: $PASS" From ab4afab8bca7c434fce75ee72a4ef68ed90782b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 15:39:34 -0400 Subject: [PATCH 5183/6505] Create turnkey-wordpress.sh --- turnkey/turnkey-wordpress.sh | 178 +++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 turnkey/turnkey-wordpress.sh diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh new file mode 100644 index 00000000..9d9b5620 --- /dev/null +++ b/turnkey/turnkey-wordpress.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-wordpress.sh)" + +# Setup script environment +PASS="$(openssl rand -base64 8)" +TEMPLATE_SEARCH="debian-11-turnkey-wordpress_17.1-1_amd64.tar.gz" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-wordpress + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ _ __ _____ +/_ __/_ _________ / //_/__ __ __ | | /| / /__ _______/ / _ \_______ ___ ___ + / / / // / __/ _ \/ ,< / -_) // / | |/ |/ / _ \/ __/ _ / ___/ __/ -_|_-<(_-< +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / |__/|__/\___/_/ \_,_/_/ /_/ \__/___/___/ + /___/ +EOF +} +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +CTID=$(pvesh get /cluster/nextid) +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey WordPress Password" >>~/turnkey-wordpress.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-wordpress.creds #run `cat turnkey-wordpress.creds` in the Proxmox shell +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From 7d87c278bee9a9aed65a70999a9673a15919d5b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 16:07:38 -0400 Subject: [PATCH 5184/6505] Create turnkey-observium.sh --- turnkey/turnkey-observium.sh | 178 +++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 turnkey/turnkey-observium.sh diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh new file mode 100644 index 00000000..52ae0971 --- /dev/null +++ b/turnkey/turnkey-observium.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-observium.sh)" + +# Setup script environment +PASS="$(openssl rand -base64 8)" +TEMPLATE_SEARCH="debian-11-turnkey-observium_17.2-1_amd64.tar.gz" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-observium + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ ____ __ _ +/_ __/_ _________ / //_/__ __ __ / __ \/ / ___ ___ _____ __(_)_ ____ _ + / / / // / __/ _ \/ ,< / -_) // / / /_/ / _ \(_-&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +CTID=$(pvesh get /cluster/nextid) +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey Observium Password" >>~/turnkey-observium.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-observium.creds #run `cat turnkey-observium.creds` in the Proxmox shell +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From 8feaf1ef848c80c8f2fb70344595b47d7c883b1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 17:01:59 -0400 Subject: [PATCH 5185/6505] Create turnkey-nextcloud.sh --- turnkey/turnkey-nextcloud.sh | 178 +++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 turnkey/turnkey-nextcloud.sh diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh new file mode 100644 index 00000000..ebd2b5cd --- /dev/null +++ b/turnkey/turnkey-nextcloud.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-nextcloud.sh)" + +# Setup script environment +PASS="$(openssl rand -base64 8)" +TEMPLATE_SEARCH="debian-11-turnkey-nextcloud_17.2-1_amd64.tar.gz" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-nextcloud + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ _ __ __ __ __ +/_ __/_ _________ / //_/__ __ __ / |/ /____ __/ /_____/ /__ __ _____/ / + / / / // / __/ _ \/ ,< / -_) // / / / -_) \ / __/ __/ / _ \/ // / _ / +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/|_/\__/_\_\\__/\__/_/\___/\_,_/\_,_/ + /___/ +EOF +} +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Test if required variables are set +CTID=$(pvesh get /cluster/nextid) +[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." + +# Test if ID is valid +[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." + +# Test if ID is in use +if pct status $CTID &>/dev/null; then + warn "ID '$CTID' is already in use." + unset CTID + die "Cannot use ID that is already in use." +fi + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey Nextcloud Password" >>~/turnkey-nextcloud.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-nextcloud.creds #run `cat turnkey-nextcloud.creds` in the Proxmox shell +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From 604c20df17d37253cfd044a525f23e65517dca71 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 19:17:30 -0400 Subject: [PATCH 5186/6505] turnkey code refactoring --- turnkey/turnkey-core.sh | 25 +++++++------------------ turnkey/turnkey-fileserver.sh | 25 +++++++------------------ turnkey/turnkey-gitlab.sh | 25 +++++++------------------ turnkey/turnkey-nextcloud.sh | 25 +++++++------------------ turnkey/turnkey-observium.sh | 25 +++++++------------------ turnkey/turnkey-owncloud.sh | 25 +++++++------------------ turnkey/turnkey-wordpress.sh | 25 +++++++------------------ 7 files changed, 49 insertions(+), 126 deletions(-) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index d850eabe..6739424b 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -7,11 +7,14 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-core.sh)" # Setup script environment +NAME="core" PASS="$(openssl rand -base64 8)" -TEMPLATE_SEARCH="debian-11-turnkey-core_17.1-1_amd64.tar.gz" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +PCT_DISK_SIZE="4" PCT_OPTIONS=" -features keyctl=1,nesting=1 - -hostname turnkey-core + -hostname turnkey-${NAME} -tags proxmox-helper-scripts -onboot 1 -cores 2 @@ -118,20 +121,6 @@ function select_storage() { fi } -# Test if required variables are set -CTID=$(pvesh get /cluster/nextid) -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." @@ -168,8 +157,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." -echo "TurnKey Core Password" >>~/turnkey-core.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-core.creds #run `cat turnkey-core.creds` in the Proxmox shell +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index fea4aa0b..859c9f7b 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -7,11 +7,14 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-fileserver.sh)" # Setup script environment +NAME="fileserver" PASS="$(openssl rand -base64 8)" -TEMPLATE_SEARCH="debian-11-turnkey-fileserver_17.1-1_amd64.tar.gz" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +PCT_DISK_SIZE="8" PCT_OPTIONS=" -features keyctl=1,nesting=1 - -hostname turnkey-fileserver + -hostname turnkey-${NAME} -tags proxmox-helper-scripts -onboot 1 -cores 2 @@ -118,20 +121,6 @@ function select_storage() { fi } -# Test if required variables are set -CTID=$(pvesh get /cluster/nextid) -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." @@ -168,8 +157,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." -echo "TurnKey File Server Password" >>~/turnkey-fileserver.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-fileserver.creds #run `cat turnkey-fileserver.creds` in the Proxmox shell +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index ffdd3e58..1feddb3a 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -7,11 +7,14 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-gitlab.sh)" # Setup script environment +NAME="gitlab" PASS="$(openssl rand -base64 8)" -TEMPLATE_SEARCH="debian-11-turnkey-gitlab_17.1-1_amd64.tar.gz" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +PCT_DISK_SIZE="8" PCT_OPTIONS=" -features keyctl=1,nesting=1 - -hostname turnkey-gitlab + -hostname turnkey-${NAME} -tags proxmox-helper-scripts -onboot 1 -cores 4 @@ -118,20 +121,6 @@ function select_storage() { fi } -# Test if required variables are set -CTID=$(pvesh get /cluster/nextid) -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." @@ -168,8 +157,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." -echo "TurnKey GitLab Password" >>~/turnkey-gitlab.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-gitlab.creds #run `cat turnkey-gitlab.creds` in the Proxmox shell +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index ebd2b5cd..dfbd2247 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -7,11 +7,14 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-nextcloud.sh)" # Setup script environment +NAME="nextcloud" PASS="$(openssl rand -base64 8)" -TEMPLATE_SEARCH="debian-11-turnkey-nextcloud_17.2-1_amd64.tar.gz" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.2-1_amd64.tar.gz" +PCT_DISK_SIZE="10" PCT_OPTIONS=" -features keyctl=1,nesting=1 - -hostname turnkey-nextcloud + -hostname turnkey-${NAME} -tags proxmox-helper-scripts -onboot 1 -cores 2 @@ -118,20 +121,6 @@ function select_storage() { fi } -# Test if required variables are set -CTID=$(pvesh get /cluster/nextid) -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." @@ -168,8 +157,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." -echo "TurnKey Nextcloud Password" >>~/turnkey-nextcloud.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-nextcloud.creds #run `cat turnkey-nextcloud.creds` in the Proxmox shell +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index 52ae0971..bbde4f62 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -7,11 +7,14 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-observium.sh)" # Setup script environment +NAME="observium" PASS="$(openssl rand -base64 8)" -TEMPLATE_SEARCH="debian-11-turnkey-observium_17.2-1_amd64.tar.gz" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.2-1_amd64.tar.gz" +PCT_DISK_SIZE="4" PCT_OPTIONS=" -features keyctl=1,nesting=1 - -hostname turnkey-observium + -hostname turnkey-${NAME} -tags proxmox-helper-scripts -onboot 1 -cores 2 @@ -118,20 +121,6 @@ function select_storage() { fi } -# Test if required variables are set -CTID=$(pvesh get /cluster/nextid) -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." @@ -168,8 +157,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." -echo "TurnKey Observium Password" >>~/turnkey-observium.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-observium.creds #run `cat turnkey-observium.creds` in the Proxmox shell +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index 56ea54f9..74f4b5e6 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -7,11 +7,14 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-owncloud.sh)" # Setup script environment +NAME="owncloud" PASS="$(openssl rand -base64 8)" -TEMPLATE_SEARCH="debian-11-turnkey-owncloud_17.1-1_amd64.tar.gz" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +PCT_DISK_SIZE="10" PCT_OPTIONS=" -features keyctl=1,nesting=1 - -hostname turnkey-owncloud + -hostname turnkey-${NAME} -tags proxmox-helper-scripts -onboot 1 -cores 2 @@ -118,20 +121,6 @@ function select_storage() { fi } -# Test if required variables are set -CTID=$(pvesh get /cluster/nextid) -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." @@ -168,8 +157,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." -echo "TurnKey ownCloud Password" >>~/turnkey-owncloud.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-owncloud.creds #run `cat turnkey-owncloud.creds` in the Proxmox shell +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index 9d9b5620..39039884 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -7,11 +7,14 @@ # bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-wordpress.sh)" # Setup script environment +NAME="wordpress" PASS="$(openssl rand -base64 8)" -TEMPLATE_SEARCH="debian-11-turnkey-wordpress_17.1-1_amd64.tar.gz" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +PCT_DISK_SIZE="8" PCT_OPTIONS=" -features keyctl=1,nesting=1 - -hostname turnkey-wordpress + -hostname turnkey-${NAME} -tags proxmox-helper-scripts -onboot 1 -cores 2 @@ -118,20 +121,6 @@ function select_storage() { fi } -# Test if required variables are set -CTID=$(pvesh get /cluster/nextid) -[[ "${CTID:-}" ]] || die "You need to set 'CTID' variable." - -# Test if ID is valid -[ "$CTID" -ge "100" ] || die "ID cannot be less than 100." - -# Test if ID is in use -if pct status $CTID &>/dev/null; then - warn "ID '$CTID' is already in use." - unset CTID - die "Cannot use ID that is already in use." -fi - # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." @@ -168,8 +157,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ msg "Starting LXC Container..." pct start "$CTID" info "LXC container '$CTID' was successfully created." -echo "TurnKey WordPress Password" >>~/turnkey-wordpress.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-wordpress.creds #run `cat turnkey-wordpress.creds` in the Proxmox shell +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi From 4f40e110575dd80d024405122248138bdd01728d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 29 Aug 2023 20:33:41 -0400 Subject: [PATCH 5187/6505] Create turnkey-torrentserver.sh --- turnkey/turnkey-torrentserver.sh | 167 +++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 turnkey/turnkey-torrentserver.sh diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh new file mode 100644 index 00000000..ba2cad0c --- /dev/null +++ b/turnkey/turnkey-torrentserver.sh @@ -0,0 +1,167 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-torrentserver.sh)" + +# Setup script environment +NAME="torrentserver" +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +PCT_DISK_SIZE="10" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-${NAME} + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ ______ __ ____ +/_ __/_ _________ / //_/__ __ __ /_ __/__ ___________ ___ / /_ / __/__ _____ _____ ____ + / / / // / __/ _ \/ ,< / -_) // / / / / _ \/ __/ __/ -_) _ \/ __/ _\ \/ -_) __/ |/ / -_) __/ +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/ \___/_/ /_/ \__/_//_/\__/ /___/\__/_/ |___/\__/_/ + /___/ +EOF +} +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From dd2202695fa7c9f8ae713082694a352f1e07580a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 05:33:03 -0400 Subject: [PATCH 5188/6505] tweak turnkey scripts --- turnkey/turnkey-core.sh | 1 + turnkey/turnkey-fileserver.sh | 1 + turnkey/turnkey-gitlab.sh | 1 + turnkey/turnkey-nextcloud.sh | 1 + turnkey/turnkey-observium.sh | 1 + turnkey/turnkey-owncloud.sh | 1 + turnkey/turnkey-torrentserver.sh | 1 + turnkey/turnkey-wordpress.sh | 1 + 8 files changed, 8 insertions(+) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index 6739424b..d55506eb 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 859c9f7b..721bb1c0 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index 1feddb3a..a80cdc9a 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index dfbd2247..fbb52549 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index bbde4f62..7bcaa888 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index 74f4b5e6..32cf68e4 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh index ba2cad0c..5e58db77 100644 --- a/turnkey/turnkey-torrentserver.sh +++ b/turnkey/turnkey-torrentserver.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index 39039884..3d553549 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -37,6 +37,7 @@ cat <<"EOF" EOF } header_info +read -p "Press ENTER to continue..." set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error From 0af714731d3544093a040f98ec2bbb0b9ac73d20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 05:57:45 -0400 Subject: [PATCH 5189/6505] Create turnkey-gitea.sh --- turnkey/turnkey-gitea.sh | 168 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 turnkey/turnkey-gitea.sh diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh new file mode 100644 index 00000000..33a8ec2b --- /dev/null +++ b/turnkey/turnkey-gitea.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-gitea.sh)" + +# Setup script environment +NAME="gitea" +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.2-1_amd64.tar.gz" +PCT_DISK_SIZE="4" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-${NAME} + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ ______ __ +/_ __/_ _________ / //_/__ __ __ / ___(_) /____ ___ _ + / / / // / __/ _ \/ ,< / -_) // / / (_ / / __/ -_) _ `/ +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/_/\__/\__/\_,_/ + /___/ +EOF +} +header_info +read -p "Press ENTER to continue..." +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +info "LXC container '$CTID' was successfully created." +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi +info "Proceed to the LXC console to complete the setup." +info "login: root" +info "password: $PASS" From 4bc2a87189ffd961a329ab7a4b0f17b6068f861f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 13:02:57 -0400 Subject: [PATCH 5190/6505] Update CHANGELOG.md --- CHANGELOG.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26d95595..6e05acf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,30 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. -## 2023-08-29 +## 2023-08-30 ### Changed -- **TurnKey LXC Template Scripts** - - Primitive [scripts](https://github.com/tteck/Proxmox/tree/main/turnkey) to install [TurnKey LXC templates](https://www.turnkeylinux.org/) using basic settings. [More info](https://github.com/tteck/Proxmox/discussions/1742#discussion-5571966) +- **TurnKey** + - Introducing a **NEW** Category on the Site. +- **TurnKey Core LXC** + - NEW Script +- **TurnKey File Server LXC** + - NEW Script +- **TurnKey Gitea LXC** + - NEW Script +- **TurnKey GitLab LXC** + - NEW Script +- **TurnKey Nextcloud LXC** + - NEW Script +- **TurnKey Observium LXC** + - NEW Script +- **TurnKey ownCloud LXC** + - NEW Script +- **TurnKey Torrent Server LXC** + - NEW Script +- **TurnKey Wordpress LXC** + - NEW Script ## 2023-08-24 From ac469960bc56e533d94311a5ead955a5931860ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 13:09:59 -0400 Subject: [PATCH 5191/6505] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e05acf2..afde7a56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - **TurnKey** - Introducing a **NEW** Category on the Site. + - My intention is to maintain the TurnKey scripts in their simplest form, contained within a single file, and with minimal options, if any. - **TurnKey Core LXC** - NEW Script - **TurnKey File Server LXC** From 4b076f8c1999825e7904370bff4740dbfe89e15a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 14:04:52 -0400 Subject: [PATCH 5192/6505] tweak turnkey scripts --- turnkey/turnkey-core.sh | 2 +- turnkey/turnkey-fileserver.sh | 2 +- turnkey/turnkey-gitea.sh | 2 +- turnkey/turnkey-gitlab.sh | 2 +- turnkey/turnkey-nextcloud.sh | 2 +- turnkey/turnkey-observium.sh | 2 +- turnkey/turnkey-owncloud.sh | 2 +- turnkey/turnkey-torrentserver.sh | 2 +- turnkey/turnkey-wordpress.sh | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index d55506eb..cd2377f7 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -10,7 +10,7 @@ NAME="core" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="4" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 721bb1c0..fb6c4924 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -10,7 +10,7 @@ NAME="fileserver" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="8" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh index 33a8ec2b..71266831 100644 --- a/turnkey/turnkey-gitea.sh +++ b/turnkey/turnkey-gitea.sh @@ -10,7 +10,7 @@ NAME="gitea" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.2-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="4" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index a80cdc9a..9e827139 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -10,7 +10,7 @@ NAME="gitlab" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="8" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index fbb52549..587a261b 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -10,7 +10,7 @@ NAME="nextcloud" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.2-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="10" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index 7bcaa888..999c8e63 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -10,7 +10,7 @@ NAME="observium" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.2-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="4" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index 32cf68e4..9283f4b6 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -10,7 +10,7 @@ NAME="owncloud" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="10" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh index 5e58db77..d40b30d8 100644 --- a/turnkey/turnkey-torrentserver.sh +++ b/turnkey/turnkey-torrentserver.sh @@ -10,7 +10,7 @@ NAME="torrentserver" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="10" PCT_OPTIONS=" -features keyctl=1,nesting=1 diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index 3d553549..e1f07047 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -10,7 +10,7 @@ NAME="wordpress" PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}_17.1-1_amd64.tar.gz" +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" PCT_DISK_SIZE="8" PCT_OPTIONS=" -features keyctl=1,nesting=1 From 19a33639dc8c795847870262b04f7ed6b3cb536a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 16:00:13 -0400 Subject: [PATCH 5193/6505] tweak turnkey scripts --- turnkey/turnkey-core.sh | 10 +++++++++- turnkey/turnkey-fileserver.sh | 10 +++++++++- turnkey/turnkey-gitea.sh | 10 +++++++++- turnkey/turnkey-gitlab.sh | 10 +++++++++- turnkey/turnkey-nextcloud.sh | 10 +++++++++- turnkey/turnkey-observium.sh | 10 +++++++++- turnkey/turnkey-owncloud.sh | 10 +++++++++- turnkey/turnkey-torrentserver.sh | 10 +++++++++- turnkey/turnkey-wordpress.sh | 10 +++++++++- 9 files changed, 81 insertions(+), 9 deletions(-) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index cd2377f7..9db74e64 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index fb6c4924..66efe4b1 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh index 71266831..16838fb5 100644 --- a/turnkey/turnkey-gitea.sh +++ b/turnkey/turnkey-gitea.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index 9e827139..9b8127f3 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index 587a261b..8dc8f673 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index 999c8e63..6aaf7af4 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index 9283f4b6..2a263a79 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh index d40b30d8..ce74f19e 100644 --- a/turnkey/turnkey-torrentserver.sh +++ b/turnkey/turnkey-torrentserver.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index e1f07047..5e953343 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -38,6 +38,7 @@ EOF } header_info read -p "Press ENTER to continue..." +header_info set -o errexit #Exit immediately if a pipeline returns a non-zero status set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell set -o nounset #Treat unset variables as an error @@ -157,12 +158,19 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -info "LXC container '$CTID' was successfully created." +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo info "Proceed to the LXC console to complete the setup." +echo info "login: root" info "password: $PASS" +echo From a00a0a0ef36195ce778db34156568d12f045b1b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 16:54:55 -0400 Subject: [PATCH 5194/6505] Update turnkey-fileserver.sh test --- turnkey/turnkey-fileserver.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 66efe4b1..da0f3240 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -158,8 +158,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') +#sleep 5 +#IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then @@ -167,7 +167,7 @@ if [[ -f /etc/systemd/system/ping-instances.service ]]; then fi header_info echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +info "LXC container '$CTID' was successfully created." echo info "Proceed to the LXC console to complete the setup." echo From d5ea1be5a602cd6d3a1858839e54662ae7fc3941 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 30 Aug 2023 18:24:58 -0400 Subject: [PATCH 5195/6505] Update turnkey-fileserver.sh revert test --- turnkey/turnkey-fileserver.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index da0f3240..66efe4b1 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -158,8 +158,8 @@ pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/ # Success message msg "Starting LXC Container..." pct start "$CTID" -#sleep 5 -#IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory echo $PASS >>~/turnkey-${NAME}.creds if [[ -f /etc/systemd/system/ping-instances.service ]]; then @@ -167,7 +167,7 @@ if [[ -f /etc/systemd/system/ping-instances.service ]]; then fi header_info echo -info "LXC container '$CTID' was successfully created." +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." echo info "Proceed to the LXC console to complete the setup." echo From 0e08ce5c9c0171b1a843f995bcf465cefcdc8690 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Aug 2023 06:57:01 -0400 Subject: [PATCH 5196/6505] Create turnkey-zoneminder.sh --- turnkey/turnkey-zoneminder.sh | 175 ++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 turnkey/turnkey-zoneminder.sh diff --git a/turnkey/turnkey-zoneminder.sh b/turnkey/turnkey-zoneminder.sh new file mode 100644 index 00000000..300c6d30 --- /dev/null +++ b/turnkey/turnkey-zoneminder.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +# Setup script environment +NAME="zoneminder" +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" +PCT_DISK_SIZE="8" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-${NAME} + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ ____ __ ____ __ +/_ __/_ _________ / //_/__ __ __ /_ / ___ ___ ___ / |/ (_)__ ___/ /__ ____ + / / / // / __/ _ \/ ,< / -_) // / / /_/ _ \/ _ \/ -_) /|_/ / / _ \/ _ / -_) __/ +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /___/\___/_//_/\__/_/ /_/_/_//_/\_,_/\__/_/ + /___/ +EOF +} +header_info +read -p "Press ENTER to continue..." +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Success message +msg "Starting LXC Container..." +pct start "$CTID" +sleep 5 +IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') +echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory +echo $PASS >>~/turnkey-${NAME}.creds +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo +info "Proceed to the LXC console to complete the setup." +echo +info "login: root" +info "password: $PASS" +echo From 573caa7a7751ee3a73c5027d86b30f630c8546b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Aug 2023 06:59:34 -0400 Subject: [PATCH 5197/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index afde7a56..79bab7e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-08-31 + +### Changed + +- **TurnKey ZoneMinder LXC** + - NEW Script + ## 2023-08-30 ### Changed From 21ad01113ba40615f4a5e9ce9e2b5962ab297f67 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Aug 2023 08:48:11 -0400 Subject: [PATCH 5198/6505] testing new get ip code in turnkey-observium.sh --- turnkey/turnkey-observium.sh | 37 +++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index 6aaf7af4..89e93204 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -4,7 +4,6 @@ # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-observium.sh)" # Setup script environment NAME="observium" @@ -78,6 +77,8 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi @@ -147,6 +148,7 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi +# Create variable for 'pct' options PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) [[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) @@ -155,16 +157,41 @@ msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=6 +attempt=1 +IP="" + +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." From 55a2fa2ac80fbdcf4403804c60643065ddfc96d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Aug 2023 11:14:42 -0400 Subject: [PATCH 5199/6505] Create turnkey-openvpn.sh --- turnkey/turnkey-openvpn.sh | 204 +++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 turnkey/turnkey-openvpn.sh diff --git a/turnkey/turnkey-openvpn.sh b/turnkey/turnkey-openvpn.sh new file mode 100644 index 00000000..8a7edab0 --- /dev/null +++ b/turnkey/turnkey-openvpn.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env bash +# A primitive script to install TurnKey LXC templates using basic settings. +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +# Setup script environment +NAME="openvpn" +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" +PCT_DISK_SIZE="4" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-${NAME} + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ ____ _ _____ _ __ +/_ __/_ _________ / //_/__ __ __ / __ \___ ___ ___| | / / _ \/ |/ / + / / / // / __/ _ \/ ,< / -_) // / / /_/ / _ \/ -_) _ \ |/ / ___/ / +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \____/ .__/\__/_//_/___/_/ /_/|_/ + /___/ /_/ +EOF +} +header_info +read -p "Press ENTER to continue..." +header_info +set -o errexit #Exit immediately if a pipeline returns a non-zero status +set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell +set -o nounset #Treat unset variables as an error +set -o pipefail #Pipe will exit with last non-zero status if applicable +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} + +# Start Proxmox VE Monitor-All if running +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi + +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=( "$TAG" "$ITEM" "OFF" ) + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + printf ${MENU[0]} + else # More than one storage location is detected + local STORAGE + while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +# Create variable for 'pct' options +PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container +msg "Starting LXC Container..." +pct start "$CTID" +sleep 5 + +# Get container IP +max_attempts=6 +attempt=1 +IP="" + +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi + +# Success message +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo +info "Proceed to the LXC console to complete the setup." +echo +info "login: root" +info "password: $PASS" +echo From e073c01895ee3b8ad35b9ab7861da9bf55ed6721 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Aug 2023 11:23:20 -0400 Subject: [PATCH 5200/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79bab7e9..3d8985b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - **TurnKey ZoneMinder LXC** - NEW Script +- **TurnKey OpenVPN LXC** + - NEW Script ## 2023-08-30 From 9c44b26add7f23b0f78d7c752c6b1259f7a319b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 31 Aug 2023 14:21:31 -0400 Subject: [PATCH 5201/6505] turnkey scripts code refactoring --- turnkey/turnkey-core.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-fileserver.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-gitea.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-gitlab.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-nextcloud.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-observium.sh | 53 ++++++++++++------------- turnkey/turnkey-openvpn.sh | 54 ++++++++++++-------------- turnkey/turnkey-owncloud.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-torrentserver.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-wordpress.sh | 66 ++++++++++++++++++++++---------- turnkey/turnkey-zoneminder.sh | 65 +++++++++++++++++++++---------- 11 files changed, 455 insertions(+), 245 deletions(-) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index 9db74e64..2294896d 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-core.sh)" # Setup script environment NAME="core" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 66efe4b1..88bbd21d 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-fileserver.sh)" # Setup script environment NAME="fileserver" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-4} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh index 16838fb5..85ef344b 100644 --- a/turnkey/turnkey-gitea.sh +++ b/turnkey/turnkey-gitea.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-gitea.sh)" # Setup script environment NAME="gitea" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index 9b8127f3..a85c609a 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-gitlab.sh)" # Setup script environment NAME="gitlab" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index 8dc8f673..cdbc41d9 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-nextcloud.sh)" # Setup script environment NAME="nextcloud" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index 89e93204..da16c7ae 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT @@ -38,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -82,6 +78,8 @@ function cleanup_ctid() { if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -103,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -149,8 +147,8 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then fi # Create variable for 'pct' options -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." @@ -166,24 +164,23 @@ pct start "$CTID" sleep 5 # Get container IP -max_attempts=6 +max_attempts=5 attempt=1 IP="" - while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi done if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" fi # Start Proxmox VE Monitor-All if available @@ -200,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-openvpn.sh b/turnkey/turnkey-openvpn.sh index 8a7edab0..c1548cab 100644 --- a/turnkey/turnkey-openvpn.sh +++ b/turnkey/turnkey-openvpn.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT @@ -38,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,11 +74,12 @@ function cleanup_ctid() { fi } -# Start Proxmox VE Monitor-All if running +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -104,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -150,8 +147,8 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then fi # Create variable for 'pct' options -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." @@ -167,24 +164,23 @@ pct start "$CTID" sleep 5 # Get container IP -max_attempts=6 +max_attempts=5 attempt=1 IP="" - while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi done if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" fi # Start Proxmox VE Monitor-All if available @@ -201,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index 2a263a79..a71630b9 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-owncloud.sh)" # Setup script environment NAME="owncloud" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh index ce74f19e..549a7786 100644 --- a/turnkey/turnkey-torrentserver.sh +++ b/turnkey/turnkey-torrentserver.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-torrentserver.sh)" # Setup script environment NAME="torrentserver" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index 5e953343..63858486 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -1,10 +1,8 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/turnkey/turnkey-wordpress.sh)" # Setup script environment NAME="wordpress" @@ -39,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -78,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -102,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -147,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -173,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file diff --git a/turnkey/turnkey-zoneminder.sh b/turnkey/turnkey-zoneminder.sh index 300c6d30..ba90bd4f 100644 --- a/turnkey/turnkey-zoneminder.sh +++ b/turnkey/turnkey-zoneminder.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -# A primitive script to install TurnKey LXC templates using basic settings. # Copyright (c) 2021-2023 tteck # Author: tteck (tteckster) # License: MIT @@ -38,10 +37,7 @@ EOF header_info read -p "Press ENTER to continue..." header_info -set -o errexit #Exit immediately if a pipeline returns a non-zero status -set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell -set -o nounset #Treat unset variables as an error -set -o pipefail #Pipe will exit with last non-zero status if applicable +set -eEuo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR @@ -77,9 +73,13 @@ function cleanup_ctid() { pct destroy $CTID fi } + +# Stop Proxmox VE Monitor-All if running if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi + +# Set the CONTENT and CONTENT_LABEL variables function select_storage() { local CLASS=$1 local CONTENT @@ -101,22 +101,22 @@ function select_storage() { if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) fi - MENU+=( "$TAG" "$ITEM" "OFF" ) + MENU+=("$TAG" "$ITEM" "OFF") done < <(pvesm status -content $CONTENT | awk 'NR>1') # Select storage location - if [ $((${#MENU[@]}/3)) -eq 0 ]; then # No storage locations are detected + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." die "Unable to detect valid storage location." - elif [ $((${#MENU[@]}/3)) -eq 1 ]; then # Only one storage location is detected + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then printf ${MENU[0]} - else # More than one storage location is detected + else local STORAGE - while [ -z "${STORAGE:+x}" ]; do # Generate graphical menu + while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." done printf $STORAGE fi @@ -146,24 +146,49 @@ if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then die "A problem occured while downloading the LXC template." fi -PCT_OPTIONS=( ${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}} ) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=( -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8} ) +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) # Create LXC msg "Creating LXC container..." pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || die "A problem occured while trying to create container." -# Success message +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container msg "Starting LXC Container..." pct start "$CTID" sleep 5 -IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') -echo "TurnKey ${NAME} Password" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory -echo $PASS >>~/turnkey-${NAME}.creds + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi + +# Success message header_info echo info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." @@ -172,4 +197,4 @@ info "Proceed to the LXC console to complete the setup." echo info "login: root" info "password: $PASS" -echo +echo \ No newline at end of file From 57b320f6642c9d3798981df10d46094b040b768f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Sep 2023 05:46:11 -0400 Subject: [PATCH 5202/6505] Create turnkey-mediaserver.sh --- turnkey/turnkey-mediaserver.sh | 200 +++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 turnkey/turnkey-mediaserver.sh diff --git a/turnkey/turnkey-mediaserver.sh b/turnkey/turnkey-mediaserver.sh new file mode 100644 index 00000000..2ce0209c --- /dev/null +++ b/turnkey/turnkey-mediaserver.sh @@ -0,0 +1,200 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +# Setup script environment +NAME="mediaserver" +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" +PCT_DISK_SIZE="8" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-${NAME} + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + ______ __ __ __ ___ ___ ____ +/_ __/_ _________ / //_/__ __ __ / |/ /__ ___/ (_)__ _ / __/__ _____ _____ ____ + / / / // / __/ _ \/ ,< / -_) // / / /|_/ / -_) _ / / _ `/ _\ \/ -_) __/ |/ / -_) __/ +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/ /_/\__/\_,_/_/\_,_/ /___/\__/_/ |___/\__/_/ + /___/ +EOF +} +header_info +read -p "Press ENTER to continue..." +header_info +set -eEuo pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} + +# Stop Proxmox VE Monitor-All if running +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi + +# Set the CONTENT and CONTENT_LABEL variables +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=("$TAG" "$ITEM" "OFF") + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then + printf ${MENU[0]} + else + local STORAGE + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container +msg "Starting LXC Container..." +pct start "$CTID" +sleep 5 + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi + +# Success message +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo +info "Proceed to the LXC console to complete the setup." +echo +info "login: root" +info "password: $PASS" +echo From a70b14072e9d9fcc039e989b0eb5b2f60a34a459 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Sep 2023 05:52:38 -0400 Subject: [PATCH 5203/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d8985b1..aca2b545 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-01 + +### Changed + +- **TurnKey Media Server LXC** + - NEW Script + ## 2023-08-31 ### Changed From 49662ddd3dc6d89504484a0b59b4a7ef20ff219b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Sep 2023 06:44:41 -0400 Subject: [PATCH 5204/6505] Update changedetection-install.sh new nodejs install method fixes https://github.com/tteck/Proxmox/issues/1748 --- install/changedetection-install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 7bae8084..1ff0af91 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -41,7 +41,9 @@ $STD apt-get install -y \ libpangocairo-1.0-0 \ qpdf \ xdg-utils \ - xvfb + xvfb \ + ca-certificates \ + gnupg msg_ok "Installed Dependencies" msg_info "Updating Python3" @@ -52,10 +54,12 @@ $STD apt-get install -y \ msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" From c17e8d4fc48b28cac2e6b503f639e1fb4cb23abf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Sep 2023 07:19:05 -0400 Subject: [PATCH 5205/6505] new nodejs install method --- ct/cronicle.sh | 6 +++++- install/homarr-install.sh | 6 +++++- install/homepage-install.sh | 11 +++++++++-- install/jellyseerr-install.sh | 6 +++++- install/n8n-install.sh | 6 +++++- install/node-red-install.sh | 6 +++++- install/overseerr-install.sh | 6 +++++- install/photoprism-install.sh | 9 ++++++--- install/scrypted-install.sh | 8 ++++++-- install/shinobi-install.sh | 6 +++++- install/uptimekuma-install.sh | 8 ++++++-- install/wikijs-install.sh | 6 +++++- install/zigbee2mqtt-install.sh | 6 +++++- 13 files changed, 72 insertions(+), 18 deletions(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index f5227c32..65ee9e8f 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -73,13 +73,17 @@ apt-get install -y git &>/dev/null apt-get install -y make &>/dev/null apt-get install -y g++ &>/dev/null apt-get install -y gcc &>/dev/null +apt-get install -y ca-certificates &>/dev/null +apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) &>/dev/null +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +apt-get update &>/dev/null apt-get install -y nodejs &>/dev/null msg_ok "Installed Node.js" diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 54725ee5..16348ea6 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -18,13 +18,17 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/homepage-install.sh b/install/homepage-install.sh index f0c221e5..264aa2ce 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -18,14 +18,21 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -$STD apt-get install -y nodejs git make g++ gcc +$STD apt-get update +$STD apt-get install -y nodejs $STD npm install -g pnpm msg_ok "Installed Node.js" diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 06803fc0..e310dda6 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -18,13 +18,17 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 6f36c40b..2ee84d21 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -17,13 +17,17 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/node-red-install.sh b/install/node-red-install.sh index b9ca4fd3..d5985427 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -18,13 +18,17 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/overseerr-install.sh b/install/overseerr-install.sh index bb62febe..f3d47f23 100644 --- a/install/overseerr-install.sh +++ b/install/overseerr-install.sh @@ -18,13 +18,17 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 64f303b6..4ff708fd 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -20,20 +20,23 @@ $STD apt-get install -y mc $STD apt-get install -y gcc $STD apt-get install -y g++ $STD apt-get install -y git -$STD apt-get install -y gnupg $STD apt-get install -y make $STD apt-get install -y zip $STD apt-get install -y exiftool $STD apt-get install -y ffmpeg $STD apt-get install -y libheif1 +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -$STD apt-get -y install nodejs +$STD apt-get update +$STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Installing Golang" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index b8707308..89fa9d5b 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -33,7 +33,9 @@ $STD apt-get -y install \ pkg-config \ curl \ sudo \ - mc + mc \ + ca-certificates \ + gnupg msg_ok "Installed Dependencies" if [[ "$CTTYPE" == "0" ]]; then @@ -63,10 +65,12 @@ $STD apt-get -y install \ msg_ok "Installed GStreamer" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index 3d8801dd..357025b6 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -26,13 +26,17 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl sudo git mc $STD apt-get install -y make zip net-tools $STD apt-get install -y gcc g++ cmake +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh index c78a890e..44631596 100644 --- a/install/uptimekuma-install.sh +++ b/install/uptimekuma-install.sh @@ -18,14 +18,18 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" -$STD sudo apt-get install -y nodejs +$STD apt-get update +$STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Installing Uptime Kuma" diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index 32152da6..71171f54 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -18,13 +18,17 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_16.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 151d028b..0c3ed43b 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -21,13 +21,17 @@ $STD apt-get install -y git $STD apt-get install -y make $STD apt-get install -y g++ $STD apt-get install -y gcc +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" -$STD bash <(curl -fsSL https://deb.nodesource.com/setup_18.x) +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" +$STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" From 9a62e3ceeaae4b0ddbee4e490df78e06c3eeb180 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Sep 2023 08:27:13 -0400 Subject: [PATCH 5206/6505] Update wikijs.sh default Debian 12 --- ct/wikijs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/wikijs.sh b/ct/wikijs.sh index a8f58ce8..341c251d 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -20,11 +20,11 @@ EOF header_info echo -e "Loading..." APP="Wikijs" -var_disk="2" +var_disk="3" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From faf3bb8dd74b63fd7253d5ee5a8a18a6c29bcb31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Sep 2023 08:28:55 -0400 Subject: [PATCH 5207/6505] Update wikijs-install.sh node v18 fixes https://github.com/tteck/Proxmox/issues/1752 --- install/wikijs-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index 71171f54..7ad7e3f3 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -24,7 +24,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 145123220d450221e64c0e51344b0718853d4153 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Sep 2023 08:36:54 -0400 Subject: [PATCH 5208/6505] create /etc/apt/keyrings for Debian 11 --- ct/cronicle.sh | 3 ++- install/changedetection-install.sh | 1 + install/homarr-install.sh | 1 + install/homepage-install.sh | 1 + install/jellyseerr-install.sh | 1 + install/n8n-install.sh | 1 + install/node-red-install.sh | 1 + install/overseerr-install.sh | 1 + install/photoprism-install.sh | 1 + install/scrypted-install.sh | 1 + install/shinobi-install.sh | 1 + install/uptimekuma-install.sh | 1 + install/wikijs-install.sh | 1 + install/zigbee2mqtt-install.sh | 1 + 14 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 65ee9e8f..5421eef4 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -78,8 +78,9 @@ apt-get install -y gnupg &>/dev/null msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 1ff0af91..7ad0e307 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -54,6 +54,7 @@ $STD apt-get install -y \ msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 16348ea6..8ef64f09 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 264aa2ce..52dbd17e 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -26,6 +26,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index e310dda6..45e29472 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 2ee84d21..6a250703 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -22,6 +22,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/node-red-install.sh b/install/node-red-install.sh index d5985427..5b673133 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/overseerr-install.sh b/install/overseerr-install.sh index f3d47f23..86a4defa 100644 --- a/install/overseerr-install.sh +++ b/install/overseerr-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 4ff708fd..8a4e3da2 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -30,6 +30,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 89fa9d5b..348f0368 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -65,6 +65,7 @@ $STD apt-get -y install \ msg_ok "Installed GStreamer" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index 357025b6..94fe7bc2 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -31,6 +31,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh index 44631596..47f9ca24 100644 --- a/install/uptimekuma-install.sh +++ b/install/uptimekuma-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index 7ad7e3f3..cc2697c4 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 0c3ed43b..1e8b5089 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -26,6 +26,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" From 421ba29201836d8d5f1eb8fb4e7b574538219255 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Sep 2023 11:29:50 -0400 Subject: [PATCH 5209/6505] Update dashy-install.sh revert https://github.com/tteck/Proxmox/pull/1670 --- install/dashy-install.sh | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index e7de0462..f4819a83 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -42,7 +42,7 @@ export NODE_OPTIONS=--max-old-space-size=1000 $STD yarn build msg_ok "Installed Dashy" -msg_info "Creating Services" +msg_info "Creating Service" cat </etc/systemd/system/dashy.service [Unit] Description=dashy @@ -51,32 +51,11 @@ Description=dashy Type=simple WorkingDirectory=/dashy ExecStart=/usr/bin/yarn start -[Install] -WantedBy=multi-user.target -EOF - -cat </etc/systemd/system/dashy-rebuild.service -[Unit] -Description=Rebuild Dashy on Config Changes - -[Service] -Type=oneshot -ExecStart=/usr/bin/yarn --cwd=/dashy build -EOF - -cat </etc/systemd/system/dashy-rebuild.path -[Unit] -Description=Monitor Dashy Config for Changes - -[Path] -PathChanged=/dashy/public/conf.yml - [Install] WantedBy=multi-user.target EOF systemctl -q --now enable dashy -systemctl -q --now enable dashy-rebuild -msg_ok "Created Services" +msg_ok "Created Service" motd_ssh customize From 966c08a0618c4e5ac4681dab38cb6d177dd0f215 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 4 Sep 2023 09:37:56 -0400 Subject: [PATCH 5210/6505] Update wikijs.sh Fix backup directory path fixes https://github.com/tteck/Proxmox/issues/1760 --- ct/wikijs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/wikijs.sh b/ct/wikijs.sh index 341c251d..44027900 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -59,7 +59,7 @@ systemctl stop wikijs msg_ok "Stopped ${APP}" msg_info "Backing up Data" -mkdir -p data-backup +mkdir -p ~/data-backup cp -R /opt/wikijs/{db.sqlite,config.yml,/data} ~/data-backup msg_ok "Backed up Data" From a85593afa43095c4bd527748af7090e3e4840311 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Sep 2023 05:24:29 -0400 Subject: [PATCH 5211/6505] Update mikrotik-routeros.sh version 7.11.2 --- vm/mikrotik-routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 39a07919..78f7208a 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -234,7 +234,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Mikrotik RouterOS Disk Image" -URL=https://download.mikrotik.com/routeros/7.11/install-image-7.11.zip +URL=https://download.mikrotik.com/routeros/7.11.2/install-image-7.11.2.zip sleep 2 msg_ok "${CL}${BL}${URL}${CL}" From 347d8310e4af4214aa9f81ed115c5454891893c4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Sep 2023 11:39:29 -0400 Subject: [PATCH 5212/6505] fix copy-data file paths --- ...-assistant-container-copy-data-home-assistant-container.sh | 2 +- .../home-assistant-container-copy-data-home-assistant-core.sh | 2 +- ...ome-assistant-container-copy-data-podman-home-assistant.sh | 2 +- .../home-assistant-core-copy-data-home-assistant-container.sh | 2 +- .../home-assistant-core-copy-data-home-assistant-core.sh | 2 +- misc/copy-data/plex-copy-data-plex.sh | 2 +- ...odman-home-assistant-copy-data-home-assistant-container.sh | 2 +- misc/copy-data/z2m-copy-data-z2m.sh | 2 +- misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh | 4 ++++ 9 files changed, 12 insertions(+), 8 deletions(-) diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh index 0ff1828e..83ef60bd 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh @@ -125,4 +125,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Home Assistant LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)" diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh index f278911a..ff42886a 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh @@ -121,4 +121,4 @@ info "Successfully Transferred Data." # Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacontainer2hacore-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)" diff --git a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh index 62f9ed8b..ef003eb2 100644 --- a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh +++ b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh @@ -126,4 +126,4 @@ info "Successfully Transferred Data." # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/ha-copy-data-podman.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)" diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh index 3a451f17..c36c18cb 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh @@ -121,4 +121,4 @@ info "Successfully Transferred Data." # Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacore2hacontainer-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)" diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh index 5244c284..8589e367 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh @@ -116,4 +116,4 @@ info "Successfully Transferred Data." # Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/hacore2hacore-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)" diff --git a/misc/copy-data/plex-copy-data-plex.sh b/misc/copy-data/plex-copy-data-plex.sh index 35e43bea..851a8b6f 100644 --- a/misc/copy-data/plex-copy-data-plex.sh +++ b/misc/copy-data/plex-copy-data-plex.sh @@ -125,4 +125,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Plex Media Server LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/pms-copy-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/plex-copy-data-plex.sh)" diff --git a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh index 8db36359..1b159d10 100644 --- a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh +++ b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh @@ -126,4 +126,4 @@ info "Successfully Transferred Data." # Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/podman-copy-data-docker.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)" diff --git a/misc/copy-data/z2m-copy-data-z2m.sh b/misc/copy-data/z2m-copy-data-z2m.sh index 69a3573a..1fa6841e 100644 --- a/misc/copy-data/z2m-copy-data-z2m.sh +++ b/misc/copy-data/z2m-copy-data-z2m.sh @@ -125,4 +125,4 @@ info "Successfully Transferred Data." # Use to copy all data from one Zigbee2MQTT LXC to another # run from the Proxmox Shell -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/z2m-copy-data.sh)" +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/z2m-copy-data-z2m.sh)" diff --git a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh index 9f58fc5b..dd038ed7 100644 --- a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh +++ b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh @@ -124,3 +124,7 @@ rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PA echo -en "\e[1A\e[0K\e[1A\e[0K" info "Successfully Transferred Data." + +# Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC +# run from the Proxmox Shell +# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)" From d580ef30c00d53f974742d14807d13943a57b1a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Sep 2023 17:19:13 -0400 Subject: [PATCH 5213/6505] Update update-lxcs.sh new menu that allows you to choose which containers you want to exclude from the update process --- misc/update-lxcs.sh | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 4c293179..b8176b46 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -26,7 +26,7 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info while true; do - read -p "This Will Update All LXC Containers. Proceed(y/n)?" yn + read -p "This Will Update Selected LXC Containers. Proceed(y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; @@ -34,7 +34,20 @@ while true; do esac done clear -excluded_containers=("$@") +TITLE="Containers on node" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') +excluded_containers=$(whiptail --title "$TITLE" --checklist \ + "\nSelect containers to skip from updates:\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit function update_container() { container=$1 header_info @@ -56,14 +69,7 @@ function update_container() { } header_info for container in $(pct list | awk '{if(NR>1) print $1}'); do - excluded=false - for excluded_container in "${excluded_containers[@]}"; do - if [ "$container" == "$excluded_container" ]; then - excluded=true - break - fi - done - if [ "$excluded" == true ]; then + if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then header_info echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}" sleep 1 @@ -85,4 +91,4 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do done wait header_info -echo -e "${GN} Finished, All Containers Updated. ${CL} \n" +echo -e "${GN} Finished, Selected Containers Updated. ${CL} \n" From 858a00176db77c18d0f6bdf336ffd2d3f77c3719 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Sep 2023 17:21:43 -0400 Subject: [PATCH 5214/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aca2b545..4a1d16af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-05 + +### Changed + +- **Proxmox VE LXC Updater** + - Added a new menu that allows you to choose which containers you want to exclude from the update process. + ## 2023-09-01 ### Changed From fb572342634ca251aa73387b9de4b43255e2a1a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 00:34:31 -0400 Subject: [PATCH 5215/6505] Update clean-lxcs.sh add a new menu that allows you to choose which containers you want to exclude from the cleaning process. --- misc/clean-lxcs.sh | 66 ++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 447d8076..38bffa21 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -10,10 +10,10 @@ function header_info() { cat <<"EOF" ________ __ _ ________ / ____/ /__ ____ _____ / / | |/ / ____/ - / / / / _ \/ __ `/ __ \ / / | / / -/ /___/ / __/ /_/ / / / / / /___/ / /___ -\____/_/\___/\__,_/_/ /_/ /_____/_/|_\____/ - + / / / / _ \/ __ `/ __ \ / / | / / +/ /___/ / __/ /_/ / / / / / /___/ / /___ +\____/_/\___/\__,_/_/ /_/ /_____/_/|_\____/ + EOF } set -e @@ -33,6 +33,21 @@ while true; do esac done clear +TITLE="Containers on node" +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') +excluded_containers=$(whiptail --title "$TITLE" --checklist \ + "\nSelect containers to skip from cleaning:\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + function clean_container() { container=$1 header_info @@ -40,29 +55,36 @@ function clean_container() { echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" } - for container in $(pct list | awk '{if(NR>1) print $1}'); do - os=$(pct config "$container" | awk '/^ostype/ {print $2}') - if [ "$os" != "debian" ] && [ "$os" != "ubuntu" ]; then + if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then header_info - echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container is not Debian or Ubuntu ${CL} \n" + echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}" sleep 1 - continue - fi - status=$(pct status $container) - template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") - if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then - echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" - pct start $container - echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" - sleep 5 - clean_container $container - echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" - pct shutdown $container & - elif [ "$status" == "status: running" ]; then - clean_container $container + else + os=$(pct config "$container" | awk '/^ostype/ {print $2}') + if [ "$os" != "debian" ] && [ "$os" != "ubuntu" ]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container is not Debian or Ubuntu ${CL} \n" + sleep 1 + continue + fi + + status=$(pct status $container) + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then + echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" + pct start $container + echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" + sleep 5 + clean_container $container + echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" + pct shutdown $container & + elif [ "$status" == "status: running" ]; then + clean_container $container + fi fi done + wait header_info echo -e "${GN} Finished, Containers Cleaned. ${CL} \n" From 4362b74a340e57a4ec4d791f7b33c737ee455417 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 00:40:27 -0400 Subject: [PATCH 5216/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a1d16af..150f0d25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - **Proxmox VE LXC Updater** - Added a new menu that allows you to choose which containers you want to exclude from the update process. +- **Proxmox VE LXC Cleaner** + - Added a new menu that allows you to choose which containers you want to exclude from the clean process. ## 2023-09-01 From 9cfa05170024d731e4a5ceb8d74709d575a14f94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 00:52:15 -0400 Subject: [PATCH 5217/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 150f0d25..7d8b4a79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,14 +4,19 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-06 + +### Changed + +- **Proxmox VE LXC Cleaner** + - Added a new menu that allows you to choose which containers you want to exclude from the clean process. + ## 2023-09-05 ### Changed - **Proxmox VE LXC Updater** - Added a new menu that allows you to choose which containers you want to exclude from the update process. -- **Proxmox VE LXC Cleaner** - - Added a new menu that allows you to choose which containers you want to exclude from the clean process. ## 2023-09-01 From b8ebc36c511273b87238b1c29d5c1780cfb55f4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 02:59:48 -0400 Subject: [PATCH 5218/6505] Update clean-lxcs.sh tweak --- misc/clean-lxcs.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 38bffa21..a595f1f3 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -25,7 +25,7 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info while true; do - read -p "This Will Clean logs, cache and update apt lists on all LXC Containers. Proceed(y/n)?" yn + read -p "This Will Clean logs, cache and update apt lists on selected LXC Containers. Proceed(y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; @@ -33,7 +33,7 @@ while true; do esac done clear -TITLE="Containers on node" +NODE=$(hostname) while read -r line; do TAG=$(echo "$line" | awk '{print $1}') ITEM=$(echo "$line" | awk '{print substr($0,36)}') @@ -43,7 +43,7 @@ while read -r line; do fi CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') -excluded_containers=$(whiptail --title "$TITLE" --checklist \ +excluded_containers=$(whiptail --title "Containers on $NODE" --checklist \ "\nSelect containers to skip from cleaning:\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit From 544f163e1598ebfa147d85d4f72890263083e9a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 03:01:10 -0400 Subject: [PATCH 5219/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index b8176b46..5bc0f978 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -34,7 +34,7 @@ while true; do esac done clear -TITLE="Containers on node" +NODE=$(hostname) while read -r line; do TAG=$(echo "$line" | awk '{print $1}') ITEM=$(echo "$line" | awk '{print substr($0,36)}') @@ -44,7 +44,7 @@ while read -r line; do fi CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') -excluded_containers=$(whiptail --title "$TITLE" --checklist \ +excluded_containers=$(whiptail --title "Containers on $NODE" --checklist \ "\nSelect containers to skip from updates:\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit From b3777abadca5a49a5d355ffeb4fdd9bde36cedf4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 03:28:41 -0400 Subject: [PATCH 5220/6505] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 466cfa26..c27d9e2b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@

    Contributing to Proxmox VE Helper Scripts

    -These scripts enable users to build a Linux container or virtual machine in an interactive manner, offering options for both basic and advanced configurations. The basic setup utilizes default settings, whereas the advanced setup empowers users to alter these default settings. Through the use of the whiptail command, options are presented to users in a dialog box format. After the user makes their selections, the script collects and verifies the user's input in order to generate the final configuration for the container or virtual machine. +These scripts empower users to create a Linux container or virtual machine interactively, providing choices for both simple and advanced configurations. The basic setup adheres to default settings, while the advanced setup gives users the ability to customize these defaults. Utilizing the whiptail command, options are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine.

    Proxmox VE Helper Scripts

    -
    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.
    -

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources.

    +

    Exercise caution and conduct a comprehensive assessment of scripts and automation tasks acquired from external sources.

    Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.
    From 186230591ba9da31100ac986411c2ce4dc4299da Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 14:24:44 -0400 Subject: [PATCH 5221/6505] Update add-tailscale-lxc.sh added a menu that enables you to choose the specific container where you want to install Tailscale. --- misc/add-tailscale-lxc.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 52de7c9f..4020ac43 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -17,9 +17,8 @@ EOF } clear header_info -echo -e "\e[1;33mThis script will add Tailscale to an existing LXC Container ONLY\e[0m" while true; do - read -p "Did you replace 106 with your LXC ID? Proceed(y/n)?" yn + read -p "This will add Tailscale to an existing LXC Container ONLY. Proceed(y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; @@ -48,7 +47,24 @@ function msg() { echo -e "$TEXT" } -CTID=$1 +NODE=$(hostname) +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') + +while [ -z "${CTID:+x}" ]; do + CTID=$(whiptail --title "Containers on $NODE" --radiolist \ + "\nSelect a container to add Tailscale to:\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done + CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf cat <>$CTID_CONFIG_PATH lxc.cgroup2.devices.allow: c 10:200 rwm From 4d32c6eda67137567bcc3f24aaa7b6909416937f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 14:31:22 -0400 Subject: [PATCH 5222/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d8b4a79..27516c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - **Proxmox VE LXC Cleaner** - Added a new menu that allows you to choose which containers you want to exclude from the clean process. +- **Tailscale** + - Added a menu that enables you to choose the specific container where you want to install Tailscale.. ## 2023-09-05 From 56c946abf4f875d737eccb39f269eb78c44b4c24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 18:45:37 -0400 Subject: [PATCH 5223/6505] tweaks --- misc/frigate-support.sh | 90 +++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/misc/frigate-support.sh b/misc/frigate-support.sh index 21b641d5..849052f1 100644 --- a/misc/frigate-support.sh +++ b/misc/frigate-support.sh @@ -5,55 +5,43 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -echo -e "\e[1;33m This script will Prepare a LXC Container for Frigate \e[0m" +function header_info { + clear +cat <<"EOF" + ____ _ __ ____ __ + / __/___(_)__ ____ _/ /____ / __/_ _____ ___ ___ ____/ /_ + / _// __/ / _ `/ _ `/ __/ -_) _\ \/ // / _ \/ _ \/ _ \/ __/ __/ +/_/ /_/ /_/\_, /\_,_/\__/\__/ /___/\_,_/ .__/ .__/\___/_/ \__/ + /___/ /_/ /_/ +EOF +} +header_info while true; do - read -p "Did you replace 106 with your LXC ID? Proceed (y/n)?" yn + read -p "This will Prepare a LXC Container for Frigate. Proceed (y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; *) echo "Please answer yes or no." ;; esac done -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR -trap cleanup EXIT +header_info -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" - exit $EXIT -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null - -CHAR_DEVS+=("1:1") -CHAR_DEVS+=("29:0") -CHAR_DEVS+=("188:.*") -CHAR_DEVS+=("189:.*") -CHAR_DEVS+=("226:0") -CHAR_DEVS+=("226:128") +# The array of device types +# CHAR_DEVS+=(major:minor) +CHAR_DEVS+=("1:1") # mem +CHAR_DEVS+=("29:0") # fb0 +CHAR_DEVS+=("188:.*") # ttyUSB* +CHAR_DEVS+=("189:.*") # bus/usb/* +CHAR_DEVS+=("226:0") # card0 +CHAR_DEVS+=("226:128") # renderD128 +# Proccess char device string for char_dev in ${CHAR_DEVS[@]}; do [ ! -z "${CHAR_DEV_STRING-}" ] && CHAR_DEV_STRING+=" -o" CHAR_DEV_STRING+=" -regex \".*/${char_dev}\"" done +# Store autodev hook script in a variable read -r -d '' HOOK_SCRIPT <<-EOF || true for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do dev="/dev/\$(sed -n "/DEVNAME/ s/^.*=\(.*\)$/\1/p" \${char_dev}/uevent)"; @@ -65,9 +53,31 @@ for char_dev in \$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do cp -dpR \$dev \${LXC_ROOTFS_MOUNT}\${dev}; done; EOF + +# Remove newline char from the variable HOOK_SCRIPT=${HOOK_SCRIPT//$'\n'/} -CTID=$1 +# Generate menu of LXC containers in current node +NODE=$(hostname) +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') + +# Selection menu for LXC containers +while [ -z "${CTID:+x}" ]; do + CTID=$(whiptail --title "Containers on $NODE" --radiolist \ + "\nSelect a container to add support:\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done + +# Add autodev settings CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf cat CTID.conf >$CTID_CONFIG_PATH @@ -76,8 +86,8 @@ cat <>$CTID_CONFIG_PATH lxc.autodev: 1 lxc.hook.autodev: bash -c '$HOOK_SCRIPT' EOF -echo -e "\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \e[0m" +echo -e "\e[1;33m \nFinished....Reboot ${CTID} LXC to apply the changes.\n \e[0m" -# In the Proxmox web shell run (replace 106 with your LXC ID) -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/frigate-support.sh)" -s 106 -# Reboot the LXC to apply the changes +# In the Proxmox web shell run +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/frigate-support.sh)" +# Reboot the LXC to apply the changes \ No newline at end of file From 8e75d8cb1f53c5cf2a8dacb389e2f72d8348876d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Sep 2023 18:58:18 -0400 Subject: [PATCH 5224/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27516c62..500c1b91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ - **Proxmox VE LXC Cleaner** - Added a new menu that allows you to choose which containers you want to exclude from the clean process. - **Tailscale** - - Added a menu that enables you to choose the specific container where you want to install Tailscale.. + - Added a menu that enables you to choose the specific container where you want to install Tailscale. ## 2023-09-05 From 1e372141f1de277b980cad0096efa80a4bec2874 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Sep 2023 16:06:51 -0400 Subject: [PATCH 5225/6505] Create host-backup.sh --- misc/host-backup.sh | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 misc/host-backup.sh diff --git a/misc/host-backup.sh b/misc/host-backup.sh new file mode 100644 index 00000000..9a681d7a --- /dev/null +++ b/misc/host-backup.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear +cat <<"EOF" + __ __ __ ___ __ + / // /__ ___ / /_ / _ )___ _____/ /____ _____ + / _ / _ \(_-&1 1>&2 2>&3) || exit + + for selected_dir in ${HOST_BACKUP//\"}; do + selected_directories+=("/etc/$selected_dir") + done +done + +selected_directories_string=$(printf "%s " "${selected_directories[@]}") +header_info +echo -e "This will create backups for the directories \e[1;33m ${selected_directories_string% } \e[0m" +read -p "Press ENTER to continue..." +header_info +tar -czf $BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz --absolute-names ${selected_directories_string% } + +echo -e "\nFinished" +echo -e "\e[1;33m \nA backup is rendered ineffective when it remains stored on the host.\n \e[0m" From 9d96fae50bbfd485b5eae47d01eb91ff068be641 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Sep 2023 16:40:14 -0400 Subject: [PATCH 5226/6505] Update host-backup.sh tweak --- misc/host-backup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/host-backup.sh b/misc/host-backup.sh index 9a681d7a..b1c82510 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -37,12 +37,12 @@ while read -r dir; do MSG_MAX_LENGTH=$((${#DIRNAME} + $OFFSET)) fi CTID_MENU+=("$DIRNAME" "$dir " "OFF") -done < <(ls -d /etc/*/) +done < <(ls -d /etc/*) while [ -z "${HOST_BACKUP:+x}" ]; do HOST_BACKUP=$(whiptail --title "Select Directories" --checklist \ "\nSelect what directories to backup:\n" \ - 16 $(($MSG_MAX_LENGTH + 38)) 6 \ + 16 $(($MSG_MAX_LENGTH + 58)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit for selected_dir in ${HOST_BACKUP//\"}; do From 1e04051b673a4bd114eaa4e52e2a530a44790676 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Sep 2023 16:51:29 -0400 Subject: [PATCH 5227/6505] Update host-backup.sh tweak --- misc/host-backup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/host-backup.sh b/misc/host-backup.sh index b1c82510..d24779e8 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -17,7 +17,7 @@ EOF } header_info while true; do - read -p "This will Backup Selected Directories. Proceed (y/n)?" yn + read -p "This will backup specific files and directories within the 'etc' directory. Proceed (y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; @@ -40,8 +40,8 @@ while read -r dir; do done < <(ls -d /etc/*) while [ -z "${HOST_BACKUP:+x}" ]; do - HOST_BACKUP=$(whiptail --title "Select Directories" --checklist \ - "\nSelect what directories to backup:\n" \ + HOST_BACKUP=$(whiptail --title "SELECTIONS" --checklist \ + "\nSelect what files/directories to backup:\n" \ 16 $(($MSG_MAX_LENGTH + 58)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit From c8f73eb38fd24a7a2b7961b156d62c26e08e2f1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Sep 2023 17:52:30 -0400 Subject: [PATCH 5228/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 500c1b91..abc22ed1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-07 + +### Changed + +- **Host Backup** + - NEW Script + ## 2023-09-06 ### Changed From 5fecbd44e9cfefdb8628bded91f61609ca22a94d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 7 Sep 2023 19:04:21 -0400 Subject: [PATCH 5229/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abc22ed1..c624dda2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ### Changed -- **Host Backup** +- **Proxmox VE Host Backup** - NEW Script ## 2023-09-06 From ab394e04aba4696e205e20306a99bf940f4bd296 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Sep 2023 06:02:47 -0400 Subject: [PATCH 5230/6505] Update filebrowser.sh use latest --- misc/filebrowser.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index 81958d23..b4e40fd1 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -68,7 +68,7 @@ function msg_ok() { msg_info "Installing ${APP}" RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') -curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null +curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null From e48b2bd0dfdd64ea0b4a4d44cb9689a5e6a6e55f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Sep 2023 14:40:53 -0400 Subject: [PATCH 5231/6505] Update homarr.sh modify git update --- ct/homarr.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index dd06a8ff..514d49c0 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -56,13 +56,19 @@ if [[ ! -d /opt/homarr ]]; then msg_error "No ${APP} Installation Found!"; exit; msg_info "Updating $APP" systemctl stop homarr cd /opt/homarr -output=$(git pull) -git pull &>/dev/null +output=$(git pull 2>&1) if echo "$output" | grep -q "Already up to date." then - msg_ok " $APP is already up to date." + msg_ok "$APP is already up to date." systemctl start homarr - exit +else + if ! git pull; then + echo "Update failed, temporarily storing changes and trying again." + git stash && git pull || ( + echo "Update failed even after storing changes. Aborting." + exit 1 + ) + fi fi yarn install &>/dev/null yarn build &>/dev/null From 8c0155e64bbf163712fbe49305cd06879ce71ce4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Sep 2023 15:00:34 -0400 Subject: [PATCH 5232/6505] Update homarr.sh modify git update --- ct/homarr.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index 514d49c0..3816ca6d 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -58,22 +58,22 @@ systemctl stop homarr cd /opt/homarr output=$(git pull 2>&1) if echo "$output" | grep -q "Already up to date." -then - msg_ok "$APP is already up to date." - systemctl start homarr -else - if ! git pull; then - echo "Update failed, temporarily storing changes and trying again." - git stash && git pull || ( + then + msg_ok "$APP is already up to date." + systemctl start homarr + else + if ! git pull; then + echo "Update failed, temporarily storing changes and trying again." + git stash && git pull || ( echo "Update failed even after storing changes. Aborting." exit 1 ) - fi + yarn install &>/dev/null + yarn build &>/dev/null + systemctl start homarr + msg_ok "Updated $APP" + fi fi -yarn install &>/dev/null -yarn build &>/dev/null -systemctl start homarr -msg_ok "Updated $APP" exit } From e52b7872d27b68d283abfc05a222dd7134528059 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Sep 2023 21:43:08 -0400 Subject: [PATCH 5233/6505] Update homarr.sh redo update fixes https://github.com/tteck/Proxmox/issues/1774 --- ct/homarr.sh | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index 3816ca6d..4f327ec7 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -56,24 +56,15 @@ if [[ ! -d /opt/homarr ]]; then msg_error "No ${APP} Installation Found!"; exit; msg_info "Updating $APP" systemctl stop homarr cd /opt/homarr -output=$(git pull 2>&1) -if echo "$output" | grep -q "Already up to date." - then - msg_ok "$APP is already up to date." - systemctl start homarr - else - if ! git pull; then - echo "Update failed, temporarily storing changes and trying again." - git stash && git pull || ( - echo "Update failed even after storing changes. Aborting." - exit 1 - ) - yarn install &>/dev/null - yarn build &>/dev/null - systemctl start homarr - msg_ok "Updated $APP" - fi -fi +cp -R data data-backup +git stash &>/dev/null +git pull &>/dev/null +yarn install &>/dev/null +yarn build &>/dev/null +cp -R data-backup/* data +rm -rf data-backup +systemctl start homarr +msg_ok "Updated $APP" exit } From 6fae1fc557508c42ab18bc9beaff42e4a9955a77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Sep 2023 05:13:17 -0400 Subject: [PATCH 5234/6505] add backtitle --- ct/alpine-docker.sh | 2 +- ct/alpine-grafana.sh | 2 +- ct/alpine-vaultwarden.sh | 4 +- ct/alpine-zigbee2mqtt.sh | 2 +- ct/alpine.sh | 2 +- ct/archlinux.sh | 44 ++++++------- ct/create_lxc.sh | 2 +- ct/cronicle.sh | 2 +- ct/homeassistant-core.sh | 4 +- ct/homeassistant.sh | 2 +- ct/node-red.sh | 4 +- ct/paperless-ngx.sh | 2 +- ct/plex.sh | 2 +- ct/podman-homeassistant.sh | 2 +- ct/vaultwarden.sh | 4 +- ct/wireguard.sh | 2 +- misc/add-tailscale-lxc.sh | 2 +- misc/build.func | 66 +++++++++---------- misc/clean-lxcs.sh | 2 +- ...iner-copy-data-home-assistant-container.sh | 6 +- ...container-copy-data-home-assistant-core.sh | 6 +- ...ntainer-copy-data-podman-home-assistant.sh | 6 +- ...core-copy-data-home-assistant-container.sh | 6 +- ...tant-core-copy-data-home-assistant-core.sh | 6 +- misc/copy-data/plex-copy-data-plex.sh | 6 +- ...tant-copy-data-home-assistant-container.sh | 6 +- misc/copy-data/z2m-copy-data-z2m.sh | 6 +- .../zwavejs2mqtt-copy-data-zwavejsui.sh | 6 +- misc/cron-update-lxcs.sh | 2 +- misc/frigate-support.sh | 2 +- misc/host-backup.sh | 2 +- misc/monitor-all.sh | 2 +- misc/pbs3-upgrade.sh | 14 ++-- misc/post-pbs-install.sh | 18 ++--- misc/post-pve-install.sh | 26 ++++---- misc/pve8-upgrade.sh | 14 ++-- misc/update-lxcs.sh | 2 +- turnkey/turnkey-core.sh | 2 +- turnkey/turnkey-fileserver.sh | 2 +- turnkey/turnkey-gitea.sh | 2 +- turnkey/turnkey-gitlab.sh | 2 +- turnkey/turnkey-mediaserver.sh | 2 +- turnkey/turnkey-nextcloud.sh | 2 +- turnkey/turnkey-observium.sh | 2 +- turnkey/turnkey-openvpn.sh | 2 +- turnkey/turnkey-owncloud.sh | 2 +- turnkey/turnkey-torrentserver.sh | 2 +- turnkey/turnkey-wordpress.sh | 2 +- turnkey/turnkey-zoneminder.sh | 2 +- vm/haos-vm.sh | 36 +++++----- vm/mikrotik-routeros.sh | 26 ++++---- vm/openwrt.sh | 38 +++++------ vm/pimox-haos-vm.sh | 28 ++++---- 53 files changed, 220 insertions(+), 220 deletions(-) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 9806f568..2a0c46eb 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -57,7 +57,7 @@ function update_script() { fi while true; do CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ + whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \ "1" "Check for Docker Updates" 3>&2 2>&1 1>&3 ) exit_status=$? diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 6b82788a..f891e48d 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -58,7 +58,7 @@ function update_script() { LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 3 \ + whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \ "1" "Check for Grafana Updates" \ "2" "Allow 0.0.0.0 for listening" \ "3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3 diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 32b9f946..6add4976 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -57,7 +57,7 @@ function update_script() { fi while true; do CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 2 \ + whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 2 \ "1" "Update Vaultwarden" \ "2" "Reset ADMIN_TOKEN" 3>&2 2>&1 1>&3 ) @@ -73,7 +73,7 @@ function update_script() { exit ;; 2) - if NEWTOKEN=$(whiptail --passwordbox "Setup your ADMIN_TOKEN (make it strong)" 10 58 3>&1 1>&2 2>&3); then + if NEWTOKEN=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Setup your ADMIN_TOKEN (make it strong)" 10 58 3>&1 1>&2 2>&3); then if [[ -z "$NEWTOKEN" ]]; then exit-script; fi if ! command -v argon2 >/dev/null 2>&1; then apk add argon2 &>/dev/null; fi TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1) diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index d00fcf4c..1a0f92b4 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -57,7 +57,7 @@ function update_script() { fi while true; do CHOICE=$( - whiptail --title "SUPPORT" --menu "Select option" 11 58 1 \ + whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \ "1" "Check for Zigbee2MQTT Updates" 3>&2 2>&1 1>&3 ) exit_status=$? diff --git a/ct/alpine.sh b/ct/alpine.sh index 3be89e7b..f134cac0 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -52,7 +52,7 @@ function default_settings() { } function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 1 \ +UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 1 \ "1" "Check for Alpine Updates" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/archlinux.sh b/ct/archlinux.sh index f7b8e6cc..75e4119d 100644 --- a/ct/archlinux.sh +++ b/ct/archlinux.sh @@ -129,7 +129,7 @@ function exit-script() { } function advanced_settings() { -if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ +if CT_TYPE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" ON \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3); then @@ -138,7 +138,7 @@ else exit-script fi -if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then +if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then PW1="Automatic Login" PW=" " @@ -150,7 +150,7 @@ else exit-script fi -if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then +if CT_ID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then if [ -z "$CT_ID" ]; then CT_ID="$NEXTID" echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" @@ -161,7 +161,7 @@ else exit fi -if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then +if CT_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then if [ -z "$CT_NAME" ]; then HN="$NSAPP" else @@ -172,7 +172,7 @@ else exit-script fi -if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then +if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then if [ -z "$DISK_SIZE" ]; then DISK_SIZE="$var_disk" echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" @@ -187,7 +187,7 @@ else exit-script fi -if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then +if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then if [ -z "$CORE_COUNT" ]; then CORE_COUNT="$var_cpu" echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" @@ -198,7 +198,7 @@ else exit-script fi -if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then +if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then if [ -z "$RAM_SIZE" ]; then RAM_SIZE="$var_ram" echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" @@ -209,7 +209,7 @@ else exit-script fi -if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then +if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then if [ -z "$BRG" ]; then BRG="vmbr0" echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" @@ -220,7 +220,7 @@ else exit-script fi -if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then +if NET=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $NET ]; then NET="dhcp" echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" @@ -230,7 +230,7 @@ if NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --t else exit-script fi -if GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then +if GATE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then if [ -z $GATE1 ]; then GATE1="Default" GATE="" @@ -242,14 +242,14 @@ else exit-script fi -if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" else DISABLEIP6="no" fi echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" -if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then +if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then MTU1="Default" MTU="" @@ -261,7 +261,7 @@ else exit-script fi -if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then +if SD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then SX=Host SD="" @@ -274,7 +274,7 @@ else exit-script fi -if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then +if NX=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then if [ -z $NX ]; then NX=Host NS="" @@ -286,7 +286,7 @@ else exit-script fi -if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then +if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then MAC1="Default" MAC="" @@ -298,7 +298,7 @@ else exit-script fi -if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then +if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN="" @@ -310,21 +310,21 @@ else exit-script fi -if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then SSH="yes" else SSH="no" fi echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" -if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then VERB="yes" else VERB="no" fi echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" -if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -339,7 +339,7 @@ ARCH_CHECK PVE_CHECK NEXTID=$(pvesh get /cluster/nextid) header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings @@ -361,7 +361,7 @@ exit } if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then clear echo -e "⚠ User exited script \n" exit @@ -370,7 +370,7 @@ if command -v pveversion >/dev/null 2>&1; then fi if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then clear echo -e "⚠ User exited script \n" exit diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 557d88eb..1cd31ba0 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -100,7 +100,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\nTo make a selection, use the Spacebar.\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || exit "Menu aborted." diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 5421eef4..4d59253a 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -51,7 +51,7 @@ function default_settings() { } function update_script() { -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ +UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ "2" "Install ${APP} Worker" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 024b0be5..7b14b802 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -57,7 +57,7 @@ function update_script() { fi PY=$(ls /srv/homeassistant/lib/) IP=$(hostname -I | awk '{print $1}') - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update Core" ON \ "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ @@ -65,7 +65,7 @@ function update_script() { 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then - if (whiptail --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SELECT BRANCH" --yesno "Use Beta Branch?" 10 58); then clear header_info echo -e "${GN}Updating to Beta Version${CL}" diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 51a46299..3c1abf63 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -56,7 +56,7 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update ALL Containers" ON \ "2" "Remove ALL Unused Images" OFF \ "3" "Install HACS" OFF \ diff --git a/ct/node-red.sh b/ct/node-red.sh index f95388a1..029bbae8 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { if [[ ! -d /root/.node-red ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ +UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ "2" "Install Themes" OFF \ 3>&1 1>&2 2>&3) @@ -73,7 +73,7 @@ msg_ok "Update Successful" exit fi if [ "$UPD" == "2" ]; then -THEME=$(whiptail --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ +THEME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ "dark" "" OFF \ "dracula" "" OFF \ "midnight-red" "" ON \ diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index c58a3004..31277348 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -59,7 +59,7 @@ function update_script() { RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') SER=/etc/systemd/system/paperless-task-queue.service - UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update Paperless-ngx to $RELEASE" ON \ "2" "Paperless-ngx Credentials" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/plex.sh b/ct/plex.sh index ac09683a..77cf02a7 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ +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) diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index a1c8c4fc..14c2ed98 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -56,7 +56,7 @@ function default_settings() { function update_script() { if [[ ! -f /etc/systemd/system/homeassistant.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi - UPD=$(whiptail --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update system and containers" ON \ "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 2d326b6c..b804f195 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -62,7 +62,7 @@ function update_script() { grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ + UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ "1" "VaultWarden $VAULT" ON \ "2" "Web-Vault $WVRELEASE" OFF \ "3" "Set Admin Token" OFF \ @@ -121,7 +121,7 @@ function update_script() { exit fi if [ "$UPD" == "3" ]; then - if NEWTOKEN=$(whiptail --passwordbox "Set the ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then + if NEWTOKEN=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Set the ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then if [[ -z "$NEWTOKEN" ]]; then exit; fi if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 60156f2e..828697d9 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { if [[ ! -d /etc/pivpn/wireguard ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -UPD=$(whiptail --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ +UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP} LXC" ON \ "2" "Install WGDashboard" OFF \ 3>&1 1>&2 2>&3) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 4020ac43..a4661001 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -59,7 +59,7 @@ while read -r line; do done < <(pct list | awk 'NR>1') while [ -z "${CTID:+x}" ]; do - CTID=$(whiptail --title "Containers on $NODE" --radiolist \ + CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --radiolist \ "\nSelect a container to add Tailscale to:\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit diff --git a/misc/build.func b/misc/build.func index 43925d1b..c1c9394f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -55,7 +55,7 @@ msg_error() { # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - whiptail --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters. \n Default distribution for $APP LXC is ${var_os} ${var_version}" 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters. \n Default distribution for $APP LXC is ${var_os} ${var_version}" 10 58 fi if ! pveversion | grep -Eq "pve-manager/(7\.[0-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" @@ -80,7 +80,7 @@ arch_check() { ssh_check() { if command -v pveversion >/dev/null 2>&1; then if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then echo "you've been warned" else clear @@ -127,12 +127,12 @@ exit-script() { # This function allows the user to configure advanced settings for the script. advanced_settings() { - whiptail --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - whiptail --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n" 8 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n" 8 58 if [ "$var_os" != "alpine" ]; then var_os="" while [ -z "$var_os" ]; do - if var_os=$(whiptail --title "DISTRIBUTION" --radiolist "Choose Distribution:" 10 58 2 \ + if var_os=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISTRIBUTION" --radiolist "Choose Distribution:" 10 58 2 \ "debian" "" OFF \ "ubuntu" "" OFF \ 3>&1 1>&2 2>&3); then @@ -148,7 +148,7 @@ advanced_settings() { if [ "$var_os" == "debian" ]; then var_version="" while [ -z "$var_version" ]; do - if var_version=$(whiptail --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ + if var_version=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DEBIAN VERSION" --radiolist "Choose Version" 10 58 2 \ "11" "Bullseye" OFF \ "12" "Bookworm" OFF \ 3>&1 1>&2 2>&3); then @@ -164,7 +164,7 @@ advanced_settings() { if [ "$var_os" == "ubuntu" ]; then var_version="" while [ -z "$var_version" ]; do - if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ + if var_version=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "20.04" "Focal" OFF \ "22.04" "Jammy" OFF \ "23.04" "Lunar" OFF \ @@ -180,7 +180,7 @@ advanced_settings() { CT_TYPE="" while [ -z "$CT_TYPE" ]; do - if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ + if CT_TYPE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ "1" "Unprivileged" OFF \ "0" "Privileged" OFF \ 3>&1 1>&2 2>&3); then @@ -192,7 +192,7 @@ advanced_settings() { fi done - if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [ -z $PW1 ]; then PW1="Automatic Login" PW="" @@ -204,7 +204,7 @@ advanced_settings() { exit-script fi - if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then + if CT_ID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then if [ -z "$CT_ID" ]; then CT_ID="$NEXTID" echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" @@ -215,7 +215,7 @@ advanced_settings() { exit fi - if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then + if CT_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then if [ -z "$CT_NAME" ]; then HN="$NSAPP" else @@ -226,7 +226,7 @@ advanced_settings() { exit-script fi - if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then + if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then if [ -z "$DISK_SIZE" ]; then DISK_SIZE="$var_disk" echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" @@ -241,7 +241,7 @@ advanced_settings() { exit-script fi - if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then if [ -z "$CORE_COUNT" ]; then CORE_COUNT="$var_cpu" echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" @@ -252,7 +252,7 @@ advanced_settings() { exit-script fi - if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then if [ -z "$RAM_SIZE" ]; then RAM_SIZE="$var_ram" echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" @@ -263,7 +263,7 @@ advanced_settings() { exit-script fi - if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then if [ -z "$BRG" ]; then BRG="vmbr0" echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" @@ -275,7 +275,7 @@ advanced_settings() { fi while true; do - NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) + NET=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3) exit_status=$? if [ $exit_status -eq 0 ]; then if [ "$NET" = "dhcp" ]; then @@ -286,7 +286,7 @@ advanced_settings() { echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" break else - whiptail --msgbox "$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'" 8 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox "$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'" 8 58 fi fi else @@ -296,11 +296,11 @@ advanced_settings() { if [ "$NET" != "dhcp" ]; then while true; do - GATE1=$(whiptail --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) + GATE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Enter gateway IP address" 8 58 --title "Gateway IP" 3>&1 1>&2 2>&3) if [ -z "$GATE1" ]; then - whiptail --msgbox "Gateway IP address cannot be empty" 8 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox "Gateway IP address cannot be empty" 8 58 elif [[ ! "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - whiptail --msgbox "Invalid IP address format" 8 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox "Invalid IP address format" 8 58 else GATE=",gw=$GATE1" echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" @@ -312,14 +312,14 @@ advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" fi - if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" else DISABLEIP6="no" fi echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then MTU1="Default" MTU="" @@ -331,7 +331,7 @@ advanced_settings() { exit-script fi - if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then + if SD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then if [ -z $SD ]; then SX=Host SD="" @@ -344,7 +344,7 @@ advanced_settings() { exit-script fi - if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then + if NX=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then if [ -z $NX ]; then NX=Host NS="" @@ -356,7 +356,7 @@ advanced_settings() { exit-script fi - if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then MAC1="Default" MAC="" @@ -368,7 +368,7 @@ advanced_settings() { exit-script fi - if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN="" @@ -381,7 +381,7 @@ advanced_settings() { fi if [[ "$PW" == -password* ]]; then - if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then SSH="yes" else SSH="no" @@ -393,7 +393,7 @@ advanced_settings() { fi if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then FUSE="yes" else FUSE="no" @@ -401,14 +401,14 @@ advanced_settings() { echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" fi - if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then VERB="yes" else VERB="no" fi echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" else clear @@ -428,7 +428,7 @@ install_script() { NEXTID=$(pvesh get /cluster/nextid) timezone=$(cat /etc/timezone) header_info - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings @@ -441,7 +441,7 @@ install_script() { start() { if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then + if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then clear echo -e "⚠ User exited script \n" exit @@ -450,7 +450,7 @@ start() { fi if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then clear echo -e "⚠ User exited script \n" exit diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index a595f1f3..2614846b 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -43,7 +43,7 @@ while read -r line; do fi CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') -excluded_containers=$(whiptail --title "Containers on $NODE" --checklist \ +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist \ "\nSelect containers to skip from cleaning:\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh index 83ef60bd..9da8f68a 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh @@ -68,13 +68,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -85,7 +85,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.23" 13 50 || exit diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh index ff42886a..19a0975c 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh @@ -66,13 +66,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Container LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Core LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -83,7 +83,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.10.02" 13 50 || exit diff --git a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh index ef003eb2..01ac7b82 100644 --- a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh +++ b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh @@ -68,13 +68,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Podman LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -85,7 +85,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.02.12" 13 50 || exit diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh index c36c18cb..e2ae0eec 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh @@ -66,13 +66,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Core LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Container LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -83,7 +83,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.10.02" 13 50 || exit diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh index 8589e367..7603e8a1 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh @@ -61,13 +61,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Core LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Core LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -78,7 +78,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.10.03" 13 50 || exit diff --git a/misc/copy-data/plex-copy-data-plex.sh b/misc/copy-data/plex-copy-data-plex.sh index 851a8b6f..58ef49f0 100644 --- a/misc/copy-data/plex-copy-data-plex.sh +++ b/misc/copy-data/plex-copy-data-plex.sh @@ -68,13 +68,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich Plex Media Server LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich Plex Media Server LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -85,7 +85,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.24" 13 50 || exit diff --git a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh index 1b159d10..0d8a6542 100644 --- a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh +++ b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh @@ -68,13 +68,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA Podman LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich HA LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -85,7 +85,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.03.31" 13 50 || exit diff --git a/misc/copy-data/z2m-copy-data-z2m.sh b/misc/copy-data/z2m-copy-data-z2m.sh index 1fa6841e..ee69da79 100644 --- a/misc/copy-data/z2m-copy-data-z2m.sh +++ b/misc/copy-data/z2m-copy-data-z2m.sh @@ -68,13 +68,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich Zigbee2MQTT LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich Zigbee2MQTT LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -85,7 +85,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.01.23" 13 50 || exit diff --git a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh index dd038ed7..c4375761 100644 --- a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh +++ b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh @@ -69,13 +69,13 @@ while read -r line; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') while [ -z "${CTID_FROM:+x}" ]; do - CTID_FROM=$(whiptail --title "$TITLE" --radiolist \ + CTID_FROM=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich Zwavejs2MQTT LXC would you like to copy FROM?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit done while [ -z "${CTID_TO:+x}" ]; do - CTID_TO=$(whiptail --title "$TITLE" --radiolist \ + CTID_TO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$TITLE" --radiolist \ "\nWhich Z-wave JS UI LXC would you like to copy TO?\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit @@ -86,7 +86,7 @@ for i in ${!CTID_MENU[@]}; do [ "${CTID_MENU[$i]}" == "$CTID_TO" ] && CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]}) done -whiptail --defaultno --title "$TITLE" --yesno \ +whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ "Are you sure you want to copy data between the following LXCs? $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.09.21" 13 50 || exit diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 3cd4d9be..9fa9b549 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -39,7 +39,7 @@ remove() { OPTIONS=(Add "Add Crontab Schedule" Remove "Remove Crontab Schedule") -CHOICE=$(whiptail --title "Cron Update LXCs" --menu "Select an option:" 10 58 2 \ +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Cron Update LXCs" --menu "Select an option:" 10 58 2 \ "${OPTIONS[@]}" 3>&1 1>&2 2>&3) case $CHOICE in diff --git a/misc/frigate-support.sh b/misc/frigate-support.sh index 849052f1..88e43ea1 100644 --- a/misc/frigate-support.sh +++ b/misc/frigate-support.sh @@ -71,7 +71,7 @@ done < <(pct list | awk 'NR>1') # Selection menu for LXC containers while [ -z "${CTID:+x}" ]; do - CTID=$(whiptail --title "Containers on $NODE" --radiolist \ + CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --radiolist \ "\nSelect a container to add support:\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit diff --git a/misc/host-backup.sh b/misc/host-backup.sh index d24779e8..0fbe9a41 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -40,7 +40,7 @@ while read -r dir; do done < <(ls -d /etc/*) while [ -z "${HOST_BACKUP:+x}" ]; do - HOST_BACKUP=$(whiptail --title "SELECTIONS" --checklist \ + HOST_BACKUP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECTIONS" --checklist \ "\nSelect what files/directories to backup:\n" \ 16 $(($MSG_MAX_LENGTH + 58)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index a60f8dd5..7e6f15c7 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -130,7 +130,7 @@ OPTIONS=(Add "Add Monitor-All to Proxmox VE" \ Remove "Remove Monitor-All from Proxmox VE") # Show the whiptail menu and save the user's choice -CHOICE=$(whiptail --title "Monitor-All for Proxmox VE" --menu "Select an option:" 10 58 2 \ +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Monitor-All for Proxmox VE" --menu "Select an option:" 10 58 2 \ "${OPTIONS[@]}" 3>&1 1>&2 2>&3) # Check the user's choice and perform the corresponding action diff --git a/misc/pbs3-upgrade.sh b/misc/pbs3-upgrade.sh index 6b389e97..942154df 100644 --- a/misc/pbs3-upgrade.sh +++ b/misc/pbs3-upgrade.sh @@ -47,7 +47,7 @@ msg_error() { start_routines() { header_info - CHOICE=$(whiptail --title "PBS 2 BACKUP" --menu "\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS 2 BACKUP" --menu "\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -61,7 +61,7 @@ start_routines() { ;; esac - CHOICE=$(whiptail --title "PBS 3 SOURCES" --menu "This will set the correct sources to update and install Proxmox Backup Server 3.\n \nChange to Proxmox Backup Server 3 sources?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS 3 SOURCES" --menu "This will set the correct sources to update and install Proxmox Backup Server 3.\n \nChange to Proxmox Backup Server 3 sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -79,7 +79,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PBS3-ENTERPRISE" --menu "The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pbs-enterprise' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS3-ENTERPRISE" --menu "The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pbs-enterprise' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -95,7 +95,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PBS3-NO-SUBSCRIPTION" --menu "The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\n \nEnable 'pbs-no-subscription' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS3-NO-SUBSCRIPTION" --menu "The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\n \nEnable 'pbs-no-subscription' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -111,7 +111,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PBS3 TEST" --menu "The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pbstest' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS3 TEST" --menu "The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pbstest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -127,7 +127,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PBS 3 UPDATE" --menu "\nUpdate to Proxmox Backup Server 3 now?" 11 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS 3 UPDATE" --menu "\nUpdate to Proxmox Backup Server 3 now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -142,7 +142,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox Backup Server 3 now? (recommended)" 11 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "REBOOT" --menu "\nReboot Proxmox Backup Server 3 now? (recommended)" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index aebddb14..9f53edc3 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -48,7 +48,7 @@ msg_error() { start_routines() { header_info VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" - CHOICE=$(whiptail --title "PBS SOURCES" --menu "This will set the correct sources to update and install Proxmox Backup Server.\n \nChange to Proxmox Backup Server sources?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS SOURCES" --menu "This will set the correct sources to update and install Proxmox Backup Server.\n \nChange to Proxmox Backup Server sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -66,7 +66,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PBS-ENTERPRISE" --menu "The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pbs-enterprise' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS-ENTERPRISE" --menu "The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pbs-enterprise' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -82,7 +82,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PBS-NO-SUBSCRIPTION" --menu "The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\n \nEnable 'pbs-no-subscription' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS-NO-SUBSCRIPTION" --menu "The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\n \nEnable 'pbs-no-subscription' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -98,7 +98,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PBS TEST" --menu "The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pbstest' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS TEST" --menu "The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pbstest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -115,25 +115,25 @@ EOF esac if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then - CHOICE=$(whiptail --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_info "Disabling subscription nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled subscription nag (Delete browser cache)" ;; no) - whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_error "Selected no to Disabling subscription nag" ;; esac fi - CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox Backup Server now?" 11 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --menu "\nUpdate Proxmox Backup Server now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -148,7 +148,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox Backup Server now? (recommended)" 11 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "REBOOT" --menu "\nReboot Proxmox Backup Server now? (recommended)" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index ca076582..5f4fe348 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -48,10 +48,10 @@ start_routines() { header_info VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" if lscpu | grep -qP 'Vendor ID:.*GenuineIntel' && lscpu | grep -qP 'Model name:.*N' && [[ "$VERSION" == "bullseye" ]]; then - whiptail --msgbox --title "N-SERIES PROCESSOR DETECTED" "To ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install Proxmox Virtual Environment 8" 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "N-SERIES PROCESSOR DETECTED" "To ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install Proxmox Virtual Environment 8" 10 58 fi - CHOICE=$(whiptail --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -69,7 +69,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PVE-ENTERPRISE" --menu "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\n \nDisable 'pve-enterprise' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -85,7 +85,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PVE-NO-SUBSCRIPTION" --menu "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\n \nEnable 'pve-no-subscription' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -102,7 +102,7 @@ EOF esac if [[ "${VERSION}" == "bookworm" ]]; then - CHOICE=$(whiptail --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nAdd 'ceph package repositories?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nAdd 'ceph package repositories?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -120,7 +120,7 @@ EOF esac fi - CHOICE=$(whiptail --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -137,26 +137,26 @@ EOF esac if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then - CHOICE=$(whiptail --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUBSCRIPTION NAG" --menu "This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\n \nDisable subscription nag?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_info "Disabling subscription nag" echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled subscription nag (Delete browser cache)" ;; no) - whiptail --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_error "Selected no to Disabling subscription nag" ;; esac fi if ! systemctl is-active --quiet pve-ha-lrm; then - CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "Enable high availability?" 10 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HIGH AVAILABILITY" --menu "Enable high availability?" 10 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -174,7 +174,7 @@ EOF fi if systemctl is-active --quiet pve-ha-lrm; then - CHOICE=$(whiptail --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HIGH AVAILABILITY" --menu "If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\n\nIf HA becomes necessary at a later stage, the services can be re-enabled.\n\nDisable high availability?" 18 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -191,7 +191,7 @@ EOF esac fi - CHOICE=$(whiptail --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --menu "\nUpdate Proxmox VE now?" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -206,7 +206,7 @@ EOF ;; esac - CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE now? (recommended)" 11 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "REBOOT" --menu "\nReboot Proxmox VE now? (recommended)" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index 53eff2cc..e2e86cb5 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -47,7 +47,7 @@ msg_error() { start_routines() { header_info - whiptail --msgbox --title "PVE8 SOURCES" "This will set the correct sources to update and install Proxmox VE 8." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "PVE8 SOURCES" "This will set the correct sources to update and install Proxmox VE 8." 10 58 msg_info "Changing to Proxmox VE 8 Sources" cat </etc/apt/sources.list deb http://ftp.debian.org/debian bookworm main contrib @@ -56,21 +56,21 @@ deb http://security.debian.org/debian-security bookworm-security main contrib EOF msg_ok "Changed to Proxmox VE 8 Sources" - whiptail --msgbox --title "PVE8-ENTERPRISE" "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "PVE8-ENTERPRISE" "The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription." 10 58 msg_info "Disabling 'pve-enterprise' repository" cat </etc/apt/sources.list.d/pve-enterprise.list # deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise EOF msg_ok "Disabled 'pve-enterprise' repository" - whiptail --msgbox --title "PVE8-NO-SUBSCRIPTION" "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "PVE8-NO-SUBSCRIPTION" "The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE." 10 58 msg_info "Enabling 'pve-no-subscription' repository" cat </etc/apt/sources.list.d/pve-install-repo.list deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" - whiptail --msgbox --title "PVE8 CEPH PACKAGE REPOSITORIES" "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "PVE8 CEPH PACKAGE REPOSITORIES" "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories." 10 58 msg_info "Enabling 'ceph package repositories'" cat </etc/apt/sources.list.d/ceph.list # deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise @@ -78,20 +78,20 @@ deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription EOF msg_ok "Enabled 'ceph package repositories'" - whiptail --msgbox --title "PVE8 TEST" "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released (Disabled)." 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "PVE8 TEST" "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released (Disabled)." 10 58 msg_info "Adding 'pvetest' repository and set disabled" cat </etc/apt/sources.list.d/pvetest-for-beta.list # deb http://download.proxmox.com/debian/pve bookworm pvetest EOF msg_ok "Added 'pvetest' repository" - whiptail --msgbox --title "PVE8 UPDATE" "Updating to Proxmox VE 8" 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "PVE8 UPDATE" "Updating to Proxmox VE 8" 10 58 msg_info "Updating to Proxmox VE 8 (Patience)" apt-get update DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y msg_ok "Updated to Proxmox VE 8" - CHOICE=$(whiptail --title "REBOOT" --menu "\nReboot Proxmox VE 8 now? (recommended)" 11 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "REBOOT" --menu "\nReboot Proxmox VE 8 now? (recommended)" 11 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 5bc0f978..dd826f46 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -44,7 +44,7 @@ while read -r line; do fi CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') -excluded_containers=$(whiptail --title "Containers on $NODE" --checklist \ +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist \ "\nSelect containers to skip from updates:\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index 2294896d..f780971e 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 88bbd21d..01915039 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh index 85ef344b..4f122c0d 100644 --- a/turnkey/turnkey-gitea.sh +++ b/turnkey/turnkey-gitea.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index a85c609a..0a59fad6 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-mediaserver.sh b/turnkey/turnkey-mediaserver.sh index 2ce0209c..a4a6a538 100644 --- a/turnkey/turnkey-mediaserver.sh +++ b/turnkey/turnkey-mediaserver.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index cdbc41d9..02383f51 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index da16c7ae..b065d90e 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-openvpn.sh b/turnkey/turnkey-openvpn.sh index c1548cab..62483753 100644 --- a/turnkey/turnkey-openvpn.sh +++ b/turnkey/turnkey-openvpn.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index a71630b9..c726005a 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh index 549a7786..b6638157 100644 --- a/turnkey/turnkey-torrentserver.sh +++ b/turnkey/turnkey-torrentserver.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index 63858486..56400e73 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/turnkey/turnkey-zoneminder.sh b/turnkey/turnkey-zoneminder.sh index ba90bd4f..daf137b7 100644 --- a/turnkey/turnkey-zoneminder.sh +++ b/turnkey/turnkey-zoneminder.sh @@ -113,7 +113,7 @@ function select_storage() { else local STORAGE while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 06d15d21..8294ec68 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -63,7 +63,7 @@ function cleanup() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if whiptail --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then : else header_info && echo -e "⚠ User exited script \n" && exit @@ -106,7 +106,7 @@ function arch_check() { function ssh_check() { if command -v pveversion >/dev/null 2>&1; then if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then echo "you've been warned" else clear @@ -154,7 +154,7 @@ function default_settings() { } function advanced_settings() { - if BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ + if BRANCH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ "$stable" "Stable " ON \ "$beta" "Beta " OFF \ "$dev" "Dev " OFF \ @@ -165,7 +165,7 @@ function advanced_settings() { fi while true; do - if VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z "$VMID" ]; then VMID="$NEXTID" fi @@ -181,7 +181,7 @@ function advanced_settings() { fi done - if MACH=$(whiptail --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ "i440fx" "Machine i440fx" ON \ "q35" "Machine q35" OFF \ 3>&1 1>&2 2>&3); then @@ -198,7 +198,7 @@ function advanced_settings() { exit-script fi - if DISK_CACHE1=$(whiptail --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + if DISK_CACHE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ "0" "Default" ON \ "1" "Write Through" OFF \ 3>&1 1>&2 2>&3); then @@ -213,7 +213,7 @@ function advanced_settings() { exit-script fi - if VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VM_NAME ]; then HN="haos${BRANCH}" echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" @@ -225,7 +225,7 @@ function advanced_settings() { exit-script fi - if CPU_TYPE1=$(whiptail --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ "0" "KVM64 (Default)" ON \ "1" "Host" OFF \ 3>&1 1>&2 2>&3); then @@ -240,7 +240,7 @@ function advanced_settings() { exit-script fi - if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $CORE_COUNT ]; then CORE_COUNT="2" echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" @@ -251,7 +251,7 @@ function advanced_settings() { exit-script fi - if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $RAM_SIZE ]; then RAM_SIZE="4096" echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" @@ -262,7 +262,7 @@ function advanced_settings() { exit-script fi - if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $BRG ]; then BRG="vmbr0" echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" @@ -273,7 +273,7 @@ function advanced_settings() { exit-script fi - if MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then MAC="$GEN_MAC" echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" @@ -285,7 +285,7 @@ function advanced_settings() { exit-script fi - if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN="" @@ -298,7 +298,7 @@ function advanced_settings() { exit-script fi - if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then MTU1="Default" MTU="" @@ -311,7 +311,7 @@ function advanced_settings() { exit-script fi - if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" else @@ -319,7 +319,7 @@ function advanced_settings() { START_VM="no" fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" else header_info @@ -329,7 +329,7 @@ function advanced_settings() { } function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings @@ -365,7 +365,7 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 78f7208a..35a92d9b 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -69,7 +69,7 @@ pushd $TEMP_DIR >/dev/null sleep 3 exit fi -if (whiptail --title "Mikrotik RouterOS VM" --yesno "This will create a New Mikrotik RouterOS VM. Proceed?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Mikrotik RouterOS VM" --yesno "This will create a New Mikrotik RouterOS VM. Proceed?" 10 58); then echo "User selected Yes" else clear @@ -107,14 +107,14 @@ function default_settings() { echo -e "${BL}Creating a Mikrotik RouterOS VM using the above default settings${CL}" } function advanced_settings() { - VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) + VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}" else exit fi - VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 Mikrotik-RouterOS --title "HOSTNAME" 3>&1 1>&2 2>&3) + VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 Mikrotik-RouterOS --title "HOSTNAME" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' ') @@ -122,28 +122,28 @@ function advanced_settings() { else exit fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) + CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" else exit fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) + RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" else exit fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) + BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" else exit fi - MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) + MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then MAC="$MAC1" @@ -151,7 +151,7 @@ function advanced_settings() { else exit fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) + VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then @@ -162,7 +162,7 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MTU1 ]; then @@ -173,14 +173,14 @@ function advanced_settings() { echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi fi - if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS VM when completed?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS VM when completed?" 10 58); then echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}yes${CL}" START_VM="yes" else echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}no${CL}" START_VM="no" fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create Mikrotik RouterOS VM?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create Mikrotik RouterOS VM?" 10 58); then echo -e "${RD}Creating Mikrotik RouterOS VM using the above advanced settings${CL}" else clear @@ -190,7 +190,7 @@ function advanced_settings() { fi } function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then clear header_info echo -e "${BL}Using Default Settings${CL}" @@ -224,7 +224,7 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the Mikrotik RouterOS VM?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 66bccd19..dc1c1828 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -135,7 +135,7 @@ function send_line_to_vm() { TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if (whiptail --title "OpenWrt VM" --yesno "This will create a New OpenWrt VM. Proceed?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "OpenWrt VM" --yesno "This will create a New OpenWrt VM. Proceed?" 10 58); then : else header_info && echo -e "⚠ User exited script \n" && exit @@ -178,7 +178,7 @@ function arch_check() { function ssh_check() { if command -v pveversion >/dev/null 2>&1; then if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then echo "you've been warned" else clear @@ -228,7 +228,7 @@ function default_settings() { function advanced_settings() { while true; do - if VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z "$VMID" ]; then VMID="$NEXTID" fi @@ -244,7 +244,7 @@ function advanced_settings() { fi done - if VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 openwrt --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 openwrt --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VM_NAME ]; then HN="openwrt" else @@ -255,7 +255,7 @@ function advanced_settings() { exit-script fi - if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $CORE_COUNT ]; then CORE_COUNT="1" fi @@ -264,7 +264,7 @@ function advanced_settings() { exit-script fi - if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 256 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 256 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $RAM_SIZE ]; then RAM_SIZE="256" fi @@ -273,7 +273,7 @@ function advanced_settings() { exit-script fi - if BRG=$(whiptail --inputbox "Set a WAN Bridge" 8 58 vmbr0 --title "WAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a WAN Bridge" 8 58 vmbr0 --title "WAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $BRG ]; then BRG="vmbr0" fi @@ -282,7 +282,7 @@ function advanced_settings() { exit-script fi - if LAN_BRG=$(whiptail --inputbox "Set a LAN Bridge" 8 58 vmbr0 --title "LAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if LAN_BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a LAN Bridge" 8 58 vmbr0 --title "LAN BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $LAN_BRG ]; then LAN_BRG="vmbr0" fi @@ -291,7 +291,7 @@ function advanced_settings() { exit-script fi - if LAN_IP_ADDR=$(whiptail --inputbox "Set a router IP" 8 58 $LAN_IP_ADDR --title "LAN IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if LAN_IP_ADDR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a router IP" 8 58 $LAN_IP_ADDR --title "LAN IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $LAN_IP_ADDR ]; then LAN_IP_ADDR="192.168.1.1" fi @@ -300,7 +300,7 @@ function advanced_settings() { exit-script fi - if LAN_NETMASK=$(whiptail --inputbox "Set a router netmmask" 8 58 $LAN_NETMASK --title "LAN NETMASK" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if LAN_NETMASK=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a router netmmask" 8 58 $LAN_NETMASK --title "LAN NETMASK" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $LAN_NETMASK ]; then LAN_NETMASK="255.255.255.0" fi @@ -309,7 +309,7 @@ function advanced_settings() { exit-script fi - if MAC1=$(whiptail --inputbox "Set a WAN MAC Address" 8 58 $GEN_MAC --title "WAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a WAN MAC Address" 8 58 $GEN_MAC --title "WAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MAC1 ]; then MAC="$GEN_MAC" else @@ -320,7 +320,7 @@ function advanced_settings() { exit-script fi - if MAC2=$(whiptail --inputbox "Set a LAN MAC Address" 8 58 $GEN_MAC_LAN --title "LAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if MAC2=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a LAN MAC Address" 8 58 $GEN_MAC_LAN --title "LAN MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MAC2 ]; then LAN_MAC="$GEN_MAC_LAN" else @@ -331,7 +331,7 @@ function advanced_settings() { exit-script fi - if VLAN1=$(whiptail --inputbox "Set a WAN Vlan (leave blank for default)" 8 58 --title "WAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a WAN Vlan (leave blank for default)" 8 58 --title "WAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VLAN1 ]; then VLAN1="Default" VLAN="" @@ -343,7 +343,7 @@ function advanced_settings() { exit-script fi - if VLAN2=$(whiptail --inputbox "Set a LAN Vlan" 8 58 999 --title "LAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if VLAN2=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a LAN Vlan" 8 58 999 --title "LAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $VLAN2 ]; then VLAN2="999" LAN_VLAN=",tag=$VLAN2" @@ -355,7 +355,7 @@ function advanced_settings() { exit-script fi - if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then if [ -z $MTU1 ]; then MTU1="Default" MTU="" @@ -367,14 +367,14 @@ function advanced_settings() { exit-script fi - if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then START_VM="yes" else START_VM="no" fi echo -e "${DGN}Start VM when completed: ${BGN}$START_VM${CL}" - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create OpenWrt VM?" --no-button Do-Over 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create OpenWrt VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a OpenWrt VM using the above advanced settings${CL}" else header_info @@ -384,7 +384,7 @@ function advanced_settings() { } function start_script() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then header_info echo -e "${BL}Using Default Settings${CL}" default_settings @@ -421,7 +421,7 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the OpenWrt VM?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index 9fc13f2c..1cf39709 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -71,7 +71,7 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null -if (whiptail --title "PiMox HAOS VM" --yesno "This will create a New PiMox HAOS VM. Proceed?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "PiMox HAOS VM" --yesno "This will create a New PiMox HAOS VM. Proceed?" 10 58); then echo "User selected Yes" else clear @@ -133,14 +133,14 @@ function default_settings() { echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" } function advanced_settings() { - BRANCH=$(whiptail --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ + BRANCH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ "$STABLE" "Stable" ON \ "$BETA" "Beta" OFF \ "$DEV" "Dev" OFF \ 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"; fi - VMID=$(whiptail --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $VMID ]; then VMID="$NEXTID" @@ -155,7 +155,7 @@ function advanced_settings() { if [ $exitstatus = 0 ]; then echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"; fi fi fi - VM_NAME=$(whiptail --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $VM_NAME ]; then HN="haos${BRANCH}" @@ -166,7 +166,7 @@ function advanced_settings() { echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" fi fi - CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $CORE_COUNT ]; then CORE_COUNT="2" @@ -174,7 +174,7 @@ function advanced_settings() { else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi fi - RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $RAM_SIZE ]; then RAM_SIZE="4096" @@ -182,7 +182,7 @@ function advanced_settings() { else if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi fi - BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $BRG ]; then BRG="vmbr0" @@ -190,7 +190,7 @@ function advanced_settings() { else if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi fi - MAC1=$(whiptail --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ -z $MAC1 ]; then MAC="$GEN_MAC" @@ -201,7 +201,7 @@ function advanced_settings() { echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" fi fi - VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $VLAN1 ]; then @@ -212,7 +212,7 @@ function advanced_settings() { echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" fi fi - MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) + MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then if [ -z $MTU1 ]; then @@ -223,14 +223,14 @@ function advanced_settings() { echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi fi - if (whiptail --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" START_VM="yes" else echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" fi - if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" else clear @@ -240,7 +240,7 @@ function advanced_settings() { fi } function START_SCRIPT() { - if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then clear header_info echo -e "${BL}Using Default Settings${CL}" @@ -273,7 +273,7 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for the HAOS VM?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit From b31de2b71211debd69e41cef3776871747840843 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Sep 2023 16:50:45 -0400 Subject: [PATCH 5235/6505] Update host-backup.sh Allow users to specify the backup path and directory they want to work in. --- misc/host-backup.sh | 85 ++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/misc/host-backup.sh b/misc/host-backup.sh index 0fbe9a41..5722e1f0 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -6,8 +6,8 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - clear -cat <<"EOF" + clear + cat <<"EOF" __ __ __ ___ __ / // /__ ___ / /_ / _ )___ _____/ /____ _____ / _ / _ \(_-&1 1>&2 2>&3) -while read -r dir; do - DIRNAME=$(basename "$dir") - OFFSET=2 - if [[ $((${#DIRNAME} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#DIRNAME} + $OFFSET)) + if [ -z "$BACKUP_PATH" ]; then + BACKUP_PATH="/root/" + else + BACKUP_PATH="$BACKUP_PATH" fi - CTID_MENU+=("$DIRNAME" "$dir " "OFF") -done < <(ls -d /etc/*) -while [ -z "${HOST_BACKUP:+x}" ]; do - HOST_BACKUP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECTIONS" --checklist \ - "\nSelect what files/directories to backup:\n" \ - 16 $(($MSG_MAX_LENGTH + 58)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to etc\ne.g. root, var/lib/pve-cluster etc." 9 68 --title "Directory to work in (No leading or trailing slashes):" 3>&1 1>&2 2>&3) - for selected_dir in ${HOST_BACKUP//\"}; do - selected_directories+=("/etc/$selected_dir") + if [ -z "$DIR" ]; then + DIR="etc" + else + DIR="$DIR" + fi + + DIR_DASH=$(echo "$DIR" | tr '/' '-') + BACKUP_FILE="$(hostname)-${DIR_DASH}-backup" + selected_directories=() + + while read -r dir; do + DIRNAME=$(basename "$dir") + OFFSET=2 + if [[ $((${#DIRNAME} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#DIRNAME} + $OFFSET)) + fi + CTID_MENU+=("$DIRNAME" "$dir " "OFF") + done < <(ls -d /${DIR}/*) + + while [ -z "${HOST_BACKUP:+x}" ]; do + HOST_BACKUP=$(whiptail --backtitle "Proxmox VE Host Backup" --title "Working in the ${DIR} directory " --checklist \ + "\nSelect what files/directories to backup:\n" \ + 16 $(($MSG_MAX_LENGTH + 58)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + + for selected_dir in ${HOST_BACKUP//\"/}; do + selected_directories+=("/${DIR}/$selected_dir") + done done -done -selected_directories_string=$(printf "%s " "${selected_directories[@]}") -header_info -echo -e "This will create backups for the directories \e[1;33m ${selected_directories_string% } \e[0m" -read -p "Press ENTER to continue..." -header_info -tar -czf $BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz --absolute-names ${selected_directories_string% } + selected_directories_string=$(printf "%s " "${selected_directories[@]}") + header_info + echo -e "This will create a backup in\e[1;33m $BACKUP_PATH \e[0mfor these files and directories\e[1;33m ${selected_directories_string% } \e[0m" + read -p "Press ENTER to continue..." + header_info + tar -czf "$BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz" --absolute-names ${selected_directories_string% } -echo -e "\nFinished" + echo -e "\nFinished" +} + +if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Host Backup" --yesno "This will create backups for particular files and directories located within a designated directory. Proceed?" 10 88); then + start +fi echo -e "\e[1;33m \nA backup is rendered ineffective when it remains stored on the host.\n \e[0m" From 06686f506a166e1db04d1c5f3cade6e106ebf755 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Sep 2023 16:54:24 -0400 Subject: [PATCH 5236/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c624dda2..e7c9ac98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-09 + +### Changed + +- **Proxmox VE Host Backup** + - Users are now able to specify both the backup path and the directory in which they wish to work. + ## 2023-09-07 ### Changed From 8c4d2a37119b91736a9bf3ef5dfc7663778565ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Sep 2023 17:07:58 -0400 Subject: [PATCH 5237/6505] Update host-backup.sh tweak --- misc/host-backup.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/host-backup.sh b/misc/host-backup.sh index 5722e1f0..78712ae7 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -63,12 +63,13 @@ start() { echo -e "This will create a backup in\e[1;33m $BACKUP_PATH \e[0mfor these files and directories\e[1;33m ${selected_directories_string% } \e[0m" read -p "Press ENTER to continue..." header_info + echo "Working..." tar -czf "$BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz" --absolute-names ${selected_directories_string% } - + header_info echo -e "\nFinished" + echo -e "\e[1;33m \nA backup is rendered ineffective when it remains stored on the host.\n \e[0m" } if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Host Backup" --yesno "This will create backups for particular files and directories located within a designated directory. Proceed?" 10 88); then start fi -echo -e "\e[1;33m \nA backup is rendered ineffective when it remains stored on the host.\n \e[0m" From 4535f31d3db8493d65ad71dba033d747b552a9d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Sep 2023 17:26:14 -0400 Subject: [PATCH 5238/6505] Update host-backup.sh tweak --- misc/host-backup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/host-backup.sh b/misc/host-backup.sh index 78712ae7..03140862 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -18,7 +18,7 @@ EOF header_info start() { - BACKUP_PATH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to root\ne.g. /mnt/backups/" 9 68 --title "Directory to backup to:" 3>&1 1>&2 2>&3) + BACKUP_PATH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to /root/\ne.g. /mnt/backups/" 11 68 --title "Directory to backup to:" 3>&1 1>&2 2>&3) if [ -z "$BACKUP_PATH" ]; then BACKUP_PATH="/root/" @@ -26,7 +26,7 @@ start() { BACKUP_PATH="$BACKUP_PATH" fi - DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to etc\ne.g. root, var/lib/pve-cluster etc." 9 68 --title "Directory to work in (No leading or trailing slashes):" 3>&1 1>&2 2>&3) + DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to etc\ne.g. root, var/lib/pve-cluster etc." 11 68 --title "Directory to work in (No leading or trailing slashes):" 3>&1 1>&2 2>&3) if [ -z "$DIR" ]; then DIR="etc" From 64b395868552fbcc19b8f400406631f2509b8219 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Sep 2023 19:02:27 -0400 Subject: [PATCH 5239/6505] Update host-backup.sh For consistency, it's necessary to include slashes both before and after the backup path and directory path when entering them. --- misc/host-backup.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/misc/host-backup.sh b/misc/host-backup.sh index 03140862..2cac3bb4 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -26,16 +26,16 @@ start() { BACKUP_PATH="$BACKUP_PATH" fi - DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to etc\ne.g. root, var/lib/pve-cluster etc." 11 68 --title "Directory to work in (No leading or trailing slashes):" 3>&1 1>&2 2>&3) + DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to /etc/\ne.g. /root/, /var/lib/pve-cluster/ etc." 11 68 --title "Directory to work in:" 3>&1 1>&2 2>&3) if [ -z "$DIR" ]; then - DIR="etc" + DIR="/etc/" else DIR="$DIR" fi DIR_DASH=$(echo "$DIR" | tr '/' '-') - BACKUP_FILE="$(hostname)-${DIR_DASH}-backup" + BACKUP_FILE="$(hostname)${DIR_DASH}backup" selected_directories=() while read -r dir; do @@ -45,7 +45,7 @@ start() { MSG_MAX_LENGTH=$((${#DIRNAME} + $OFFSET)) fi CTID_MENU+=("$DIRNAME" "$dir " "OFF") - done < <(ls -d /${DIR}/*) + done < <(ls -d ${DIR}*) while [ -z "${HOST_BACKUP:+x}" ]; do HOST_BACKUP=$(whiptail --backtitle "Proxmox VE Host Backup" --title "Working in the ${DIR} directory " --checklist \ @@ -54,17 +54,17 @@ start() { "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit for selected_dir in ${HOST_BACKUP//\"/}; do - selected_directories+=("/${DIR}/$selected_dir") + selected_directories+=("${DIR}${selected_dir}") done done selected_directories_string=$(printf "%s " "${selected_directories[@]}") header_info - echo -e "This will create a backup in\e[1;33m $BACKUP_PATH \e[0mfor these files and directories\e[1;33m ${selected_directories_string% } \e[0m" + echo -e "This will create a backup in\e[1;33m ${BACKUP_PATH} \e[0mfor these files and directories\e[1;33m ${selected_directories_string% } \e[0m" read -p "Press ENTER to continue..." header_info echo "Working..." - tar -czf "$BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz" --absolute-names ${selected_directories_string% } + tar -czf "${BACKUP_PATH}${BACKUP_FILE}-$(date +%Y_%m_%d).tar.gz" --absolute-names ${selected_directories_string% } header_info echo -e "\nFinished" echo -e "\e[1;33m \nA backup is rendered ineffective when it remains stored on the host.\n \e[0m" From e098af8ed9dda752d8d5fcb582b0df8b586ed173 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Sep 2023 20:50:26 -0400 Subject: [PATCH 5240/6505] Update host-backup.sh - code refactoring - add comments - loop the main script execution until "No" --- misc/host-backup.sh | 68 ++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/misc/host-backup.sh b/misc/host-backup.sh index 2cac3bb4..f2c231d8 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -15,61 +15,65 @@ function header_info { /_/ EOF } -header_info -start() { - BACKUP_PATH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to /root/\ne.g. /mnt/backups/" 11 68 --title "Directory to backup to:" 3>&1 1>&2 2>&3) +# Function to perform backup +function perform_backup { + local BACKUP_PATH + local DIR + local DIR_DASH + local BACKUP_FILE + local selected_directories=() - if [ -z "$BACKUP_PATH" ]; then - BACKUP_PATH="/root/" - else - BACKUP_PATH="$BACKUP_PATH" - fi + # Get backup path from user + BACKUP_PATH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to /root/\ne.g. /mnt/backups/" 11 68 --title "Directory to backup to:" 3>&1 1>&2 2>&3) || return - DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to /etc/\ne.g. /root/, /var/lib/pve-cluster/ etc." 11 68 --title "Directory to work in:" 3>&1 1>&2 2>&3) + # Default to /root/ if no input + BACKUP_PATH="${BACKUP_PATH:-/root/}" - if [ -z "$DIR" ]; then - DIR="/etc/" - else - DIR="$DIR" - fi + # Get directory to work in from user + DIR=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nDefaults to /etc/\ne.g. /root/, /var/lib/pve-cluster/ etc." 11 68 --title "Directory to work in:" 3>&1 1>&2 2>&3) || return + + # Default to /etc/ if no input + DIR="${DIR:-/etc/}" DIR_DASH=$(echo "$DIR" | tr '/' '-') BACKUP_FILE="$(hostname)${DIR_DASH}backup" - selected_directories=() + # Build a list of directories for backup + local CTID_MENU=() while read -r dir; do - DIRNAME=$(basename "$dir") - OFFSET=2 - if [[ $((${#DIRNAME} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#DIRNAME} + $OFFSET)) - fi - CTID_MENU+=("$DIRNAME" "$dir " "OFF") - done < <(ls -d ${DIR}*) + CTID_MENU+=("$(basename "$dir")" "$dir " "OFF") + done < <(ls -d "${DIR}"*) + # Allow the user to select directories + local HOST_BACKUP while [ -z "${HOST_BACKUP:+x}" ]; do HOST_BACKUP=$(whiptail --backtitle "Proxmox VE Host Backup" --title "Working in the ${DIR} directory " --checklist \ - "\nSelect what files/directories to backup:\n" \ - 16 $(($MSG_MAX_LENGTH + 58)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit + "\nSelect what files/directories to backup:\n" 16 $(((${#DIRNAME} + 2) + 88)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || return for selected_dir in ${HOST_BACKUP//\"/}; do - selected_directories+=("${DIR}${selected_dir}") + selected_directories+=("${DIR}$selected_dir") done done - selected_directories_string=$(printf "%s " "${selected_directories[@]}") + # Perform the backup header_info - echo -e "This will create a backup in\e[1;33m ${BACKUP_PATH} \e[0mfor these files and directories\e[1;33m ${selected_directories_string% } \e[0m" + echo -e "This will create a backup in\e[1;33m $BACKUP_PATH \e[0mfor these files and directories\e[1;33m ${selected_directories[*]} \e[0m" read -p "Press ENTER to continue..." header_info echo "Working..." - tar -czf "${BACKUP_PATH}${BACKUP_FILE}-$(date +%Y_%m_%d).tar.gz" --absolute-names ${selected_directories_string% } + tar -czf "$BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz" --absolute-names "${selected_directories[@]}" header_info echo -e "\nFinished" echo -e "\e[1;33m \nA backup is rendered ineffective when it remains stored on the host.\n \e[0m" + sleep 2 } -if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Host Backup" --yesno "This will create backups for particular files and directories located within a designated directory. Proceed?" 10 88); then - start -fi +# Main script execution loop +while true; do + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Host Backup" --yesno "This will create backups for particular files and directories located within a designated directory. Proceed?" 10 88); then + perform_backup + else + break + fi +done From 761f05ca65df642751f4082eb75e25d376b219e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Sep 2023 09:43:31 -0400 Subject: [PATCH 5241/6505] Create turnkey-gameserver.sh --- turnkey/turnkey-gameserver.sh | 200 ++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 turnkey/turnkey-gameserver.sh diff --git a/turnkey/turnkey-gameserver.sh b/turnkey/turnkey-gameserver.sh new file mode 100644 index 00000000..9b603ce6 --- /dev/null +++ b/turnkey/turnkey-gameserver.sh @@ -0,0 +1,200 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +# Setup script environment +NAME="gameserver" +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" +PCT_DISK_SIZE="8" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-${NAME} + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,hwaddr=AE:1A:60:07:B7:59,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) +function header_info { +clear +cat <<"EOF" + _____ ____ + / ___/__ ___ _ ___ / __/__ _____ _____ ____ +/ (_ / _ `/ ' \/ -_) _\ \/ -_) __/ |/ / -_) __/ +\___/\_,_/_/_/_/\__/ /___/\__/_/ |___/\__/_/ + +EOF +} +header_info +read -p "Press ENTER to continue..." +header_info +set -eEuo pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR + +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} + +# Stop Proxmox VE Monitor-All if running +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi + +# Set the CONTENT and CONTENT_LABEL variables +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) CONTENT='rootdir'; CONTENT_LABEL='Container';; + template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; + *) false || die "Invalid storage class.";; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=("$TAG" "$ITEM" "OFF") + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then + printf ${MENU[0]} + else + local STORAGE + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Save password +echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory + +# Start container +msg "Starting LXC Container..." +pct start "$CTID" +sleep 5 + +# Get container IP +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +# Start Proxmox VE Monitor-All if available +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi + +# Success message +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo +info "Proceed to the LXC console to complete the setup." +echo +info "login: root" +info "password: $PASS" +echo From 4bbbcd2fea9e73951408d78955fd4e92f7d3d1f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Sep 2023 09:44:50 -0400 Subject: [PATCH 5242/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7c9ac98..6e7a746e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-10 + +### Changed + +- **TurnKey Game Server LXC** + - NEW Script + ## 2023-09-09 ### Changed From c64c8d5adfb4b3d5bcf29ac3dd0cb96ebcc0f19b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Sep 2023 15:57:03 -0400 Subject: [PATCH 5243/6505] Update turnkey-gameserver.sh remove test MAC --- turnkey/turnkey-gameserver.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turnkey/turnkey-gameserver.sh b/turnkey/turnkey-gameserver.sh index 9b603ce6..e810688a 100644 --- a/turnkey/turnkey-gameserver.sh +++ b/turnkey/turnkey-gameserver.sh @@ -18,7 +18,7 @@ PCT_OPTIONS=" -cores 2 -memory 2048 -password $PASS - -net0 name=eth0,bridge=vmbr0,hwaddr=AE:1A:60:07:B7:59,ip=dhcp + -net0 name=eth0,bridge=vmbr0,ip=dhcp -unprivileged 1 " DEFAULT_PCT_OPTIONS=( From 3b1560fa63a85ba121995f0bbfe98fe455d2d144 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Sep 2023 16:07:40 -0400 Subject: [PATCH 5244/6505] An alternative method for acquiring the IP address in the TurnKey scripts. --- turnkey/turnkey-core.sh | 2 +- turnkey/turnkey-fileserver.sh | 2 +- turnkey/turnkey-gameserver.sh | 2 +- turnkey/turnkey-gitea.sh | 2 +- turnkey/turnkey-gitlab.sh | 2 +- turnkey/turnkey-mediaserver.sh | 2 +- turnkey/turnkey-nextcloud.sh | 2 +- turnkey/turnkey-observium.sh | 2 +- turnkey/turnkey-openvpn.sh | 2 +- turnkey/turnkey-owncloud.sh | 2 +- turnkey/turnkey-torrentserver.sh | 2 +- turnkey/turnkey-wordpress.sh | 2 +- turnkey/turnkey-zoneminder.sh | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index f780971e..49ff3b73 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 01915039..379e8785 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-gameserver.sh b/turnkey/turnkey-gameserver.sh index e810688a..9bf18305 100644 --- a/turnkey/turnkey-gameserver.sh +++ b/turnkey/turnkey-gameserver.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh index 4f122c0d..2573f471 100644 --- a/turnkey/turnkey-gitea.sh +++ b/turnkey/turnkey-gitea.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index 0a59fad6..b5ec6f5f 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-mediaserver.sh b/turnkey/turnkey-mediaserver.sh index a4a6a538..f43e54a1 100644 --- a/turnkey/turnkey-mediaserver.sh +++ b/turnkey/turnkey-mediaserver.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index 02383f51..2147c3c2 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index b065d90e..d4e5e5de 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-openvpn.sh b/turnkey/turnkey-openvpn.sh index 62483753..4727d459 100644 --- a/turnkey/turnkey-openvpn.sh +++ b/turnkey/turnkey-openvpn.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index c726005a..0ae77f2d 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh index b6638157..6d15b34c 100644 --- a/turnkey/turnkey-torrentserver.sh +++ b/turnkey/turnkey-torrentserver.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index 56400e73..3ae34dea 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else diff --git a/turnkey/turnkey-zoneminder.sh b/turnkey/turnkey-zoneminder.sh index daf137b7..be3197c3 100644 --- a/turnkey/turnkey-zoneminder.sh +++ b/turnkey/turnkey-zoneminder.sh @@ -168,7 +168,7 @@ max_attempts=5 attempt=1 IP="" while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') if [[ -n $IP ]]; then break else From c10678e251185c59d073f240474afaa7161c03a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Sep 2023 17:05:03 -0400 Subject: [PATCH 5245/6505] Update TurnKey scripts Disable the 'exit on error' behavior while checking for an IP. --- turnkey/turnkey-core.sh | 2 ++ turnkey/turnkey-fileserver.sh | 2 ++ turnkey/turnkey-gameserver.sh | 2 ++ turnkey/turnkey-gitea.sh | 2 ++ turnkey/turnkey-gitlab.sh | 2 ++ turnkey/turnkey-mediaserver.sh | 2 ++ turnkey/turnkey-nextcloud.sh | 2 ++ turnkey/turnkey-observium.sh | 2 ++ turnkey/turnkey-openvpn.sh | 2 ++ turnkey/turnkey-owncloud.sh | 2 ++ turnkey/turnkey-torrentserver.sh | 2 ++ turnkey/turnkey-wordpress.sh | 2 ++ turnkey/turnkey-zoneminder.sh | 2 ++ 13 files changed, 26 insertions(+) diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh index 49ff3b73..7a0f8733 100644 --- a/turnkey/turnkey-core.sh +++ b/turnkey/turnkey-core.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh index 379e8785..4826f253 100644 --- a/turnkey/turnkey-fileserver.sh +++ b/turnkey/turnkey-fileserver.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-gameserver.sh b/turnkey/turnkey-gameserver.sh index 9bf18305..bc19fd26 100644 --- a/turnkey/turnkey-gameserver.sh +++ b/turnkey/turnkey-gameserver.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh index 2573f471..3943cde5 100644 --- a/turnkey/turnkey-gitea.sh +++ b/turnkey/turnkey-gitea.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh index b5ec6f5f..4059f424 100644 --- a/turnkey/turnkey-gitlab.sh +++ b/turnkey/turnkey-gitlab.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-mediaserver.sh b/turnkey/turnkey-mediaserver.sh index f43e54a1..edd1b6f6 100644 --- a/turnkey/turnkey-mediaserver.sh +++ b/turnkey/turnkey-mediaserver.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh index 2147c3c2..b13cdb5e 100644 --- a/turnkey/turnkey-nextcloud.sh +++ b/turnkey/turnkey-nextcloud.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh index d4e5e5de..93f444b7 100644 --- a/turnkey/turnkey-observium.sh +++ b/turnkey/turnkey-observium.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-openvpn.sh b/turnkey/turnkey-openvpn.sh index 4727d459..79f5b407 100644 --- a/turnkey/turnkey-openvpn.sh +++ b/turnkey/turnkey-openvpn.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh index 0ae77f2d..a5f16ff0 100644 --- a/turnkey/turnkey-owncloud.sh +++ b/turnkey/turnkey-owncloud.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh index 6d15b34c..795d6c6f 100644 --- a/turnkey/turnkey-torrentserver.sh +++ b/turnkey/turnkey-torrentserver.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh index 3ae34dea..9c7aedc8 100644 --- a/turnkey/turnkey-wordpress.sh +++ b/turnkey/turnkey-wordpress.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service diff --git a/turnkey/turnkey-zoneminder.sh b/turnkey/turnkey-zoneminder.sh index be3197c3..41321872 100644 --- a/turnkey/turnkey-zoneminder.sh +++ b/turnkey/turnkey-zoneminder.sh @@ -164,6 +164,7 @@ pct start "$CTID" sleep 5 # Get container IP +set +e max_attempts=5 attempt=1 IP="" @@ -183,6 +184,7 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi +set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service From 67edaf0193ad877a23f212738cf7521637859a62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 05:47:03 -0400 Subject: [PATCH 5246/6505] Update scrypted-install.sh remove `sudo` as the user is already `root` --- install/scrypted-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 348f0368..e51d3a65 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -108,7 +108,7 @@ msg_ok "Coral Edge TPU Support Added" fi msg_info "Installing Scrypted" -$STD sudo -u root npx -y scrypted@latest install-server +$STD npx -y scrypted@latest install-server msg_ok "Installed Scrypted" msg_info "Creating Service" From 3da94bb95c8eb61262ee563effb9c2dfebae7cda Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 13:18:06 -0400 Subject: [PATCH 5247/6505] Update paperless-ngx-install.sh use Redis and PostgreSQL --- install/paperless-ngx-install.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 50f749f5..c7efc8ae 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -93,10 +93,11 @@ msg_info "Installing Natural Language Toolkit (Patience)" $STD python3 -m nltk.downloader -d /usr/share/nltk_data all msg_ok "Installed Natural Language Toolkit" -msg_info "Setting up database" +msg_info "Setting up PostgreSQL database" +DB_NAME=paperlessdb DB_USER=paperless DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" -DB_NAME=paperlessdb +SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" echo "Paperless-ngx Database User" >>~/paperless.creds @@ -106,13 +107,16 @@ echo $DB_PASS >>~/paperless.creds echo "Paperless-ngx Database Name" >>~/paperless.creds echo $DB_NAME >>~/paperless.creds mkdir -p {consume,media} -sed -i -e 's|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=paperlessdb|' /opt/paperless/paperless.conf +sed -i -e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' /opt/paperless/paperless.conf +sed -i -e 's|#PAPERLESS_DBHOST=localhost|PAPERLESS_DBHOST=localhost|' /opt/paperless/paperless.conf +sed -i -e 's|#PAPERLESS_DBPORT=5432|PAPERLESS_DBPORT=5432|' /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=$DB_NAME|" /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_DBUSER=paperless|PAPERLESS_DBUSER=$DB_USER|" /opt/paperless/paperless.conf sed -i -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" /opt/paperless/paperless.conf -SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" sed -i -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" /opt/paperless/paperless.conf cd /opt/paperless/src $STD python3 manage.py migrate -msg_ok "Set up database" +msg_ok "Set up PostgreSQL database" msg_info "Setting up admin Paperless-ngx User & Password" ## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations From 85d523dbdf66d70ac87271cfb4242a9024016fce Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 13:43:34 -0400 Subject: [PATCH 5248/6505] Update paperless-ngx-install.sh add option to install Adminer --- install/paperless-ngx-install.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index c7efc8ae..cd2331ce 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -118,6 +118,15 @@ cd /opt/paperless/src $STD python3 manage.py migrate msg_ok "Set up PostgreSQL database" +read -r -p "Would you like to add Adminer? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Adminer" + $STD apt install -y adminer + $STD a2enconf adminer + systemctl reload apache2 + msg_ok "Installed Adminer" +fi + msg_info "Setting up admin Paperless-ngx User & Password" ## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations cat < Date: Mon, 11 Sep 2023 14:00:11 -0400 Subject: [PATCH 5249/6505] Update paperless-ngx-install.sh update `paperless.creds` --- install/paperless-ngx-install.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index cd2331ce..065594f9 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -124,6 +124,19 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then $STD apt install -y adminer $STD a2enconf adminer systemctl reload apache2 + echo "" >>~/paperless.creds + echo "Adminer Interface" >>~/paperless.creds + echo $IP/adminer/ >>~/paperless.creds + echo "Adminer System" >>~/paperless.creds + echo PostgreSQL >>~/paperless.creds + echo "Adminer Server" >>~/paperless.creds + echo localhost:5432 >>~/paperless.creds + echo "Adminer Username" >>~/paperless.creds + echo $DB_USER >>~/paperless.creds + echo "Adminer Password" >>~/paperless.creds + echo $DB_PASS >>~/paperless.creds + echo "Adminer Database" >>~/paperless.creds + echo $DB_NAME >>~/paperless.creds msg_ok "Installed Adminer" fi From 95a762c38f322cfd1c1ef4778c08ced4670b24a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 14:14:21 -0400 Subject: [PATCH 5250/6505] Update paperless-ngx-install.sh fix unbound variable --- install/paperless-ngx-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 065594f9..c617ed68 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -124,6 +124,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then $STD apt install -y adminer $STD a2enconf adminer systemctl reload apache2 + IP=$(hostname -I) echo "" >>~/paperless.creds echo "Adminer Interface" >>~/paperless.creds echo $IP/adminer/ >>~/paperless.creds From 29c764031aaf01b15a3a4bf9a704749c8dc0b21d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 14:26:36 -0400 Subject: [PATCH 5251/6505] Update paperless-ngx-install.sh tweak --- install/paperless-ngx-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index c617ed68..27709e35 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -124,7 +124,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then $STD apt install -y adminer $STD a2enconf adminer systemctl reload apache2 - IP=$(hostname -I) + IP=$(hostname -I | awk '{print $1}') echo "" >>~/paperless.creds echo "Adminer Interface" >>~/paperless.creds echo $IP/adminer/ >>~/paperless.creds From 435e19d21ed16e8732165872f4b0d7a5611949c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 14:40:12 -0400 Subject: [PATCH 5252/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e7a746e..4aa13c47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-11 + +### Changed + +- **Paperless-ngx LXC** + - Modify the script to incorporate Redis and PostgreSQL, while also introducing an option to include Adminer during installation. + ## 2023-09-10 ### Changed From 3b0168b8d471d45ec770c74002507b3906e15a8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 14:43:56 -0400 Subject: [PATCH 5253/6505] Update paperless-ngx.sh increase storage --- ct/paperless-ngx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 31277348..ff4db22b 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -20,7 +20,7 @@ EOF header_info echo -e "Loading..." APP="Paperless-ngx" -var_disk="8" +var_disk="10" var_cpu="2" var_ram="2048" var_os="debian" From 7306991688f9444bed6cbf729345888f33be442c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 15:22:40 -0400 Subject: [PATCH 5254/6505] Update paperless-ngx-install.sh make `/paperless.creds` easier to read --- install/paperless-ngx-install.sh | 35 ++++++++++++-------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 27709e35..49a9bff2 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -100,12 +100,10 @@ DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" -echo "Paperless-ngx Database User" >>~/paperless.creds -echo $DB_USER >>~/paperless.creds -echo "Paperless-ngx Database Password" >>~/paperless.creds -echo $DB_PASS >>~/paperless.creds -echo "Paperless-ngx Database Name" >>~/paperless.creds -echo $DB_NAME >>~/paperless.creds +echo "" >>~/paperless.creds +echo -e "Paperless-ngx Database User: \e[32m$DB_USER\e[0m" >>~/paperless.creds +echo -e "Paperless-ngx Database Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds +echo -e "Paperless-ngx Database Name: \e[32m$DB_NAME\e[0m" >>~/paperless.creds mkdir -p {consume,media} sed -i -e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' /opt/paperless/paperless.conf sed -i -e 's|#PAPERLESS_DBHOST=localhost|PAPERLESS_DBHOST=localhost|' /opt/paperless/paperless.conf @@ -126,18 +124,12 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then systemctl reload apache2 IP=$(hostname -I | awk '{print $1}') echo "" >>~/paperless.creds - echo "Adminer Interface" >>~/paperless.creds - echo $IP/adminer/ >>~/paperless.creds - echo "Adminer System" >>~/paperless.creds - echo PostgreSQL >>~/paperless.creds - echo "Adminer Server" >>~/paperless.creds - echo localhost:5432 >>~/paperless.creds - echo "Adminer Username" >>~/paperless.creds - echo $DB_USER >>~/paperless.creds - echo "Adminer Password" >>~/paperless.creds - echo $DB_PASS >>~/paperless.creds - echo "Adminer Database" >>~/paperless.creds - echo $DB_NAME >>~/paperless.creds + echo -e "Adminer Interface: \e[32m$IP/adminer/\e[0m" >>~/paperless.creds + echo -e "Adminer System: \e[32mPostgreSQL\e[0m" >>~/paperless.creds + echo -e "Adminer Server: \e[32mlocalhost:5432\e[0m" >>~/paperless.creds + echo -e "Adminer Username: \e[32m$DB_USER\e[0m" >>~/paperless.creds + echo -e "Adminer Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds + echo -e "Adminer Database: \e[32m$DB_NAME\e[0m" >>~/paperless.creds msg_ok "Installed Adminer" fi @@ -152,10 +144,9 @@ user.is_staff = True user.save() EOF echo "" >>~/paperless.creds -echo "Paperless-ngx WebUI User" >>~/paperless.creds -echo admin >>~/paperless.creds -echo "Paperless-ngx WebUI Password" >>~/paperless.creds -echo $DB_PASS >>~/paperless.creds +echo -e "Paperless-ngx WebUI User: \e[32madmin\e[0m" >>~/paperless.creds +echo -e "Paperless-ngx WebUI Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds +echo "" >>~/paperless.creds msg_ok "Set up admin Paperless-ngx User & Password" msg_info "Creating Services" From 9dab6d52bcf62cd71a5488b547b2b88be3115a7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Sep 2023 16:56:42 -0400 Subject: [PATCH 5255/6505] Update paperless-ngx-install.sh create directories named "consume," "data," "media," and "static," then configure the corresponding paths in the `paperless.conf` file. --- install/paperless-ngx-install.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 49a9bff2..b52064bf 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -87,6 +87,12 @@ sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://gi $STD pip install --upgrade pip $STD pip install -r requirements.txt curl -s -o /opt/paperless/paperless.conf https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/paperless.conf.example +mkdir -p {consume,data,media,static} +sed -i -e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_CONSUMPTION_DIR=../consume|PAPERLESS_CONSUMPTION_DIR=/opt/paperless/consume|" /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_DATA_DIR=../data|PAPERLESS_DATA_DIR=/opt/paperless/data|" /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_MEDIA_ROOT=../media|PAPERLESS_MEDIA_ROOT=/opt/paperless/media|" /opt/paperless/paperless.conf +sed -i -e "s|#PAPERLESS_STATICDIR=../static|PAPERLESS_STATICDIR=/opt/paperless/static|" /opt/paperless/paperless.conf msg_ok "Installed Paperless-ngx" msg_info "Installing Natural Language Toolkit (Patience)" @@ -104,8 +110,6 @@ echo "" >>~/paperless.creds echo -e "Paperless-ngx Database User: \e[32m$DB_USER\e[0m" >>~/paperless.creds echo -e "Paperless-ngx Database Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds echo -e "Paperless-ngx Database Name: \e[32m$DB_NAME\e[0m" >>~/paperless.creds -mkdir -p {consume,media} -sed -i -e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' /opt/paperless/paperless.conf sed -i -e 's|#PAPERLESS_DBHOST=localhost|PAPERLESS_DBHOST=localhost|' /opt/paperless/paperless.conf sed -i -e 's|#PAPERLESS_DBPORT=5432|PAPERLESS_DBPORT=5432|' /opt/paperless/paperless.conf sed -i -e "s|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=$DB_NAME|" /opt/paperless/paperless.conf @@ -214,6 +218,7 @@ motd_ssh customize msg_info "Cleaning up" +rm -rf /opt/paperless/docker $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 5b7eb21c6a472fa319643c54fadc1b22ffa7f7c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Sep 2023 02:18:28 -0400 Subject: [PATCH 5256/6505] Update update-lxcs.sh code refactoring --- misc/update-lxcs.sh | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index dd826f46..d4b442f0 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -6,8 +6,8 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { -clear -cat <<"EOF" + clear + cat <<"EOF" __ __ __ __ __ _ ________ / / / /___ ____/ /___ _/ /____ / / | |/ / ____/ / / / / __ \/ __ / __ `/ __/ _ \ / / | / / @@ -25,29 +25,18 @@ CM='\xE2\x9C\x94\033' GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info -while true; do - read -p "This Will Update Selected LXC Containers. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear +echo "Loading..." +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update Selected LXC Containers. Proceed?" 10 58 || exit NODE=$(hostname) -while read -r line; do - TAG=$(echo "$line" | awk '{print $1}') - ITEM=$(echo "$line" | awk '{print substr($0,36)}') +while read -r TAG ITEM; do OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist \ "\nSelect containers to skip from updates:\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + function update_container() { container=$1 header_info @@ -55,16 +44,16 @@ function update_container() { os=$(pct config "$container" | awk '/^ostype/ {print $2}') if [[ "$os" == "ubuntu" || "$os" == "debian" ]]; then disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') - read -ra disk_info_array <<< "$disk_info" + read -ra disk_info_array <<<"$disk_info" echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\n" else echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}[No disk info for ${os}]${CL}\n" fi case "$os" in - alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; - archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm";; - fedora|rocky|centos|alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu|debian|devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; + alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; + archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; + fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; esac } header_info From 273dc38c8acc58a33f737ec31a49e9267b299bae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Sep 2023 19:32:27 -0400 Subject: [PATCH 5257/6505] Create kernel-clean-test.sh --- misc/kernel-clean-test.sh | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 misc/kernel-clean-test.sh diff --git a/misc/kernel-clean-test.sh b/misc/kernel-clean-test.sh new file mode 100644 index 00000000..c440a9cf --- /dev/null +++ b/misc/kernel-clean-test.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ __ ________ + / //_/__ _________ ___ / / / ____/ /__ ____ _____ + / ,< / _ \/ ___/ __ \/ _ \/ / / / / / _ \/ __ `/ __ \ + / /| / __/ / / / / / __/ / / /___/ / __/ /_/ / / / / +/_/ |_\___/_/ /_/ /_/\___/_/ \____/_/\___/\__,_/_/ /_/ + +EOF +} +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +current_kernel=$(uname -r) +available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v "$current_kernel" | sort -V) +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Clean" --yesno "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed?" 10 68 || exit + +if [ -z "$available_kernels" ]; then + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Other Kernels" --msgbox "It appears there are no old Kernels on your system. \nCurrent kernel ($current_kernel)." 10 68 + msg_info "Exiting" + sleep 2 + msg_ok "Done" + exit +fi + +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(echo "$available_kernels") + +remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" \ + 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the selected Kernels\n $remove_kernels\n Proceed?" 10 68 || exit + +msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" +/usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 +msg_ok "Successfully Removed Kernels" + +msg_info "Updating GRUB" +/usr/sbin/update-grub >/dev/null 2>&1 +msg_ok "Successfully Updated GRUB" +msg_info "Exiting" +sleep 2 +msg_ok "Done" From 7f5d708977bdde06e3c3bf89d364ccc7c2f4c27f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 04:20:38 -0400 Subject: [PATCH 5258/6505] Update nginxproxymanager-install.sh - add plugin for certbot to obtain certificates using a DNS TXT record for Porkbun domains - fixes https://github.com/tteck/Proxmox/issues/1790 --- install/nginxproxymanager-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 640227d9..6946848c 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -30,7 +30,7 @@ $STD apt-get -y install \ git msg_ok "Installed Dependencies" -msg_info "Updating Python" +msg_info "Installing Python Dependencies" $STD apt-get install -y \ python3 \ python3-dev \ @@ -38,10 +38,10 @@ $STD apt-get install -y \ python3-venv \ python3-cffi \ python3-certbot \ - python3-certbot-dns-cloudflare - + python3-certbot-dns-cloudflare \ + pip3 install certbot_dns_porkbun $STD python3 -m venv /opt/certbot/ -msg_ok "Updated Python" +msg_ok "Installed Python Dependencies" VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" From acdd9f8203f05a3e005f183b0b4b53ccab0ffe8e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 07:25:40 -0400 Subject: [PATCH 5259/6505] Update nginxproxymanager-install.sh remove `\` --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 6946848c..412fa4e1 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -38,7 +38,7 @@ $STD apt-get install -y \ python3-venv \ python3-cffi \ python3-certbot \ - python3-certbot-dns-cloudflare \ + python3-certbot-dns-cloudflare pip3 install certbot_dns_porkbun $STD python3 -m venv /opt/certbot/ msg_ok "Installed Python Dependencies" From fc49442ff871eebc72569bbf319df30a6d539b94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 07:27:42 -0400 Subject: [PATCH 5260/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 412fa4e1..04b8820e 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -39,7 +39,7 @@ $STD apt-get install -y \ python3-cffi \ python3-certbot \ python3-certbot-dns-cloudflare - pip3 install certbot_dns_porkbun +$STD pip3 install certbot_dns_porkbun $STD python3 -m venv /opt/certbot/ msg_ok "Installed Python Dependencies" From 4041a275c2785af48b59bc1715e19999be907117 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 08:09:25 -0400 Subject: [PATCH 5261/6505] Create pialert-install.sh --- install/pialert-install.sh | 97 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 install/pialert-install.sh diff --git a/install/pialert-install.sh b/install/pialert-install.sh new file mode 100644 index 00000000..a3181661 --- /dev/null +++ b/install/pialert-install.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get -y install \ + sudo \ + mc \ + curl \ + apt-utils \ + lighttpd \ + sqlite3 \ + mmdb-bin \ + arp-scan \ + dnsutils \ + net-tools \ + libwww-perl \ + nmap \ + zip \ + wakeonlan +msg_ok "Installed Dependencies" + +msg_info "Installing PHP Dependencies" +$STD apt-get -y install \ + php \ + php-cgi \ + php-fpm \ + php-curl \ + php-sqlite3 +$STD lighttpd-enable-mod fastcgi-php +service lighttpd force-reload +msg_ok "Installed PHP Dependencies" +#arp-scan -l + +msg_info "Installing Python Dependencies" +$STD apt-get -y install \ + python3-pip \ + python3-requests +$STD pip3 install mac-vendor-lookup +$STD pip3 install fritzconnection +$STD pip3 install cryptography +msg_ok "Installed Python Dependencies" + +msg_info "Installing Pi.Alert (Patience)" +curl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1 + +rm /var/www/html/index.html +mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old +ln -s /opt/pialert/install/index.html /var/www/html/index.html +ln -s /opt/pialert/front /var/www/html/pialert +chmod go+x /opt/pialert +chgrp -R www-data /opt/pialert/db +chmod -R 775 /opt/pialert/db +chmod -R 775 /opt/pialert/db/temp +chgrp www-data /opt/pialert/config +chmod -R 775 /opt/pialert/config +chgrp www-data /opt/pialert/config/pialert.conf +chmod -R 775 /opt/pialert/front/reports +chgrp -R www-data /opt/pialert/front/reports +chmod +x /opt/pialert/back/shoutrrr/x86/shoutrrr +touch "/opt/pialert/log/pialert.vendors.log" +touch "/opt/pialert/log/pialert.IP.log" +touch "/opt/pialert/log/pialert.1.log" +touch "/opt/pialert/log/pialert.cleanup.log" +touch "/opt/pialert/log/pialert.webservices.log" +ln -s "/opt/pialert/log/pialert.vendors.log" "/opt/pialert/front/php/server/pialert.vendors.log" +ln -s "/opt/pialert/log/pialert.IP.log" "/opt/pialert/front/php/server/pialert.IP.log" +ln -s "/opt/pialert/log/pialert.1.log" "/opt/pialert/front/php/server/pialert.1.log" +ln -s "/opt/pialert/log/pialert.cleanup.log" "/opt/pialert/front/php/server/pialert.cleanup.log" +ln -s "/opt/pialert/log/pialert.webservices.log" "/opt/pialert/front/php/server/pialert.webservices.log" +sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf +msg_ok "Installed Pi.Alert" + +msg_info "Start Pi.Alert Scan" +$STD python3 /opt/pialert/back/pialert.py update_vendors +$STD python3 /opt/pialert/back/pialert.py internet_IP +$STD python3 /opt/pialert/back/pialert.py 1 +msg_ok "Finished Pi.Alert Scan" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 4ad11e74f74b1a13e6ddb885873e9e5a2a993411 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 08:10:44 -0400 Subject: [PATCH 5262/6505] Create pialert.sh --- ct/pialert.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/pialert.sh diff --git a/ct/pialert.sh b/ct/pialert.sh new file mode 100644 index 00000000..39ddd9de --- /dev/null +++ b/ct/pialert.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _ ___ __ __ + / __ \(_) / | / /__ _____/ /_ + / /_/ / / / /| | / / _ \/ ___/ __/ + / ____/ / / ___ |/ / __/ / / /_ +/_/ /_(_)_/ |_/_/\___/_/ \__/ + +EOF +} +header_info +echo -e "Loading..." +APP="PiAlert" +var_disk="3" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}/pialert/${CL} \n" From e09013a8df10c3dd3efeb08cefa2dd0742386e7a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 08:28:57 -0400 Subject: [PATCH 5263/6505] Update pialert-install.sh tweak --- install/pialert-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index a3181661..32453b42 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -52,7 +52,7 @@ $STD pip3 install fritzconnection $STD pip3 install cryptography msg_ok "Installed Python Dependencies" -msg_info "Installing Pi.Alert (Patience)" +msg_info "Installing Pi.Alert" curl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1 rm /var/www/html/index.html @@ -82,7 +82,7 @@ ln -s "/opt/pialert/log/pialert.webservices.log" "/opt/pialert/front/php/server/ sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf msg_ok "Installed Pi.Alert" -msg_info "Start Pi.Alert Scan" +msg_info "Start Pi.Alert Scan (Patience)" $STD python3 /opt/pialert/back/pialert.py update_vendors $STD python3 /opt/pialert/back/pialert.py internet_IP $STD python3 /opt/pialert/back/pialert.py 1 From 644ca75dbdd3dddf30741712f84b826e4b7cf9e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 08:50:10 -0400 Subject: [PATCH 5264/6505] Update kernel-clean.sh Code overhaul with a fresh start. --- misc/kernel-clean.sh | 144 +++++++++++-------------------------------- 1 file changed, 37 insertions(+), 107 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 81bc0e63..c440a9cf 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -6,8 +6,9 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { - cat <<"EOF" - __ __ __ ________ + clear + cat <<"EOF" + __ __ __ ________ / //_/__ _________ ___ / / / ____/ /__ ____ _____ / ,< / _ \/ ___/ __ \/ _ \/ / / / / / _ \/ __ `/ __ \ / /| / __/ / / / / / __/ / / /___/ / __/ /_/ / / / / @@ -15,126 +16,55 @@ function header_info { EOF } -set -euo pipefail -shopt -s inherit_errexit nullglob YW=$(echo "\033[33m") -BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") CL=$(echo "\033[m") BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -PARTY="🎉" current_kernel=$(uname -r) -clear +available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v "$current_kernel" | sort -V) header_info -while true; do - read -p "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo -e "${RD}Please answer y/n${CL}" ;; - esac -done -clear + function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." } function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -function check_root() { - if [[ $EUID -ne 0 ]]; then - echo -e "${CROSS}${RD}Error: This script must be ran as the root user.\n${CL}" - exit 1 - else - header_info - other_kernel - kernel_info - kernel_clean - fi -} +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Clean" --yesno "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed?" 10 68 || exit - VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" -function other_kernel() { - if [[ "${VERSION}" == "bullseye" ]]; then - if [[ "$current_kernel" == *"edge"* ]]; then - echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" - echo -e "\nAn Active PVE Kernel is required to use Kernel Clean\n" - exit 1 - fi - if [[ "$current_kernel" == *"6.1"* || "$current_kernel" == *"6.2"* ]]; then - echo -e "\n${CROSS} ${RD}ERROR:${CL} Proxmox ${BL}${current_kernel}${CL} Kernel Active" - echo -e "\nThe script cannot be used when running opt-in kernels. \nProxmox VE's package management relies directly on the current default kernel, which is 5.15. \nTherefore, it is not possible to utilize this script. In this case, you should use autoremove instead. \n`apt-get autoremove`\n" - exit 1 - fi - fi -} - -function kernel_info() { - if [[ "$MODE" != "PBS" ]]; then - echo -e "${YW}PVE Version: ${BL}$(pveversion)\n${CL}" - fi - if [[ "$current_kernel" == *"pve"* ]]; then - echo -e "${YW}Current Kernel: ${BL}$current_kernel\n${CL}" - else - echo -e "\n${CROSS} ${RD}ERROR: No PVE Kernel Found\n${CL}" - exit 1 - fi -} - -function kernel_clean() { - kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | sort -V) - remove_kernels="" - for kernel in $kernels; do - if [ "$(echo $kernel | grep $current_kernel)" ]; then - break - else - echo -e "${BL}'$kernel' ${CL}${YW}has been added to the remove Kernel list\n${CL}" - remove_kernels+=" $kernel" - fi - done - msg_ok "Kernel Search Completed\n" - if [[ "$remove_kernels" != *"pve"* ]]; then - echo -e "${PARTY} ${GN}It appears there are no old Kernels on your system. \n${CL}" - msg_info "Exiting" - sleep 2 - msg_ok "Done" - else - read -p "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') selected Kernels listed above? [y/n]: " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" - /usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 - msg_ok "Successfully Removed Kernels" - msg_info "Updating GRUB" - /usr/sbin/update-grub >/dev/null 2>&1 - msg_ok "Successfully Updated GRUB" - msg_info "Exiting" - sleep 2 - msg_ok "Done" - else - msg_info "Exiting" - sleep 2 - msg_ok "Done" - fi - fi -} - -if ! command -v pveversion >/dev/null 2>&1; then - echo -e " Switching to PBS mode" - MODE="PBS" - sleep 2 -else - MODE="PVE" +if [ -z "$available_kernels" ]; then + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Other Kernels" --msgbox "It appears there are no old Kernels on your system. \nCurrent kernel ($current_kernel)." 10 68 + msg_info "Exiting" + sleep 2 + msg_ok "Done" + exit fi -check_root +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(echo "$available_kernels") + +remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" \ + 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the selected Kernels\n $remove_kernels\n Proceed?" 10 68 || exit + +msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" +/usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 +msg_ok "Successfully Removed Kernels" + +msg_info "Updating GRUB" +/usr/sbin/update-grub >/dev/null 2>&1 +msg_ok "Successfully Updated GRUB" +msg_info "Exiting" +sleep 2 +msg_ok "Done" From 4fdead6380aef15485d760df7a0be2a8ec3ff901 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 08:50:28 -0400 Subject: [PATCH 5265/6505] Delete misc/kernel-clean-test.sh --- misc/kernel-clean-test.sh | 70 --------------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 misc/kernel-clean-test.sh diff --git a/misc/kernel-clean-test.sh b/misc/kernel-clean-test.sh deleted file mode 100644 index c440a9cf..00000000 --- a/misc/kernel-clean-test.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { - clear - cat <<"EOF" - __ __ __ ________ - / //_/__ _________ ___ / / / ____/ /__ ____ _____ - / ,< / _ \/ ___/ __ \/ _ \/ / / / / / _ \/ __ `/ __ \ - / /| / __/ / / / / / __/ / / /___/ / __/ /_/ / / / / -/_/ |_\___/_/ /_/ /_/\___/_/ \____/_/\___/\__,_/_/ /_/ - -EOF -} -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -current_kernel=$(uname -r) -available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v "$current_kernel" | sort -V) -header_info - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Clean" --yesno "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed?" 10 68 || exit - -if [ -z "$available_kernels" ]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Other Kernels" --msgbox "It appears there are no old Kernels on your system. \nCurrent kernel ($current_kernel)." 10 68 - msg_info "Exiting" - sleep 2 - msg_ok "Done" - exit -fi - -while read -r TAG ITEM; do - OFFSET=2 - ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$TAG" "$ITEM " "OFF") -done < <(echo "$available_kernels") - -remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" \ - 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit - -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the selected Kernels\n $remove_kernels\n Proceed?" 10 68 || exit - -msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" -/usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 -msg_ok "Successfully Removed Kernels" - -msg_info "Updating GRUB" -/usr/sbin/update-grub >/dev/null 2>&1 -msg_ok "Successfully Updated GRUB" -msg_info "Exiting" -sleep 2 -msg_ok "Done" From d8044f713d46092e78f73a9f9d649893f60b91f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 08:57:02 -0400 Subject: [PATCH 5266/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aa13c47..8c7f9116 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-13 + +### Changed + +- **Pi.Alert LXC** + - NEW Script +- **Proxmox VE Kernel Clean** + - Code overhaul with a fresh start. + ## 2023-09-11 ### Changed From e35904fbcfada638e166663dd10312d045c35a20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 09:38:12 -0400 Subject: [PATCH 5267/6505] Update kernel-clean.sh tweak --- misc/kernel-clean.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index c440a9cf..0dc53347 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -40,7 +40,7 @@ function msg_ok() { whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Clean" --yesno "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed?" 10 68 || exit if [ -z "$available_kernels" ]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Other Kernels" --msgbox "It appears there are no old Kernels on your system. \nCurrent kernel ($current_kernel)." 10 68 + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Old Kernels" --msgbox "It appears there are no old Kernels on your system. \nCurrent kernel ($current_kernel)." 10 68 msg_info "Exiting" sleep 2 msg_ok "Done" From 955d4b8ce54e387ca247179129aad74677eabaa7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 10:59:59 -0400 Subject: [PATCH 5268/6505] Update kernel-clean.sh tweak --- misc/kernel-clean.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 0dc53347..ace0f0a1 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -56,7 +56,7 @@ done < <(echo "$available_kernels") remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" \ 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the selected Kernels\n $remove_kernels\n Proceed?" 10 68 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the previously selected Kernels?" 10 68 || exit msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" /usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 From c844311b548bf8d4ff0cc2ed3af56d61e8cc8224 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 11:15:30 -0400 Subject: [PATCH 5269/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c7f9116..07884985 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ - **Pi.Alert LXC** - NEW Script - **Proxmox VE Kernel Clean** - - Code overhaul with a fresh start. + - Code overhaul with a fresh start. This script offers the flexibility to select specific kernels for removal, unlike the previous version, which was an all-or-nothing approach. ## 2023-09-11 From 14390c0e9ef19527528641062baed0009f574ff8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 11:35:21 -0400 Subject: [PATCH 5270/6505] Update clean-lxcs.sh code refactoring --- misc/clean-lxcs.sh | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 2614846b..a44e67cb 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -16,38 +16,23 @@ function header_info() { EOF } -set -e -YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") CM='\xE2\x9C\x94\033' GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info -while true; do - read -p "This Will Clean logs, cache and update apt lists on selected LXC Containers. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear +echo "Loading..." +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Clean logs, cache and update apt lists on selected LXC Containers. Proceed?" 10 58 || exit NODE=$(hostname) -while read -r line; do - TAG=$(echo "$line" | awk '{print $1}') - ITEM=$(echo "$line" | awk '{print substr($0,36)}') +while read -r TAG ITEM; do OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') -excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist \ - "\nSelect containers to skip from cleaning:\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit - +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from cleaning:\n" \ + 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + function clean_container() { container=$1 header_info @@ -87,4 +72,4 @@ done wait header_info -echo -e "${GN} Finished, Containers Cleaned. ${CL} \n" +echo -e "${GN} Finished, Selected Containers Cleaned. ${CL} \n" From 975bce31ba10f7a4d7a42180732562f3f259f2ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 11:48:21 -0400 Subject: [PATCH 5271/6505] Update clean.sh code refactoring --- misc/clean.sh | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/misc/clean.sh b/misc/clean.sh index 1d32009e..8e223784 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -6,14 +6,14 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info() { -clear -cat <<"EOF" + clear + cat <<"EOF" ________ __ _ ________ / ____/ /__ ____ _____ / / | |/ / ____/ - / / / / _ \/ __ `/ __ \ / / | / / -/ /___/ / __/ /_/ / / / / / /___/ / /___ -\____/_/\___/\__,_/_/ /_/ /_____/_/|_\____/ - + / / / / _ \/ __ `/ __ \ / / | / / +/ /___/ / __/ /_/ / / / / / /___/ / /___ +\____/_/\___/\__,_/_/ /_/ /_____/_/|_\____/ + EOF } BL=$(echo "\033[36m") @@ -27,16 +27,10 @@ if [[ -z "$cache" ]]; then echo -e "It appears there are no cached files on your system. \n" sleep 2 else - echo -e "$cache \n" - echo -e "${GN}Cache in $name${CL}" - read -p "Would you like to remove the selected cache listed above? [y/N] " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Removing cache" - find /var/cache -type f -delete - echo "Successfully Removed cache" - sleep 2 - fi + echo "Removing Cache" + find /var/cache -type f -delete + echo "Successfully Removed Cache" + sleep 2 fi header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" @@ -45,16 +39,10 @@ if [[ -z "$logs" ]]; then echo -e "It appears there are no logs on your system. \n" sleep 2 else - echo -e "$logs \n" - echo -e "${GN}Logs in $name${CL}" - read -p "Would you like to remove the selected logs listed above? [y/N] " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Removing logs" - find /var/log -type f -delete - echo "Successfully Removed logs" - sleep 2 - fi + echo "Removing Logs" + find /var/log -type f -delete + echo "Successfully Removed Logs" + sleep 2 fi header_info echo -e "${BL}[Info]${GN} Cleaning $name${CL} \n" From b651b404f67368ad6600029c9e318c81f1fa8ce6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Sep 2023 15:13:01 -0400 Subject: [PATCH 5272/6505] Update clean.sh tweak --- misc/clean.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/misc/clean.sh b/misc/clean.sh index 8e223784..1e73f66d 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -27,7 +27,6 @@ if [[ -z "$cache" ]]; then echo -e "It appears there are no cached files on your system. \n" sleep 2 else - echo "Removing Cache" find /var/cache -type f -delete echo "Successfully Removed Cache" sleep 2 @@ -39,7 +38,6 @@ if [[ -z "$logs" ]]; then echo -e "It appears there are no logs on your system. \n" sleep 2 else - echo "Removing Logs" find /var/log -type f -delete echo "Successfully Removed Logs" sleep 2 From ff42ff1082443dc1f5d1768f25e55e89e4cb9c5e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 07:41:16 -0400 Subject: [PATCH 5273/6505] Update shinobi-install.sh fixes https://github.com/tteck/Proxmox/issues/1792 --- install/shinobi-install.sh | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index 94fe7bc2..dd81b791 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -13,15 +13,6 @@ setting_up_container network_check update_os -ubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) -if [ "$ubuntuversion" = "18" ] || [ "$ubuntuversion" -le "18" ]; then - apt install sudo wget -y - sudo apt install -y software-properties-common - sudo add-apt-repository universe -y - apt update -y - apt update --fix-missing -y -fi - msg_info "Installing Dependencies" $STD apt-get install -y curl sudo git mc $STD apt-get install -y make zip net-tools @@ -57,21 +48,20 @@ echo '{"Product" : "'"Shinobi"'" , "Branch" : "'"master"'" , "Version" : "'"$git msg_ok "Cloned Shinobi" msg_info "Installing Database" -sqlpass="" +sqluser="root" +sqlpass="root" echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections $STD apt-get install -y mariadb-server service mysql start -sqluser="root" -mysql -e "source sql/user.sql" || true -mysql -e "source sql/framework.sql" || true +mysql -u "$sqluser" -p"$sqlpass" -e "source sql/user.sql" || true msg_ok "Installed Database" + +msg_info "Installing Shinobi" cp conf.sample.json conf.json cronKey=$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)}') sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json cp super.sample.json super.json - -msg_info "Installing Shinobi" $STD npm i npm -g $STD npm install --unsafe-perm $STD npm install pm2@latest -g From 3db776e749356d18e30d8c977da4786419e694a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 07:42:39 -0400 Subject: [PATCH 5274/6505] Update shinobi.sh default Ubuntu 22.04 --- ct/shinobi.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/shinobi.sh b/ct/shinobi.sh index 58882700..c5ce6ae3 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -24,7 +24,6 @@ var_cpu="2" var_ram="2048" var_os="ubuntu" var_version="22.04" -var_version="20.04" variables color catch_errors From 6df6d1c2fb27c5480e64e7aba8908b4cae12eafe Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 10:21:18 -0400 Subject: [PATCH 5275/6505] Update postgresql-install.sh postgresql-16 --- install/postgresql-install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/install/postgresql-install.sh b/install/postgresql-install.sh index 309b2d50..f85ca562 100644 --- a/install/postgresql-install.sh +++ b/install/postgresql-install.sh @@ -30,7 +30,7 @@ msg_info "Installing PostgreSQL" $STD apt-get update $STD apt-get install -y postgresql -cat </etc/postgresql/15/main/pg_hba.conf +cat </etc/postgresql/16/main/pg_hba.conf # PostgreSQL Client Authentication Configuration File local all postgres peer # TYPE DATABASE USER ADDRESS METHOD @@ -49,7 +49,7 @@ host replication all 127.0.0.1/32 scram-sha-256 host replication all ::1/128 scram-sha-256 EOF -cat </etc/postgresql/15/main/postgresql.conf +cat </etc/postgresql/16/main/postgresql.conf # ----------------------------- # PostgreSQL configuration file # ----------------------------- @@ -58,10 +58,10 @@ cat </etc/postgresql/15/main/postgresql.conf # FILE LOCATIONS #------------------------------------------------------------------------------ -data_directory = '/var/lib/postgresql/15/main' -hba_file = '/etc/postgresql/15/main/pg_hba.conf' -ident_file = '/etc/postgresql/15/main/pg_ident.conf' -external_pid_file = '/var/run/postgresql/15-main.pid' +data_directory = '/var/lib/postgresql/16/main' +hba_file = '/etc/postgresql/16/main/pg_hba.conf' +ident_file = '/etc/postgresql/16/main/pg_ident.conf' +external_pid_file = '/var/run/postgresql/16-main.pid' #------------------------------------------------------------------------------ # CONNECTIONS AND AUTHENTICATION @@ -107,7 +107,7 @@ log_timezone = 'Etc/UTC' # PROCESS TITLE #------------------------------------------------------------------------------ -cluster_name = '15/main' +cluster_name = '16/main' #------------------------------------------------------------------------------ # CLIENT CONNECTION DEFAULTS From 64bdc91b677b1e7f36657d4dee5898b0a4a76de0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 12:16:26 -0400 Subject: [PATCH 5276/6505] Update microcode.sh code refactoring --- misc/microcode.sh | 121 +++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 56 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 6b3bb5fc..7900bacd 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -5,8 +5,8 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { -clear -cat <<"EOF" + clear + cat <<"EOF" ____ __ ____ __ / __ \_________ ________ ______________ _____ / |/ (_)_____________ _________ ____/ /__ / /_/ / ___/ __ \/ ___/ _ \/ ___/ ___/ __ \/ ___/ / /|_/ / / ___/ ___/ __ \/ ___/ __ \/ __ / _ \ @@ -25,90 +25,99 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} +msg_info() { echo -ne " ${HOLD} ${YW}$1..."; } +msg_ok() { echo -e "${BFR} ${CM} ${GN}$1${CL}"; } +msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; } header_info -current_microcode=$(dmesg | grep -o 'microcode updated early to revision [^,]*, date = [0-9\-]*') -while true; do - if [ -z "${current_microcode}" ]; then - msg_error "Microcode update information not found." - else - msg_ok "Current ${current_microcode}" - fi - read -p "Install the latest Processor Microcode (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -header_info +current_microcode=$(journalctl -k | grep -E "microcode: microcode" | awk -F 'microcode: microcode updated early to revision |, date = ' '{print $2 ", date = " $3}') +[ -z "$current_microcode" ] && current_microcode="Not found." intel() { if ! dpkg -s iucode-tool >/dev/null 2>&1; then - msg_info "Installing iucode-tool: a tool for updating Intel processor microcode" + msg_info "Installing iucode-tool (Intel microcode updater)" apt-get install -y iucode-tool &>/dev/null msg_ok "Installed iucode-tool" else msg_ok "Intel iucode-tool is already installed" + sleep 1 fi - - msg_info "Downloading the latest Intel Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/intel-microcode_3.20230808.1_amd64.deb - msg_ok "Downloaded the latest Intel Processor Microcode Package" - msg_info "Installing the Intel Processor Microcode (Patience)" - dpkg -i intel-microcode_3.20230808.1_amd64.deb &>/dev/null - msg_ok "Installed the Intel Processor Microcode" + intel_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode//" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//') + [ -z "$intel_microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + CTID_MENU=() + MSG_MAX_LENGTH=0 + + while read -r TAG ITEM; do + OFFSET=2 + (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + CTID_MENU+=("$TAG" "$ITEM " "OFF") + done < <(echo "$intel_microcode") + + microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + + [ -z "$microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Selected" --msgbox "It appears that no microcode packages were selected" 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + msg_info "Downloading the Intel Processor Microcode Package $microcode" + wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/$microcode + msg_ok "Downloaded the Intel Processor Microcode Package $microcode" + + msg_info "Installing $microcode (Patience)" + dpkg -i $microcode &>/dev/null + msg_ok "Installed $microcode" msg_info "Cleaning up" - rm intel-microcode_3.20230808.1_amd64.deb + rm $microcode msg_ok "Cleaned" - - echo -e "\n To apply the changes, the system will need to be rebooted.\n" + echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n" } amd() { - msg_info "Downloading the latest AMD Processor Microcode Package for Linux" - wget -q http://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/amd64-microcode_3.20230808.1.1_amd64.deb - msg_ok "Downloaded the latest AMD Processor Microcode Package" + amd_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode///" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//') - msg_info "Installing the AMD Processor Microcode (Patience)" - dpkg -i amd64-microcode_3.20230808.1.1_amd64.deb &>/dev/null - msg_ok "Installed the AMD Processor Microcode" + [ -z "$amd_microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + CTID_MENU=() + MSG_MAX_LENGTH=0 + + while read -r TAG ITEM; do + OFFSET=2 + (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + CTID_MENU+=("$TAG" "$ITEM " "OFF") + done < <(echo "$amd_microcode") + + microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + + [ -z "$microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Selected" --msgbox "It appears that no microcode packages were selected" 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } + + msg_info "Downloading the AMD Processor Microcode Package $microcode" + wget -q https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode + msg_ok "Downloaded the AMD Processor Microcode Package $microcode" + + msg_info "Installing $microcode (Patience)" + dpkg -i $microcode &>/dev/null + msg_ok "Installed $microcode" msg_info "Cleaning up" - rm amd64-microcode_3.20230808.1.1_amd64.deb + rm $microcode msg_ok "Cleaned" - - echo -e "\n To apply the changes, the system will need to be rebooted.\n" + echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n" } -if ! command -v pveversion >/dev/null 2>&1; then - header_info - msg_error "\n No PVE Detected!\n" - exit -fi +if ! command -v pveversion >/dev/null 2>&1; then header_info; msg_error "No PVE Detected!"; exit; fi + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Processor Microcode" --yesno "This will check for CPU microcode packages with the option to install. Proceed?" 10 58 || exit + msg_info "Checking CPU Vendor" cpu=$(lscpu | grep -oP 'Vendor ID:\s*\K\S+' | head -n 1) if [ "$cpu" == "GenuineIntel" ]; then msg_ok "${cpu} was detected" + sleep 1 intel elif [ "$cpu" == "AuthenticAMD" ]; then msg_ok "${cpu} was detected" + sleep 1 amd else msg_error "${cpu} is not supported" From 43d77409606c6ba9bda4c1aba79735207c1ffdf7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 12:20:58 -0400 Subject: [PATCH 5277/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07884985..f6359acb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ ### Changed +- **Proxmox VE Processor Microcode** + - Allow users to select available microcode packages. + +## 2023-09-13 + +### Changed + - **Pi.Alert LXC** - NEW Script - **Proxmox VE Kernel Clean** From 4b5069f2bc99d1b53f89ab7453f38f1b074ace3a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 12:21:17 -0400 Subject: [PATCH 5278/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6359acb..15de103c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. -## 2023-09-13 +## 2023-09-14 ### Changed From d48b458969891c89e3515026337aa6aa5579c256 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 22:24:08 -0400 Subject: [PATCH 5279/6505] Create turnkey.sh This will allow for the creation of one of the many TurnKey LXC Containers. --- turnkey/turnkey.sh | 236 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 turnkey/turnkey.sh diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh new file mode 100644 index 00000000..fff4a4c4 --- /dev/null +++ b/turnkey/turnkey.sh @@ -0,0 +1,236 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ______ __ __ __ _ _______ +/_ __/_ _________ / //_/__ __ __ / / | |/_/ ___/ + / / / // / __/ _ \/ ,< / -_) // / / /___> &2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} + +# Stop Proxmox VE Monitor-All if running +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +header_info +whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs" --yesno "This will allow for the creation of one of the many TurnKey LXC Containers. Proceed?" 10 68 || exit +CTID_MENU=() +MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <( + cat <&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$turnkey" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No TurnKey LXC Selected" --msgbox "It appears that no TurnKey LXC container was selected" 10 68 + msg "Done" + exit +} + +# Setup script environment +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +TEMPLATE_SEARCH="debian-11-turnkey-${turnkey}" +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname turnkey-${turnkey} + -tags proxmox-helper-scripts + -onboot 1 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) + +# Set the CONTENT and CONTENT_LABEL variables +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) + CONTENT='rootdir' + CONTENT_LABEL='Container' + ;; + template) + CONTENT='vztmpl' + CONTENT_LABEL='Container template' + ;; + *) false || die "Invalid storage class." ;; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=("$TAG" "$ITEM" "OFF") + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then + printf ${MENU[0]} + else + local STORAGE + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Update LXC template list +msg "Updating LXC template list..." +pveam update >/dev/null + +# Get LXC template string +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +TEMPLATE="${TEMPLATES[-1]}" + +# Download LXC template +if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then + msg "Downloading LXC template (Patience)..." + pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || + die "A problem occured while downloading the LXC template." +fi + +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Save password +echo "TurnKey ${turnkey} password: ${PASS}" >>~/turnkey-${turnkey}.creds # file is located in the Proxmox root directory + +# Start container +msg "Starting LXC Container..." +pct start "$CTID" +sleep 5 + +# Get container IP +set +e +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +set -e +# Start Proxmox VE Monitor-All if available +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi + +# Success message +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo +info "Proceed to the LXC console to complete the setup." +echo +info "login: root" +info "password: $PASS" +echo From 63dbfcdec4a79217884410fd5911744b3bcc1760 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Sep 2023 23:16:54 -0400 Subject: [PATCH 5280/6505] Remove unnecessary turnkey container files. --- turnkey/turnkey-core.sh | 202 ------------------------------- turnkey/turnkey-fileserver.sh | 202 ------------------------------- turnkey/turnkey-gameserver.sh | 202 ------------------------------- turnkey/turnkey-gitea.sh | 202 ------------------------------- turnkey/turnkey-gitlab.sh | 202 ------------------------------- turnkey/turnkey-mediaserver.sh | 202 ------------------------------- turnkey/turnkey-nextcloud.sh | 202 ------------------------------- turnkey/turnkey-observium.sh | 202 ------------------------------- turnkey/turnkey-openvpn.sh | 202 ------------------------------- turnkey/turnkey-owncloud.sh | 202 ------------------------------- turnkey/turnkey-torrentserver.sh | 202 ------------------------------- turnkey/turnkey-wordpress.sh | 202 ------------------------------- turnkey/turnkey-zoneminder.sh | 202 ------------------------------- 13 files changed, 2626 deletions(-) delete mode 100644 turnkey/turnkey-core.sh delete mode 100644 turnkey/turnkey-fileserver.sh delete mode 100644 turnkey/turnkey-gameserver.sh delete mode 100644 turnkey/turnkey-gitea.sh delete mode 100644 turnkey/turnkey-gitlab.sh delete mode 100644 turnkey/turnkey-mediaserver.sh delete mode 100644 turnkey/turnkey-nextcloud.sh delete mode 100644 turnkey/turnkey-observium.sh delete mode 100644 turnkey/turnkey-openvpn.sh delete mode 100644 turnkey/turnkey-owncloud.sh delete mode 100644 turnkey/turnkey-torrentserver.sh delete mode 100644 turnkey/turnkey-wordpress.sh delete mode 100644 turnkey/turnkey-zoneminder.sh diff --git a/turnkey/turnkey-core.sh b/turnkey/turnkey-core.sh deleted file mode 100644 index 7a0f8733..00000000 --- a/turnkey/turnkey-core.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="core" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="4" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ _____ -/_ __/_ _________ / //_/__ __ __ / ___/__ _______ - / / / // / __/ _ \/ ,< / -_) // / / /__/ _ \/ __/ -_) -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/\___/_/ \__/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-fileserver.sh b/turnkey/turnkey-fileserver.sh deleted file mode 100644 index 4826f253..00000000 --- a/turnkey/turnkey-fileserver.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="fileserver" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="8" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ _____ __ ____ -/_ __/_ _________ / //_/__ __ __ / __(_) /__ / __/__ _____ _____ ____ - / / / // / __/ _ \/ ,< / -_) // / / _// / / -_) _\ \/ -_) __/ |/ / -_) __/ -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/ /_/_/\__/ /___/\__/_/ |___/\__/_/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-gameserver.sh b/turnkey/turnkey-gameserver.sh deleted file mode 100644 index bc19fd26..00000000 --- a/turnkey/turnkey-gameserver.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="gameserver" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="8" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - _____ ____ - / ___/__ ___ _ ___ / __/__ _____ _____ ____ -/ (_ / _ `/ ' \/ -_) _\ \/ -_) __/ |/ / -_) __/ -\___/\_,_/_/_/_/\__/ /___/\__/_/ |___/\__/_/ - -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo diff --git a/turnkey/turnkey-gitea.sh b/turnkey/turnkey-gitea.sh deleted file mode 100644 index 3943cde5..00000000 --- a/turnkey/turnkey-gitea.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="gitea" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="4" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ ______ __ -/_ __/_ _________ / //_/__ __ __ / ___(_) /____ ___ _ - / / / // / __/ _ \/ ,< / -_) // / / (_ / / __/ -_) _ `/ -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/_/\__/\__/\_,_/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-gitlab.sh b/turnkey/turnkey-gitlab.sh deleted file mode 100644 index 4059f424..00000000 --- a/turnkey/turnkey-gitlab.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="gitlab" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="8" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 4 - -memory 4096 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ ______ __ __ __ -/_ __/_ _________ / //_/__ __ __ / ___(_) /_/ / ___ _/ / - / / / // / __/ _ \/ ,< / -_) // / / (_ / / __/ /__/ _ `/ _ \ -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/_/\__/____/\_,_/_.__/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-mediaserver.sh b/turnkey/turnkey-mediaserver.sh deleted file mode 100644 index edd1b6f6..00000000 --- a/turnkey/turnkey-mediaserver.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="mediaserver" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="8" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ __ ___ ___ ____ -/_ __/_ _________ / //_/__ __ __ / |/ /__ ___/ (_)__ _ / __/__ _____ _____ ____ - / / / // / __/ _ \/ ,< / -_) // / / /|_/ / -_) _ / / _ `/ _\ \/ -_) __/ |/ / -_) __/ -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/ /_/\__/\_,_/_/\_,_/ /___/\__/_/ |___/\__/_/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo diff --git a/turnkey/turnkey-nextcloud.sh b/turnkey/turnkey-nextcloud.sh deleted file mode 100644 index b13cdb5e..00000000 --- a/turnkey/turnkey-nextcloud.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="nextcloud" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="10" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ _ __ __ __ __ -/_ __/_ _________ / //_/__ __ __ / |/ /____ __/ /_____/ /__ __ _____/ / - / / / // / __/ _ \/ ,< / -_) // / / / -_) \ / __/ __/ / _ \/ // / _ / -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/|_/\__/_\_\\__/\__/_/\___/\_,_/\_,_/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-observium.sh b/turnkey/turnkey-observium.sh deleted file mode 100644 index 93f444b7..00000000 --- a/turnkey/turnkey-observium.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="observium" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="4" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ ____ __ _ -/_ __/_ _________ / //_/__ __ __ / __ \/ / ___ ___ _____ __(_)_ ____ _ - / / / // / __/ _ \/ ,< / -_) // / / /_/ / _ \(_-&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-openvpn.sh b/turnkey/turnkey-openvpn.sh deleted file mode 100644 index 79f5b407..00000000 --- a/turnkey/turnkey-openvpn.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="openvpn" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="4" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ ____ _ _____ _ __ -/_ __/_ _________ / //_/__ __ __ / __ \___ ___ ___| | / / _ \/ |/ / - / / / // / __/ _ \/ ,< / -_) // / / /_/ / _ \/ -_) _ \ |/ / ___/ / -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \____/ .__/\__/_//_/___/_/ /_/|_/ - /___/ /_/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-owncloud.sh b/turnkey/turnkey-owncloud.sh deleted file mode 100644 index a5f16ff0..00000000 --- a/turnkey/turnkey-owncloud.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="owncloud" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="10" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ _______ __ -/_ __/_ _________ / //_/__ __ __ ___ _ _____ / ___/ /__ __ _____/ / - / / / // / __/ _ \/ ,< / -_) // / / _ \ |/|/ / _ \/ /__/ / _ \/ // / _ / -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/__,__/_//_/\___/_/\___/\_,_/\_,_/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-torrentserver.sh b/turnkey/turnkey-torrentserver.sh deleted file mode 100644 index 795d6c6f..00000000 --- a/turnkey/turnkey-torrentserver.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="torrentserver" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="10" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ ______ __ ____ -/_ __/_ _________ / //_/__ __ __ /_ __/__ ___________ ___ / /_ / __/__ _____ _____ ____ - / / / // / __/ _ \/ ,< / -_) // / / / / _ \/ __/ __/ -_) _ \/ __/ _\ \/ -_) __/ |/ / -_) __/ -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/ \___/_/ /_/ \__/_//_/\__/ /___/\__/_/ |___/\__/_/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-wordpress.sh b/turnkey/turnkey-wordpress.sh deleted file mode 100644 index 9c7aedc8..00000000 --- a/turnkey/turnkey-wordpress.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="wordpress" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="8" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ _ __ _____ -/_ __/_ _________ / //_/__ __ __ | | /| / /__ _______/ / _ \_______ ___ ___ - / / / // / __/ _ \/ ,< / -_) // / | |/ |/ / _ \/ __/ _ / ___/ __/ -_|_-<(_-< -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / |__/|__/\___/_/ \_,_/_/ /_/ \__/___/___/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file diff --git a/turnkey/turnkey-zoneminder.sh b/turnkey/turnkey-zoneminder.sh deleted file mode 100644 index 41321872..00000000 --- a/turnkey/turnkey-zoneminder.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# Setup script environment -NAME="zoneminder" -PASS="$(openssl rand -base64 8)" -CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${NAME}" -PCT_DISK_SIZE="8" -PCT_OPTIONS=" - -features keyctl=1,nesting=1 - -hostname turnkey-${NAME} - -tags proxmox-helper-scripts - -onboot 1 - -cores 2 - -memory 2048 - -password $PASS - -net0 name=eth0,bridge=vmbr0,ip=dhcp - -unprivileged 1 - " -DEFAULT_PCT_OPTIONS=( - -arch $(dpkg --print-architecture) -) -function header_info { -clear -cat <<"EOF" - ______ __ __ ____ __ ____ __ -/_ __/_ _________ / //_/__ __ __ /_ / ___ ___ ___ / |/ (_)__ ___/ /__ ____ - / / / // / __/ _ \/ ,< / -_) // / / /_/ _ \/ _ \/ -_) /|_/ / / _ \/ _ / -_) __/ -/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /___/\___/_//_/\__/_/ /_/_/_//_/\_,_/\__/_/ - /___/ -EOF -} -header_info -read -p "Press ENTER to continue..." -header_info -set -eEuo pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local DEFAULT='Unknown failure occured.' - local REASON="\e[97m${1:-$DEFAULT}\e[39m" - local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" - msg "$FLAG $REASON" 1>&2 - [ ! -z ${CTID-} ] && cleanup_ctid - exit $EXIT -} -function warn() { - local REASON="\e[97m$1\e[39m" - local FLAG="\e[93m[WARNING]\e[39m" - msg "$FLAG $REASON" -} -function info() { - local REASON="$1" - local FLAG="\e[36m[INFO]\e[39m" - msg "$FLAG $REASON" -} -function msg() { - local TEXT="$1" - echo -e "$TEXT" -} -function cleanup_ctid() { - if pct status $CTID &>/dev/null; then - if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then - pct stop $CTID - fi - pct destroy $CTID - fi -} - -# Stop Proxmox VE Monitor-All if running -if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service -fi - -# Set the CONTENT and CONTENT_LABEL variables -function select_storage() { - local CLASS=$1 - local CONTENT - local CONTENT_LABEL - case $CLASS in - container) CONTENT='rootdir'; CONTENT_LABEL='Container';; - template) CONTENT='vztmpl'; CONTENT_LABEL='Container template';; - *) false || die "Invalid storage class.";; - esac - - # Query all storage locations - local -a MENU - while read -r line; do - local TAG=$(echo $line | awk '{print $1}') - local TYPE=$(echo $line | awk '{printf "%-10s", $2}') - local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - local ITEM=" Type: $TYPE Free: $FREE " - local OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - MENU+=("$TAG" "$ITEM" "OFF") - done < <(pvesm status -content $CONTENT | awk 'NR>1') - - # Select storage location - if [ $((${#MENU[@]} / 3)) -eq 0 ]; then - warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." - die "Unable to detect valid storage location." - elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then - printf ${MENU[0]} - else - local STORAGE - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." - done - printf $STORAGE - fi -} - -# Get template storage -TEMPLATE_STORAGE=$(select_storage template) || exit -info "Using '$TEMPLATE_STORAGE' for template storage." - -# Get container storage -CONTAINER_STORAGE=$(select_storage container) || exit -info "Using '$CONTAINER_STORAGE' for container storage." - -# Update LXC template list -msg "Updating LXC template list..." -pveam update >/dev/null - -# Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." -TEMPLATE="${TEMPLATES[-1]}" - -# Download LXC template -if ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then - msg "Downloading LXC template (Patience)..." - pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || - die "A problem occured while downloading the LXC template." -fi - -# Create variable for 'pct' options -PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) -[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) - -# Create LXC -msg "Creating LXC container..." -pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || - die "A problem occured while trying to create container." - -# Save password -echo "TurnKey ${NAME} password: ${PASS}" >>~/turnkey-${NAME}.creds # file is located in the Proxmox root directory - -# Start container -msg "Starting LXC Container..." -pct start "$CTID" -sleep 5 - -# Get container IP -set +e -max_attempts=5 -attempt=1 -IP="" -while [[ $attempt -le $max_attempts ]]; do - IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') - if [[ -n $IP ]]; then - break - else - warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." - sleep 5 - ((attempt++)) - fi -done - -if [[ -z $IP ]]; then - warn "Maximum number of attempts reached. IP address not found." - IP="NOT FOUND" -fi - -set -e -# Start Proxmox VE Monitor-All if available -if [[ -f /etc/systemd/system/ping-instances.service ]]; then - systemctl start ping-instances.service -fi - -# Success message -header_info -echo -info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." -echo -info "Proceed to the LXC console to complete the setup." -echo -info "login: root" -info "password: $PASS" -echo \ No newline at end of file From 7edf944b6b18e8f485daef0943e6645324de06b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Sep 2023 05:28:17 -0400 Subject: [PATCH 5281/6505] Update nginxproxymanager-install.sh fixes https://github.com/tteck/Proxmox/issues/1797 --- install/nginxproxymanager-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 04b8820e..add592ee 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -40,6 +40,7 @@ $STD apt-get install -y \ python3-certbot \ python3-certbot-dns-cloudflare $STD pip3 install certbot_dns_porkbun +$STD pip3 install certbot-dns-duckdns $STD python3 -m venv /opt/certbot/ msg_ok "Installed Python Dependencies" From 28b290c4e5aa34094bb0bc74b9108d3eececc28f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 15 Sep 2023 17:44:16 -0400 Subject: [PATCH 5282/6505] Update turnkey.sh add Invoice Ninja --- turnkey/turnkey.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index fff4a4c4..51197ea5 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -71,6 +71,7 @@ gallery Gallery gameserver Game Server gitea Gitea gitlab GitLab +invoice-ninja Invoice Ninja mediaserver Media Server nextcloud Nextcloud observium Observium From 6c4a48dd658a6e4edd8e6ee9ebcfe28db3b3f1ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Sep 2023 11:42:03 -0400 Subject: [PATCH 5283/6505] Update pialert-install.sh code refactoring --- install/pialert-install.sh | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 32453b42..866bb94a 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -54,31 +54,20 @@ msg_ok "Installed Python Dependencies" msg_info "Installing Pi.Alert" curl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1 - -rm /var/www/html/index.html +mkdir -p /opt/pialert/front/reports +rm -rf /var/www/html/index.html /opt/pialert/{docs,install,tar} mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old ln -s /opt/pialert/install/index.html /var/www/html/index.html ln -s /opt/pialert/front /var/www/html/pialert -chmod go+x /opt/pialert -chgrp -R www-data /opt/pialert/db -chmod -R 775 /opt/pialert/db -chmod -R 775 /opt/pialert/db/temp -chgrp www-data /opt/pialert/config -chmod -R 775 /opt/pialert/config -chgrp www-data /opt/pialert/config/pialert.conf -chmod -R 775 /opt/pialert/front/reports -chgrp -R www-data /opt/pialert/front/reports -chmod +x /opt/pialert/back/shoutrrr/x86/shoutrrr -touch "/opt/pialert/log/pialert.vendors.log" -touch "/opt/pialert/log/pialert.IP.log" -touch "/opt/pialert/log/pialert.1.log" -touch "/opt/pialert/log/pialert.cleanup.log" -touch "/opt/pialert/log/pialert.webservices.log" -ln -s "/opt/pialert/log/pialert.vendors.log" "/opt/pialert/front/php/server/pialert.vendors.log" -ln -s "/opt/pialert/log/pialert.IP.log" "/opt/pialert/front/php/server/pialert.IP.log" -ln -s "/opt/pialert/log/pialert.1.log" "/opt/pialert/front/php/server/pialert.1.log" -ln -s "/opt/pialert/log/pialert.cleanup.log" "/opt/pialert/front/php/server/pialert.cleanup.log" -ln -s "/opt/pialert/log/pialert.webservices.log" "/opt/pialert/front/php/server/pialert.webservices.log" +chmod go+x /opt/pialert /opt/pialert/back/shoutrrr/x86/shoutrrr +chgrp -R www-data /opt/pialert/db /opt/pialert/front/reports /opt/pialert/config /opt/pialert/config/pialert.conf +chmod -R 775 /opt/pialert/db /opt/pialert/db/temp /opt/pialert/config /opt/pialert/front/reports +touch /opt/pialert/log/pialert.vendors.log /opt/pialert/log/pialert.IP.log /opt/pialert/log/pialert.1.log /opt/pialert/log/pialert.cleanup.log /opt/pialert/log/pialert.webservices.log +src_dir="/opt/pialert/log" +dest_dir="/opt/pialert/front/php/server" +for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log pialert.webservices.log; do + ln -s "$src_dir/$file" "$dest_dir/$file" +done sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf msg_ok "Installed Pi.Alert" From c68e8e69e0769b4a03c8dbf93fd62d65a189909b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Sep 2023 13:54:54 -0400 Subject: [PATCH 5284/6505] Update pialert-install.sh switch to "git clone" installation --- install/pialert-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 866bb94a..90a5626d 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -18,6 +18,7 @@ $STD apt-get -y install \ sudo \ mc \ curl \ + git \ apt-utils \ lighttpd \ sqlite3 \ @@ -52,8 +53,8 @@ $STD pip3 install fritzconnection $STD pip3 install cryptography msg_ok "Installed Python Dependencies" -msg_info "Installing Pi.Alert" -curl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1 +msg_info "Installing Pi.Alert (Patience)" +git clone -q https://github.com/leiweibau/Pi.Alert.git /opt/pialert mkdir -p /opt/pialert/front/reports rm -rf /var/www/html/index.html /opt/pialert/{docs,install,tar} mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old From ed674aaedd5695c8de2276b77ace3b7d170a3c51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Sep 2023 15:24:18 -0400 Subject: [PATCH 5285/6505] Update pialert.sh tweak --- ct/pialert.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ct/pialert.sh b/ct/pialert.sh index 39ddd9de..abe9c4b3 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -52,11 +52,8 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +if [[ ! -d /opt/pialert ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." exit } From 0554641b835d095452a6fdb6cfbfa8da6c491b3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Sep 2023 22:53:33 -0400 Subject: [PATCH 5286/6505] Update pialert-install.sh tweak --- install/pialert-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 90a5626d..4fd3078a 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -56,7 +56,7 @@ msg_ok "Installed Python Dependencies" msg_info "Installing Pi.Alert (Patience)" git clone -q https://github.com/leiweibau/Pi.Alert.git /opt/pialert mkdir -p /opt/pialert/front/reports -rm -rf /var/www/html/index.html /opt/pialert/{docs,install,tar} +rm -rf /var/www/html/index.html mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old ln -s /opt/pialert/install/index.html /var/www/html/index.html ln -s /opt/pialert/front /var/www/html/pialert From 1fb4fcf84e0f239eb8353d93d4c5b1f4f7724112 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 10:55:33 -0400 Subject: [PATCH 5287/6505] Update pialert-install.sh add three new commands - "scan" Runs arp-scan - "permissions" Repair file group permissions - "sudoers" Create sudoer file for www-data and Pi.Alert user --- install/pialert-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 4fd3078a..63c9ba4d 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -70,6 +70,12 @@ for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log ln -s "$src_dir/$file" "$dest_dir/$file" done sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf +echo "python3 /opt/pialert/back/pialert.py 1" >/usr/bin/scan +chmod +x /usr/bin/scan +echo "/opt/pialert/back/pialert-cli set_permissions --lxc" >/usr/bin/permissions +chmod +x /usr/bin/permissions +echo "/opt/pialert/back/pialert-cli set_sudoers --lxc" >/usr/bin/sudoers +chmod +x /usr/bin/sudoers msg_ok "Installed Pi.Alert" msg_info "Start Pi.Alert Scan (Patience)" From d1da3949eac9e7f9a7ced9ba51d957b5f59b8aeb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 16:44:04 -0400 Subject: [PATCH 5288/6505] Update pialert-install.sh - add crontab - fixes https://github.com/tteck/Proxmox/issues/1806 --- install/pialert-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 63c9ba4d..f0e3f0d6 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -70,6 +70,8 @@ for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log ln -s "$src_dir/$file" "$dest_dir/$file" done sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf +sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron +(crontab -l 2>/dev/null; cat /opt/pialert/install/pialert.cron) | crontab - echo "python3 /opt/pialert/back/pialert.py 1" >/usr/bin/scan chmod +x /usr/bin/scan echo "/opt/pialert/back/pialert-cli set_permissions --lxc" >/usr/bin/permissions From 0042ec95cf70341f440b06e8160c74b5f8bf8c51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 22:13:11 -0400 Subject: [PATCH 5289/6505] Update pialert.sh increase storage --- ct/pialert.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pialert.sh b/ct/pialert.sh index abe9c4b3..f9f98a92 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -19,7 +19,7 @@ EOF header_info echo -e "Loading..." APP="PiAlert" -var_disk="3" +var_disk="6" var_cpu="1" var_ram="512" var_os="debian" From 3fd4a5007857258f6587f8f9d3c9c6fb035934ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 22:33:28 -0400 Subject: [PATCH 5290/6505] Update pialert-install.sh - added a new "update" command that allows you to execute updates for Pi.Alert. - tweaks --- install/pialert-install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index f0e3f0d6..34b57319 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -53,8 +53,8 @@ $STD pip3 install fritzconnection $STD pip3 install cryptography msg_ok "Installed Python Dependencies" -msg_info "Installing Pi.Alert (Patience)" -git clone -q https://github.com/leiweibau/Pi.Alert.git /opt/pialert +msg_info "Installing Pi.Alert" +curl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1 mkdir -p /opt/pialert/front/reports rm -rf /var/www/html/index.html mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old @@ -69,9 +69,13 @@ dest_dir="/opt/pialert/front/php/server" for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log pialert.webservices.log; do ln -s "$src_dir/$file" "$dest_dir/$file" done +git config --global --add safe.directory /opt/pialert sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron (crontab -l 2>/dev/null; cat /opt/pialert/install/pialert.cron) | crontab - +cp -R /opt/pialert/install/pialert_update.sh /usr/bin/update +sed -i 's/~/\/opt/g' /usr/bin/update +chmod +x /usr/bin/update echo "python3 /opt/pialert/back/pialert.py 1" >/usr/bin/scan chmod +x /usr/bin/scan echo "/opt/pialert/back/pialert-cli set_permissions --lxc" >/usr/bin/permissions From 35701cb845a9ebee89967de4a1566c5d218bf1fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 22:54:31 -0400 Subject: [PATCH 5291/6505] Update pialert-install.sh test --- install/pialert-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 34b57319..c452d0b7 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -72,7 +72,9 @@ done git config --global --add safe.directory /opt/pialert sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron +set +e (crontab -l 2>/dev/null; cat /opt/pialert/install/pialert.cron) | crontab - +set -e cp -R /opt/pialert/install/pialert_update.sh /usr/bin/update sed -i 's/~/\/opt/g' /usr/bin/update chmod +x /usr/bin/update From fb57a5f0f1884ef9ef1342e63129a4bd63b5f6f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 23:24:00 -0400 Subject: [PATCH 5292/6505] Update pialert-install.sh --- install/pialert-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index c452d0b7..8c45003a 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -71,7 +71,7 @@ for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log done git config --global --add safe.directory /opt/pialert sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf -sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron +sed -i -e 's/0 2 \* \* \*\/4/0 2 * * 3/g' -e 's/~/\/opt/g' /opt/pialert/install/pialert.cron set +e (crontab -l 2>/dev/null; cat /opt/pialert/install/pialert.cron) | crontab - set -e From 3115e46e3041446569ec536c5dead91c8a35f187 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 23:45:47 -0400 Subject: [PATCH 5293/6505] Update pialert-install.sh --- install/pialert-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 8c45003a..563244ea 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -71,9 +71,10 @@ for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log done git config --global --add safe.directory /opt/pialert sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf -sed -i -e 's/0 2 \* \* \*\/4/0 2 * * 3/g' -e 's/~/\/opt/g' /opt/pialert/install/pialert.cron +sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron set +e -(crontab -l 2>/dev/null; cat /opt/pialert/install/pialert.cron) | crontab - +#(crontab -l 2>/dev/null; cat /opt/pialert/install/pialert.cron) | crontab - +crontab /opt/pialert/install/pialert.cron set -e cp -R /opt/pialert/install/pialert_update.sh /usr/bin/update sed -i 's/~/\/opt/g' /usr/bin/update From fc8ddc3a7c252180f52a27118adf8a609faf63a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Sep 2023 23:53:59 -0400 Subject: [PATCH 5294/6505] Update pialert-install.sh fix crontab --- install/pialert-install.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 563244ea..394ac8e2 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -72,10 +72,7 @@ done git config --global --add safe.directory /opt/pialert sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron -set +e -#(crontab -l 2>/dev/null; cat /opt/pialert/install/pialert.cron) | crontab - crontab /opt/pialert/install/pialert.cron -set -e cp -R /opt/pialert/install/pialert_update.sh /usr/bin/update sed -i 's/~/\/opt/g' /usr/bin/update chmod +x /usr/bin/update From 97219fc7c221db613f3717c9a12845177656d000 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Sep 2023 00:38:38 -0400 Subject: [PATCH 5295/6505] Update pialert.sh update --- ct/pialert.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ct/pialert.sh b/ct/pialert.sh index f9f98a92..1fbbf2bb 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -53,8 +53,9 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/pialert ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." -exit +msg_info "Updating $APP" +update +msg_ok "Updated $APP" } start From 16bdcb3cb16974acd0ee84b67d22d5ed5deb45ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Sep 2023 00:40:54 -0400 Subject: [PATCH 5296/6505] Update pialert.sh tweak --- ct/pialert.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/pialert.sh b/ct/pialert.sh index 1fbbf2bb..76bb430f 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -53,7 +53,6 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/pialert ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP" update msg_ok "Updated $APP" } From 6d360c6d4305c8d0bb2fd235aff53491766036a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Sep 2023 07:04:12 -0400 Subject: [PATCH 5297/6505] Update openobserve.sh fix spelling fixes https://github.com/tteck/Proxmox/issues/1807 --- ct/openobserve.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/openobserve.sh b/ct/openobserve.sh index 7cdd431e..d3300770 100644 --- a/ct/openobserve.sh +++ b/ct/openobserve.sh @@ -56,10 +56,10 @@ function update_script() { header_info if [[ ! -d /opt/openobserve/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating $APP" -systemctl stop openobsecure +systemctl stop openobserve LATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '"tag_name":' | cut -d'"' -f4) tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve -systemctl start openobsecure +systemctl start openobserve msg_ok "Updated $APP" exit } From 4ad7bbd8848e63dd6073e67c1030f23f2637abfe Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Sep 2023 08:59:59 -0400 Subject: [PATCH 5298/6505] Update pialert.sh tweak --- ct/pialert.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/pialert.sh b/ct/pialert.sh index 76bb430f..dd3a1615 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -55,6 +55,7 @@ header_info if [[ ! -d /opt/pialert ]]; then msg_error "No ${APP} Installation Found!"; exit; fi update msg_ok "Updated $APP" +exit } start From c7fef220b165c1abd6fdf8321693188fdf79aaa0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Sep 2023 14:27:51 -0400 Subject: [PATCH 5299/6505] Update pialert-install.sh - redirect updates to https://github.com/leiweibau/Pi.Alert - clean code (final) --- install/pialert-install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 394ac8e2..3c3ba4ad 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -55,7 +55,6 @@ msg_ok "Installed Python Dependencies" msg_info "Installing Pi.Alert" curl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1 -mkdir -p /opt/pialert/front/reports rm -rf /var/www/html/index.html mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old ln -s /opt/pialert/install/index.html /var/www/html/index.html @@ -69,12 +68,10 @@ dest_dir="/opt/pialert/front/php/server" for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log pialert.webservices.log; do ln -s "$src_dir/$file" "$dest_dir/$file" done -git config --global --add safe.directory /opt/pialert sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron crontab /opt/pialert/install/pialert.cron -cp -R /opt/pialert/install/pialert_update.sh /usr/bin/update -sed -i 's/~/\/opt/g' /usr/bin/update +echo "bash -c \"\$(wget -qLO - https://github.com/leiweibau/Pi.Alert/raw/main/install/pialert_update.sh)\" -s --lxc" >/usr/bin/update chmod +x /usr/bin/update echo "python3 /opt/pialert/back/pialert.py 1" >/usr/bin/scan chmod +x /usr/bin/scan From 5a526099f7aad83ded2386d9c38ab9bc6ca1a924 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Sep 2023 14:28:36 -0400 Subject: [PATCH 5300/6505] Update pialert.sh reduce storage --- ct/pialert.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pialert.sh b/ct/pialert.sh index dd3a1615..17a1195b 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -19,7 +19,7 @@ EOF header_info echo -e "Loading..." APP="PiAlert" -var_disk="6" +var_disk="3" var_cpu="1" var_ram="512" var_os="debian" From a72c411497376946fdc9b02368e87c7dcd30f17e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 18 Sep 2023 19:53:44 -0400 Subject: [PATCH 5301/6505] Update turnkey.sh add appliances --- turnkey/turnkey.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index 51197ea5..333badad 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -66,6 +66,7 @@ while read -r TAG ITEM; do done < <( cat < Date: Tue, 19 Sep 2023 16:00:04 -0400 Subject: [PATCH 5302/6505] Update zwave-js-ui.sh default Debian 12 --- ct/zwave-js-ui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index c4217d3e..465f02df 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From a520795e1b3f4ea585bc00816c1952c17a5b013e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Sep 2023 05:27:06 -0400 Subject: [PATCH 5303/6505] Update kernel-clean.sh tweak --- misc/kernel-clean.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index ace0f0a1..d34a63af 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -56,7 +56,7 @@ done < <(echo "$available_kernels") remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" \ 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the previously selected Kernels?" 10 68 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') previously selected Kernels?" 10 68 || exit msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" /usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1 From b0a7fc06ebec7eb0524313c0ed4c361c5238a487 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Sep 2023 19:00:13 -0400 Subject: [PATCH 5304/6505] Update monitor-all.sh tweak --- misc/monitor-all.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 7e6f15c7..187c82fb 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -35,6 +35,7 @@ while true; do for instance in $(pct list | awk '\''{if(NR>1) print $1}'\''; qm list | awk '\''{if(NR>1) print $1}'\''); do # Skip excluded instances if [[ " ${excluded_instances[@]} " =~ " ${instance} " ]]; then + echo "Skipping $instance because it is excluded" continue fi From 0692bad5c6c0b0adaa5b18dafa1c0b8d7dcaed0f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Sep 2023 08:46:41 -0400 Subject: [PATCH 5305/6505] Update pialert-install.sh tweaks for new release --- install/pialert-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 3c3ba4ad..789710c0 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -18,7 +18,6 @@ $STD apt-get -y install \ sudo \ mc \ curl \ - git \ apt-utils \ lighttpd \ sqlite3 \ @@ -29,6 +28,7 @@ $STD apt-get -y install \ libwww-perl \ nmap \ zip \ + aria2 \ wakeonlan msg_ok "Installed Dependencies" @@ -42,7 +42,6 @@ $STD apt-get -y install \ $STD lighttpd-enable-mod fastcgi-php service lighttpd force-reload msg_ok "Installed PHP Dependencies" -#arp-scan -l msg_info "Installing Python Dependencies" $STD apt-get -y install \ @@ -55,8 +54,10 @@ msg_ok "Installed Python Dependencies" msg_info "Installing Pi.Alert" curl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1 -rm -rf /var/www/html/index.html +rm -rf /var/lib/ieee-data /var/www/html/index.html +sed -i -e 's#^sudo cp -n /usr/share/ieee-data/.* /var/lib/ieee-data/#\# &#' -e '/^sudo mkdir -p 2_backup$/s/^/# /' -e '/^sudo cp \*.txt 2_backup$/s/^/# /' -e '/^sudo cp \*.csv 2_backup$/s/^/# /' /opt/pialert/back/update_vendors.sh mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old +ln -s /usr/share/ieee-data/ /var/lib/ ln -s /opt/pialert/install/index.html /var/www/html/index.html ln -s /opt/pialert/front /var/www/html/pialert chmod go+x /opt/pialert /opt/pialert/back/shoutrrr/x86/shoutrrr @@ -69,7 +70,7 @@ for file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log ln -s "$src_dir/$file" "$dest_dir/$file" done sed -i 's#PIALERT_PATH\s*=\s*'\''/home/pi/pialert'\''#PIALERT_PATH = '\''/opt/pialert'\''#' /opt/pialert/config/pialert.conf -sed -i 's/~/\/opt/g' /opt/pialert/install/pialert.cron +sed -i 's/$HOME/\/opt/g' /opt/pialert/install/pialert.cron crontab /opt/pialert/install/pialert.cron echo "bash -c \"\$(wget -qLO - https://github.com/leiweibau/Pi.Alert/raw/main/install/pialert_update.sh)\" -s --lxc" >/usr/bin/update chmod +x /usr/bin/update From 7f2c3d15492faa341f502efc44d8f86b07fc80a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Sep 2023 14:17:01 -0400 Subject: [PATCH 5306/6505] Update update-lxcs.sh change wording fixes https://github.com/tteck/Proxmox/issues/1824 --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index d4b442f0..c6e41f3b 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -26,7 +26,7 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update Selected LXC Containers. Proceed?" 10 58 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || exit NODE=$(hostname) while read -r TAG ITEM; do OFFSET=2 From 461a737b98c53b918bcb9768e089e0c74c643140 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Sep 2023 21:02:00 -0400 Subject: [PATCH 5307/6505] Update update-lxcs.sh fixes https://github.com/tteck/Proxmox/issues/1825 --- misc/update-lxcs.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index c6e41f3b..dcf5cbfc 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -17,7 +17,7 @@ function header_info { EOF } -set -e +set -eEuo pipefail YW=$(echo "\033[33m") BL=$(echo "\033[36m") RD=$(echo "\033[01;31m") @@ -26,8 +26,10 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || clear; exit NODE=$(hostname) +CTID_MENU=() +MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET @@ -35,7 +37,7 @@ while read -r TAG ITEM; do done < <(pct list | awk 'NR>1') excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist \ "\nSelect containers to skip from updates:\n" \ - 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || clear; exit function update_container() { container=$1 From f6a59ba4fd7f8db5fa96c7eafba68d7c21fb6555 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Sep 2023 21:03:41 -0400 Subject: [PATCH 5308/6505] Update update-lxcs.sh --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index dcf5cbfc..168ce2c0 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -26,7 +26,7 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || clear; exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || exit NODE=$(hostname) CTID_MENU=() MSG_MAX_LENGTH=0 From 7942bf57559bb7370d906d7d0894c95eebf54b22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Sep 2023 21:10:00 -0400 Subject: [PATCH 5309/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 168ce2c0..dcf5cbfc 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -26,7 +26,7 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || clear; exit NODE=$(hostname) CTID_MENU=() MSG_MAX_LENGTH=0 From c7593ed2eb5797642d5c6692da7d63e93d83c987 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Sep 2023 21:20:00 -0400 Subject: [PATCH 5310/6505] Update update-lxcs.sh tweaks --- misc/update-lxcs.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index dcf5cbfc..1e63ff1b 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -26,7 +26,7 @@ GN=$(echo "\033[1;92m") CL=$(echo "\033[m") header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || clear; exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || exit NODE=$(hostname) CTID_MENU=() MSG_MAX_LENGTH=0 @@ -35,10 +35,7 @@ while read -r TAG ITEM; do ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') -excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist \ - "\nSelect containers to skip from updates:\n" \ - 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || clear; exit - +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from updates:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit function update_container() { container=$1 header_info From 9dc43c396f96f7916e07b7c8207bfca185a22e5d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Sep 2023 05:58:20 -0400 Subject: [PATCH 5311/6505] Update docker-install.sh change Portainer to port 9443 fixes https://github.com/tteck/Proxmox/issues/1763 --- install/docker-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/docker-install.sh b/install/docker-install.sh index 37575f46..1a15edb3 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -50,7 +50,7 @@ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then docker volume create portainer_data >/dev/null $STD docker run -d \ -p 8000:8000 \ - -p 9000:9000 \ + -p 9443:9443 \ --name=portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ From e24879f192f859d932eef7f9b598d9b3728198b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Sep 2023 07:39:53 -0400 Subject: [PATCH 5312/6505] Create all-templates.sh Builds upon the functionality of the existing "turnkey.sh" script to incorporate all available templates. --- misc/all-templates.sh | 208 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 misc/all-templates.sh diff --git a/misc/all-templates.sh b/misc/all-templates.sh new file mode 100644 index 00000000..8f3ac79b --- /dev/null +++ b/misc/all-templates.sh @@ -0,0 +1,208 @@ +#!/usr/bin/env bash +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ___ ____ ______ __ __ + / _ | / / / /_ __/__ __ _ ___ / /__ _/ /____ ___ + / __ |/ / / / / / -_) ' \/ _ \/ / _ `/ __/ -_|_-< +/_/ |_/_/_/ /_/ \__/_/_/_/ .__/_/\_,_/\__/\__/___/ + /_/ +EOF +} + +set -eEuo pipefail +shopt -s expand_aliases +alias die='EXIT=$? LINE=$LINENO error_exit' +trap die ERR +function error_exit() { + trap - ERR + local DEFAULT='Unknown failure occured.' + local REASON="\e[97m${1:-$DEFAULT}\e[39m" + local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" + msg "$FLAG $REASON" 1>&2 + [ ! -z ${CTID-} ] && cleanup_ctid + exit $EXIT +} +function warn() { + local REASON="\e[97m$1\e[39m" + local FLAG="\e[93m[WARNING]\e[39m" + msg "$FLAG $REASON" +} +function info() { + local REASON="$1" + local FLAG="\e[36m[INFO]\e[39m" + msg "$FLAG $REASON" +} +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} +function cleanup_ctid() { + if pct status $CTID &>/dev/null; then + if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then + pct stop $CTID + fi + pct destroy $CTID + fi +} + +# Stop Proxmox VE Monitor-All if running +if systemctl is-active -q ping-instances.service; then + systemctl stop ping-instances.service +fi +header_info +pveam update >/dev/null 2>&1 +whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68 || exit +CTID_MENU=() +MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + CTID_MENU+=("$ITEM" "$TAG " "OFF") +done < <(pveam available) +TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$TEMPLATE" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68 + msg "Done" + exit +} + +# Setup script environment +NAME=$(echo "$TEMPLATE" | grep -oE '^[^-]+-[^-]+') +PASS="$(openssl rand -base64 8)" +CTID=$(pvesh get /cluster/nextid) +PCT_OPTIONS=" + -features keyctl=1,nesting=1 + -hostname $NAME + -tags proxmox-helper-scripts + -onboot 0 + -cores 2 + -memory 2048 + -password $PASS + -net0 name=eth0,bridge=vmbr0,hwaddr=AE:1A:60:07:B7:59,ip=dhcp + -unprivileged 1 + " +DEFAULT_PCT_OPTIONS=( + -arch $(dpkg --print-architecture) +) + +# Set the CONTENT and CONTENT_LABEL variables +function select_storage() { + local CLASS=$1 + local CONTENT + local CONTENT_LABEL + case $CLASS in + container) + CONTENT='rootdir' + CONTENT_LABEL='Container' + ;; + template) + CONTENT='vztmpl' + CONTENT_LABEL='Container template' + ;; + *) false || die "Invalid storage class." ;; + esac + + # Query all storage locations + local -a MENU + while read -r line; do + local TAG=$(echo $line | awk '{print $1}') + local TYPE=$(echo $line | awk '{printf "%-10s", $2}') + local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + local ITEM=" Type: $TYPE Free: $FREE " + local OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + MENU+=("$TAG" "$ITEM" "OFF") + done < <(pvesm status -content $CONTENT | awk 'NR>1') + + # Select storage location + if [ $((${#MENU[@]} / 3)) -eq 0 ]; then + warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." + die "Unable to detect valid storage location." + elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then + printf ${MENU[0]} + else + local STORAGE + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\n\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." + done + printf $STORAGE + fi +} + +# Get template storage +TEMPLATE_STORAGE=$(select_storage template) || exit +info "Using '$TEMPLATE_STORAGE' for template storage." + +# Get container storage +CONTAINER_STORAGE=$(select_storage container) || exit +info "Using '$CONTAINER_STORAGE' for container storage." + +# Download template +msg "Downloading LXC template (Patience)..." +pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." + +# Create variable for 'pct' options +PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) +[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) + +# Create LXC +msg "Creating LXC container..." +pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || + die "A problem occured while trying to create container." + +# Save password +echo "$NAME password: ${PASS}" >>~/$NAME.creds # file is located in the Proxmox root directory + +# Start container +msg "Starting LXC Container..." +pct start "$CTID" +sleep 5 + +# Get container IP +set +eEuo pipefail +max_attempts=5 +attempt=1 +IP="" +while [[ $attempt -le $max_attempts ]]; do + IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \K[^/]+') + if [[ -n $IP ]]; then + break + else + warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." + sleep 5 + ((attempt++)) + fi +done + +if [[ -z $IP ]]; then + warn "Maximum number of attempts reached. IP address not found." + IP="NOT FOUND" +fi + +set -eEuo pipefail +# Start Proxmox VE Monitor-All if available +if [[ -f /etc/systemd/system/ping-instances.service ]]; then + systemctl start ping-instances.service +fi + +# Success message +header_info +echo +info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." +echo +info "Proceed to the LXC console to complete the setup." +echo +info "login: root" +info "password: $PASS" +echo From 148c2cb1265bcfe2331af57916705324f2edb8fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Sep 2023 07:53:12 -0400 Subject: [PATCH 5313/6505] Update all-templates.sh tweaks --- misc/all-templates.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/all-templates.sh b/misc/all-templates.sh index 8f3ac79b..472f0f2d 100644 --- a/misc/all-templates.sh +++ b/misc/all-templates.sh @@ -56,6 +56,7 @@ if systemctl is-active -q ping-instances.service; then systemctl stop ping-instances.service fi header_info +echo "Loading..." pveam update >/dev/null 2>&1 whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68 || exit CTID_MENU=() @@ -65,7 +66,7 @@ while read -r TAG ITEM; do ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET CTID_MENU+=("$ITEM" "$TAG " "OFF") done < <(pveam available) -TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit [ -z "$TEMPLATE" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68 msg "Done" From af5a0e340910baa17f13fd900ee87153097efea2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Sep 2023 08:00:12 -0400 Subject: [PATCH 5314/6505] Update all-templates.sh remove test MAC address --- misc/all-templates.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/all-templates.sh b/misc/all-templates.sh index 472f0f2d..a63f44ac 100644 --- a/misc/all-templates.sh +++ b/misc/all-templates.sh @@ -85,7 +85,7 @@ PCT_OPTIONS=" -cores 2 -memory 2048 -password $PASS - -net0 name=eth0,bridge=vmbr0,hwaddr=AE:1A:60:07:B7:59,ip=dhcp + -net0 name=eth0,bridge=vmbr0,ip=dhcp -unprivileged 1 " DEFAULT_PCT_OPTIONS=( From 7691aded5861f74ebc0c555abb99d23ebc02472d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Sep 2023 08:38:39 -0400 Subject: [PATCH 5315/6505] Update all-templates.sh tweak --- misc/all-templates.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/all-templates.sh b/misc/all-templates.sh index a63f44ac..34c291a5 100644 --- a/misc/all-templates.sh +++ b/misc/all-templates.sh @@ -140,7 +140,7 @@ function select_storage() { printf $STORAGE fi } - +header_info # Get template storage TEMPLATE_STORAGE=$(select_storage template) || exit info "Using '$TEMPLATE_STORAGE' for template storage." From e26aeb25a8bafee96d23182f9eb2614c54ffd4a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Sep 2023 15:03:35 -0400 Subject: [PATCH 5316/6505] Update turnkey.sh add Ansible --- turnkey/turnkey.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index 333badad..292930f6 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -65,6 +65,7 @@ while read -r TAG ITEM; do CTID_MENU+=("$TAG" "$ITEM " "OFF") done < <( cat < Date: Sun, 24 Sep 2023 20:23:32 -0400 Subject: [PATCH 5317/6505] Update homarr-install.sh set NEXTAUTH_URL=http://localhost:3000 --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 8ef64f09..5d083f84 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -41,7 +41,7 @@ msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr cd /opt/homarr $STD yarn install -$STD yarn build +$STD NEXTAUTH_URL=http://localhost:3000 yarn build msg_ok "Installed Homarr" msg_info "Creating Service" From 62784e9200cbd0a02c0fb9b485e4f50caa165f74 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Sep 2023 20:32:41 -0400 Subject: [PATCH 5318/6505] Update homarr-install.sh --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 5d083f84..ebd6d7a0 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -41,7 +41,7 @@ msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr cd /opt/homarr $STD yarn install -$STD NEXTAUTH_URL=http://localhost:3000 yarn build +NEXTAUTH_URL=http://localhost:3000 yarn build &>/dev/null msg_ok "Installed Homarr" msg_info "Creating Service" From f39274a5c7fd22d3fb45ceba000d9628c8c281d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Sep 2023 21:35:32 -0400 Subject: [PATCH 5319/6505] Update homarr-install.sh --- install/homarr-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index ebd6d7a0..1e8788fd 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -35,13 +35,14 @@ msg_ok "Installed Node.js" msg_info "Installing Yarn" $STD npm install -g yarn +$STD npm install next react react-dom msg_ok "Installed Yarn" msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr cd /opt/homarr $STD yarn install -NEXTAUTH_URL=http://localhost:3000 yarn build &>/dev/null +$STD yarn build msg_ok "Installed Homarr" msg_info "Creating Service" From a6318456be2f320154eb956f1e6c2ced6f4e829a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Sep 2023 05:17:51 -0400 Subject: [PATCH 5320/6505] Update homarr-install.sh Homarr is currently undergoing extensive development, and we do not recommend installing it from source at this point. As a result, Homarr has been taken down from this site. We kindly suggest using the Docker installation method as an alternative. --- install/homarr-install.sh | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 1e8788fd..d4f91978 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -31,16 +31,44 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" $STD apt-get update $STD apt-get install -y nodejs +$STD npm install next +$STD npm instal react +$STD npm instal react-dom msg_ok "Installed Node.js" msg_info "Installing Yarn" $STD npm install -g yarn -$STD npm install next react react-dom +$STD yarn global add prisma msg_ok "Installed Yarn" msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr cd /opt/homarr +cat </opt/homarr/.env +# Since the ".env" file is gitignored, you can use the ".env.example" file to +# build a new ".env" file when you clone the repo. Keep this file up-to-date +# when you add new variables to `.env`. + +# This file will be committed to version control, so make sure not to have any +# secrets in it. If you are cloning this repo, create a copy of this file named +# ".env" and populate it with your secrets. + +# When adding additional environment variables, the schema in "/src/env.js" +# should be updated accordingly. + +# Prisma +# https://www.prisma.io/docs/reference/database-reference/connection-urls#env +DATABASE_URL="file:../database/db.sqlite" + +# Next Auth +# You can generate a new secret on the command line with: +# openssl rand -base64 32 +# https://next-auth.js.org/configuration/options#secret +# NEXTAUTH_SECRET="" +NEXTAUTH_URL="http://localhost:3000" + +NEXTAUTH_SECRET="1234" +EOF $STD yarn install $STD yarn build msg_ok "Installed Homarr" @@ -54,6 +82,7 @@ After=network.target [Service] Type=exec WorkingDirectory=/opt/homarr +EnvironmentFile=-/opt/homarr/.env ExecStart=/usr/bin/yarn start [Install] From 4ea029864480ad8337ce0bbfc10028714663147f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Sep 2023 16:57:00 -0400 Subject: [PATCH 5321/6505] Update monitor-all.sh implement a 5-minute delay before starting fixes https://github.com/tteck/Proxmox/issues/1840 --- misc/monitor-all.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 187c82fb..02d0b696 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -102,6 +102,7 @@ Type=simple # To specify which CT/VM should be excluded, add the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified. # For example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 # Virtual machines without the QEMU guest agent installed must be excluded. +ExecStartPre=/usr/bin/sleep 300 # Sleep for 300 seconds (5 minutes) ExecStart=/usr/local/bin/ping-instances.sh Restart=always StandardOutput=file:/var/log/ping-instances.log From d7ed355918118c1dd2648277afd45118ee706668 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Sep 2023 11:43:20 -0400 Subject: [PATCH 5322/6505] Update openwrt.sh fixes https://github.com/tteck/Proxmox/issues/1842 --- vm/openwrt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index dc1c1828..9c511e37 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -36,7 +36,7 @@ BFR="\\r\\033[K" HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" -set -Eeuo pipefail +set -Eeo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT function error_handler() { From 4689cbc5e559da8e0a462dad70902fdc0aea2ef0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Sep 2023 12:14:30 -0400 Subject: [PATCH 5323/6505] Update CONTRIBUTING.md The repository will only accept Alpine applications that make use of the Alpine Package Keeper. --- .github/CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 142f6aa9..3b61df05 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -5,3 +5,5 @@ Everybody is invited and welcome to contribute to Proxmox VE Helper Scripts. - Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. By adhering to the established patterns and conventions throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). - It is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. + +- The repository will only accept Alpine applications that make use of the Alpine Package Keeper. From e0e81a022d6203bdcca13d03fbf6c4faf9cc6d02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Sep 2023 17:55:13 -0400 Subject: [PATCH 5324/6505] Update build.func Please run these scripts as root (not with sudo). --- misc/build.func | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/misc/build.func b/misc/build.func index c1c9394f..90d24563 100644 --- a/misc/build.func +++ b/misc/build.func @@ -52,6 +52,15 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +# Run as root only +if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit +fi + # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then From 682a08e970f847b96a24bc81f80c06e7d40308d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Sep 2023 19:16:25 -0400 Subject: [PATCH 5325/6505] Update build.func tweak --- misc/build.func | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/build.func b/misc/build.func index 90d24563..79b5b5ad 100644 --- a/misc/build.func +++ b/misc/build.func @@ -53,6 +53,7 @@ msg_error() { } # Run as root only +check_root() { if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then clear msg_error "Please run this script as root." @@ -60,6 +61,7 @@ if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then sleep 2 exit fi +} # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { @@ -428,6 +430,7 @@ advanced_settings() { } install_script() { + check_root ssh_check arch_check pve_check From 885f5a9a2b020083a224fc06eb3841f25b100d9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Sep 2023 19:18:57 -0400 Subject: [PATCH 5326/6505] Update build.func --- misc/build.func | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/misc/build.func b/misc/build.func index 79b5b5ad..c1e36895 100644 --- a/misc/build.func +++ b/misc/build.func @@ -54,13 +54,13 @@ msg_error() { # Run as root only check_root() { -if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit -fi + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi } # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. From 24551de29206f1a1b71a1df413125126353d0757 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Sep 2023 06:40:15 -0400 Subject: [PATCH 5327/6505] Update haos-vm.sh - Add a function to verify if the user is the root user (without using sudo). - Set default disk cache to writethrough - Set default CPU type to host --- vm/haos-vm.sh | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 8294ec68..05dd891e 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -84,9 +84,19 @@ function msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +function check_root() { + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + function pve_check() { if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" + msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 7.2 or higher" echo -e "Exiting..." sleep 2 @@ -96,7 +106,7 @@ function pve_check() { function arch_check() { if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" + msg_error "This script will not work with PiMox! \n" echo -e "Exiting..." sleep 2 exit @@ -127,9 +137,9 @@ function default_settings() { VMID="$NEXTID" FORMAT=",efitype=4m" MACHINE="" - DISK_CACHE="" + DISK_CACHE="cache=writethrough," HN="haos$stable" - CPU_TYPE="" + CPU_TYPE=" -cpu host" CORE_COUNT="2" RAM_SIZE="4096" BRG="vmbr0" @@ -140,9 +150,9 @@ function default_settings() { echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" - echo -e "${DGN}Using Disk Cache: ${BGN}Default${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}Writethrough${CL}" echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" - echo -e "${DGN}Using CPU Model: ${BGN}Default${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" @@ -340,6 +350,7 @@ function start_script() { fi } +check_root arch_check pve_check ssh_check From 9d7372b679bfb77406478d1eac80e35cc8821a11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Sep 2023 06:52:05 -0400 Subject: [PATCH 5328/6505] Update haos-vm.sh - Set "Advanced" defaults --- vm/haos-vm.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 05dd891e..27dcb8ce 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -150,7 +150,7 @@ function default_settings() { echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" - echo -e "${DGN}Using Disk Cache: ${BGN}Writethrough${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" @@ -209,14 +209,14 @@ function advanced_settings() { fi if DISK_CACHE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ - "0" "Default" ON \ - "1" "Write Through" OFF \ + "0" "None" OFF \ + "1" "Write Through (Default)" ON \ 3>&1 1>&2 2>&3); then if [ $DISK_CACHE1 = "1" ]; then echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" DISK_CACHE="cache=writethrough," else - echo -e "${DGN}Using Disk Cache: ${BGN}Default${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" DISK_CACHE="" fi else @@ -236,14 +236,14 @@ function advanced_settings() { fi if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ - "0" "KVM64 (Default)" ON \ - "1" "Host" OFF \ + "0" "KVM64" OFF \ + "1" "Host (Default)" ON \ 3>&1 1>&2 2>&3); then if [ $CPU_TYPE1 = "1" ]; then echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" CPU_TYPE=" -cpu host" else - echo -e "${DGN}Using CPU Model: ${BGN}Default${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" CPU_TYPE="" fi else From 1ca1be76cfa15bbcd66622f7d0c2da2be88eaf1e Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:14:58 +0200 Subject: [PATCH 5329/6505] Initial Release for Alpine-Nextcloud Script (#1850) - initial Release - for testing --- ct/alpine-nextcloud.sh | 110 +++++++++++++ install/alpine-nextcloud-install.sh | 242 ++++++++++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 ct/alpine-nextcloud.sh create mode 100644 install/alpine-nextcloud-install.sh diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh new file mode 100644 index 00000000..aac6be33 --- /dev/null +++ b/ct/alpine-nextcloud.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + _ __ __ ________ __ + / | / /__ _ __/ /_/ ____/ /___ __ ______/ / + / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / + / /| / __/> /dev/null 2>&1; then + apk add -q newt + fi + RELEASE=$(curl -s https://api.github.com/repos/nextcloud/server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + while true; do + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ + "1" "Update Nextcloud to $RELEASE" ON \ + "2" "Nextcloud Credentials" OFF \ + "3" "Renew selfsigned Certificate" OFF \ + 3>&1 1>&2 2>&3) + exit_status=$? + if [ $exit_status == 1 ]; then + clear + exit-script + fi + header_info + case $CHOICE in + 1) + INSTALLED=$(grep -Rnw '/usr/share/webapps/nextcloud/config/config.php' -e '\'installed\'' => false,') + if [ -z "$INSTALLED" ] + then + apk update && apk upgrade + su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ upgrade' + su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ db:add-missing-indices' + else + msg_error "${APP} not initialized, go to the WebUI and run the Setup-Wizard first.\n" + fi + exit + ;; + 2) + cat nextcloud.creds + exit + ;; + 3) + openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj "/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local" > /dev/null 2>&1 + rc-service nginx restart + exit + ;; + esac + done +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "To get the randomized credentials for Setup-Wizard, +run the script again inside the LXC Container. \n + +${APP} should be reachable by going to the following URL. + ${BL}https://${IP}${CL} \n" diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh new file mode 100644 index 00000000..127f5bf1 --- /dev/null +++ b/install/alpine-nextcloud-install.sh @@ -0,0 +1,242 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" + +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apk add newt +$STD apk add curl +$STD apk add openssl +$STD apk add openssh +$STD apk add nano +$STD apk add mc +$STD apk add argon2 +msg_ok "Installed Dependencies" + +msg_info "Installing Alpine-Nextcloud" +$STD apk add nextcloud-mysql mariadb mariadb-client +$STD mysql_install_db --user=mysql --datadir=/var/lib/mysql +$STD service mariadb start +$STD rc-update add mariadb +msg_ok "Installed Alpine-Nextcloud" + +msg_info "Setting up MySQL database" +DB_NAME=nextcloud +DB_USER=nextcloud +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +ROOT_PASS="$(openssl rand -base64 18 | cut -c1-13)" +$STD mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ROOT_PASS' WITH GRANT OPTION;FLUSH PRIVILEGES;" +$STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='';" +$STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" +$STD mysql -uroot -p$ROOT_PASS -e "DROP DATABASE test;" +$STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';" +$STD mysql -uroot -p$ROOT_PASS -e "CREATE DATABASE $DB_NAME;" +$STD mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" +$STD mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS';" +$STD mysql -uroot -p$ROOT_PASS -e "FLUSH PRIVILEGES;" +echo "" >>~/nextcloud.creds +echo -e "MySQL Root Password: \e[32m$ROOT_PASS\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Database User: \e[32m$DB_USER\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Database Password: \e[32m$DB_PASS\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Database Name: \e[32m$DB_NAME\e[0m" >>~/nextcloud.creds +$STD apk del mariadb-client +msg_ok "Set up MySQL database" + +msg_info "Installing Web-Server" +$STD apk add nextcloud-initscript +$STD apk add nginx +$STD apk add php82-fpm +$STD apk add php82-sysvsem +$STD apk add php82-pecl-imagick +$STD apk add php82-exif +msg_ok "Installed Web-Server" + +msg_info "Setting up Web-Server" +$STD openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj "/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local" +$STD rm /etc/nginx/http.d/default.conf +cat <<'EOF' >/etc/nginx/http.d/nextcloud.conf +server { + listen [::]:80; + listen 80; + return 301 https://$host$request_uri; + server_name localhost; +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name localhost; + + root /usr/share/webapps/nextcloud; + index index.php index.html index.htm; + disable_symlinks off; + + ssl_certificate /etc/ssl/certs/nextcloud-selfsigned.crt; + ssl_certificate_key /etc/ssl/private/nextcloud-selfsigned.key; + ssl_session_timeout 5m; + + #Enable Perfect Forward Secrecy and ciphers without known vulnerabilities + #Beware! It breaks compatibility with older OS and browsers (e.g. Windows XP, Android 2.x, etc.) + ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA; + ssl_prefer_server_ciphers on; + + + location / { + try_files $uri $uri/ /index.html; + } + + # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + if (!-f $document_root$fastcgi_script_name) { + return 404; + } + #fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/run/php-fpm/socket; + fastcgi_pass unix:/run/nextcloud/fastcgi.sock; # From the nextcloud-initscript package + fastcgi_index index.php; + include fastcgi.conf; + } + + # Help pass nextcloud's configuration checks after install: + # Per https://docs.nextcloud.com/server/22/admin_manual/issues/general_troubleshooting.html#service-discovery + location ^~ /.well-known/carddav { return 301 /remote.php/dav/; } + location ^~ /.well-known/caldav { return 301 /remote.php/dav/; } + location ^~ /.well-known/webfinger { return 301 /index.php/.well-known/webfinger; } + location ^~ /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo; } +} +EOF +sed -i -e 's|client_max_body_size 1m;|client_max_body_size 5120m;|' /etc/nginx/nginx.conf +sed -i -e 's|php_admin_value\[memory_limit\] = 512M|php_admin_value\[memory_limit\] = 5120M|' /etc/php82/php-fpm.d/nextcloud.conf +sed -i -e 's|php_admin_value\[post_max_size\] = 513M|php_admin_value\[post_max_size\] = 5121M|' /etc/php82/php-fpm.d/nextcloud.conf +sed -i -e 's|php_admin_value\[upload_max_filesize\] = 513M|php_admin_value\[upload_max_filesize\] = 5121M|' /etc/php82/php-fpm.d/nextcloud.conf +sed -i -e 's|upload_max_filesize = 513M|upload_max_filesize = 5121M|' /etc/php82/php.ini +sed -i -e 's|memory_limit = 128M|memory_limit = 512M|' /etc/php82/php.ini +msg_ok "Set up Web-Server" + +msg_info "Adding additional Nextcloud Packages" +$STD apk add nextcloud-activity +$STD apk add nextcloud-admin_audit +$STD apk add nextcloud-comments +$STD apk add nextcloud-dashboard +$STD apk add nextcloud-default-apps +$STD apk add nextcloud-doc +$STD apk add nextcloud-encryption +$STD apk add nextcloud-federation +$STD apk add nextcloud-files_external +$STD apk add nextcloud-files_pdfviewer +$STD apk add nextcloud-files_rightclick +$STD apk add nextcloud-files_sharing +$STD apk add nextcloud-files_trashbin +$STD apk add nextcloud-files_versions +$STD apk add nextcloud-logreader +$STD apk add nextcloud-notifications +$STD apk add nextcloud-password_policy +$STD apk add nextcloud-photos +$STD apk add nextcloud-privacy +$STD apk add nextcloud-recommendations +$STD apk add nextcloud-serverinfo +$STD apk add nextcloud-sharebymail +$STD apk add nextcloud-suspicious_login +$STD apk add nextcloud-support +$STD apk add nextcloud-systemtags +$STD apk add nextcloud-text +$STD apk add nextcloud-user_status +$STD apk add nextcloud-weather_status +msg_ok "Added additional Nextcloud Packages" + +msg_info "Setting up PHP-opcache + Redis" +$STD apk add php82-opcache +$STD apk add php82-redis +$STD apk add php82-apcu +$STD apk add redis +sed -i -e 's|;opcache.enable=1|opcache.enable=1|' /etc/php82/php.ini +sed -i -e 's|;opcache.enable_cli=1|opcache.enable_cli=1|' /etc/php82/php.ini +sed -i -e 's|;opcache.interned_strings_buffer=8|opcache.interned_strings_buffer=16|' /etc/php82/php.ini +sed -i -e 's|;opcache.max_accelerated_files=10000|opcache.max_accelerated_files=10000|' /etc/php82/php.ini +sed -i -e 's|;opcache.memory_consumption=128|opcache.memory_consumption=256|' /etc/php82/php.ini +sed -i -e 's|;opcache.save_comments=1|opcache.save_comments=1|' /etc/php82/php.ini +sed -i -e 's|;opcache.revalidate_freq=1|opcache.revalidate_freq=1|' /etc/php82/php.ini +$STD rc-update add redis +$STD rc-service redis start +msg_ok "Set up PHP-opcache + Redis" + +msg_info "Setting up Nextcloud-Cronjob" +mkdir -p /etc/periodic/5min +cat <<'EOF' >/etc/periodic/5min/nextcloud_cron +#!/bin/sh + +# Run only when nextcloud service is started. +if rc-service nextcloud -q status >/dev/null 2>&1; then + su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' +fi +EOF +sed -i '/monthly/a */5 * * * * run-parts /etc/periodic/5min' /etc/crontabs/root +msg_ok "Set up Nextcloud-Cronjob" + +msg_info "Setting up Nextcloud-Config" +cat <<'EOF' >/usr/share/webapps/nextcloud/config/config.php + '/var/lib/nextcloud/data', + 'logfile' => '/var/log/nextcloud/nextcloud.log', + 'logdateformat' => 'F d, Y H:i:s', + 'log_rotate_size' => 104857600, + 'apps_paths' => array ( + // Read-only location for apps shipped with Nextcloud and installed by apk. + 0 => array ( + 'path' => '/usr/share/webapps/nextcloud/apps', + 'url' => '/apps', + 'writable' => false, + ), + // Writable location for apps installed from AppStore. + 1 => array ( + 'path' => '/var/lib/nextcloud/apps', + 'url' => '/apps-appstore', + 'writable' => true, + ), + ), + 'updatechecker' => false, + 'check_for_working_htaccess' => false, + + // Uncomment to enable Zend OPcache. + 'memcache.local' => '\\OC\\Memcache\\Redis', + + // Uncomment this and add user nextcloud to the redis group to enable Redis + // cache for file locking. This is highly recommended, see + // https://github.com/nextcloud/server/issues/9305. + 'memcache.locking' => '\\OC\\Memcache\\Redis', + 'redis' => array( + 'host' => 'localhost', + 'port' => 6379, + 'dbindex' => 0, + 'timeout' => 1.5, + ), + + 'installed' => false, +); +EOF +msg_ok "Set up Nextcloud-Config" + +msg_info "Starting Alpine-Nextcloud" +$STD rc-service php-fpm82 start +$STD chown -R nextcloud:www-data /var/log/nextcloud/ +$STD rc-service php-fpm82 restart +$STD rc-service nginx start +$STD rc-service nextcloud start +$STD rc-update add nginx default +$STD rc-update add nextcloud default +msg_ok "Started Alpine-Nextcloud" + +motd_ssh +customize From c1627e1ce77f47f78883aca35d15d718fc060201 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Thu, 28 Sep 2023 19:11:57 +0200 Subject: [PATCH 5330/6505] Fixed Update Part (#1851) there was a missing ' --- ct/alpine-nextcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index aac6be33..8931f824 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -74,7 +74,7 @@ function update_script() { header_info case $CHOICE in 1) - INSTALLED=$(grep -Rnw '/usr/share/webapps/nextcloud/config/config.php' -e '\'installed\'' => false,') + INSTALLED=$(grep -Rnw '/usr/share/webapps/nextcloud/config/config.php' -e ''\'installed\'' => false,') if [ -z "$INSTALLED" ] then apk update && apk upgrade From a9fea5e552c40a3fae3ae619204284421e7a0816 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Thu, 28 Sep 2023 19:29:18 +0200 Subject: [PATCH 5331/6505] Update alpine-nextcloud.sh (#1852) as suggested by tteckster --- ct/alpine-nextcloud.sh | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 8931f824..b0faf344 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -74,15 +74,9 @@ function update_script() { header_info case $CHOICE in 1) - INSTALLED=$(grep -Rnw '/usr/share/webapps/nextcloud/config/config.php' -e ''\'installed\'' => false,') - if [ -z "$INSTALLED" ] - then - apk update && apk upgrade - su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ upgrade' - su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ db:add-missing-indices' - else - msg_error "${APP} not initialized, go to the WebUI and run the Setup-Wizard first.\n" - fi + apk update && apk upgrade + su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ upgrade' + su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ db:add-missing-indices' exit ;; 2) From 497b6bd9a89ef988aab9faf1b6fccc8c324bfd27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Sep 2023 13:34:24 -0400 Subject: [PATCH 5332/6505] Update alpine-nextcloud.sh tweak --- ct/alpine-nextcloud.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index b0faf344..5356a022 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -8,13 +8,12 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _ __ __ ________ __ - / | / /__ _ __/ /_/ ____/ /___ __ ______/ / - / |/ / _ \| |/_/ __/ / / / __ \/ / / / __ / - / /| / __/> Date: Thu, 28 Sep 2023 13:57:47 -0400 Subject: [PATCH 5333/6505] Update alpine-nextcloud.sh tweaks --- ct/alpine-nextcloud.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 5356a022..77ce63d0 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -61,9 +61,9 @@ function update_script() { RELEASE=$(curl -s https://api.github.com/repos/nextcloud/server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') while true; do CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ - "1" "Update Nextcloud to $RELEASE" ON \ - "2" "Nextcloud Credentials" OFF \ - "3" "Renew selfsigned Certificate" OFF \ + "1" "Update Nextcloud to $RELEASE" OFF \ + "2" "Nextcloud Database Credentials" ON \ + "3" "Renew Self-signed Certificate" OFF \ 3>&1 1>&2 2>&3) exit_status=$? if [ $exit_status == 1 ]; then @@ -96,8 +96,7 @@ build_container description msg_ok "Completed Successfully!\n" -echo -e "To get the randomized credentials for Setup-Wizard, -run the script again inside the LXC Container. \n +echo -e "To retrieve the database credentials required for the Setup-Wizard, execute the same script within the LXC Console.\n ${APP} should be reachable by going to the following URL. ${BL}https://${IP}${CL} \n" From feb04ca52b30a8667dba8e60c4c7a5c7231d3d2b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Sep 2023 13:59:33 -0400 Subject: [PATCH 5334/6505] Update alpine-nextcloud-install.sh tweak --- install/alpine-nextcloud-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 127f5bf1..2f33c37d 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -124,7 +124,7 @@ sed -i -e 's|upload_max_filesize = 513M|upload_max_filesize = 5121M|' /etc/php82 sed -i -e 's|memory_limit = 128M|memory_limit = 512M|' /etc/php82/php.ini msg_ok "Set up Web-Server" -msg_info "Adding additional Nextcloud Packages" +msg_info "Adding Additional Nextcloud Packages" $STD apk add nextcloud-activity $STD apk add nextcloud-admin_audit $STD apk add nextcloud-comments @@ -153,7 +153,7 @@ $STD apk add nextcloud-systemtags $STD apk add nextcloud-text $STD apk add nextcloud-user_status $STD apk add nextcloud-weather_status -msg_ok "Added additional Nextcloud Packages" +msg_ok "Added Additional Nextcloud Packages" msg_info "Setting up PHP-opcache + Redis" $STD apk add php82-opcache From 2be6c1cf55f2c2f82ae64e0df5461a0ad48ce078 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Sep 2023 14:24:16 -0400 Subject: [PATCH 5335/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index c1e36895..8b752d6d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -462,7 +462,7 @@ start() { fi if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then + if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "Support functions for ${APP} LXC. Proceed?" 10 58); then clear echo -e "⚠ User exited script \n" exit From c9a9e45be23e6f1b38f8878ee0651df683b98c12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 28 Sep 2023 15:06:49 -0400 Subject: [PATCH 5336/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15de103c..7352f879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-28 + +### Changed + +- **Alpine Nextcloud Hub LXC** + - NEW Script (Thanks to @nicedevil007) + ## 2023-09-14 ### Changed From 0bd5c03afe13c0280bb29a93c47e4a6d714ffce1 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Fri, 29 Sep 2023 08:57:16 +0200 Subject: [PATCH 5337/6505] Update for Alpine-Nextcloud (#1854) code refactoring --- ct/alpine-nextcloud.sh | 1 + install/alpine-nextcloud-install.sh | 64 +++++++++++++++++------------ 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 77ce63d0..1a6e9cf9 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -97,6 +97,7 @@ description msg_ok "Completed Successfully!\n" echo -e "To retrieve the database credentials required for the Setup-Wizard, execute the same script within the LXC Console.\n +For advanced configuration use this file: /usr/share/webapps/nextcloud/config/config.php \n ${APP} should be reachable by going to the following URL. ${BL}https://${IP}${CL} \n" diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 2f33c37d..d42cb406 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -23,18 +23,30 @@ $STD apk add mc $STD apk add argon2 msg_ok "Installed Dependencies" -msg_info "Installing Alpine-Nextcloud" -$STD apk add nextcloud-mysql mariadb mariadb-client -$STD mysql_install_db --user=mysql --datadir=/var/lib/mysql -$STD service mariadb start -$STD rc-update add mariadb -msg_ok "Installed Alpine-Nextcloud" - -msg_info "Setting up MySQL database" +msg_info "Creating Credentials" DB_NAME=nextcloud DB_USER=nextcloud DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" ROOT_PASS="$(openssl rand -base64 18 | cut -c1-13)" +ADMIN_USER=ncAdmin +ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)" +echo "" >>~/nextcloud.creds +echo -e "Nextcloud Database Username: \e[32m$DB_USER\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Database Password: \e[32m$DB_PASS\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Database Name: \e[32m$DB_NAME\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Admin Password: \e[32m$ADMIN_PASS\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Admin Username: \e[32m$ADMIN_USER\e[0m" >>~/nextcloud.creds +echo -e "MySQL Root Password: \e[32m$ROOT_PASS\e[0m" >>~/nextcloud.creds +msg_ok "Created Credentials" + +msg_info "Installing MySQL Database" +$STD apk add nextcloud-mysql mariadb mariadb-client +$STD mysql_install_db --user=mysql --datadir=/var/lib/mysql +$STD service mariadb start +$STD rc-update add mariadb +msg_ok "Installed MySQL Database" + +msg_info "Setting up MySQL Database" $STD mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ROOT_PASS' WITH GRANT OPTION;FLUSH PRIVILEGES;" $STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='';" $STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" @@ -44,13 +56,8 @@ $STD mysql -uroot -p$ROOT_PASS -e "CREATE DATABASE $DB_NAME;" $STD mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" $STD mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS';" $STD mysql -uroot -p$ROOT_PASS -e "FLUSH PRIVILEGES;" -echo "" >>~/nextcloud.creds -echo -e "MySQL Root Password: \e[32m$ROOT_PASS\e[0m" >>~/nextcloud.creds -echo -e "Nextcloud Database User: \e[32m$DB_USER\e[0m" >>~/nextcloud.creds -echo -e "Nextcloud Database Password: \e[32m$DB_PASS\e[0m" >>~/nextcloud.creds -echo -e "Nextcloud Database Name: \e[32m$DB_NAME\e[0m" >>~/nextcloud.creds $STD apk del mariadb-client -msg_ok "Set up MySQL database" +msg_ok "Set up MySQL Database" msg_info "Installing Web-Server" $STD apk add nextcloud-initscript @@ -129,33 +136,23 @@ $STD apk add nextcloud-activity $STD apk add nextcloud-admin_audit $STD apk add nextcloud-comments $STD apk add nextcloud-dashboard -$STD apk add nextcloud-default-apps $STD apk add nextcloud-doc $STD apk add nextcloud-encryption $STD apk add nextcloud-federation $STD apk add nextcloud-files_external -$STD apk add nextcloud-files_pdfviewer -$STD apk add nextcloud-files_rightclick $STD apk add nextcloud-files_sharing $STD apk add nextcloud-files_trashbin $STD apk add nextcloud-files_versions -$STD apk add nextcloud-logreader $STD apk add nextcloud-notifications -$STD apk add nextcloud-password_policy -$STD apk add nextcloud-photos -$STD apk add nextcloud-privacy -$STD apk add nextcloud-recommendations -$STD apk add nextcloud-serverinfo $STD apk add nextcloud-sharebymail $STD apk add nextcloud-suspicious_login $STD apk add nextcloud-support $STD apk add nextcloud-systemtags -$STD apk add nextcloud-text $STD apk add nextcloud-user_status $STD apk add nextcloud-weather_status msg_ok "Added Additional Nextcloud Packages" -msg_info "Setting up PHP-opcache + Redis" +msg_info "Setting up Cache" $STD apk add php82-opcache $STD apk add php82-redis $STD apk add php82-apcu @@ -169,7 +166,7 @@ sed -i -e 's|;opcache.save_comments=1|opcache.save_comments=1|' /etc/php82/php.i sed -i -e 's|;opcache.revalidate_freq=1|opcache.revalidate_freq=1|' /etc/php82/php.ini $STD rc-update add redis $STD rc-service redis start -msg_ok "Set up PHP-opcache + Redis" +msg_ok "Set up Cache" msg_info "Setting up Nextcloud-Cronjob" mkdir -p /etc/periodic/5min @@ -182,6 +179,7 @@ if rc-service nextcloud -q status >/dev/null 2>&1; then fi EOF sed -i '/monthly/a */5 * * * * run-parts /etc/periodic/5min' /etc/crontabs/root +$STD chmod +x /etc/periodic/5min/nextcloud_cron msg_ok "Set up Nextcloud-Cronjob" msg_info "Setting up Nextcloud-Config" @@ -222,7 +220,6 @@ $CONFIG = array ( 'dbindex' => 0, 'timeout' => 1.5, ), - 'installed' => false, ); EOF @@ -238,5 +235,18 @@ $STD rc-update add nginx default $STD rc-update add nextcloud default msg_ok "Started Alpine-Nextcloud" +msg_info "Start Setup-Wizard" +$STD cd /usr/share/webapps/nextcloud +$STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ +--database='mysql' --database-name $DB_NAME \ +--database-user '$DB_USER' --database-pass '$DB_PASS' \ +--admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \ +--data-dir '/var/lib/nextcloud/data'" +$STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' +$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable dashboard' +IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) +sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php +msg_ok "Run Setup-Wizard" + motd_ssh customize From 31c34d368ac3bb96c89f4ad822ce31c91ee2295e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 03:32:16 -0400 Subject: [PATCH 5338/6505] Update alpine-nextcloud-install.sh testing --- install/alpine-nextcloud-install.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index d42cb406..a730a2b0 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -31,12 +31,12 @@ ROOT_PASS="$(openssl rand -base64 18 | cut -c1-13)" ADMIN_USER=ncAdmin ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)" echo "" >>~/nextcloud.creds +echo -e "MySQL Admin Password: \e[32m$ROOT_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Username: \e[32m$DB_USER\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Password: \e[32m$DB_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Name: \e[32m$DB_NAME\e[0m" >>~/nextcloud.creds -echo -e "Nextcloud Admin Password: \e[32m$ADMIN_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Admin Username: \e[32m$ADMIN_USER\e[0m" >>~/nextcloud.creds -echo -e "MySQL Root Password: \e[32m$ROOT_PASS\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Admin Password: \e[32m$ADMIN_PASS\e[0m" >>~/nextcloud.creds msg_ok "Created Credentials" msg_info "Installing MySQL Database" @@ -70,7 +70,7 @@ msg_ok "Installed Web-Server" msg_info "Setting up Web-Server" $STD openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj "/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local" -$STD rm /etc/nginx/http.d/default.conf +rm /etc/nginx/http.d/default.conf cat <<'EOF' >/etc/nginx/http.d/nextcloud.conf server { listen [::]:80; @@ -152,7 +152,7 @@ $STD apk add nextcloud-user_status $STD apk add nextcloud-weather_status msg_ok "Added Additional Nextcloud Packages" -msg_info "Setting up Cache" +msg_info "Setting up PHP/Redis" $STD apk add php82-opcache $STD apk add php82-redis $STD apk add php82-apcu @@ -166,7 +166,7 @@ sed -i -e 's|;opcache.save_comments=1|opcache.save_comments=1|' /etc/php82/php.i sed -i -e 's|;opcache.revalidate_freq=1|opcache.revalidate_freq=1|' /etc/php82/php.ini $STD rc-update add redis $STD rc-service redis start -msg_ok "Set up Cache" +msg_ok "Set up PHP/Redis" msg_info "Setting up Nextcloud-Cronjob" mkdir -p /etc/periodic/5min @@ -178,8 +178,8 @@ if rc-service nextcloud -q status >/dev/null 2>&1; then su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' fi EOF -sed -i '/monthly/a */5 * * * * run-parts /etc/periodic/5min' /etc/crontabs/root -$STD chmod +x /etc/periodic/5min/nextcloud_cron +#sed -i '/monthly/a */5 * * * * run-parts /etc/periodic/5min' /etc/crontabs/root +#chmod +x /etc/periodic/5min/nextcloud_cron msg_ok "Set up Nextcloud-Cronjob" msg_info "Setting up Nextcloud-Config" @@ -227,7 +227,7 @@ msg_ok "Set up Nextcloud-Config" msg_info "Starting Alpine-Nextcloud" $STD rc-service php-fpm82 start -$STD chown -R nextcloud:www-data /var/log/nextcloud/ +chown -R nextcloud:www-data /var/log/nextcloud/ $STD rc-service php-fpm82 restart $STD rc-service nginx start $STD rc-service nextcloud start @@ -236,17 +236,17 @@ $STD rc-update add nextcloud default msg_ok "Started Alpine-Nextcloud" msg_info "Start Setup-Wizard" -$STD cd /usr/share/webapps/nextcloud +cd /usr/share/webapps/nextcloud $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ --database='mysql' --database-name $DB_NAME \ --database-user '$DB_USER' --database-pass '$DB_PASS' \ --admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \ --data-dir '/var/lib/nextcloud/data'" $STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' -$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable dashboard' +#$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable dashboard' IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php -msg_ok "Run Setup-Wizard" +msg_ok "Finished Setup-Wizard" motd_ssh customize From 970475a21034cbc4bcde912ab9fe1d0117c00bb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 04:07:30 -0400 Subject: [PATCH 5339/6505] Update alpine-nextcloud-install.sh tweak --- install/alpine-nextcloud-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index a730a2b0..39cc825f 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -178,8 +178,8 @@ if rc-service nextcloud -q status >/dev/null 2>&1; then su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' fi EOF -#sed -i '/monthly/a */5 * * * * run-parts /etc/periodic/5min' /etc/crontabs/root -#chmod +x /etc/periodic/5min/nextcloud_cron +(crontab -l ; echo "*/5 * * * * run-parts /etc/periodic/5min") | crontab - +chmod +x /etc/periodic/5min/nextcloud_cron msg_ok "Set up Nextcloud-Cronjob" msg_info "Setting up Nextcloud-Config" @@ -243,7 +243,6 @@ $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ --admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \ --data-dir '/var/lib/nextcloud/data'" $STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' -#$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable dashboard' IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php msg_ok "Finished Setup-Wizard" From 9124b596eb570258000662deb59e38191b61b9e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 05:49:09 -0400 Subject: [PATCH 5340/6505] Update rdtclient.sh fix path --- ct/rdtclient.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh index 3e70c3dd..227856d6 100755 --- a/ct/rdtclient.sh +++ b/ct/rdtclient.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /opt/rdtclient/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -d /opt/rdtc/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null From 88fd96dc5d3cf6213f8d58860926eac181722659 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 06:31:02 -0400 Subject: [PATCH 5341/6505] Update alpine-nextcloud.sh tweak --- ct/alpine-nextcloud.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 1a6e9cf9..2f596c9f 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -96,8 +96,5 @@ build_container description msg_ok "Completed Successfully!\n" -echo -e "To retrieve the database credentials required for the Setup-Wizard, execute the same script within the LXC Console.\n -For advanced configuration use this file: /usr/share/webapps/nextcloud/config/config.php \n - ${APP} should be reachable by going to the following URL. ${BL}https://${IP}${CL} \n" From 1c5ac20a6ff54352b01977ef6c641eecce4c00d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 06:42:06 -0400 Subject: [PATCH 5342/6505] Update alpine-nextcloud.sh --- ct/alpine-nextcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 2f596c9f..084d36e0 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -95,6 +95,6 @@ start build_container description -msg_ok "Completed Successfully!\n" +msg_ok "Completed Successfully!\n ${APP} should be reachable by going to the following URL. ${BL}https://${IP}${CL} \n" From 9fb5e232bd56aa7a78a76e256b396390e2ebb135 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 06:48:31 -0400 Subject: [PATCH 5343/6505] Update alpine-nextcloud.sh --- ct/alpine-nextcloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 084d36e0..4769d44e 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -95,6 +95,6 @@ start build_container description -msg_ok "Completed Successfully!\n -${APP} should be reachable by going to the following URL. +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. ${BL}https://${IP}${CL} \n" From 6faf005189dd1504394451b593fbe724f8ebba2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 12:34:23 -0400 Subject: [PATCH 5344/6505] Update alpine-nextcloud-install.sh code refactoring --- install/alpine-nextcloud-install.sh | 185 +++++++++++++--------------- 1 file changed, 83 insertions(+), 102 deletions(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 39cc825f..ae30ab31 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -20,9 +20,30 @@ $STD apk add openssl $STD apk add openssh $STD apk add nano $STD apk add mc -$STD apk add argon2 +$STD apk add nginx +echo -e "export VISUAL=nano\nexport EDITOR=nano" >>/etc/profile msg_ok "Installed Dependencies" +msg_info "Installing PHP/Redis" +$STD apk add php82-opcache +$STD apk add php82-redis +$STD apk add php82-apcu +$STD apk add php82-fpm +$STD apk add php82-sysvsem +$STD apk add php82-pecl-imagick +$STD apk add php82-exif +$STD apk add redis +sed -i -e 's|;opcache.enable=1|opcache.enable=1|' /etc/php82/php.ini +sed -i -e 's|;opcache.enable_cli=1|opcache.enable_cli=1|' /etc/php82/php.ini +sed -i -e 's|;opcache.interned_strings_buffer=8|opcache.interned_strings_buffer=16|' /etc/php82/php.ini +sed -i -e 's|;opcache.max_accelerated_files=10000|opcache.max_accelerated_files=10000|' /etc/php82/php.ini +sed -i -e 's|;opcache.memory_consumption=128|opcache.memory_consumption=256|' /etc/php82/php.ini +sed -i -e 's|;opcache.save_comments=1|opcache.save_comments=1|' /etc/php82/php.ini +sed -i -e 's|;opcache.revalidate_freq=1|opcache.revalidate_freq=1|' /etc/php82/php.ini +$STD rc-update add redis +$STD rc-service redis start +msg_ok "Installed PHP/Redis" + msg_info "Creating Credentials" DB_NAME=nextcloud DB_USER=nextcloud @@ -35,8 +56,9 @@ echo -e "MySQL Admin Password: \e[32m$ROOT_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Username: \e[32m$DB_USER\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Password: \e[32m$DB_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Name: \e[32m$DB_NAME\e[0m" >>~/nextcloud.creds +echo "" >>~/nextcloud.creds echo -e "Nextcloud Admin Username: \e[32m$ADMIN_USER\e[0m" >>~/nextcloud.creds -echo -e "Nextcloud Admin Password: \e[32m$ADMIN_PASS\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Admin Password: \e[32m$ADMIN_PASS\e[0m (Initially enter twice)" >>~/nextcloud.creds msg_ok "Created Credentials" msg_info "Installing MySQL Database" @@ -44,32 +66,62 @@ $STD apk add nextcloud-mysql mariadb mariadb-client $STD mysql_install_db --user=mysql --datadir=/var/lib/mysql $STD service mariadb start $STD rc-update add mariadb + +mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ROOT_PASS' WITH GRANT OPTION;FLUSH PRIVILEGES;" +mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='';" +mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" +mysql -uroot -p$ROOT_PASS -e "DROP DATABASE test;" +mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';" +mysql -uroot -p$ROOT_PASS -e "CREATE DATABASE $DB_NAME;" +mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" +mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS';" +mysql -uroot -p$ROOT_PASS -e "FLUSH PRIVILEGES;" +$STD apk del mariadb-client msg_ok "Installed MySQL Database" -msg_info "Setting up MySQL Database" -$STD mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ROOT_PASS' WITH GRANT OPTION;FLUSH PRIVILEGES;" -$STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='';" -$STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" -$STD mysql -uroot -p$ROOT_PASS -e "DROP DATABASE test;" -$STD mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';" -$STD mysql -uroot -p$ROOT_PASS -e "CREATE DATABASE $DB_NAME;" -$STD mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" -$STD mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS';" -$STD mysql -uroot -p$ROOT_PASS -e "FLUSH PRIVILEGES;" -$STD apk del mariadb-client -msg_ok "Set up MySQL Database" - -msg_info "Installing Web-Server" +msg_info "Installing Nextcloud" $STD apk add nextcloud-initscript -$STD apk add nginx -$STD apk add php82-fpm -$STD apk add php82-sysvsem -$STD apk add php82-pecl-imagick -$STD apk add php82-exif -msg_ok "Installed Web-Server" - -msg_info "Setting up Web-Server" $STD openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj "/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local" +cat <<'EOF' >/usr/share/webapps/nextcloud/config/config.php + '/var/lib/nextcloud/data', + 'logfile' => '/var/log/nextcloud/nextcloud.log', + 'logdateformat' => 'F d, Y H:i:s', + 'log_rotate_size' => 104857600, + 'apps_paths' => array ( + // Read-only location for apps shipped with Nextcloud and installed by apk. + 0 => array ( + 'path' => '/usr/share/webapps/nextcloud/apps', + 'url' => '/apps', + 'writable' => false, + ), + // Writable location for apps installed from AppStore. + 1 => array ( + 'path' => '/var/lib/nextcloud/apps', + 'url' => '/apps-appstore', + 'writable' => true, + ), + ), + 'updatechecker' => false, + 'check_for_working_htaccess' => false, + + // Uncomment to enable Zend OPcache. + 'memcache.local' => '\\OC\\Memcache\\Redis', + + // Uncomment this and add user nextcloud to the redis group to enable Redis + // cache for file locking. This is highly recommended, see + // https://github.com/nextcloud/server/issues/9305. + 'memcache.locking' => '\\OC\\Memcache\\Redis', + 'redis' => array( + 'host' => 'localhost', + 'port' => 6379, + 'dbindex' => 0, + 'timeout' => 1.5, + ), + 'installed' => false, +); +EOF rm /etc/nginx/http.d/default.conf cat <<'EOF' >/etc/nginx/http.d/nextcloud.conf server { @@ -129,9 +181,10 @@ sed -i -e 's|php_admin_value\[post_max_size\] = 513M|php_admin_value\[post_max_s sed -i -e 's|php_admin_value\[upload_max_filesize\] = 513M|php_admin_value\[upload_max_filesize\] = 5121M|' /etc/php82/php-fpm.d/nextcloud.conf sed -i -e 's|upload_max_filesize = 513M|upload_max_filesize = 5121M|' /etc/php82/php.ini sed -i -e 's|memory_limit = 128M|memory_limit = 512M|' /etc/php82/php.ini -msg_ok "Set up Web-Server" +msg_ok "Installed Nextcloud" msg_info "Adding Additional Nextcloud Packages" +$STD apk add nextcloud-default-apps $STD apk add nextcloud-activity $STD apk add nextcloud-admin_audit $STD apk add nextcloud-comments @@ -152,80 +205,7 @@ $STD apk add nextcloud-user_status $STD apk add nextcloud-weather_status msg_ok "Added Additional Nextcloud Packages" -msg_info "Setting up PHP/Redis" -$STD apk add php82-opcache -$STD apk add php82-redis -$STD apk add php82-apcu -$STD apk add redis -sed -i -e 's|;opcache.enable=1|opcache.enable=1|' /etc/php82/php.ini -sed -i -e 's|;opcache.enable_cli=1|opcache.enable_cli=1|' /etc/php82/php.ini -sed -i -e 's|;opcache.interned_strings_buffer=8|opcache.interned_strings_buffer=16|' /etc/php82/php.ini -sed -i -e 's|;opcache.max_accelerated_files=10000|opcache.max_accelerated_files=10000|' /etc/php82/php.ini -sed -i -e 's|;opcache.memory_consumption=128|opcache.memory_consumption=256|' /etc/php82/php.ini -sed -i -e 's|;opcache.save_comments=1|opcache.save_comments=1|' /etc/php82/php.ini -sed -i -e 's|;opcache.revalidate_freq=1|opcache.revalidate_freq=1|' /etc/php82/php.ini -$STD rc-update add redis -$STD rc-service redis start -msg_ok "Set up PHP/Redis" - -msg_info "Setting up Nextcloud-Cronjob" -mkdir -p /etc/periodic/5min -cat <<'EOF' >/etc/periodic/5min/nextcloud_cron -#!/bin/sh - -# Run only when nextcloud service is started. -if rc-service nextcloud -q status >/dev/null 2>&1; then - su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' -fi -EOF -(crontab -l ; echo "*/5 * * * * run-parts /etc/periodic/5min") | crontab - -chmod +x /etc/periodic/5min/nextcloud_cron -msg_ok "Set up Nextcloud-Cronjob" - -msg_info "Setting up Nextcloud-Config" -cat <<'EOF' >/usr/share/webapps/nextcloud/config/config.php - '/var/lib/nextcloud/data', - 'logfile' => '/var/log/nextcloud/nextcloud.log', - 'logdateformat' => 'F d, Y H:i:s', - 'log_rotate_size' => 104857600, - 'apps_paths' => array ( - // Read-only location for apps shipped with Nextcloud and installed by apk. - 0 => array ( - 'path' => '/usr/share/webapps/nextcloud/apps', - 'url' => '/apps', - 'writable' => false, - ), - // Writable location for apps installed from AppStore. - 1 => array ( - 'path' => '/var/lib/nextcloud/apps', - 'url' => '/apps-appstore', - 'writable' => true, - ), - ), - 'updatechecker' => false, - 'check_for_working_htaccess' => false, - - // Uncomment to enable Zend OPcache. - 'memcache.local' => '\\OC\\Memcache\\Redis', - - // Uncomment this and add user nextcloud to the redis group to enable Redis - // cache for file locking. This is highly recommended, see - // https://github.com/nextcloud/server/issues/9305. - 'memcache.locking' => '\\OC\\Memcache\\Redis', - 'redis' => array( - 'host' => 'localhost', - 'port' => 6379, - 'dbindex' => 0, - 'timeout' => 1.5, - ), - 'installed' => false, -); -EOF -msg_ok "Set up Nextcloud-Config" - -msg_info "Starting Alpine-Nextcloud" +msg_info "Starting Services" $STD rc-service php-fpm82 start chown -R nextcloud:www-data /var/log/nextcloud/ $STD rc-service php-fpm82 restart @@ -233,9 +213,9 @@ $STD rc-service nginx start $STD rc-service nextcloud start $STD rc-update add nginx default $STD rc-update add nextcloud default -msg_ok "Started Alpine-Nextcloud" +msg_ok "Started Services" -msg_info "Start Setup-Wizard" +msg_info "Start Nextcloud Setup-Wizard" cd /usr/share/webapps/nextcloud $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ --database='mysql' --database-name $DB_NAME \ @@ -245,7 +225,8 @@ $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ $STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php -msg_ok "Finished Setup-Wizard" +su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' +msg_ok "Finished Nextcloud Setup-Wizard" motd_ssh customize From 6e296bbc2e11c50ea05dd361ea9304b884362b3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 13:10:04 -0400 Subject: [PATCH 5345/6505] Update alpine-nextcloud-install.sh error control --- install/alpine-nextcloud-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index ae30ab31..e201875b 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -175,6 +175,7 @@ server { location ^~ /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo; } } EOF +sed -i -E '/^php_admin_(flag|value)\[opcache/s/^/;/' /etc/php82/php-fpm.d/nextcloud.conf sed -i -e 's|client_max_body_size 1m;|client_max_body_size 5120m;|' /etc/nginx/nginx.conf sed -i -e 's|php_admin_value\[memory_limit\] = 512M|php_admin_value\[memory_limit\] = 5120M|' /etc/php82/php-fpm.d/nextcloud.conf sed -i -e 's|php_admin_value\[post_max_size\] = 513M|php_admin_value\[post_max_size\] = 5121M|' /etc/php82/php-fpm.d/nextcloud.conf From c2b3388dbaba512ac67b29408c7d505446c190b8 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Fri, 29 Sep 2023 19:37:56 +0200 Subject: [PATCH 5346/6505] Updates (#1859) - APCu enabled for most performance on single server (https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/caching_configuration.html) - External Storage working with CIFS/SMB now - Disabled Serverinfo because it is not working on alpine (shell_exec.....) --- install/alpine-nextcloud-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index e201875b..7c508489 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -31,6 +31,7 @@ $STD apk add php82-apcu $STD apk add php82-fpm $STD apk add php82-sysvsem $STD apk add php82-pecl-imagick +$STD apk add php82-pecl-smbclient $STD apk add php82-exif $STD apk add redis sed -i -e 's|;opcache.enable=1|opcache.enable=1|' /etc/php82/php.ini @@ -107,7 +108,8 @@ $CONFIG = array ( 'check_for_working_htaccess' => false, // Uncomment to enable Zend OPcache. - 'memcache.local' => '\\OC\\Memcache\\Redis', + 'memcache.local' => '\\OC\\Memcache\\APCu', + 'memcache.distributed' => '\\OC\\Memcache\\Redis', // Uncomment this and add user nextcloud to the redis group to enable Redis // cache for file locking. This is highly recommended, see @@ -182,6 +184,7 @@ sed -i -e 's|php_admin_value\[post_max_size\] = 513M|php_admin_value\[post_max_s sed -i -e 's|php_admin_value\[upload_max_filesize\] = 513M|php_admin_value\[upload_max_filesize\] = 5121M|' /etc/php82/php-fpm.d/nextcloud.conf sed -i -e 's|upload_max_filesize = 513M|upload_max_filesize = 5121M|' /etc/php82/php.ini sed -i -e 's|memory_limit = 128M|memory_limit = 512M|' /etc/php82/php.ini +sed -i -e '$aapc.enable_cli=1' /etc/php82/php.ini msg_ok "Installed Nextcloud" msg_info "Adding Additional Nextcloud Packages" @@ -224,6 +227,7 @@ $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ --admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \ --data-dir '/var/lib/nextcloud/data'" $STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' +$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable serverinfo' IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' From 60112cddd2691fc6efe6cd8ae624cd7aeffef3c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 13:50:17 -0400 Subject: [PATCH 5347/6505] Update alpine-nextcloud-install.sh test --- install/alpine-nextcloud-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 7c508489..01cfa664 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -227,7 +227,7 @@ $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ --admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \ --data-dir '/var/lib/nextcloud/data'" $STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' -$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable serverinfo' +#$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable serverinfo' IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' From 7af2bda0395d65c3c880dac252c1be4c68f1733c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 13:58:45 -0400 Subject: [PATCH 5348/6505] Update alpine-nextcloud-install.sh fix error in logs --- install/alpine-nextcloud-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 01cfa664..83e029be 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -227,7 +227,7 @@ $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ --admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \ --data-dir '/var/lib/nextcloud/data'" $STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' -#$STD su nextcloud -s /bin/sh -c 'php82 occ app:disable serverinfo' +rm -rf /usr/share/webapps/nextcloud/apps/serverinfo IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' From 1f63d49e428da3080cb30794f3e1c89ccefe38fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Sep 2023 18:32:43 -0400 Subject: [PATCH 5349/6505] Update alpine-nextcloud-install.sh code refactoring --- install/alpine-nextcloud-install.sh | 78 ++++++----------------------- 1 file changed, 14 insertions(+), 64 deletions(-) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 83e029be..15ead7e0 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -21,7 +21,6 @@ $STD apk add openssh $STD apk add nano $STD apk add mc $STD apk add nginx -echo -e "export VISUAL=nano\nexport EDITOR=nano" >>/etc/profile msg_ok "Installed Dependencies" msg_info "Installing PHP/Redis" @@ -30,57 +29,35 @@ $STD apk add php82-redis $STD apk add php82-apcu $STD apk add php82-fpm $STD apk add php82-sysvsem -$STD apk add php82-pecl-imagick $STD apk add php82-pecl-smbclient +$STD apk add php82-pecl-imagick $STD apk add php82-exif $STD apk add redis -sed -i -e 's|;opcache.enable=1|opcache.enable=1|' /etc/php82/php.ini -sed -i -e 's|;opcache.enable_cli=1|opcache.enable_cli=1|' /etc/php82/php.ini -sed -i -e 's|;opcache.interned_strings_buffer=8|opcache.interned_strings_buffer=16|' /etc/php82/php.ini -sed -i -e 's|;opcache.max_accelerated_files=10000|opcache.max_accelerated_files=10000|' /etc/php82/php.ini -sed -i -e 's|;opcache.memory_consumption=128|opcache.memory_consumption=256|' /etc/php82/php.ini -sed -i -e 's|;opcache.save_comments=1|opcache.save_comments=1|' /etc/php82/php.ini -sed -i -e 's|;opcache.revalidate_freq=1|opcache.revalidate_freq=1|' /etc/php82/php.ini -$STD rc-update add redis -$STD rc-service redis start msg_ok "Installed PHP/Redis" -msg_info "Creating Credentials" +msg_info "Installing MySQL Database" DB_NAME=nextcloud DB_USER=nextcloud DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" -ROOT_PASS="$(openssl rand -base64 18 | cut -c1-13)" -ADMIN_USER=ncAdmin ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)" echo "" >>~/nextcloud.creds -echo -e "MySQL Admin Password: \e[32m$ROOT_PASS\e[0m" >>~/nextcloud.creds +echo -e "MySQL Admin Password: \e[32m$ADMIN_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Username: \e[32m$DB_USER\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Password: \e[32m$DB_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Name: \e[32m$DB_NAME\e[0m" >>~/nextcloud.creds -echo "" >>~/nextcloud.creds -echo -e "Nextcloud Admin Username: \e[32m$ADMIN_USER\e[0m" >>~/nextcloud.creds -echo -e "Nextcloud Admin Password: \e[32m$ADMIN_PASS\e[0m (Initially enter twice)" >>~/nextcloud.creds -msg_ok "Created Credentials" - -msg_info "Installing MySQL Database" $STD apk add nextcloud-mysql mariadb mariadb-client $STD mysql_install_db --user=mysql --datadir=/var/lib/mysql $STD service mariadb start $STD rc-update add mariadb - -mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ROOT_PASS' WITH GRANT OPTION;FLUSH PRIVILEGES;" -mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='';" -mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" -mysql -uroot -p$ROOT_PASS -e "DROP DATABASE test;" -mysql -uroot -p$ROOT_PASS -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';" -mysql -uroot -p$ROOT_PASS -e "CREATE DATABASE $DB_NAME;" -mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" -mysql -uroot -p$ROOT_PASS -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS';" -mysql -uroot -p$ROOT_PASS -e "FLUSH PRIVILEGES;" +mysql -uroot -p"$ADMIN_PASS" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ADMIN_PASS' WITH GRANT OPTION; DELETE FROM mysql.user WHERE User=''; DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); DROP DATABASE test; DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'; CREATE DATABASE $DB_NAME; GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS'; GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS'; FLUSH PRIVILEGES;" $STD apk del mariadb-client msg_ok "Installed MySQL Database" msg_info "Installing Nextcloud" +ADMIN_USER=ncAdmin +echo "" >>~/nextcloud.creds +echo -e "Nextcloud Admin Username: \e[32m$ADMIN_USER\e[0m" >>~/nextcloud.creds +echo -e "Nextcloud Admin Password: \e[32m$ADMIN_PASS\e[0m (Initially enter twice)" >>~/nextcloud.creds $STD apk add nextcloud-initscript $STD openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj "/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local" cat <<'EOF' >/usr/share/webapps/nextcloud/config/config.php @@ -91,13 +68,11 @@ $CONFIG = array ( 'logdateformat' => 'F d, Y H:i:s', 'log_rotate_size' => 104857600, 'apps_paths' => array ( - // Read-only location for apps shipped with Nextcloud and installed by apk. 0 => array ( 'path' => '/usr/share/webapps/nextcloud/apps', 'url' => '/apps', 'writable' => false, ), - // Writable location for apps installed from AppStore. 1 => array ( 'path' => '/var/lib/nextcloud/apps', 'url' => '/apps-appstore', @@ -106,14 +81,7 @@ $CONFIG = array ( ), 'updatechecker' => false, 'check_for_working_htaccess' => false, - - // Uncomment to enable Zend OPcache. - 'memcache.local' => '\\OC\\Memcache\\APCu', - 'memcache.distributed' => '\\OC\\Memcache\\Redis', - - // Uncomment this and add user nextcloud to the redis group to enable Redis - // cache for file locking. This is highly recommended, see - // https://github.com/nextcloud/server/issues/9305. + 'memcache.local' => '\\OC\\Memcache\\Redis', 'memcache.locking' => '\\OC\\Memcache\\Redis', 'redis' => array( 'host' => 'localhost', @@ -124,7 +92,7 @@ $CONFIG = array ( 'installed' => false, ); EOF -rm /etc/nginx/http.d/default.conf +rm -rf /etc/nginx/http.d/default.conf cat <<'EOF' >/etc/nginx/http.d/nextcloud.conf server { listen [::]:80; @@ -132,59 +100,38 @@ server { return 301 https://$host$request_uri; server_name localhost; } - server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name localhost; - root /usr/share/webapps/nextcloud; index index.php index.html index.htm; disable_symlinks off; - ssl_certificate /etc/ssl/certs/nextcloud-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nextcloud-selfsigned.key; ssl_session_timeout 5m; - - #Enable Perfect Forward Secrecy and ciphers without known vulnerabilities - #Beware! It breaks compatibility with older OS and browsers (e.g. Windows XP, Android 2.x, etc.) ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA; ssl_prefer_server_ciphers on; - - location / { try_files $uri $uri/ /index.html; } - - # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; if (!-f $document_root$fastcgi_script_name) { return 404; } - #fastcgi_pass 127.0.0.1:9000; - #fastcgi_pass unix:/run/php-fpm/socket; fastcgi_pass unix:/run/nextcloud/fastcgi.sock; # From the nextcloud-initscript package fastcgi_index index.php; include fastcgi.conf; } - - # Help pass nextcloud's configuration checks after install: - # Per https://docs.nextcloud.com/server/22/admin_manual/issues/general_troubleshooting.html#service-discovery location ^~ /.well-known/carddav { return 301 /remote.php/dav/; } location ^~ /.well-known/caldav { return 301 /remote.php/dav/; } location ^~ /.well-known/webfinger { return 301 /index.php/.well-known/webfinger; } location ^~ /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo; } } EOF +sed -i -e 's|memory_limit = 128M|memory_limit = 512M|; $aapc.enable_cli=1' /etc/php82/php.ini sed -i -E '/^php_admin_(flag|value)\[opcache/s/^/;/' /etc/php82/php-fpm.d/nextcloud.conf -sed -i -e 's|client_max_body_size 1m;|client_max_body_size 5120m;|' /etc/nginx/nginx.conf -sed -i -e 's|php_admin_value\[memory_limit\] = 512M|php_admin_value\[memory_limit\] = 5120M|' /etc/php82/php-fpm.d/nextcloud.conf -sed -i -e 's|php_admin_value\[post_max_size\] = 513M|php_admin_value\[post_max_size\] = 5121M|' /etc/php82/php-fpm.d/nextcloud.conf -sed -i -e 's|php_admin_value\[upload_max_filesize\] = 513M|php_admin_value\[upload_max_filesize\] = 5121M|' /etc/php82/php-fpm.d/nextcloud.conf -sed -i -e 's|upload_max_filesize = 513M|upload_max_filesize = 5121M|' /etc/php82/php.ini -sed -i -e 's|memory_limit = 128M|memory_limit = 512M|' /etc/php82/php.ini -sed -i -e '$aapc.enable_cli=1' /etc/php82/php.ini msg_ok "Installed Nextcloud" msg_info "Adding Additional Nextcloud Packages" @@ -210,6 +157,8 @@ $STD apk add nextcloud-weather_status msg_ok "Added Additional Nextcloud Packages" msg_info "Starting Services" +$STD rc-service redis start +$STD rc-update add redis default $STD rc-service php-fpm82 start chown -R nextcloud:www-data /var/log/nextcloud/ $STD rc-service php-fpm82 restart @@ -220,6 +169,7 @@ $STD rc-update add nextcloud default msg_ok "Started Services" msg_info "Start Nextcloud Setup-Wizard" +echo -e "export VISUAL=nano\nexport EDITOR=nano" >>/etc/profile cd /usr/share/webapps/nextcloud $STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ --database='mysql' --database-name $DB_NAME \ From 4280da6c42f814a1730ff0127bd96fc005ca5c95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Sep 2023 07:03:00 -0400 Subject: [PATCH 5350/6505] Update alpine-nextcloud.sh tweak --- ct/alpine-nextcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 4769d44e..0028e6a7 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -96,5 +96,5 @@ build_container description msg_ok "Completed Successfully!\n" -echo -e "${APP} Setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}https://${IP}${CL} \n" From 0e60f4ac4b0117fdf32b5aff97462ba3f4ecceec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Sep 2023 08:29:05 -0400 Subject: [PATCH 5351/6505] Update umbrel.sh set default Debian 12 fixes https://github.com/tteck/Proxmox/issues/1862 http://umbrel.local --- ct/umbrel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 8babfc1b..2dd3c08f 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 45067cfdd1b57179f00ba244d67de4b840adabbe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Sep 2023 11:19:22 -0400 Subject: [PATCH 5352/6505] Update unifi.sh tweak update --- ct/unifi.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/unifi.sh b/ct/unifi.sh index 5f20a0ed..188b5f56 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -54,7 +54,7 @@ function update_script() { header_info if [[ ! -d /usr/lib/unifi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" -apt-get update +apt-get update --allow-releaseinfo-change apt-get install -y unifi msg_ok "Updated Successfully" exit From 3678d28151068620c74e21420e627e41cc4043df Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Sep 2023 11:55:47 -0400 Subject: [PATCH 5353/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7352f879..1b6f1615 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-09-30 + +### Changed + +- **All Templates** + - NEW Script + ## 2023-09-28 ### Changed From a37c57665d46ce234eb0cbf514f9d111e81a8c6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 1 Oct 2023 07:51:17 -0400 Subject: [PATCH 5354/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 8b752d6d..75878301 100644 --- a/misc/build.func +++ b/misc/build.func @@ -462,7 +462,7 @@ start() { fi if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "Support functions for ${APP} LXC. Proceed?" 10 58); then + if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "Support/Update functions for ${APP} LXC. Proceed?" 10 58); then clear echo -e "⚠ User exited script \n" exit From b1f2e76f7a78dbefe131b9f7274c3e7e8264ef66 Mon Sep 17 00:00:00 2001 From: leiweibau <105860611+leiweibau@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:26:18 +0200 Subject: [PATCH 5355/6505] Update pialert-install.sh (#1871) Update php dependencies. --- install/pialert-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 789710c0..0a5d06cf 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -38,6 +38,7 @@ $STD apt-get -y install \ php-cgi \ php-fpm \ php-curl \ + php-xml \ php-sqlite3 $STD lighttpd-enable-mod fastcgi-php service lighttpd force-reload From d48605dcde110003572fb4d67fdcc8ad27a39e04 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:14:26 +0200 Subject: [PATCH 5356/6505] Update Alpine Nextcloud (#1876) add php82-pecl-vips --- install/alpine-nextcloud-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 15ead7e0..e89a1c4a 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -31,6 +31,7 @@ $STD apk add php82-fpm $STD apk add php82-sysvsem $STD apk add php82-pecl-smbclient $STD apk add php82-pecl-imagick +$STD apk add php82-pecl-vips $STD apk add php82-exif $STD apk add redis msg_ok "Installed PHP/Redis" From 9c7dccf152290177b1805c4dfb80b2c05275aa35 Mon Sep 17 00:00:00 2001 From: nicedevil007 <17103076+nicedevil007@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:59:18 +0200 Subject: [PATCH 5357/6505] Update Alpine Nextcloud (#1877) add option for FTP Support --- install/alpine-nextcloud-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index e89a1c4a..8ee125bf 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -29,6 +29,7 @@ $STD apk add php82-redis $STD apk add php82-apcu $STD apk add php82-fpm $STD apk add php82-sysvsem +$STD apk add php82-ftp $STD apk add php82-pecl-smbclient $STD apk add php82-pecl-imagick $STD apk add php82-pecl-vips From 597c9ad1e3ae2a745a1927c11bb6267efabcd47a Mon Sep 17 00:00:00 2001 From: Ben Bennett Date: Tue, 3 Oct 2023 11:32:18 -0400 Subject: [PATCH 5358/6505] Add fedora disk info command (#1878) Added fedora to the supported list for the disk info command. --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 1e63ff1b..2e4c510d 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -41,7 +41,7 @@ function update_container() { header_info name=$(pct exec "$container" hostname) os=$(pct config "$container" | awk '/^ostype/ {print $2}') - if [[ "$os" == "ubuntu" || "$os" == "debian" ]]; then + if [[ "$os" == "ubuntu" || "$os" == "debian" || "$os" == "fedora" ]]; then disk_info=$(pct exec "$container" df /boot | awk 'NR==2{gsub("%","",$5); printf "%s %.1fG %.1fG %.1fG", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }') read -ra disk_info_array <<<"$disk_info" echo -e "${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\n" From 216d7116601d9b594235dad35b69f3b65a822494 Mon Sep 17 00:00:00 2001 From: h-4-t <65722138+h-4-t@users.noreply.github.com> Date: Wed, 4 Oct 2023 12:11:30 +0100 Subject: [PATCH 5359/6505] Update monitor-all.sh (#1881) Fix service file --- misc/monitor-all.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 02d0b696..f7e74dcf 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -102,7 +102,8 @@ Type=simple # To specify which CT/VM should be excluded, add the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified. # For example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 # Virtual machines without the QEMU guest agent installed must be excluded. -ExecStartPre=/usr/bin/sleep 300 # Sleep for 300 seconds (5 minutes) +# Sleep for 300 seconds (5 minutes) +ExecStartPre=/usr/bin/sleep 300 ExecStart=/usr/local/bin/ping-instances.sh Restart=always StandardOutput=file:/var/log/ping-instances.log From c37e75f6eed17494a060de342a181ec4c2682ccd Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 4 Oct 2023 07:36:49 -0400 Subject: [PATCH 5360/6505] Update node-red-install.sh node version 20 --- install/node-red-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/node-red-install.sh b/install/node-red-install.sh index 5b673133..94271b41 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -25,7 +25,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 295ddcdc8237958ce788178401866815137bbe0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Oct 2023 01:15:20 -0400 Subject: [PATCH 5361/6505] Create pingvin-install.sh --- install/pingvin-install.sh | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 install/pingvin-install.sh diff --git a/install/pingvin-install.sh b/install/pingvin-install.sh new file mode 100644 index 00000000..b8d31fb2 --- /dev/null +++ b/install/pingvin-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +$STD npm install pm2 -g +msg_ok "Installed Node.js" + +msg_info "Installing Pingvin Share (Patience)" +git clone -q https://github.com/stonith404/pingvin-share /opt/pingvin-share +cd /opt/pingvin-share +$STD git fetch --tags +$STD git checkout $(git describe --tags `git rev-list --tags --max-count=1`) +cd backend +$STD npm install +$STD npm run build +$STD pm2 start --name="pingvin-share-backend" npm -- run prod +cd ../frontend +$STD npm install +$STD npm run build +$STD pm2 start --name="pingvin-share-frontend" npm -- run start +$STD pm2 startup +msg_ok "Installed Pingvin Share" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 0c5836e61a6a7d2a3c4636f5f8a8d6ed10e37c4e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Oct 2023 01:21:05 -0400 Subject: [PATCH 5362/6505] Create pingvin.sh --- ct/pingvin.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/pingvin.sh diff --git a/ct/pingvin.sh b/ct/pingvin.sh new file mode 100644 index 00000000..20ad9b67 --- /dev/null +++ b/ct/pingvin.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _ _ _____ __ + / __ \(_)___ ____ __ __(_)___ / ___// /_ ____ _________ + / /_/ / / __ \/ __ `/ | / / / __ \ \__ \/ __ \/ __ `/ ___/ _ \ + / ____/ / / / / /_/ /| |/ / / / / / ___/ / / / / /_/ / / / __/ +/_/ /_/_/ /_/\__, / |___/_/_/ /_/ /____/_/ /_/\__,_/_/ \___/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Pingvin" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000 ${CL} \n" From e9d6f10b3c0b7afebe13617b1ac5f7bb49ad9b8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Oct 2023 09:11:08 -0400 Subject: [PATCH 5363/6505] Update pingvin.sh create update path --- ct/pingvin.sh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ct/pingvin.sh b/ct/pingvin.sh index 20ad9b67..cba10c06 100644 --- a/ct/pingvin.sh +++ b/ct/pingvin.sh @@ -52,8 +52,26 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +if [[ ! -d /opt/pingvin-share ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping Pingvin Share" +pm2 stop pingvin-share-backend pingvin-share-frontend &>/dev/null +msg_ok "Stopped Pingvin Share" + +msg_info "Updating Pingvin Share" +cd /opt/pingvin-share +git fetch --tags +git checkout $(git describe --tags `git rev-list --tags --max-count=1`) &>/dev/null +cd backend +npm run build &>/dev/null +cd ../frontend +npm run build &>/dev/null +msg_ok "Updated Pingvin Share" + +msg_info "Starting Pingvin Share" +pm2 start pingvin-share-backend pingvin-share-frontend &>/dev/null +msg_ok "Started Pingvin Share" + +msg_ok "Updated Successfully" exit } From 067169f92bfecb2a7bf3bea5d11a62630a1b8e76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Oct 2023 09:22:47 -0400 Subject: [PATCH 5364/6505] Update pingvin-install.sh add update command --- install/pingvin-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/pingvin-install.sh b/install/pingvin-install.sh index b8d31fb2..6131e534 100644 --- a/install/pingvin-install.sh +++ b/install/pingvin-install.sh @@ -47,6 +47,8 @@ $STD npm install $STD npm run build $STD pm2 start --name="pingvin-share-frontend" npm -- run start $STD pm2 startup +echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update +chmod +x /usr/bin/update msg_ok "Installed Pingvin Share" motd_ssh From 95e6a5436ab1ffc4ada8606184ab980f4c4e1db1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Oct 2023 09:26:18 -0400 Subject: [PATCH 5365/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b6f1615..aa0db42f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-05 + +### Changed + +- **Pingvin Share LXC** + - NEW Script + ## 2023-09-30 ### Changed From e45aa5e42a98ecbc3c75bd034376fa2337113ab1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 5 Oct 2023 15:36:19 -0400 Subject: [PATCH 5366/6505] Update install.func - globally add update command --- install/esphome-install.sh | 2 -- install/homeassistant-core-install.sh | 2 -- install/homeassistant-install.sh | 2 -- install/node-red-install.sh | 2 -- install/omada-install.sh | 2 -- install/pingvin-install.sh | 2 -- install/zigbee2mqtt-install.sh | 2 -- misc/install.func | 2 ++ 8 files changed, 2 insertions(+), 14 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 5cb2cb59..7dbbbc18 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -35,8 +35,6 @@ msg_info "Installing ESPHome" #python3 -m venv . #source bin/activate $STD pip install esphome tornado esptool -echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update -chmod +x /usr/bin/update msg_ok "Installed ESPHome" msg_info "Creating Service" diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 0c3a8cff..cbb10ed5 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -87,8 +87,6 @@ $STD pip install homeassistant $STD pip install mysqlclient $STD pip install psycopg2-binary mkdir -p /root/.homeassistant -echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update -chmod +x /usr/bin/update msg_ok "Installed Home Assistant-Core" msg_info "Creating Service" diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 5bfe63d2..0c19ca6c 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -88,8 +88,6 @@ $STD docker run -d \ --net=host \ ghcr.io/home-assistant/home-assistant:stable mkdir /root/hass_config -echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update -chmod +x /usr/bin/update msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" motd_ssh diff --git a/install/node-red-install.sh b/install/node-red-install.sh index 94271b41..dc1f8759 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -43,8 +43,6 @@ echo "systemctl start nodered" >/usr/bin/node-red-start chmod +x /usr/bin/node-red-start echo "systemctl restart nodered" >/usr/bin/node-red-restart chmod +x /usr/bin/node-red-restart -echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update -chmod +x /usr/bin/update msg_ok "Installed Node-Red" msg_info "Creating Service" diff --git a/install/omada-install.sh b/install/omada-install.sh index f2f7a3e5..79a35359 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -42,8 +42,6 @@ latest_version=$(basename "$latest_url" | sed -e 's/.*ller_//;s/_Li.*//') msg_info "Installing Omada Controller ${latest_version}" wget -qL ${latest_url} $STD dpkg -i Omada_SDN_Controller_${latest_version}_Linux_x64.deb -echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update -chmod +x /usr/bin/update msg_ok "Installed Omada Controller ${latest_version}" motd_ssh diff --git a/install/pingvin-install.sh b/install/pingvin-install.sh index 6131e534..b8d31fb2 100644 --- a/install/pingvin-install.sh +++ b/install/pingvin-install.sh @@ -47,8 +47,6 @@ $STD npm install $STD npm run build $STD pm2 start --name="pingvin-share-frontend" npm -- run start $STD pm2 startup -echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update -chmod +x /usr/bin/update msg_ok "Installed Pingvin Share" motd_ssh diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 1e8b5089..dc52ffa0 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -53,8 +53,6 @@ if [[ $DEV == "y" ]]; then $STD git checkout dev fi $STD npm ci -echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update -chmod +x /usr/bin/update msg_ok "Installed Zigbee2MQTT" msg_info "Creating Service" diff --git a/misc/install.func b/misc/install.func index 24fd8533..a15364c2 100644 --- a/misc/install.func +++ b/misc/install.func @@ -143,4 +143,6 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi + echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update + chmod +x /usr/bin/update } From ec6ff20ca2690eac1f9dc6323aebf36be1bfe2f0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Oct 2023 23:38:34 -0400 Subject: [PATCH 5367/6505] Update all-templates.sh change whiptail variables --- misc/all-templates.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/all-templates.sh b/misc/all-templates.sh index 34c291a5..d376cbf7 100644 --- a/misc/all-templates.sh +++ b/misc/all-templates.sh @@ -59,14 +59,14 @@ header_info echo "Loading..." pveam update >/dev/null 2>&1 whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68 || exit -CTID_MENU=() +TEMPLATE_MENU=() MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$ITEM" "$TAG " "OFF") + TEMPLATE_MENU+=("$ITEM" "$TAG " "OFF") done < <(pveam available) -TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${TEMPLATE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit [ -z "$TEMPLATE" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68 msg "Done" From 6c57809037e1d594c33371d167dfbb2069e679e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Oct 2023 23:42:54 -0400 Subject: [PATCH 5368/6505] Update clean-lxcs.sh change whiptail variables --- misc/clean-lxcs.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index a44e67cb..99af44a9 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -25,13 +25,15 @@ header_info echo "Loading..." whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Clean logs, cache and update apt lists on selected LXC Containers. Proceed?" 10 58 || exit NODE=$(hostname) +EXCLUDE_MENU=() +MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$TAG" "$ITEM " "OFF") + EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from cleaning:\n" \ - 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + 16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit function clean_container() { container=$1 From 6b2df5dd0f85cb2a1483250666ef18ee42dc22a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Oct 2023 23:48:01 -0400 Subject: [PATCH 5369/6505] Update microcode.sh change whiptail variables --- misc/microcode.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 7900bacd..a4653be5 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -46,16 +46,16 @@ intel() { intel_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode//" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//') [ -z "$intel_microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } - CTID_MENU=() + MICROCODE_MENU=() MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$TAG" "$ITEM " "OFF") + MICROCODE_MENU+=("$TAG" "$ITEM " "OFF") done < <(echo "$intel_microcode") - microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${MICROCODE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit [ -z "$microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Selected" --msgbox "It appears that no microcode packages were selected" 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } @@ -78,16 +78,16 @@ amd() { [ -z "$amd_microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } - CTID_MENU=() + MICROCODE_MENU=() MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$TAG" "$ITEM " "OFF") + MICROCODE_MENU+=("$TAG" "$ITEM " "OFF") done < <(echo "$amd_microcode") - microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + microcode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Microcode revision:${current_microcode}" --radiolist "\nSelect a microcode package to install:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${MICROCODE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit [ -z "$microcode" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Selected" --msgbox "It appears that no microcode packages were selected" 10 68; msg_info "Exiting"; sleep 1; msg_ok "Done"; exit; } From 7b7619aaa7d0c574eb628bcc2e2364561267a613 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Oct 2023 23:51:11 -0400 Subject: [PATCH 5370/6505] Update update-lxcs.sh change whiptail variables --- misc/update-lxcs.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 2e4c510d..53fdd42c 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -28,14 +28,14 @@ header_info echo "Loading..." whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58 || exit NODE=$(hostname) -CTID_MENU=() +EXCLUDE_MENU=() MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$TAG" "$ITEM " "OFF") + EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') -excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from updates:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from updates:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit function update_container() { container=$1 header_info From 5d40a203e6953d46c6d5724cafa6b451bec60bd0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 6 Oct 2023 23:53:18 -0400 Subject: [PATCH 5371/6505] Update turnkey.sh change whiptail variables --- turnkey/turnkey.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index 292930f6..a77573b5 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -57,12 +57,12 @@ if systemctl is-active -q ping-instances.service; then fi header_info whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs" --yesno "This will allow for the creation of one of the many TurnKey LXC Containers. Proceed?" 10 68 || exit -CTID_MENU=() +TURNKEY_MENU=() MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$TAG" "$ITEM " "OFF") + TURNKEY_MENU+=("$TAG" "$ITEM " "OFF") done < <( cat <&1 1>&2 2>&3 | tr -d '"') || exit +turnkey=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs" --radiolist "\nSelect a TurnKey LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${TURNKEY_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit [ -z "$turnkey" ] && { whiptail --backtitle "Proxmox VE Helper Scripts" --title "No TurnKey LXC Selected" --msgbox "It appears that no TurnKey LXC container was selected" 10 68 msg "Done" From 27060de398f769a87580ea845f481c141f003eb8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Oct 2023 13:31:39 -0400 Subject: [PATCH 5372/6505] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa0db42f..ee6e1518 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ - +

    + # Change Log **All notable changes to this project will be documented in this file.**
    From bc4329a3b4676a62e8a97fda18b6b1d714ede556 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Oct 2023 13:53:26 -0400 Subject: [PATCH 5373/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee6e1518..79ac503b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -

    +

    # Change Log **All notable changes to this project will be documented in this file.**
    From 40ea76c0662d9c309c902283bd62011e43eb4447 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 7 Oct 2023 13:55:25 -0400 Subject: [PATCH 5374/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79ac503b..0210c6a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -

    +

    # Change Log **All notable changes to this project will be documented in this file.**
    From 87e3c7581db6f8214dbc633f18b8c39f5706df6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 10:06:12 -0400 Subject: [PATCH 5375/6505] Update update-lxcs.sh List containers that require a reboot --- misc/update-lxcs.sh | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 53fdd42c..1254b454 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -36,6 +36,21 @@ while read -r TAG ITEM; do EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF") done < <(pct list | awk 'NR>1') excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from updates:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + +function needs_reboot() { + local container=$1 + local os=$(pct config "$container" | awk '/^ostype/ {print $2}') + local reboot_required_file="/var/run/reboot-required.pkgs" + if [ -f "$reboot_required_file" ]; then + if [[ "$os" == "ubuntu" || "$os" == "debian" ]]; then + if pct exec "$container" -- [ -s "$reboot_required_file" ]; then + return 0 + fi + fi + fi + return 1 +} + function update_container() { container=$1 header_info @@ -55,6 +70,8 @@ function update_container() { ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; esac } + +containers_needing_reboot=() header_info for container in $(pct list | awk '{if(NR>1) print $1}'); do if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then @@ -75,8 +92,18 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do elif [ "$status" == "status: running" ]; then update_container $container fi + if pct exec "$container" -- [ -e "/var/run/reboot-required" ]; then + containers_needing_reboot+=("$container") + fi fi done wait header_info -echo -e "${GN} Finished, Selected Containers Updated. ${CL} \n" +echo -e "${GN}The process is complete, and the selected containers have been updated.${CL}\n" +if [ "${#containers_needing_reboot[@]}" -gt 0 ]; then + echo -e "${RD}The following containers require a reboot:${CL}" + for container_name in "${containers_needing_reboot[@]}"; do + echo "$container_name" + done +fi +echo "" From 61773ad6afa17e4c580b7587235054e3196d4eb2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 10:44:00 -0400 Subject: [PATCH 5376/6505] Update CHANGELOG.md - Proxmox VE LXC Updater --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0210c6a7..ba43fd68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-08 + +### Changed + +- **Proxmox VE LXC Updater** + - Now displays which containers require a reboot. + ## 2023-10-05 ### Changed From 3b4b021c9a6f489a819ca8c93407452a57f515b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 12:01:25 -0400 Subject: [PATCH 5377/6505] Update update-lxcs.sh display hostname of containers that require a reboot --- misc/update-lxcs.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 1254b454..e1b810da 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -93,7 +93,9 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do update_container $container fi if pct exec "$container" -- [ -e "/var/run/reboot-required" ]; then - containers_needing_reboot+=("$container") + # Get the container's hostname and add it to the list + container_hostname=$(pct exec "$container" hostname) + containers_needing_reboot+=("$container - $container_hostname") fi fi done From 1517bec1c3a21a9d401b0a0a4eb08ad08703e9bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 12:07:56 -0400 Subject: [PATCH 5378/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index e1b810da..9a48dc1f 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -95,7 +95,7 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do if pct exec "$container" -- [ -e "/var/run/reboot-required" ]; then # Get the container's hostname and add it to the list container_hostname=$(pct exec "$container" hostname) - containers_needing_reboot+=("$container - $container_hostname") + containers_needing_reboot+=("$container ($container_hostname)") fi fi done From 453a934c8f252bdb50ebd14c884ce02f36a0bcb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 15:08:30 -0400 Subject: [PATCH 5379/6505] Update kernel-clean.sh code refactoring --- misc/kernel-clean.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index d34a63af..7918ff81 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -38,24 +38,29 @@ function msg_ok() { } whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Clean" --yesno "This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed?" 10 68 || exit - if [ -z "$available_kernels" ]; then whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Old Kernels" --msgbox "It appears there are no old Kernels on your system. \nCurrent kernel ($current_kernel)." 10 68 - msg_info "Exiting" + echo "Exiting..." sleep 2 - msg_ok "Done" + clear exit fi - + KERNEL_MENU=() + MSG_MAX_LENGTH=0 while read -r TAG ITEM; do OFFSET=2 ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET - CTID_MENU+=("$TAG" "$ITEM " "OFF") + KERNEL_MENU+=("$TAG" "$ITEM " "OFF") done < <(echo "$available_kernels") -remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" \ - 16 $((MSG_MAX_LENGTH + 58)) 6 "${CTID_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit - +remove_kernels=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --checklist "\nSelect Kernels to remove:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${KERNEL_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$remove_kernels" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Kernel Selected" --msgbox "It appears that no Kernel was selected" 10 68 + echo "Exiting..." + sleep 2 + clear + exit +} whiptail --backtitle "Proxmox VE Helper Scripts" --title "Remove Kernels" --yesno "Would you like to remove the $(echo $remove_kernels | awk '{print NF}') previously selected Kernels?" 10 68 || exit msg_info "Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}" @@ -67,4 +72,4 @@ msg_info "Updating GRUB" msg_ok "Successfully Updated GRUB" msg_info "Exiting" sleep 2 -msg_ok "Done" +msg_ok "Finished" From 8bc37d93b7636ea408a1ae7653f023d3eadfe0c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 19:44:36 -0400 Subject: [PATCH 5380/6505] Delete misc/bluetooth.sh outdated --- misc/bluetooth.sh | 58 ----------------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 misc/bluetooth.sh diff --git a/misc/bluetooth.sh b/misc/bluetooth.sh deleted file mode 100644 index d3a3ca60..00000000 --- a/misc/bluetooth.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Run from the Proxmox Shell"; exit; fi -set -e -clear - -while true; do - read -p "Start the Bluetooth Integration Preparation (y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -clear - cat <<"EOF" - __ __ ___ _ __ __ - / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ - / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ - / __ )/ /_ _____ / /_____ ____ / /_/ /_ - / __ / / / / / _ \/ __/ __ \/ __ \/ __/ __ \ - / /_/ / / /_/ / __/ /_/ /_/ / /_/ / /_/ / / / - /_____/_/\__,_/\___/\__/\____/\____/\__/_/_/_/_ - / _/___ / /____ ____ __________ _/ /_(_)___ ____ - / // __ \/ __/ _ \/ __ `/ ___/ __ `/ __/ / __ \/ __ \ - _/ // / / / /_/ __/ /_/ / / / /_/ / /_/ / /_/ / / / / - /___/_/_/_/\__/\___/\__, /_/ \__,_/\__/_/\____/_/ /_/ - / __ \________/____/ ____ __________ _/ /_(_)___ ____ - / /_/ / ___/ _ \/ __ \/ __ `/ ___/ __ `/ __/ / __ \/ __ \ - / ____/ / / __/ /_/ / /_/ / / / /_/ / /_/ / /_/ / / / / - /_/ /_/ \___/ .___/\__,_/_/ \__,_/\__/_/\____/_/ /_/ - /_/ - -EOF -read -r -p "Switch from dbus-daemon to dbus-broker? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then -cat <>/etc/apt/sources.list -deb http://deb.debian.org/debian bullseye-backports main contrib non-free - -deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free -EOF -apt-get update &>/dev/null -apt-get -t bullseye-backports install -y dbus-broker &>/dev/null -systemctl enable dbus-broker.service &>/dev/null -fi -read -r -p "Install BlueZ? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then -apt-get -t bullseye-backports install -y bluez* &>/dev/null -fi -echo -e "Finished, reboot for changes to take affect" From 8b0f6b27fe74922614bd7607c82950f4aa6fe91f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 21:19:40 -0400 Subject: [PATCH 5381/6505] Update filebrowser.sh - Uninstall by re-executing the script - Option to use No Authentication --- misc/filebrowser.sh | 67 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index b4e40fd1..6a7325b4 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -6,13 +6,14 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { + clear cat <<"EOF" - _______ __ ____ + _______ __ ____ / ____(_) /__ / __ )_________ _ __________ _____ / /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/ - / __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ / -/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/ - + / __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ / +/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/ + EOF } IP=$(hostname -I | awk '{print $1}') @@ -28,24 +29,21 @@ HOLD="-" CM="${GN}✓${CL}" APP="FileBrowser" hostname="$(hostname)" -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} -clear header_info +if [ -f /root/filebrowser.db ]; then + read -r -p "Would you like to uninstall ${APP} on $hostname.? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + systemctl disable -q --now filebrowser.service + rm -rf /usr/local/bin/filebrowser /root/filebrowser.db /etc/systemd/system/filebrowser.service + echo "$APP Removed" + sleep 2 + clear + exit + else + clear + exit + fi +fi while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in @@ -54,7 +52,6 @@ while true; do *) echo "Please answer yes or no." ;; esac done -clear header_info function msg_info() { local msg="$1" @@ -66,17 +63,27 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +read -r -p "Would you like to use No Authentication? " prompt msg_info "Installing ${APP}" RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null -filebrowser config init -a '0.0.0.0' &>/dev/null -filebrowser config set -a '0.0.0.0' &>/dev/null -filebrowser users add admin changeme --perm.admin &>/dev/null + +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + filebrowser config init -a '0.0.0.0' &>/dev/null + filebrowser config set -a '0.0.0.0' &>/dev/null + filebrowser config init --auth.method=noauth &>/dev/null + filebrowser config set --auth.method=noauth &>/dev/null + filebrowser users add ID 1 --perm.admin &>/dev/null +else + filebrowser config init -a '0.0.0.0' &>/dev/null + filebrowser config set -a '0.0.0.0' &>/dev/null + filebrowser users add admin changeme --perm.admin &>/dev/null +fi msg_ok "Installed ${APP} on $hostname" msg_info "Creating Service" -service_path="/etc/systemd/system/filebrowser.service" -echo "[Unit] +cat </etc/systemd/system/filebrowser.service +[Unit] Description=Filebrowser After=network-online.target @@ -86,9 +93,9 @@ WorkingDirectory=/root/ ExecStart=/usr/local/bin/filebrowser -r / [Install] -WantedBy=default.target" >$service_path - -systemctl enable --now filebrowser.service &>/dev/null +WantedBy=default.target +EOF +systemctl enable -q --now filebrowser.service msg_ok "Created Service" msg_ok "Completed Successfully!\n" From b0c32c4e47c214890362b15f8c8b84e5d462cc1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 8 Oct 2023 21:22:58 -0400 Subject: [PATCH 5382/6505] Update CHANGELOG.md File Browser --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba43fd68..0282da4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ - **Proxmox VE LXC Updater** - Now displays which containers require a reboot. +- **File Browser** + - Uninstall by re-executing the script + - Option to use No Authentication ## 2023-10-05 From 36aff248875bd33f39fece44d1ca08904ca4438c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Oct 2023 10:38:24 -0400 Subject: [PATCH 5383/6505] Update CHANGELOG.md comment out stats --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0282da4f..16d280ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -

    + # Change Log **All notable changes to this project will be documented in this file.**
    From 6aeda1d4ff2bab2c6891fba42068e8ca4849edbe Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 9 Oct 2023 12:40:11 -0400 Subject: [PATCH 5384/6505] Update sabnzbd-install.sh fixes https://github.com/tteck/Proxmox/issues/1904 --- install/sabnzbd-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 6c97bd07..fb9690d3 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -19,9 +19,9 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y par2 $STD apt-get install -y p7zip-full -wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_6.0.3-1+deb11u1_amd64.deb -$STD dpkg -i unrar_6.0.3-1+deb11u1_amd64.deb -rm unrar_6.0.3-1+deb11u1_amd64.deb +wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_6.2.12-1_amd64.deb +$STD dpkg -i unrar_6.2.12-1_amd64.deb +rm unrar_6.2.12-1_amd64.deb msg_ok "Installed Dependencies" msg_info "Updating Python3" From 2d85b461bdfbcdaab4f7d4a129d89367b05645ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Oct 2023 14:39:33 -0400 Subject: [PATCH 5385/6505] Update scaling-governor.sh - A full code overhaul. - Include an option to configure a crontab for ensuring that the CPU Scaling Governor configuration persists across reboots. --- misc/scaling-governor.sh | 84 +++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 20138b08..74e1feeb 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -8,51 +8,45 @@ header_info() { clear cat < MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + GOVERNORS_MENU+=("$TAG" "$ITEM " "OFF") +done < <(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors | tr ' ' '\n' | grep -v "$current_governor") +scaling_governor=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current CPU Scaling Governor is set to $current_governor" --checklist "\nSelect the Scaling Governor to use:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${GOVERNORS_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +echo "${scaling_governor}" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor >/dev/null +current_governor=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) +whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Current CPU Scaling Governor" "\nCurrent CPU Scaling Governor has been set to $current_governor\n" 10 60 +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU Scaling Governor" --menu "This will establish a crontab to maintain the CPU Scaling Governor configuration across reboots.\n \nSetup a crontab?" 14 68 2 \ + "yes" " " \ + "no" " " 3>&2 2>&1 1>&3) + +case $CHOICE in + yes) + NEW_CRONTAB_COMMAND="(sleep 60 && echo \"$current_governor\" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor)" + EXISTING_CRONTAB=$(crontab -l 2>/dev/null) + if [[ -n "$EXISTING_CRONTAB" ]]; then + TEMP_CRONTAB_FILE=$(mktemp) + echo "$EXISTING_CRONTAB" | grep -v "@reboot (sleep 60 && echo*" > "$TEMP_CRONTAB_FILE" + crontab "$TEMP_CRONTAB_FILE" + rm "$TEMP_CRONTAB_FILE" fi - show_menu -done + (crontab -l 2>/dev/null; echo "@reboot $NEW_CRONTAB_COMMAND") | crontab - + echo -e "\nCrontab Set (use 'crontab -e' to check)" + ;; + no) + echo -e "\n\033[31mNOTE: Settings return to default after reboot\033[m\n" + ;; +esac +echo -e "Current CPU Scaling Governor is set to \033[36m$current_governor\033[m\n" From 30a8e9687887af557ac46a2d4fd225865f9954cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Oct 2023 14:42:56 -0400 Subject: [PATCH 5386/6505] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16d280ae..9a3121c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-11 + +### Changed + +- **Proxmox VE CPU Scaling Governor** + - A full code overhaul. + - Include an option to configure a crontab for ensuring that the CPU Scaling Governor configuration persists across reboots. + ## 2023-10-08 ### Changed From 11b941da4ef06dd10f73c1b965663c5fb1e4b2e9 Mon Sep 17 00:00:00 2001 From: leiweibau <105860611+leiweibau@users.noreply.github.com> Date: Wed, 11 Oct 2023 21:21:57 +0200 Subject: [PATCH 5387/6505] Update pialert-install.sh (#1909) Add UniFi dependency --- install/pialert-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 0a5d06cf..5f4f7a09 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -51,6 +51,7 @@ $STD apt-get -y install \ $STD pip3 install mac-vendor-lookup $STD pip3 install fritzconnection $STD pip3 install cryptography +$STD pip3 install pyunifi msg_ok "Installed Python Dependencies" msg_info "Installing Pi.Alert" From 3d3583488aa53af1fb637f4e1e62d2c385bd10a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 11 Oct 2023 15:31:27 -0400 Subject: [PATCH 5388/6505] Update scaling-governor.sh tweak --- misc/scaling-governor.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 74e1feeb..556a3854 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -4,7 +4,7 @@ # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE - +set -e header_info() { clear cat <&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$scaling_governor" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No CPU Scaling Governor Selected" --msgbox "It appears that no CPU Scaling Governor was selected" 10 68 + clear + exit +} echo "${scaling_governor}" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor >/dev/null current_governor=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Current CPU Scaling Governor" "\nCurrent CPU Scaling Governor has been set to $current_governor\n" 10 60 @@ -34,6 +39,7 @@ CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU Scaling G case $CHOICE in yes) + set +e NEW_CRONTAB_COMMAND="(sleep 60 && echo \"$current_governor\" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor)" EXISTING_CRONTAB=$(crontab -l 2>/dev/null) if [[ -n "$EXISTING_CRONTAB" ]]; then From 39c47b8d2380f260fe99a1de28cae09cf08814fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 Oct 2023 13:03:19 -0400 Subject: [PATCH 5389/6505] Update magicmirror.sh default Debian 12 --- ct/magicmirror.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index c3078bc3..4fde189e 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -24,7 +24,7 @@ var_disk="3" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From d6abb580d2e0fde1d58abfdf16659b9f1d3621b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 12 Oct 2023 13:04:26 -0400 Subject: [PATCH 5390/6505] Update magicmirror-install.sh fixes https://github.com/tteck/Proxmox/issues/1911 --- install/magicmirror-install.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/install/magicmirror-install.sh b/install/magicmirror-install.sh index 52d480b0..e2f5a054 100644 --- a/install/magicmirror-install.sh +++ b/install/magicmirror-install.sh @@ -18,13 +18,19 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y git +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +$STD apt-get update +$STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Setting up MagicMirror Repository" From 737240916ee8daab0e54ad2f45642ef3f89f46a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 Oct 2023 06:32:31 -0400 Subject: [PATCH 5391/6505] Update alpine-docker-install.sh Change Portainer port --- install/alpine-docker-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh index eacbe6b0..ac9a0f7e 100644 --- a/install/alpine-docker-install.sh +++ b/install/alpine-docker-install.sh @@ -39,7 +39,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then docker volume create portainer_data >/dev/null $STD docker run -d \ -p 8000:8000 \ - -p 9000:9000 \ + -p 9443:9443 \ --name=portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ @@ -59,4 +59,4 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then fi motd_ssh -customize \ No newline at end of file +customize From 359d5a3a48048ee7d8b0b9b51cd0033ca17e03d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 13 Oct 2023 12:13:31 -0400 Subject: [PATCH 5392/6505] Remove unused scripts - archlinux.sh - devuan.sh - devuan-install.sh --- ct/archlinux.sh | 418 -------------------------------------- ct/devuan.sh | 67 ------ install/devuan-install.sh | 28 --- 3 files changed, 513 deletions(-) delete mode 100644 ct/archlinux.sh delete mode 100644 ct/devuan.sh delete mode 100644 install/devuan-install.sh diff --git a/ct/archlinux.sh b/ct/archlinux.sh deleted file mode 100644 index 75e4119d..00000000 --- a/ct/archlinux.sh +++ /dev/null @@ -1,418 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ___ __ __ _ - / | __________/ /_ / / (_)___ __ ___ __ - / /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ - / ___ |/ / / /__/ / / / / /___/ / / / / /_/ /> < -/_/ |_/_/ \___/_/ /_/ /_____/_/_/ /_/\__,_/_/|_| - -EOF -} -header_info -echo -e "Loading..." -APP="Arch Linux" -var_disk="1" -var_cpu="1" -var_ram="512" -var_os="archlinux" -var_version="base" -NSAPP=$(echo ${APP,,} | tr -d ' ') -var_install="${NSAPP}-v5-install" -timezone=$(cat /etc/timezone) -INTEGER='^[0-9]+([.][0-9]+)?$' -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -set -Eeuo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" -} - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function PVE_CHECK() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" - echo -e "Exiting..." - sleep 2 - exit - fi -} -function ARCH_CHECK() { -if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${CROSS} This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 -exit -fi -} - -function default_settings() { - echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL} ${RD}NO DEVICE PASSTHROUGH${CL}" - CT_TYPE="1" - echo -e "${DGN}Using Root Password: ${BGN}archlinux${CL}" - PW="-password archlinux" - echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" - CT_ID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" - HN=$NSAPP - echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" - DISK_SIZE="$var_disk" - echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" - RAM_SIZE="$var_ram" - echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" - BRG="vmbr0" - echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - NET="dhcp" - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - GATE="" - echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" - DISABLEIP6="no" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - MTU="" - echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" - SD="" - echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}" - NS="" - echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" - MAC="" - echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" - VLAN="" - echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - SSH="no" - echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" - VERB="no" - echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function advanced_settings() { -if CT_TYPE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \ - "1" "Unprivileged" ON \ - "0" "Privileged" OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" -else - exit-script -fi - -if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW=" " - else - PW="-password $PW1" - fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" -else - exit-script -fi - -if CT_ID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then - if [ -z "$CT_ID" ]; then - CT_ID="$NEXTID" - echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}" - else - echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}" - fi -else - exit -fi - -if CT_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then - if [ -z "$CT_NAME" ]; then - HN="$NSAPP" - else - HN=$(echo ${CT_NAME,,} | tr -d ' ') - fi - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" -else - exit-script -fi - -if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then - if [ -z "$DISK_SIZE" ]; then - DISK_SIZE="$var_disk" - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - else - if ! [[ $DISK_SIZE =~ $INTEGER ]]; then - echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" - advanced_settings - fi - echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}" - fi -else - exit-script -fi - -if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then - if [ -z "$CORE_COUNT" ]; then - CORE_COUNT="$var_cpu" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi -else - exit-script -fi - -if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then - if [ -z "$RAM_SIZE" ]; then - RAM_SIZE="$var_ram" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi -else - exit-script -fi - -if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then - if [ -z "$BRG" ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi -else - exit-script -fi - -if NET=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $NET ]; then - NET="dhcp" - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - else - echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}" - fi -else - exit-script -fi -if GATE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3); then - if [ -z $GATE1 ]; then - GATE1="Default" - GATE="" - else - GATE=",gw=$GATE1" - fi - echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" -else - exit-script -fi - -if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then - DISABLEIP6="yes" -else - DISABLEIP6="no" -fi - echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}" - -if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - else - MTU=",mtu=$MTU1" - fi - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" -else - exit-script -fi - -if SD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then - if [ -z $SD ]; then - SX=Host - SD="" - else - SX=$SD - SD="-searchdomain=$SD" - fi - echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}" -else - exit-script -fi - -if NX=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then - if [ -z $NX ]; then - NX=Host - NS="" - else - NS="-nameserver=$NX" - fi - echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}" -else - exit-script -fi - -if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC1="Default" - MAC="" - else - MAC=",hwaddr=$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi -else - exit-script -fi - -if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - else - VLAN=",tag=$VLAN1" - fi - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" -else - exit-script -fi - -if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then - SSH="yes" -else - SSH="no" -fi - echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" - -if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then - VERB="yes" -else - VERB="no" -fi - echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}" - -if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then - echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" -else - clear - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings -fi -} - -function install_script() { -ARCH_CHECK -PVE_CHECK -NEXTID=$(pvesh get /cluster/nextid) -header_info - if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function update_script() { -header_info -msg_info "Updating ${APP} LXC" -pacman-key --init -pacman-key --populate archlinux -pacman -Sy archlinux-keyring && pacman -Su -msg_ok "Updated Successfully" -exit -} - -if command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - install_script -fi - -if ! command -v pveversion >/dev/null 2>&1; then - if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then - clear - echo -e "⚠ User exited script \n" - exit - fi - update_script -fi - -if [ "$VERB" == "yes" ]; then set -x; fi -if [ "$CT_TYPE" == "1" ]; then - FEATURES="nesting=1,keyctl=1" -else - FEATURES="nesting=1" -fi -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -export tz=$timezone -export DISABLEIPV6=$DISABLEIP6 -export APPLICATION=$APP -export VERBOSE=$VERB -export SSH_ROOT=${SSH} -export CTID=$CT_ID -export PCT_OSTYPE=$var_os -export PCT_OSVERSION=$var_version -export PCT_DISK_SIZE=$DISK_SIZE -export PCT_OPTIONS=" - -features $FEATURES - -hostname $HN - $SD - $NS - -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU - -onboot 1 - -cores $CORE_COUNT - -memory $RAM_SIZE - -unprivileged $CT_TYPE - $PW -" -bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit -msg_info "Starting LXC Container" -pct start $CTID -msg_ok "Started LXC Container" -IP=$(pct exec $CTID ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -pct set $CTID -description "# ${APP} ${var_version} LXC -### https://tteck.github.io/Proxmox/ -" -msg_ok "Completed Successfully!\n" diff --git a/ct/devuan.sh b/ct/devuan.sh deleted file mode 100644 index 25bdc96f..00000000 --- a/ct/devuan.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ____ - / __ \___ _ ____ ______ ____ - / / / / _ \ | / / / / / __ `/ __ \ - / /_/ / __/ |/ / /_/ / /_/ / / / / -/_____/\___/|___/\__,_/\__,_/_/ /_/ - -EOF -} -header_info -echo -e "Loading..." -APP="Devuan" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="devuan" -var_version="4.0" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET="dhcp" - GATE="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { -header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" diff --git a/install/devuan-install.sh b/install/devuan-install.sh deleted file mode 100644 index 64e6f242..00000000 --- a/install/devuan-install.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" From be4d28c1417105ccba825943933ab47804ce1cef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Oct 2023 09:58:39 -0400 Subject: [PATCH 5393/6505] Update monitor-all.sh - disable start delay - fixes https://github.com/tteck/Proxmox/issues/1919 --- misc/monitor-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index f7e74dcf..0067ca90 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -103,7 +103,7 @@ Type=simple # For example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 # Virtual machines without the QEMU guest agent installed must be excluded. # Sleep for 300 seconds (5 minutes) -ExecStartPre=/usr/bin/sleep 300 +# ExecStartPre=/usr/bin/sleep 300 ExecStart=/usr/local/bin/ping-instances.sh Restart=always StandardOutput=file:/var/log/ping-instances.log From 7724546b6f3fac39f3231a9c8a029e3b75cd4747 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Oct 2023 12:31:06 -0400 Subject: [PATCH 5394/6505] Update monitor-all.sh code refactoring --- misc/monitor-all.sh | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index 0067ca90..b5567b8e 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -88,43 +88,54 @@ while true; do # Wait for 5 minutes. (Edit to your needs) echo "$(date): Pausing for 5 minutes..." sleep 300 -done >> /var/log/ping-instances.log 2>&1' >/usr/local/bin/ping-instances.sh - +done >/var/log/ping-instances.log 2>&1' >/usr/local/bin/ping-instances.sh +touch /var/log/ping-instances.log # Change file permissions to executable chmod +x /usr/local/bin/ping-instances.sh +cat </etc/systemd/system/ping-instances.timer +[Unit] +Description=Delay ping-instances.service by 5 minutes + +[Timer] +OnBootSec=300 +OnUnitActiveSec=300 + +[Install] +WantedBy=timers.target +EOF # Create ping-instances.service -echo '[Unit] +cat </etc/systemd/system/ping-instances.service +[Unit] Description=Ping instances every 5 minutes and restarts if necessary - +After=ping-instances.timer +Requires=ping-instances.timer [Service] Type=simple # To specify which CT/VM should be excluded, add the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified. # For example: ExecStart=/usr/local/bin/ping-instances.sh 100 102 # Virtual machines without the QEMU guest agent installed must be excluded. -# Sleep for 300 seconds (5 minutes) -# ExecStartPre=/usr/bin/sleep 300 + ExecStart=/usr/local/bin/ping-instances.sh -Restart=always StandardOutput=file:/var/log/ping-instances.log StandardError=file:/var/log/ping-instances.log [Install] -WantedBy=multi-user.target' >/etc/systemd/system/ping-instances.service +WantedBy=multi-user.target +EOF # Reload daemon, enable and start ping-instances.service systemctl daemon-reload +systemctl enable -q --now ping-instances.timer systemctl enable -q --now ping-instances.service clear echo -e "\n To view Monitor All logs: cat /var/log/ping-instances.log" } remove() { - systemctl stop ping-instances.service - systemctl disable ping-instances.service &>/dev/null - rm /etc/systemd/system/ping-instances.service - rm /usr/local/bin/ping-instances.sh - rm /var/log/ping-instances.log + systemctl disable -q --now ping-instances.timer + systemctl disable -q --now ping-instances.service + rm /etc/systemd/system/ping-instances.service /etc/systemd/system/ping-instances.timer /usr/local/bin/ping-instances.sh /var/log/ping-instances.log echo "Removed Monitor All from Proxmox VE" } From 85b0003df959634982e26dc2986343b29165ce37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Oct 2023 12:45:48 -0400 Subject: [PATCH 5395/6505] Update monitor-all.sh tweak --- misc/monitor-all.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index b5567b8e..e4251757 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -117,6 +117,7 @@ Type=simple # Virtual machines without the QEMU guest agent installed must be excluded. ExecStart=/usr/local/bin/ping-instances.sh +Restart=always StandardOutput=file:/var/log/ping-instances.log StandardError=file:/var/log/ping-instances.log From c79153f4a6645bd4f39985069fc4b629a9d129ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Oct 2023 19:56:28 -0400 Subject: [PATCH 5396/6505] Update meshcentral.sh default Debian 12 --- ct/meshcentral.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 03b3efd2..ff75e93d 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 34414e6266feea6488ebc91422dccd0583133888 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Oct 2023 19:57:25 -0400 Subject: [PATCH 5397/6505] Update meshcentral-install.sh fixes https://github.com/tteck/Proxmox/issues/1923 --- install/meshcentral-install.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh index ec191bdc..1cd0b903 100644 --- a/install/meshcentral-install.sh +++ b/install/meshcentral-install.sh @@ -17,13 +17,19 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +$STD apt-get update +$STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Installing MeshCentral" From 89c3dfd206642242d658eb5e6bc4365ced0e2a30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Oct 2023 20:18:46 -0400 Subject: [PATCH 5398/6505] Update sonarr-install.sh - add an option to install v4 (experimental) --- install/sonarr-install.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index e2857b87..78f96594 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -21,11 +21,22 @@ $STD apt-get install -y gnupg $STD apt-get install -y ca-certificates msg_ok "Installed Dependencies" +read -r -p "Would you like to install v4 (experimental)? " prompt msg_info "Installing Sonarr" wget -qO /etc/apt/trusted.gpg.d/sonarr-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2009837cbffd68f45bc180471f4f90de2a9b4bf8" echo "deb https://apt.sonarr.tv/debian testing-main main" >/etc/apt/sources.list.d/sonarr.list $STD apt-get update DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy sonarr &>/dev/null +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + systemctl stop sonarr.service + wget -q https://download.sonarr.tv/v4/develop/4.0.0.697/Sonarr.develop.4.0.0.697.linux-x64.tar.gz + tar -xzf Sonarr.develop.4.0.0.697.linux-x64.tar.gz + cp -r Sonarr/* /usr/lib/sonarr/bin + rm -rf Sonarr Sonarr.develop.4.0.0.697.linux-x64.tar.gz + sed -i 's|ExecStart=/usr/bin/mono --debug /usr/lib/sonarr/bin/Sonarr.exe -nobrowser -data=/var/lib/sonarr|ExecStart=/usr/lib/sonarr/bin/Sonarr -nobrowser -data=/var/lib/sonarr|' /lib/systemd/system/sonarr.service + systemctl daemon-reload + systemctl start sonarr.service +fi msg_ok "Installed Sonarr" motd_ssh From 4d2343607b21922043a67ae9c53a881ae31978e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 14 Oct 2023 20:21:58 -0400 Subject: [PATCH 5399/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3121c4..5eff2168 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-14 + +### Changed + +- **Sonarr LXC** + - Include an option to install v4 (experimental) + ## 2023-10-11 ### Changed From 8014a410f5dd6a869a440b7b392c836d1adb480b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Oct 2023 01:15:09 -0400 Subject: [PATCH 5400/6505] Create tasmoadmin.sh --- ct/tasmoadmin.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/tasmoadmin.sh diff --git a/ct/tasmoadmin.sh b/ct/tasmoadmin.sh new file mode 100644 index 00000000..7287ed1a --- /dev/null +++ b/ct/tasmoadmin.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ ___ __ _ + /_ __/___ __________ ___ ____ / | ____/ /___ ___ (_)___ + / / / __ `/ ___/ __ `__ \/ __ \/ /| |/ __ / __ `__ \/ / __ \ + / / / /_/ (__ ) / / / / / /_/ / ___ / /_/ / / / / / / / / / / +/_/ \__,_/____/_/ /_/ /_/\____/_/ |_\__,_/_/ /_/ /_/_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="TasmoAdmin" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:9999${CL} \n" From fa21400a98b7aa80cd82964483de7685922f5515 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Oct 2023 01:16:41 -0400 Subject: [PATCH 5401/6505] Create tasmoadmin-install.sh --- install/tasmoadmin-install.sh | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 install/tasmoadmin-install.sh diff --git a/install/tasmoadmin-install.sh b/install/tasmoadmin-install.sh new file mode 100644 index 00000000..0b65b9ce --- /dev/null +++ b/install/tasmoadmin-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y apache2 +$STD apt-get install -y php8.2 +$STD apt-get install -y libapache2-mod-php +$STD apt-get install -y php8.2-curl +$STD apt-get install -y php8.2-zip +$STD apt-get install -y php8.2-mbstring +$STD apt-get install -y php8.2-xml +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Installing TasmoAdmin" +wget -q https://github.com/TasmoAdmin/TasmoAdmin/releases/download/v3.1.1/tasmoadmin_v3.1.1.tar.gz +tar -xzf tasmoadmin_v3.1.1.tar.gz -C /var/www/ +rm -rf tasmoadmin_v3.1.1.tar.gz /etc/php/8.2/apache2/conf.d/10-opcache.ini +chown -R www-data:www-data /var/www/tasmoadmin +chmod 777 /var/www/tasmoadmin/tmp /var/www/tasmoadmin/data +cat </etc/apache2/sites-available/tasmoadmin.conf + + ServerName tasmoadmin + ServerAdmin webmaster@localhost + DocumentRoot /var/www/tasmoadmin + + AllowOverride All + Order allow,deny + allow from all + + ErrorLog /var/log/apache2/error.log + LogLevel warn + CustomLog /var/log/apache2/access.log combined + ServerSignature On + +EOF +sed -i '6iListen 9999' /etc/apache2/ports.conf +$STD a2ensite tasmoadmin +$STD a2enmod rewrite +systemctl reload apache2 +systemctl restart apache2 +msg_ok "Installed TasmoAdmin" +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 937695b3b894e65d976197075b86307a96fe809b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Oct 2023 01:43:25 -0400 Subject: [PATCH 5402/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eff2168..9123a5b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-15 + +### Changed + +- **TasmoAdmin LXC** + - NEW Script + ## 2023-10-14 ### Changed From e71b8cd2de575a76c77a4252f0d5535253f5e100 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Oct 2023 07:27:56 -0400 Subject: [PATCH 5403/6505] Update openwrt.sh fixes https://github.com/tteck/Proxmox/issues/1924 --- vm/openwrt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 9c511e37..b9bc088e 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -431,8 +431,8 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for OpenWrt Disk Image" -regex='Current Stable Release - OpenWrt ([^/]*)<\/strong>' && response=$(curl -s https://openwrt.org) && [[ $response =~ $regex ]] && stableVersion="${BASH_REMATCH[1]}" -URL=https://downloads.openwrt.org/releases/$stableVersion/targets/x86/64/openwrt-$stableVersion-x86-64-generic-ext4-combined.img.gz +# regex='Current Stable Release - OpenWrt ([^/]*)<\/strong>' && response=$(curl -s https://openwrt.org) && [[ $response =~ $regex ]] && stableVersion="${BASH_REMATCH[1]}" +URL=https://downloads.openwrt.org/releases/23.05.0/targets/x86/64/openwrt-23.05.0-x86-64-generic-ext4-combined.img.gz sleep 2 msg_ok "${CL}${BL}${URL}${CL}" From 7a58b8c01c5d8fe8d20d8e6def18346ed8faf99f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Oct 2023 08:43:44 -0400 Subject: [PATCH 5404/6505] Update openwrt.sh fix stableversion variable --- vm/openwrt.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index b9bc088e..5f9d6fcc 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -431,8 +431,9 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for OpenWrt Disk Image" -# regex='Current Stable Release - OpenWrt ([^/]*)<\/strong>' && response=$(curl -s https://openwrt.org) && [[ $response =~ $regex ]] && stableVersion="${BASH_REMATCH[1]}" -URL=https://downloads.openwrt.org/releases/23.05.0/targets/x86/64/openwrt-23.05.0-x86-64-generic-ext4-combined.img.gz +response=$(curl -s https://openwrt.org) +stableversion=$(echo "$response" | sed -n 's/.*Current stable release - OpenWrt \([0-9.]\+\).*/\1/p') +URL="https://downloads.openwrt.org/releases/$stableversion/targets/x86/64/openwrt-$stableversion-x86-64-generic-ext4-combined.img.gz" sleep 2 msg_ok "${CL}${BL}${URL}${CL}" From e95a7bf9fbcb88701189bd250930b4436092c6bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 15 Oct 2023 11:19:54 -0400 Subject: [PATCH 5405/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 75878301..4c975369 100644 --- a/misc/build.func +++ b/misc/build.func @@ -435,7 +435,7 @@ install_script() { arch_check pve_check if systemctl is-active -q ping-instances.service; then - systemctl stop ping-instances.service + systemctl -q stop ping-instances.service fi NEXTID=$(pvesh get /cluster/nextid) timezone=$(cat /etc/timezone) From 1c0f43fb91782fc8ccab57811b6fd55bde17bb11 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 17 Oct 2023 18:55:25 -0400 Subject: [PATCH 5406/6505] Update sonarr-install.sh change User/Group to root --- install/sonarr-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index 78f96594..c183454a 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -34,6 +34,7 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then cp -r Sonarr/* /usr/lib/sonarr/bin rm -rf Sonarr Sonarr.develop.4.0.0.697.linux-x64.tar.gz sed -i 's|ExecStart=/usr/bin/mono --debug /usr/lib/sonarr/bin/Sonarr.exe -nobrowser -data=/var/lib/sonarr|ExecStart=/usr/lib/sonarr/bin/Sonarr -nobrowser -data=/var/lib/sonarr|' /lib/systemd/system/sonarr.service + sed -i 's/\(User=\|Group=\).*/\1root/' /lib/systemd/system/sonarr.service systemctl daemon-reload systemctl start sonarr.service fi From a901f2a06547e5a74cb795485650866e435357ed Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:06:28 +1300 Subject: [PATCH 5407/6505] Update haos-vm.sh (#1940) Dev OS builds have been moved to a new server --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 27dcb8ce..d535b99a 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -386,7 +386,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image" if [ "$BRANCH" == "$dev" ]; then - URL=https://os-builds.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz + URL=https://os-artifacts.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz else URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz fi From b2fc242e68d6a765f5885f02e2818f211f8351eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 Oct 2023 04:36:55 -0400 Subject: [PATCH 5408/6505] Update mqtt.sh set new file path check --- ct/mqtt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 79273287..7c8fa42e 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -52,7 +52,7 @@ function default_settings() { function update_script() { header_info -if [[ ! -f /etc/apt/sources.list.d/mosquitto-bullseye.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -f /etc/mosquitto/conf.d/default.conf ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null From 3d54b1dfbbc8ba3ee0f6bddd8d996e5cb1b3826b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 19 Oct 2023 08:08:46 -0400 Subject: [PATCH 5409/6505] Update pialert.sh fix update --- ct/pialert.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pialert.sh b/ct/pialert.sh index 17a1195b..967b5043 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -53,7 +53,7 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/pialert ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -update +bash -c "$(wget -qLO - https://github.com/leiweibau/Pi.Alert/raw/main/install/pialert_update.sh)" -s --lxc msg_ok "Updated $APP" exit } From 108c4e1a14de47c73f306457dc274db56645800d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Oct 2023 05:32:58 -0400 Subject: [PATCH 5410/6505] Update unifi-install.sh tweak --- install/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 4ce0e417..c0d1c823 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -48,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf mongodb-org-server_3.6.23_amd64.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +rm -rf mongodb-org-server_3.6.23_amd64.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb /etc/apt/sources.list.d/openjdk-11-jre-headless.list $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 8e5760af2865b7ff0338bb101414c709fc75f57a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Oct 2023 13:17:43 -0400 Subject: [PATCH 5411/6505] Update influxdb.sh - default Debian 12 - set new file path check --- ct/influxdb.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 3c7bda46..8f3216d6 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors @@ -52,12 +52,8 @@ function default_settings() { function update_script() { header_info -if [[ ! -f /etc/apt/sources.list.d/influxdb.list || ! -f /etc/apt/sources.list.d/influxdata.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -f /etc/apt/sources.list.d/influxdata.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" -wget -q https://repos.influxdata.com/influxdata-archive_compat.key -cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null -echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | tee /etc/apt/sources.list.d/influxdata.list -rm -f /etc/apt/trusted.gpg.d/influxdb.gpg apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated Successfully" From abd627f93b1c0e24b54d06e899e01e5793ce7910 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 20 Oct 2023 21:33:14 -0400 Subject: [PATCH 5412/6505] Create hw-acceleration.sh --- misc/hw-acceleration.sh | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 misc/hw-acceleration.sh diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh new file mode 100644 index 00000000..2bc78f13 --- /dev/null +++ b/misc/hw-acceleration.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +set -eEuo pipefail +function header_info { + clear + cat <<"EOF" + + __ ___ __ ___ __ __ _ + / // / | /| / / / _ |___________ / /__ _______ _/ /_(_)__ ___ + / _ /| |/ |/ / / __ / __/ __/ -_) / -_) __/ _ `/ __/ / _ \/ _ \ +/_//_/ |__/|__/ /_/ |_\__/\__/\__/_/\__/_/ \_,_/\__/_/\___/_//_/ + +EOF +} +header_info +echo "Loading..." +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Add HW Acceleration" --yesno "This Will Add HW Acceleration to an exixting LXC Container. Proceed?" 10 68 || exit +NODE=$(hostname) +PREV_MENU=() +MSG_MAX_LENGTH=0 +privileged_containers=$(pct list | awk 'NR>1 && system("grep -q \047unprivileged: 1\047 /etc/pve/lxc/" $1 ".conf")') +if [ -z "$privileged_containers" ]; then + whiptail --msgbox "No Privileged Containers Found." 10 58 + exit +fi +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + PREV_MENU+=("$TAG" "$ITEM " "OFF") +done < <(echo "$privileged_containers") +privileged_container=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Privileged Containers on $NODE" --checklist "\nSelect a Container To Add HW Acceleration:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${PREV_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +header_info +cat <>/etc/pve/lxc/${privileged_container}.conf +lxc.cgroup2.devices.allow: c 226:0 rwm +lxc.cgroup2.devices.allow: c 226:128 rwm +lxc.cgroup2.devices.allow: c 29:0 rwm +lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file +lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir +lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file +EOF +pct exec $privileged_container -- bash -c "apt-get -y install va-driver-all && apt-get -y install ocl-icd-libopencl1 && apt-get install -y intel-opencl-icd && chgrp video /dev/dri && chmod 755 /dev/dri && chmod 660 /dev/dri/*" +header_info +echo -e "Completed Successfully!\n" +echo -e "Reboot container $privileged_container to apply the new settings\n" From f3c8d3c774f91336290dacb18e1328cf4ee6985b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 09:52:23 -0400 Subject: [PATCH 5413/6505] Update nocodb-install.sh - full code overhaul --- install/nocodb-install.sh | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh index 509bd282..aaa3b55d 100644 --- a/install/nocodb-install.sh +++ b/install/nocodb-install.sh @@ -17,25 +17,13 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y git -$STD apt-get install -y make -$STD apt-get install -y g++ -$STD apt-get install -y gcc msg_ok "Installed Dependencies" -msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node -ln -sf /root/.nvm/versions/node/v16.20.1/bin/npm /usr/bin/npm -msg_ok "Installed Node.js" - msg_info "Installing NocoDB" -$STD git clone https://github.com/nocodb/nocodb-seed -mv nocodb-seed /opt/nocodb +mkdir -p /opt/nocodb cd /opt/nocodb -$STD npm install +curl -s http://get.nocodb.com/linux-x64 -o nocodb -L +chmod +x nocodb msg_ok "Installed NocoDB" msg_info "Creating Service" @@ -48,11 +36,11 @@ Type=simple Restart=always User=root WorkingDirectory=/opt/nocodb -ExecStart=/usr/bin/npm start +ExecStart=/opt/nocodb/./nocodb [Install] WantedBy=multi-user.target" >$service_path -systemctl enable --now nocodb.service &>/dev/null +systemctl enable -q --now nocodb.service &>/dev/null msg_ok "Created Service" motd_ssh From 1e62c159f1bd4f5117d815ba60f84c812666986a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 09:54:09 -0400 Subject: [PATCH 5414/6505] Update nocodb.sh - default Debian 12 - new update path --- ct/nocodb.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 3c400a1e..b46ee722 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors @@ -54,10 +54,12 @@ function update_script() { header_info if [[ ! -f /etc/systemd/system/nocodb.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" +systemctl stop nocodb.service cd /opt/nocodb -npm uninstall -s --save nocodb &>/dev/null -npm install -s --save nocodb &>/dev/null -systemctl restart nocodb.service +rm nocodb +curl -s http://get.nocodb.com/linux-x64 -o nocodb -L +chmod +x nocodb +systemctl start nocodb.service msg_ok "Updated Successfully" exit } From 85cc309f8b7d28c6883320fd18b0f551a66e8336 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 11:00:50 -0400 Subject: [PATCH 5415/6505] Update nocodb.sh test --- ct/nocodb.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index b46ee722..efb2eb76 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -56,9 +56,24 @@ if [[ ! -f /etc/systemd/system/nocodb.service ]]; then msg_error "No ${APP} Inst msg_info "Updating ${APP}" systemctl stop nocodb.service cd /opt/nocodb -rm nocodb +rm -rf nocodb curl -s http://get.nocodb.com/linux-x64 -o nocodb -L chmod +x nocodb +cat </etc/systemd/system/nocodb.service" +echo "[Unit] +Description=nocodb + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/nocodb +ExecStart=/opt/nocodb/./nocodb + +[Install] +WantedBy=multi-user.target +EOF +systemctl daemon-reload systemctl start nocodb.service msg_ok "Updated Successfully" exit From a017ba7c000554923ddafa695f427352afefa070 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 11:15:54 -0400 Subject: [PATCH 5416/6505] Update nocodb.sh tweak --- ct/nocodb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index efb2eb76..cd0f1295 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -60,7 +60,7 @@ rm -rf nocodb curl -s http://get.nocodb.com/linux-x64 -o nocodb -L chmod +x nocodb cat </etc/systemd/system/nocodb.service" -echo "[Unit] +echo [Unit] Description=nocodb [Service] From 537a855553a045379ad8ac65b492bc62ebc4b362 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 11:17:56 -0400 Subject: [PATCH 5417/6505] Update nocodb.sh --- ct/nocodb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index cd0f1295..4ac7fea0 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -60,7 +60,7 @@ rm -rf nocodb curl -s http://get.nocodb.com/linux-x64 -o nocodb -L chmod +x nocodb cat </etc/systemd/system/nocodb.service" -echo [Unit] +[Unit] Description=nocodb [Service] From b81028fb3bde93724772719ee7259e89a3aa4efd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 11:48:25 -0400 Subject: [PATCH 5418/6505] Update nocodb.sh tweak --- ct/nocodb.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 4ac7fea0..018a06b2 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -59,8 +59,8 @@ cd /opt/nocodb rm -rf nocodb curl -s http://get.nocodb.com/linux-x64 -o nocodb -L chmod +x nocodb -cat </etc/systemd/system/nocodb.service" -[Unit] +service_path="/etc/systemd/system/nocodb.service" +echo "[Unit] Description=nocodb [Service] @@ -71,8 +71,7 @@ WorkingDirectory=/opt/nocodb ExecStart=/opt/nocodb/./nocodb [Install] -WantedBy=multi-user.target -EOF +WantedBy=multi-user.target" >$service_path systemctl daemon-reload systemctl start nocodb.service msg_ok "Updated Successfully" From f2e58ac26e7b9b1567026b0e6c23b9d3384c2740 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 11:53:44 -0400 Subject: [PATCH 5419/6505] Update nocodb.sh --- ct/nocodb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 018a06b2..26da3998 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -73,7 +73,7 @@ ExecStart=/opt/nocodb/./nocodb [Install] WantedBy=multi-user.target" >$service_path systemctl daemon-reload -systemctl start nocodb.service +systemctl start -q nocodb.service msg_ok "Updated Successfully" exit } From f2a7a1699d1ff8f4872803f5f907fa70b51751b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 11:59:21 -0400 Subject: [PATCH 5420/6505] Update nocodb.sh --- ct/nocodb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 26da3998..0a1739f6 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -72,7 +72,7 @@ ExecStart=/opt/nocodb/./nocodb [Install] WantedBy=multi-user.target" >$service_path -systemctl daemon-reload +systemctl -q daemon-reload systemctl start -q nocodb.service msg_ok "Updated Successfully" exit From 8e6f0c185cf24916ab2e4606a46a5cb204899b2b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 21 Oct 2023 12:16:58 -0400 Subject: [PATCH 5421/6505] Update nocodb.sh revert test --- ct/nocodb.sh | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 0a1739f6..b25c2175 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -59,21 +59,7 @@ cd /opt/nocodb rm -rf nocodb curl -s http://get.nocodb.com/linux-x64 -o nocodb -L chmod +x nocodb -service_path="/etc/systemd/system/nocodb.service" -echo "[Unit] -Description=nocodb - -[Service] -Type=simple -Restart=always -User=root -WorkingDirectory=/opt/nocodb -ExecStart=/opt/nocodb/./nocodb - -[Install] -WantedBy=multi-user.target" >$service_path -systemctl -q daemon-reload -systemctl start -q nocodb.service +systemctl start nocodb.service msg_ok "Updated Successfully" exit } From 1c402475fdb1b83f19ad4761671bbc47c33de599 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 22 Oct 2023 16:52:21 -0400 Subject: [PATCH 5422/6505] Add files via upload --- misc/images/tteck.png | Bin 0 -> 52328 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/tteck.png diff --git a/misc/images/tteck.png b/misc/images/tteck.png new file mode 100644 index 0000000000000000000000000000000000000000..91d872b40039592f203fed4b21567b2dba6d038d GIT binary patch literal 52328 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 literal 0 HcmV?d00001 From f3ab218d2fa20ada361e637c18d265d73850e754 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 22 Oct 2023 18:09:16 -0400 Subject: [PATCH 5423/6505] Add files via upload --- misc/images/newtteck.png | Bin 0 -> 57853 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/newtteck.png diff --git a/misc/images/newtteck.png b/misc/images/newtteck.png new file mode 100644 index 0000000000000000000000000000000000000000..fa59dd85a347a0a076a39ef4e4c5ae40b3da19fc GIT binary patch literal 57853 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 Date: Sun, 22 Oct 2023 19:16:24 -0400 Subject: [PATCH 5424/6505] remove unused images --- misc/images/newtteck.png | Bin 57853 -> 0 bytes misc/images/tteck.png | Bin 52328 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/newtteck.png delete mode 100644 misc/images/tteck.png diff --git a/misc/images/newtteck.png b/misc/images/newtteck.png deleted file mode 100644 index fa59dd85a347a0a076a39ef4e4c5ae40b3da19fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57853 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 From b848920c6a38f4f9a981ff476af65033b2e73843 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 24 Oct 2023 23:05:44 -0400 Subject: [PATCH 5425/6505] Update changedetection.sh default Debian 12 --- ct/changedetection.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 8f938dd5..c625e67c 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 7c527fa385a6207dd306215483e604ccac5e926e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 26 Oct 2023 14:36:36 -0400 Subject: [PATCH 5426/6505] Update omada-install.sh fixes https://github.com/tteck/Proxmox/issues/1963 --- install/omada-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index 79a35359..3bc337ab 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -30,8 +30,8 @@ $STD apt-get -y install zulu8-jdk msg_ok "Installed Azul Zulu" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" @@ -48,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_${latest_version}_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +rm -rf Omada_SDN_Controller_${latest_version}_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From d45f386407e0a748ffd495c5848c91abcfb21120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Iskrzy=C5=84ski?= Date: Fri, 27 Oct 2023 00:36:18 +0200 Subject: [PATCH 5427/6505] libssl version update (#1965) update libssl version --- install/deconz-install.sh | 6 +++--- install/unifi-install.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/install/deconz-install.sh b/install/deconz-install.sh index 54631139..5611b7cc 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -26,8 +26,8 @@ echo "deb [arch=amd64] http://phoscon.de/apt/deconz $VERSION main" >/etc/apt/sou msg_ok "Setup Phoscon Repository" msg_info "Installing deConz" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb $STD apt-get update $STD apt-get install -y deconz msg_ok "Installed deConz" @@ -56,7 +56,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +rm -rf libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" diff --git a/install/unifi-install.sh b/install/unifi-install.sh index c0d1c823..d65d2f2f 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -31,8 +31,8 @@ $STD apt-mark hold openjdk-11-* msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" @@ -48,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf mongodb-org-server_3.6.23_amd64.deb libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb /etc/apt/sources.list.d/openjdk-11-jre-headless.list +rm -rf mongodb-org-server_3.6.23_amd64.deb libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb /etc/apt/sources.list.d/openjdk-11-jre-headless.list $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From b5c28fd921353561acd9b000b3758e0afe1bfd94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Oct 2023 12:21:36 -0400 Subject: [PATCH 5428/6505] Update webmin.sh A full code overhaul. --- misc/webmin.sh | 75 +++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/misc/webmin.sh b/misc/webmin.sh index b4375267..881de91a 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -5,40 +5,57 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -YW=$(echo "\033[33m") -RD=$(echo "\033[01;31m") -BL=$(echo "\033[36m") -CM='\xE2\x9C\x94\033' -GN=$(echo "\033[1;92m") -CL=$(echo "\033[m") -while true; do - read -p "This will Install Webmin, Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear +function header_info { + clear + cat <<"EOF" + _ __ __ _ + | | /| / /__ / / __ _ (_)__ + | |/ |/ / -_) _ \/ ' \/ / _ \ + |__/|__/\__/_.__/_/_/_/_/_//_/ -echo -en "${GN} Installing Prerequisites... " +EOF +} +set -eEuo pipefail +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +CM="${GN}✓${CL}" +BFR="\\r\\033[K" +HOLD="-" + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +header_info + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Webmin Installer" --yesno "This Will Install Webmin on this LXC Container. Proceed?" 10 58 || exit + +msg_info "Installing Prerequisites" apt update &>/dev/null apt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null -echo -e "${CM}${CL} \r" +msg_ok "Installed Prerequisites" -echo -en "${GN} Downloading Webmin... " -wget http://prdownloads.sourceforge.net/webadmin/webmin_2.021_all.deb &>/dev/null -echo -e "${CM}${CL} \r" +LATEST=$(curl -sL https://api.github.com/repos/webmin/webmin/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -echo -en "${GN} Installing Webmin... " -dpkg --install webmin_2.021_all.deb &>/dev/null -echo -e "${CM}${CL} \r" +msg_info "Downloading Webmin" +wget -q https://github.com/webmin/webmin/releases/download/$LATEST/webmin_${LATEST}_all.deb +msg_ok "Downloaded Webmin" -echo -en "${GN} Setting Default Webmin usermame & password to root... " +msg_info "Installing Webmin" +dpkg -i webmin_${LATEST}_all.deb &>/dev/null /usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null -rm -rf /root/webmin_2.021_all.deb -echo -e "${CM}${CL} \r" -IP=$(hostname -I | cut -f1 -d ' ') -echo -e "Successfully Installed!! Webmin should be reachable by going to https://${IP}:10000" +rm -rf /root/webmin_${LATEST}_all.deb +msg_ok "Installed Webmin" -# bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/webmin.sh)" +IP=$(hostname -I | cut -f1 -d ' ') +echo -e "Successfully Installed!! Webmin should be reachable by going to ${BL}https://${IP}:10000${CL}" From b7747c2b076d75415489ed7c8e522cd921b9d9d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 27 Oct 2023 12:28:17 -0400 Subject: [PATCH 5429/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9123a5b3..d3a77f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-27 + +### Changed + +- **Webmin** + - A full code overhaul. + ## 2023-10-15 ### Changed From 52b0fd8f694c26167454c7c7efb0f9fedbc66fb7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Oct 2023 06:54:37 -0400 Subject: [PATCH 5430/6505] Update deluge-install.sh make Debian 12 compatible --- install/deluge-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/deluge-install.sh b/install/deluge-install.sh index 1fde3caa..fb6c50e1 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y python3-libtorrent msg_ok "Installed Dependencies" msg_info "Updating Python3" @@ -28,7 +29,6 @@ msg_ok "Updated Python3" msg_info "Installing Deluge" $STD pip install deluge[all] -$STD pip install lbry-libtorrent msg_ok "Installed Deluge" msg_info "Creating Service" From 1a985d64174322be5975e8cb543789d687485a3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 28 Oct 2023 06:55:11 -0400 Subject: [PATCH 5431/6505] Update deluge.sh default Debian 12 --- ct/deluge.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/deluge.sh b/ct/deluge.sh index 163fe125..35d7eb16 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 3d4af6184daafa51019f37c7a0083a339428ef43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 09:21:44 -0400 Subject: [PATCH 5432/6505] Create unmanic.sh --- misc/unmanic.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 misc/unmanic.sh diff --git a/misc/unmanic.sh b/misc/unmanic.sh new file mode 100644 index 00000000..984917a4 --- /dev/null +++ b/misc/unmanic.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ _ + / / / /__ __ _ ___ ____ (_)___ +/ /_/ / _ \/ ' \/ _ `/ _ \/ / __/ +\____/_//_/_/_/_/\_,_/_//_/_/\__/ + +EOF +} +header_info +while true; do + read -p "This will add Unmanic to an existing LXC Container ONLY. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +set -e +NODE=$(hostname) +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') + +while [ -z "${CTID:+x}" ]; do + CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --radiolist \ + "\nSelect a container to add Unmanic to:\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done + +echo "Installing Unmanic..." +lxc-attach -n $CTID -- bash -c "apt-get -y install python3-pip && python3 -m pip install unmanic && cat << EOF >/etc/systemd/system/unmanic.service +[Unit] +Description=Unmanic - Library Optimiser +After=network-online.target +StartLimitInterval=200 +StartLimitBurst=3 + +[Service] +Type=simple +ExecStart=/usr/local/bin/unmanic +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target +EOF" +lxc-attach -n $CTID -- bash -c "systemctl enable -q --now unmanic.service" +echo "Installed Unmanic" +sleep 2 +echo -e "\n\e[1;32m ✔ Completed Successfully!\e[0m" +echo -e "\n\e[1;32m In a browser, go to ${CTID}'s IP:8888 \e[0m" From f34c2f150cbb412ef76e9d4dcc7531f18d36f8b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 10:08:24 -0400 Subject: [PATCH 5433/6505] Update unmanic.sh add ffmpeg --- misc/unmanic.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/unmanic.sh b/misc/unmanic.sh index 984917a4..9b423bfe 100644 --- a/misc/unmanic.sh +++ b/misc/unmanic.sh @@ -44,7 +44,7 @@ while [ -z "${CTID:+x}" ]; do done echo "Installing Unmanic..." -lxc-attach -n $CTID -- bash -c "apt-get -y install python3-pip && python3 -m pip install unmanic && cat << EOF >/etc/systemd/system/unmanic.service +lxc-attach -n $CTID -- bash -c "apt-get -y install python3-pip && python3 -m pip install unmanic && apt-get -y install ffmpeg && cat << EOF >/etc/systemd/system/unmanic.service [Unit] Description=Unmanic - Library Optimiser After=network-online.target From c674b53a06d3dba4341b2c2d7c799eb3a6ba4c2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 15:33:13 -0400 Subject: [PATCH 5434/6505] Update sabnzbd-install.sh unrar 7.0.2 --- install/sabnzbd-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index fb9690d3..06c6b19b 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -19,9 +19,9 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y par2 $STD apt-get install -y p7zip-full -wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_6.2.12-1_amd64.deb -$STD dpkg -i unrar_6.2.12-1_amd64.deb -rm unrar_6.2.12-1_amd64.deb +wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_7.0.2-1_amd64.deb +$STD dpkg -i unrar_7.0.2-1_amd64.deb +rm unrar_7.0.2-1_amd64.deb msg_ok "Installed Dependencies" msg_info "Updating Python3" From d4b0512eaf107ba42a244e80c828372cb2408fe3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 17:53:59 -0400 Subject: [PATCH 5435/6505] Create unmanic-install.sh --- install/unmanic-install.sh | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 install/unmanic-install.sh diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh new file mode 100644 index 00000000..72b898a1 --- /dev/null +++ b/install/unmanic-install.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y ffmpeg +$STD apt-get install -y python3-pip +msg_ok "Installed Dependencies" + +if [[ "$CTTYPE" == "0" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + intel-opencl-icd + + /bin/chgrp video /dev/dri + /bin/chmod 755 /dev/dri + /bin/chmod 660 /dev/dri/* + msg_ok "Set Up Hardware Acceleration" +fi + +msg_info "Installing Unmanic" +$STD pip3 install unmanic +msg_ok "Installed Unmanic" + +msg_info "Creating Service" +cat << EOF >/etc/systemd/system/unmanic.service +[Unit] +Description=Unmanic - Library Optimiser +After=network-online.target +StartLimitInterval=200 +StartLimitBurst=3 + +[Service] +Type=simple +ExecStart=/usr/local/bin/unmanic +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now -q unmanic.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 801ce7b7d76528d020dd6e7143c3c25daedcf471 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 17:55:19 -0400 Subject: [PATCH 5436/6505] Create unmanic.sh --- ct/unmanic.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/unmanic.sh diff --git a/ct/unmanic.sh b/ct/unmanic.sh new file mode 100644 index 00000000..76d61497 --- /dev/null +++ b/ct/unmanic.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ _ + / / / /___ ____ ___ ____ _____ (_)____ + / / / / __ \/ __ `__ \/ __ `/ __ \/ / ___/ +/ /_/ / / / / / / / / / /_/ / / / / / /__ +\____/_/ /_/_/ /_/ /_/\__,_/_/ /_/_/\___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Unmanic" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/unmanic.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +pip3 install -U unmanic &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8888${CL} \n" From a690992d631dbbd7a40b4c8627901688a2dbcf60 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 19:09:28 -0400 Subject: [PATCH 5437/6505] Update unmanic-install.sh tweak --- install/unmanic-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh index 72b898a1..3e86fc89 100644 --- a/install/unmanic-install.sh +++ b/install/unmanic-install.sh @@ -27,10 +27,10 @@ if [[ "$CTTYPE" == "0" ]]; then va-driver-all \ ocl-icd-libopencl1 \ intel-opencl-icd - - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* + mkdir /dev/dri >/dev/null 2>&1 + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* msg_ok "Set Up Hardware Acceleration" fi From 59a8f12c0f293f13e354edcbc7b7a94ffd34a5c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 19:37:25 -0400 Subject: [PATCH 5438/6505] Update build.func add Unmanic to VAAPI hardware transcoding group --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 4c975369..78f3c74d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -545,7 +545,7 @@ EOF fi if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" ]]; then + if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm From 85b0592f99b52305d37f08a1de16377fe4930a50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 19:42:12 -0400 Subject: [PATCH 5439/6505] Update unmanic-install.sh tweak --- install/unmanic-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh index 3e86fc89..53df335e 100644 --- a/install/unmanic-install.sh +++ b/install/unmanic-install.sh @@ -27,7 +27,7 @@ if [[ "$CTTYPE" == "0" ]]; then va-driver-all \ ocl-icd-libopencl1 \ intel-opencl-icd - mkdir /dev/dri >/dev/null 2>&1 + chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* From f2172b46097558504adcd5c97c2528000cf1a271 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 20:07:49 -0400 Subject: [PATCH 5440/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a77f17..45ab818a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-29 + +### Changed + +- **Unmanic LXC** + - NEW Script + ## 2023-10-27 ### Changed From 9decac3cd3a50ca0625f3bea05243f8ad8fbca3a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 20:52:15 -0400 Subject: [PATCH 5441/6505] Update unmanic-install.sh tweak --- install/unmanic-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh index 53df335e..ebf48b26 100644 --- a/install/unmanic-install.sh +++ b/install/unmanic-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc From 2d832fb19408dafa2992101c4321a45b293d4d33 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 21:26:22 -0400 Subject: [PATCH 5442/6505] Update hw-acceleration.sh tweak --- misc/hw-acceleration.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 2bc78f13..72e807c7 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -43,7 +43,7 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF -pct exec $privileged_container -- bash -c "apt-get -y install va-driver-all && apt-get -y install ocl-icd-libopencl1 && apt-get install -y intel-opencl-icd && chgrp video /dev/dri && chmod 755 /dev/dri && chmod 660 /dev/dri/*" +pct exec $privileged_container -- bash -c "apt-get -y install va-driver-all && apt-get -y install ocl-icd-libopencl1 && apt-get install -y intel-opencl-icd" header_info echo -e "Completed Successfully!\n" echo -e "Reboot container $privileged_container to apply the new settings\n" From c12a4f9f7c9a526aa73918aca004ecfc2ca849f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 29 Oct 2023 21:51:51 -0400 Subject: [PATCH 5443/6505] Update alpine-nextcloud.sh tweak --- ct/alpine-nextcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 0028e6a7..e950f101 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -62,7 +62,7 @@ function update_script() { while true; do CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ "1" "Update Nextcloud to $RELEASE" OFF \ - "2" "Nextcloud Database Credentials" ON \ + "2" "Nextcloud Login Credentials" ON \ "3" "Renew Self-signed Certificate" OFF \ 3>&1 1>&2 2>&3) exit_status=$? From e0e09f8a0b988d47387f2600c6d2716b4c2dc48c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 30 Oct 2023 05:32:56 -0400 Subject: [PATCH 5444/6505] Delete misc/unmanic.sh outdated --- misc/unmanic.sh | 67 ------------------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 misc/unmanic.sh diff --git a/misc/unmanic.sh b/misc/unmanic.sh deleted file mode 100644 index 9b423bfe..00000000 --- a/misc/unmanic.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { - clear - cat <<"EOF" - __ __ _ - / / / /__ __ _ ___ ____ (_)___ -/ /_/ / _ \/ ' \/ _ `/ _ \/ / __/ -\____/_//_/_/_/_/\_,_/_//_/_/\__/ - -EOF -} -header_info -while true; do - read -p "This will add Unmanic to an existing LXC Container ONLY. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -set -e -NODE=$(hostname) -while read -r line; do - TAG=$(echo "$line" | awk '{print $1}') - ITEM=$(echo "$line" | awk '{print substr($0,36)}') - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - CTID_MENU+=("$TAG" "$ITEM " "OFF") -done < <(pct list | awk 'NR>1') - -while [ -z "${CTID:+x}" ]; do - CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --radiolist \ - "\nSelect a container to add Unmanic to:\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit -done - -echo "Installing Unmanic..." -lxc-attach -n $CTID -- bash -c "apt-get -y install python3-pip && python3 -m pip install unmanic && apt-get -y install ffmpeg && cat << EOF >/etc/systemd/system/unmanic.service -[Unit] -Description=Unmanic - Library Optimiser -After=network-online.target -StartLimitInterval=200 -StartLimitBurst=3 - -[Service] -Type=simple -ExecStart=/usr/local/bin/unmanic -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target -EOF" -lxc-attach -n $CTID -- bash -c "systemctl enable -q --now unmanic.service" -echo "Installed Unmanic" -sleep 2 -echo -e "\n\e[1;32m ✔ Completed Successfully!\e[0m" -echo -e "\n\e[1;32m In a browser, go to ${CTID}'s IP:8888 \e[0m" From 8de41a87c7bd9517eeb10449aaa09a6009b48b2f Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 30 Oct 2023 13:57:03 -0400 Subject: [PATCH 5445/6505] Update esphome-install.sh - create `config` directory - fixes https://github.com/tteck/Proxmox/issues/1981 --- install/esphome-install.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 7dbbbc18..38710d3e 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -26,14 +26,10 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv - msg_ok "Updated Python3" msg_info "Installing ESPHome" -#mkdir /srv/esphome -#cd /srv/esphome -#python3 -m venv . -#source bin/activate +mkdir config $STD pip install esphome tornado esptool msg_ok "Installed ESPHome" @@ -44,7 +40,6 @@ Description=ESPHome Dashboard After=network.target [Service] -#ExecStart=/srv/esphome/bin/esphome dashboard /root/config/ ExecStart=/usr/local/bin/esphome dashboard /root/config/ Restart=always User=root From 6da234a3ed5be71d82c83b6c4c9e2b561649d513 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 30 Oct 2023 14:02:46 -0400 Subject: [PATCH 5446/6505] Update esphome-install.sh --- install/esphome-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 38710d3e..5b5a8d1f 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -29,7 +29,7 @@ $STD apt-get install -y \ msg_ok "Updated Python3" msg_info "Installing ESPHome" -mkdir config +mkdir /root/config $STD pip install esphome tornado esptool msg_ok "Installed ESPHome" From 4a2d9296bdc88dbb45e1f41888534a858ec0feaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 31 Oct 2023 16:01:05 -0400 Subject: [PATCH 5447/6505] Create debian-vm.sh --- vm/debian-vm.sh | 421 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 vm/debian-vm.sh diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh new file mode 100644 index 00000000..feaf5238 --- /dev/null +++ b/vm/debian-vm.sh @@ -0,0 +1,421 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ____ __ _ ______ + / __ \___ / /_ (_)___ _____ < /__ \ + / / / / _ \/ __ \/ / __ `/ __ \ / /__/ / + / /_/ / __/ /_/ / / /_/ / / / / / // __/ +/_____/\___/_.___/_/\__,_/_/ /_/ /_//____/ + +EOF +} +header_info +echo -e "\n Loading..." +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +NEXTID=$(pvesh get /cluster/nextid) + +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +THIN="discard=on,ssd=1," +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +trap cleanup EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid +} + +function cleanup_vmid() { + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Debian 12 VM" --yesno "This will create a New Debian 12 VM. Proceed?" 10 58; then + : +else + header_info && echo -e "⚠ User exited script \n" && exit +fi + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function check_root() { + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + +function pve_check() { + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + msg_error "This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function ssh_check() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function default_settings() { + VMID="$NEXTID" + FORMAT=",efitype=4m" + MACHINE="" + DISK_CACHE="" + HN="debian" + CPU_TYPE="" + CORE_COUNT="2" + RAM_SIZE="2048" + BRG="vmbr0" + MAC="$GEN_MAC" + VLAN="" + MTU="" + START_VM="yes" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + echo -e "${BL}Creating a Debian 12 VM using the above default settings${CL}" +} + +function advanced_settings() { + while true; do + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + exit-script + fi + done + + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "i440fx" "Machine i440fx" ON \ + "q35" "Machine q35" OFF \ + 3>&1 1>&2 2>&3); then + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" + fi + else + exit-script + fi + + if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "None (Default)" ON \ + "1" "Write Through" OFF \ + 3>&1 1>&2 2>&3); then + if [ $DISK_CACHE = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + DISK_CACHE="" + fi + else + exit-script + fi + + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 debian --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="debian" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + else + exit-script + fi + + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "KVM64 (Default)" ON \ + "1" "Host" OFF \ + 3>&1 1>&2 2>&3); then + if [ $CPU_TYPE1 = "1" ]; then + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + CPU_TYPE=" -cpu host" + else + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + CPU_TYPE="" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="2048" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + else + exit-script + fi + + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + else + exit-script + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Debian 12 VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a Debian 12 VM using the above advanced settings${CL}" + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function start_script() { + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +check_root +arch_check +pve_check +ssh_check +start_script + +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + msg_error "Unable to detect a valid storage location." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image" +URL=https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-nocloud-amd64-20231013-1532.qcow2 +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}${FILE}${CL}" + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in +nfs | dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + THIN="" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done + +msg_info "Creating a Debian 12 VM" +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \ + -boot order=scsi0 \ + -description "# Debian 12 VM +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null +msg_ok "Created a Debian 12 VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then + msg_info "Starting Debian 12 VM" + qm start $VMID + msg_ok "Started Debian 12 VM" +fi +msg_ok "Completed Successfully!\n" From 45baf98e99a9fb5f09055880514e9cf5363c166f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 31 Oct 2023 16:09:07 -0400 Subject: [PATCH 5448/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45ab818a..8c513f7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-10-31 + +### Changed + +- **Debian 12 VM** + - NEW Script + ## 2023-10-29 ### Changed From cf8704529ca887636d2f50f8d4a9b4399edcbaa7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Nov 2023 02:23:38 -0400 Subject: [PATCH 5449/6505] Create owncast-install.sh --- install/owncast-install.sh | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 install/owncast-install.sh diff --git a/install/owncast-install.sh b/install/owncast-install.sh new file mode 100644 index 00000000..5b08b076 --- /dev/null +++ b/install/owncast-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y ffmpeg +msg_ok "Installed Dependencies" + +msg_info "Installing Owncast" +mkdir /opt/owncast +cd /opt/owncast +wget -q $(curl -s https://api.github.com/repos/owncast/owncast/releases/latest | grep download | grep linux-64bit | cut -d\" -f4) +unzip owncast*.zip +rm owncast*.zip +msg_ok "Installed Owncast" + +msg_info "Creating Service" +cat </etc/systemd/system/owncast.service +[Unit] +Description=Owncast +After=syslog.target network-online.target + +[Service] +ExecStart=/opt/owncast/./owncast +WorkingDirectory=/opt/owncast +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now owncast.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 7186cfc2a8346f4a6b4d66cb64dcee4dd243e02a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Nov 2023 02:25:03 -0400 Subject: [PATCH 5450/6505] Create owncast.sh --- ct/owncast.sh | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ct/owncast.sh diff --git a/ct/owncast.sh b/ct/owncast.sh new file mode 100644 index 00000000..4049f043 --- /dev/null +++ b/ct/owncast.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \_ ______ _________ ______/ /_ + / / / / | /| / / __ \/ ___/ __ `/ ___/ __/ +/ /_/ /| |/ |/ / / / / /__/ /_/ (__ ) /_ +\____/ |__/|__/_/ /_/\___/\__,_/____/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="Owncast" +var_disk="2" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/owncast ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} + ${BL}http://${IP}:8080/admin${CL} admin|abc123\n" From 732b663147d474d216541840db69320dbc4663e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Nov 2023 02:29:46 -0400 Subject: [PATCH 5451/6505] Update owncast-install.sh tweak --- install/owncast-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/owncast-install.sh b/install/owncast-install.sh index 5b08b076..8514ae8b 100644 --- a/install/owncast-install.sh +++ b/install/owncast-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc @@ -24,7 +24,7 @@ msg_info "Installing Owncast" mkdir /opt/owncast cd /opt/owncast wget -q $(curl -s https://api.github.com/repos/owncast/owncast/releases/latest | grep download | grep linux-64bit | cut -d\" -f4) -unzip owncast*.zip +$STD unzip owncast*.zip rm owncast*.zip msg_ok "Installed Owncast" From a94bcac429e83832a0af203fa52b0c60dfeb44e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Nov 2023 02:58:33 -0400 Subject: [PATCH 5452/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c513f7f..d59d41eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-1 + +### Changed + +- **Owncast LXC** + - NEW Script + ## 2023-10-31 ### Changed From 15f1343a000f8b43792b98c146d62d90c20cf719 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Nov 2023 03:40:43 -0400 Subject: [PATCH 5453/6505] Update openwrt.sh tweak --- vm/openwrt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 5f9d6fcc..d163b926 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -478,7 +478,7 @@ qm set $VMID \ -description "# OpenWrt VM ### https://github.com/tteck/Proxmox [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null -msg_ok "OpenWrt VM ${CL}${BL}(${HN})" +msg_ok "Created OpenWrt VM ${CL}${BL}(${HN})" msg_info "OpenWrt is being started in order to configure the network interfaces." qm start $VMID sleep 15 From 19a6a06f5f9f74cd1f59454a7e4e47e7f5999d29 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 Nov 2023 19:16:54 -0400 Subject: [PATCH 5454/6505] Update podman-homeassistant.sh https://github.com/tteck/Proxmox/issues/1994 --- ct/podman-homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index 14c2ed98..aa473549 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -74,7 +74,7 @@ if [ "$UPD" == "1" ]; then for container in ${CONTAINER_LIST}; do CONTAINER_IMAGE="$(podman inspect --format "{{.Config.Image}}" --type container ${container})" RUNNING_IMAGE="$(podman inspect --format "{{.Image}}" --type container "${container}")" - podman pull "docker.io/${CONTAINER_IMAGE}" + podman pull "${CONTAINER_IMAGE}" LATEST_IMAGE="$(podman inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then echo "Updating ${container} image ${CONTAINER_IMAGE}" From 8982211e12a94d8aa7a80f25dce6a16f3fa72a1e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Nov 2023 10:45:28 -0400 Subject: [PATCH 5455/6505] Update photoprism.sh Transitioned to PhotoPrism's latest installation package, featuring Linux binaries. --- ct/photoprism.sh | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index ae29e486..2eefb474 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -20,8 +20,8 @@ header_info echo -e "Loading..." APP="PhotoPrism" var_disk="8" -var_cpu="4" -var_ram="4096" +var_cpu="2" +var_ram="2048" var_os="debian" var_version="12" variables @@ -61,24 +61,9 @@ function update_script() { sudo systemctl stop photoprism msg_ok "Stopped PhotoPrism" - msg_info "Cloning PhotoPrism" - cd ~ - git clone https://github.com/photoprism/photoprism.git &>/dev/null - cd photoprism - git checkout release &>/dev/null - msg_ok "Cloned PhotoPrism" - - msg_info "Building PhotoPrism" - sudo make all &>/dev/null - sudo ./scripts/build.sh prod /opt/photoprism/bin/photoprism &>/dev/null - sudo rm -rf /opt/photoprism/assets - sudo cp -r assets/ /opt/photoprism/ &>/dev/null - msg_ok "Built PhotoPrism" - - msg_info "Cleaning" - cd ~ - rm -rf photoprism - msg_ok "Cleaned" + msg_info "Updating PhotoPrism" + wget -q -cO - https://dl.photoprism.app/pkg/linux/amd64.tar.gz | tar -xzf - -C /opt/photoprism --strip-components=1 + msg_ok "Updated PhotoPrism" msg_info "Starting PhotoPrism" sudo systemctl start photoprism @@ -91,9 +76,6 @@ start build_container description -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 2048 -msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:2342${CL} \n" From 9cfc8e3a62ad33987c5267ada869356cefa5d68c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Nov 2023 10:48:47 -0400 Subject: [PATCH 5456/6505] Update photoprism-install.sh - Transitioned to PhotoPrism's latest installation package, featuring Linux binaries. --- install/photoprism-install.sh | 109 ++++++++-------------------------- 1 file changed, 24 insertions(+), 85 deletions(-) diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 8a4e3da2..84573941 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -17,96 +17,41 @@ msg_info "Installing Dependencies (Patience)" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y gcc -$STD apt-get install -y g++ -$STD apt-get install -y git -$STD apt-get install -y make -$STD apt-get install -y zip $STD apt-get install -y exiftool $STD apt-get install -y ffmpeg $STD apt-get install -y libheif1 -$STD apt-get install -y ca-certificates -$STD apt-get install -y gnupg +$STD apt-get install -y libpng-dev +$STD apt-get install -y libjpeg-dev +$STD apt-get install -y libtiff-dev +$STD apt-get install -y imagemagick +$STD apt-get install -y darktable + msg_ok "Installed Dependencies" -msg_info "Setting up Node.js Repository" -mkdir -p /etc/apt/keyrings -curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list -msg_ok "Set up Node.js Repository" - -msg_info "Installing Node.js" -$STD apt-get update -$STD apt-get install -y nodejs -msg_ok "Installed Node.js" - -msg_info "Installing Golang" -set +o pipefail -RELEASE=$(curl -s https://go.dev/dl/ | grep -o "go.*\linux-amd64.tar.gz" | head -n 1) -wget -q https://golang.org/dl/$RELEASE -$STD tar -xzf $RELEASE -C /usr/local -$STD ln -s /usr/local/go/bin/go /usr/local/bin/go -msg_ok "Installed Golang" - -msg_info "Installing Go Dependencies" -$STD go install github.com/tianon/gosu@latest -$STD go install golang.org/x/tools/cmd/goimports@latest -$STD go install github.com/psampaz/go-mod-outdated@latest -$STD go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest -$STD go install github.com/mikefarah/yq/v4@latest -$STD go install github.com/kyoh86/richgo@latest -cp /root/go/bin/* /usr/local/go/bin/ -cp /usr/local/go/bin/richgo /usr/local/bin/richgo -cp /usr/local/go/bin/gosu /usr/local/sbin/gosu -chown root:root /usr/local/sbin/gosu -chmod 755 /usr/local/sbin/gosu -msg_ok "Installed Go Dependencies" - -msg_info "Installing Tensorflow" -if grep -q avx2 /proc/cpuinfo; then - suffix="avx2-" -elif grep -q avx /proc/cpuinfo; then - suffix="avx-" +msg_info "Installing PhotoPrism (Patience)" +mkdir -p /opt/photoprism/{cache,photos/originals,photos/import,storage,temp} +wget -q -cO - https://dl.photoprism.app/pkg/linux/amd64.tar.gz | tar -xz -C /opt/photoprism --strip-components=1 +if [[ ${PCT_OSTYPE} == "ubuntu" ]]; then + wget -q -cO - https://dl.photoprism.app/dist/libheif/libheif-jammy-amd64-v1.17.1.tar.gz | tar -xzf - -C /usr/local --strip-components=1 else - suffix="1" + wget -q -cO - https://dl.photoprism.app/dist/libheif/libheif-bookworm-amd64-v1.17.1.tar.gz | tar -xzf - -C /usr/local --strip-components=1 fi -version=$(curl -s https://dl.photoprism.org/tensorflow/amd64/ | grep -o "libtensorflow-amd64-$suffix.*\\.tar.gz" | head -n 1) -wget -q https://dl.photoprism.org/tensorflow/amd64/$version -tar -C /usr/local -xzf $version ldconfig -set -o pipefail -msg_ok "Installed Tensorflow" - -msg_info "Cloning PhotoPrism" -mkdir -p /opt/photoprism/bin -mkdir -p /var/lib/photoprism/storage -$STD git clone https://github.com/photoprism/photoprism.git -cd photoprism -$STD git checkout release -msg_ok "Cloned PhotoPrism" - -msg_info "Building PhotoPrism (Patience)" -$STD make -B -$STD ./scripts/build.sh prod /opt/photoprism/bin/photoprism -$STD cp -r assets/ /opt/photoprism/ -msg_ok "Built PhotoPrism" - -env_path="/var/lib/photoprism/.env" -echo " +cat </opt/photoprism/config/.env PHOTOPRISM_AUTH_MODE='password' PHOTOPRISM_ADMIN_PASSWORD='changeme' PHOTOPRISM_HTTP_HOST='0.0.0.0' PHOTOPRISM_HTTP_PORT='2342' PHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/' -PHOTOPRISM_STORAGE_PATH='/var/lib/photoprism/storage' -PHOTOPRISM_ORIGINALS_PATH='/var/lib/photoprism/photos/Originals' -PHOTOPRISM_IMPORT_PATH='/var/lib/photoprism/photos/Import' -" >$env_path +PHOTOPRISM_STORAGE_PATH='/opt/photoprism/storage' +PHOTOPRISM_ORIGINALS_PATH='/opt/photoprism/photos/originals' +PHOTOPRISM_IMPORT_PATH='/opt/photoprism/photos/import' +EOF +msg_ok "Installed PhotoPrism" msg_info "Creating Service" -service_path="/etc/systemd/system/photoprism.service" - -echo "[Unit] +cat </etc/systemd/system/photoprism.service +[Unit] Description=PhotoPrism service After=network.target @@ -114,12 +59,14 @@ After=network.target Type=forking User=root WorkingDirectory=/opt/photoprism -EnvironmentFile=/var/lib/photoprism/.env +EnvironmentFile=/opt/photoprism/config/.env ExecStart=/opt/photoprism/bin/photoprism up -d ExecStop=/opt/photoprism/bin/photoprism down [Install] -WantedBy=multi-user.target" >$service_path +WantedBy=multi-user.target +EOF +systemctl enable -q --now photoprism msg_ok "Created Service" motd_ssh @@ -128,12 +75,4 @@ customize msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean -rm -rf /var/{cache,log}/* \ - /photoprism \ - /$RELEASE \ - /$version msg_ok "Cleaned" - -msg_info "Starting PhotoPrism" -systemctl enable -q --now photoprism -msg_ok "Started PhotoPrism" From 4c4ff24327f7e601530adb7e7e23da1b273d0c19 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 Nov 2023 18:19:27 -0400 Subject: [PATCH 5457/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d59d41eb..b6dd39bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-2 + +### Changed + +- **PhotoPrism LXC** + - Transitioned to PhotoPrism's latest installation package, featuring Linux binaries. + ## 2023-11-1 ### Changed From e57a7f66c128fd94ddf3ddcdf5df7acec47c083f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Nov 2023 16:25:03 -0400 Subject: [PATCH 5458/6505] Update photoprism-install.sh create config directory --- install/photoprism-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 84573941..75a03fee 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -29,7 +29,7 @@ $STD apt-get install -y darktable msg_ok "Installed Dependencies" msg_info "Installing PhotoPrism (Patience)" -mkdir -p /opt/photoprism/{cache,photos/originals,photos/import,storage,temp} +mkdir -p /opt/photoprism/{cache,config,photos/originals,photos/import,storage,temp} wget -q -cO - https://dl.photoprism.app/pkg/linux/amd64.tar.gz | tar -xz -C /opt/photoprism --strip-components=1 if [[ ${PCT_OSTYPE} == "ubuntu" ]]; then wget -q -cO - https://dl.photoprism.app/dist/libheif/libheif-jammy-amd64-v1.17.1.tar.gz | tar -xzf - -C /usr/local --strip-components=1 From b918091d6b754053ffc22a927fb71ff7ee94efe8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 3 Nov 2023 16:39:23 -0400 Subject: [PATCH 5459/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 5f4fe348..b977a7cf 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -102,7 +102,7 @@ EOF esac if [[ "${VERSION}" == "bookworm" ]]; then - CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nAdd 'ceph package repositories?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nCorrect 'ceph package sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From 5dc1cf587096c05eacd5b82693886886d6eca802 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 Nov 2023 09:17:47 -0400 Subject: [PATCH 5460/6505] Update esphome-install.sh move /config to /.config --- install/esphome-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 5b5a8d1f..8961664b 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -29,7 +29,6 @@ $STD apt-get install -y \ msg_ok "Updated Python3" msg_info "Installing ESPHome" -mkdir /root/config $STD pip install esphome tornado esptool msg_ok "Installed ESPHome" @@ -40,7 +39,7 @@ Description=ESPHome Dashboard After=network.target [Service] -ExecStart=/usr/local/bin/esphome dashboard /root/config/ +ExecStart=/usr/local/bin/esphome dashboard /root/.config/ Restart=always User=root From 64d5ec81eeee2c09318228bbcef77e26f10459a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fries?= Date: Sun, 5 Nov 2023 22:52:56 +0100 Subject: [PATCH 5461/6505] Fix typo (#2007) --- ct/homeassistant-core.sh | 4 ++-- ct/homeassistant.sh | 4 ++-- ct/podman-homeassistant.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 7b14b802..f3929b14 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -96,12 +96,12 @@ function update_script() { exit fi if [ "$UPD" == "2" ]; then - msg_info "Installing Home Assistant Comunity Store (HACS)" + msg_info "Installing Home Assistant Community Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null cd .homeassistant bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null - msg_ok "Installed Home Assistant Comunity Store (HACS)" + msg_ok "Installed Home Assistant Community Store (HACS)" echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" exit fi diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 3c1abf63..1298c150 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -88,12 +88,12 @@ function update_script() { exit fi if [ "$UPD" == "3" ]; then - msg_info "Installing Home Assistant Comunity Store (HACS)" + msg_info "Installing Home Assistant Community Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null cd /var/lib/docker/volumes/hass_config/_data bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null - msg_ok "Installed Home Assistant Comunity Store (HACS)" + msg_ok "Installed Home Assistant Community Store (HACS)" echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" exit fi diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index aa473549..87b1ed72 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -85,12 +85,12 @@ if [ "$UPD" == "1" ]; then exit fi if [ "$UPD" == "2" ]; then - msg_info "Installing Home Assistant Comunity Store (HACS)" + msg_info "Installing Home Assistant Community Store (HACS)" apt update &>/dev/null apt install unzip &>/dev/null cd /var/lib/containers/storage/volumes/hass_config/_data bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null - msg_ok "Installed Home Assistant Comunity Store (HACS)" + msg_ok "Installed Home Assistant Community Store (HACS)" echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" exit fi From d74faa16732560cf1f38156c2c6f43906d5e2281 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Nov 2023 09:06:13 -0500 Subject: [PATCH 5462/6505] Create linkwarden.sh --- ct/linkwarden.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/linkwarden.sh diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh new file mode 100644 index 00000000..1ece83f2 --- /dev/null +++ b/ct/linkwarden.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ _ __ __ + / / (_)___ / /___ ______ __________/ /__ ____ + / / / / __ \/ //_/ | /| / / __ `/ ___/ __ / _ \/ __ \ + / /___/ / / / / ,< | |/ |/ / /_/ / / / /_/ / __/ / / / +/_____/_/_/ /_/_/|_| |__/|__/\__,_/_/ \__,_/\___/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Linkwarden" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="22.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/linkwarden ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP}${CL} should be reachable by going to the following URL. + ${BL}https://${IP}:3000${CL} \n" From 5746f5c1c97682451d877f44a48daa073561db90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Nov 2023 09:08:51 -0500 Subject: [PATCH 5463/6505] Create linkwarden-install.sh --- install/linkwarden-install.sh | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 install/linkwarden-install.sh diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh new file mode 100644 index 00000000..e959f555 --- /dev/null +++ b/install/linkwarden-install.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y gpg +$STD apt-get install -y postgresql +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Clone Linkwarden Repository" +$STD git clone https://github.com/linkwarden/linkwarden.git /opt/linkwarden +cd /opt/linkwarden +msg_info "Cloned Linkwarden Repository" + +msg_info "Setting up PostgreSQL DB" +DB_NAME=linkwardendb +DB_USER=linkwarden +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" + +echo "" >>~/linkwarden.creds +echo -e "Linkwarden Database User: \e[32m$DB_USER\e[0m" >>~/linkwarden.creds +echo -e "Linkwarden Database Password: \e[32m$DB_PASS\e[0m" >>~/linkwarden.creds +echo -e "Linkwarden Database Name: \e[32m$DB_NAME\e[0m" >>~/linkwarden.creds +msg_ok "Set up PostgreSQL DB" + +read -r -p "Would you like to add Adminer? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Adminer" + $STD apt install -y adminer + $STD a2enconf adminer + systemctl reload apache2 + IP=$(hostname -I | awk '{print $1}') + echo "" >>~/linkwarden.creds + echo -e "Adminer Interface: \e[32m$IP/adminer/\e[0m" >>~/linkwarden.creds + echo -e "Adminer System: \e[32mPostgreSQL\e[0m" >>~/linkwarden.creds + echo -e "Adminer Server: \e[32mlocalhost:5432\e[0m" >>~/linkwarden.creds + echo -e "Adminer Username: \e[32m$DB_USER\e[0m" >>~/linkwarden.creds + echo -e "Adminer Password: \e[32m$DB_PASS\e[0m" >>~/linkwarden.creds + echo -e "Adminer Database: \e[32m$DB_NAME\e[0m" >>~/linkwarden.creds + msg_ok "Installed Adminer" +fi + +msg_info "Installing Linkwarden (Patience)" +$STD yarn +$STD npx playwright install-deps +IP=$(hostname -I | awk '{print $1}') +SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" +env_path="/opt/linkwarden/.env" +echo " +NEXTAUTH_SECRET=${SECRET_KEY} +NEXTAUTH_URL=http://${IP}:3000 +DATABASE_URL=postgresql://linkwarden:password@localhost:5432/linkwardendb +" >$env_path +$STD yarn build +$STD yarn prisma migrate deploy +msg_ok "Installed Linkwarden" + +msg_info "Creating Service" +cat </etc/systemd/system/linkwarden.service +[Unit] +Description=Linkwarden Service +After=network.target + +[Service] +Type=exec +WorkingDirectory=/opt/linkwarden +ExecStart=/usr/bin/yarn start + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now linkwarden.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 41763b94ee73bf6ac0be7c1f0435bc51bde364c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Nov 2023 09:17:09 -0500 Subject: [PATCH 5464/6505] Update linkwarden-install.sh --- install/linkwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh index e959f555..06624471 100644 --- a/install/linkwarden-install.sh +++ b/install/linkwarden-install.sh @@ -77,7 +77,7 @@ env_path="/opt/linkwarden/.env" echo " NEXTAUTH_SECRET=${SECRET_KEY} NEXTAUTH_URL=http://${IP}:3000 -DATABASE_URL=postgresql://linkwarden:password@localhost:5432/linkwardendb +DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME} " >$env_path $STD yarn build $STD yarn prisma migrate deploy From 26552c40816c3656b60e99c9a36bc84e70a52775 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Nov 2023 09:18:50 -0500 Subject: [PATCH 5465/6505] Update linkwarden-install.sh --- install/linkwarden-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh index 06624471..7ab85f54 100644 --- a/install/linkwarden-install.sh +++ b/install/linkwarden-install.sh @@ -28,10 +28,11 @@ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dea echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" -msg_info "Installing Node.js" +msg_info "Installing Node.js/Yarn" $STD apt-get update $STD apt-get install -y nodejs -msg_ok "Installed Node.js" +$STD npm install -g yarn +msg_ok "Installed Node.js/Yarn" msg_info "Clone Linkwarden Repository" $STD git clone https://github.com/linkwarden/linkwarden.git /opt/linkwarden From 579d10a429d28578f276e27cb2da4daf5df1880d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Nov 2023 09:25:25 -0500 Subject: [PATCH 5466/6505] Update linkwarden-install.sh --- install/linkwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh index 7ab85f54..585d76c7 100644 --- a/install/linkwarden-install.sh +++ b/install/linkwarden-install.sh @@ -37,7 +37,7 @@ msg_ok "Installed Node.js/Yarn" msg_info "Clone Linkwarden Repository" $STD git clone https://github.com/linkwarden/linkwarden.git /opt/linkwarden cd /opt/linkwarden -msg_info "Cloned Linkwarden Repository" +msg_ok "Cloned Linkwarden Repository" msg_info "Setting up PostgreSQL DB" DB_NAME=linkwardendb From fb3a909c287c787755574f9fcf92d5aef5229d5c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Nov 2023 09:49:32 -0500 Subject: [PATCH 5467/6505] Update linkwarden.sh --- ct/linkwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index 1ece83f2..fb2a8d01 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -63,4 +63,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP}${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:3000${CL} \n" + ${BL}http://${IP}:3000${CL} \n" From b0a9d6281431bd48786dc9623c09b5a937a5bb47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 Nov 2023 10:25:05 -0500 Subject: [PATCH 5468/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6dd39bd..74d99b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-8 + +### Changed + +- **Linkwarden LXC** + - NEW Script + ## 2023-11-2 ### Changed From 95e26b68427592dbf25e8f187a0ebe7ab22cce51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 09:09:44 -0500 Subject: [PATCH 5469/6505] Update alpine-install.func fixes https://github.com/tteck/Proxmox/issues/2015 --- misc/alpine-install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 3fd39278..959d5443 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -72,7 +72,7 @@ setting_up_container() { echo -e " 🖧 Check Network Settings" exit 1 fi - cat </etc/apk/repositories + cat <>/etc/apk/repositories https://dl-cdn.alpinelinux.org/alpine/edge/main https://dl-cdn.alpinelinux.org/alpine/edge/community https://dl-cdn.alpinelinux.org/alpine/edge/testing From 9af470895c0712055035c053988dcd7cc5fc972e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 10:33:56 -0500 Subject: [PATCH 5470/6505] Create agentdvr.sh --- ct/agentdvr.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/agentdvr.sh diff --git a/ct/agentdvr.sh b/ct/agentdvr.sh new file mode 100644 index 00000000..e93bab1a --- /dev/null +++ b/ct/agentdvr.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ ____ _ ______ + / | ____ ____ ____ / /_/ __ \ | / / __ \ + / /| |/ __ `/ _ \/ __ \/ __/ / / / | / / /_/ / + / ___ / /_/ / __/ / / / /_/ /_/ /| |/ / _, _/ +/_/ |_\__, /\___/_/ /_/\__/_____/ |___/_/ |_| + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="AgentDVR" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="ubuntu" +var_version="22.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/agentdvr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP}${CL} should be reachable by going to the following URL. + ${BL}https://${IP}:8090${CL} \n" From e874e9c5cc22a3b3e41b65e6307bd17b6e9b73de Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 10:35:01 -0500 Subject: [PATCH 5471/6505] Create agentdvr-install.sh --- install/agentdvr-install.sh | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 install/agentdvr-install.sh diff --git a/install/agentdvr-install.sh b/install/agentdvr-install.sh new file mode 100644 index 00000000..431b44ba --- /dev/null +++ b/install/agentdvr-install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y unzip +$STD apt-get install -y apt-transport-https +$STD apt-get install -y alsa-utils +$STD apt-get install -y libxext-dev +$STD apt-get install -y fontconfig +msg_ok "Installed Dependencies" + +msg_info "Installing AgentDVR" +mkdir -p /opt/agentdvr/agent +RELEASE=$(curl -s "https://www.ispyconnect.com/api/Agent/DownloadLocation4?platform=Linux64&fromVersion=0" | grep -o 'https://.*\.zip') +cd /opt/agentdvr/agent +wget -q $RELEASE +$STD unzip Agent_Linux64*.zip +rm -rf Agent_Linux64*.zip +chmod +x ./Agent +msg_info "Installed AgentDVR" + +msg_info "Creating Service" +cat </etc/systemd/system/agentdvr.service +[Unit] +Description=AgentDVR + +[Service] +WorkingDirectory=/opt/agentdvr/agent +ExecStart=/opt/agentdvr/agent/./Agent +Environment="MALLOC_TRIM_THRESHOLD_=100000" +SyslogIdentifier=AgentDVR +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now agentdvr.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 813771cde472b368476b9b34030c4c1f00772f44 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 10:43:50 -0500 Subject: [PATCH 5472/6505] Update agentdvr.sh --- ct/agentdvr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/agentdvr.sh b/ct/agentdvr.sh index e93bab1a..25b17e77 100644 --- a/ct/agentdvr.sh +++ b/ct/agentdvr.sh @@ -63,4 +63,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP}${CL} should be reachable by going to the following URL. - ${BL}https://${IP}:8090${CL} \n" + ${BL}http://${IP}:8090${CL} \n" From c9d255012cfed7771d7e4e133c4f689921e4f35f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 10:44:33 -0500 Subject: [PATCH 5473/6505] Update agentdvr-install.sh --- install/agentdvr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/agentdvr-install.sh b/install/agentdvr-install.sh index 431b44ba..7dcd0d0a 100644 --- a/install/agentdvr-install.sh +++ b/install/agentdvr-install.sh @@ -32,7 +32,7 @@ wget -q $RELEASE $STD unzip Agent_Linux64*.zip rm -rf Agent_Linux64*.zip chmod +x ./Agent -msg_info "Installed AgentDVR" +msg_ok "Installed AgentDVR" msg_info "Creating Service" cat </etc/systemd/system/agentdvr.service From ec2b16970f8a677c526b0752abc33aed774923fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 11:01:08 -0500 Subject: [PATCH 5474/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74d99b2b..b7bd0170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-9 + +### Changed + +- **AgentDVR LXC** + - NEW Script + ## 2023-11-8 ### Changed From 2bfd58c92c1767c0cd51463b227e30476793f982 Mon Sep 17 00:00:00 2001 From: Scott Russell <95888238+scott-hpe@users.noreply.github.com> Date: Thu, 9 Nov 2023 11:59:48 -0500 Subject: [PATCH 5475/6505] Update update-lxcs.sh (#2018) Add -q to apt-get to avoid terminal noise in the logs --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 9a48dc1f..5443d59e 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -67,7 +67,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -y dist-upgrade" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade" ;; esac } From 6463c85f05f386bc70b4e5f561689de04625433b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 17:46:25 -0500 Subject: [PATCH 5476/6505] Update sonarr-install.sh change v4 path --- install/sonarr-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index c183454a..5a1780b0 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -29,10 +29,10 @@ $STD apt-get update DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy sonarr &>/dev/null if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then systemctl stop sonarr.service - wget -q https://download.sonarr.tv/v4/develop/4.0.0.697/Sonarr.develop.4.0.0.697.linux-x64.tar.gz - tar -xzf Sonarr.develop.4.0.0.697.linux-x64.tar.gz + wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/develop/latest?version=4&os=linux' + tar -xzf SonarrV4.tar.gz cp -r Sonarr/* /usr/lib/sonarr/bin - rm -rf Sonarr Sonarr.develop.4.0.0.697.linux-x64.tar.gz + rm -rf Sonarr SonarrV4.tar.gz sed -i 's|ExecStart=/usr/bin/mono --debug /usr/lib/sonarr/bin/Sonarr.exe -nobrowser -data=/var/lib/sonarr|ExecStart=/usr/lib/sonarr/bin/Sonarr -nobrowser -data=/var/lib/sonarr|' /lib/systemd/system/sonarr.service sed -i 's/\(User=\|Group=\).*/\1root/' /lib/systemd/system/sonarr.service systemctl daemon-reload From 92b50cf36f23e6bfe205e11d634fb78ce51238a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 17:52:48 -0500 Subject: [PATCH 5477/6505] Update sonarr.sh add update for v4 --- ct/sonarr.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ct/sonarr.sh b/ct/sonarr.sh index cbcf3e34..bd0f7342 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -53,6 +53,16 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/apt/sources.list.d/sonarr.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +read -r -p "Are you updating Sonarr v4? " prompt +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + systemctl stop sonarr.service + wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/develop/latest?version=4&os=linux' + tar -xzf SonarrV4.tar.gz + cp -r Sonarr/* /usr/lib/sonarr/bin + rm -rf Sonarr SonarrV4.tar.gz + systemctl start sonarr.service + exit +fi msg_info "Updating $APP LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null From 04647388bfadee59470233b7a2d0af4d44629f9b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 Nov 2023 18:23:14 -0500 Subject: [PATCH 5478/6505] Update tdarr.sh default Debian 12 --- ct/tdarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/tdarr.sh b/ct/tdarr.sh index cff3d7fc..5210d6c1 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 239b9ea0bad419c1fd71a9940f130c4a8f9fc8ec Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Nov 2023 05:25:46 -0500 Subject: [PATCH 5479/6505] Update kavita.sh - default Debian 12 - set update path --- ct/kavita.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ct/kavita.sh b/ct/kavita.sh index 4d86cd74..ca448e24 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors @@ -54,8 +54,13 @@ function update_script() { header_info if [[ ! -d /opt/Kavita ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +systemctl stop kavita +RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, l> +tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) &>/dev/null +rm -rf Kavita/config +cp -r Kavita/* /opt/Kavita +rm -rf Kavita +systemctl start kavita msg_ok "Updated $APP LXC" exit } From 4fa50c91006058af184d2051a10017ca3b6488ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 Nov 2023 13:32:21 -0500 Subject: [PATCH 5480/6505] Update kavita.sh fixes https://github.com/tteck/Proxmox/issues/2022 --- ct/kavita.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/kavita.sh b/ct/kavita.sh index ca448e24..f5e1ba5b 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -55,7 +55,7 @@ header_info if [[ ! -d /opt/Kavita ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating $APP LXC" systemctl stop kavita -RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, l> +RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) &>/dev/null rm -rf Kavita/config cp -r Kavita/* /opt/Kavita From e1cdf7ddd4d29fc1e5ec634f1297b5f231e5acac Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 06:50:31 -0500 Subject: [PATCH 5481/6505] Update shinobi-install.sh fix spelling --- install/shinobi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index dd81b791..52d470b4 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -36,7 +36,7 @@ msg_info "Installing FFMPEG" $STD apt-get install -y ffmpeg msg_ok "Installed FFMPEG" -msg_info "Clonning Shinobi" +msg_info "Cloning Shinobi" cd /opt $STD git clone https://gitlab.com/Shinobi-Systems/Shinobi.git -b master Shinobi cd Shinobi From 026ad7bbec68d9f3f253ea1b100461a5182b3cb6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 07:35:38 -0500 Subject: [PATCH 5482/6505] Update sonarr.sh tweak --- ct/sonarr.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/sonarr.sh b/ct/sonarr.sh index bd0f7342..dbfb22ea 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -55,12 +55,14 @@ header_info if [[ ! -f /etc/apt/sources.list.d/sonarr.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi read -r -p "Are you updating Sonarr v4? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Updating $APP v4" systemctl stop sonarr.service wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/develop/latest?version=4&os=linux' tar -xzf SonarrV4.tar.gz cp -r Sonarr/* /usr/lib/sonarr/bin rm -rf Sonarr SonarrV4.tar.gz systemctl start sonarr.service + msg_ok "Updated $APP v4" exit fi msg_info "Updating $APP LXC" From 72f580664d68fd9fda8d190ff91253af301ebdd2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 12:08:31 -0500 Subject: [PATCH 5483/6505] Update homarr-install.sh --- install/homarr-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index d4f91978..bf26eb19 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -71,6 +71,7 @@ NEXTAUTH_SECRET="1234" EOF $STD yarn install $STD yarn build +$STD yarn db:migrate msg_ok "Installed Homarr" msg_info "Creating Service" From 5998a3c542ff4c3c501e17690c6cfc60ad2cdc79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 12:39:23 -0500 Subject: [PATCH 5484/6505] Update homarr-install.sh --- install/homarr-install.sh | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index bf26eb19..2fe23c2b 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -25,7 +25,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" @@ -44,33 +44,10 @@ msg_ok "Installed Yarn" msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr cd /opt/homarr -cat </opt/homarr/.env -# Since the ".env" file is gitignored, you can use the ".env.example" file to -# build a new ".env" file when you clone the repo. Keep this file up-to-date -# when you add new variables to `.env`. - -# This file will be committed to version control, so make sure not to have any -# secrets in it. If you are cloning this repo, create a copy of this file named -# ".env" and populate it with your secrets. - -# When adding additional environment variables, the schema in "/src/env.js" -# should be updated accordingly. - -# Prisma -# https://www.prisma.io/docs/reference/database-reference/connection-urls#env -DATABASE_URL="file:../database/db.sqlite" - -# Next Auth -# You can generate a new secret on the command line with: -# openssl rand -base64 32 -# https://next-auth.js.org/configuration/options#secret -# NEXTAUTH_SECRET="" -NEXTAUTH_URL="http://localhost:3000" - -NEXTAUTH_SECRET="1234" -EOF $STD yarn install $STD yarn build +cp -p /opt/homarr/.env.example /opt/homarr/.env +sed -i 's/NEXTAUTH_SECRET="[^"]*"/NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"/' /opt/homarr/.env $STD yarn db:migrate msg_ok "Installed Homarr" From 50165e4d38b288dd250e181971d5c08879012236 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 13:03:35 -0500 Subject: [PATCH 5485/6505] Update homarr-install.sh --- install/homarr-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 2fe23c2b..18d37290 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -44,10 +44,10 @@ msg_ok "Installed Yarn" msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr cd /opt/homarr -$STD yarn install -$STD yarn build cp -p /opt/homarr/.env.example /opt/homarr/.env sed -i 's/NEXTAUTH_SECRET="[^"]*"/NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"/' /opt/homarr/.env +$STD yarn install +$STD yarn build $STD yarn db:migrate msg_ok "Installed Homarr" From ef222e11d4a3101ca4b78a6a047a714aa1357462 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 13:13:45 -0500 Subject: [PATCH 5486/6505] Update homarr-install.sh test --- install/homarr-install.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 18d37290..38966a3f 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -28,18 +28,16 @@ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dea echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" -msg_info "Installing Node.js" +msg_info "Installing Node.js/Yarn" $STD apt-get update $STD apt-get install -y nodejs -$STD npm install next -$STD npm instal react -$STD npm instal react-dom -msg_ok "Installed Node.js" - -msg_info "Installing Yarn" +npm install -g npm@latest $STD npm install -g yarn $STD yarn global add prisma -msg_ok "Installed Yarn" +npm install next +$STD npm instal react +$STD npm instal react-dom +msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr From e7436ee55d5a91866097e0bce9f9677820192701 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 13:19:01 -0500 Subject: [PATCH 5487/6505] Update homarr-install.sh test --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 38966a3f..9067e47e 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -34,7 +34,7 @@ $STD apt-get install -y nodejs npm install -g npm@latest $STD npm install -g yarn $STD yarn global add prisma -npm install next +# npm install next $STD npm instal react $STD npm instal react-dom msg_ok "Installed Node.js/Yarn" From 9b251be440f1c39ce87e3c0949968013b981634a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 13:25:57 -0500 Subject: [PATCH 5488/6505] Update homarr-install.sh test --- install/homarr-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 9067e47e..eed6b88e 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -33,10 +33,10 @@ $STD apt-get update $STD apt-get install -y nodejs npm install -g npm@latest $STD npm install -g yarn -$STD yarn global add prisma +#$STD yarn global add prisma # npm install next -$STD npm instal react -$STD npm instal react-dom +#$STD npm install react +#$STD npm install react-dom msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" From 60d5522ec17e4c458af8d7e90a83861195092f90 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 13:36:23 -0500 Subject: [PATCH 5489/6505] Update homarr-install.sh ready for testing --- install/homarr-install.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index eed6b88e..b6e23993 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -31,12 +31,8 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js/Yarn" $STD apt-get update $STD apt-get install -y nodejs -npm install -g npm@latest +$STD npm install -g npm@latest $STD npm install -g yarn -#$STD yarn global add prisma -# npm install next -#$STD npm install react -#$STD npm install react-dom msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" From 3ecfbe91e25dac00727faeaf345fd030481048f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 14:17:12 -0500 Subject: [PATCH 5490/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7bd0170..2292f503 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-11 + +### Changed + +- **Homarr LXC** + - Returns + ## 2023-11-9 ### Changed From fa44c278fb1e9cfef25dfd32d2d349062624da19 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 15:44:33 -0500 Subject: [PATCH 5491/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2292f503..4aa6dfa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ ### Changed - **Homarr LXC** - - Returns + - Returns with v0.14.0 (The authentication update). ## 2023-11-9 From 8185b09e010d02e57dda0f045cee913d1f8bdfc9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 Nov 2023 19:35:32 -0500 Subject: [PATCH 5492/6505] Update vaultwarden.sh default Debian 12 --- ct/vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index b804f195..3600f984 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -23,7 +23,7 @@ var_disk="6" var_cpu="4" var_ram="4096" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 161e51796a2551a9500b49dd9a8631f81c9349bf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 Nov 2023 01:16:05 -0500 Subject: [PATCH 5493/6505] default Debian 12 - autobrr - jackett - transmission --- ct/autobrr.sh | 2 +- ct/jackett.sh | 2 +- ct/transmission.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/autobrr.sh b/ct/autobrr.sh index c3f79c42..8365bc1a 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/jackett.sh b/ct/jackett.sh index 892e2da2..c005c552 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/transmission.sh b/ct/transmission.sh index fd8a5c2d..25c07b54 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 53f0f7493aef0634f7fe8b1848168125012be820 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 11:34:32 -0500 Subject: [PATCH 5494/6505] Update homarr-install.sh change delimiter in sed command --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index b6e23993..958dc10e 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -39,7 +39,7 @@ msg_info "Installing Homarr (Patience)" git clone -q https://github.com/ajnart/homarr.git /opt/homarr cd /opt/homarr cp -p /opt/homarr/.env.example /opt/homarr/.env -sed -i 's/NEXTAUTH_SECRET="[^"]*"/NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"/' /opt/homarr/.env +sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env $STD yarn install $STD yarn build $STD yarn db:migrate From ed6443bc84a7279847cd0906e09c8fe78a7948ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 12:10:15 -0500 Subject: [PATCH 5495/6505] default Debian 12 - Homer - Cronicle Thanks @zelig2 --- ct/cronicle.sh | 2 +- ct/homer.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 4d59253a..08d6a961 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/homer.sh b/ct/homer.sh index fcdc17ac..7d0c8a3a 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 2f824100830be4d6f3e76aae98279a235381c3bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 13:07:18 -0500 Subject: [PATCH 5496/6505] Update blocky-install.sh code refactoring --- install/blocky-install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/install/blocky-install.sh b/install/blocky-install.sh index 6ef5abcc..f7e23b98 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -20,13 +20,13 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Blocky" -systemctl stop systemd-resolved -$STD systemctl disable systemd-resolved.service -RELEASE=0.20 #$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -q https://github.com/0xERR0R/blocky/releases/download/v$RELEASE/blocky_${RELEASE}_Linux_x86_64.tar.gz -mkdir -p /opt/blocky -tar -xf blocky_${RELEASE}_Linux_x86_64.tar.gz -C /opt/blocky -rm -rf blocky_${RELEASE}_Linux_x86_64.tar.gz +if systemctl is-active systemd-resolved > /dev/null 2>&1; then + systemctl disable -q --now systemd-resolved +fi +mkdir /opt/blocky +RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -qO- https://github.com/0xERR0R/blocky/releases/download/v${RELEASE}/blocky_v${RELEASE}_Linux_x86_64.tar.gz | tar -xzf - -C /opt/blocky/ + cat </opt/blocky/config.yml upstream: # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query From 8c8bce10e55fffe81c6fff79a9a29aa364a2290d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 13:07:54 -0500 Subject: [PATCH 5497/6505] Update blocky.sh default Debian 12 --- ct/blocky.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/blocky.sh b/ct/blocky.sh index 049f979d..e90b66fb 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 073aba4d5df39c12cc2efa91809ca40dc699efa1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 15:49:48 -0500 Subject: [PATCH 5498/6505] Update whoogle.sh default Debian 12 --- ct/whoogle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/whoogle.sh b/ct/whoogle.sh index c6054537..d4cb472a 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From f2f9b035b36ccb5c740dd0ef6d1ebc30dda74b79 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 15:54:23 -0500 Subject: [PATCH 5499/6505] default Debian 12 - Podman - Podman-Homeassastant --- ct/podman-homeassistant.sh | 2 +- ct/podman.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index 87b1ed72..a7a6e7a6 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -27,7 +27,7 @@ var_disk="16" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/podman.sh b/ct/podman.sh index bd048a08..d5cf7bf6 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 70d8ce37067cc590f8a466ad89c981fc484dfa7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 16:07:30 -0500 Subject: [PATCH 5500/6505] Update casaos.sh default Debian 12 --- ct/casaos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/casaos.sh b/ct/casaos.sh index 52e9f880..a6dab10d 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From b03ddde9e2617127137da3be25b9611f7817cfee Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 16:12:08 -0500 Subject: [PATCH 5501/6505] Update daemonsync.sh - default Debian 12 Thanks @onethree7 --- ct/daemonsync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index c134ce41..ba536268 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 4748a65692c2f3df6229580dd7c5596104e98eb3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 16:22:39 -0500 Subject: [PATCH 5502/6505] Update prometheus.sh - default Debian 12 Thanks @onethree7 --- ct/prometheus.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 3ee8a3de..c51fb4d3 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="1" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From bbd7393d94fede64dfbbe77342d9fec76d27515e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 17:42:37 -0500 Subject: [PATCH 5503/6505] Update sabnzbd-install.sh fixes https://github.com/tteck/Proxmox/issues/2051 --- install/sabnzbd-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 06c6b19b..fd29e48d 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -19,9 +19,9 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y par2 $STD apt-get install -y p7zip-full -wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_7.0.2-1_amd64.deb -$STD dpkg -i unrar_7.0.2-1_amd64.deb -rm unrar_7.0.2-1_amd64.deb +wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_7.0.3-1_amd64.deb +$STD dpkg -i unrar*.deb +rm unrar*.deb msg_ok "Installed Dependencies" msg_info "Updating Python3" From 19f08297e66994def88174a4e16fe0b048b59d7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 Nov 2023 18:20:59 -0500 Subject: [PATCH 5504/6505] Update sabnzbd-install.sh code refactoring --- install/sabnzbd-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index fd29e48d..0fef42d1 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -19,7 +19,8 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y par2 $STD apt-get install -y p7zip-full -wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/unrar_7.0.3-1_amd64.deb +RELEASE=$(curl -s http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/ | grep -oP 'href="\K[^"]*unrar_7\.\d+\.\d+-\d+_amd64\.deb') +wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/$RELEASE $STD dpkg -i unrar*.deb rm unrar*.deb msg_ok "Installed Dependencies" From 9418ccb1ef67e0a3c95d1fe0fa6ba63bca342da8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 04:19:26 -0500 Subject: [PATCH 5505/6505] default Debian 12 - go2rtc - homebridge - iobroker - motioneye - navidrome - octoprint - rtsptoweb - syncthing - whisparr Thanks @t0rb3n --- ct/go2rtc.sh | 2 +- ct/homebridge.sh | 2 +- ct/iobroker.sh | 2 +- ct/motioneye.sh | 2 +- ct/navidrome.sh | 2 +- ct/octoprint.sh | 2 +- ct/rtsptoweb.sh | 2 +- ct/syncthing.sh | 2 +- ct/whisparr.sh | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 89c7405b..5fd59314 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 7522a7f4..1c10dd00 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 8feef540..f2577806 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 8ec8f6a2..244738c8 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/navidrome.sh b/ct/navidrome.sh index 258c0acd..c7d9c290 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/octoprint.sh b/ct/octoprint.sh index 3d4cb3e0..e0c38fa4 100644 --- a/ct/octoprint.sh +++ b/ct/octoprint.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="1" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/rtsptoweb.sh b/ct/rtsptoweb.sh index ce040eb5..e0208273 100644 --- a/ct/rtsptoweb.sh +++ b/ct/rtsptoweb.sh @@ -23,7 +23,7 @@ var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/syncthing.sh b/ct/syncthing.sh index b45fcfd8..0cfce841 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -24,7 +24,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors diff --git a/ct/whisparr.sh b/ct/whisparr.sh index 4304d4aa..df39c2f9 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 6ef30fbeb9cd07e53244110e20c9441d102ead28 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 07:31:43 -0500 Subject: [PATCH 5506/6505] Update homarr-install.sh fixes https://github.com/tteck/Proxmox/issues/2054 --- install/homarr-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 958dc10e..13d97470 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -36,7 +36,9 @@ $STD npm install -g yarn msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" -git clone -q https://github.com/ajnart/homarr.git /opt/homarr +mkdir -p /opt/homarr +RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt && mv /opt/homarr-${RELEASE} /opt/homarr cd /opt/homarr cp -p /opt/homarr/.env.example /opt/homarr/.env sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env From 866cf119ce168f34c9055496981ea4d865907ac5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 07:41:32 -0500 Subject: [PATCH 5507/6505] Update homarr-install.sh --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 13d97470..bc7c805d 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -38,7 +38,7 @@ msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" mkdir -p /opt/homarr RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt && mv /opt/homarr-${RELEASE} /opt/homarr +wget -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr cd /opt/homarr cp -p /opt/homarr/.env.example /opt/homarr/.env sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env From 2a13cce5b5d19841010e16f4c74ac6e1e93f3cec Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 07:45:40 -0500 Subject: [PATCH 5508/6505] Update homarr-install.sh --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index bc7c805d..01f7c9f1 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -38,7 +38,7 @@ msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" mkdir -p /opt/homarr RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr +wget -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | $STD tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr cd /opt/homarr cp -p /opt/homarr/.env.example /opt/homarr/.env sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env From 2c3a3292608361ba79f175864504c924aecd4d8b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 07:50:39 -0500 Subject: [PATCH 5509/6505] Update homarr-install.sh --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 01f7c9f1..fbf2790f 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -40,7 +40,7 @@ mkdir -p /opt/homarr RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | $STD tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr cd /opt/homarr -cp -p /opt/homarr/.env.example /opt/homarr/.env +wget -q -O /opt/homarr/.env https://raw.githubusercontent.com/ajnart/homarr/dev/.env.example sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env $STD yarn install $STD yarn build From f8b1d7600c096cdfa4718c680663264a90393229 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 07:57:30 -0500 Subject: [PATCH 5510/6505] Update homarr.sh increase storage --- ct/homarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index 4f327ec7..ee27dd03 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -19,7 +19,7 @@ EOF header_info echo -e "Loading..." APP="Homarr" -var_disk="4" +var_disk="6" var_cpu="2" var_ram="2048" var_os="debian" From 8f8f5e27feb36913e756d650e4da705074a812f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 08:09:13 -0500 Subject: [PATCH 5511/6505] Update homarr-install.sh --- install/homarr-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index fbf2790f..fbd6c11e 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -38,7 +38,8 @@ msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" mkdir -p /opt/homarr RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | $STD tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr +wget -q -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | $STD tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr +rm -rf /opt/homarr-0.14.0 cd /opt/homarr wget -q -O /opt/homarr/.env https://raw.githubusercontent.com/ajnart/homarr/dev/.env.example sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env From f35cf214e4329fbf23f139d0a40618ea1bb0c94f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 08:10:00 -0500 Subject: [PATCH 5512/6505] Update homarr.sh increase storage --- ct/homarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index ee27dd03..05b4f204 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -19,7 +19,7 @@ EOF header_info echo -e "Loading..." APP="Homarr" -var_disk="6" +var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" From bc6b4d51f978c05f4991b89b15ac1c5cf115bd77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 08:21:09 -0500 Subject: [PATCH 5513/6505] Update homarr-install.sh tweak --- install/homarr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index fbd6c11e..94a4d760 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -39,7 +39,7 @@ msg_info "Installing Homarr (Patience)" mkdir -p /opt/homarr RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget -q -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | $STD tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr -rm -rf /opt/homarr-0.14.0 +rm -rf /opt/homarr-${RELEASE} cd /opt/homarr wget -q -O /opt/homarr/.env https://raw.githubusercontent.com/ajnart/homarr/dev/.env.example sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env From 7851ed6b70d2adfb9de27cba0514a412deebf3ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 09:36:00 -0500 Subject: [PATCH 5514/6505] Update turnkey.sh fixes https://github.com/tteck/Proxmox/issues/2055 --- turnkey/turnkey.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index a77573b5..d49a7b19 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -97,7 +97,6 @@ turnkey=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs # Setup script environment PASS="$(openssl rand -base64 8)" CTID=$(pvesh get /cluster/nextid) -TEMPLATE_SEARCH="debian-11-turnkey-${turnkey}" PCT_OPTIONS=" -features keyctl=1,nesting=1 -hostname turnkey-${turnkey} @@ -175,8 +174,8 @@ msg "Updating LXC template list..." pveam update >/dev/null # Get LXC template string -mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V) -[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '$TEMPLATE_SEARCH'." +mapfile -t TEMPLATES < <(pveam available -section turnkeylinux | awk -v turnkey="${turnkey}" '$0 ~ turnkey {print $2}' | sort -t - -k 2 -V) +[ ${#TEMPLATES[@]} -gt 0 ] || die "Unable to find a template when searching for '${turnkey}'." TEMPLATE="${TEMPLATES[-1]}" # Download LXC template From 587ae7ab3f96aa78d249c76a5cc9392b1c1f5293 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 11:33:48 -0500 Subject: [PATCH 5515/6505] Create owncloud-vm.sh --- vm/owncloud-vm.sh | 420 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 vm/owncloud-vm.sh diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh new file mode 100644 index 00000000..03fd3fd5 --- /dev/null +++ b/vm/owncloud-vm.sh @@ -0,0 +1,420 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ______ __ __ _______ __ _ ____ ___ +/_ __/_ _________ / //_/__ __ __ ___ _ _____ / ___/ /__ __ _____/ / | | / / |/ / + / / / // / __/ _ \/ ,< / -_) // / / _ \ |/|/ / _ \/ /__/ / _ \/ // / _ / | |/ / /|_/ / +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / \___/__,__/_//_/\___/_/\___/\_,_/\_,_/ |___/_/ /_/ + /___/ +EOF +} +header_info +echo -e "\n Loading..." +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +NEXTID=$(pvesh get /cluster/nextid) + +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +THIN="discard=on,ssd=1," +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +trap cleanup EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid +} + +function cleanup_vmid() { + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey-ownCloud VM" --yesno "This will create a New TurnKey-ownCloud VM. Proceed?" 10 58; then + : +else + header_info && echo -e "⚠ User exited script \n" && exit +fi + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function check_root() { + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + +function pve_check() { + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + msg_error "This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function ssh_check() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function default_settings() { + VMID="$NEXTID" + FORMAT=",efitype=4m" + MACHINE="" + DISK_CACHE="" + HN="turnkey-owncloud-vm" + CPU_TYPE="" + CORE_COUNT="2" + RAM_SIZE="2048" + BRG="vmbr0" + MAC="$GEN_MAC" + VLAN="" + MTU="" + START_VM="yes" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + echo -e "${BL}Creating a TurnKey ownCloud VM using the above default settings${CL}" +} + +function advanced_settings() { + while true; do + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + exit-script + fi + done + + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "i440fx" "Machine i440fx" ON \ + "q35" "Machine q35" OFF \ + 3>&1 1>&2 2>&3); then + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" + fi + else + exit-script + fi + + if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "None (Default)" ON \ + "1" "Write Through" OFF \ + 3>&1 1>&2 2>&3); then + if [ $DISK_CACHE = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + DISK_CACHE="" + fi + else + exit-script + fi + + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 turnkey-owncloud-vm --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="turnkey-owncloud-vm" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + else + exit-script + fi + + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "KVM64 (Default)" ON \ + "1" "Host" OFF \ + 3>&1 1>&2 2>&3); then + if [ $CPU_TYPE1 = "1" ]; then + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + CPU_TYPE=" -cpu host" + else + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + CPU_TYPE="" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="2048" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + else + exit-script + fi + + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + else + exit-script + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a TurnKey ownCloud VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a TurnKey ownCloud VM using the above advanced settings${CL}" + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function start_script() { + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +check_root +arch_check +pve_check +ssh_check +start_script + +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + msg_error "Unable to detect a valid storage location." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Retrieving the URL for the TurnKey ownCloud ISO Disk Image" +URL=http://mirror.turnkeylinux.org/turnkeylinux/images/iso/turnkey-owncloud-18.0-bookworm-amd64.iso +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}${FILE}${CL}" + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in +nfs | dir) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + THIN="" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done + +msg_info "Creating a TurnKey ownCloud VM" +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios seabios${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=12G \ + -boot order=scsi0 \ + -description "# TurnKey ownCloud VM +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null +msg_ok "Created a TurnKey ownCloud VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then + msg_info "Starting TurnKey ownCloud VM" + qm start $VMID + msg_ok "Started TurnKey ownCloud VM" +fi +msg_ok "Completed Successfully!\n" From ac546e3f42478d81a9730ec76a22c481b0f82937 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 11:54:11 -0500 Subject: [PATCH 5516/6505] Create nextcloud-vm.sh --- vm/nextcloud-vm.sh | 420 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 vm/nextcloud-vm.sh diff --git a/vm/nextcloud-vm.sh b/vm/nextcloud-vm.sh new file mode 100644 index 00000000..c4074aaa --- /dev/null +++ b/vm/nextcloud-vm.sh @@ -0,0 +1,420 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ______ __ __ _ __ __ __ _ ____ ___ +/_ __/_ _________ / //_/__ __ __ / |/ /____ ______/ /__ __ _____/ / | | / / |/ / + / / / // / __/ _ \/ ,< / -_) // / / / -_) \ / __/ / _ \/ // / _ / | |/ / /|_/ / +/_/ \_,_/_/ /_//_/_/|_|\__/\_, / /_/|_/\__/_\_\\__/_/\___/\_,_/\_,_/ |___/_/ /_/ + /___/ +EOF +} +header_info +echo -e "\n Loading..." +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +NEXTID=$(pvesh get /cluster/nextid) +NAME="TurnKey Nexcloud VM" +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +THIN="discard=on,ssd=1," +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +trap cleanup EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid +} + +function cleanup_vmid() { + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "$NAME" --yesno "This will create a New $NAME. Proceed?" 10 58; then + : +else + header_info && echo -e "⚠ User exited script \n" && exit +fi + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function check_root() { + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + +function pve_check() { + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + msg_error "This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function ssh_check() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function default_settings() { + VMID="$NEXTID" + FORMAT=",efitype=4m" + MACHINE="" + DISK_CACHE="" + HN="turnkey-nextcloud-vm" + CPU_TYPE="" + CORE_COUNT="2" + RAM_SIZE="2048" + BRG="vmbr0" + MAC="$GEN_MAC" + VLAN="" + MTU="" + START_VM="no" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + echo -e "${BL}Creating a $NAME using the above default settings${CL}" +} + +function advanced_settings() { + while true; do + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + exit-script + fi + done + + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "i440fx" "Machine i440fx" ON \ + "q35" "Machine q35" OFF \ + 3>&1 1>&2 2>&3); then + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" + fi + else + exit-script + fi + + if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "None (Default)" ON \ + "1" "Write Through" OFF \ + 3>&1 1>&2 2>&3); then + if [ $DISK_CACHE = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + DISK_CACHE="" + fi + else + exit-script + fi + + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 $HN --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="$HN" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + else + exit-script + fi + + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "KVM64 (Default)" ON \ + "1" "Host" OFF \ + 3>&1 1>&2 2>&3); then + if [ $CPU_TYPE1 = "1" ]; then + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + CPU_TYPE=" -cpu host" + else + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + CPU_TYPE="" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="2048" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + else + exit-script + fi + + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + else + exit-script + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a $NAME?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a $NAME using the above advanced settings${CL}" + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function start_script() { + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +check_root +arch_check +pve_check +ssh_check +start_script + +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + msg_error "Unable to detect a valid storage location." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Retrieving the URL for the $NAME Disk Image" +URL=http://mirror.turnkeylinux.org/turnkeylinux/images/iso/turnkey-nextcloud-18.0-bookworm-amd64.iso +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}${FILE}${CL}" + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in +nfs | dir) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + THIN="" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done + +msg_info "Creating a $NAME" +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios seabios${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=12G \ + -boot order=scsi0 \ + -description "# $NAME +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null +msg_ok "Created a $NAME ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then + msg_info "Starting $NAME" + qm start $VMID + msg_ok "Started $NAME" +fi +msg_ok "Completed Successfully!\n" From 9c4aa5410bb83635c5a6e0508a9ffa858a3f5eba Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 12:13:25 -0500 Subject: [PATCH 5517/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aa6dfa9..f75daa3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-14 + +### Changed + +- **TurnKey Nextcloud VM** + - NEW Script +- **TurnKey ownCloud VM** + - NEW Script + ## 2023-11-11 ### Changed From 897c75478e997de4ee2a87a81c214de1e71f4f02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 13:02:13 -0500 Subject: [PATCH 5518/6505] Update owncloud-vm.sh tweak --- vm/owncloud-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh index 03fd3fd5..c41c1124 100644 --- a/vm/owncloud-vm.sh +++ b/vm/owncloud-vm.sh @@ -141,7 +141,7 @@ function default_settings() { MAC="$GEN_MAC" VLAN="" MTU="" - START_VM="yes" + START_VM="no" echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" From a53f2e50aa07db23dc6c5875d58a2e0da2ff02a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 16:04:40 -0500 Subject: [PATCH 5519/6505] Update homarr.sh --- ct/homarr.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/homarr.sh b/ct/homarr.sh index 05b4f204..a340dbcd 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -53,6 +53,8 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/homarr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit msg_info "Updating $APP" systemctl stop homarr cd /opt/homarr From 3fd87569dfabb5b0a65c48fc9cf3b8cfe46e7377 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 Nov 2023 17:28:08 -0500 Subject: [PATCH 5520/6505] Update homarr.sh attempt to fix update --- ct/homarr.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index a340dbcd..340cc11f 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -53,18 +53,18 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/homarr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." -exit -msg_info "Updating $APP" +msg_info "Updating $APP (Patience)" systemctl stop homarr +cp -Rf /opt/homarr/data /opt/homarr/data-backup +cp -Rf /opt/homarr/database /opt/homarr/data-backup +RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt +cp -Rf /opt/homarr-${RELEASE}/* /opt/homarr/ +cp -Rf /opt/homarr/data-backup/* /opt/homarr/ +rm -rf /opt/homarr-${RELEASE} /opt/homarr/data-backup cd /opt/homarr -cp -R data data-backup -git stash &>/dev/null -git pull &>/dev/null yarn install &>/dev/null yarn build &>/dev/null -cp -R data-backup/* data -rm -rf data-backup systemctl start homarr msg_ok "Updated $APP" exit From 634283c04e746c4bfff61d82b3b7debb735641a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Nov 2023 07:50:51 -0500 Subject: [PATCH 5521/6505] Update zigbee2mqtt.sh follow https://github.com/Koenkk/zigbee2mqtt/commit/311ea070b167ddc6d8de1f8922aed0d8b38025d7 --- ct/zigbee2mqtt.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 14b75066..9f679fe6 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -94,7 +94,13 @@ function update_script() { exit 1 } - echo "Initiating update" + echo "Checking if any changes were made to package-lock.json..." + git checkout package-lock.json || { + echo "Failed to check package-lock.json." + exit 1 + } + + echo "Initiating update..." if ! git pull; then echo "Update failed, temporarily storing changes and trying again." git stash && git pull || ( @@ -109,6 +115,12 @@ function update_script() { exit 1 } + echo "Building..." + npm run build || { + echo "Failed to build new version." + exit 1 + } + echo "Restoring configuration..." cp -R data-backup/* data || { echo "Failed to restore configuration." From c968f07e42685ac00704729d2cf567a48159b34f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 15 Nov 2023 19:22:40 -0500 Subject: [PATCH 5522/6505] Update debian-vm.sh tweak --- vm/debian-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index feaf5238..bd86e7a9 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -154,7 +154,7 @@ function default_settings() { echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" echo -e "${BL}Creating a Debian 12 VM using the above default settings${CL}" } From 48f59062462c0470d6b2027a228487bbd5d738e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 Nov 2023 10:39:04 -0500 Subject: [PATCH 5523/6505] Update debian-vm.sh - add serial0 socket --- vm/debian-vm.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index bd86e7a9..b549f062 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -409,6 +409,7 @@ qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \ -boot order=scsi0 \ + -serial0 socket \ -description "# Debian 12 VM ### https://github.com/tteck/Proxmox [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null @@ -419,3 +420,4 @@ if [ "$START_VM" == "yes" ]; then msg_ok "Started Debian 12 VM" fi msg_ok "Completed Successfully!\n" +echo "More Info at https://github.com/tteck/Proxmox/discussions/1988" From 26230754af1445be9902474638700d9a146f03dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 Nov 2023 18:20:09 -0500 Subject: [PATCH 5524/6505] Update homarr.sh - fix backup/restore paths - keep backups until the next update (root directory) --- ct/homarr.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index 340cc11f..94ce3640 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -55,13 +55,15 @@ header_info if [[ ! -d /opt/homarr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating $APP (Patience)" systemctl stop homarr -cp -Rf /opt/homarr/data /opt/homarr/data-backup -cp -Rf /opt/homarr/database /opt/homarr/data-backup +rm -rf /root/data-homarr-backup +rm -rf /root/database-homarr-backup +cp -R /opt/homarr/data /root/data-homarr-backup +cp -R /opt/homarr/database /root/database-homarr-backup RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget -q -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt -cp -Rf /opt/homarr-${RELEASE}/* /opt/homarr/ -cp -Rf /opt/homarr/data-backup/* /opt/homarr/ -rm -rf /opt/homarr-${RELEASE} /opt/homarr/data-backup +cp -R /root/data-homarr-backup/* /opt/homarr/data +cp -R /root/database-homarr-backup/* /opt/homarr/database +rm -rf /opt/homarr-${RELEASE} cd /opt/homarr yarn install &>/dev/null yarn build &>/dev/null From 03ea3fb8dd83749c73e09b1711d43c35e55840e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 Nov 2023 19:38:59 -0500 Subject: [PATCH 5525/6505] Update esphome-install.sh - revert https://github.com/tteck/Proxmox/commit/5dc1cf587096c05eacd5b82693886886d6eca802 - fixes https://github.com/tteck/Proxmox/issues/2062 --- install/esphome-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 8961664b..5b5a8d1f 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -29,6 +29,7 @@ $STD apt-get install -y \ msg_ok "Updated Python3" msg_info "Installing ESPHome" +mkdir /root/config $STD pip install esphome tornado esptool msg_ok "Installed ESPHome" @@ -39,7 +40,7 @@ Description=ESPHome Dashboard After=network.target [Service] -ExecStart=/usr/local/bin/esphome dashboard /root/.config/ +ExecStart=/usr/local/bin/esphome dashboard /root/config/ Restart=always User=root From b3784e4df4d80d8136a7c7e83cd32ddd5875ee8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 Nov 2023 05:11:58 -0500 Subject: [PATCH 5526/6505] Update navidrome-install.sh fixes https://github.com/tteck/Proxmox/issues/2065 --- install/navidrome-install.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh index d1a890db..b5a003af 100644 --- a/install/navidrome-install.sh +++ b/install/navidrome-install.sh @@ -20,14 +20,12 @@ $STD apt-get install -y mc $STD apt-get install -y ffmpeg msg_ok "Installed Dependencies" -RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') +RELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') msg_info "Installing Navidrome" install -d -o root -g root /opt/navidrome install -d -o root -g root /var/lib/navidrome -$STD wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz +wget -q https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_linux_amd64.tar.gz -O Navidrome.tar.gz $STD tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ chown -R root:root /opt/navidrome mkdir -p /music From b8222e26fc16b2a6f7962934ad24a1775b742ccf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 Nov 2023 05:14:28 -0500 Subject: [PATCH 5527/6505] Update navidrome.sh fix file name --- ct/navidrome.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/navidrome.sh b/ct/navidrome.sh index c7d9c290..4062fd7f 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -59,7 +59,7 @@ systemctl stop navidrome.service msg_ok "Stopped Navidrome" msg_info "Updating to v${RELEASE}" -wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_Linux_x86_64.tar.gz -O Navidrome.tar.gz &>/dev/null +wget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_linux_amd64.tar.gz -O Navidrome.tar.gz &>/dev/null tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null msg_ok "Updated ${APP}" rm Navidrome.tar.gz From f2aed7d532d04fa29edf16c32c9329bc4398e3d5 Mon Sep 17 00:00:00 2001 From: efr2et Date: Fri, 17 Nov 2023 16:35:23 +0200 Subject: [PATCH 5528/6505] Update syncthing-install.sh (#2066) Fix "301 Moved Permanently" for curl --- install/syncthing-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh index 3e8eef08..6fe0f10a 100644 --- a/install/syncthing-install.sh +++ b/install/syncthing-install.sh @@ -21,7 +21,7 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Installing Syncthing" -curl -s -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg +curl -sL -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg sh -c 'echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" > /etc/apt/sources.list.d/syncthing.list' $STD apt-get update $STD apt-get install -y syncthing From b422923ea70ee2df62a5e19e87aced7435225e30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Nov 2023 12:13:11 -0500 Subject: [PATCH 5529/6505] Update changedetection-install.sh remove dnspython-2.2.1 --- install/changedetection-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 7ad0e307..91f6e681 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -67,7 +67,6 @@ msg_ok "Installed Node.js" msg_info "Installing Change Detection" mkdir /opt/changedetection $STD pip3 install changedetection.io -$STD python3 -m pip install dnspython==2.2.1 msg_ok "Installed Change Detection" msg_info "Installing Browserless & Playwright" From eb6fd78fa6d8711496a958bf83f2bd7d958f222f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Nov 2023 16:58:19 -0500 Subject: [PATCH 5530/6505] Create ubuntu-vm.sh --- vm/ubuntu-vm.sh | 424 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 vm/ubuntu-vm.sh diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh new file mode 100644 index 00000000..4da0d913 --- /dev/null +++ b/vm/ubuntu-vm.sh @@ -0,0 +1,424 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ ____ __ ___ ___ ____ __ __ _ ____ ___ + / / / / /_ __ ______ / /___ __ |__ \|__ \ / __ \/ // / | | / / |/ / + / / / / __ \/ / / / __ \/ __/ / / / __/ /__/ / / / / / // /_ | | / / /|_/ / +/ /_/ / /_/ / /_/ / / / / /_/ /_/ / / __// __/_/ /_/ /__ __/ | |/ / / / / +\____/_.___/\__,_/_/ /_/\__/\__,_/ /____/____(_)____/ /_/ |___/_/ /_/ + +EOF +} +header_info +echo -e "\n Loading..." +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +NEXTID=$(pvesh get /cluster/nextid) + +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +THIN="discard=on,ssd=1," +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +trap cleanup EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid +} + +function cleanup_vmid() { + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Ubuntu 22.04 VM" --yesno "This will create a New Ubuntu 22.04 VM. Proceed?" 10 58; then + : +else + header_info && echo -e "⚠ User exited script \n" && exit +fi + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function check_root() { + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + +function pve_check() { + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + msg_error "This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function ssh_check() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function default_settings() { + VMID="$NEXTID" + FORMAT=",efitype=4m" + MACHINE="" + DISK_CACHE="" + HN="ubuntu" + CPU_TYPE="" + CORE_COUNT="2" + RAM_SIZE="2048" + BRG="vmbr0" + MAC="$GEN_MAC" + VLAN="" + MTU="" + START_VM="no" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + echo -e "${BL}Creating a Ubuntu 22.04 VM using the above default settings${CL}" +} + +function advanced_settings() { + while true; do + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + exit-script + fi + done + + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "i440fx" "Machine i440fx" ON \ + "q35" "Machine q35" OFF \ + 3>&1 1>&2 2>&3); then + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" + fi + else + exit-script + fi + + if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "None (Default)" ON \ + "1" "Write Through" OFF \ + 3>&1 1>&2 2>&3); then + if [ $DISK_CACHE = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + DISK_CACHE="" + fi + else + exit-script + fi + + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 ubuntu --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="ubuntu" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + else + exit-script + fi + + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "KVM64 (Default)" ON \ + "1" "Host" OFF \ + 3>&1 1>&2 2>&3); then + if [ $CPU_TYPE1 = "1" ]; then + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + CPU_TYPE=" -cpu host" + else + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + CPU_TYPE="" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="2048" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + else + exit-script + fi + + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + else + exit-script + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Ubuntu 22.04 VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a Ubuntu 22.04 VM using the above advanced settings${CL}" + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function start_script() { + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +check_root +arch_check +pve_check +ssh_check +start_script + +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + msg_error "Unable to detect a valid storage location." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Retrieving the URL for the Ubuntu 22.04 Disk Image" +URL=https://cloud-images.ubuntu.com/jammy/20231027/jammy-server-cloudimg-amd64.img +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}${FILE}${CL}" + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in +nfs | dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + THIN="" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done + +msg_info "Creating a Ubuntu 22.04 VM" +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \ + -ide2 local-lvm:cloudinit \ + -boot order=scsi0 \ + -serial0 socket \ + -description "# Ubuntu 22.04 VM +### https://github.com/tteck/Proxmox +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null +msg_ok "Created a Ubuntu 22.04 VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then + msg_info "Starting Ubuntu 22.04 VM" + qm start $VMID + msg_ok "Started Ubuntu 22.04 VM" +fi +msg_ok "Completed Successfully!\n" +echo "Setup Cloud-Init before starting" From 8c3fd6f90da3a2a6d8e798914da8c2a7df1b9bcb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Nov 2023 17:42:31 -0500 Subject: [PATCH 5531/6505] Update ubuntu-vm.sh tweak --- vm/ubuntu-vm.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index 4da0d913..d44d404f 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -155,7 +155,7 @@ function default_settings() { echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" - echo -e "${BL}Creating a Ubuntu 22.04 VM using the above default settings${CL}" + echo -e "${BL}Creating an Ubuntu 22.04 VM using the above default settings${CL}" } function advanced_settings() { @@ -314,8 +314,8 @@ function advanced_settings() { START_VM="no" fi - if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Ubuntu 22.04 VM?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a Ubuntu 22.04 VM using the above advanced settings${CL}" + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create an Ubuntu 22.04 VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating an Ubuntu 22.04 VM using the above advanced settings${CL}" else header_info echo -e "${RD}Using Advanced Settings${CL}" @@ -421,4 +421,5 @@ if [ "$START_VM" == "yes" ]; then msg_ok "Started Ubuntu 22.04 VM" fi msg_ok "Completed Successfully!\n" -echo "Setup Cloud-Init before starting" +echo -e "Setup Cloud-Init before starting \n +More info at https://github.com/tteck/Proxmox/discussions/2072 \n" From 12d7efc7283662be4aff529ea668c15edabefa51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Nov 2023 18:06:08 -0500 Subject: [PATCH 5532/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f75daa3f..fc50e917 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ +## 2023-11-18 + +### Changed + +- **Ubuntu 22.04 VM** + - NEW Script + # Change Log **All notable changes to this project will be documented in this file.**
    From a9e67dc9d5bdfe747729096b07a55429d6152e6c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 Nov 2023 20:47:42 -0500 Subject: [PATCH 5533/6505] Update CHANGELOG.md --- CHANGELOG.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc50e917..38474a38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ - + +# Change Log +**All notable changes to this project will be documented in this file.**
    + +- All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. ## 2023-11-18 @@ -7,11 +11,6 @@ - **Ubuntu 22.04 VM** - NEW Script -# Change Log -**All notable changes to this project will be documented in this file.**
    - -- All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - ## 2023-11-14 ### Changed From 29efbdd2eb0a2e9c16a02fc6d7d311b1cd3bdc9f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Nov 2023 08:35:07 -0500 Subject: [PATCH 5534/6505] Create dockge.sh --- ct/dockge.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ct/dockge.sh diff --git a/ct/dockge.sh b/ct/dockge.sh new file mode 100644 index 00000000..756fac46 --- /dev/null +++ b/ct/dockge.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \____ _____/ /______ ____ + / / / / __ \/ ___/ //_/ __ `/ _ \ + / /_/ / /_/ / /__/ ,< / /_/ / __/ +/_____/\____/\___/_/|_|\__, /\___/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Dockge" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + FUSE="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5001${CL} \n" From d8cb2f19d2d8b1469f6fac4c3ff7dc7a3dc43d3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Nov 2023 08:36:33 -0500 Subject: [PATCH 5535/6505] Create dockge-install.sh --- install/dockge-install.sh | 89 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 install/dockge-install.sh diff --git a/install/dockge-install.sh b/install/dockge-install.sh new file mode 100644 index 00000000..ad4834f6 --- /dev/null +++ b/install/dockge-install.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +get_latest_release() { + curl -sL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") + +msg_info "Installing Docker $DOCKER_LATEST_VERSION" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +if [ "$ST" == "yes" ]; then + VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + cd /usr/local/bin + curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 + chmod 755 /usr/local/bin/fuse-overlayfs + cd ~ + echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' >/etc/docker/daemon.json +else + echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json +fi +$STD sh <(curl -sSL https://get.docker.com) +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" + +msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" +DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} +mkdir -p $DOCKER_CONFIG/cli-plugins +curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose +chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose +msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" + +msg_info "Installing Dockge" +mkdir -p /opt/stacks /opt/dockge +cd /opt/dockge +$STD curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml +$STD docker compose up -d +msg_ok "Installed Dockge" + +read -r -p "Would you like to add Home Assistant? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Adding Home Assistant compose.yaml" + mkdir -p /opt/stacks/homeassistant + cat </opt/stacks/homeassistant/compose.yaml +version: "3.3" +services: + home-assistant: + container_name: homeassistant + privileged: true + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /dev:/dev + - ha_config:/config + network_mode: host + image: ghcr.io/home-assistant/home-assistant:stable +volumes: + ha_config: {} +networks: {} +EOF +msg_ok "Added Home Assistant compose.yaml" +fi + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 804aeaabb73cf66c61c1b613f6ac07a7d5d42f73 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Nov 2023 08:41:11 -0500 Subject: [PATCH 5536/6505] Update dockge-install.sh tweak --- install/dockge-install.sh | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/install/dockge-install.sh b/install/dockge-install.sh index ad4834f6..eec8bec6 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -29,16 +29,7 @@ DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then - VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - cd /usr/local/bin - curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 - chmod 755 /usr/local/bin/fuse-overlayfs - cd ~ - echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' >/etc/docker/daemon.json -else - echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json -fi +echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json $STD sh <(curl -sSL https://get.docker.com) msg_ok "Installed Docker $DOCKER_LATEST_VERSION" From 7f6521e3c7247591ded69ee78fa3e057825e14d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 Nov 2023 09:10:28 -0500 Subject: [PATCH 5537/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38474a38..1fe7b7e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-19 + +### Changed + +- **Dockge LXC** + - NEW Script + ## 2023-11-18 ### Changed From 46533c082b40477c6c664ae5bd8e5ecf7a65c318 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Nov 2023 07:46:08 -0500 Subject: [PATCH 5538/6505] Update dockge-install.sh option to add Immich --- install/dockge-install.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/install/dockge-install.sh b/install/dockge-install.sh index eec8bec6..20108196 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -47,6 +47,16 @@ $STD curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml $STD docker compose up -d msg_ok "Installed Dockge" +read -r -p "Would you like to add Immich? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Adding Immich compose.yaml" + mkdir -p /opt/stacks/immich + wget -q -O /opt/stacks/immich/compose.yaml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml + wget -q -O /opt/stacks/immich/.env https://github.com/immich-app/immich/releases/latest/download/example.env + wget -q -O /opt/stacks/immich/hwaccel.yaml https://github.com/immich-app/immich/releases/latest/download/hwaccel.yml + msg_ok "Added Immich compose.yaml" +fi + read -r -p "Would you like to add Home Assistant? " prompt if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then msg_info "Adding Home Assistant compose.yaml" @@ -61,6 +71,7 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock - /dev:/dev + - /etc/localtime:/etc/localtime:ro - ha_config:/config network_mode: host image: ghcr.io/home-assistant/home-assistant:stable From f3b501d37a979ae70a79d02e71dde66378640ca1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Nov 2023 07:54:39 -0500 Subject: [PATCH 5539/6505] Update dockge-install.sh tweak --- install/dockge-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dockge-install.sh b/install/dockge-install.sh index 20108196..7d57b1cc 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -53,7 +53,7 @@ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then mkdir -p /opt/stacks/immich wget -q -O /opt/stacks/immich/compose.yaml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml wget -q -O /opt/stacks/immich/.env https://github.com/immich-app/immich/releases/latest/download/example.env - wget -q -O /opt/stacks/immich/hwaccel.yaml https://github.com/immich-app/immich/releases/latest/download/hwaccel.yml + wget -q -O /opt/stacks/immich/hwaccel.yml https://github.com/immich-app/immich/releases/latest/download/hwaccel.yml msg_ok "Added Immich compose.yaml" fi From 22dd71822e5772fe6a5c71335dfc47766faf71ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Nov 2023 07:55:52 -0500 Subject: [PATCH 5540/6505] Update dockge.sh increase storage --- ct/dockge.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/dockge.sh b/ct/dockge.sh index 756fac46..155ef799 100644 --- a/ct/dockge.sh +++ b/ct/dockge.sh @@ -19,7 +19,7 @@ EOF header_info echo -e "Loading..." APP="Dockge" -var_disk="8" +var_disk="18" var_cpu="2" var_ram="2048" var_os="debian" From cd4faadeb6108fc2ea668fc5eaef9126a96a5844 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Nov 2023 09:06:43 -0500 Subject: [PATCH 5541/6505] Update dockge.sh create update path --- ct/dockge.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ct/dockge.sh b/ct/dockge.sh index 155ef799..64cc093e 100644 --- a/ct/dockge.sh +++ b/ct/dockge.sh @@ -53,11 +53,12 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" +if [[ ! -d /opt/dockge ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +cd /opt/dockge +docker compose pull +docker compose up -d +msg_ok "Updated ${APP}" exit } From 6c643e39d1726b0f6a008e90c1fb1c1c45e4e8e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Nov 2023 13:03:09 -0500 Subject: [PATCH 5542/6505] Update dockge-install.sh tweak --- install/dockge-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/dockge-install.sh b/install/dockge-install.sh index 7d57b1cc..988c56f2 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -41,9 +41,9 @@ chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" msg_info "Installing Dockge" -mkdir -p /opt/stacks /opt/dockge +mkdir -p /opt/{dockge,stacks} +wget -q -O /opt/dockge/compose.yaml https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml cd /opt/dockge -$STD curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml $STD docker compose up -d msg_ok "Installed Dockge" From a697e5af52517dd63b11b3cb2f0f82c83e8108b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 Nov 2023 17:46:05 -0500 Subject: [PATCH 5543/6505] Update monitor-all.sh tweak --- misc/monitor-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index e4251757..e7702268 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -51,7 +51,7 @@ while true; do fi # Skip instances based on onboot and templates - onboot=$($config_cmd $instance | grep onboot | grep -q "onboot: 0" && echo "true" || echo "false") + onboot=$($config_cmd $instance | grep -q "onboot: 0" || ( ! $config_cmd $instance | grep -q "onboot" ) && echo "true" || echo "false") template=$($config_cmd $instance | grep template | grep -q "template:" && echo "true" || echo "false") if [ "$onboot" == "true" ]; then From 2b713d69973cbcfa80900313d484fc4f70810cf2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Nov 2023 04:31:03 -0500 Subject: [PATCH 5544/6505] Update homebridge-install.sh tweak --- install/homebridge-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh index ed071136..185a970e 100644 --- a/install/homebridge-install.sh +++ b/install/homebridge-install.sh @@ -29,7 +29,7 @@ msg_ok "Set up Homebridge Repository" msg_info "Installing Homebridge" $STD apt update $STD apt-get install -y homebridge -msg_info "Installed Homebridge" +msg_ok "Installed Homebridge" motd_ssh customize From 117c32a408c9c60e1a76b57938c37db1eceaf600 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Nov 2023 10:26:20 -0500 Subject: [PATCH 5545/6505] Update microcode.sh tweak --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index a4653be5..91296a22 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -30,7 +30,7 @@ msg_ok() { echo -e "${BFR} ${CM} ${GN}$1${CL}"; } msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; } header_info -current_microcode=$(journalctl -k | grep -E "microcode: microcode" | awk -F 'microcode: microcode updated early to revision |, date = ' '{print $2 ", date = " $3}') +current_microcode=$(journalctl -k | grep -oP "microcode: updated early: [^ ]+ -> \K[^,]+, date = [^ ]+" | head -n 1) [ -z "$current_microcode" ] && current_microcode="Not found." intel() { From e39cd4c56d3df956707d14c5e1c9aee5d4700d08 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Nov 2023 10:39:04 -0500 Subject: [PATCH 5546/6505] Update USER_SUBMITTED_GUIDES.md update link --- USER_SUBMITTED_GUIDES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 57ec2294..9d011721 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -10,7 +10,7 @@ [Home Assistant: Installing InfluxDB (LXC)](https://www.derekseaman.com/2023/04/home-assistant-installing-influxdb-lxc.html) -[Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/04/installing-home-assistant-on-proxmox-quick-start-guide.html) +[Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/10/home-assistant-proxmox-ve-8-0-quick-start-guide-2.html) [Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html) From 8e9ea1bd3c4c80dd7e69ffb7b801cee643224281 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Nov 2023 15:30:18 -0500 Subject: [PATCH 5547/6505] Update rdtclient-install.sh tweak --- install/rdtclient-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/rdtclient-install.sh b/install/rdtclient-install.sh index 8de86327..cc48a014 100644 --- a/install/rdtclient-install.sh +++ b/install/rdtclient-install.sh @@ -21,11 +21,11 @@ $STD apt-get install -y unzip msg_ok "Installed Dependencies" msg_info "Installing ASP.NET Core Runtime" -wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb +wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb $STD dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb $STD apt-get update -$STD apt-get install -y dotnet-sdk-6.0 +$STD apt-get install -y dotnet-sdk-8.0 msg_ok "Installed ASP.NET Core Runtime" msg_info "Installing rdtclient" @@ -33,7 +33,7 @@ wget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebr unzip -qq RealDebridClient.zip -d /opt/rdtc rm RealDebridClient.zip cd /opt/rdtc -mkdir -p data/db/ data/downloads +mkdir -p data/{db,downloads} sed -i 's#/data/db/#/opt/rdtc&#g' /opt/rdtc/appsettings.json msg_ok "Installed rdtclient" From 2e5bcd8424e3e02a4c1f33bfcea6b4d6ccf4c40e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 Nov 2023 16:55:09 -0500 Subject: [PATCH 5548/6505] Update rdtclient.sh create update path --- ct/rdtclient.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh index 227856d6..e87c21f4 100755 --- a/ct/rdtclient.sh +++ b/ct/rdtclient.sh @@ -53,10 +53,16 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/rdtc/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +msg_info "Updating $APP" +systemctl stop rdtc +mkdir -p rdtc-backup +cp -R /opt/rdtc/appsettings.json rdtc-backup/ +wget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebridClient.zip +unzip -oqq RealDebridClient.zip -d /opt/rdtc +cp -R rdtc-backup/appsettings.json /opt/rdtc/ +rm -rf rdtc-backup RealDebridClient.zip +systemctl start rdtc +msg_ok "Updated $APP" exit } From 014b2dab554a8dcfc9962d81d2beb8696e86c5c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 00:12:19 -0500 Subject: [PATCH 5549/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 7c8d7a5a..5548ce3e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -6,7 +6,7 @@ body: value: | **IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure. - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. - - Changing Linux distributions without confirming the proper functioning of default settings. + - Switching Linux distributions without verifying that the default distribution is working correctly. - When encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. - For suggestions, questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: input From c870b93810a13be3b328a192f6f2a7c82620db94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 09:34:09 -0500 Subject: [PATCH 5550/6505] Update linkwarden.sh - create update path --- ct/linkwarden.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index fb2a8d01..70bf88e8 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -53,7 +53,21 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/linkwarden ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +msg_info "Updating $APP" +systemctl stop linkwarden +cd /opt/linkwarden +if git pull | grep 'Already up to date'; then + echo "Exiting script." + systemctl start linkwarden + exit +fi +git pull +yarn +npx playwright install-deps +yarn build +yarn prisma migrate deploy +systemctl start linkwarden +msg_ok "Updated $APP" exit } From c95f5dec17b34780d2fe6afed0f7445ff34f6ea7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 09:37:58 -0500 Subject: [PATCH 5551/6505] Update linkwarden.sh tweak --- ct/linkwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index 70bf88e8..c8dbbf01 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -57,7 +57,7 @@ msg_info "Updating $APP" systemctl stop linkwarden cd /opt/linkwarden if git pull | grep 'Already up to date'; then - echo "Exiting script." + echo "Exiting script.${CL}" systemctl start linkwarden exit fi From 778c58f49e24bd3d9a5937876204224adad6528d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 09:41:48 -0500 Subject: [PATCH 5552/6505] Update linkwarden.sh tweak --- ct/linkwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index c8dbbf01..a94bdea5 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -57,7 +57,7 @@ msg_info "Updating $APP" systemctl stop linkwarden cd /opt/linkwarden if git pull | grep 'Already up to date'; then - echo "Exiting script.${CL}" + echo -e "Exiting script.${CL}" systemctl start linkwarden exit fi From 946114f59eda770781bbcb3d73ebe1f387c81b3a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 09:49:18 -0500 Subject: [PATCH 5553/6505] Update linkwarden.sh tweak --- ct/linkwarden.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index a94bdea5..0a10b1d9 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -56,8 +56,8 @@ if [[ ! -d /opt/linkwarden ]]; then msg_error "No ${APP} Installation Found!"; e msg_info "Updating $APP" systemctl stop linkwarden cd /opt/linkwarden -if git pull | grep 'Already up to date'; then - echo -e "Exiting script.${CL}" +if git pull | grep -q 'Already up to date'; then + msg_ok "Already up to date" systemctl start linkwarden exit fi From 04a0a412c4fe8fba780f1cce214136cd82d1a0b8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 13:00:53 -0500 Subject: [PATCH 5554/6505] Update ubuntu-vm.sh fixes https://github.com/tteck/Proxmox/issues/2090 --- vm/ubuntu-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index d44d404f..9d5f4e17 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -408,7 +408,7 @@ qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \ - -ide2 local-lvm:cloudinit \ + -ide2 ${STORAGE}:cloudinit \ -boot order=scsi0 \ -serial0 socket \ -description "# Ubuntu 22.04 VM From d3a3c723356a58249e72e30d5830b8ef2049d868 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 14:58:01 -0500 Subject: [PATCH 5555/6505] Update README.md --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c27d9e2b..13ddf05a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ -

    Contributing to Proxmox VE Helper Scripts

    +

    Proxmox VE Helper Scripts

    -These scripts empower users to create a Linux container or virtual machine interactively, providing choices for both simple and advanced configurations. The basic setup adheres to default settings, while the advanced setup gives users the ability to customize these defaults. Utilizing the whiptail command, options are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine. +

    + Visit the project website | + Contribute to Proxmox VE Helper Scripts +

    -

    Proxmox VE Helper Scripts

    -

    Exercise caution and conduct a comprehensive assessment of scripts and automation tasks acquired from external sources.

    +--- + +These scripts empower users to create a Linux container or virtual machine interactively, providing choices for both simple and advanced configurations. The basic setup adheres to default settings, while the advanced setup gives users the ability to customize these defaults. Utilizing the whiptail command, options are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine. +

    +Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources. Read more +

    Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.
    From 0e8144e9606b863f2a988d7809bc79b030dfee4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 15:13:00 -0500 Subject: [PATCH 5556/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13ddf05a..9634618f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ --- -These scripts empower users to create a Linux container or virtual machine interactively, providing choices for both simple and advanced configurations. The basic setup adheres to default settings, while the advanced setup gives users the ability to customize these defaults. Utilizing the whiptail command, options are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine. +These scripts empower users to create a Linux container or virtual machine interactively, providing choices for both simple and advanced configurations. The basic setup adheres to default settings, while the advanced setup gives users the ability to customize these defaults. + +Utilizing the whiptail command, options are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine.

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources. Read more

    From ddd0a9ab4d30bebe2794c6f08c35ada3e6702be0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 15:21:43 -0500 Subject: [PATCH 5557/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9634618f..1827d12c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    Visit the project website | - Contribute to Proxmox VE Helper Scripts + Contribute to Helper Scripts

    --- From 745f1aca2123c0f12750ce4a77fb2b74e743df12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 17:30:07 -0500 Subject: [PATCH 5558/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 5548ce3e..f64afc99 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,5 +1,5 @@ name: Problems with a script. -description: Generate a report on the issue pertaining specifically to the script in order to aid us in improving it. +description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) body: - type: markdown attributes: From c944e77cf4aa10474953e14e54a411cbfc37a6bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 17:31:42 -0500 Subject: [PATCH 5559/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index f64afc99..11a8371d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,5 +1,5 @@ name: Problems with a script. -description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) +description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the Discussions section. body: - type: markdown attributes: From 6922be6928a890a817e5c970da14a84fc00ddc4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 17:33:09 -0500 Subject: [PATCH 5560/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 11a8371d..928395e2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,5 +1,5 @@ name: Problems with a script. -description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the Discussions section. +description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the Discussions section. Blank issues will be closed. body: - type: markdown attributes: From 9a6fcbdfd632df6738864a60a7a6e09d88e9481b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 Nov 2023 17:34:34 -0500 Subject: [PATCH 5561/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 928395e2..a99cae4d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,5 +1,5 @@ name: Problems with a script. -description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the Discussions section. Blank issues will be closed. +description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the Discussions section. Blank issues will be closed immediately. body: - type: markdown attributes: From 92408b5fae86c930a965df01d5c0b5a9351705f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Nov 2023 08:46:33 -0500 Subject: [PATCH 5562/6505] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1827d12c..7e88e7b8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@

    Proxmox VE Helper Scripts

    - Visit the project website | - Contribute to Helper Scripts + Website | + Contribute | + Guides | + Changelog | + Support

    --- From 9ebffbcc3e53c4f042a29c2372227447ff6d8a7f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Nov 2023 08:49:01 -0500 Subject: [PATCH 5563/6505] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7e88e7b8..12d51d7c 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@

    Website | - Contribute | - Guides | - Changelog | + Contribute | + Guides | + Changelog | Support

    From 054ed83e0d9489c851c9eed26e10b7fd4bb6e995 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Nov 2023 08:50:19 -0500 Subject: [PATCH 5564/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12d51d7c..81e6c9bb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    Website | - Contribute | + Contribute | Guides | Changelog | Support From 96abbe81d19b309b55bd645feadc84c71fe50824 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 Nov 2023 15:17:02 -0500 Subject: [PATCH 5565/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 81e6c9bb..f575c691 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

    Proxmox VE Helper Scripts

    +

    Proxmox VE Helper-Scripts

    Website | From 166c9c85c44b4b52fbeb9f9d3cd60a39adf21b6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Nov 2023 06:59:49 -0500 Subject: [PATCH 5566/6505] Update post-pve-install.sh fix No Nag for 8.1 --- misc/post-pve-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index b977a7cf..6d1aece2 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -47,9 +47,6 @@ msg_error() { start_routines() { header_info VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" - if lscpu | grep -qP 'Vendor ID:.*GenuineIntel' && lscpu | grep -qP 'Model name:.*N' && [[ "$VERSION" == "bullseye" ]]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "N-SERIES PROCESSOR DETECTED" "To ensure compatibility with Proxmox VE on systems equipped with N-series processors, it is recommended to install Proxmox Virtual Environment 8" 10 58 - fi CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ "yes" " " \ @@ -144,7 +141,11 @@ EOF yes) whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_info "Disabling subscription nag" - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + if ! pveversion | grep -Eq "pve-manager/(8\.[1-3])"; then + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/.data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + else + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script + fi apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled subscription nag (Delete browser cache)" ;; From acf59946b63e5e6bc99af2d5967f25ee10c56cf6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 Nov 2023 08:04:58 -0500 Subject: [PATCH 5567/6505] Update post-pve-install.sh improve No Nag --- misc/post-pve-install.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 6d1aece2..97def72d 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -141,11 +141,7 @@ EOF yes) whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58 msg_info "Disabling subscription nag" - if ! pveversion | grep -Eq "pve-manager/(8\.[1-3])"; then - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/.data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script - else - echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script - fi + echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/.*data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script apt --reinstall install proxmox-widget-toolkit &>/dev/null msg_ok "Disabled subscription nag (Delete browser cache)" ;; From 6ab86e5c05b486227b1ad6d56ab7917e266933cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Nov 2023 10:19:33 -0500 Subject: [PATCH 5568/6505] Update sabnzbd-install.sh fix release variable --- install/sabnzbd-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 0fef42d1..368633da 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -19,7 +19,7 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y par2 $STD apt-get install -y p7zip-full -RELEASE=$(curl -s http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/ | grep -oP 'href="\K[^"]*unrar_7\.\d+\.\d+-\d+_amd64\.deb') +RELEASE=$(curl -s http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/ | grep -oP 'href="\K[^"]*unrar_7\.\d+\.\d+-\d+_amd64\.deb' | head -1) wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/$RELEASE $STD dpkg -i unrar*.deb rm unrar*.deb From cc97e682aee17cade6d8fe516509dd0aafbd997e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Nov 2023 14:03:23 -0500 Subject: [PATCH 5569/6505] Update add-tailscale-lxc.sh tweak --- misc/add-tailscale-lxc.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index a4661001..301c4a7e 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -8,11 +8,11 @@ function header_info { cat <<"EOF" ______ _ __ __ - /_ __/___ _(_) /_____________ _/ /__ - / / / __ `/ / / ___/ ___/ __ `/ / _ \ - / / / /_/ / / (__ ) /__/ /_/ / / __/ -/_/ \__,_/_/_/____/\___/\__,_/_/\___/ - + /_ __/___ _(_) /_____________ _/ /__ + / / / __ `/ / / ___/ ___/ __ `/ / _ \ + / / / /_/ / / (__ ) /__/ /_/ / / __/ +/_/ \__,_/_/_/____/\___/\__,_/_/\___/ + EOF } clear @@ -48,6 +48,7 @@ function msg() { } NODE=$(hostname) +MSG_MAX_LENGTH=0 while read -r line; do TAG=$(echo "$line" | awk '{print $1}') ITEM=$(echo "$line" | awk '{print substr($0,36)}') From 2c6d131d936ebcd4ddb1870b13754e8e66b24af0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Nov 2023 19:00:17 -0500 Subject: [PATCH 5570/6505] Add files via upload --- misc/images/tths.png | Bin 0 -> 24684 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/tths.png diff --git a/misc/images/tths.png b/misc/images/tths.png new file mode 100644 index 0000000000000000000000000000000000000000..e51475534450d22d312f7586dd3e698a56aaa63a GIT binary patch literal 24684 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 literal 0 HcmV?d00001 From c8cbb8626bae2348530120629a4b80a1a336e111 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Nov 2023 19:50:28 -0500 Subject: [PATCH 5571/6505] Add files via upload --- misc/images/tths.png | Bin 24684 -> 17782 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/tths.png b/misc/images/tths.png index e51475534450d22d312f7586dd3e698a56aaa63a..c0ba97a25f629ce5274e580e977fd73ce5e702a3 100644 GIT binary patch literal 17782 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 literal 24684 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 From 60eeefe0c48340875dba5359347ee341a556fd66 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Nov 2023 20:48:14 -0500 Subject: [PATCH 5572/6505] Add files via upload --- misc/images/tths.png | Bin 17782 -> 25593 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/misc/images/tths.png b/misc/images/tths.png index c0ba97a25f629ce5274e580e977fd73ce5e702a3..d70a0cd0d4383540c5559346be8865d9385f9d1c 100644 GIT binary patch literal 25593 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 From c912a037a1953a20517bb5406bc7d154fb769e6d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 Nov 2023 23:14:11 -0500 Subject: [PATCH 5573/6505] Update homarr.sh fixes https://github.com/tteck/Proxmox/issues/2102 --- ct/homarr.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homarr.sh b/ct/homarr.sh index 94ce3640..3e247bb2 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -61,6 +61,7 @@ cp -R /opt/homarr/data /root/data-homarr-backup cp -R /opt/homarr/database /root/database-homarr-backup RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') wget -q -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt +cp -R /opt/homarr-${RELEASE}/* /opt/homarr cp -R /root/data-homarr-backup/* /opt/homarr/data cp -R /root/database-homarr-backup/* /opt/homarr/database rm -rf /opt/homarr-${RELEASE} From 6fa39cb2830926dcee5bcb1d257ca8514da691bb Mon Sep 17 00:00:00 2001 From: Andy B Date: Sun, 26 Nov 2023 14:30:19 +0200 Subject: [PATCH 5574/6505] Update unifi to mongodb 4.4 and jre 17 (#2104) --- install/unifi-install.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index d65d2f2f..2970f848 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -18,28 +18,30 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y apt-transport-https +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" -if [[ "$PCT_OSVERSION" == "12" ]]; then - echo -e "deb http://ftp.debian.org/debian bullseye main" >/etc/apt/sources.list.d/openjdk-11-jre-headless.list - $STD apt-get update -fi - msg_info "Installing OpenJDK" -$STD apt-get install -y openjdk-11-jre-headless -$STD apt-mark hold openjdk-11-* +#$STD apt-get install -y openjdk-17-jre-headless +#$STD apt-mark hold openjdk-17-* +wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor | tee /etc/apt/trusted.gpg.d/adoptium.gpg >/dev/null 2>&1 +echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' > /etc/apt/sources.list.d/adoptium.list +$STD apt-get update +$STD apt-get install -y temurin-17-jre msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb $STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb -wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb -$STD dpkg -i mongodb-org-server_3.6.23_amd64.deb +wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg >/dev/null 2>&1 +echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list +$STD apt-get update +$STD apt-get install -y mongodb-org msg_ok "Installed MongoDB" msg_info "Installing UniFi Network Application" wget -qO /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ui.com/unifi/unifi-repo.gpg -echo 'deb https://www.ui.com/downloads/unifi/debian stable ubiquiti' >/etc/apt/sources.list.d/100-ubnt-unifi.list +echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/unifi-repo.gpg] https://www.ui.com/downloads/unifi/debian stable ubiquiti' >/etc/apt/sources.list.d/100-ubnt-unifi.list $STD apt-get update $STD apt-get install -y unifi msg_ok "Installed UniFi Network Application" @@ -48,7 +50,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf mongodb-org-server_3.6.23_amd64.deb libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb /etc/apt/sources.list.d/openjdk-11-jre-headless.list +rm -rf libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From cb09bdf7b86645fe4378a1c95747b63dcba3d18d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Nov 2023 07:43:37 -0500 Subject: [PATCH 5575/6505] Update unifi-install.sh tweak --- install/unifi-install.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 2970f848..cadb6db4 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -22,10 +22,8 @@ $STD apt-get install -y gnupg msg_ok "Installed Dependencies" msg_info "Installing OpenJDK" -#$STD apt-get install -y openjdk-17-jre-headless -#$STD apt-mark hold openjdk-17-* -wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor | tee /etc/apt/trusted.gpg.d/adoptium.gpg >/dev/null 2>&1 -echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' > /etc/apt/sources.list.d/adoptium.list +wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg +echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list $STD apt-get update $STD apt-get install -y temurin-17-jre msg_ok "Installed OpenJDK" @@ -33,7 +31,7 @@ msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb $STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb -wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg >/dev/null 2>&1 +wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list $STD apt-get update $STD apt-get install -y mongodb-org From b6fdaa624eb8664e9459b4369837b313e8921b03 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Nov 2023 11:32:42 -0500 Subject: [PATCH 5576/6505] Update turnkey.sh add BookStack --- turnkey/turnkey.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index d49a7b19..6eb31634 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -66,6 +66,7 @@ while read -r TAG ITEM; do done < <( cat < Date: Sun, 26 Nov 2023 15:54:00 -0500 Subject: [PATCH 5577/6505] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f575c691..2f1d12cf 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ These scripts empower users to create a Linux container or virtual machine interactively, providing choices for both simple and advanced configurations. The basic setup adheres to default settings, while the advanced setup gives users the ability to customize these defaults. -Utilizing the whiptail command, options are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine. +Options are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine.

    Be cautious and thoroughly evaluate scripts and automation tasks obtained from external sources. Read more

    From 9183ff2a7ec4ae779f7b3edfadc04ca63ea9757c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Nov 2023 17:06:48 -0500 Subject: [PATCH 5578/6505] Add files via upload --- misc/images/logo.png | Bin 0 -> 64142 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/logo.png diff --git a/misc/images/logo.png b/misc/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1d2186daaff82486871ca55f12b4014d988c7841 GIT binary patch literal 64142 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 Date: Sun, 26 Nov 2023 17:36:25 -0500 Subject: [PATCH 5579/6505] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2f1d12cf..36128c63 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +
    + +

    Proxmox VE Helper-Scripts

    + + # ${APP} LXC + + +
    " if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi From 6fac4f32ae0eefab6d162873f69954fea142c1eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:07:42 -0500 Subject: [PATCH 5583/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 243fa3c5..b1277f9d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -577,7 +577,7 @@ description() { # ${APP} LXC - + " if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service From f3b9b0fdf0866d137bb920092a2a5c897907b358 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:40:33 -0500 Subject: [PATCH 5584/6505] Update haos-vm.sh tweak description --- vm/haos-vm.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index d535b99a..005e2ef9 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -429,9 +429,12 @@ qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=32G \ -boot order=scsi0 \ - -description "# Home Assistant OS -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -description "
    + + # Home Assistant OS + + +
    " >/dev/null msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" From f76bfa30378f452c0e3760d36713cce36f41b34b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:48:44 -0500 Subject: [PATCH 5585/6505] Update pimox-haos-vm.sh tweak description --- vm/pimox-haos-vm.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index 1cf39709..41e25281 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -314,10 +314,13 @@ qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=64M \ -scsi0 ${DISK1_REF},size=32G >/dev/null qm set $VMID \ - -boot order=scsi0 >/dev/null -qm set $VMID -description "# PiMox HAOS -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -boot order=scsi0 \ + -description "
    + + # Home Assistant OS + + +
    " >/dev/null msg_ok "Created HAOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" From 942fd3fda2da3144dddf48ccb73416208666add6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:50:06 -0500 Subject: [PATCH 5586/6505] Update debian-vm.sh tweak description --- vm/debian-vm.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index b549f062..e8037443 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -410,9 +410,12 @@ qm set $VMID \ -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \ -boot order=scsi0 \ -serial0 socket \ - -description "# Debian 12 VM -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -description "
    + + # Debian 12 + + +
    " >/dev/null msg_ok "Created a Debian 12 VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Debian 12 VM" From 09cc28b017ff41faf3de258d2b78a60bac765d59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:51:48 -0500 Subject: [PATCH 5587/6505] Update mikrotik-routeros.sh tweak description --- vm/mikrotik-routeros.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 35a92d9b..0ffb85aa 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -273,9 +273,12 @@ qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=2G \ -boot order=scsi0 \ - -description "# Mikrotik RouterOS VM -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -description "
    + + # Mikrotik RouterOS + + +
    " >/dev/null msg_ok "Mikrotik RouterOS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Mikrotik RouterOS VM" From dcad1abbbbe3ed798afd108e1df13cf3a6ded65d Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:52:59 -0500 Subject: [PATCH 5588/6505] Update nextcloud-vm.sh tweak description --- vm/nextcloud-vm.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vm/nextcloud-vm.sh b/vm/nextcloud-vm.sh index c4074aaa..303910aa 100644 --- a/vm/nextcloud-vm.sh +++ b/vm/nextcloud-vm.sh @@ -408,9 +408,12 @@ qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=12G \ -boot order=scsi0 \ - -description "# $NAME -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -description "
    + + # $NAME + + +
    " >/dev/null msg_ok "Created a $NAME ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting $NAME" From 70cedc41e5b6097088f1fb9aad5aed4b8d9e24a3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:54:38 -0500 Subject: [PATCH 5589/6505] Update owncloud-vm.sh tweak description --- vm/owncloud-vm.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh index c41c1124..40c5c0cb 100644 --- a/vm/owncloud-vm.sh +++ b/vm/owncloud-vm.sh @@ -408,9 +408,12 @@ qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=12G \ -boot order=scsi0 \ - -description "# TurnKey ownCloud VM -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -description "
    + + # TurnKey ownCloud VM + + +
    " >/dev/null msg_ok "Created a TurnKey ownCloud VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting TurnKey ownCloud VM" From cb970e8873e31e7d6a0530b9244c72a07aa5a232 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:56:24 -0500 Subject: [PATCH 5590/6505] Update openwrt.sh tweak description --- vm/openwrt.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index d163b926..96bca2be 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -475,9 +475,12 @@ qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=512M \ -boot order=scsi0 \ - -description "# OpenWrt VM -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -description "
    + + # OpenWRT + + +
    " >/dev/null msg_ok "Created OpenWrt VM ${CL}${BL}(${HN})" msg_info "OpenWrt is being started in order to configure the network interfaces." qm start $VMID From 4ecb33e99da0c5d3c81457a87c1b9a2b0d93b6f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:57:22 -0500 Subject: [PATCH 5591/6505] Update ubuntu-vm.sh tweak description --- vm/ubuntu-vm.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index 9d5f4e17..e971c027 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -411,9 +411,12 @@ qm set $VMID \ -ide2 ${STORAGE}:cloudinit \ -boot order=scsi0 \ -serial0 socket \ - -description "# Ubuntu 22.04 VM -### https://github.com/tteck/Proxmox -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D7EP4GF)" >/dev/null + -description "
    + + # Ubuntu 22.04 VM + + +
    " >/dev/null msg_ok "Created a Ubuntu 22.04 VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Ubuntu 22.04 VM" From 8a98b3d24e87068d2c3ea39928fe1f28ffc980bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:58:16 -0500 Subject: [PATCH 5592/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index b1277f9d..096b1a6f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -577,7 +577,7 @@ description() { # ${APP} LXC - + " if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service From 4fdf751a509e1142fe963f9075d0d3e6e8d8ec12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 12:43:17 -0500 Subject: [PATCH 5593/6505] Update debian-vm.sh tweak description --- vm/debian-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index e8037443..e74afdc1 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -412,7 +412,7 @@ qm set $VMID \ -serial0 socket \ -description "
    - # Debian 12 + # Debian 12 VM
    " >/dev/null From 0f727b91095ccdb5b8ddf0396b6c574a329dc7e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 Nov 2023 10:10:56 -0500 Subject: [PATCH 5594/6505] Update dockge-install.sh tweak Home Assistant compose.yaml --- install/dockge-install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/install/dockge-install.sh b/install/dockge-install.sh index 988c56f2..8509c2ad 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -72,12 +72,9 @@ services: - /var/run/docker.sock:/var/run/docker.sock - /dev:/dev - /etc/localtime:/etc/localtime:ro - - ha_config:/config + - ./config:/config network_mode: host image: ghcr.io/home-assistant/home-assistant:stable -volumes: - ha_config: {} -networks: {} EOF msg_ok "Added Home Assistant compose.yaml" fi From 14101800db5e0805b589404e8dfd497b85e4caed Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 06:51:52 -0500 Subject: [PATCH 5595/6505] Update build.func - If the default Linux distribution is not adhered to, script support will be discontinued. --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 096b1a6f..42036724 100644 --- a/misc/build.func +++ b/misc/build.func @@ -139,7 +139,7 @@ exit-script() { # This function allows the user to configure advanced settings for the script. advanced_settings() { whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n" 8 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n \nIf the default Linux distribution is not adhered to, script support will be discontinued. \n" 11 58 if [ "$var_os" != "alpine" ]; then var_os="" while [ -z "$var_os" ]; do From 45d30dbbba778c0abdc5ed26ff2cce87ea3a9aeb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 07:08:31 -0500 Subject: [PATCH 5596/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 42036724..e734fd1f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -139,7 +139,7 @@ exit-script() { # This function allows the user to configure advanced settings for the script. advanced_settings() { whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58 - whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n \nIf the default Linux distribution is not adhered to, script support will be discontinued. \n" 11 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Default distribution for $APP" "${var_os} ${var_version} \n \nIf the default Linux distribution is not adhered to, script support will be discontinued. \n" 10 58 if [ "$var_os" != "alpine" ]; then var_os="" while [ -z "$var_os" ]; do From 8d5ca6becee342c8d0213c649605d64c60aff105 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 07:19:53 -0500 Subject: [PATCH 5597/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index a99cae4d..dacb876c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -6,7 +6,7 @@ body: value: | **IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure. - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. - - Switching Linux distributions without verifying that the default distribution is working correctly. + - If the default Linux distribution is not adhered to, script support will be discontinued. - When encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. - For suggestions, questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: input From ab521623cdf779ea2644ed415a08683e7ad70214 Mon Sep 17 00:00:00 2001 From: Danofun <568343+danofun@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:36:42 -0500 Subject: [PATCH 5598/6505] Randomize the PiVPN subnet (#2118) --- install/wireguard-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh index a133b2df..93ae6e56 100644 --- a/install/wireguard-install.sh +++ b/install/wireguard-install.sh @@ -22,11 +22,12 @@ msg_ok "Installed Dependencies" msg_info "Installing WireGuard (using pivpn.io)" OPTIONS_PATH='/options.conf' -cat >$OPTIONS_PATH <<'EOF' +SUBNET=$(printf %d.%d.%d.%d 10 $((RANDOM % 256)) $((RANDOM % 256)) 0) +cat >$OPTIONS_PATH < Date: Wed, 29 Nov 2023 09:43:11 -0500 Subject: [PATCH 5599/6505] Update wireguard-install.sh tweak --- install/wireguard-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh index 93ae6e56..d74118d6 100644 --- a/install/wireguard-install.sh +++ b/install/wireguard-install.sh @@ -22,12 +22,11 @@ msg_ok "Installed Dependencies" msg_info "Installing WireGuard (using pivpn.io)" OPTIONS_PATH='/options.conf' -SUBNET=$(printf %d.%d.%d.%d 10 $((RANDOM % 256)) $((RANDOM % 256)) 0) cat >$OPTIONS_PATH < Date: Wed, 29 Nov 2023 15:51:32 -0500 Subject: [PATCH 5600/6505] Update paperless-ngx.sh fixes https://github.com/tteck/Proxmox/issues/2123 --- ct/paperless-ngx.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index ff4db22b..98c0c556 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -74,6 +74,7 @@ function update_script() { msg_ok "Stopped Paperless-ngx" msg_info "Updating to ${RELEASE}" + cd ~ if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }' | wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null From 9534dd7a52e7799994eeacb4992e5e73b5fa8197 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 17:36:45 -0500 Subject: [PATCH 5601/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fe7b7e2..108345bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-11-29 + +### Changed + +- **CasaOS LXC** + - Broken, temporarily removed from the website. + ## 2023-11-19 ### Changed From 883a16637ef34cb32742a16a0020de437df7cc00 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 23:14:56 -0500 Subject: [PATCH 5602/6505] Update casaos-install.sh - pin v0.4.1 - update after install --- install/casaos-install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/install/casaos-install.sh b/install/casaos-install.sh index c0a068d0..2ff7b68b 100644 --- a/install/casaos-install.sh +++ b/install/casaos-install.sh @@ -32,7 +32,10 @@ echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n} else echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json fi -$STD bash <(curl -fsSL https://get.casaos.io) +wget -q https://get.casaos.io/v0.4.1 +chmod +x v0.4.1 +$STD ./v0.4.1 +rm v0.4.1 msg_ok "Installed CasaOS" motd_ssh From 83aee5ef7ac9ce4eaab69f142ed9f8f9348c1693 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 23:25:52 -0500 Subject: [PATCH 5603/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 108345bf..1fe7b7e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,6 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. -## 2023-11-29 - -### Changed - -- **CasaOS LXC** - - Broken, temporarily removed from the website. - ## 2023-11-19 ### Changed From 36a911878882233c6246f83c2b40ddf478268efa Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 23:35:56 -0500 Subject: [PATCH 5604/6505] Update technitiumdns-install.sh tweak --- install/technitiumdns-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index f2b67d39..c1c58ec0 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -17,10 +17,11 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y libmsquic msg_ok "Installed Dependencies" msg_info "Installing ASP.NET Core Runtime" -wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb +wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb $STD dpkg -i packages-microsoft-prod.deb rm -rf packages-microsoft-prod.deb $STD apt-get update From 2154a19c1a571a68a02119880e4906cd8ae067b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 Nov 2023 23:40:47 -0500 Subject: [PATCH 5605/6505] Update technitiumdns-install.sh tweak --- install/technitiumdns-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index c1c58ec0..01f5fcd8 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y libmsquic msg_ok "Installed Dependencies" msg_info "Installing ASP.NET Core Runtime" From 7cc47d1d16ea5ea3d32b59dc1b61a862e3d1cf9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 10:31:45 -0500 Subject: [PATCH 5606/6505] Update casaos-install.sh tweak --- install/casaos-install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/install/casaos-install.sh b/install/casaos-install.sh index 2ff7b68b..d3caecbc 100644 --- a/install/casaos-install.sh +++ b/install/casaos-install.sh @@ -32,10 +32,7 @@ echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n} else echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json fi -wget -q https://get.casaos.io/v0.4.1 -chmod +x v0.4.1 -$STD ./v0.4.1 -rm v0.4.1 +$STD bash <(curl -fsSL https://get.casaos.io/v0.4.1) msg_ok "Installed CasaOS" motd_ssh From de0fd7aa6d2f33ce64c014c246e087e04f03ae07 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 14:11:29 -0500 Subject: [PATCH 5607/6505] Update zwave-js-ui-install.sh fix service --- install/zwave-js-ui-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh index a9a05c3e..e1e6da5d 100644 --- a/install/zwave-js-ui-install.sh +++ b/install/zwave-js-ui-install.sh @@ -36,7 +36,7 @@ After=network-online.target [Service] User=root WorkingDirectory=/opt/zwave-js-ui -ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux +ExecStart=/opt/zwave-js-ui/zwave-js-ui [Install] WantedBy=multi-user.target" >$service_path systemctl start zwave-js-ui From 6594ce2f3a3c0c89b72101ea6c76b8f3ed1daca6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 14:18:09 -0500 Subject: [PATCH 5608/6505] Update zwave-js-ui.sh fixes https://github.com/tteck/Proxmox/issues/2129 --- ct/zwave-js-ui.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 465f02df..a3407c6c 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -64,7 +64,19 @@ function update_script() { msg_info "Updating Z-wave JS UI" wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null - \cp -R zwave-js-ui-linux /opt/zwave-js-ui + \cp -R zwave-js-ui /opt/zwave-js-ui + cat </etc/systemd/system/zwave-js-ui.service + [Unit] + Description=zwave-js-ui + Wants=network-online.target + After=network-online.target + [Service] + User=root + WorkingDirectory=/opt/zwave-js-ui + ExecStart=/opt/zwave-js-ui/zwave-js-ui + [Install] + WantedBy=multi-user.target + EOF msg_ok "Updated Z-wave JS UI" msg_info "Starting Z-wave JS UI" From 76dbbf91ed078b8501daa9d673c810b320e7f9c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 14:20:12 -0500 Subject: [PATCH 5609/6505] Update zwave-js-ui.sh tweak --- ct/zwave-js-ui.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index a3407c6c..57187eb7 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -65,18 +65,18 @@ function update_script() { wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null \cp -R zwave-js-ui /opt/zwave-js-ui - cat </etc/systemd/system/zwave-js-ui.service - [Unit] - Description=zwave-js-ui - Wants=network-online.target - After=network-online.target - [Service] - User=root - WorkingDirectory=/opt/zwave-js-ui - ExecStart=/opt/zwave-js-ui/zwave-js-ui - [Install] - WantedBy=multi-user.target - EOF +cat </etc/systemd/system/zwave-js-ui.service +[Unit] +Description=zwave-js-ui +Wants=network-online.target +After=network-online.target +[Service] +User=root +WorkingDirectory=/opt/zwave-js-ui +ExecStart=/opt/zwave-js-ui/zwave-js-ui +[Install] +WantedBy=multi-user.target +EOF msg_ok "Updated Z-wave JS UI" msg_info "Starting Z-wave JS UI" From d4c685f05e388f2daa0520659eedab40b58e66c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 14:23:45 -0500 Subject: [PATCH 5610/6505] Update zwave-js-ui.sh tweak service file --- ct/zwave-js-ui.sh | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 57187eb7..3c63b70f 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -65,18 +65,17 @@ function update_script() { wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null \cp -R zwave-js-ui /opt/zwave-js-ui -cat </etc/systemd/system/zwave-js-ui.service -[Unit] -Description=zwave-js-ui -Wants=network-online.target -After=network-online.target -[Service] -User=root -WorkingDirectory=/opt/zwave-js-ui -ExecStart=/opt/zwave-js-ui/zwave-js-ui -[Install] -WantedBy=multi-user.target -EOF + service_path="/etc/systemd/system/zwave-js-ui.service" + echo "[Unit] + Description=zwave-js-ui + Wants=network-online.target + After=network-online.target + [Service] + User=root + WorkingDirectory=/opt/zwave-js-ui + ExecStart=/opt/zwave-js-ui/zwave-js-ui + [Install] + WantedBy=multi-user.target" >$service_path msg_ok "Updated Z-wave JS UI" msg_info "Starting Z-wave JS UI" From f0a661fea9ac45f48a901c69c0389d9bc18961c9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 14:28:13 -0500 Subject: [PATCH 5611/6505] Update zwave-js-ui.sh tweak cleanup --- ct/zwave-js-ui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 3c63b70f..5291e134 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -83,7 +83,7 @@ function update_script() { msg_ok "Started Z-wave JS UI" msg_info "Cleanup" - rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store + rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui store msg_ok "Cleaned" msg_ok "Updated Successfully!\n" exit From 83136610ed42eae54a6b4e973ffc99a95f1ccd27 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 17:51:02 -0500 Subject: [PATCH 5612/6505] Create channels-install.sh --- install/channels-install.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 install/channels-install.sh diff --git a/install/channels-install.sh b/install/channels-install.sh new file mode 100644 index 00000000..95bf8a40 --- /dev/null +++ b/install/channels-install.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Channels DVR Server (Patience)" +$STD bash <(curl -fsSL https://getchannels.com/dvr/setup.sh) +# adduser $(id -u -n) video && adduser $(id -u -n) render +msg_ok "Installed Channels DVR Server" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 3cda045ccefec3dbc12e0530fa43ec9485f92326 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 17:56:40 -0500 Subject: [PATCH 5613/6505] Create channels.sh --- ct/channels.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/channels.sh diff --git a/ct/channels.sh b/ct/channels.sh new file mode 100644 index 00000000..ce4722a5 --- /dev/null +++ b/ct/channels.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ __ ____ _ ______ _____ + / ____/ /_ ____ _____ ____ ___ / /____ / __ \ | / / __ \ / ___/___ ______ _____ _____ + / / / __ \/ __ `/ __ \/ __ \/ _ \/ / ___/ / / / / | / / /_/ / \__ \/ _ \/ ___/ | / / _ \/ ___/ +/ /___/ / / / /_/ / / / / / / / __/ (__ ) / /_/ /| |/ / _, _/ ___/ / __/ / | |/ / __/ / +\____/_/ /_/\__,_/_/ /_/_/ /_/\___/_/____/ /_____/ |___/_/ |_| /____/\___/_/ |___/\___/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Channels DVR Server" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/channels-dvr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +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}:8089 ${CL} \n" From e01ff6dcb48c69d3283640a2ae2c1426bc2c115d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 17:57:33 -0500 Subject: [PATCH 5614/6505] Update channels-install.sh tweak --- install/channels-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/channels-install.sh b/install/channels-install.sh index 95bf8a40..7ff03334 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -20,6 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Channels DVR Server (Patience)" +cd /opt $STD bash <(curl -fsSL https://getchannels.com/dvr/setup.sh) # adduser $(id -u -n) video && adduser $(id -u -n) render msg_ok "Installed Channels DVR Server" From ed40ffc000eb7d3274e762122238403154df682e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 18:03:25 -0500 Subject: [PATCH 5615/6505] Update channels.sh tweak name --- ct/channels.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/channels.sh b/ct/channels.sh index ce4722a5..f7018dda 100644 --- a/ct/channels.sh +++ b/ct/channels.sh @@ -18,7 +18,7 @@ EOF } header_info echo -e "Loading..." -APP="Channels DVR Server" +APP="Channels" var_disk="8" var_cpu="2" var_ram="2048" From 6dab19d260833fec2b16e72d5037f89324aa72e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 19:35:09 -0500 Subject: [PATCH 5616/6505] Update channels.sh adjust ram --- ct/channels.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/channels.sh b/ct/channels.sh index f7018dda..5a192475 100644 --- a/ct/channels.sh +++ b/ct/channels.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="Channels" var_disk="8" var_cpu="2" -var_ram="2048" +var_ram="1024" var_os="debian" var_version="12" variables From 590f85ccd2e11035c8a3fc88267e2efdcdde29b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 19:39:28 -0500 Subject: [PATCH 5617/6505] Update channels-install.sh add extra dependencies --- install/channels-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/channels-install.sh b/install/channels-install.sh index 7ff03334..9f395ca8 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -17,6 +17,8 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y chromium-browser +$STD apt-get install -y xvfb msg_ok "Installed Dependencies" msg_info "Installing Channels DVR Server (Patience)" From dd43d742e0a6042101297f39085ac3bfe76fc7f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 19:42:10 -0500 Subject: [PATCH 5618/6505] Update build.func add Channels to the VAAPI hardware transcoding group --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index e734fd1f..cb684c48 100644 --- a/misc/build.func +++ b/misc/build.func @@ -545,7 +545,7 @@ EOF fi if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then + if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm From ec320d565a145603d75ccb85c6adf3a0080ae8e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 Nov 2023 19:43:55 -0500 Subject: [PATCH 5619/6505] Update build.func revert add Channels to the VAAPI hardware transcoding group --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index cb684c48..e734fd1f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -545,7 +545,7 @@ EOF fi if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then + if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm From 03b23c04564f0086716f05f68ac51cb7cf69c4ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Dec 2023 09:44:18 -0500 Subject: [PATCH 5620/6505] Update channels-install.sh tweak --- install/channels-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/channels-install.sh b/install/channels-install.sh index 9f395ca8..dbb4fb4f 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -17,7 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y chromium-browser +$STD apt-get install -y chromium $STD apt-get install -y xvfb msg_ok "Installed Dependencies" From c59141daf69b416ab8262259c57188416b400bb2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Dec 2023 19:03:26 -0500 Subject: [PATCH 5621/6505] Update zwave-js-ui-install.sh fix service file --- install/zwave-js-ui-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh index e1e6da5d..a9a05c3e 100644 --- a/install/zwave-js-ui-install.sh +++ b/install/zwave-js-ui-install.sh @@ -36,7 +36,7 @@ After=network-online.target [Service] User=root WorkingDirectory=/opt/zwave-js-ui -ExecStart=/opt/zwave-js-ui/zwave-js-ui +ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux [Install] WantedBy=multi-user.target" >$service_path systemctl start zwave-js-ui From d4af04dfd38588a98244ee3e450e4d22cbec7be7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Dec 2023 19:06:38 -0500 Subject: [PATCH 5622/6505] Update zwave-js-ui.sh change back to `*-linux` --- ct/zwave-js-ui.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 5291e134..de994a7b 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -64,7 +64,7 @@ function update_script() { msg_info "Updating Z-wave JS UI" wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null - \cp -R zwave-js-ui /opt/zwave-js-ui + \cp -R zwave-js-ui-linux /opt/zwave-js-ui service_path="/etc/systemd/system/zwave-js-ui.service" echo "[Unit] Description=zwave-js-ui @@ -73,7 +73,7 @@ function update_script() { [Service] User=root WorkingDirectory=/opt/zwave-js-ui - ExecStart=/opt/zwave-js-ui/zwave-js-ui + ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux [Install] WantedBy=multi-user.target" >$service_path msg_ok "Updated Z-wave JS UI" @@ -83,7 +83,7 @@ function update_script() { msg_ok "Started Z-wave JS UI" msg_info "Cleanup" - rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui store + rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store msg_ok "Cleaned" msg_ok "Updated Successfully!\n" exit From c82fc0ddbc19555d345997a23ddf8904a4ac0f7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Dec 2023 21:16:31 -0500 Subject: [PATCH 5623/6505] Update mikrotik-routeros.sh - code refactoring - update to CHR - thanks to @NiccyB --- vm/mikrotik-routeros.sh | 78 ++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 0ffb85aa..659f8385 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -7,12 +7,12 @@ function header_info { cat <<"EOF" - __ ____ __ __ _ __ ____ __ ____ _____ - / |/ (_) /___________ / /_(_) /__ / __ \____ __ __/ /____ _____/ __ \/ ___/ - / /|_/ / / //_/ ___/ __ \/ __/ / //_/ / /_/ / __ \/ / / / __/ _ \/ ___/ / / /\__ \ - / / / / / < / / / /_/ / /_/ / < / _ _/ /_/ / /_/ / /_/ __/ / / /_/ /___/ / -/_/ /_/_/_/|_/_/ \____/\__/_/_/|_| /_/ |_|\____/\__,_/\__/\___/_/ \____//____/ - + __ ____ __ __ _ __ ____ __ ____ _____ ________ ______ + / |/ (_) /___________ / /_(_) /__ / __ \____ __ __/ /____ _____/ __ \/ ___/ / ____/ / / / __ \ + / /|_/ / / //_/ ___/ __ \/ __/ / //_/ / /_/ / __ \/ / / / __/ _ \/ ___/ / / /\__ \ / / / /_/ / /_/ / + / / / / / ,< / / / /_/ / /_/ / ,< / _, _/ /_/ / /_/ / /_/ __/ / / /_/ /___/ / / /___/ __ / _, _/ +/_/ /_/_/_/|_/_/ \____/\__/_/_/|_| /_/ |_|\____/\__,_/\__/\___/_/ \____//____/ \____/_/ /_/_/ |_| + EOF } clear @@ -69,7 +69,7 @@ pushd $TEMP_DIR >/dev/null sleep 3 exit fi -if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Mikrotik RouterOS VM" --yesno "This will create a New Mikrotik RouterOS VM. Proceed?" 10 58); then +if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Mikrotik RouterOS CHR VM" --yesno "This will create a New Mikrotik RouterOS CHR VM. Proceed?" 10 58); then echo "User selected Yes" else clear @@ -88,12 +88,12 @@ function msg_ok() { function default_settings() { echo -e "${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}" VMID=$NEXTID - echo -e "${DGN}Using Hostname: ${BGN}mikrotik-routeros${CL}" - HN=mikrotik-routeros + echo -e "${DGN}Using Hostname: ${BGN}mikrotik-routeros-chr${CL}" + HN=mikrotik-routeros-chr echo -e "${DGN}Allocated Cores: ${BGN}1${CL}" - CORE_COUNT="1" - echo -e "${DGN}Allocated RAM: ${BGN}1024${CL}" - RAM_SIZE="1024" + CORE_COUNT="2" + echo -e "${DGN}Allocated RAM: ${BGN}256${CL}" + RAM_SIZE="512" echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" BRG="vmbr0" echo -e "${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}" @@ -104,7 +104,7 @@ function default_settings() { MTU="" echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" START_VM="no" - echo -e "${BL}Creating a Mikrotik RouterOS VM using the above default settings${CL}" + echo -e "${BL}Creating a Mikrotik RouterOS CHR VM using the above default settings${CL}" } function advanced_settings() { VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" 3>&1 1>&2 2>&3) @@ -114,7 +114,7 @@ function advanced_settings() { else exit fi - VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 Mikrotik-RouterOS --title "HOSTNAME" 3>&1 1>&2 2>&3) + VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 mikrotik-routeros-chr --title "HOSTNAME" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then HN=$(echo ${VM_NAME,,} | tr -d ' ') @@ -122,14 +122,14 @@ function advanced_settings() { else exit fi - CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 1 --title "CORE COUNT" 3>&1 1>&2 2>&3) + CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" else exit fi - RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 1024 --title "RAM" 3>&1 1>&2 2>&3) + RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 512 --title "RAM" 3>&1 1>&2 2>&3) exitstatus=$? if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" @@ -173,15 +173,15 @@ function advanced_settings() { echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" fi fi - if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS VM when completed?" 10 58); then - echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}yes${CL}" + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start Mikrotik RouterOS CHR VM when completed?" 10 58); then + echo -e "${DGN}Start Mikrotik RouterOS CHR VM when completed: ${BGN}yes${CL}" START_VM="yes" else - echo -e "${DGN}Start Mikrotik RouterOS VM when completed: ${BGN}no${CL}" + echo -e "${DGN}Start Mikrotik RouterOS CHR VM when completed: ${BGN}no${CL}" START_VM="no" fi if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create Mikrotik RouterOS VM?" 10 58); then - echo -e "${RD}Creating Mikrotik RouterOS VM using the above advanced settings${CL}" + echo -e "${RD}Creating Mikrotik RouterOS CHR VM using the above advanced settings${CL}" else clear header_info @@ -190,7 +190,7 @@ function advanced_settings() { fi } function start_script() { - if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" 10 58); then + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then clear header_info echo -e "${BL}Using Default Settings${CL}" @@ -225,16 +225,16 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then else while [ -z "${STORAGE:+x}" ]; do STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for the Mikrotik RouterOS VM?\n\n" \ + "Which storage pool you would like to use for the Mikrotik RouterOS CHR VM?\n\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit done fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Getting URL for Mikrotik RouterOS Disk Image" +msg_info "Getting URL for Mikrotik RouterOS CHR Disk Image" -URL=https://download.mikrotik.com/routeros/7.11.2/install-image-7.11.2.zip +URL=https://download.mikrotik.com/routeros/7.12.1/chr-7.12.1.img.zip sleep 2 msg_ok "${CL}${BL}${URL}${CL}" @@ -242,7 +242,7 @@ wget -q --show-progress $URL echo -en "\e[1A\e[0K" FILE=$(basename $URL) msg_ok "Downloaded ${CL}${BL}$FILE${CL}" -msg_info "Extracting Mikrotik RouterOS Disk Image" +msg_info "Extracting Mikrotik RouterOS CHR Disk Image" gunzip -f -S .zip $FILE STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') case $STORAGE_TYPE in @@ -258,31 +258,29 @@ btrfs) DISK_IMPORT="-format raw" ;; esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done -msg_ok "Extracted Mikrotik RouterOS Disk Image" -msg_info "Creating Mikrotik RouterOS VM" -qm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \ + +DISK_VAR="vm-${VMID}-disk-0${DISK_EXT:-}" +DISK_REF="${STORAGE}:${DISK_VAR:-}" + +msg_ok "Extracted Mikrotik RouterOS CHR Disk Image" +msg_info "Creating Mikrotik RouterOS CHR VM" +qm create $VMID -tablet 0 -localtime 1 -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \ + -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \ -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ - -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ - -scsi0 ${DISK1_REF},size=2G \ + -scsi0 "$DISK_REF" \ -boot order=scsi0 \ -description "
    - # Mikrotik RouterOS + # Mikrotik RouterOS CHR
    " >/dev/null -msg_ok "Mikrotik RouterOS VM ${CL}${BL}(${HN})" +msg_ok "Mikrotik RouterOS CHR VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then - msg_info "Starting Mikrotik RouterOS VM" + msg_info "Starting Mikrotik RouterOS CHR VM" qm start $VMID - msg_ok "Started Mikrotik RouterOS VM" + msg_ok "Started Mikrotik RouterOS CHR VM" fi msg_ok "Completed Successfully!\n" From fa38661006ffa5d2d6e61b1fce77276e59de9c25 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Dec 2023 21:23:32 -0500 Subject: [PATCH 5624/6505] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fe7b7e2..283a3f60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-12-01 + +### Changed + +- **Mikrotik RouterOS VM** + - Now Mikrotik RouterOS CHR VM + - code refactoring + - update to CHR + - thanks to @NiccyB + ## 2023-11-19 ### Changed From f39d8cff0f2a2dceefa16db7648aeee04f8bbf9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Dec 2023 21:39:15 -0500 Subject: [PATCH 5625/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 283a3f60..6ec1448b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - code refactoring - update to CHR - thanks to @NiccyB +- **Channels DVR Server LXC** + - NEW Script ## 2023-11-19 From f3c70a02225023b59c8408d661bc6bd9c6ce5c80 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 06:36:12 -0500 Subject: [PATCH 5626/6505] Create runtipi-install.sh --- install/runtipi-install.sh | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 install/runtipi-install.sh diff --git a/install/runtipi-install.sh b/install/runtipi-install.sh new file mode 100644 index 00000000..c9a2dce8 --- /dev/null +++ b/install/runtipi-install.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Runtipi (Patience)" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" +echo -e '{\n "log-driver": "journald"\n}' > "$DOCKER_CONFIG_PATH" +cd /opt +wget -q https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh +sed -i -e '/newgrp docker/d' -e '/exit 0/d' install.sh +chmod +x install.sh +$STD ./install.sh +msg_ok "Installed Runtipi" + +motd_ssh +customize + +msg_info "Cleaning up" +rm /opt/install.sh +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 1112e0d8f656d1e6ba53cb4c5427fe6362599f76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 06:37:26 -0500 Subject: [PATCH 5627/6505] Create runtipi.sh --- ct/runtipi.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/runtipi.sh diff --git a/ct/runtipi.sh b/ct/runtipi.sh new file mode 100644 index 00000000..e4eeaba4 --- /dev/null +++ b/ct/runtipi.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ _ _ + / __ \__ ______ / /_(_)___ (_) + / /_/ / / / / __ \/ __/ / __ \/ / + / _, _/ /_/ / / / / /_/ / /_/ / / +/_/ |_|\__,_/_/ /_/\__/_/ .___/_/ + /_/ +EOF +} +header_info +echo -e "Loading..." +APP="Runtipi" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/runtipi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP} ${CL} \n" From 08aabfb27cafd5253ed89bbcbe4e46cf66cea6f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 07:11:08 -0500 Subject: [PATCH 5628/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ec1448b..5724aa3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-12-02 + +### Changed + +- **Runtipi LXC** + - NEW Script + ## 2023-12-01 ### Changed From 2ccb561ff4d83f2493c2db1f328614d362ab9246 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 19:35:10 -0500 Subject: [PATCH 5629/6505] Create haos-test.sh test DO NOT USE --- vm/haos-test.sh | 444 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 444 insertions(+) create mode 100644 vm/haos-test.sh diff --git a/vm/haos-test.sh b/vm/haos-test.sh new file mode 100644 index 00000000..3afdbaa6 --- /dev/null +++ b/vm/haos-test.sh @@ -0,0 +1,444 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ ___ _ __ __ ____ _____ + / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ + / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ + / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / +/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ + +EOF +} +header_info +echo -e "\n Loading..." +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +NEXTID=$(pvesh get /cluster/nextid) +VERSIONS=(stable beta dev) +for version in "${VERSIONS[@]}"; do + eval "$version=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/$version.json | grep "ova" | cut -d '"' -f 4)" +done +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +THIN="discard=on,ssd=1," +set -euo pipefail +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +trap cleanup EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid +} + +function cleanup_vmid() { + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then + : +else + header_info && echo -e "⚠ User exited script \n" && exit +fi + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function check_root() { + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + +function pve_check() { + if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.2 or higher" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + msg_error "This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function ssh_check() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function default_settings() { + BRANCH="$stable" + VMID="$NEXTID" + FORMAT=",efitype=4m" + MACHINE="" + DISK_CACHE="cache=writethrough," + HN="haos$stable" + CPU_TYPE=" -cpu host" + CORE_COUNT="2" + RAM_SIZE="4096" + BRG="vmbr0" + MAC="$GEN_MAC" + VLAN="" + MTU="" + START_VM="no" + echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" +} + +function advanced_settings() { + if BRANCH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ + "$stable" "Stable " ON \ + "$beta" "Beta " OFF \ + "$dev" "Dev " OFF \ + 3>&1 1>&2 2>&3); then + echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" + else + exit-script + fi + + while true; do + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + exit-script + fi + done + + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "i440fx" "Machine i440fx" ON \ + "q35" "Machine q35" OFF \ + 3>&1 1>&2 2>&3); then + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" + fi + else + exit-script + fi + + if DISK_CACHE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "None" OFF \ + "1" "Write Through (Default)" ON \ + 3>&1 1>&2 2>&3); then + if [ $DISK_CACHE1 = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + DISK_CACHE="" + fi + else + exit-script + fi + + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="haos${BRANCH}" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + else + exit-script + fi + + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "KVM64" OFF \ + "1" "Host (Default)" ON \ + 3>&1 1>&2 2>&3); then + if [ $CPU_TYPE1 = "1" ]; then + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + CPU_TYPE=" -cpu host" + else + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + CPU_TYPE="" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="4096" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + else + exit-script + fi + + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + else + exit-script + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function start_script() { + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +check_root +arch_check +pve_check +ssh_check +start_script + +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + msg_error "Unable to detect a valid storage location." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image" +if [ "$BRANCH" == "$dev" ]; then + URL=https://os-artifacts.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +else + URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz +fi +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" +msg_info "Extracting KVM Disk Image" +unxz $FILE +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in +nfs | dir) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + THIN="" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" + ;; +esac + +DISK_VAR="vm-${VMID}-disk-0${DISK_EXT:-}" +DISK_REF="${STORAGE}:${DISK_VAR:-}" +NODE=$(hostname) + +msg_ok "Extracted KVM Disk Image" +msg_info "Creating HAOS VM" +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw \virtio-scsi-pci +lvcreate -L 4G -n vm-$VMID-disk-1 $NODE 1>&/dev/null +qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${STORAGE}:vm-${VMID}-disk-1,efitype=4m \ + -scsi0 "${DISK_REF},${DISK_CACHE}${THIN}size=32G" \ + -boot order=scsi0 \ + -description "
    + + # Home Assistant OS + + +
    " >/dev/null +msg_ok "Created HAOS VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then + msg_info "Starting Home Assistant OS VM" + qm start $VMID + msg_ok "Started Home Assistant OS VM" +fi +msg_ok "Completed Successfully!\n" From e679048dda521391cccc91c0522c297d5eca480d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 19:56:35 -0500 Subject: [PATCH 5630/6505] Update haos-test.sh --- vm/haos-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-test.sh b/vm/haos-test.sh index 3afdbaa6..3cccf640 100644 --- a/vm/haos-test.sh +++ b/vm/haos-test.sh @@ -422,7 +422,7 @@ NODE=$(hostname) msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ - -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw \virtio-scsi-pci + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci lvcreate -L 4G -n vm-$VMID-disk-1 $NODE 1>&/dev/null qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ From e95e8992a9387a98fde49b774f6d228e964daaf8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 20:06:05 -0500 Subject: [PATCH 5631/6505] Update haos-test.sh --- vm/haos-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-test.sh b/vm/haos-test.sh index 3cccf640..c431b5c7 100644 --- a/vm/haos-test.sh +++ b/vm/haos-test.sh @@ -37,7 +37,7 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" THIN="discard=on,ssd=1," -set -euo pipefail +set -e trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT function error_handler() { From fea40f6526f97d00e1559782e0af0be27c34caba Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 20:22:18 -0500 Subject: [PATCH 5632/6505] Update haos-test.sh --- vm/haos-test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/haos-test.sh b/vm/haos-test.sh index c431b5c7..3b11b977 100644 --- a/vm/haos-test.sh +++ b/vm/haos-test.sh @@ -37,7 +37,7 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" THIN="discard=on,ssd=1," -set -e +set -euo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT function error_handler() { @@ -423,8 +423,8 @@ msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -lvcreate -L 4G -n vm-$VMID-disk-1 $NODE 1>&/dev/null -qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +lvcreate -L 4G -n vm-${VMID}-disk-1 ${NODE} 1>&/dev/null +qm importdisk $VMID ${FILE%.*} ${STORAGE} ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${STORAGE}:vm-${VMID}-disk-1,efitype=4m \ -scsi0 "${DISK_REF},${DISK_CACHE}${THIN}size=32G" \ From 47ecba463abd0afe49f44255b20e5698670bf215 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 20:30:12 -0500 Subject: [PATCH 5633/6505] Update haos-test.sh --- vm/haos-test.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/haos-test.sh b/vm/haos-test.sh index 3b11b977..3cd5936b 100644 --- a/vm/haos-test.sh +++ b/vm/haos-test.sh @@ -417,13 +417,12 @@ esac DISK_VAR="vm-${VMID}-disk-0${DISK_EXT:-}" DISK_REF="${STORAGE}:${DISK_VAR:-}" -NODE=$(hostname) msg_ok "Extracted KVM Disk Image" msg_info "Creating HAOS VM" qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -lvcreate -L 4G -n vm-${VMID}-disk-1 ${NODE} 1>&/dev/null +lvcreate -L 4G -n vm-${VMID}-disk-1 pve 1>&/dev/null qm importdisk $VMID ${FILE%.*} ${STORAGE} ${DISK_IMPORT:-} 1>&/dev/null qm set $VMID \ -efidisk0 ${STORAGE}:vm-${VMID}-disk-1,efitype=4m \ From a78448679b71bcdae8bcc94e2f9d0bdf839f0df2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 2 Dec 2023 20:47:12 -0500 Subject: [PATCH 5634/6505] Delete vm/haos-test.sh --- vm/haos-test.sh | 443 ------------------------------------------------ 1 file changed, 443 deletions(-) delete mode 100644 vm/haos-test.sh diff --git a/vm/haos-test.sh b/vm/haos-test.sh deleted file mode 100644 index 3cd5936b..00000000 --- a/vm/haos-test.sh +++ /dev/null @@ -1,443 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { - clear - cat <<"EOF" - __ __ ___ _ __ __ ____ _____ - / / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / __ \/ ___/ - / /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / /\__ \ - / __ / /_/ / / / / / / __/ / ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ / /_/ /___/ / -/_/ /_/\____/_/ /_/ /_/\___/ /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ \____//____/ - -EOF -} -header_info -echo -e "\n Loading..." -GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') -NEXTID=$(pvesh get /cluster/nextid) -VERSIONS=(stable beta dev) -for version in "${VERSIONS[@]}"; do - eval "$version=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/$version.json | grep "ova" | cut -d '"' -f 4)" -done -YW=$(echo "\033[33m") -BL=$(echo "\033[36m") -HA=$(echo "\033[1;34m") -RD=$(echo "\033[01;31m") -BGN=$(echo "\033[4;92m") -GN=$(echo "\033[1;92m") -DGN=$(echo "\033[32m") -CL=$(echo "\033[m") -BFR="\\r\\033[K" -HOLD="-" -CM="${GN}✓${CL}" -CROSS="${RD}✗${CL}" -THIN="discard=on,ssd=1," -set -euo pipefail -trap 'error_handler $LINENO "$BASH_COMMAND"' ERR -trap cleanup EXIT -function error_handler() { - local exit_code="$?" - local line_number="$1" - local command="$2" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" - cleanup_vmid -} - -function cleanup_vmid() { - if qm status $VMID &>/dev/null; then - qm stop $VMID &>/dev/null - qm destroy $VMID &>/dev/null - fi -} - -function cleanup() { - popd >/dev/null - rm -rf $TEMP_DIR -} - -TEMP_DIR=$(mktemp -d) -pushd $TEMP_DIR >/dev/null -if whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then - : -else - header_info && echo -e "⚠ User exited script \n" && exit -fi - -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." -} - -function msg_ok() { - local msg="$1" - echo -e "${BFR} ${CM} ${GN}${msg}${CL}" -} - -function msg_error() { - local msg="$1" - echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" -} - -function check_root() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi -} - -function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then - msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - msg_error "This script will not work with PiMox! \n" - echo -e "Exiting..." - sleep 2 - exit - fi -} - -function ssh_check() { - if command -v pveversion >/dev/null 2>&1; then - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then - echo "you've been warned" - else - clear - exit - fi - fi - fi -} - -function exit-script() { - clear - echo -e "⚠ User exited script \n" - exit -} - -function default_settings() { - BRANCH="$stable" - VMID="$NEXTID" - FORMAT=",efitype=4m" - MACHINE="" - DISK_CACHE="cache=writethrough," - HN="haos$stable" - CPU_TYPE=" -cpu host" - CORE_COUNT="2" - RAM_SIZE="4096" - BRG="vmbr0" - MAC="$GEN_MAC" - VLAN="" - MTU="" - START_VM="no" - echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" - echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" - echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" - echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" - echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" - echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" - echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" - echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" - echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" - echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" - echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" - echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" - echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" - echo -e "${BL}Creating a HAOS VM using the above default settings${CL}" -} - -function advanced_settings() { - if BRANCH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \ - "$stable" "Stable " ON \ - "$beta" "Beta " OFF \ - "$dev" "Dev " OFF \ - 3>&1 1>&2 2>&3); then - echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}" - else - exit-script - fi - - while true; do - if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z "$VMID" ]; then - VMID="$NEXTID" - fi - if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then - echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" - sleep 2 - continue - fi - echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" - break - else - exit-script - fi - done - - if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "i440fx" "Machine i440fx" ON \ - "q35" "Machine q35" OFF \ - 3>&1 1>&2 2>&3); then - if [ $MACH = q35 ]; then - echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" - FORMAT="" - MACHINE=" -machine q35" - else - echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" - FORMAT=",efitype=4m" - MACHINE="" - fi - else - exit-script - fi - - if DISK_CACHE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ - "0" "None" OFF \ - "1" "Write Through (Default)" ON \ - 3>&1 1>&2 2>&3); then - if [ $DISK_CACHE1 = "1" ]; then - echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" - DISK_CACHE="cache=writethrough," - else - echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" - DISK_CACHE="" - fi - else - exit-script - fi - - if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z $VM_NAME ]; then - HN="haos${BRANCH}" - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - else - HN=$(echo ${VM_NAME,,} | tr -d ' ') - echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" - fi - else - exit-script - fi - - if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ - "0" "KVM64" OFF \ - "1" "Host (Default)" ON \ - 3>&1 1>&2 2>&3); then - if [ $CPU_TYPE1 = "1" ]; then - echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" - CPU_TYPE=" -cpu host" - else - echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" - CPU_TYPE="" - fi - else - exit-script - fi - - if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z $CORE_COUNT ]; then - CORE_COUNT="2" - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - else - echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" - fi - else - exit-script - fi - - if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z $RAM_SIZE ]; then - RAM_SIZE="4096" - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - else - echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" - fi - else - exit-script - fi - - if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z $BRG ]; then - BRG="vmbr0" - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - else - echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" - fi - else - exit-script - fi - - if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z $MAC1 ]; then - MAC="$GEN_MAC" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" - else - MAC="$MAC1" - echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" - fi - else - exit-script - fi - - if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z $VLAN1 ]; then - VLAN1="Default" - VLAN="" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - else - VLAN=",tag=$VLAN1" - echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" - fi - else - exit-script - fi - - if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then - if [ -z $MTU1 ]; then - MTU1="Default" - MTU="" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - else - MTU=",mtu=$MTU1" - echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" - fi - else - exit-script - fi - - if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then - echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" - START_VM="yes" - else - echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" - START_VM="no" - fi - - if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then - echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}" - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -function start_script() { - if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then - header_info - echo -e "${BL}Using Default Settings${CL}" - default_settings - else - header_info - echo -e "${RD}Using Advanced Settings${CL}" - advanced_settings - fi -} - -check_root -arch_check -pve_check -ssh_check -start_script - -msg_info "Validating Storage" -while read -r line; do - TAG=$(echo $line | awk '{print $1}') - TYPE=$(echo $line | awk '{printf "%-10s", $2}') - FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=("$TAG" "$ITEM" "OFF") -done < <(pvesm status -content images | awk 'NR>1') -VALID=$(pvesm status -content images | awk 'NR>1') -if [ -z "$VALID" ]; then - msg_error "Unable to detect a valid storage location." - exit -elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then - STORAGE=${STORAGE_MENU[0]} -else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit - done -fi -msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image" -if [ "$BRANCH" == "$dev" ]; then - URL=https://os-artifacts.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -else - URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz -fi -sleep 2 -msg_ok "${CL}${BL}${URL}${CL}" -wget -q --show-progress $URL -echo -en "\e[1A\e[0K" -FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}" -msg_info "Extracting KVM Disk Image" -unxz $FILE -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in -nfs | dir) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_IMPORT="-format raw" - THIN="" - ;; -btrfs) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_IMPORT="-format raw" - FORMAT=",efitype=4m" - THIN="" - ;; -esac - -DISK_VAR="vm-${VMID}-disk-0${DISK_EXT:-}" -DISK_REF="${STORAGE}:${DISK_VAR:-}" - -msg_ok "Extracted KVM Disk Image" -msg_info "Creating HAOS VM" -qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ - -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -lvcreate -L 4G -n vm-${VMID}-disk-1 pve 1>&/dev/null -qm importdisk $VMID ${FILE%.*} ${STORAGE} ${DISK_IMPORT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${STORAGE}:vm-${VMID}-disk-1,efitype=4m \ - -scsi0 "${DISK_REF},${DISK_CACHE}${THIN}size=32G" \ - -boot order=scsi0 \ - -description "
    - - # Home Assistant OS - - -
    " >/dev/null -msg_ok "Created HAOS VM ${CL}${BL}(${HN})" -if [ "$START_VM" == "yes" ]; then - msg_info "Starting Home Assistant OS VM" - qm start $VMID - msg_ok "Started Home Assistant OS VM" -fi -msg_ok "Completed Successfully!\n" From 21e95ccf6d6cacab691f4426a3d36aeb4e15eff2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Dec 2023 13:14:09 -0500 Subject: [PATCH 5635/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 9d011721..3506f415 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -25,3 +25,5 @@ [Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/) [How-to: Proxmox VE 7.4 to 8.0 Upgrade](https://www.derekseaman.com/2023/06/how-to-proxmox-7-4-to-8-0-upgrade.html) + +[iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs) From bafd32f777b97526a592e0dffa8837faf9127ccf Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Dec 2023 14:40:39 -0500 Subject: [PATCH 5636/6505] Update HW Acceleration LXCs --- install/emby-install.sh | 8 +++++--- install/jellyfin-install.sh | 8 +++++--- install/plex-install.sh | 8 +++++--- install/scrypted-install.sh | 9 +++++---- install/tdarr-install.sh | 9 +++++---- install/unmanic-install.sh | 3 ++- misc/hw-acceleration.sh | 2 +- 7 files changed, 28 insertions(+), 19 deletions(-) diff --git a/install/emby-install.sh b/install/emby-install.sh index 52fc3af6..e0337e77 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -29,9 +29,11 @@ if [[ "$CTTYPE" == "0" ]]; then else $STD apt-get install -y intel-opencl-icd fi - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render msg_ok "Set Up Hardware Acceleration" fi diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index 787b0ab2..be373996 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -30,9 +30,11 @@ if [[ "$CTTYPE" == "0" ]]; then else $STD apt-get install -y intel-opencl-icd fi - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render msg_ok "Set Up Hardware Acceleration" fi diff --git a/install/plex-install.sh b/install/plex-install.sh index 5e7fda8d..4aec89ce 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -29,9 +29,11 @@ if [[ "$CTTYPE" == "0" ]]; then else $STD apt-get install -y intel-opencl-icd fi - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render msg_ok "Set Up Hardware Acceleration" fi diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index e51d3a65..081772fe 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -44,10 +44,11 @@ if [[ "$CTTYPE" == "0" ]]; then va-driver-all \ ocl-icd-libopencl1 \ intel-opencl-icd - - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render msg_ok "Set Up Hardware Acceleration" fi msg_info "Installing GStreamer (Patience)" diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index 5e097586..702d3203 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -25,10 +25,11 @@ if [[ "$CTTYPE" == "0" ]]; then va-driver-all \ ocl-icd-libopencl1 \ intel-opencl-icd - - /bin/chgrp video /dev/dri - /bin/chmod 755 /dev/dri - /bin/chmod 660 /dev/dri/* + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render msg_ok "Set Up Hardware Acceleration" fi diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh index ebf48b26..be5d336c 100644 --- a/install/unmanic-install.sh +++ b/install/unmanic-install.sh @@ -27,10 +27,11 @@ if [[ "$CTTYPE" == "0" ]]; then va-driver-all \ ocl-icd-libopencl1 \ intel-opencl-icd - chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render msg_ok "Set Up Hardware Acceleration" fi diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 72e807c7..32ccb72d 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -43,7 +43,7 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF -pct exec $privileged_container -- bash -c "apt-get -y install va-driver-all && apt-get -y install ocl-icd-libopencl1 && apt-get install -y intel-opencl-icd" +pct exec $privileged_container -- bash -c "apt-get -y install va-driver-all && apt-get -y install ocl-icd-libopencl1 && apt-get install -y intel-opencl-icd && chgrp video /dev/dri && chmod 755 /dev/dri && chmod 660 /dev/dri/* && adduser \$(id -u -n) video && adduser \$(id -u -n) render" header_info echo -e "Completed Successfully!\n" echo -e "Reboot container $privileged_container to apply the new settings\n" From d4363eb49f7530620c4d7019a7bfdaf9f2838653 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 4 Dec 2023 05:19:05 -0500 Subject: [PATCH 5637/6505] Update kavita.sh fixes https://github.com/tteck/Proxmox/issues/2151 --- ct/kavita.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/kavita.sh b/ct/kavita.sh index f5e1ba5b..1b37feda 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -56,7 +56,7 @@ if [[ ! -d /opt/Kavita ]]; then msg_error "No ${APP} Installation Found!"; exit; msg_info "Updating $APP LXC" systemctl stop kavita RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) &>/dev/null +tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) --no-same-owner &>/dev/null rm -rf Kavita/config cp -r Kavita/* /opt/Kavita rm -rf Kavita From 1290e91450c3c510638a11134d42252b7802fda7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 4 Dec 2023 05:56:44 -0500 Subject: [PATCH 5638/6505] Update turnkey.sh tweak --- turnkey/turnkey.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index 6eb31634..f4100572 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -15,7 +15,7 @@ function header_info { EOF } -set -eEuo pipefail +set -euo pipefail shopt -s expand_aliases alias die='EXIT=$? LINE=$LINENO error_exit' trap die ERR From cb312d1f5b186ec8a2bffb23cfcbd891550b4e9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 5 Dec 2023 05:41:51 -0500 Subject: [PATCH 5639/6505] Update turnkey.sh tweak --- turnkey/turnkey.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index f4100572..795dfbcb 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -204,7 +204,7 @@ pct start "$CTID" sleep 5 # Get container IP -set +e +set +euo pipefail # Turn off error checking max_attempts=5 attempt=1 IP="" @@ -224,7 +224,6 @@ if [[ -z $IP ]]; then IP="NOT FOUND" fi -set -e # Start Proxmox VE Monitor-All if available if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service From a22c3644a69470af17bd60f6f56173b5eb248cb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Dec 2023 20:13:12 -0500 Subject: [PATCH 5640/6505] drop fuse-overlayfs storage driver - As of Proxmox 8.1, `overlay2` is now a supported Docker storage driver when using ZFS, specifically with OpenZFS version 2.2.0 or later. --- ct/casaos.sh | 1 - ct/docker.sh | 1 - ct/dockge.sh | 1 - ct/homeassistant.sh | 1 - ct/umbrel.sh | 1 - install/casaos-install.sh | 9 --------- install/docker-install.sh | 11 +---------- install/homeassistant-install.sh | 11 +---------- install/umbrel-install.sh | 9 --------- misc/build.func | 33 +++++--------------------------- 10 files changed, 7 insertions(+), 71 deletions(-) diff --git a/ct/casaos.sh b/ct/casaos.sh index a6dab10d..ba4a5aed 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -46,7 +46,6 @@ function default_settings() { MAC="" VLAN="" SSH="no" - FUSE="no" VERB="no" echo_default } diff --git a/ct/docker.sh b/ct/docker.sh index db176aec..81a3a1dc 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -46,7 +46,6 @@ function default_settings() { MAC="" VLAN="" SSH="no" - FUSE="no" VERB="no" echo_default } diff --git a/ct/dockge.sh b/ct/dockge.sh index 64cc093e..fba046b6 100644 --- a/ct/dockge.sh +++ b/ct/dockge.sh @@ -46,7 +46,6 @@ function default_settings() { MAC="" VLAN="" SSH="no" - FUSE="no" VERB="no" echo_default } diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 1298c150..2056f0d6 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -46,7 +46,6 @@ function default_settings() { MAC="" VLAN="" SSH="no" - FUSE="no" VERB="no" echo_default } diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 2dd3c08f..d5992e0e 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -46,7 +46,6 @@ function default_settings() { MAC="" VLAN="" SSH="no" - FUSE="no" VERB="no" echo_default } diff --git a/install/casaos-install.sh b/install/casaos-install.sh index d3caecbc..05473132 100644 --- a/install/casaos-install.sh +++ b/install/casaos-install.sh @@ -22,16 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing CasaOS (Patience)" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi $STD bash <(curl -fsSL https://get.casaos.io/v0.4.1) msg_ok "Installed CasaOS" diff --git a/install/docker-install.sh b/install/docker-install.sh index 1a15edb3..6425d48e 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -31,16 +31,7 @@ DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then - VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - cd /usr/local/bin - curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 - chmod 755 /usr/local/bin/fuse-overlayfs - cd ~ - echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' >/etc/docker/daemon.json -else - echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json -fi +echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json $STD sh <(curl -sSL https://get.docker.com) msg_ok "Installed Docker $DOCKER_LATEST_VERSION" diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 0c19ca6c..3609a358 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -42,16 +42,7 @@ PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") msg_info "Installing Docker $DOCKER_LATEST_VERSION" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then - VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - cd /usr/local/bin - curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 - chmod 755 /usr/local/bin/fuse-overlayfs - cd ~ - echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' >/etc/docker/daemon.json -else - echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json -fi +echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json $STD sh <(curl -sSL https://get.docker.com) msg_ok "Installed Docker $DOCKER_LATEST_VERSION" diff --git a/install/umbrel-install.sh b/install/umbrel-install.sh index ea4d17ba..db058225 100644 --- a/install/umbrel-install.sh +++ b/install/umbrel-install.sh @@ -22,16 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Umbrel (Patience)" DOCKER_CONFIG_PATH='/etc/docker/daemon.json' mkdir -p $(dirname $DOCKER_CONFIG_PATH) -if [ "$ST" == "yes" ]; then -VER=$(curl -s https://api.github.com/repos/containers/fuse-overlayfs/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -cd /usr/local/bin -curl -sSL -o fuse-overlayfs https://github.com/containers/fuse-overlayfs/releases/download/$VER/fuse-overlayfs-x86_64 -chmod 755 /usr/local/bin/fuse-overlayfs -cd ~ -echo -e '{\n "storage-driver": "fuse-overlayfs",\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -else echo -e '{\n "log-driver": "journald"\n}' > /etc/docker/daemon.json -fi $STD bash <(curl -fsSL https://umbrel.sh) systemctl daemon-reload $STD systemctl enable --now umbrel-startup.service diff --git a/misc/build.func b/misc/build.func index e734fd1f..5656561d 100644 --- a/misc/build.func +++ b/misc/build.func @@ -122,9 +122,6 @@ echo_default() { echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}" - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}" - fi echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}" echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" } @@ -403,15 +400,6 @@ advanced_settings() { echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}" fi - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then - FUSE="yes" - else - FUSE="no" - fi - echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}" - fi - if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then VERB="yes" else @@ -475,21 +463,13 @@ start() { build_container() { if [ "$VERB" == "yes" ]; then set -x; fi - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - if [ "$FUSE" == "yes" ]; then - FEATURES="fuse=1,keyctl=1,nesting=1" - else - FEATURES="keyctl=1,nesting=1" - fi - fi - if [[ "$APP" != "Docker" && "$APP" != "Umbrel" && "$APP" != "CasaOS" && "$APP" != "Home Assistant" ]]; then - if [ "$CT_TYPE" == "1" ]; then - FEATURES="keyctl=1,nesting=1" - else - FEATURES="nesting=1" - fi + if [ "$CT_TYPE" == "1" ]; then + FEATURES="keyctl=1,nesting=1" + else + FEATURES="nesting=1" fi + TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if [ "$var_os" == "alpine" ]; then @@ -498,9 +478,6 @@ build_container() { export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" fi export tz="$timezone" - if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then - export ST="$FUSE" - fi export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" export app="$NSAPP" From e2354aaab88c790102db67fb435aa6d6b0b768b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Dec 2023 20:30:41 -0500 Subject: [PATCH 5641/6505] Update homeassistant-install.sh change Portainer port to 9443 --- install/homeassistant-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 3609a358..958789e4 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -54,7 +54,7 @@ msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" $STD docker volume create portainer_data $STD docker run -d \ -p 8000:8000 \ - -p 9000:9000 \ + -p 9443:9443 \ --name=portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ From 9a9e91988fa8879957e8dd2942a01c51493655a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Dec 2023 07:59:22 -0500 Subject: [PATCH 5642/6505] Update syncthing-install.sh fix config path --- install/syncthing-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh index 6fe0f10a..43348999 100644 --- a/install/syncthing-install.sh +++ b/install/syncthing-install.sh @@ -28,7 +28,7 @@ $STD apt-get install -y syncthing $STD systemctl enable syncthing@root.service systemctl start syncthing@root.service sleep 5 -sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.config/syncthing/config.xml +sed -i "{s/127.0.0.1:8384/0.0.0.0:8384/g}" /root/.local/state/syncthing/config.xml systemctl restart syncthing@root.service msg_ok "Installed Syncthing" From 587a8d64673a4172e47945fd5b4b45ff8523a4b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 06:44:09 -0500 Subject: [PATCH 5643/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 3506f415..11981378 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -27,3 +27,5 @@ [How-to: Proxmox VE 7.4 to 8.0 Upgrade](https://www.derekseaman.com/2023/06/how-to-proxmox-7-4-to-8-0-upgrade.html) [iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs) + +[Proxmox + NetData]() From ec08dae49cc0e675c0458937b1e414861bb2ac4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 09:15:10 -0500 Subject: [PATCH 5644/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 1 - 1 file changed, 1 deletion(-) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 11981378..34e92707 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -28,4 +28,3 @@ [iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs) -[Proxmox + NetData]() From 128f22d0001461a6aa9170bd4ef603324f0d9e0a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 12:19:06 -0500 Subject: [PATCH 5645/6505] Create netdata.sh --- misc/netdata.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 misc/netdata.sh diff --git a/misc/netdata.sh b/misc/netdata.sh new file mode 100644 index 00000000..b4dd83e1 --- /dev/null +++ b/misc/netdata.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +clear +cat <<"EOF" + _ __ __ ____ __ + / | / /__ / /_/ __ \____ _/ /_____ _ + / |/ / _ \/ __/ / / / __ `/ __/ __ `/ + / /| / __/ /_/ /_/ / /_/ / /_/ /_/ / +/_/ |_/\___/\__/_____/\__,_/\__/\__,_/ + +EOF + +install() { +while true; do + read -p "This script will install NetData on Proxmox VE. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +cat </etc/apt/sources.list.d/netdata.list +deb http://repo.netdata.cloud/repos/stable/debian/ bookworm/ +deb http://repo.netdata.cloud/repos/repoconfig/debian/ bookworm/ +EOF +apt-get update && apt-get -y upgrade +apt-get install -y netdata +echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" +} + +uninstall() { +apt remove -y netdata --purge +rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/apt/sources.list.d/netdata.list +apt autoremove -y +userdel netdata + echo -e "\nRemoved NetData from Proxmox VE\n" +} + +if ! command -v pveversion >/dev/null 2>&1; then + clear + echo -e "\n No PVE Detected!\n" + exit +fi + +OPTIONS=(Install "Install NetData on Proxmox VE" \ + Uninstall "Uninstall NetData from Proxmox VE") + +# Show the whiptail menu and save the user's choice +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +case $CHOICE in + "Install") + install + ;; + "Uninstall") + uninstall + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac From a78e93ae8330b55a03e9c1c75719d5c40650a785 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 13:31:54 -0500 Subject: [PATCH 5646/6505] Update netdata.sh tweak --- misc/netdata.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/netdata.sh b/misc/netdata.sh index b4dd83e1..51b9f743 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -25,6 +25,8 @@ while true; do esac done +useradd -r -s /bin/false netdata +wget -q https://repo.netdata.cloud/netdatabot.gpg.key -O - | gpg --dearmor >/usr/share/keyrings/netdata-archive-keyring.gpg cat </etc/apt/sources.list.d/netdata.list deb http://repo.netdata.cloud/repos/stable/debian/ bookworm/ deb http://repo.netdata.cloud/repos/repoconfig/debian/ bookworm/ From 487657850414d873887db52c2e4b092c930147ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 13:48:03 -0500 Subject: [PATCH 5647/6505] Update netdata.sh tweak --- misc/netdata.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 51b9f743..06aaf131 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -26,7 +26,7 @@ while true; do done useradd -r -s /bin/false netdata -wget -q https://repo.netdata.cloud/netdatabot.gpg.key -O - | gpg --dearmor >/usr/share/keyrings/netdata-archive-keyring.gpg +curl -fsSL https://repo.netdata.cloud/netdatabot.gpg.key >/usr/share/keyrings/netdata.gpg cat </etc/apt/sources.list.d/netdata.list deb http://repo.netdata.cloud/repos/stable/debian/ bookworm/ deb http://repo.netdata.cloud/repos/repoconfig/debian/ bookworm/ From 76b26b030e58f7a5120ab94aaf2721c1def0642a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 14:49:24 -0500 Subject: [PATCH 5648/6505] Update netdata.sh tweak --- misc/netdata.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 06aaf131..7741bb54 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -25,20 +25,20 @@ while true; do esac done -useradd -r -s /bin/false netdata -curl -fsSL https://repo.netdata.cloud/netdatabot.gpg.key >/usr/share/keyrings/netdata.gpg +curl -sSL --fail --connect-timeout 10 --retry 3 -o /root/netdata-repo-edge_2-1+debian12_all.deb https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo-edge_2-1+debian12_all.deb cat </etc/apt/sources.list.d/netdata.list deb http://repo.netdata.cloud/repos/stable/debian/ bookworm/ deb http://repo.netdata.cloud/repos/repoconfig/debian/ bookworm/ EOF +rm -rf /etc/apt/sources.list.d/netdata-edge.list apt-get update && apt-get -y upgrade apt-get install -y netdata echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" } uninstall() { -apt remove -y netdata --purge -rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/apt/sources.list.d/netdata.list +apt purge -y netdata netdata-core +rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/apt/sources.list.d/netdata.list /usr/share/keyrings/netdata.gpg apt autoremove -y userdel netdata echo -e "\nRemoved NetData from Proxmox VE\n" From a777fd5364d807e93ad7338380b79da631d24144 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 15:00:17 -0500 Subject: [PATCH 5649/6505] Update netdata.sh tweak --- misc/netdata.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 7741bb54..ea6bfa67 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -25,12 +25,12 @@ while true; do esac done -curl -sSL --fail --connect-timeout 10 --retry 3 -o /root/netdata-repo-edge_2-1+debian12_all.deb https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo-edge_2-1+debian12_all.deb +curl -sSL --fail --connect-timeout 10 --retry 3 -o netdata-repo-edge_2-1+debian12_all.deb https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo-edge_2-1+debian12_all.deb cat </etc/apt/sources.list.d/netdata.list deb http://repo.netdata.cloud/repos/stable/debian/ bookworm/ deb http://repo.netdata.cloud/repos/repoconfig/debian/ bookworm/ EOF -rm -rf /etc/apt/sources.list.d/netdata-edge.list +rm -rf /etc/apt/sources.list.d/netdata-edge.list netdata-repo-edge_2-1+debian12_all.deb apt-get update && apt-get -y upgrade apt-get install -y netdata echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" From 0e1b0a838294c470a99274149af5993c36d6e246 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 15:13:19 -0500 Subject: [PATCH 5650/6505] Update netdata.sh more tweaks --- misc/netdata.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index ea6bfa67..5bfaeb9c 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -25,13 +25,15 @@ while true; do esac done -curl -sSL --fail --connect-timeout 10 --retry 3 -o netdata-repo-edge_2-1+debian12_all.deb https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo-edge_2-1+debian12_all.deb +curl -sSL --fail --connect-timeout 10 --retry 3 -o /root/netdata-repo-edge_2-1+debian12_all.deb https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo-edge_2-1+debian12_all.deb +apt-get install -y /root/netdata-repo-edge_2-1+debian12_all.deb cat </etc/apt/sources.list.d/netdata.list deb http://repo.netdata.cloud/repos/stable/debian/ bookworm/ deb http://repo.netdata.cloud/repos/repoconfig/debian/ bookworm/ EOF rm -rf /etc/apt/sources.list.d/netdata-edge.list netdata-repo-edge_2-1+debian12_all.deb -apt-get update && apt-get -y upgrade +apt-get update &>/dev/null +apt-get -y upgrade apt-get install -y netdata echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" } From 5e4f0d683ac73a4cbe9fac81b65cdc01634edf80 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 15:58:56 -0500 Subject: [PATCH 5651/6505] Update USER_SUBMITTED_GUIDES.md NetData --- USER_SUBMITTED_GUIDES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 34e92707..11981378 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -28,3 +28,4 @@ [iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs) +[Proxmox + NetData]() From dbf7425f222f8263ff55ba82b9b140d7d9f1e013 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 16:10:59 -0500 Subject: [PATCH 5652/6505] Delete misc/netdata.sh --- misc/netdata.sh | 73 ------------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 misc/netdata.sh diff --git a/misc/netdata.sh b/misc/netdata.sh deleted file mode 100644 index 5bfaeb9c..00000000 --- a/misc/netdata.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2023 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -clear -cat <<"EOF" - _ __ __ ____ __ - / | / /__ / /_/ __ \____ _/ /_____ _ - / |/ / _ \/ __/ / / / __ `/ __/ __ `/ - / /| / __/ /_/ /_/ / /_/ / /_/ /_/ / -/_/ |_/\___/\__/_____/\__,_/\__/\__,_/ - -EOF - -install() { -while true; do - read -p "This script will install NetData on Proxmox VE. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - -curl -sSL --fail --connect-timeout 10 --retry 3 -o /root/netdata-repo-edge_2-1+debian12_all.deb https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo-edge_2-1+debian12_all.deb -apt-get install -y /root/netdata-repo-edge_2-1+debian12_all.deb -cat </etc/apt/sources.list.d/netdata.list -deb http://repo.netdata.cloud/repos/stable/debian/ bookworm/ -deb http://repo.netdata.cloud/repos/repoconfig/debian/ bookworm/ -EOF -rm -rf /etc/apt/sources.list.d/netdata-edge.list netdata-repo-edge_2-1+debian12_all.deb -apt-get update &>/dev/null -apt-get -y upgrade -apt-get install -y netdata -echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" -} - -uninstall() { -apt purge -y netdata netdata-core -rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/apt/sources.list.d/netdata.list /usr/share/keyrings/netdata.gpg -apt autoremove -y -userdel netdata - echo -e "\nRemoved NetData from Proxmox VE\n" -} - -if ! command -v pveversion >/dev/null 2>&1; then - clear - echo -e "\n No PVE Detected!\n" - exit -fi - -OPTIONS=(Install "Install NetData on Proxmox VE" \ - Uninstall "Uninstall NetData from Proxmox VE") - -# Show the whiptail menu and save the user's choice -CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" --menu "Select an option:" 10 58 2 \ - "${OPTIONS[@]}" 3>&1 1>&2 2>&3) - -case $CHOICE in - "Install") - install - ;; - "Uninstall") - uninstall - ;; - *) - echo "Exiting..." - exit 0 - ;; -esac From 6b31484fffc896e5eabec06119da11deb39d02fd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 10 Dec 2023 18:16:44 -0500 Subject: [PATCH 5653/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5724aa3e..4db61b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-12-10 + +### Changed + +- **Homarr LXC** + - Removed, again. + ## 2023-12-02 ### Changed From 54720bdcdb97ee8d529cb6ecb70f7a8aa21e2129 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Dec 2023 06:12:00 -0500 Subject: [PATCH 5654/6505] Update heimdalldashboard-install.sh add php-intl --- install/heimdalldashboard-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index 78d3be90..5fd52cff 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -24,6 +24,7 @@ $STD apt-get install -y php $STD apt-get install -y php-sqlite3 $STD apt-get install -y php-zip $STD apt-get install -y php-xml +$STD apt-get install -y php-intl msg_ok "Installed PHP" RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') From f39262c86eaab2df8f5d4d0c07a525f43daca4d8 Mon Sep 17 00:00:00 2001 From: Pablo Date: Thu, 14 Dec 2023 10:07:34 +0100 Subject: [PATCH 5655/6505] Updated address of cloud img file - ubuntu-vm.sh (#2189) Update to '20231207' https://cloud-images.ubuntu.com/jammy/20231207/jammy-server-cloudimg-amd64.img --- vm/ubuntu-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index e971c027..e9eacdf3 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -370,7 +370,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Retrieving the URL for the Ubuntu 22.04 Disk Image" -URL=https://cloud-images.ubuntu.com/jammy/20231027/jammy-server-cloudimg-amd64.img +URL=https://cloud-images.ubuntu.com/jammy/20231207/jammy-server-cloudimg-amd64.img sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From 589d7d6377165c7d0404ad9dadc22f37a64ee10d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Dec 2023 04:51:52 -0500 Subject: [PATCH 5656/6505] Update ubuntu-vm.sh set image to `current` --- vm/ubuntu-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index e9eacdf3..4ff0af77 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -370,7 +370,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Retrieving the URL for the Ubuntu 22.04 Disk Image" -URL=https://cloud-images.ubuntu.com/jammy/20231207/jammy-server-cloudimg-amd64.img +URL=https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From 9873829c6786d30035b48eaa8806e4163b61b37f Mon Sep 17 00:00:00 2001 From: Gerard Date: Thu, 14 Dec 2023 23:23:35 +0100 Subject: [PATCH 5657/6505] Small textual change (#2192) --- misc/hw-acceleration.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 32ccb72d..0806bdfa 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -19,7 +19,7 @@ EOF } header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Add HW Acceleration" --yesno "This Will Add HW Acceleration to an exixting LXC Container. Proceed?" 10 68 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Add HW Acceleration" --yesno "This Will Add HW Acceleration to an existing LXC Container. Proceed?" 10 68 || exit NODE=$(hostname) PREV_MENU=() MSG_MAX_LENGTH=0 From 72b8deb363170bb20c553bd5e7787942b588773c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 16 Dec 2023 15:01:04 -0500 Subject: [PATCH 5658/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index add592ee..37656877 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -55,7 +55,7 @@ msg_ok "Installed Openresty" msg_info "Installing Node.js" $STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) -. ~/.bashrc +source ~/.bashrc $STD nvm install 16.20.1 ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node msg_ok "Installed Node.js" From 144c067c6f3e4298b73c017103912563c0c08f3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Dec 2023 20:21:23 -0500 Subject: [PATCH 5659/6505] Update homepage-install.sh install per releases/latest --- install/homepage-install.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 52dbd17e..00e2fec6 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -37,15 +37,18 @@ $STD apt-get install -y nodejs $STD npm install -g pnpm msg_ok "Installed Node.js" -msg_info "Installing Homepage (Patience)" -cd /opt -$STD git clone https://github.com/benphelps/homepage.git +RELEASE=$(curl -s https://api.github.com/repos/gethomepage/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Installing Homepage v${RELEASE} (Patience)" +wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz +$STD tar -xzf v${RELEASE}.tar.gz +mkdir -p /opt/homepage/config +mv homepage-${RELEASE}/* /opt/homepage +rm -rf mv homepage-${RELEASE} cd /opt/homepage -mkdir -p config cp /opt/homepage/src/skeleton/* /opt/homepage/config $STD pnpm install $STD pnpm build -msg_ok "Installed Homepage" +msg_ok "Installed Homepage v${RELEASE}" msg_info "Creating Service" service_path="/etc/systemd/system/homepage.service" From 0909ad493b4822ba7fcadade610aa84477fb7c1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Dec 2023 20:23:32 -0500 Subject: [PATCH 5660/6505] Update homepage.sh update to /releases/latest --- ct/homepage.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ct/homepage.sh b/ct/homepage.sh index eba11d3c..137ae1a1 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -53,17 +53,19 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/homepage ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP}" -if ! command -v pnpm >/dev/null 2>&1; then - npm install -g pnpm &>/dev/null -fi -cd /opt/homepage +RELEASE=$(curl -s https://api.github.com/repos/gethomepage/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Updating Homepage to v${RELEASE} (Patience)" systemctl stop homepage -git pull --force &>/dev/null -pnpm install &>/dev/null -pnpm build &>/dev/null +wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz +tar -xzf v${RELEASE}.tar.gz +cp -r homepage-${RELEASE}/* /opt/homepage/ +rm -rf mv homepage-${RELEASE} +cd /opt/homepage +npx update-browserslist-db@latest +pnpm install +pnpm build systemctl start homepage -msg_ok "Updated Successfully" +msg_ok "Updated Homepage to v${RELEASE}" exit } From 82921933ea966e100caa775dc7725d499541cda6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Dec 2023 20:32:27 -0500 Subject: [PATCH 5661/6505] Update homepage-install.sh tweak --- install/homepage-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 00e2fec6..0a1dee42 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -43,7 +43,7 @@ wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.ta $STD tar -xzf v${RELEASE}.tar.gz mkdir -p /opt/homepage/config mv homepage-${RELEASE}/* /opt/homepage -rm -rf mv homepage-${RELEASE} +rm -rf homepage-${RELEASE} cd /opt/homepage cp /opt/homepage/src/skeleton/* /opt/homepage/config $STD pnpm install From e3739a8d40cec835f64ca8693c30afe44aae08fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Dec 2023 20:33:19 -0500 Subject: [PATCH 5662/6505] Update homepage-install.sh tweak --- install/homepage-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 0a1dee42..457eb796 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y git $STD apt-get install -y make $STD apt-get install -y g++ $STD apt-get install -y gcc From ab36af75af826ad7862d147578bc056997b2cd09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 17 Dec 2023 20:35:11 -0500 Subject: [PATCH 5663/6505] Update homepage.sh tweak --- ct/homepage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homepage.sh b/ct/homepage.sh index 137ae1a1..988d0074 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -59,7 +59,7 @@ systemctl stop homepage wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz tar -xzf v${RELEASE}.tar.gz cp -r homepage-${RELEASE}/* /opt/homepage/ -rm -rf mv homepage-${RELEASE} +rm -rf homepage-${RELEASE} cd /opt/homepage npx update-browserslist-db@latest pnpm install From e441bdbad6a44bea1baef78f7a870c60affb7337 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Dec 2023 19:49:20 -0500 Subject: [PATCH 5664/6505] Create netdata.sh --- misc/netdata.sh | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 misc/netdata.sh diff --git a/misc/netdata.sh b/misc/netdata.sh new file mode 100644 index 00000000..1005f065 --- /dev/null +++ b/misc/netdata.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +clear +cat <<"EOF" + _ __ __ ____ __ + / | / /__ / /_/ __ \____ _/ /_____ _ + / |/ / _ \/ __/ / / / __ `/ __/ __ `/ + / /| / __/ /_/ /_/ / /_/ / /_/ /_/ / +/_/ |_/\___/\__/_____/\__,_/\__/\__,_/ + +EOF + +install() { +while true; do + read -p "This script will install NetData on Proxmox VE. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +wget -q https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_2-2+debian12_all.deb +dpkg -i netdata-repo_2-2+debian12_all.deb +rm -rf netdata-repo_2-2+debian12_all.deb +apt-get update &>/dev/null +apt-get -y upgrade +apt-get install -y netdata +echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" +} + +uninstall() { +systemctl stop netdata +apt-get remove -y --purge netdata netdata-repo +rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/apt/sources.list.d/netdata.list +rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg +systemctl daemon-reload +apt autoremove -y +userdel netdata + echo -e "\nRemoved NetData from Proxmox VE\n" +} + +if ! command -v pveversion >/dev/null 2>&1; then + clear + echo -e "\n No PVE Detected!\n" + exit +fi + +OPTIONS=(Install "Install NetData on Proxmox VE" \ + Uninstall "Uninstall NetData from Proxmox VE") + +# Show the whiptail menu and save the user's choice +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +case $CHOICE in + "Install") + install + ;; + "Uninstall") + uninstall + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac From 524e80e88165d63bda15bd5b59c36fc773d3b921 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Dec 2023 20:17:36 -0500 Subject: [PATCH 5665/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4db61b3d..fc07fadf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2023-12-19 + +### Changed + +- **Proxmox VE Netdata** + - NEW Script + ## 2023-12-10 ### Changed From fb394e9e8136145200064fcad75b367280fbdc18 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Dec 2023 20:23:19 -0500 Subject: [PATCH 5666/6505] Update netdata.sh tweak --- misc/netdata.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 1005f065..01fd787f 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -36,7 +36,7 @@ echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" uninstall() { systemctl stop netdata -apt-get remove -y --purge netdata netdata-repo +apt-get remove --purge -y netdata netdata-repo rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/apt/sources.list.d/netdata.list rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg systemctl daemon-reload From b3a6f29bc2aa678a26785e29b78b9a776b02aeb7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 04:12:13 -0500 Subject: [PATCH 5667/6505] Update netdata.sh tweak --- misc/netdata.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 01fd787f..67c6646e 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -17,7 +17,7 @@ EOF install() { while true; do - read -p "This script will install NetData on Proxmox VE. Proceed(y/n)?" yn + read -p "This script will install NetData on Proxmox VE 8+. Proceed(y/n)?" yn case $yn in [Yy]*) break ;; [Nn]*) exit ;; @@ -45,16 +45,17 @@ userdel netdata echo -e "\nRemoved NetData from Proxmox VE\n" } -if ! command -v pveversion >/dev/null 2>&1; then - clear - echo -e "\n No PVE Detected!\n" +if ! pveversion | grep -Eq "pve-manager/(8\.[0-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 8.0 or higher" + echo -e "Exiting..." + sleep 2 exit fi OPTIONS=(Install "Install NetData on Proxmox VE" \ Uninstall "Uninstall NetData from Proxmox VE") -# Show the whiptail menu and save the user's choice CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" --menu "Select an option:" 10 58 2 \ "${OPTIONS[@]}" 3>&1 1>&2 2>&3) From 09bf75771dd10052f365962677a240b458cf5e9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 06:39:20 -0500 Subject: [PATCH 5668/6505] Update alpine-nextcloud-install.sh Nextcloud 28.0 requires sodium and bz2 --- install/alpine-nextcloud-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 8ee125bf..64c233b3 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -34,6 +34,8 @@ $STD apk add php82-pecl-smbclient $STD apk add php82-pecl-imagick $STD apk add php82-pecl-vips $STD apk add php82-exif +$STD apk add php82-sodium +$STD apk add php82-bz2 $STD apk add redis msg_ok "Installed PHP/Redis" From 7377f1627b388605957cd09baa4b0b7059fa2077 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 06:44:01 -0500 Subject: [PATCH 5669/6505] Update alpine-nextcloud.sh Nextcloud 28.0 requires sodium and bz2 --- ct/alpine-nextcloud.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index e950f101..92e2d98c 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -74,6 +74,12 @@ function update_script() { case $CHOICE in 1) apk update && apk upgrade + if ! apk -e info php82-sodium >/dev/null 2>&1; then + apk add -q php82-sodium + fi + if ! apk -e info php82-bz2 >/dev/null 2>&1; then + apk add -q php82-bz2 + fi su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ upgrade' su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ db:add-missing-indices' exit From e8c61ddea7beca012fa1b75c3ed783394801e090 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 11:25:00 -0500 Subject: [PATCH 5670/6505] Update netdata.sh code refactoring --- misc/netdata.sh | 97 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 67c6646e..2e02d515 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -5,8 +5,9 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -clear -cat <<"EOF" +function header_info { + clear + cat <<"EOF" _ __ __ ____ __ / | / /__ / /_/ __ \____ _/ /_____ _ / |/ / _ \/ __/ / / / __ `/ __/ __ `/ @@ -14,35 +15,81 @@ cat <<"EOF" /_/ |_/\___/\__/_____/\__,_/\__/\__,_/ EOF +} + +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +silent() { "$@" >/dev/null 2>&1; } +set -e +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} install() { -while true; do - read -p "This script will install NetData on Proxmox VE 8+. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done + while true; do + read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done -wget -q https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_2-2+debian12_all.deb -dpkg -i netdata-repo_2-2+debian12_all.deb -rm -rf netdata-repo_2-2+debian12_all.deb -apt-get update &>/dev/null -apt-get -y upgrade -apt-get install -y netdata -echo -e "\nInstalled NetData (http://$(hostname -I | awk '{print $1}'):19999)\n" + read -r -p "Verbose mode? " prompt + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + STD="" + else + STD="silent" + fi + header_info + + msg_info "Setting up repository" + wget -q https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_2-2+debian12_all.deb + $STD dpkg -i netdata-repo_2-2+debian12_all.deb + rm -rf netdata-repo_2-2+debian12_all.deb + msg_ok "Set up repository" + + msg_info "Installing Netdata" + $STD apt-get update + $STD apt-get install -y netdata + msg_ok "Installed Netdata\n" + msg_ok "Completed Successfully!\n" + echo -e "\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\n" } uninstall() { -systemctl stop netdata -apt-get remove --purge -y netdata netdata-repo -rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/apt/sources.list.d/netdata.list -rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg -systemctl daemon-reload -apt autoremove -y -userdel netdata - echo -e "\nRemoved NetData from Proxmox VE\n" + read -r -p "Verbose mode? " prompt + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + STD="" + else + STD="silent" + fi + header_info + + msg_info "Uninstalling Netdata" + systemctl stop netdata + rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d + rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list + $STD apt-get remove --purge -y netdata netdata-repo + systemctl daemon-reload + $STD apt autoremove -y + $STD userdel netdata + msg_ok "Uninstalled Netdata\n" + msg_ok "Completed Successfully!\n" } if ! pveversion | grep -Eq "pve-manager/(8\.[0-9])"; then From db0abe293d1b7a815d0a0f63b6d6a5f4f6fabb56 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 11:26:26 -0500 Subject: [PATCH 5671/6505] Update install.func tweak --- misc/install.func | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index a15364c2..36b46eaf 100644 --- a/misc/install.func +++ b/misc/install.func @@ -18,7 +18,6 @@ color() { # This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to "yes" verb_ip6() { if [ "$VERBOSE" = "yes" ]; then - set -x STD="" else STD="silent"; fi silent() { "$@" >/dev/null 2>&1; } From 7cfb239d70ce9bf8950bd703405f0c095a89673f Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 11:32:06 -0500 Subject: [PATCH 5672/6505] Update install.func revert tweak --- misc/install.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/install.func b/misc/install.func index 36b46eaf..a15364c2 100644 --- a/misc/install.func +++ b/misc/install.func @@ -18,6 +18,7 @@ color() { # This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to "yes" verb_ip6() { if [ "$VERBOSE" = "yes" ]; then + set -x STD="" else STD="silent"; fi silent() { "$@" >/dev/null 2>&1; } From c2a3eb52caa871f3cc0a66c2a7f3065474bb3e69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 20:54:09 -0500 Subject: [PATCH 5673/6505] Update hw-acceleration.sh - code refactoring - add an option to install intel-media-va-driver-non-free - add vainfo - add intel-gpu-tools --- misc/hw-acceleration.sh | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 0806bdfa..37ba817e 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -5,7 +5,7 @@ # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -set -eEuo pipefail +set -e function header_info { clear cat <<"EOF" @@ -19,7 +19,7 @@ EOF } header_info echo "Loading..." -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Add HW Acceleration" --yesno "This Will Add HW Acceleration to an existing LXC Container. Proceed?" 10 68 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Add Intel HW Acceleration" --yesno "This Will Add Intel HW Acceleration to an existing LXC Container. Proceed?" 8 72 || exit NODE=$(hostname) PREV_MENU=() MSG_MAX_LENGTH=0 @@ -33,7 +33,7 @@ while read -r TAG ITEM; do ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET PREV_MENU+=("$TAG" "$ITEM " "OFF") done < <(echo "$privileged_containers") -privileged_container=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Privileged Containers on $NODE" --checklist "\nSelect a Container To Add HW Acceleration:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${PREV_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +privileged_container=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Privileged Containers on $NODE" --checklist "\nSelect a Container To Add Intel HW Acceleration:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${PREV_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit header_info cat <>/etc/pve/lxc/${privileged_container}.conf lxc.cgroup2.devices.allow: c 226:0 rwm @@ -43,7 +43,27 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF -pct exec $privileged_container -- bash -c "apt-get -y install va-driver-all && apt-get -y install ocl-icd-libopencl1 && apt-get install -y intel-opencl-icd && chgrp video /dev/dri && chmod 755 /dev/dri && chmod 660 /dev/dri/* && adduser \$(id -u -n) video && adduser \$(id -u -n) render" +read -r -p "Do you need the intel-media-va-driver-non-free driver (Sources change)? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + header_info + pct exec ${privileged_container} -- bash -c "cat </etc/apt/sources.list + +deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware +deb-src http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware + +deb http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware +deb-src http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware + +deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware +deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware +EOF" + + pct exec ${privileged_container} -- bash -c "apt-get update && apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && adduser \$(id -u -n) video && adduser \$(id -u -n) render" +else + header_info + pct exec ${privileged_container} -- bash -c "apt-get install -y va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && adduser \$(id -u -n) video && adduser \$(id -u -n) render" +fi +whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Added tools" "vainfo, execute command 'vainfo'\nintel-gpu-tools, execute command 'intel_gpu_top'" 8 58 header_info echo -e "Completed Successfully!\n" echo -e "Reboot container $privileged_container to apply the new settings\n" From d94dacc53b656efc8cfea05ae0c3eae48d2b7cd6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Dec 2023 22:13:31 -0500 Subject: [PATCH 5674/6505] Update hw-acceleration.sh - code refactoring - add non-verbose option --- misc/hw-acceleration.sh | 47 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 37ba817e..8c9d03dc 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -17,24 +17,55 @@ function header_info { EOF } + +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +set -e header_info echo "Loading..." +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + whiptail --backtitle "Proxmox VE Helper Scripts" --title "Add Intel HW Acceleration" --yesno "This Will Add Intel HW Acceleration to an existing LXC Container. Proceed?" 8 72 || exit NODE=$(hostname) PREV_MENU=() MSG_MAX_LENGTH=0 privileged_containers=$(pct list | awk 'NR>1 && system("grep -q \047unprivileged: 1\047 /etc/pve/lxc/" $1 ".conf")') + if [ -z "$privileged_containers" ]; then whiptail --msgbox "No Privileged Containers Found." 10 58 exit fi + while read -r TAG ITEM; do OFFSET=2 ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET PREV_MENU+=("$TAG" "$ITEM " "OFF") done < <(echo "$privileged_containers") + privileged_container=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Privileged Containers on $NODE" --checklist "\nSelect a Container To Add Intel HW Acceleration:\n" 16 $((MSG_MAX_LENGTH + 23)) 6 "${PREV_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit header_info +read -r -p "Verbose mode? " prompt + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + STD="" + else + STD="silent" + fi +header_info + cat <>/etc/pve/lxc/${privileged_container}.conf lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm @@ -43,9 +74,11 @@ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF + read -r -p "Do you need the intel-media-va-driver-non-free driver (Sources change)? " prompt if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then header_info + msg_info "Installing Hardware Acceleration (non-free)" pct exec ${privileged_container} -- bash -c "cat </etc/apt/sources.list deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware @@ -58,12 +91,16 @@ deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware EOF" - pct exec ${privileged_container} -- bash -c "apt-get update && apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && adduser \$(id -u -n) video && adduser \$(id -u -n) render" + pct exec ${privileged_container} -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get update && $STD apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render" + msg_ok "Installed Hardware Acceleration (non-free)" else header_info - pct exec ${privileged_container} -- bash -c "apt-get install -y va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && adduser \$(id -u -n) video && adduser \$(id -u -n) render" + msg_info "Installing Hardware Acceleration" + pct exec ${privileged_container} -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get install -y va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render" + msg_ok "Installed Hardware Acceleration" fi +sleep 1 whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Added tools" "vainfo, execute command 'vainfo'\nintel-gpu-tools, execute command 'intel_gpu_top'" 8 58 -header_info -echo -e "Completed Successfully!\n" -echo -e "Reboot container $privileged_container to apply the new settings\n" + +msg_ok "Completed Successfully!\n" +echo -e "Reboot container ${BL}$privileged_container${CL} to apply the new settings\n" From 16a37644bb5db06b3cbdd5c0f77609232ac9dcd7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Dec 2023 17:37:36 -0500 Subject: [PATCH 5675/6505] Update hw-acceleration.sh - Requires PVE Version 8.0 or higher --- misc/hw-acceleration.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 8c9d03dc..8772aba8 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -39,6 +39,14 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +if ! pveversion | grep -Eq "pve-manager/(8\.[0-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 8.0 or higher" + echo -e "Exiting..." + sleep 2 + exit +fi + whiptail --backtitle "Proxmox VE Helper Scripts" --title "Add Intel HW Acceleration" --yesno "This Will Add Intel HW Acceleration to an existing LXC Container. Proceed?" 8 72 || exit NODE=$(hostname) PREV_MENU=() From 79a542cd5addb36665fdfc4ead51c10b9c8b6450 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Dec 2023 19:45:53 -0500 Subject: [PATCH 5676/6505] Update netdata.sh tweak --- misc/netdata.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 2e02d515..3c0cb81d 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -28,7 +28,7 @@ CM="${GN}✓${CL}" silent() { "$@" >/dev/null 2>&1; } set -e header_info - +echo "Loading..." function msg_info() { local msg="$1" echo -ne " ${HOLD} ${YW}${msg}..." @@ -40,6 +40,7 @@ function msg_ok() { } install() { + header_info while true; do read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)?" yn case $yn in @@ -48,7 +49,7 @@ install() { *) echo "Please answer yes or no." ;; esac done - + header_info read -r -p "Verbose mode? " prompt if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then STD="" @@ -56,7 +57,7 @@ install() { STD="silent" fi header_info - + msg_info "Setting up repository" wget -q https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_2-2+debian12_all.deb $STD dpkg -i netdata-repo_2-2+debian12_all.deb @@ -66,12 +67,13 @@ install() { msg_info "Installing Netdata" $STD apt-get update $STD apt-get install -y netdata - msg_ok "Installed Netdata\n" + msg_ok "Installed Netdata" msg_ok "Completed Successfully!\n" echo -e "\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\n" } uninstall() { + header_info read -r -p "Verbose mode? " prompt if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then STD="" @@ -79,8 +81,8 @@ uninstall() { STD="silent" fi header_info - - msg_info "Uninstalling Netdata" + + msg_info "Uninstalling Netdata" systemctl stop netdata rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list @@ -88,7 +90,7 @@ uninstall() { systemctl daemon-reload $STD apt autoremove -y $STD userdel netdata - msg_ok "Uninstalled Netdata\n" + msg_ok "Uninstalled Netdata" msg_ok "Completed Successfully!\n" } From 6f0788f220436e67ec334874d267f09d5d8ddc8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Dec 2023 19:51:33 -0500 Subject: [PATCH 5677/6505] Update add-tailscale-lxc.sh tweak --- misc/add-tailscale-lxc.sh | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 301c4a7e..70d77945 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -6,6 +6,7 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE function header_info { +clear cat <<"EOF" ______ _ __ __ /_ __/___ _(_) /_____________ _/ /__ @@ -15,8 +16,8 @@ cat <<"EOF" EOF } -clear header_info +set-e while true; do read -p "This will add Tailscale to an existing LXC Container ONLY. Proceed(y/n)?" yn case $yn in @@ -25,23 +26,7 @@ while true; do *) echo "Please answer yes or no." ;; esac done - -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail -shopt -s expand_aliases -alias die='EXIT=$? LINE=$LINENO error_exit' -trap die ERR - -function error_exit() { - trap - ERR - local reason="Unknown failure occured." - local msg="${1:-$reason}" - local flag="\e[1;31m‼ ERROR\e[0m $EXIT@$LINE" - echo -e "$flag $msg" 1>&2 - exit $EXIT -} +header_info function msg() { local TEXT="$1" echo -e "$TEXT" From 3964789ca383023a3eb11a2bf86527942cef6bd9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Dec 2023 04:54:55 -0500 Subject: [PATCH 5678/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 5656561d..01805961 100644 --- a/misc/build.func +++ b/misc/build.func @@ -66,7 +66,7 @@ check_root() { # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7, refrain from creating Debian 12 LXCs due to differences in locale parameters. \n Default distribution for $APP LXC is ${var_os} ${var_version}" 10 58 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7 (Debian 11), refrain from creating Debian 12 LXCs. \nDefault distribution for $APP LXC is ${var_os} ${var_version}" 10 60 fi if ! pveversion | grep -Eq "pve-manager/(7\.[0-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" From 6ba8c5e06cf8a94305d4982581c26682a5cf7815 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Dec 2023 06:44:38 -0500 Subject: [PATCH 5679/6505] Update add-tailscale-lxc.sh tweak --- misc/add-tailscale-lxc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 70d77945..e0f666af 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -17,7 +17,7 @@ cat <<"EOF" EOF } header_info -set-e +set -e while true; do read -p "This will add Tailscale to an existing LXC Container ONLY. Proceed(y/n)?" yn case $yn in From 325288f099ec251b9c5c3c59337d59a99fdb70dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Dec 2023 09:24:52 -0500 Subject: [PATCH 5680/6505] Update add-tailscale-lxc.sh tweak --- misc/add-tailscale-lxc.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index e0f666af..68062908 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -8,7 +8,7 @@ function header_info { clear cat <<"EOF" - ______ _ __ __ + ______ _ __ __ /_ __/___ _(_) /_____________ _/ /__ / / / __ `/ / / ___/ ___/ __ `/ / _ \ / / / /_/ / / (__ ) /__/ /_/ / / __/ @@ -27,6 +27,7 @@ while true; do esac done header_info +echo "Loading..." function msg() { local TEXT="$1" echo -e "$TEXT" @@ -56,7 +57,7 @@ cat <>$CTID_CONFIG_PATH lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF - +header_info msg "Installing Tailscale..." lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" &>/dev/null || exit msg "Installed Tailscale" From 36fffde5022549fce80410caa09ef92c420aa8d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 23 Dec 2023 18:42:34 -0500 Subject: [PATCH 5681/6505] Update runtipi.sh add update path --- ct/runtipi.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/runtipi.sh b/ct/runtipi.sh index e4eeaba4..5ff66901 100644 --- a/ct/runtipi.sh +++ b/ct/runtipi.sh @@ -53,7 +53,7 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/runtipi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +cd /opt/runtipi && ./runtipi-cli update latest exit } From 5bf822849e648c7c577f695c8c300725bc1cfd76 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Dec 2023 11:19:05 -0500 Subject: [PATCH 5682/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 5443d59e..0366b11c 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -67,7 +67,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1 | grep -v '^N:'" ;; esac } From b337babee90b982d2dac14810fb8e8140cc21219 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Dec 2023 15:52:59 -0500 Subject: [PATCH 5683/6505] Update alpine-nextcloud.sh Increase RAM --- ct/alpine-nextcloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 92e2d98c..c8e73e8f 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="Alpine-Nextcloud" var_disk="2" var_cpu="2" -var_ram="512" +var_ram="1024" var_os="alpine" var_version="3.18" variables From 1de4df71621bfe6724981b36f6010bf2734d7d3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Dec 2023 18:30:12 -0500 Subject: [PATCH 5684/6505] Update uptimekuma-install.sh node 20.x --- install/uptimekuma-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh index 47f9ca24..f2a9fef4 100644 --- a/install/uptimekuma-install.sh +++ b/install/uptimekuma-install.sh @@ -25,7 +25,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From bbc36a9cbabe1016dc7c319ca990c3100b39a6e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Dec 2023 18:54:57 -0500 Subject: [PATCH 5685/6505] Update zigbee2mqtt-install.sh node 20.x --- install/zigbee2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index dc52ffa0..c6c167f4 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -28,7 +28,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 2b02f7d49d48aeb725d8876b7a6faa8ace7d4053 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Dec 2023 19:03:35 -0500 Subject: [PATCH 5686/6505] update to node 20.x --- ct/cronicle.sh | 2 +- install/changedetection-install.sh | 2 +- install/homepage-install.sh | 2 +- install/jellyseerr-install.sh | 2 +- install/n8n-install.sh | 2 +- install/overseerr-install.sh | 2 +- install/scrypted-install.sh | 2 +- install/shinobi-install.sh | 2 +- install/wikijs-install.sh | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 08d6a961..01c863f4 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -80,7 +80,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 91f6e681..ca9990b9 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -56,7 +56,7 @@ msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 457eb796..f26b896b 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -27,7 +27,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 45e29472..4cb55f7d 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -25,7 +25,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 6a250703..9c809a7e 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -24,7 +24,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/overseerr-install.sh b/install/overseerr-install.sh index 86a4defa..9aa1e207 100644 --- a/install/overseerr-install.sh +++ b/install/overseerr-install.sh @@ -25,7 +25,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 081772fe..620d9e5a 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -68,7 +68,7 @@ msg_ok "Installed GStreamer" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index 52d470b4..375b7f55 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -24,7 +24,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index cc2697c4..d8d0f1ac 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -25,7 +25,7 @@ msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 8c780535a126d0a07730c5d135d00c6e0da01ba7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Dec 2023 20:04:50 -0500 Subject: [PATCH 5687/6505] Update alpine-install.func change repositories to `latest-stable` --- misc/alpine-install.func | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 959d5443..39e76d8f 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -72,10 +72,9 @@ setting_up_container() { echo -e " 🖧 Check Network Settings" exit 1 fi - cat <>/etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/edge/main -https://dl-cdn.alpinelinux.org/alpine/edge/community -https://dl-cdn.alpinelinux.org/alpine/edge/testing + cat </etc/apk/repositories +https://dl-cdn.alpinelinux.org/alpine/latest-stable/main +https://dl-cdn.alpinelinux.org/alpine/latest-stable/community EOF msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" From a9b44432c4ff5810582de9bc11c03e7c8e346d83 Mon Sep 17 00:00:00 2001 From: Jayden <5250189+lukyjay@users.noreply.github.com> Date: Fri, 29 Dec 2023 00:42:10 +0800 Subject: [PATCH 5688/6505] Update changedetection-install.sh V2 doesn't appear to work, so clone v1 instead. --- install/changedetection-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index ca9990b9..217523de 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -72,7 +72,7 @@ msg_ok "Installed Change Detection" msg_info "Installing Browserless & Playwright" mkdir /opt/browserless $STD python3 -m pip install playwright -$STD git clone https://github.com/browserless/chrome /opt/browserless +$STD git clone -b v1 https://github.com/browserless/chrome /opt/browserless $STD npm install --prefix /opt/browserless $STD npm run build --prefix /opt/browserless $STD npm prune production --prefix /opt/browserless From 6f3b33550ec289fd07ef4b54686a94e459fb6e07 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Dec 2023 09:46:07 -0500 Subject: [PATCH 5689/6505] Update build.func passwords cannot start with a hyphen --- misc/build.func | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/misc/build.func b/misc/build.func index 01805961..12a61b14 100644 --- a/misc/build.func +++ b/misc/build.func @@ -200,17 +200,22 @@ advanced_settings() { fi done - if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW="" + while true; do + if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z "$PW1" ]; then + PW1="Automatic Login" + PW="" + elif [[ $PW1 == -* ]]; then + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Invalid Password" "Passwords cannot start with a hyphen. Please try again." 8 59 + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + break + fi else - PW="-password $PW1" + exit-script fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - exit-script - fi + done if CT_ID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then if [ -z "$CT_ID" ]; then From 475edf432d0203717e9bbecbeceafd2885d95ce6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Dec 2023 16:27:58 -0500 Subject: [PATCH 5690/6505] Update build.func revert --- misc/build.func | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/misc/build.func b/misc/build.func index 12a61b14..01805961 100644 --- a/misc/build.func +++ b/misc/build.func @@ -200,22 +200,17 @@ advanced_settings() { fi done - while true; do - if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z "$PW1" ]; then - PW1="Automatic Login" - PW="" - elif [[ $PW1 == -* ]]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Invalid Password" "Passwords cannot start with a hyphen. Please try again." 8 59 - else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - break - fi + if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z $PW1 ]; then + PW1="Automatic Login" + PW="" else - exit-script + PW="-password $PW1" fi - done + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + else + exit-script + fi if CT_ID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then if [ -z "$CT_ID" ]; then From 7beb2105ebeace2f298fb7d06afb28b4cf0c3f53 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Dec 2023 17:21:00 -0500 Subject: [PATCH 5691/6505] Update scrypted-install.sh revert back to node 18.x --- install/scrypted-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 620d9e5a..081772fe 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -68,7 +68,7 @@ msg_ok "Installed GStreamer" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" From 77cd36e094401fc6e2f0e5552fd5956a373fcf29 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Dec 2023 17:55:12 -0500 Subject: [PATCH 5692/6505] Update linkwarden.sh make default unprivileged --- ct/linkwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index 0a10b1d9..86130c31 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="0" + CT_TYPE="1" PW="" CT_ID=$NEXTID HN=$NSAPP From 109b0893c4f904195e93a89343b59448ab237bb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Dec 2023 07:11:02 -0500 Subject: [PATCH 5693/6505] Update scrypted-install.sh add npm (node 18.x stopped utilizing npm by default) --- install/scrypted-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 081772fe..a9963144 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -71,10 +71,11 @@ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dea echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" -msg_info "Installing Node.js" +msg_info "Installing Node.js/npm" $STD apt-get update $STD apt-get install -y nodejs -msg_ok "Installed Node.js" +$STD apt-get install -y npm +msg_ok "Installed Node.js/npm" msg_info "Updating Python3" $STD apt-get install -y \ From f442c1b328cfeb4376150a5e40b3fc5451cf867d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Dec 2023 07:59:11 -0500 Subject: [PATCH 5694/6505] Update update-lxcs.sh - postfix fix fixes https://github.com/tteck/Proxmox/issues/2270 --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 0366b11c..c03f4c1a 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -67,7 +67,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1 | grep -v '^N:'" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1" ;; esac } From 6f8302dc3be8433c76e62ba70aefb525a915d867 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 31 Dec 2023 17:44:52 -0500 Subject: [PATCH 5695/6505] Update debian-vm.sh update url --- vm/debian-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index e74afdc1..63f00be2 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -370,7 +370,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image" -URL=https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-nocloud-amd64-20231013-1532.qcow2 +URL=https://cloud.debian.org/images/cloud/bookworm/20231228-1609/debian-12-nocloud-amd64-20231228-1609.qcow2 sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From 497d629fdc22192f7563a6dbc90e1a56fe524531 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 11:08:24 -0500 Subject: [PATCH 5696/6505] Update zigbee2mqtt.sh (node 18.x has stopped utilizing npm by default) - check if the installed version of Node.js is 18.x and, if so, ensures that npm is also installed. - fixes https://github.com/tteck/Proxmox/issues/2281 --- ct/zigbee2mqtt.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index 9f679fe6..abb11a3c 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -57,6 +57,13 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + echo "Installed NPM..." + fi + fi cd /opt/zigbee2mqtt stop_zigbee2mqtt() { From 0dd9401ed7dd8967d44805b18a57f874479f0514 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 11:35:26 -0500 Subject: [PATCH 5697/6505] Create gotify-install.sh --- install/gotify-install.sh | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 install/gotify-install.sh diff --git a/install/gotify-install.sh b/install/gotify-install.sh new file mode 100644 index 00000000..1b0a3efb --- /dev/null +++ b/install/gotify-install.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Gotify" +RELEASE=$(curl -s https://api.github.com/repos/gotify/server/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +cd /opt/gotify +wget -q https://github.com/gotify/server/releases/download/v${RELEASE}/gotify-linux-amd64.zip +unzip gotify-linux-amd64.zip +rm -rf gotify-linux-amd64.zip +chmod +x gotify-linux-amd64 + +cat </etc/systemd/system/gotify.service +[Unit] +Description=Gotify +Requires=network.target +After=network.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/gotify +ExecStart=/opt/gotify/./gotify-linux-amd64 +Restart=always +RestartSec=3 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now gotify +msg_ok "Installed Gotify" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 96b0a6d172a6fe05ca2aef156a38e37057041732 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 11:37:43 -0500 Subject: [PATCH 5698/6505] Create gotify.sh --- ct/gotify.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/gotify.sh diff --git a/ct/gotify.sh b/ct/gotify.sh new file mode 100644 index 00000000..ccec0eb3 --- /dev/null +++ b/ct/gotify.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2023 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ __ _ ____ + / ____/___ / /_(_) __/_ __ + / / __/ __ \/ __/ / /_/ / / / +/ /_/ / /_/ / /_/ / __/ /_/ / +\____/\____/\__/_/_/ \__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Gotify" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/gotify ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP} ${CL} \n" From 0d288a2e66c185ae6c17e9ae556562676325e59e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 11:42:03 -0500 Subject: [PATCH 5699/6505] Update gotify-install.sh create directory --- install/gotify-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/gotify-install.sh b/install/gotify-install.sh index 1b0a3efb..89f7e82e 100644 --- a/install/gotify-install.sh +++ b/install/gotify-install.sh @@ -21,6 +21,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Gotify" RELEASE=$(curl -s https://api.github.com/repos/gotify/server/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +mkdir -p /opt/gotify cd /opt/gotify wget -q https://github.com/gotify/server/releases/download/v${RELEASE}/gotify-linux-amd64.zip unzip gotify-linux-amd64.zip From 4eab2fed423ea8de98e4398b04f0200b7665d2e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 11:49:31 -0500 Subject: [PATCH 5700/6505] Update gotify-install.sh tweak --- install/gotify-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/gotify-install.sh b/install/gotify-install.sh index 89f7e82e..dfdd110b 100644 --- a/install/gotify-install.sh +++ b/install/gotify-install.sh @@ -24,7 +24,7 @@ RELEASE=$(curl -s https://api.github.com/repos/gotify/server/releases/latest | g mkdir -p /opt/gotify cd /opt/gotify wget -q https://github.com/gotify/server/releases/download/v${RELEASE}/gotify-linux-amd64.zip -unzip gotify-linux-amd64.zip +$STD unzip gotify-linux-amd64.zip rm -rf gotify-linux-amd64.zip chmod +x gotify-linux-amd64 From 3cfb46c580c315d45b6feeede7ccb1457953fefa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 12:10:17 -0500 Subject: [PATCH 5701/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc07fadf..4f740213 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-01 + +### Changed + +- **Gotify LXC** + - NEW Script + ## 2023-12-19 ### Changed From 30c53d695874280f10efa2edb275b0a052ab10f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 12:13:05 -0500 Subject: [PATCH 5702/6505] update year to 2024 --- ct/adguard.sh | 2 +- ct/agentdvr.sh | 2 +- ct/alpine-docker.sh | 2 +- ct/alpine-grafana.sh | 2 +- ct/alpine-nextcloud.sh | 2 +- ct/alpine-vaultwarden.sh | 2 +- ct/alpine-zigbee2mqtt.sh | 2 +- ct/alpine.sh | 2 +- ct/audiobookshelf.sh | 2 +- ct/autobrr.sh | 2 +- ct/bazarr.sh | 2 +- ct/blocky.sh | 2 +- ct/casaos.sh | 2 +- ct/changedetection.sh | 2 +- ct/channels.sh | 2 +- ct/cloudflared.sh | 2 +- ct/create_lxc.sh | 2 +- ct/cronicle.sh | 2 +- ct/daemonsync.sh | 2 +- ct/dashy.sh | 2 +- ct/debian.sh | 2 +- ct/deconz.sh | 2 +- ct/deluge.sh | 2 +- ct/docker.sh | 2 +- ct/dockge.sh | 2 +- ct/emby.sh | 2 +- ct/emqx.sh | 2 +- ct/esphome.sh | 2 +- ct/fhem.sh | 2 +- ct/go2rtc.sh | 2 +- ct/gotify.sh | 2 +- ct/grafana.sh | 2 +- ct/grocy.sh | 2 +- ct/heimdalldashboard.sh | 2 +- ct/homarr.sh | 2 +- ct/homeassistant-core.sh | 2 +- ct/homeassistant.sh | 2 +- ct/homebridge.sh | 2 +- ct/homepage.sh | 2 +- ct/homer.sh | 2 +- ct/hyperion.sh | 2 +- ct/influxdb.sh | 2 +- ct/iobroker.sh | 2 +- ct/jackett.sh | 2 +- ct/jellyfin.sh | 2 +- ct/jellyseerr.sh | 2 +- ct/k0s.sh | 2 +- ct/kavita.sh | 2 +- ct/keycloak.sh | 2 +- ct/lidarr.sh | 2 +- ct/linkwarden.sh | 2 +- ct/magicmirror.sh | 2 +- ct/mariadb.sh | 2 +- ct/meshcentral.sh | 2 +- ct/motioneye.sh | 2 +- ct/mqtt.sh | 2 +- ct/n8n.sh | 2 +- ct/navidrome.sh | 2 +- ct/nextcloudpi.sh | 2 +- ct/nginxproxymanager.sh | 2 +- ct/nocodb.sh | 2 +- ct/node-red.sh | 2 +- ct/octoprint.sh | 2 +- ct/omada.sh | 2 +- ct/ombi.sh | 2 +- ct/omv.sh | 2 +- ct/openhab.sh | 2 +- ct/openobserve.sh | 2 +- ct/overseerr.sh | 2 +- ct/owncast.sh | 2 +- ct/paperless-ngx.sh | 2 +- ct/photoprism.sh | 2 +- ct/pialert.sh | 2 +- ct/pihole.sh | 2 +- ct/pingvin.sh | 2 +- ct/plex.sh | 2 +- ct/podman-homeassistant.sh | 2 +- ct/podman.sh | 2 +- ct/postgresql.sh | 2 +- ct/prometheus.sh | 2 +- ct/prowlarr.sh | 2 +- ct/qbittorrent.sh | 2 +- ct/radarr.sh | 2 +- ct/rdtclient.sh | 2 +- ct/readarr.sh | 2 +- ct/rockylinux.sh | 2 +- ct/rtsptoweb.sh | 2 +- ct/runtipi.sh | 2 +- ct/sabnzbd.sh | 2 +- ct/scrypted.sh | 2 +- ct/shinobi.sh | 2 +- ct/sonarr.sh | 2 +- ct/syncthing.sh | 2 +- ct/tasmoadmin.sh | 2 +- ct/tautulli.sh | 2 +- ct/tdarr.sh | 2 +- ct/technitiumdns.sh | 2 +- ct/transmission.sh | 2 +- ct/trilium.sh | 2 +- ct/ubuntu.sh | 2 +- ct/umbrel.sh | 2 +- ct/unifi.sh | 2 +- ct/unmanic.sh | 2 +- ct/uptimekuma.sh | 2 +- ct/vaultwarden.sh | 2 +- ct/whisparr.sh | 2 +- ct/whoogle.sh | 2 +- ct/wikijs.sh | 2 +- ct/wireguard.sh | 2 +- ct/yunohost.sh | 2 +- ct/zigbee2mqtt.sh | 2 +- ct/zoraxy.sh | 2 +- ct/zwave-js-ui.sh | 2 +- install/adguard-install.sh | 2 +- install/agentdvr-install.sh | 2 +- install/alpine-docker-install.sh | 2 +- install/alpine-grafana-install.sh | 2 +- install/alpine-install.sh | 2 +- install/alpine-nextcloud-install.sh | 2 +- install/alpine-vaultwarden-install.sh | 2 +- install/alpine-zigbee2mqtt-install.sh | 2 +- install/audiobookshelf-install.sh | 2 +- install/autobrr-install.sh | 2 +- install/bazarr-install.sh | 2 +- install/blocky-install.sh | 2 +- install/casaos-install.sh | 2 +- install/changedetection-install.sh | 2 +- install/channels-install.sh | 2 +- install/cloudflared-install.sh | 2 +- install/cronicle-install.sh | 2 +- install/daemonsync-install.sh | 2 +- install/dashy-install.sh | 2 +- install/debian-install.sh | 2 +- install/deconz-install.sh | 2 +- install/deluge-install.sh | 2 +- install/docker-install.sh | 2 +- install/dockge-install.sh | 2 +- install/emby-install.sh | 2 +- install/emqx-install.sh | 2 +- install/esphome-install.sh | 2 +- install/fhem-install.sh | 2 +- install/go2rtc-install.sh | 2 +- install/grafana-install.sh | 2 +- install/grocy-install.sh | 2 +- install/heimdalldashboard-install.sh | 2 +- install/homarr-install.sh | 2 +- install/homeassistant-core-install.sh | 2 +- install/homeassistant-install.sh | 2 +- install/homebridge-install.sh | 2 +- install/homepage-install.sh | 2 +- install/homer-install.sh | 2 +- install/hyperion-install.sh | 2 +- install/influxdb-install.sh | 2 +- install/iobroker-install.sh | 2 +- install/jackett-install.sh | 2 +- install/jellyfin-install.sh | 2 +- install/jellyseerr-install.sh | 2 +- install/k0s-install.sh | 2 +- install/kavita-install.sh | 2 +- install/keycloak-install.sh | 2 +- install/lidarr-install.sh | 2 +- install/linkwarden-install.sh | 2 +- install/magicmirror-install.sh | 2 +- install/mariadb-install.sh | 2 +- install/meshcentral-install.sh | 2 +- install/motioneye-install.sh | 2 +- install/mqtt-install.sh | 2 +- install/n8n-install.sh | 2 +- install/navidrome-install.sh | 2 +- install/nextcloudpi-install.sh | 2 +- install/nginxproxymanager-install.sh | 2 +- install/nocodb-install.sh | 2 +- install/node-red-install.sh | 2 +- install/octoprint-install.sh | 2 +- install/omada-install.sh | 2 +- install/ombi-install.sh | 2 +- install/omv-install.sh | 2 +- install/openhab-install.sh | 2 +- install/openobserve-install.sh | 2 +- install/overseerr-install.sh | 2 +- install/owncast-install.sh | 2 +- install/paperless-ngx-install.sh | 2 +- install/photoprism-install.sh | 2 +- install/pialert-install.sh | 2 +- install/pihole-install.sh | 2 +- install/pingvin-install.sh | 2 +- install/plex-install.sh | 2 +- install/podman-homeassistant-install.sh | 2 +- install/podman-install.sh | 2 +- install/postgresql-install.sh | 2 +- install/prometheus-install.sh | 2 +- install/prowlarr-install.sh | 2 +- install/qbittorrent-install.sh | 2 +- install/radarr-install.sh | 2 +- install/rdtclient-install.sh | 2 +- install/readarr-install.sh | 2 +- install/rtsptoweb-install.sh | 2 +- install/runtipi-install.sh | 2 +- install/sabnzbd-install.sh | 2 +- install/scrypted-install.sh | 2 +- install/shinobi-install.sh | 2 +- install/sonarr-install.sh | 2 +- install/syncthing-install.sh | 2 +- install/tasmoadmin-install.sh | 2 +- install/tautulli-install.sh | 2 +- install/tdarr-install.sh | 2 +- install/technitiumdns-install.sh | 2 +- install/transmission-install.sh | 2 +- install/trilium-install.sh | 2 +- install/ubuntu-install.sh | 2 +- install/umbrel-install.sh | 2 +- install/unifi-install.sh | 2 +- install/unmanic-install.sh | 2 +- install/uptimekuma-install.sh | 2 +- install/vaultwarden-install.sh | 2 +- install/whisparr-install.sh | 2 +- install/whoogle-install.sh | 2 +- install/wikijs-install.sh | 2 +- install/wireguard-install.sh | 2 +- install/yunohost-install.sh | 2 +- install/zigbee2mqtt-install.sh | 2 +- install/zoraxy-install.sh | 2 +- install/zwave-js-ui-install.sh | 2 +- misc/add-tailscale-lxc.sh | 2 +- misc/all-templates.sh | 2 +- misc/clean-lxcs.sh | 2 +- misc/clean.sh | 2 +- misc/code-server.sh | 2 +- misc/container-restore-from-backup.sh | 2 +- ...-assistant-container-copy-data-home-assistant-container.sh | 2 +- .../home-assistant-container-copy-data-home-assistant-core.sh | 2 +- ...ome-assistant-container-copy-data-podman-home-assistant.sh | 2 +- .../home-assistant-core-copy-data-home-assistant-container.sh | 2 +- .../home-assistant-core-copy-data-home-assistant-core.sh | 2 +- misc/copy-data/plex-copy-data-plex.sh | 2 +- ...odman-home-assistant-copy-data-home-assistant-container.sh | 2 +- misc/copy-data/z2m-copy-data-z2m.sh | 2 +- misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh | 2 +- misc/core-restore-from-backup.sh | 2 +- misc/cron-update-lxcs.sh | 2 +- misc/crowdsec.sh | 2 +- misc/edge-kernel.sh | 2 +- misc/filebrowser.sh | 2 +- misc/frigate-support.sh | 2 +- misc/host-backup.sh | 2 +- misc/hw-acceleration.sh | 2 +- misc/kernel-clean.sh | 2 +- misc/microcode.sh | 2 +- misc/monitor-all.sh | 2 +- misc/netdata.sh | 2 +- misc/olivetin.sh | 2 +- misc/pbs3-upgrade.sh | 2 +- misc/post-pbs-install.sh | 2 +- misc/post-pve-install.sh | 2 +- misc/pve8-upgrade.sh | 2 +- misc/pyenv.sh | 4 ++-- misc/scaling-governor.sh | 2 +- misc/update-lxcs-cron.sh | 2 +- misc/update-lxcs.sh | 2 +- misc/usb-passthrough.sh | 2 +- misc/webmin.sh | 2 +- turnkey/turnkey.sh | 2 +- vm/debian-vm.sh | 2 +- vm/haos-vm.sh | 2 +- vm/mikrotik-routeros.sh | 2 +- vm/nextcloud-vm.sh | 2 +- vm/openwrt.sh | 2 +- vm/owncloud-vm.sh | 2 +- vm/pimox-haos-vm.sh | 2 +- vm/ubuntu-vm.sh | 2 +- 270 files changed, 271 insertions(+), 271 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index 807800c3..5c15fca1 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/agentdvr.sh b/ct/agentdvr.sh index 25b17e77..caab7c04 100644 --- a/ct/agentdvr.sh +++ b/ct/agentdvr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 2a0c46eb..c79f03d1 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index f891e48d..e99bef4e 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index c8e73e8f..bee4bf5f 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 6add4976..359f90c0 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 1a0f92b4..d8941417 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/alpine.sh b/ct/alpine.sh index f134cac0..8da732a5 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 4df74961..78b04add 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 8365bc1a..4fe249e5 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/bazarr.sh b/ct/bazarr.sh index be9cc53a..687445ae 100755 --- a/ct/bazarr.sh +++ b/ct/bazarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/blocky.sh b/ct/blocky.sh index e90b66fb..1d6d9858 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/casaos.sh b/ct/casaos.sh index ba4a5aed..3b90d107 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/changedetection.sh b/ct/changedetection.sh index c625e67c..d12ead96 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/channels.sh b/ct/channels.sh index 5a192475..7f05f7ec 100644 --- a/ct/channels.sh +++ b/ct/channels.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/cloudflared.sh b/ct/cloudflared.sh index 59634450..19429bc3 100644 --- a/ct/cloudflared.sh +++ b/ct/cloudflared.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 1cd31ba0..34b78f09 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 01c863f4..278be46a 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index ba536268..ce3c885a 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/dashy.sh b/ct/dashy.sh index 64016d38..6155bd77 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/debian.sh b/ct/debian.sh index f684369d..edc59f1b 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/deconz.sh b/ct/deconz.sh index 2c59fa20..93bfae2d 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/deluge.sh b/ct/deluge.sh index 35d7eb16..75806917 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/docker.sh b/ct/docker.sh index 81a3a1dc..368d3518 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/dockge.sh b/ct/dockge.sh index fba046b6..39e7eac2 100644 --- a/ct/dockge.sh +++ b/ct/dockge.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/emby.sh b/ct/emby.sh index 1491a55c..954bc140 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/emqx.sh b/ct/emqx.sh index ccfbd747..20fd755e 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/esphome.sh b/ct/esphome.sh index a752b0d3..6262cd67 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/fhem.sh b/ct/fhem.sh index 7f9c8ecf..0b4812b7 100644 --- a/ct/fhem.sh +++ b/ct/fhem.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 5fd59314..7ad54ab7 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/gotify.sh b/ct/gotify.sh index ccec0eb3..99cbfbee 100644 --- a/ct/gotify.sh +++ b/ct/gotify.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/grafana.sh b/ct/grafana.sh index 9b61620b..f3747d05 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/grocy.sh b/ct/grocy.sh index 020971cb..43a123e0 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 8dd31293..c8106cbe 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/homarr.sh b/ct/homarr.sh index 3e247bb2..9f0353c2 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index f3929b14..ea3ea3f1 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 2056f0d6..5b6a858e 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 1c10dd00..28a12a7b 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/homepage.sh b/ct/homepage.sh index 988d0074..9195c0a6 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/homer.sh b/ct/homer.sh index 7d0c8a3a..59670953 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/hyperion.sh b/ct/hyperion.sh index fbd17687..309b8754 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/influxdb.sh b/ct/influxdb.sh index 8f3216d6..dded776f 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/iobroker.sh b/ct/iobroker.sh index f2577806..84edc759 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/jackett.sh b/ct/jackett.sh index c005c552..68d967a2 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index 5c8018fd..b56e271e 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index ef320216..68a93218 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/k0s.sh b/ct/k0s.sh index 0591912e..f39b8a77 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/kavita.sh b/ct/kavita.sh index 1b37feda..84afe3fb 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 5d9215b8..0a67f9d3 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/lidarr.sh b/ct/lidarr.sh index 9f2bbb5d..3b800506 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index 86130c31..95937e29 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index 4fde189e..3b21a8b2 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/mariadb.sh b/ct/mariadb.sh index dcf59e0d..6051169c 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index ff75e93d..16c9a837 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 244738c8..306f6281 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 7c8fa42e..86b5c18d 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/n8n.sh b/ct/n8n.sh index fbf697a8..08abdb78 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/navidrome.sh b/ct/navidrome.sh index 4062fd7f..28e10544 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index 1b63695c..7e75d135 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 5a5dd685..016c391c 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/nocodb.sh b/ct/nocodb.sh index b25c2175..6f2c76ea 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/node-red.sh b/ct/node-red.sh index 029bbae8..764d558b 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/octoprint.sh b/ct/octoprint.sh index e0c38fa4..af27fabe 100644 --- a/ct/octoprint.sh +++ b/ct/octoprint.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/omada.sh b/ct/omada.sh index 3d41116a..4d433261 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/ombi.sh b/ct/ombi.sh index 156d7507..d367b165 100644 --- a/ct/ombi.sh +++ b/ct/ombi.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/omv.sh b/ct/omv.sh index 063bc49b..8ca264c3 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/openhab.sh b/ct/openhab.sh index 168785b8..14e9bbf4 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/openobserve.sh b/ct/openobserve.sh index d3300770..86828d9f 100644 --- a/ct/openobserve.sh +++ b/ct/openobserve.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/overseerr.sh b/ct/overseerr.sh index 8f3ce0a1..392be917 100644 --- a/ct/overseerr.sh +++ b/ct/overseerr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/owncast.sh b/ct/owncast.sh index 4049f043..3bf376bf 100644 --- a/ct/owncast.sh +++ b/ct/owncast.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 98c0c556..9b0cfe3f 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 2eefb474..5e8d754b 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/pialert.sh b/ct/pialert.sh index 967b5043..6766107f 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/pihole.sh b/ct/pihole.sh index 9417013d..2d5e8f2f 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/pingvin.sh b/ct/pingvin.sh index cba10c06..c3943725 100644 --- a/ct/pingvin.sh +++ b/ct/pingvin.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/plex.sh b/ct/plex.sh index 77cf02a7..12ab74f4 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index a7a6e7a6..d9cb8573 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/podman.sh b/ct/podman.sh index d5cf7bf6..820b20c3 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/postgresql.sh b/ct/postgresql.sh index b3b9106e..47bf54d1 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/prometheus.sh b/ct/prometheus.sh index c51fb4d3..570eb1bf 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index 09c3bdd5..655a73cf 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 40cfa24d..9f0a07f6 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/radarr.sh b/ct/radarr.sh index 8a1d5972..2dc8668b 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh index e87c21f4..2df7fede 100755 --- a/ct/rdtclient.sh +++ b/ct/rdtclient.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/readarr.sh b/ct/readarr.sh index 1a1eb7c2..4a0dcd6a 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index 02a0a090..9e476b5c 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/rtsptoweb.sh b/ct/rtsptoweb.sh index e0208273..18642616 100644 --- a/ct/rtsptoweb.sh +++ b/ct/rtsptoweb.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/runtipi.sh b/ct/runtipi.sh index 5ff66901..a779a1df 100644 --- a/ct/runtipi.sh +++ b/ct/runtipi.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index be10fb72..427e53f7 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/scrypted.sh b/ct/scrypted.sh index e3c15644..8ffec8b5 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/shinobi.sh b/ct/shinobi.sh index c5ce6ae3..c5488d2a 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/sonarr.sh b/ct/sonarr.sh index dbfb22ea..89409d81 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/syncthing.sh b/ct/syncthing.sh index 0cfce841..9beff817 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/tasmoadmin.sh b/ct/tasmoadmin.sh index 7287ed1a..9aa75124 100644 --- a/ct/tasmoadmin.sh +++ b/ct/tasmoadmin.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/tautulli.sh b/ct/tautulli.sh index 5baf342d..3445d79e 100644 --- a/ct/tautulli.sh +++ b/ct/tautulli.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 5210d6c1..89f68c3e 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index fa139dc1..e091db9d 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/transmission.sh b/ct/transmission.sh index 25c07b54..435b4994 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/trilium.sh b/ct/trilium.sh index 7216f249..e0d2d75b 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 1804b96b..c61b90bd 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/umbrel.sh b/ct/umbrel.sh index d5992e0e..40ce605b 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/unifi.sh b/ct/unifi.sh index 188b5f56..f70327b2 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/unmanic.sh b/ct/unmanic.sh index 76d61497..05eb7298 100644 --- a/ct/unmanic.sh +++ b/ct/unmanic.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 108a004a..f4ad1b2b 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 3600f984..f204a484 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/whisparr.sh b/ct/whisparr.sh index df39c2f9..3679741d 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/whoogle.sh b/ct/whoogle.sh index d4cb472a..8334f650 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/wikijs.sh b/ct/wikijs.sh index 44027900..0dfe3b4a 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 828697d9..31a554d6 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/yunohost.sh b/ct/yunohost.sh index b024d239..387a7dad 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index abb11a3c..a4ccac5c 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh index 354a4434..9633a968 100644 --- a/ct/zoraxy.sh +++ b/ct/zoraxy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index de994a7b..e0a3039c 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/adguard-install.sh b/install/adguard-install.sh index 4b03cb71..263aa52b 100644 --- a/install/adguard-install.sh +++ b/install/adguard-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/agentdvr-install.sh b/install/agentdvr-install.sh index 7dcd0d0a..8eeaf33d 100644 --- a/install/agentdvr-install.sh +++ b/install/agentdvr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh index ac9a0f7e..5fa141b2 100644 --- a/install/alpine-docker-install.sh +++ b/install/alpine-docker-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/alpine-grafana-install.sh b/install/alpine-grafana-install.sh index 09dc91ef..7d7e95ad 100644 --- a/install/alpine-grafana-install.sh +++ b/install/alpine-grafana-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/alpine-install.sh b/install/alpine-install.sh index 72830ebb..b904c7a4 100644 --- a/install/alpine-install.sh +++ b/install/alpine-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index 64c233b3..9b320546 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index c66c36b3..94956b70 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/alpine-zigbee2mqtt-install.sh b/install/alpine-zigbee2mqtt-install.sh index 322e6e5f..2c805f23 100644 --- a/install/alpine-zigbee2mqtt-install.sh +++ b/install/alpine-zigbee2mqtt-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/audiobookshelf-install.sh b/install/audiobookshelf-install.sh index b0abeca6..1b26fd10 100644 --- a/install/audiobookshelf-install.sh +++ b/install/audiobookshelf-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/autobrr-install.sh b/install/autobrr-install.sh index 5a50883d..c8883ddd 100644 --- a/install/autobrr-install.sh +++ b/install/autobrr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh index a8f07da9..812ecefe 100755 --- a/install/bazarr-install.sh +++ b/install/bazarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/blocky-install.sh b/install/blocky-install.sh index f7e23b98..86523055 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/casaos-install.sh b/install/casaos-install.sh index 05473132..50027c6c 100644 --- a/install/casaos-install.sh +++ b/install/casaos-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 217523de..e670943b 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/channels-install.sh b/install/channels-install.sh index dbb4fb4f..5836812c 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/cloudflared-install.sh b/install/cloudflared-install.sh index 3d41a7b9..dc792cee 100644 --- a/install/cloudflared-install.sh +++ b/install/cloudflared-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/cronicle-install.sh b/install/cronicle-install.sh index a38bcf06..0763bdd8 100644 --- a/install/cronicle-install.sh +++ b/install/cronicle-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/daemonsync-install.sh b/install/daemonsync-install.sh index 8118f42b..483e27aa 100644 --- a/install/daemonsync-install.sh +++ b/install/daemonsync-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/dashy-install.sh b/install/dashy-install.sh index f4819a83..2962161d 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/debian-install.sh b/install/debian-install.sh index af84fbb8..18fd5940 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/deconz-install.sh b/install/deconz-install.sh index 5611b7cc..80d938b3 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/deluge-install.sh b/install/deluge-install.sh index fb6c50e1..eceb49ce 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/docker-install.sh b/install/docker-install.sh index 6425d48e..6744aac8 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/dockge-install.sh b/install/dockge-install.sh index 8509c2ad..d6985afd 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/emby-install.sh b/install/emby-install.sh index e0337e77..9027437a 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/emqx-install.sh b/install/emqx-install.sh index a1d69324..16475d53 100644 --- a/install/emqx-install.sh +++ b/install/emqx-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 5b5a8d1f..7c603425 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/fhem-install.sh b/install/fhem-install.sh index e3ce0f67..ea98bf4d 100644 --- a/install/fhem-install.sh +++ b/install/fhem-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/go2rtc-install.sh b/install/go2rtc-install.sh index a5092fd8..e50c6d76 100644 --- a/install/go2rtc-install.sh +++ b/install/go2rtc-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/grafana-install.sh b/install/grafana-install.sh index 6f5a3efc..81083b84 100644 --- a/install/grafana-install.sh +++ b/install/grafana-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 33f2e31d..526eeaff 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index 5fd52cff..afe39d6f 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 94a4d760..0a7db8fa 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index cbb10ed5..3149cb0e 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 958789e4..729fadeb 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh index 185a970e..b18510ed 100644 --- a/install/homebridge-install.sh +++ b/install/homebridge-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/homepage-install.sh b/install/homepage-install.sh index f26b896b..7e7dc650 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/homer-install.sh b/install/homer-install.sh index f4a8d3eb..82071cf4 100644 --- a/install/homer-install.sh +++ b/install/homer-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh index 17971c57..04622a1d 100644 --- a/install/hyperion-install.sh +++ b/install/hyperion-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh index b1683824..71e4e0f5 100644 --- a/install/influxdb-install.sh +++ b/install/influxdb-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/iobroker-install.sh b/install/iobroker-install.sh index ae553a46..8e5feb31 100644 --- a/install/iobroker-install.sh +++ b/install/iobroker-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/jackett-install.sh b/install/jackett-install.sh index e54858d5..bb928687 100644 --- a/install/jackett-install.sh +++ b/install/jackett-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index be373996..a8a61d20 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 4cb55f7d..7a0f1a2c 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/k0s-install.sh b/install/k0s-install.sh index 323bbebe..14ec64cb 100644 --- a/install/k0s-install.sh +++ b/install/k0s-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/kavita-install.sh b/install/kavita-install.sh index b3fe9267..17e208ae 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh index e5081b8e..ea7d0f91 100644 --- a/install/keycloak-install.sh +++ b/install/keycloak-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/lidarr-install.sh b/install/lidarr-install.sh index e03c7680..846b4de0 100644 --- a/install/lidarr-install.sh +++ b/install/lidarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh index 585d76c7..6ad52ab0 100644 --- a/install/linkwarden-install.sh +++ b/install/linkwarden-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/magicmirror-install.sh b/install/magicmirror-install.sh index e2f5a054..5bb2e3f5 100644 --- a/install/magicmirror-install.sh +++ b/install/magicmirror-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index 19787d93..310b6c26 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh index 1cd0b903..13ac00db 100644 --- a/install/meshcentral-install.sh +++ b/install/meshcentral-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index 227cffd0..e3908f4a 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 04ea968a..860c70bb 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 9c809a7e..25cbce47 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh index b5a003af..50f68d5b 100644 --- a/install/navidrome-install.sh +++ b/install/navidrome-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh index 912e5ad6..9a53a287 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 37656877..fcf6ebc7 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh index aaa3b55d..3040f638 100644 --- a/install/nocodb-install.sh +++ b/install/nocodb-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/node-red-install.sh b/install/node-red-install.sh index dc1f8759..6da4981f 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh index 3121387c..fd093734 100644 --- a/install/octoprint-install.sh +++ b/install/octoprint-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/omada-install.sh b/install/omada-install.sh index 3bc337ab..ca97a7f3 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/ombi-install.sh b/install/ombi-install.sh index 99a0a554..c5e631e7 100644 --- a/install/ombi-install.sh +++ b/install/ombi-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/omv-install.sh b/install/omv-install.sh index 872e9c28..9ea46931 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/openhab-install.sh b/install/openhab-install.sh index 532a6506..d21657e8 100644 --- a/install/openhab-install.sh +++ b/install/openhab-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh index 48a03e31..7a52415d 100644 --- a/install/openobserve-install.sh +++ b/install/openobserve-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/overseerr-install.sh b/install/overseerr-install.sh index 9aa1e207..8d752044 100644 --- a/install/overseerr-install.sh +++ b/install/overseerr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/owncast-install.sh b/install/owncast-install.sh index 8514ae8b..d03683e3 100644 --- a/install/owncast-install.sh +++ b/install/owncast-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index b52064bf..b572f2aa 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 75a03fee..2f80b6cc 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 5f4f7a09..195b16f4 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/pihole-install.sh b/install/pihole-install.sh index 881cb233..d6472459 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/pingvin-install.sh b/install/pingvin-install.sh index b8d31fb2..e271f9e1 100644 --- a/install/pingvin-install.sh +++ b/install/pingvin-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/plex-install.sh b/install/plex-install.sh index 4aec89ce..ca8dca63 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/podman-homeassistant-install.sh b/install/podman-homeassistant-install.sh index a0fb4f5e..c74e27cc 100644 --- a/install/podman-homeassistant-install.sh +++ b/install/podman-homeassistant-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/podman-install.sh b/install/podman-install.sh index 951da53b..78ae842f 100644 --- a/install/podman-install.sh +++ b/install/podman-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/postgresql-install.sh b/install/postgresql-install.sh index f85ca562..393d694a 100644 --- a/install/postgresql-install.sh +++ b/install/postgresql-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/prometheus-install.sh b/install/prometheus-install.sh index f2aad6fd..a04baa6f 100644 --- a/install/prometheus-install.sh +++ b/install/prometheus-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/prowlarr-install.sh b/install/prowlarr-install.sh index b999d9b5..7270f471 100644 --- a/install/prowlarr-install.sh +++ b/install/prowlarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/qbittorrent-install.sh b/install/qbittorrent-install.sh index 64c63001..3c5b6469 100644 --- a/install/qbittorrent-install.sh +++ b/install/qbittorrent-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/radarr-install.sh b/install/radarr-install.sh index f9e88aa5..4839b90a 100644 --- a/install/radarr-install.sh +++ b/install/radarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/rdtclient-install.sh b/install/rdtclient-install.sh index cc48a014..a077cb51 100644 --- a/install/rdtclient-install.sh +++ b/install/rdtclient-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/readarr-install.sh b/install/readarr-install.sh index 43897970..9ba9bc21 100644 --- a/install/readarr-install.sh +++ b/install/readarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/rtsptoweb-install.sh b/install/rtsptoweb-install.sh index 583137be..a5b669d5 100644 --- a/install/rtsptoweb-install.sh +++ b/install/rtsptoweb-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/runtipi-install.sh b/install/runtipi-install.sh index c9a2dce8..f39dc1f4 100644 --- a/install/runtipi-install.sh +++ b/install/runtipi-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 368633da..00bd1141 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index a9963144..1e547297 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index 375b7f55..4b9a51ab 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index 5a1780b0..f9114b20 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh index 43348999..3709513c 100644 --- a/install/syncthing-install.sh +++ b/install/syncthing-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/tasmoadmin-install.sh b/install/tasmoadmin-install.sh index 0b65b9ce..bc934e24 100644 --- a/install/tasmoadmin-install.sh +++ b/install/tasmoadmin-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index da91ab84..d31ea075 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index 702d3203..9c74faaf 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index 01f5fcd8..bc9fade9 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/transmission-install.sh b/install/transmission-install.sh index 969e6aea..10d90352 100644 --- a/install/transmission-install.sh +++ b/install/transmission-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/trilium-install.sh b/install/trilium-install.sh index da811245..cf6a37f0 100644 --- a/install/trilium-install.sh +++ b/install/trilium-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/ubuntu-install.sh b/install/ubuntu-install.sh index 64e6f242..9aa8705c 100644 --- a/install/ubuntu-install.sh +++ b/install/ubuntu-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/umbrel-install.sh b/install/umbrel-install.sh index db058225..7ad1d5af 100644 --- a/install/umbrel-install.sh +++ b/install/umbrel-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/unifi-install.sh b/install/unifi-install.sh index cadb6db4..56423f9d 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh index be5d336c..6e9a6300 100644 --- a/install/unmanic-install.sh +++ b/install/unmanic-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh index f2a9fef4..8c4e90ea 100644 --- a/install/uptimekuma-install.sh +++ b/install/uptimekuma-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/vaultwarden-install.sh b/install/vaultwarden-install.sh index 65061b80..64f8a460 100644 --- a/install/vaultwarden-install.sh +++ b/install/vaultwarden-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/whisparr-install.sh b/install/whisparr-install.sh index 422ae576..66cb5010 100644 --- a/install/whisparr-install.sh +++ b/install/whisparr-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index e513288d..b1bdedbb 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index d8d0f1ac..3a4507a3 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh index d74118d6..2b94a801 100644 --- a/install/wireguard-install.sh +++ b/install/wireguard-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/yunohost-install.sh b/install/yunohost-install.sh index 80fd97c4..606b0e21 100644 --- a/install/yunohost-install.sh +++ b/install/yunohost-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index c6c167f4..7855e7e5 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/zoraxy-install.sh b/install/zoraxy-install.sh index 5e23e065..0938abc2 100644 --- a/install/zoraxy-install.sh +++ b/install/zoraxy-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh index a9a05c3e..0b20538c 100644 --- a/install/zwave-js-ui-install.sh +++ b/install/zwave-js-ui-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index 68062908..e5bcfaec 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/all-templates.sh b/misc/all-templates.sh index d376cbf7..ab430e7c 100644 --- a/misc/all-templates.sh +++ b/misc/all-templates.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/clean-lxcs.sh b/misc/clean-lxcs.sh index 99af44a9..17f4fe74 100644 --- a/misc/clean-lxcs.sh +++ b/misc/clean-lxcs.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/clean.sh b/misc/clean.sh index 1e73f66d..4f692366 100644 --- a/misc/clean.sh +++ b/misc/clean.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/code-server.sh b/misc/code-server.sh index cc32de97..869fdad1 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/container-restore-from-backup.sh b/misc/container-restore-from-backup.sh index efb169d1..c491e18a 100644 --- a/misc/container-restore-from-backup.sh +++ b/misc/container-restore-from-backup.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh index 9da8f68a..7b5fe050 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh index 19a0975c..36af3259 100644 --- a/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh index 01ac7b82..2423f896 100644 --- a/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh +++ b/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh index e2ae0eec..387450fc 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh index 7603e8a1..c0cf2868 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/plex-copy-data-plex.sh b/misc/copy-data/plex-copy-data-plex.sh index 58ef49f0..dbf80f18 100644 --- a/misc/copy-data/plex-copy-data-plex.sh +++ b/misc/copy-data/plex-copy-data-plex.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh index 0d8a6542..ef65e9e6 100644 --- a/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh +++ b/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/z2m-copy-data-z2m.sh b/misc/copy-data/z2m-copy-data-z2m.sh index ee69da79..6e804de5 100644 --- a/misc/copy-data/z2m-copy-data-z2m.sh +++ b/misc/copy-data/z2m-copy-data-z2m.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh index c4375761..8d552982 100644 --- a/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh +++ b/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/core-restore-from-backup.sh b/misc/core-restore-from-backup.sh index 0f41adfc..885eda9c 100644 --- a/misc/core-restore-from-backup.sh +++ b/misc/core-restore-from-backup.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/cron-update-lxcs.sh b/misc/cron-update-lxcs.sh index 9fa9b549..97fb4e6c 100644 --- a/misc/cron-update-lxcs.sh +++ b/misc/cron-update-lxcs.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/crowdsec.sh b/misc/crowdsec.sh index 712e0b19..12a20f04 100644 --- a/misc/crowdsec.sh +++ b/misc/crowdsec.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh index 876f5cab..fa24386d 100644 --- a/misc/edge-kernel.sh +++ b/misc/edge-kernel.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index 6a7325b4..f15d0537 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/frigate-support.sh b/misc/frigate-support.sh index 88e43ea1..8dbdc563 100644 --- a/misc/frigate-support.sh +++ b/misc/frigate-support.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/host-backup.sh b/misc/host-backup.sh index f2c231d8..31b67bfa 100644 --- a/misc/host-backup.sh +++ b/misc/host-backup.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 8772aba8..24d2e2de 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/kernel-clean.sh b/misc/kernel-clean.sh index 7918ff81..ca31cc2f 100644 --- a/misc/kernel-clean.sh +++ b/misc/kernel-clean.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/microcode.sh b/misc/microcode.sh index 91296a22..083e9c89 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/monitor-all.sh b/misc/monitor-all.sh index e7702268..79bf0df0 100644 --- a/misc/monitor-all.sh +++ b/misc/monitor-all.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/netdata.sh b/misc/netdata.sh index 3c0cb81d..3596f049 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/olivetin.sh b/misc/olivetin.sh index c8015572..f3909ad9 100644 --- a/misc/olivetin.sh +++ b/misc/olivetin.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/pbs3-upgrade.sh b/misc/pbs3-upgrade.sh index 942154df..4565811e 100644 --- a/misc/pbs3-upgrade.sh +++ b/misc/pbs3-upgrade.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/post-pbs-install.sh b/misc/post-pbs-install.sh index 9f53edc3..550626be 100644 --- a/misc/post-pbs-install.sh +++ b/misc/post-pbs-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 97def72d..18b86ca2 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index e2e86cb5..f4a79136 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/pyenv.sh b/misc/pyenv.sh index 675a0344..0a548e78 100644 --- a/misc/pyenv.sh +++ b/misc/pyenv.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE @@ -110,7 +110,7 @@ pip3 install --pre esphome &>/dev/null cat </srv/esphome/start.sh #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/scaling-governor.sh b/misc/scaling-governor.sh index 556a3854..3523ab2c 100644 --- a/misc/scaling-governor.sh +++ b/misc/scaling-governor.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/update-lxcs-cron.sh b/misc/update-lxcs-cron.sh index 82184365..de5fded8 100644 --- a/misc/update-lxcs-cron.sh +++ b/misc/update-lxcs-cron.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index c03f4c1a..3c54ce3f 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/usb-passthrough.sh b/misc/usb-passthrough.sh index 851b3e06..25ceb3e6 100644 --- a/misc/usb-passthrough.sh +++ b/misc/usb-passthrough.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/misc/webmin.sh b/misc/webmin.sh index 881de91a..a7188b01 100644 --- a/misc/webmin.sh +++ b/misc/webmin.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/turnkey/turnkey.sh b/turnkey/turnkey.sh index 795dfbcb..202143cf 100644 --- a/turnkey/turnkey.sh +++ b/turnkey/turnkey.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index 63f00be2..e390073b 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 005e2ef9..325124c9 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 659f8385..5aba3c29 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/vm/nextcloud-vm.sh b/vm/nextcloud-vm.sh index 303910aa..5e3fce87 100644 --- a/vm/nextcloud-vm.sh +++ b/vm/nextcloud-vm.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 96bca2be..cc920c5e 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # Jon Spriggs (jontheniceguy) # License: MIT diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh index 40c5c0cb..72ac7ad4 100644 --- a/vm/owncloud-vm.sh +++ b/vm/owncloud-vm.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index 41e25281..1347fcf6 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index 4ff0af77..9e19c43d 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2023 tteck +# Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE From 9fda1994d711b00fa03956933f9bc1fc61acd153 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 12:39:57 -0500 Subject: [PATCH 5703/6505] Update iobroker-install.sh - add node.js v20.x - fixes https://github.com/tteck/Proxmox/issues/2282 --- install/iobroker-install.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/install/iobroker-install.sh b/install/iobroker-install.sh index 8e5feb31..09a59a58 100644 --- a/install/iobroker-install.sh +++ b/install/iobroker-install.sh @@ -17,8 +17,21 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg msg_ok "Installed Dependencies" +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + msg_info "Installing ioBroker (Patience)" $STD bash <(curl -fsSL https://iobroker.net/install.sh) msg_ok "Installed ioBroker" From b7a9d517e74beabc4aa2b74deb6b65a59c7c20e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Jan 2024 15:02:21 -0500 Subject: [PATCH 5704/6505] Update node-red.sh (node 18.x has stopped utilizing npm by default) - check if the installed version of Node.js is 18.x and, if so, ensures that npm is also installed. - fixes https://github.com/tteck/Proxmox/issues/2283 --- ct/node-red.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ct/node-red.sh b/ct/node-red.sh index 764d558b..962ab584 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -58,6 +58,13 @@ UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radio 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + msg_info "Installing NPM" + apt-get install -y npm >/dev/null 2>&1 + msg_ok "Installed NPM" + fi + fi msg_info "Stopping ${APP}" systemctl stop nodered msg_ok "Stopped ${APP}" From 5b02f6639163222e4a727eee4dffcd2624eb171a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Jan 2024 00:23:26 -0500 Subject: [PATCH 5705/6505] Update build.func warn Proxmox VE 7 (EOL 2024-07) --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 01805961..ed04d262 100644 --- a/misc/build.func +++ b/misc/build.func @@ -66,7 +66,7 @@ check_root() { # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7 (Debian 11), refrain from creating Debian 12 LXCs. \nDefault distribution for $APP LXC is ${var_os} ${var_version}" 10 60 + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7 (EOL 2024-07), refrain from creating Debian 12 LXCs. \nDefault distribution for $APP LXC is ${var_os} ${var_version}" 10 60 fi if ! pveversion | grep -Eq "pve-manager/(7\.[0-9]|8\.[0-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" From c979faa719d027c24ded606cc0531dcd32712e9b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Jan 2024 00:30:28 -0500 Subject: [PATCH 5706/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index dacb876c..eb514c7f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,5 +1,5 @@ name: Problems with a script. -description: Generate a report on an issue pertaining specifically to the script. For other inquires please share them in the Discussions section. Blank issues will be closed immediately. +description: Generate a report on an issue pertaining specifically to a script. For other inquires please share them in the Discussions section. Blank issues will be closed immediately. body: - type: markdown attributes: From d9f27eeff7edad244c3b926a0ce2ba9d58264941 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Jan 2024 13:01:35 -0500 Subject: [PATCH 5707/6505] Update node-red.sh - new packages for Node-RED themes - fixes https://github.com/tteck/Proxmox/issues/2287 --- ct/node-red.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index 962ab584..065e5adf 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -81,19 +81,38 @@ exit fi if [ "$UPD" == "2" ]; then THEME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ + "aurora" "" OFF \ + "cobalt2" "" OFF \ "dark" "" OFF \ "dracula" "" OFF \ + "espresso-libre" "" OFF \ + "github-dark" "" OFF \ + "github-dark-default" "" OFF \ + "github-dark-dimmed" "" OFF \ "midnight-red" "" ON \ + "monoindustrial" "" OFF \ + "monokai" "" OFF \ + "monokai-dimmed" "" OFF \ + "noctis" "" OFF \ + "oceanic-next" "" OFF \ "oled" "" OFF \ + "one-dark-pro" "" OFF \ + "one-dark-pro-darker" "" OFF \ "solarized-dark" "" OFF \ "solarized-light" "" OFF \ + "tokyo-night" "" OFF \ + "tokyo-night-light" "" OFF \ + "tokyo-night-storm" "" OFF \ + "totallyinformation" "" OFF \ + "zenburn" "" OFF \ 3>&1 1>&2 2>&3) header_info msg_info "Installing ${THEME} Theme" cd /root/.node-red -sed -i 's|//theme: "",|theme: "",|g' /root/.node-red/settings.js -npm install @node-red-contrib-themes/${THEME} &>/dev/null +sed -i 's|// theme: ".*",|theme: "",|g' /root/.node-red/settings.js +npm install @node-red-contrib-themes/theme-collection &>/dev/null sed -i "{s/theme: ".*"/theme: '${THEME}',/g}" /root/.node-red/settings.js +systemctl restart nodered msg_ok "Installed ${THEME} Theme" msg_info "Restarting ${APP}" From 91ab250a3de313548f45c229729a957a318e7da8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Jan 2024 13:03:15 -0500 Subject: [PATCH 5708/6505] Update node-red.sh tweak --- ct/node-red.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ct/node-red.sh b/ct/node-red.sh index 065e5adf..bdb8615e 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -114,10 +114,6 @@ npm install @node-red-contrib-themes/theme-collection &>/dev/null sed -i "{s/theme: ".*"/theme: '${THEME}',/g}" /root/.node-red/settings.js systemctl restart nodered msg_ok "Installed ${THEME} Theme" - -msg_info "Restarting ${APP}" -systemctl restart nodered -msg_ok "Restarted ${APP}" exit fi } From dc556414f04fe1fae1f866eac0ef7dabe98d6b37 Mon Sep 17 00:00:00 2001 From: Ryan Winter Date: Tue, 2 Jan 2024 14:53:43 -0800 Subject: [PATCH 5709/6505] Update homeassistant.sh change Portainer port --- ct/homeassistant.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 5b6a858e..66dcafe2 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -136,4 +136,4 @@ msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL} Portainer should be reachable by going to the following URL. - ${BL}http://${IP}:9000${CL}\n" + ${BL}https://${IP}:9443${CL}\n" From 6e51ac0e69b7b4af72fa2c1b85ea70ebc4dfeb65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 01:12:19 -0500 Subject: [PATCH 5710/6505] Update uptimekuma.sh (node 18.x has stopped utilizing npm by default) - check if the installed version of Node.js is 18.x and, if so, ensures that npm is also installed. --- ct/uptimekuma.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index f4ad1b2b..4961ee5d 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -54,6 +54,13 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/uptime-kuma ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + echo "Installed NPM..." + fi + fi LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Stopping ${APP}" sudo systemctl stop uptime-kuma &>/dev/null From ba6eea5346bd185b615c963f388412c23041b68c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 01:25:05 -0500 Subject: [PATCH 5711/6505] Update cronicle.sh check for npm --- ct/cronicle.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 278be46a..fd7ea840 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -59,12 +59,26 @@ UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radio if [ "$UPD" == "1" ]; then header_info if [[ ! -d /opt/cronicle ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + echo "Installed NPM..." + fi + fi msg_info "Updating ${APP}" /opt/cronicle/bin/control.sh upgrade &>/dev/null msg_ok "Updated ${APP}" exit fi if [ "$UPD" == "2" ]; then + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + echo "Installed NPM..." + fi + fi LATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '"tag_name":' | cut -d'"' -f4) IP=$(hostname -I | awk '{print $1}') msg_info "Installing Dependencies" From 913338813ee5e81b2674a7114015a17920b70181 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 01:30:09 -0500 Subject: [PATCH 5712/6505] Update magicmirror.sh check for npm --- ct/magicmirror.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index 3b21a8b2..5a547619 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -54,6 +54,13 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/magicmirror ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + echo "Installed NPM..." + fi + fi msg_info "Updating ${APP} LXC" cd /opt/magicmirror git pull &>/dev/null From ec7772f37580c27f6cab54d32ae6cac883fc15ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 01:31:06 -0500 Subject: [PATCH 5713/6505] Update n8n.sh check for npm --- ct/n8n.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ct/n8n.sh b/ct/n8n.sh index 08abdb78..39be816e 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -54,6 +54,13 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/systemd/system/n8n.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + echo "Installed NPM..." + fi + fi msg_info "Updating ${APP} LXC" npm update -g n8n &>/dev/null msg_ok "Updated Successfully" From a82f235e3c52e8ec1291974b8d4d246fbb5a1b37 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 01:42:48 -0500 Subject: [PATCH 5714/6505] Update homepage.sh check for npm --- ct/homepage.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ct/homepage.sh b/ct/homepage.sh index 9195c0a6..25bc2c0b 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -53,6 +53,13 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/homepage ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + echo "Installed NPM..." + fi + fi RELEASE=$(curl -s https://api.github.com/repos/gethomepage/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') msg_info "Updating Homepage to v${RELEASE} (Patience)" systemctl stop homepage From 5ecdf143016f853542f5678cecddf61430de209a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 10:02:41 -0500 Subject: [PATCH 5715/6505] Update sonarr-install.sh add sqlite3 --- install/sonarr-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index f9114b20..f0b76304 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -19,6 +19,7 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y gnupg $STD apt-get install -y ca-certificates +$STD apt-get install -y sqlite3 msg_ok "Installed Dependencies" read -r -p "Would you like to install v4 (experimental)? " prompt From f2c8792461f3ac1dc6c099228d5dd2b22c783a72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 12:08:10 -0500 Subject: [PATCH 5716/6505] Update sonarr-install.sh - major code refactoring - breaking changes https://github.com/tteck/Proxmox/discussions/1738#discussioncomment-8005107 --- install/sonarr-install.sh | 52 ++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index f0b76304..820b74f1 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -17,29 +17,41 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y gnupg -$STD apt-get install -y ca-certificates $STD apt-get install -y sqlite3 msg_ok "Installed Dependencies" -read -r -p "Would you like to install v4 (experimental)? " prompt -msg_info "Installing Sonarr" -wget -qO /etc/apt/trusted.gpg.d/sonarr-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2009837cbffd68f45bc180471f4f90de2a9b4bf8" -echo "deb https://apt.sonarr.tv/debian testing-main main" >/etc/apt/sources.list.d/sonarr.list -$STD apt-get update -DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" install -qqy sonarr &>/dev/null -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - systemctl stop sonarr.service - wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/develop/latest?version=4&os=linux' - tar -xzf SonarrV4.tar.gz - cp -r Sonarr/* /usr/lib/sonarr/bin - rm -rf Sonarr SonarrV4.tar.gz - sed -i 's|ExecStart=/usr/bin/mono --debug /usr/lib/sonarr/bin/Sonarr.exe -nobrowser -data=/var/lib/sonarr|ExecStart=/usr/lib/sonarr/bin/Sonarr -nobrowser -data=/var/lib/sonarr|' /lib/systemd/system/sonarr.service - sed -i 's/\(User=\|Group=\).*/\1root/' /lib/systemd/system/sonarr.service - systemctl daemon-reload - systemctl start sonarr.service -fi -msg_ok "Installed Sonarr" +msg_info "Installing Sonarr v4" +$STD groupadd media +$STD adduser --system --no-create-home --ingroup media sonarr +mkdir -p /var/lib/sonarr/ +chown -R sonarr:media /var/lib/sonarr/ +chmod 775 /var/lib/sonarr/ +wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=x64' +tar -xzf SonarrV4.tar.gz +mv Sonarr /opt +rm -rf SonarrV4.tar.gz + +msg_ok "Installed Sonarr v4" + +msg_info "Creating Service" +cat </etc/systemd/system/sonarr.service +[Unit] +Description=Sonarr Daemon +After=syslog.target network.target +[Service] +User=sonarr +Group=media +UMask=0002 +Type=simple +ExecStart=/opt/Sonarr/Sonarr -nobrowser -data=/var/lib/sonarr/ +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now sonarr.service +msg_ok "Created Service" motd_ssh customize From a3ef98e1f8cc45f6b42cdebadd0553d79fdd7eaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 12:10:09 -0500 Subject: [PATCH 5717/6505] Update sonarr.sh - major code refactoring - breaking changes https://github.com/tteck/Proxmox/discussions/1738#discussioncomment-8005107 --- ct/sonarr.sh | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/ct/sonarr.sh b/ct/sonarr.sh index 89409d81..22af05ef 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -8,12 +8,12 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ + _____ / ___/____ ____ ____ __________ \__ \/ __ \/ __ \/ __ `/ ___/ ___/ - ___/ / /_/ / / / / /_/ / / / / -/____/\____/_/ /_/\__,_/_/ /_/ - + ___/ / /_/ / / / / /_/ / / / / +/____/\____/_/ /_/\__,_/_/ /_/ + EOF } header_info @@ -52,23 +52,16 @@ function default_settings() { function update_script() { header_info -if [[ ! -f /etc/apt/sources.list.d/sonarr.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -read -r -p "Are you updating Sonarr v4? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Updating $APP v4" - systemctl stop sonarr.service - wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/develop/latest?version=4&os=linux' - tar -xzf SonarrV4.tar.gz - cp -r Sonarr/* /usr/lib/sonarr/bin - rm -rf Sonarr SonarrV4.tar.gz - systemctl start sonarr.service - msg_ok "Updated $APP v4" - exit -fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +if [[ ! -d /opt/Sonarr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP v4" +systemctl stop sonarr.service +wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=x64' +tar -xzf SonarrV4.tar.gz +rm -rf /opt/Sonarr +mv Sonarr /opt +rm -rf SonarrV4.tar.gz +systemctl start sonarr.service +msg_ok "Updated $APP v4" exit } From f9b9b560f1e20a7e4f15aec82f455c8a5a5ca83e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 12:16:57 -0500 Subject: [PATCH 5718/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f740213..800757f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-03 + +### Changed + +- **Sonarr LXC** + - Breaking Change + - Complete recode + - https://github.com/tteck/Proxmox/discussions/1738#discussioncomment-8005107 + ## 2024-01-01 ### Changed From 00f73c7370716629d111bc8a7148de6224dd5dcb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jan 2024 16:09:16 -0500 Subject: [PATCH 5719/6505] Update install.func tweak --- misc/install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index a15364c2..e3527fb4 100644 --- a/misc/install.func +++ b/misc/install.func @@ -113,7 +113,7 @@ network_check() { update_os() { msg_info "Updating Container OS" $STD apt-get update - $STD apt-get -y upgrade + $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade msg_ok "Updated Container OS" } From 7cbc112a4622b7ff55cc1f47e1853c857849aa2a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Jan 2024 12:08:47 -0500 Subject: [PATCH 5720/6505] Create commafeed-install.sh --- install/commafeed-install.sh | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 install/commafeed-install.sh diff --git a/install/commafeed-install.sh b/install/commafeed-install.sh new file mode 100644 index 00000000..3df462f0 --- /dev/null +++ b/install/commafeed-install.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Azul Zulu" +wget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" +wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb +$STD dpkg -i zulu-repo_1.0.0-3_all.deb +$STD apt-get update +$STD apt-get -y install zulu17-jdk +msg_ok "Installed Azul Zulu" + +msg_info "Installing CommaFeed" +mkdir /opt/commafeed && cd /opt/commafeed +wget -q https://github.com/Athou/commafeed/releases/latest/download/commafeed.jar +wget -q https://github.com/Athou/commafeed/releases/latest/download/config.yml.example -O config.yml +msg_ok "Installed CommaFeed" + +msg_info "Creating Service" +cat </etc/systemd/system/commafeed.service +[Unit] +Description=CommaFeed Service +After=network.target + +[Service] +ExecStart=/usr/bin/java -Djava.net.preferIPv4Stack=true -jar /opt/commafeed/commafeed.jar server /opt/commafeed/config.yml +WorkingDirectory=/opt/commafeed/ +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now commafeed.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf zulu-repo_1.0.0-3_all.deb +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 13457886fe4899a0883aff33255d36ffec075586 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Jan 2024 12:09:10 -0500 Subject: [PATCH 5721/6505] Create commafeed.sh --- ct/commafeed.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/commafeed.sh diff --git a/ct/commafeed.sh b/ct/commafeed.sh new file mode 100644 index 00000000..d4eba134 --- /dev/null +++ b/ct/commafeed.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ ______ __ + / ____/___ ____ ___ ____ ___ ____ _/ ____/__ ___ ____/ / + / / / __ \/ __ `__ \/ __ `__ \/ __ `/ /_ / _ \/ _ \/ __ / +/ /___/ /_/ / / / / / / / / / / / /_/ / __/ / __/ __/ /_/ / +\____/\____/_/ /_/ /_/_/ /_/ /_/\__,_/_/ \___/\___/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="CommaFeed" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/commafeed ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8082${CL} \n" From fe960d1e7d6d62654a3dea5e31181327f3ba8a3a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Jan 2024 12:29:45 -0500 Subject: [PATCH 5722/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 800757f4..51161db2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-04 + +### Changed + +- **Commafeed LXC** + - NEW Script + ## 2024-01-03 ### Changed From 781d9a0b2aa98c6d49253e56d269e81fa4b15983 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Jan 2024 12:30:00 -0500 Subject: [PATCH 5723/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51161db2..7d4f768d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ### Changed -- **Commafeed LXC** +- **CommaFeed LXC** - NEW Script ## 2024-01-03 From 72b9e514bcaef24cde7e9336e3b249effc8bb4e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jan 2024 12:56:21 -0500 Subject: [PATCH 5724/6505] Update CODE-AUDIT.md --- CODE-AUDIT.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md index f1c40e9b..c8d4be26 100644 --- a/CODE-AUDIT.md +++ b/CODE-AUDIT.md @@ -1,11 +1,14 @@ -

    Exploring the Scripts and Steps Involved in an Application LXC Installation

    +
    + +
    +

    Exploring the Scripts and Steps Involved in an Application LXC Installation

    -In the case of the AdGuard Home LXC, the process involves running multiple scripts for each application or service.
    -Initially, the [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) script is executed to collect system parameters.
    -Next, the [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func) script adds user settings and integrates all the collected information.
    -Then, the [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh) script constructs the LXC container.
    -Following that, the [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh) script is executed, which utilizes the functions exported from the [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func) script for installing the required applications.
    -Finally, the process returns to the [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) script to display the completion message.
    +1) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh): This script collects system parameters. +2) [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func): Adds user settings and integrates collected information. +3) [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh): Constructs the LXC container. +4) [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func) to install required applications. +5) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) (again): To display the completion message. -Thoroughly evaluating the [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh) script is crucial to gain a better understanding of the application installation process.
    -Every application installation utilizes the same set of reusable scripts: [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func), [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh), and [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func). These scripts are not specific to any particular application.
    +The installation process uses reusable scripts: [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func), [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh), and [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func), which are not specific to any particular application. + +To gain a better understanding, focus on reviewing [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh). This script contains the commands and configurations for installing and configuring AdGuard Home within the LXC container. From 9a897be0e7da93c3a0a4d9d9c2740ab64a4dec30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jan 2024 13:11:59 -0500 Subject: [PATCH 5725/6505] Update CODE-AUDIT.md tweak --- CODE-AUDIT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md index c8d4be26..83992f98 100644 --- a/CODE-AUDIT.md +++ b/CODE-AUDIT.md @@ -6,7 +6,7 @@ 1) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh): This script collects system parameters. 2) [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func): Adds user settings and integrates collected information. 3) [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh): Constructs the LXC container. -4) [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func) to install required applications. +4) [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func), and installs the application. 5) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) (again): To display the completion message. The installation process uses reusable scripts: [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func), [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh), and [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func), which are not specific to any particular application. From 9191b26eea3573de189c68d9afcfdb01dcee7e64 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jan 2024 13:21:19 -0500 Subject: [PATCH 5726/6505] Update CODE-AUDIT.md tweak --- CODE-AUDIT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md index 83992f98..46db7c9c 100644 --- a/CODE-AUDIT.md +++ b/CODE-AUDIT.md @@ -3,7 +3,7 @@

    Exploring the Scripts and Steps Involved in an Application LXC Installation

    -1) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh): This script collects system parameters. +1) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh): This script collects system parameters. (Also holds the function to update the application.) 2) [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func): Adds user settings and integrates collected information. 3) [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh): Constructs the LXC container. 4) [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func), and installs the application. From fa31bf2f18d86b5ebee81faf5131e26b3554688e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jan 2024 13:29:27 -0500 Subject: [PATCH 5727/6505] Update CONTRIBUTING.md tweak --- .github/CONTRIBUTING.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 3b61df05..ae0755be 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,9 +1,12 @@ -# Contributing to Proxmox VE Helper Scripts +
    + +
    +

    Contributing to Proxmox VE Helper Scripts

    Everybody is invited and welcome to contribute to Proxmox VE Helper Scripts. - Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. By adhering to the established patterns and conventions throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/tteck/Proxmox/tree/main). -- It is important to stress that complaining about the decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. +- It is important to stress that complaining about a decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. - The repository will only accept Alpine applications that make use of the Alpine Package Keeper. From ce875098bc98151d0a5acdebd4e77b30bd7f0ce6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jan 2024 13:33:26 -0500 Subject: [PATCH 5728/6505] Update USER_SUBMITTED_GUIDES.md tweak --- USER_SUBMITTED_GUIDES.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 11981378..22d9c600 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -1,4 +1,7 @@ -

    User Submitted Guides

    +
    + +
    +

    User Submitted Guides

    In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. From 5b18995b97043a7286f606d2df688195cdf57b9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jan 2024 13:39:50 -0500 Subject: [PATCH 5729/6505] Update CHANGELOG.md tweak --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d4f768d..7ede93e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ +
    + +
    +

    Change Log

    -# Change Log -**All notable changes to this project will be documented in this file.**
    +

    All notable changes to this project will be documented in this file.

    - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. From 8e10c14bce6f7c8f32d85fb87e9480de5160fe41 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jan 2024 17:11:48 -0500 Subject: [PATCH 5730/6505] Update code-server.sh fixes https://github.com/tteck/Proxmox/issues/2297 --- misc/code-server.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/misc/code-server.sh b/misc/code-server.sh index 869fdad1..6ae2d024 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -67,8 +67,7 @@ function msg_ok() { } msg_info "Installing Dependencies" -apt-get install -y curl &>/dev/null -apt-get install -y sudo &>/dev/null +apt-get update &>/dev/null apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" From 867a10f03f1049c182fcd008e8e09e554f82e2f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 Jan 2024 17:15:45 -0500 Subject: [PATCH 5731/6505] Add new element - add spinner --- ct/create_lxc.sh | 31 +++++++++++++++++++++++++------ misc/build.func | 24 ++++++++++++++++++++++-- misc/install.func | 32 ++++++++++++++++++++++++++------ 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 34b78f09..ee29e706 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -25,6 +25,8 @@ trap 'error_handler $LINENO "$BASH_COMMAND"' ERR # This function handles errors function error_handler() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local exit_code="$?" local line_number="$1" local command="$2" @@ -32,20 +34,37 @@ function error_handler() { echo -e "\n$error_message\n" } -# This function prints an informational message -function msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." +# This function displays a spinner. +function spinner() { + printf "\e[?25l" + spinner="/-\\|/-\\|" + spin_i=0 + while true; do + printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" + sleep 0.1 + done } -# This function prints a success message +# This function displays an informational message with a yellow color. +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg} " + spinner & + SPINNER_PID=$! +} + +# This function displays a success message with a green color. function msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -# This function prints an error message +# This function displays a error message with a red color. function msg_error() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } diff --git a/misc/build.func b/misc/build.func index ed04d262..37dec4f0 100644 --- a/misc/build.func +++ b/misc/build.func @@ -27,6 +27,8 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local exit_code="$?" local line_number="$1" local command="$2" @@ -34,20 +36,38 @@ error_handler() { echo -e "\n$error_message\n" } +# This function displays a spinner. +spinner() { + printf "\e[?25l" + spinner="/-\\|/-\\|" + spin_i=0 + while true; do + printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" + sleep 0.1 + done +} + # This function displays an informational message with a yellow color. msg_info() { local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + echo -ne " ${HOLD} ${YW}${msg} " + spinner & + SPINNER_PID=$! } + # This function displays a success message with a green color. msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -# This function displays an error message with a red color. +# This function displays a error message with a red color. msg_error() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } diff --git a/misc/install.func b/misc/install.func index e3527fb4..66da53d2 100644 --- a/misc/install.func +++ b/misc/install.func @@ -36,6 +36,8 @@ catch_errors() { # This function handles errors error_handler() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local exit_code="$?" local line_number="$1" local command="$2" @@ -46,20 +48,38 @@ error_handler() { fi } -# This function prints an informational message -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." +# This function displays a spinner. +spinner() { + printf "\e[?25l" + spinner="/-\\|/-\\|" + spin_i=0 + while true; do + printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" + sleep 0.1 + done } -# This function prints a success message +# This function displays an informational message with a yellow color. +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg} " + spinner & + SPINNER_PID=$! +} + + +# This function displays a success message with a green color. msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -# This function prints an error message +# This function displays a error message with a red color. msg_error() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } From 101c9eb122ca9ab4a74e6aa096f53bd17c1710e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 Jan 2024 17:27:00 -0500 Subject: [PATCH 5732/6505] Update haos-vm.sh - add spinner --- vm/haos-vm.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 325124c9..bf11bd43 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -40,7 +40,10 @@ THIN="discard=on,ssd=1," set -Eeuo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT + function error_handler() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local exit_code="$?" local line_number="$1" local command="$2" @@ -69,17 +72,33 @@ else header_info && echo -e "⚠ User exited script \n" && exit fi +function spinner() { + printf "\e[?25l" + spinner="/-\\|/-\\|" + spin_i=0 + while true; do + printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" + sleep 0.1 + done +} + function msg_info() { local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." + echo -ne " ${HOLD} ${YW}${msg} " + spinner & + SPINNER_PID=$! } function msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } @@ -146,7 +165,7 @@ function default_settings() { MAC="$GEN_MAC" VLAN="" MTU="" - START_VM="yes" + START_VM="yws" echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" From d76362808662b229ab5d9958ed9deb0f3be53274 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 Jan 2024 17:55:01 -0500 Subject: [PATCH 5733/6505] Update haos-vm.sh --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index bf11bd43..dfa476b5 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -165,7 +165,7 @@ function default_settings() { MAC="$GEN_MAC" VLAN="" MTU="" - START_VM="yws" + START_VM="yes" echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}" echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" From 9f03c98e8fe8c4d2aaacb353a6821bb1aea6fc26 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 01:45:12 -0500 Subject: [PATCH 5734/6505] Update alpine-install.func add spinner --- misc/alpine-install.func | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 39e76d8f..83b842f3 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -34,6 +34,8 @@ catch_errors() { } error_handler() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local exit_code="$?" local line_number="$1" local command="$2" @@ -41,17 +43,37 @@ error_handler() { echo -e "\n$error_message\n" } -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." +# This function displays a spinner. +spinner() { + printf "\e[?25l" + spinner="/-\\|/-\\|" + spin_i=0 + while true; do + printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" + sleep 0.1 + done } +# This function displays an informational message with a yellow color. +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg} " + spinner & + SPINNER_PID=$! +} + +# This function displays a success message with a green color. msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +# This function displays a error message with a red color. msg_error() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } From 767a4ac43394927fe4b414323daec1cb2f7358fb Mon Sep 17 00:00:00 2001 From: NiceDevil <17103076+nicedevil007@users.noreply.github.com> Date: Sun, 7 Jan 2024 10:35:24 +0100 Subject: [PATCH 5735/6505] Update paperless-ngx.sh (#2299) 2 lines not needed anymore scipy is version 1.11.4 and paperless is working fine with it --- ct/paperless-ngx.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 9b0cfe3f..b7a68ea8 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -81,8 +81,6 @@ function update_script() { cp -r /opt/paperless/paperless.conf paperless-ngx/ cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless - sed -i 's/scipy==1.8.1/scipy==1.10.1/g' requirements.txt - sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt pip install -r requirements.txt &>/dev/null cd /opt/paperless/src /usr/bin/python3 manage.py migrate &>/dev/null From 8b7820b03a34e08f936e0b9e10fa33ce09dee246 Mon Sep 17 00:00:00 2001 From: NiceDevil <17103076+nicedevil007@users.noreply.github.com> Date: Sun, 7 Jan 2024 10:42:41 +0100 Subject: [PATCH 5736/6505] Update paperless-ngx-install.sh (#2300) not needed anymore, as in the other commit :) --- install/paperless-ngx-install.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index b572f2aa..5701601a 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -81,9 +81,6 @@ $STD tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/ mv paperless-ngx paperless rm paperless-ngx-$Paperlessngx.tar.xz cd /opt/paperless -sed -i 's/scipy==1.8.1/scipy==1.10.1/g' requirements.txt -## python 3.10+ doesn't like the '-e', so we remove it from this the requirements file -sed -i -e 's|-e git+https://github.com/paperless-ngx/django-q.git|git+https://github.com/paperless-ngx/django-q.git|' /opt/paperless/requirements.txt $STD pip install --upgrade pip $STD pip install -r requirements.txt curl -s -o /opt/paperless/paperless.conf https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/paperless.conf.example From e27191e60787b238ec0ce5cd88eddc5ea1a91263 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 09:41:22 -0500 Subject: [PATCH 5737/6505] Update alpine-install.func revert add spinner --- misc/alpine-install.func | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 83b842f3..39e76d8f 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -34,8 +34,6 @@ catch_errors() { } error_handler() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - printf "\e[?25h" local exit_code="$?" local line_number="$1" local command="$2" @@ -43,37 +41,17 @@ error_handler() { echo -e "\n$error_message\n" } -# This function displays a spinner. -spinner() { - printf "\e[?25l" - spinner="/-\\|/-\\|" - spin_i=0 - while true; do - printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" - sleep 0.1 - done -} - -# This function displays an informational message with a yellow color. msg_info() { local msg="$1" - echo -ne " ${HOLD} ${YW}${msg} " - spinner & - SPINNER_PID=$! + echo -ne " ${HOLD} ${YW}${msg}..." } -# This function displays a success message with a green color. msg_ok() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -# This function displays a error message with a red color. msg_error() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } From c73a2909f747b92126ac42aa4c8c3968f6c37124 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 10:36:15 -0500 Subject: [PATCH 5738/6505] Update alpine-install.func add spinner, attempt 2 --- misc/alpine-install.func | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 39e76d8f..2d031bdc 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -34,6 +34,8 @@ catch_errors() { } error_handler() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\033[?25h" local exit_code="$?" local line_number="$1" local command="$2" @@ -41,17 +43,37 @@ error_handler() { echo -e "\n$error_message\n" } -msg_info() { - local msg="$1" - echo -ne " ${HOLD} ${YW}${msg}..." +# This function displays a spinner. +spinner() { + printf "\033[?25l" + spinner="/-\\|/-\\|" + spin_i=0 + while true; do + printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" + sleep 0.1 + done } +# This function displays an informational message with a yellow color. +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg} " + spinner & + SPINNER_PID=$! +} + +# This function displays a success message with a green color. msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\033[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } +# This function displays a error message with a red color. msg_error() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + printf "\033[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } From df25fe94461f752188714f5e5b7a9f32ec98ad06 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 10:43:29 -0500 Subject: [PATCH 5739/6505] Update alpine-install.func add spinner, attempt 3 --- misc/alpine-install.func | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 2d031bdc..e7b8cf08 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -35,7 +35,7 @@ catch_errors() { error_handler() { if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - printf "\033[?25h" + tput cnorm local exit_code="$?" local line_number="$1" local command="$2" @@ -45,7 +45,7 @@ error_handler() { # This function displays a spinner. spinner() { - printf "\033[?25l" + tput civis spinner="/-\\|/-\\|" spin_i=0 while true; do @@ -65,7 +65,7 @@ msg_info() { # This function displays a success message with a green color. msg_ok() { if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - printf "\033[?25h" + tput cnorm local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } @@ -73,7 +73,7 @@ msg_ok() { # This function displays a error message with a red color. msg_error() { if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - printf "\033[?25h" + tput cnorm local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } From 5f3bd5904eb186d315c17e0412b8eec4b881eaef Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 10:50:17 -0500 Subject: [PATCH 5740/6505] Update alpine-install.func no spinner allowed --- misc/alpine-install.func | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index e7b8cf08..39e76d8f 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -34,8 +34,6 @@ catch_errors() { } error_handler() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - tput cnorm local exit_code="$?" local line_number="$1" local command="$2" @@ -43,37 +41,17 @@ error_handler() { echo -e "\n$error_message\n" } -# This function displays a spinner. -spinner() { - tput civis - spinner="/-\\|/-\\|" - spin_i=0 - while true; do - printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" - sleep 0.1 - done -} - -# This function displays an informational message with a yellow color. msg_info() { local msg="$1" - echo -ne " ${HOLD} ${YW}${msg} " - spinner & - SPINNER_PID=$! + echo -ne " ${HOLD} ${YW}${msg}..." } -# This function displays a success message with a green color. msg_ok() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - tput cnorm local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -# This function displays a error message with a red color. msg_error() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi - tput cnorm local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } From e79b61c1380d662fa9c19654171d58e95100b004 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 12:00:24 -0500 Subject: [PATCH 5741/6505] Create sftpgo-install.sh --- install/sftpgo-install.sh | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 install/sftpgo-install.sh diff --git a/install/sftpgo-install.sh b/install/sftpgo-install.sh new file mode 100644 index 00000000..cba32803 --- /dev/null +++ b/install/sftpgo-install.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +$STD apt-get install -y sqlite3 +msg_ok "Installed Dependencies" + +msg_info "Installing Golang" +set +o pipefail +RELEASE=$(curl -s https://go.dev/dl/ | grep -o "go.*\linux-amd64.tar.gz" | head -n 1) +wget -q https://golang.org/dl/$RELEASE +tar -xzf $RELEASE -C /usr/local +$STD ln -s /usr/local/go/bin/go /usr/local/bin/go +set -o pipefail +msg_ok "Installed Golang" + +msg_info "Installing SFTPGo" +curl -sS https://ftp.osuosl.org/pub/sftpgo/apt/gpg.key | gpg --dearmor -o /usr/share/keyrings/sftpgo-archive-keyring.gpg +echo "deb [signed-by=/usr/share/keyrings/sftpgo-archive-keyring.gpg] https://ftp.osuosl.org/pub/sftpgo/apt bookworm main" >/etc/apt/sources.list.d/sftpgo.list +$STD apt-get update +$STD apt-get install -y sftpgo +msg_ok "Installed SFTPGo" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf $RELEASE +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From e8501df16ecd2faf08a91df7fd938a272e55c217 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 12:01:21 -0500 Subject: [PATCH 5742/6505] Create sftpgo.sh --- ct/sftpgo.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/sftpgo.sh diff --git a/ct/sftpgo.sh b/ct/sftpgo.sh new file mode 100644 index 00000000..7b5415be --- /dev/null +++ b/ct/sftpgo.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ ________________ ______ + / ___// ____/_ __/ __ \/ ____/___ + \__ \/ /_ / / / /_/ / / __/ __ \ + ___/ / __/ / / / ____/ /_/ / /_/ / +/____/_/ /_/ /_/ \____/\____/ + +EOF +} +header_info +echo -e "Loading..." +APP="SFTPGo" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080/web/admin ${CL} \n" From 4c5f70b7bf3c8d2f4ffadbb2915daac02e82ed21 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 12:24:55 -0500 Subject: [PATCH 5743/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ede93e6..5e4afc9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-07 + +### Changed + +- **SFTPGo LXC** + - NEW Script + ## 2024-01-04 ### Changed From 10809204a82d34639acd7f37af133d67fbfe3eaa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 16:07:51 -0500 Subject: [PATCH 5744/6505] Create stirlingpdf-install.sh --- install/stirlingpdf-install.sh | 110 +++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 install/stirlingpdf-install.sh diff --git a/install/stirlingpdf-install.sh b/install/stirlingpdf-install.sh new file mode 100644 index 00000000..1cefa174 --- /dev/null +++ b/install/stirlingpdf-install.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + sudo \ + mc \ + git \ + automake \ + autoconf \ + libtool \ + libleptonica-dev \ + pkg-config \ + zlib1g-dev \ + make \ + g++ \ + python3 \ + python3-pip \ + libreoffice-writer \ + libreoffice-calc \ + libreoffice-impress \ + unpaper \ + ocrmypdf + +$STD pip3 install \ + uno \ + opencv-python-headless \ + unoconv \ + pngquant \ + WeasyPrint +msg_ok "Installed Dependencies" + +msg_info "Installing Azul Zulu" +wget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" +wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb +$STD dpkg -i zulu-repo_1.0.0-3_all.deb +$STD apt-get update +$STD apt-get -y install zulu17-jdk +msg_ok "Installed Azul Zulu" + +msg_info "Installing JBIG2" +$STD git clone https://github.com/agl/jbig2enc /opt/jbig2enc +cd /opt/jbig2enc +$STD bash ./autogen.sh +$STD bash ./configure +$STD make +$STD make install +msg_ok "Installed JBIG2" + +msg_info "Installing Language Pack" +$STD apt-get install -y 'tesseract-ocr-*' +msg_ok "Installed Language Pack" + +msg_info "Install Stirling-PDF" +$STD git clone https://github.com/Stirling-Tools/Stirling-PDF.git +cd Stirling-PDF +chmod +x ./gradlew +$STD ./gradlew build + +mkdir -p /opt/Stirling-PDF +touch /opt/Stirling-PDF/.env +mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ +mv scripts /opt/Stirling-PDF/ +msg_ok "Installed Stirling-PDF" + +msg_info "Creating Service" +cat </etc/systemd/system/stirlingpdf.service +[Unit] +Description=Stirling-PDF service +After=syslog.target network.target + +[Service] +SuccessExitStatus=143 + +User=root +Group=root + +Type=simple +EnvironmentFile=/opt/Stirling-PDF/.env +WorkingDirectory=/opt/Stirling-PDF +ExecStart=/usr/bin/java -jar Stirling-PDF-0.19.0.jar +ExecStop=/bin/kill -15 $MAINPID + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now stirlingpdf.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +cd ~ && rm -rf Stirling-PDF configs customFiles logs zulu-repo_1.0.0-3_all.deb +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From d11f09050711b1356ab60b7cda46831cd4fdd1cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 16:08:46 -0500 Subject: [PATCH 5745/6505] Create stirlingpdf.sh --- ct/stirlingpdf.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/stirlingpdf.sh diff --git a/ct/stirlingpdf.sh b/ct/stirlingpdf.sh new file mode 100644 index 00000000..a7d9677a --- /dev/null +++ b/ct/stirlingpdf.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ __ _ ___ ____ ____ ______ + / ___// /_(_)____/ (_)___ ____ _ / __ \/ __ \/ ____/ + \__ \/ __/ / ___/ / / __ \/ __ `/_____/ /_/ / / / / /_ + ___/ / /_/ / / / / / / / / /_/ /_____/ ____/ /_/ / __/ +/____/\__/_/_/ /_/_/_/ /_/\__, / /_/ /_____/_/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Stirling-PDF" +var_disk="8" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/Stirling-PDF ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080 ${CL} \n" From 1bd7b6f7575b36a3a03b174d1b5cf884562014eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 16:24:48 -0500 Subject: [PATCH 5746/6505] Update stirlingpdf.sh --- ct/stirlingpdf.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/stirlingpdf.sh b/ct/stirlingpdf.sh index a7d9677a..15a3758c 100644 --- a/ct/stirlingpdf.sh +++ b/ct/stirlingpdf.sh @@ -8,17 +8,17 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - _____ __ _ ___ ____ ____ ______ - / ___// /_(_)____/ (_)___ ____ _ / __ \/ __ \/ ____/ - \__ \/ __/ / ___/ / / __ \/ __ `/_____/ /_/ / / / / /_ - ___/ / /_/ / / / / / / / / /_/ /_____/ ____/ /_/ / __/ -/____/\__/_/_/ /_/_/_/ /_/\__, / /_/ /_____/_/ + _____ __ _ ___ ____ ____ ______ + / ___// /_(_)____/ (_)___ ____ _ / __ \/ __ \/ ____/ + \__ \/ __/ / ___/ / / __ \/ __ `/___/ /_/ / / / / /_ + ___/ / /_/ / / / / / / / / /_/ /___/ ____/ /_/ / __/ +/____/\__/_/_/ /_/_/_/ /_/\__, / /_/ /_____/_/ /____/ EOF } header_info echo -e "Loading..." -APP="Stirling-PDF" +APP="StirlingPDF" var_disk="8" var_cpu="2" var_ram="2048" From 034f6d6537cffce7fd296a493c0fd003f56f6966 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 16:44:58 -0500 Subject: [PATCH 5747/6505] Update stirlingpdf-install.sh tweak --- install/stirlingpdf-install.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/install/stirlingpdf-install.sh b/install/stirlingpdf-install.sh index 1cefa174..89e3b02d 100644 --- a/install/stirlingpdf-install.sh +++ b/install/stirlingpdf-install.sh @@ -27,21 +27,24 @@ $STD apt-get install -y \ zlib1g-dev \ make \ g++ \ - python3 \ - python3-pip \ libreoffice-writer \ libreoffice-calc \ libreoffice-impress \ unpaper \ ocrmypdf +msg_ok "Installed Dependencies" +msg_info "Installing Python Dependencies" +$STD apt-get install -y \ + python3 \ + python3-pip $STD pip3 install \ uno \ opencv-python-headless \ unoconv \ pngquant \ WeasyPrint -msg_ok "Installed Dependencies" +msg_ok "Installed Python Dependencies" msg_info "Installing Azul Zulu" wget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" @@ -60,16 +63,15 @@ $STD make $STD make install msg_ok "Installed JBIG2" -msg_info "Installing Language Pack" +msg_info "Installing Language Packs (All)" $STD apt-get install -y 'tesseract-ocr-*' msg_ok "Installed Language Pack" -msg_info "Install Stirling-PDF" +msg_info "Installing Stirling-PDF" $STD git clone https://github.com/Stirling-Tools/Stirling-PDF.git cd Stirling-PDF chmod +x ./gradlew $STD ./gradlew build - mkdir -p /opt/Stirling-PDF touch /opt/Stirling-PDF/.env mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ @@ -92,7 +94,7 @@ Type=simple EnvironmentFile=/opt/Stirling-PDF/.env WorkingDirectory=/opt/Stirling-PDF ExecStart=/usr/bin/java -jar Stirling-PDF-0.19.0.jar -ExecStop=/bin/kill -15 $MAINPID +ExecStop=/bin/kill -15 %n [Install] WantedBy=multi-user.target From 7cf643abe70943e5709ae179f8826f65860f7ab6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 16:58:09 -0500 Subject: [PATCH 5748/6505] Update stirlingpdf-install.sh tweak --- install/stirlingpdf-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/stirlingpdf-install.sh b/install/stirlingpdf-install.sh index 89e3b02d..34ee2176 100644 --- a/install/stirlingpdf-install.sh +++ b/install/stirlingpdf-install.sh @@ -65,7 +65,7 @@ msg_ok "Installed JBIG2" msg_info "Installing Language Packs (All)" $STD apt-get install -y 'tesseract-ocr-*' -msg_ok "Installed Language Pack" +msg_ok "Installed Language Packs" msg_info "Installing Stirling-PDF" $STD git clone https://github.com/Stirling-Tools/Stirling-PDF.git From 3ea4ec656ba6b4e0c06de674aaba4a84606b05ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 19:21:20 -0500 Subject: [PATCH 5749/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e4afc9f..f99e6d05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ ### Changed +- **Stirling-PDF LXC** + - NEW Script - **SFTPGo LXC** - NEW Script From 1789d7af21561d144b0c527306234e73b9885c2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jan 2024 20:42:08 -0500 Subject: [PATCH 5750/6505] Update stirlingpdf-install.sh tweak --- install/stirlingpdf-install.sh | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/install/stirlingpdf-install.sh b/install/stirlingpdf-install.sh index 34ee2176..af527fd6 100644 --- a/install/stirlingpdf-install.sh +++ b/install/stirlingpdf-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies" +msg_info "Installing Dependencies (Patience)" $STD apt-get install -y \ curl \ sudo \ @@ -27,13 +27,17 @@ $STD apt-get install -y \ zlib1g-dev \ make \ g++ \ - libreoffice-writer \ - libreoffice-calc \ - libreoffice-impress \ unpaper \ ocrmypdf msg_ok "Installed Dependencies" +msg_info "Installing LibreOffice Components" +$STD apt-get install -y \ + libreoffice-writer \ + libreoffice-calc \ + libreoffice-impress +msg_ok "Installed LibreOffice Components" + msg_info "Installing Python Dependencies" $STD apt-get install -y \ python3 \ @@ -63,11 +67,11 @@ $STD make $STD make install msg_ok "Installed JBIG2" -msg_info "Installing Language Packs (All)" +msg_info "Installing Language Packs (Patience)" $STD apt-get install -y 'tesseract-ocr-*' msg_ok "Installed Language Packs" -msg_info "Installing Stirling-PDF" +msg_info "Installing Stirling-PDF (Additional Patience)" $STD git clone https://github.com/Stirling-Tools/Stirling-PDF.git cd Stirling-PDF chmod +x ./gradlew From cd1b7a4c64629d2ab568825a36814419c9d6a3a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 06:14:47 -0500 Subject: [PATCH 5751/6505] Update stirlingpdf-install.sh - Create a symbolic link from `/opt/Stirling-PDF/Stirling-PDF-*.jar` to `/opt/Stirling-PDF/Stirling-PDF.jar` to ensure that the `stirlingpdf.service` file doesn't have to be updated after each upgrade. - Show installed version --- install/stirlingpdf-install.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/install/stirlingpdf-install.sh b/install/stirlingpdf-install.sh index af527fd6..63c5763c 100644 --- a/install/stirlingpdf-install.sh +++ b/install/stirlingpdf-install.sh @@ -80,7 +80,10 @@ mkdir -p /opt/Stirling-PDF touch /opt/Stirling-PDF/.env mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ mv scripts /opt/Stirling-PDF/ -msg_ok "Installed Stirling-PDF" +latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) +ln -s "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar +current_version=$(echo "$latest_version" | grep -oP '(?<=Stirling-PDF-)\d+(\.\d+)+(?=\.jar)') +msg_ok "Installed Stirling-PDF version $current_version" msg_info "Creating Service" cat </etc/systemd/system/stirlingpdf.service @@ -97,7 +100,7 @@ Group=root Type=simple EnvironmentFile=/opt/Stirling-PDF/.env WorkingDirectory=/opt/Stirling-PDF -ExecStart=/usr/bin/java -jar Stirling-PDF-0.19.0.jar +ExecStart=/usr/bin/java -jar Stirling-PDF.jar ExecStop=/bin/kill -15 %n [Install] @@ -110,7 +113,7 @@ motd_ssh customize msg_info "Cleaning up" -cd ~ && rm -rf Stirling-PDF configs customFiles logs zulu-repo_1.0.0-3_all.deb +# cd ~ && rm -rf Stirling-PDF configs customFiles logs zulu-repo_1.0.0-3_all.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From ca48993e01e46fb6caf7e67d31ad05ccef44564a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 06:34:39 -0500 Subject: [PATCH 5752/6505] Update stirlingpdf-install.sh tweak --- install/stirlingpdf-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/stirlingpdf-install.sh b/install/stirlingpdf-install.sh index 63c5763c..a99bf679 100644 --- a/install/stirlingpdf-install.sh +++ b/install/stirlingpdf-install.sh @@ -83,7 +83,7 @@ mv scripts /opt/Stirling-PDF/ latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) ln -s "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar current_version=$(echo "$latest_version" | grep -oP '(?<=Stirling-PDF-)\d+(\.\d+)+(?=\.jar)') -msg_ok "Installed Stirling-PDF version $current_version" +msg_ok "Installed Stirling-PDF v$current_version" msg_info "Creating Service" cat </etc/systemd/system/stirlingpdf.service @@ -113,7 +113,7 @@ motd_ssh customize msg_info "Cleaning up" -# cd ~ && rm -rf Stirling-PDF configs customFiles logs zulu-repo_1.0.0-3_all.deb +rm -rf /zulu-repo_1.0.0-3_all.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From b80c0e422a6f70f3fbf9a7d1a10816b86b7a0385 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 06:38:27 -0500 Subject: [PATCH 5753/6505] Update stirlingpdf.sh - Create update path --- ct/stirlingpdf.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ct/stirlingpdf.sh b/ct/stirlingpdf.sh index 15a3758c..4004c8b9 100644 --- a/ct/stirlingpdf.sh +++ b/ct/stirlingpdf.sh @@ -53,7 +53,21 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/Stirling-PDF ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +msg_info "Updating ${APP}" +systemctl stop stirlingpdf +git clone https://github.com/Stirling-Tools/Stirling-PDF.git +cd Stirling-PDF +chmod +x ./gradlew +./gradlew build +cp -r ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ +cp -r scripts /opt/Stirling-PDF/ +cd ~ +rm -rf Stirling-PDF +latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) +ln -s "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar +new_version=$(echo "$latest_version" | grep -oP '(?<=Stirling-PDF-)\d+(\.\d+)+(?=\.jar)') +systemctl start stirlingpdf +msg_ok "Updated ${APP} to v$new_version" exit } From e1247b6d0bbee3efa3297b964e4910e2a17d75b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 06:42:12 -0500 Subject: [PATCH 5754/6505] Update stirlingpdf.sh tweak --- ct/stirlingpdf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/stirlingpdf.sh b/ct/stirlingpdf.sh index 4004c8b9..4947e5d0 100644 --- a/ct/stirlingpdf.sh +++ b/ct/stirlingpdf.sh @@ -64,7 +64,7 @@ cp -r scripts /opt/Stirling-PDF/ cd ~ rm -rf Stirling-PDF latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) -ln -s "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar +ln -sf "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar new_version=$(echo "$latest_version" | grep -oP '(?<=Stirling-PDF-)\d+(\.\d+)+(?=\.jar)') systemctl start stirlingpdf msg_ok "Updated ${APP} to v$new_version" From 95a9467ff19d53c63ea01e4317c663bcf5e585ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 08:00:05 -0500 Subject: [PATCH 5755/6505] Update and rename stirlingpdf.sh to stirling-pdf.sh - Rename sh file - Switch update from git to relaese --- ct/{stirlingpdf.sh => stirling-pdf.sh} | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) rename ct/{stirlingpdf.sh => stirling-pdf.sh} (79%) diff --git a/ct/stirlingpdf.sh b/ct/stirling-pdf.sh similarity index 79% rename from ct/stirlingpdf.sh rename to ct/stirling-pdf.sh index 4947e5d0..4e3373b0 100644 --- a/ct/stirlingpdf.sh +++ b/ct/stirling-pdf.sh @@ -18,7 +18,7 @@ EOF } header_info echo -e "Loading..." -APP="StirlingPDF" +APP="Stirling-PDF" var_disk="8" var_cpu="2" var_ram="2048" @@ -55,19 +55,20 @@ header_info if [[ ! -d /opt/Stirling-PDF ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" systemctl stop stirlingpdf -git clone https://github.com/Stirling-Tools/Stirling-PDF.git -cd Stirling-PDF +RELEASE=$(curl -s https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz +tar -xzf v$RELEASE.tar.gz +cd Stirling-PDF-$RELEASE chmod +x ./gradlew -./gradlew build +./gradlew build &>/dev/null cp -r ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ cp -r scripts /opt/Stirling-PDF/ cd ~ -rm -rf Stirling-PDF +rm -rf Stirling-PDF-$RELEASE v$RELEASE.tar.gz latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) ln -sf "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar -new_version=$(echo "$latest_version" | grep -oP '(?<=Stirling-PDF-)\d+(\.\d+)+(?=\.jar)') systemctl start stirlingpdf -msg_ok "Updated ${APP} to v$new_version" +msg_ok "Updated ${APP} to v$RELEASE" exit } From aad569dc0d652223412a66623378548af7d681e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 08:02:34 -0500 Subject: [PATCH 5756/6505] Update and rename stirlingpdf-install.sh to stirling-pdf-install.sh - Rename stirlingpdf-install.sh to stirling-pdf-install.sh - Switch from git to release for install --- ...stirlingpdf-install.sh => stirling-pdf-install.sh} | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) rename install/{stirlingpdf-install.sh => stirling-pdf-install.sh} (86%) diff --git a/install/stirlingpdf-install.sh b/install/stirling-pdf-install.sh similarity index 86% rename from install/stirlingpdf-install.sh rename to install/stirling-pdf-install.sh index a99bf679..353d8269 100644 --- a/install/stirlingpdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -72,8 +72,10 @@ $STD apt-get install -y 'tesseract-ocr-*' msg_ok "Installed Language Packs" msg_info "Installing Stirling-PDF (Additional Patience)" -$STD git clone https://github.com/Stirling-Tools/Stirling-PDF.git -cd Stirling-PDF +RELEASE=$(curl -s https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz +tar -xzf v$RELEASE.tar.gz +cd Stirling-PDF-$RELEASE chmod +x ./gradlew $STD ./gradlew build mkdir -p /opt/Stirling-PDF @@ -82,8 +84,7 @@ mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ mv scripts /opt/Stirling-PDF/ latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) ln -s "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar -current_version=$(echo "$latest_version" | grep -oP '(?<=Stirling-PDF-)\d+(\.\d+)+(?=\.jar)') -msg_ok "Installed Stirling-PDF v$current_version" +msg_ok "Installed Stirling-PDF v$RELEASE" msg_info "Creating Service" cat </etc/systemd/system/stirlingpdf.service @@ -113,7 +114,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf /zulu-repo_1.0.0-3_all.deb +rm -rf v$RELEASE.tar.gz /zulu-repo_1.0.0-3_all.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From fd0e3748bf0bba0de62deff7bc17ed0a1812d8e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 08:21:33 -0500 Subject: [PATCH 5757/6505] Update stirling-pdf-install.sh tweak --- install/stirling-pdf-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 353d8269..43cb89a8 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -82,8 +82,7 @@ mkdir -p /opt/Stirling-PDF touch /opt/Stirling-PDF/.env mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ mv scripts /opt/Stirling-PDF/ -latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) -ln -s "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar +ln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar msg_ok "Installed Stirling-PDF v$RELEASE" msg_info "Creating Service" From 1eaf2b2988badf910aced5e5a6df574553bfac48 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 8 Jan 2024 08:23:08 -0500 Subject: [PATCH 5758/6505] Update stirling-pdf.sh tweak --- ct/stirling-pdf.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/stirling-pdf.sh b/ct/stirling-pdf.sh index 4e3373b0..8e86cbc3 100644 --- a/ct/stirling-pdf.sh +++ b/ct/stirling-pdf.sh @@ -65,8 +65,7 @@ cp -r ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ cp -r scripts /opt/Stirling-PDF/ cd ~ rm -rf Stirling-PDF-$RELEASE v$RELEASE.tar.gz -latest_version=$(ls -1 /opt/Stirling-PDF/Stirling-PDF-*.jar | sort -V | tail -n 1) -ln -sf "$latest_version" /opt/Stirling-PDF/Stirling-PDF.jar +ln -sf /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar systemctl start stirlingpdf msg_ok "Updated ${APP} to v$RELEASE" exit From 9ca401e30f26815479bd38c9e3bd04ced4d4d445 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Jan 2024 19:44:38 -0500 Subject: [PATCH 5759/6505] Update verbose mode - Remove `set -x` - Only entries with `$STD` will be shown --- ct/create_lxc.sh | 2 +- misc/alpine-install.func | 1 - misc/build.func | 2 +- misc/install.func | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index ee29e706..9d41819d 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -6,7 +6,7 @@ # https://github.com/tteck/Proxmox/raw/main/LICENSE # This sets verbose mode if the global variable is set to "yes" -if [ "$VERBOSE" == "yes" ]; then set -x; fi +# if [ "$VERBOSE" == "yes" ]; then set -x; fi # This function sets color variables for formatting output in the terminal YW=$(echo "\033[33m") diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 39e76d8f..16bde1d4 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -17,7 +17,6 @@ color() { verb_ip6() { if [ "$VERBOSE" = "yes" ]; then - set -x STD="" else STD="silent"; fi silent() { "$@" >/dev/null 2>&1; } diff --git a/misc/build.func b/misc/build.func index 37dec4f0..05a9c0b4 100644 --- a/misc/build.func +++ b/misc/build.func @@ -481,7 +481,7 @@ start() { # This function collects user settings and integrates all the collected information. build_container() { - if [ "$VERB" == "yes" ]; then set -x; fi +# if [ "$VERB" == "yes" ]; then set -x; fi if [ "$CT_TYPE" == "1" ]; then FEATURES="keyctl=1,nesting=1" diff --git a/misc/install.func b/misc/install.func index 66da53d2..d50237f4 100644 --- a/misc/install.func +++ b/misc/install.func @@ -18,7 +18,6 @@ color() { # This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to "yes" verb_ip6() { if [ "$VERBOSE" = "yes" ]; then - set -x STD="" else STD="silent"; fi silent() { "$@" >/dev/null 2>&1; } From fb13baee88df9a900215eefee74268420e057b01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Jan 2024 19:58:38 -0500 Subject: [PATCH 5760/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f99e6d05..75936efa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-09 + +### Changed + +- **Verbose mode** + - Only entries with `$STD` will be shown + ## 2024-01-07 ### Changed From 478b4e1c32ca1f9942d0f4bfd53523af6702c41c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Jan 2024 09:01:07 -0500 Subject: [PATCH 5761/6505] Update agentdvr-install.sh fixes https://github.com/tteck/Proxmox/issues/2322 --- install/agentdvr-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/agentdvr-install.sh b/install/agentdvr-install.sh index 8eeaf33d..239a57ff 100644 --- a/install/agentdvr-install.sh +++ b/install/agentdvr-install.sh @@ -22,6 +22,7 @@ $STD apt-get install -y apt-transport-https $STD apt-get install -y alsa-utils $STD apt-get install -y libxext-dev $STD apt-get install -y fontconfig +$STD apt-get install -y libva-drm2 msg_ok "Installed Dependencies" msg_info "Installing AgentDVR" From d72f269ad69418b6923fd89be5e55ef9006559fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 05:14:17 -0500 Subject: [PATCH 5762/6505] Update build.func fixes https://github.com/tteck/Proxmox/issues/2326 --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index 05a9c0b4..56599ad4 100644 --- a/misc/build.func +++ b/misc/build.func @@ -475,6 +475,7 @@ start() { echo -e "⚠ User exited script \n" exit fi + SPINNER_PID="" update_script fi } From 4fc60f8ad04caaa0b66242a21ced926fcd00085f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 10:21:33 -0500 Subject: [PATCH 5763/6505] Create apt-cacher-ng-install.sh --- install/apt-cacher-ng-install.sh | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 install/apt-cacher-ng-install.sh diff --git a/install/apt-cacher-ng-install.sh b/install/apt-cacher-ng-install.sh new file mode 100644 index 00000000..2cdf05a0 --- /dev/null +++ b/install/apt-cacher-ng-install.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Apt-Cacher NG" +DEBIAN_FRONTEND=noninteractive $STD apt-get -o Dpkg::Options::="--force-confold" install -y apt-cacher-ng +sed -i 's/# \(PassThroughPattern: .* # this would allow CONNECT to everything\)/\1/' /etc/apt-cacher-ng/acng.conf +systemctl enable -q --now apt-cacher-ng +msg_ok "Installed Apt-Cacher NG" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From f72b38f3487b65954177b5cbd810413cf81ddedd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 10:22:56 -0500 Subject: [PATCH 5764/6505] Create apt-cacher-ng.sh --- ct/apt-cacher-ng.sh | 70 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ct/apt-cacher-ng.sh diff --git a/ct/apt-cacher-ng.sh b/ct/apt-cacher-ng.sh new file mode 100644 index 00000000..6a4439ca --- /dev/null +++ b/ct/apt-cacher-ng.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ ______ __ _ ________ + / | ____ / /_ / ____/___ ______/ /_ ___ _____ / | / / ____/ + / /| | / __ \/ __/__/ / / __ `/ ___/ __ \/ _ \/ ___/__/ |/ / / __ + / ___ |/ /_/ / /_/__/ /___/ /_/ / /__/ / / / __/ / /__/ /| / /_/ / +/_/ |_/ .___/\__/ \____/\__,_/\___/_/ /_/\___/_/ /_/ |_/\____/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Apt-Cacher-NG" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} maintenance page should be reachable by going to the following URL. + ${BL}http://${IP}:3142/acng-report.html${CL} \n" From d9aedda5afd3e6fb652c0f8805b293e11a4d1641 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 10:29:27 -0500 Subject: [PATCH 5765/6505] Update build.func add option to utilize apt-cacher-ng --- misc/build.func | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/misc/build.func b/misc/build.func index 56599ad4..3beacc87 100644 --- a/misc/build.func +++ b/misc/build.func @@ -135,6 +135,7 @@ echo_default() { echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + echo -e "${DGN}APT-Cacher IP: ${BGN}None${CL}" echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -340,6 +341,18 @@ advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" fi + if APT_CACHER_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for default)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + if [ -z "$APT_CACHER_IP" ]; then + APT_CACHER="no" + APT_CACHER_IP="None" + else + APT_CACHER="yes" + fi + echo -e "${DGN}Using APT-Cacher IP: ${BGN}$APT_CACHER_IP${CL}" + else + exit-script + fi + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" else @@ -498,6 +511,8 @@ build_container() { else export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" fi + export CACHER="$APT_CACHER" + export CACHER_IP="$APT_CACHER_IP" export tz="$timezone" export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" From 4cd3cf0e23e084b95234e0bbd6f21745af1fb0b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 10:30:39 -0500 Subject: [PATCH 5766/6505] Update install.func accommodate apt-cacher-ng --- misc/install.func | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/install.func b/misc/install.func index d50237f4..68be24d7 100644 --- a/misc/install.func +++ b/misc/install.func @@ -131,6 +131,9 @@ network_check() { # This function updates the Container OS by running apt-get update and upgrade update_os() { msg_info "Updating Container OS" + if [[ "$CACHER" == "yes" ]]; then + echo "Acquire::http { Proxy \"http://${CACHER_IP}:3142\"; };" >/etc/apt/apt.conf.d/00aptproxy + fi $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade msg_ok "Updated Container OS" From ea339ecfab52d122b77cf0b6c1887cc5c9a42235 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 11:29:20 -0500 Subject: [PATCH 5767/6505] Update build.func tweak --- misc/build.func | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/build.func b/misc/build.func index 3beacc87..9bc6c582 100644 --- a/misc/build.func +++ b/misc/build.func @@ -123,6 +123,7 @@ ssh_check() { # This function displays the default values for various settings. echo_default() { + APT_CACHER="" echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}" echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" @@ -511,8 +512,10 @@ build_container() { else export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" fi + if [ "$APT_CACHER" == "yes" ]; then export CACHER="$APT_CACHER" export CACHER_IP="$APT_CACHER_IP" + fi export tz="$timezone" export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" From 5196ed8fecde8121bf670ae89e764c561dd4f1e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 11:48:37 -0500 Subject: [PATCH 5768/6505] Update build.func tweak --- misc/build.func | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index 9bc6c582..cbb7b4e9 100644 --- a/misc/build.func +++ b/misc/build.func @@ -124,6 +124,7 @@ ssh_check() { # This function displays the default values for various settings. echo_default() { APT_CACHER="" + APT_CACHER_IP="" echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}" echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" @@ -511,11 +512,9 @@ build_container() { export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)" else export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" - fi - if [ "$APT_CACHER" == "yes" ]; then + export CACHER="$APT_CACHER" export CACHER_IP="$APT_CACHER_IP" - fi export tz="$timezone" export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" From 77087f798ad30b42e35c48bff138402f9c6626c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 12:00:37 -0500 Subject: [PATCH 5769/6505] Update build.func tweak --- misc/build.func | 2 -- 1 file changed, 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index cbb7b4e9..46a7a94b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -123,8 +123,6 @@ ssh_check() { # This function displays the default values for various settings. echo_default() { - APT_CACHER="" - APT_CACHER_IP="" echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}" echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" From 7122a465a1122462a71b8a717aa1f2ac3dbb33d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 12:04:03 -0500 Subject: [PATCH 5770/6505] Add variables --- ct/adguard.sh | 2 ++ ct/agentdvr.sh | 2 ++ ct/alpine-docker.sh | 2 ++ ct/alpine-grafana.sh | 2 ++ ct/alpine-nextcloud.sh | 2 ++ ct/alpine-vaultwarden.sh | 2 ++ ct/alpine-zigbee2mqtt.sh | 2 ++ ct/alpine.sh | 2 ++ ct/apt-cacher-ng.sh | 2 ++ ct/audiobookshelf.sh | 2 ++ ct/autobrr.sh | 2 ++ ct/bazarr.sh | 2 ++ ct/blocky.sh | 2 ++ ct/casaos.sh | 2 ++ ct/changedetection.sh | 2 ++ ct/channels.sh | 2 ++ ct/cloudflared.sh | 2 ++ ct/commafeed.sh | 2 ++ ct/cronicle.sh | 2 ++ ct/daemonsync.sh | 2 ++ ct/dashy.sh | 2 ++ ct/debian.sh | 2 ++ ct/deconz.sh | 2 ++ ct/deluge.sh | 2 ++ ct/docker.sh | 2 ++ ct/dockge.sh | 2 ++ ct/emby.sh | 2 ++ ct/emqx.sh | 2 ++ ct/esphome.sh | 2 ++ ct/fhem.sh | 2 ++ ct/go2rtc.sh | 2 ++ ct/gotify.sh | 2 ++ ct/grafana.sh | 2 ++ ct/grocy.sh | 2 ++ ct/heimdalldashboard.sh | 2 ++ ct/homarr.sh | 2 ++ ct/homeassistant-core.sh | 2 ++ ct/homeassistant.sh | 2 ++ ct/homebridge.sh | 2 ++ ct/homepage.sh | 2 ++ ct/homer.sh | 2 ++ ct/hyperion.sh | 2 ++ ct/influxdb.sh | 2 ++ ct/iobroker.sh | 2 ++ ct/jackett.sh | 2 ++ ct/jellyfin.sh | 2 ++ ct/jellyseerr.sh | 2 ++ ct/k0s.sh | 2 ++ ct/kavita.sh | 2 ++ ct/keycloak.sh | 2 ++ ct/lidarr.sh | 2 ++ ct/linkwarden.sh | 2 ++ ct/magicmirror.sh | 2 ++ ct/mariadb.sh | 2 ++ ct/meshcentral.sh | 2 ++ ct/motioneye.sh | 2 ++ ct/mqtt.sh | 2 ++ ct/n8n.sh | 2 ++ ct/navidrome.sh | 2 ++ ct/nextcloudpi.sh | 2 ++ ct/nginxproxymanager.sh | 2 ++ ct/nocodb.sh | 2 ++ ct/node-red.sh | 2 ++ ct/octoprint.sh | 2 ++ ct/omada.sh | 2 ++ ct/ombi.sh | 2 ++ ct/omv.sh | 2 ++ ct/openhab.sh | 2 ++ ct/openobserve.sh | 2 ++ ct/overseerr.sh | 2 ++ ct/owncast.sh | 2 ++ ct/paperless-ngx.sh | 2 ++ ct/photoprism.sh | 2 ++ ct/pialert.sh | 2 ++ ct/pihole.sh | 2 ++ ct/pingvin.sh | 2 ++ ct/plex.sh | 2 ++ ct/podman-homeassistant.sh | 2 ++ ct/podman.sh | 2 ++ ct/postgresql.sh | 2 ++ ct/prometheus.sh | 2 ++ ct/prowlarr.sh | 2 ++ ct/qbittorrent.sh | 2 ++ ct/radarr.sh | 2 ++ ct/rdtclient.sh | 2 ++ ct/readarr.sh | 2 ++ ct/rockylinux.sh | 2 ++ ct/rtsptoweb.sh | 2 ++ ct/runtipi.sh | 2 ++ ct/sabnzbd.sh | 2 ++ ct/scrypted.sh | 2 ++ ct/sftpgo.sh | 2 ++ ct/shinobi.sh | 2 ++ ct/sonarr.sh | 2 ++ ct/stirling-pdf.sh | 2 ++ ct/syncthing.sh | 2 ++ ct/tasmoadmin.sh | 2 ++ ct/tautulli.sh | 2 ++ ct/tdarr.sh | 2 ++ ct/technitiumdns.sh | 2 ++ ct/transmission.sh | 2 ++ ct/trilium.sh | 2 ++ ct/ubuntu.sh | 2 ++ ct/umbrel.sh | 2 ++ ct/unifi.sh | 2 ++ ct/unmanic.sh | 2 ++ ct/uptimekuma.sh | 2 ++ ct/vaultwarden.sh | 2 ++ ct/whisparr.sh | 2 ++ ct/whoogle.sh | 2 ++ ct/wikijs.sh | 2 ++ ct/wireguard.sh | 2 ++ ct/yunohost.sh | 2 ++ ct/zigbee2mqtt.sh | 2 ++ ct/zoraxy.sh | 2 ++ ct/zwave-js-ui.sh | 2 ++ 116 files changed, 232 insertions(+) diff --git a/ct/adguard.sh b/ct/adguard.sh index 5c15fca1..da5d39ce 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/agentdvr.sh b/ct/agentdvr.sh index caab7c04..2d70e13c 100644 --- a/ct/agentdvr.sh +++ b/ct/agentdvr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index c79f03d1..d401fc28 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index e99bef4e..51560661 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index bee4bf5f..bc9814e5 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 359f90c0..c270574f 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index d8941417..32c435a8 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine.sh b/ct/alpine.sh index 8da732a5..6ead34bc 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/apt-cacher-ng.sh b/ct/apt-cacher-ng.sh index 6a4439ca..15d1f140 100644 --- a/ct/apt-cacher-ng.sh +++ b/ct/apt-cacher-ng.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index 78b04add..a1a3c0b9 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/autobrr.sh b/ct/autobrr.sh index 4fe249e5..d0a73164 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/bazarr.sh b/ct/bazarr.sh index 687445ae..5371beee 100755 --- a/ct/bazarr.sh +++ b/ct/bazarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/blocky.sh b/ct/blocky.sh index 1d6d9858..64311a9c 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/casaos.sh b/ct/casaos.sh index 3b90d107..fcb30fdd 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/changedetection.sh b/ct/changedetection.sh index d12ead96..84448134 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/channels.sh b/ct/channels.sh index 7f05f7ec..6368677f 100644 --- a/ct/channels.sh +++ b/ct/channels.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/cloudflared.sh b/ct/cloudflared.sh index 19429bc3..832dc1b8 100644 --- a/ct/cloudflared.sh +++ b/ct/cloudflared.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/commafeed.sh b/ct/commafeed.sh index d4eba134..4449c285 100644 --- a/ct/commafeed.sh +++ b/ct/commafeed.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/cronicle.sh b/ct/cronicle.sh index fd7ea840..bbc296d1 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index ce3c885a..859d96d4 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/dashy.sh b/ct/dashy.sh index 6155bd77..309fe40c 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/debian.sh b/ct/debian.sh index edc59f1b..4db9904f 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/deconz.sh b/ct/deconz.sh index 93bfae2d..b3a53756 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/deluge.sh b/ct/deluge.sh index 75806917..385f93c7 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/docker.sh b/ct/docker.sh index 368d3518..7997d026 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/dockge.sh b/ct/dockge.sh index 39e7eac2..e24c74e3 100644 --- a/ct/dockge.sh +++ b/ct/dockge.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/emby.sh b/ct/emby.sh index 954bc140..563ecf57 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/emqx.sh b/ct/emqx.sh index 20fd755e..f469e28e 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/esphome.sh b/ct/esphome.sh index 6262cd67..0aee7d7b 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/fhem.sh b/ct/fhem.sh index 0b4812b7..c7a12377 100644 --- a/ct/fhem.sh +++ b/ct/fhem.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 7ad54ab7..38e4f55e 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/gotify.sh b/ct/gotify.sh index 99cbfbee..1b5b19d9 100644 --- a/ct/gotify.sh +++ b/ct/gotify.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/grafana.sh b/ct/grafana.sh index f3747d05..047807f6 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/grocy.sh b/ct/grocy.sh index 43a123e0..18bca608 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index c8106cbe..70ed090b 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homarr.sh b/ct/homarr.sh index 9f0353c2..f7a516e0 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index ea3ea3f1..086c8468 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 66dcafe2..e6e28ebf 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homebridge.sh b/ct/homebridge.sh index 28a12a7b..d32e5e51 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homepage.sh b/ct/homepage.sh index 25bc2c0b..bbeef90c 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homer.sh b/ct/homer.sh index 59670953..13a1535a 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 309b8754..402a0615 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/influxdb.sh b/ct/influxdb.sh index dded776f..e732a60b 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/iobroker.sh b/ct/iobroker.sh index 84edc759..eb1cccc6 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/jackett.sh b/ct/jackett.sh index 68d967a2..898cb4e3 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index b56e271e..3f7c9883 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index 68a93218..e3af3b80 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/k0s.sh b/ct/k0s.sh index f39b8a77..5c6331bb 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/kavita.sh b/ct/kavita.sh index 84afe3fb..e2238bf1 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 0a67f9d3..73810dc8 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/lidarr.sh b/ct/lidarr.sh index 3b800506..28b1bd3b 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index 95937e29..a62a2781 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index 5a547619..bbd5c3c3 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 6051169c..70f6ab09 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 16c9a837..03bc929f 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 306f6281..918a3b6c 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 86b5c18d..80d8408d 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/n8n.sh b/ct/n8n.sh index 39be816e..04de7c01 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/navidrome.sh b/ct/navidrome.sh index 28e10544..c009f9c3 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index 7e75d135..bcbef6dc 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 016c391c..bd6ea26d 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 6f2c76ea..538641ce 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/node-red.sh b/ct/node-red.sh index bdb8615e..cdd37d15 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/octoprint.sh b/ct/octoprint.sh index af27fabe..ab091834 100644 --- a/ct/octoprint.sh +++ b/ct/octoprint.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/omada.sh b/ct/omada.sh index 4d433261..33273e1c 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/ombi.sh b/ct/ombi.sh index d367b165..b3957aaa 100644 --- a/ct/ombi.sh +++ b/ct/ombi.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/omv.sh b/ct/omv.sh index 8ca264c3..d9510fdd 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/openhab.sh b/ct/openhab.sh index 14e9bbf4..60e9d7a7 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/openobserve.sh b/ct/openobserve.sh index 86828d9f..26e36a9c 100644 --- a/ct/openobserve.sh +++ b/ct/openobserve.sh @@ -41,6 +41,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/overseerr.sh b/ct/overseerr.sh index 392be917..4f8b271c 100644 --- a/ct/overseerr.sh +++ b/ct/overseerr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/owncast.sh b/ct/owncast.sh index 3bf376bf..06832850 100644 --- a/ct/owncast.sh +++ b/ct/owncast.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index b7a68ea8..f4773d70 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 5e8d754b..5ff79708 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/pialert.sh b/ct/pialert.sh index 6766107f..a06f2f6a 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/pihole.sh b/ct/pihole.sh index 2d5e8f2f..ad17f550 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/pingvin.sh b/ct/pingvin.sh index c3943725..8d36f98a 100644 --- a/ct/pingvin.sh +++ b/ct/pingvin.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/plex.sh b/ct/plex.sh index 12ab74f4..9ab0b8b3 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index d9cb8573..667e581f 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -43,6 +43,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/podman.sh b/ct/podman.sh index 820b20c3..b8e8e1a4 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 47bf54d1..5ff19c81 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 570eb1bf..6bf41bd1 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index 655a73cf..2ad20b7c 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index 9f0a07f6..da21d11f 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/radarr.sh b/ct/radarr.sh index 2dc8668b..d481245f 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh index 2df7fede..78e19112 100755 --- a/ct/rdtclient.sh +++ b/ct/rdtclient.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/readarr.sh b/ct/readarr.sh index 4a0dcd6a..7b995990 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index 9e476b5c..c9cb151a 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/rtsptoweb.sh b/ct/rtsptoweb.sh index 18642616..20d9b7f7 100644 --- a/ct/rtsptoweb.sh +++ b/ct/rtsptoweb.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/runtipi.sh b/ct/runtipi.sh index a779a1df..56b513e4 100644 --- a/ct/runtipi.sh +++ b/ct/runtipi.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index 427e53f7..b761526d 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/scrypted.sh b/ct/scrypted.sh index 8ffec8b5..15488152 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/sftpgo.sh b/ct/sftpgo.sh index 7b5415be..d3c2d7b3 100644 --- a/ct/sftpgo.sh +++ b/ct/sftpgo.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/shinobi.sh b/ct/shinobi.sh index c5488d2a..3f1cdb6e 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/sonarr.sh b/ct/sonarr.sh index 22af05ef..36a6297a 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/stirling-pdf.sh b/ct/stirling-pdf.sh index 8e86cbc3..29232f59 100644 --- a/ct/stirling-pdf.sh +++ b/ct/stirling-pdf.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/syncthing.sh b/ct/syncthing.sh index 9beff817..ad9fb728 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/tasmoadmin.sh b/ct/tasmoadmin.sh index 9aa75124..8b772760 100644 --- a/ct/tasmoadmin.sh +++ b/ct/tasmoadmin.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/tautulli.sh b/ct/tautulli.sh index 3445d79e..8430f04a 100644 --- a/ct/tautulli.sh +++ b/ct/tautulli.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 89f68c3e..51b69f45 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index e091db9d..8e6f042c 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/transmission.sh b/ct/transmission.sh index 435b4994..22638428 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/trilium.sh b/ct/trilium.sh index e0d2d75b..9a090607 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index c61b90bd..bd89172b 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 40ce605b..1638def3 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/unifi.sh b/ct/unifi.sh index f70327b2..352a809d 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/unmanic.sh b/ct/unmanic.sh index 05eb7298..4750f0ee 100644 --- a/ct/unmanic.sh +++ b/ct/unmanic.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index 4961ee5d..c0a14a46 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index f204a484..5b8e51fa 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/whisparr.sh b/ct/whisparr.sh index 3679741d..488f8197 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/whoogle.sh b/ct/whoogle.sh index 8334f650..11b127df 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/wikijs.sh b/ct/wikijs.sh index 0dfe3b4a..03feba32 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 31a554d6..f78f4cda 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 387a7dad..2b0c6bbd 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index a4ccac5c..eebc630f 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh index 9633a968..1f36cbe4 100644 --- a/ct/zoraxy.sh +++ b/ct/zoraxy.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index e0a3039c..83adbc9d 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -39,6 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="no" + APT_CACHER_IP="none" DISABLEIP6="no" MTU="" SD="" From 371cde2d8a76163283302cb8adef86e5fd08f212 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 12:09:32 -0500 Subject: [PATCH 5771/6505] Update build.func revert --- misc/build.func | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/misc/build.func b/misc/build.func index 46a7a94b..56599ad4 100644 --- a/misc/build.func +++ b/misc/build.func @@ -135,7 +135,6 @@ echo_default() { echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" - echo -e "${DGN}APT-Cacher IP: ${BGN}None${CL}" echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -341,18 +340,6 @@ advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" fi - if APT_CACHER_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for default)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - if [ -z "$APT_CACHER_IP" ]; then - APT_CACHER="no" - APT_CACHER_IP="None" - else - APT_CACHER="yes" - fi - echo -e "${DGN}Using APT-Cacher IP: ${BGN}$APT_CACHER_IP${CL}" - else - exit-script - fi - if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" else @@ -510,9 +497,7 @@ build_container() { export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)" else export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" - - export CACHER="$APT_CACHER" - export CACHER_IP="$APT_CACHER_IP" + fi export tz="$timezone" export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" From 50bc9c334a8e9681abc9397521431ff56694ab30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 12:11:16 -0500 Subject: [PATCH 5772/6505] Update install.func revert --- misc/install.func | 3 --- 1 file changed, 3 deletions(-) diff --git a/misc/install.func b/misc/install.func index 68be24d7..d50237f4 100644 --- a/misc/install.func +++ b/misc/install.func @@ -131,9 +131,6 @@ network_check() { # This function updates the Container OS by running apt-get update and upgrade update_os() { msg_info "Updating Container OS" - if [[ "$CACHER" == "yes" ]]; then - echo "Acquire::http { Proxy \"http://${CACHER_IP}:3142\"; };" >/etc/apt/apt.conf.d/00aptproxy - fi $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade msg_ok "Updated Container OS" From 6a83a3eaac874fcc2d54b5ba7f3cca908481b401 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 15:00:42 -0500 Subject: [PATCH 5773/6505] New feature - The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to reduce bandwidth usage and provide faster operating system updates. - Requires the Apt-Cacher-NG LXC --- ct/adguard.sh | 4 ++-- ct/agentdvr.sh | 4 ++-- ct/alpine-docker.sh | 4 ++-- ct/alpine-grafana.sh | 4 ++-- ct/alpine-nextcloud.sh | 4 ++-- ct/alpine-vaultwarden.sh | 4 ++-- ct/alpine-zigbee2mqtt.sh | 4 ++-- ct/alpine.sh | 4 ++-- ct/apt-cacher-ng.sh | 4 ++-- ct/audiobookshelf.sh | 4 ++-- ct/autobrr.sh | 4 ++-- ct/bazarr.sh | 4 ++-- ct/blocky.sh | 4 ++-- ct/casaos.sh | 4 ++-- ct/changedetection.sh | 4 ++-- ct/channels.sh | 4 ++-- ct/cloudflared.sh | 4 ++-- ct/commafeed.sh | 4 ++-- ct/cronicle.sh | 4 ++-- ct/daemonsync.sh | 4 ++-- ct/dashy.sh | 4 ++-- ct/debian.sh | 4 ++-- ct/deconz.sh | 4 ++-- ct/deluge.sh | 4 ++-- ct/docker.sh | 4 ++-- ct/dockge.sh | 4 ++-- ct/emby.sh | 4 ++-- ct/emqx.sh | 4 ++-- ct/esphome.sh | 4 ++-- ct/fhem.sh | 4 ++-- ct/go2rtc.sh | 4 ++-- ct/gotify.sh | 4 ++-- ct/grafana.sh | 4 ++-- ct/grocy.sh | 4 ++-- ct/heimdalldashboard.sh | 4 ++-- ct/homarr.sh | 4 ++-- ct/homeassistant-core.sh | 4 ++-- ct/homeassistant.sh | 4 ++-- ct/homebridge.sh | 4 ++-- ct/homepage.sh | 4 ++-- ct/homer.sh | 4 ++-- ct/hyperion.sh | 4 ++-- ct/influxdb.sh | 4 ++-- ct/iobroker.sh | 4 ++-- ct/jackett.sh | 4 ++-- ct/jellyfin.sh | 4 ++-- ct/jellyseerr.sh | 4 ++-- ct/k0s.sh | 4 ++-- ct/kavita.sh | 4 ++-- ct/keycloak.sh | 4 ++-- ct/lidarr.sh | 4 ++-- ct/linkwarden.sh | 4 ++-- ct/magicmirror.sh | 4 ++-- ct/mariadb.sh | 4 ++-- ct/meshcentral.sh | 4 ++-- ct/motioneye.sh | 4 ++-- ct/mqtt.sh | 4 ++-- ct/n8n.sh | 4 ++-- ct/navidrome.sh | 4 ++-- ct/nextcloudpi.sh | 4 ++-- ct/nginxproxymanager.sh | 4 ++-- ct/nocodb.sh | 4 ++-- ct/node-red.sh | 4 ++-- ct/octoprint.sh | 4 ++-- ct/omada.sh | 4 ++-- ct/ombi.sh | 4 ++-- ct/omv.sh | 4 ++-- ct/openhab.sh | 4 ++-- ct/openobserve.sh | 4 ++-- ct/overseerr.sh | 4 ++-- ct/owncast.sh | 4 ++-- ct/paperless-ngx.sh | 4 ++-- ct/photoprism.sh | 4 ++-- ct/pialert.sh | 4 ++-- ct/pihole.sh | 4 ++-- ct/pingvin.sh | 4 ++-- ct/plex.sh | 4 ++-- ct/podman-homeassistant.sh | 4 ++-- ct/podman.sh | 4 ++-- ct/postgresql.sh | 4 ++-- ct/prometheus.sh | 4 ++-- ct/prowlarr.sh | 4 ++-- ct/qbittorrent.sh | 4 ++-- ct/radarr.sh | 4 ++-- ct/rdtclient.sh | 4 ++-- ct/readarr.sh | 4 ++-- ct/rockylinux.sh | 4 ++-- ct/rtsptoweb.sh | 4 ++-- ct/runtipi.sh | 4 ++-- ct/sabnzbd.sh | 4 ++-- ct/scrypted.sh | 4 ++-- ct/sftpgo.sh | 4 ++-- ct/shinobi.sh | 4 ++-- ct/sonarr.sh | 4 ++-- ct/stirling-pdf.sh | 4 ++-- ct/syncthing.sh | 4 ++-- ct/tasmoadmin.sh | 4 ++-- ct/tautulli.sh | 4 ++-- ct/tdarr.sh | 4 ++-- ct/technitiumdns.sh | 4 ++-- ct/transmission.sh | 4 ++-- ct/trilium.sh | 4 ++-- ct/ubuntu.sh | 4 ++-- ct/umbrel.sh | 4 ++-- ct/unifi.sh | 4 ++-- ct/unmanic.sh | 4 ++-- ct/uptimekuma.sh | 4 ++-- ct/vaultwarden.sh | 4 ++-- ct/whisparr.sh | 4 ++-- ct/whoogle.sh | 4 ++-- ct/wikijs.sh | 4 ++-- ct/wireguard.sh | 4 ++-- ct/yunohost.sh | 4 ++-- ct/zigbee2mqtt.sh | 4 ++-- ct/zoraxy.sh | 4 ++-- ct/zwave-js-ui.sh | 4 ++-- misc/build.func | 14 ++++++++++++-- misc/install.func | 5 ++++- 118 files changed, 248 insertions(+), 235 deletions(-) diff --git a/ct/adguard.sh b/ct/adguard.sh index da5d39ce..e9e667c9 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/agentdvr.sh b/ct/agentdvr.sh index 2d70e13c..d77921bf 100644 --- a/ct/agentdvr.sh +++ b/ct/agentdvr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index d401fc28..49ee7518 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 51560661..4382f131 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index bc9814e5..5e9338ac 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index c270574f..9ce6763a 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 32c435a8..2767d924 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/alpine.sh b/ct/alpine.sh index 6ead34bc..85f3ad55 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/apt-cacher-ng.sh b/ct/apt-cacher-ng.sh index 15d1f140..8d8235a3 100644 --- a/ct/apt-cacher-ng.sh +++ b/ct/apt-cacher-ng.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/audiobookshelf.sh b/ct/audiobookshelf.sh index a1a3c0b9..4d360634 100644 --- a/ct/audiobookshelf.sh +++ b/ct/audiobookshelf.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/autobrr.sh b/ct/autobrr.sh index d0a73164..8cfc2f3e 100644 --- a/ct/autobrr.sh +++ b/ct/autobrr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/bazarr.sh b/ct/bazarr.sh index 5371beee..d94543e5 100755 --- a/ct/bazarr.sh +++ b/ct/bazarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/blocky.sh b/ct/blocky.sh index 64311a9c..a9c74c4d 100644 --- a/ct/blocky.sh +++ b/ct/blocky.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/casaos.sh b/ct/casaos.sh index fcb30fdd..85cc0510 100644 --- a/ct/casaos.sh +++ b/ct/casaos.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 84448134..5fe9759a 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/channels.sh b/ct/channels.sh index 6368677f..7e8b0140 100644 --- a/ct/channels.sh +++ b/ct/channels.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/cloudflared.sh b/ct/cloudflared.sh index 832dc1b8..c4f9631c 100644 --- a/ct/cloudflared.sh +++ b/ct/cloudflared.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/commafeed.sh b/ct/commafeed.sh index 4449c285..0084964a 100644 --- a/ct/commafeed.sh +++ b/ct/commafeed.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/cronicle.sh b/ct/cronicle.sh index bbc296d1..946101f3 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh index 859d96d4..01ffa4a7 100644 --- a/ct/daemonsync.sh +++ b/ct/daemonsync.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/dashy.sh b/ct/dashy.sh index 309fe40c..759b8805 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/debian.sh b/ct/debian.sh index 4db9904f..adfd810e 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/deconz.sh b/ct/deconz.sh index b3a53756..bf42af0c 100644 --- a/ct/deconz.sh +++ b/ct/deconz.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/deluge.sh b/ct/deluge.sh index 385f93c7..897a3bf8 100644 --- a/ct/deluge.sh +++ b/ct/deluge.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/docker.sh b/ct/docker.sh index 7997d026..ce263f9b 100644 --- a/ct/docker.sh +++ b/ct/docker.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/dockge.sh b/ct/dockge.sh index e24c74e3..b1d943a4 100644 --- a/ct/dockge.sh +++ b/ct/dockge.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/emby.sh b/ct/emby.sh index 563ecf57..a063e0af 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/emqx.sh b/ct/emqx.sh index f469e28e..6ec3cab7 100644 --- a/ct/emqx.sh +++ b/ct/emqx.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/esphome.sh b/ct/esphome.sh index 0aee7d7b..7a2e0e87 100644 --- a/ct/esphome.sh +++ b/ct/esphome.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/fhem.sh b/ct/fhem.sh index c7a12377..a98ce9ae 100644 --- a/ct/fhem.sh +++ b/ct/fhem.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/go2rtc.sh b/ct/go2rtc.sh index 38e4f55e..380ed801 100644 --- a/ct/go2rtc.sh +++ b/ct/go2rtc.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/gotify.sh b/ct/gotify.sh index 1b5b19d9..15f911df 100644 --- a/ct/gotify.sh +++ b/ct/gotify.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/grafana.sh b/ct/grafana.sh index 047807f6..085cb4ee 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/grocy.sh b/ct/grocy.sh index 18bca608..b9c11170 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 70ed090b..b2d0645a 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homarr.sh b/ct/homarr.sh index f7a516e0..a81bad4f 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 086c8468..375024e6 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index e6e28ebf..3f2c63ed 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homebridge.sh b/ct/homebridge.sh index d32e5e51..d252b52b 100644 --- a/ct/homebridge.sh +++ b/ct/homebridge.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homepage.sh b/ct/homepage.sh index bbeef90c..5107f65b 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/homer.sh b/ct/homer.sh index 13a1535a..f6b04d4d 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 402a0615..9bb9a141 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/influxdb.sh b/ct/influxdb.sh index e732a60b..2d995f6b 100644 --- a/ct/influxdb.sh +++ b/ct/influxdb.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/iobroker.sh b/ct/iobroker.sh index eb1cccc6..0bbd1d0f 100644 --- a/ct/iobroker.sh +++ b/ct/iobroker.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/jackett.sh b/ct/jackett.sh index 898cb4e3..096eef89 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index 3f7c9883..6f5dfc8b 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index e3af3b80..14768ed1 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/k0s.sh b/ct/k0s.sh index 5c6331bb..3b62bfc6 100644 --- a/ct/k0s.sh +++ b/ct/k0s.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/kavita.sh b/ct/kavita.sh index e2238bf1..206778fb 100644 --- a/ct/kavita.sh +++ b/ct/kavita.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/keycloak.sh b/ct/keycloak.sh index 73810dc8..5e461722 100644 --- a/ct/keycloak.sh +++ b/ct/keycloak.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/lidarr.sh b/ct/lidarr.sh index 28b1bd3b..9628b885 100644 --- a/ct/lidarr.sh +++ b/ct/lidarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index a62a2781..e2bf2fa5 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh index bbd5c3c3..bb5e0b7b 100644 --- a/ct/magicmirror.sh +++ b/ct/magicmirror.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/mariadb.sh b/ct/mariadb.sh index 70f6ab09..2b3eef00 100644 --- a/ct/mariadb.sh +++ b/ct/mariadb.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh index 03bc929f..1040a700 100644 --- a/ct/meshcentral.sh +++ b/ct/meshcentral.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/motioneye.sh b/ct/motioneye.sh index 918a3b6c..d5a2579f 100644 --- a/ct/motioneye.sh +++ b/ct/motioneye.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/mqtt.sh b/ct/mqtt.sh index 80d8408d..b79777df 100644 --- a/ct/mqtt.sh +++ b/ct/mqtt.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/n8n.sh b/ct/n8n.sh index 04de7c01..5c5feeae 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/navidrome.sh b/ct/navidrome.sh index c009f9c3..b9af1d6f 100644 --- a/ct/navidrome.sh +++ b/ct/navidrome.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index bcbef6dc..e4312b20 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index bd6ea26d..3456304e 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/nocodb.sh b/ct/nocodb.sh index 538641ce..4f8ff0b7 100644 --- a/ct/nocodb.sh +++ b/ct/nocodb.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/node-red.sh b/ct/node-red.sh index cdd37d15..1f68dc09 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/octoprint.sh b/ct/octoprint.sh index ab091834..75c2ccd9 100644 --- a/ct/octoprint.sh +++ b/ct/octoprint.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/omada.sh b/ct/omada.sh index 33273e1c..282d6508 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/ombi.sh b/ct/ombi.sh index b3957aaa..658182dc 100644 --- a/ct/ombi.sh +++ b/ct/ombi.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/omv.sh b/ct/omv.sh index d9510fdd..318a1699 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/openhab.sh b/ct/openhab.sh index 60e9d7a7..9546085a 100644 --- a/ct/openhab.sh +++ b/ct/openhab.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/openobserve.sh b/ct/openobserve.sh index 26e36a9c..cea4c29a 100644 --- a/ct/openobserve.sh +++ b/ct/openobserve.sh @@ -41,8 +41,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/overseerr.sh b/ct/overseerr.sh index 4f8b271c..a4a76bfc 100644 --- a/ct/overseerr.sh +++ b/ct/overseerr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/owncast.sh b/ct/owncast.sh index 06832850..c06ccfbb 100644 --- a/ct/owncast.sh +++ b/ct/owncast.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index f4773d70..4d05d1d2 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 5ff79708..26e0c729 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/pialert.sh b/ct/pialert.sh index a06f2f6a..7604d444 100644 --- a/ct/pialert.sh +++ b/ct/pialert.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/pihole.sh b/ct/pihole.sh index ad17f550..57c5e9c0 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/pingvin.sh b/ct/pingvin.sh index 8d36f98a..ff582d2f 100644 --- a/ct/pingvin.sh +++ b/ct/pingvin.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/plex.sh b/ct/plex.sh index 9ab0b8b3..998fe17c 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index 667e581f..1f02fe7f 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -43,8 +43,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/podman.sh b/ct/podman.sh index b8e8e1a4..e1e65b56 100644 --- a/ct/podman.sh +++ b/ct/podman.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/postgresql.sh b/ct/postgresql.sh index 5ff19c81..8ca8f172 100644 --- a/ct/postgresql.sh +++ b/ct/postgresql.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/prometheus.sh b/ct/prometheus.sh index 6bf41bd1..ae519078 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index 2ad20b7c..a2a54ad1 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh index da21d11f..0a8b1db8 100644 --- a/ct/qbittorrent.sh +++ b/ct/qbittorrent.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/radarr.sh b/ct/radarr.sh index d481245f..69a75d62 100644 --- a/ct/radarr.sh +++ b/ct/radarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh index 78e19112..7168998e 100755 --- a/ct/rdtclient.sh +++ b/ct/rdtclient.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/readarr.sh b/ct/readarr.sh index 7b995990..2e4494cf 100644 --- a/ct/readarr.sh +++ b/ct/readarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/rockylinux.sh b/ct/rockylinux.sh index c9cb151a..8285e227 100644 --- a/ct/rockylinux.sh +++ b/ct/rockylinux.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/rtsptoweb.sh b/ct/rtsptoweb.sh index 20d9b7f7..56484a60 100644 --- a/ct/rtsptoweb.sh +++ b/ct/rtsptoweb.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/runtipi.sh b/ct/runtipi.sh index 56b513e4..279230f3 100644 --- a/ct/runtipi.sh +++ b/ct/runtipi.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh index b761526d..c6d0aa26 100644 --- a/ct/sabnzbd.sh +++ b/ct/sabnzbd.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/scrypted.sh b/ct/scrypted.sh index 15488152..306ab620 100644 --- a/ct/scrypted.sh +++ b/ct/scrypted.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/sftpgo.sh b/ct/sftpgo.sh index d3c2d7b3..2354fe7d 100644 --- a/ct/sftpgo.sh +++ b/ct/sftpgo.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/shinobi.sh b/ct/shinobi.sh index 3f1cdb6e..410f9433 100644 --- a/ct/shinobi.sh +++ b/ct/shinobi.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/sonarr.sh b/ct/sonarr.sh index 36a6297a..fe2c5939 100644 --- a/ct/sonarr.sh +++ b/ct/sonarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/stirling-pdf.sh b/ct/stirling-pdf.sh index 29232f59..f1505054 100644 --- a/ct/stirling-pdf.sh +++ b/ct/stirling-pdf.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/syncthing.sh b/ct/syncthing.sh index ad9fb728..5cf7765c 100644 --- a/ct/syncthing.sh +++ b/ct/syncthing.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/tasmoadmin.sh b/ct/tasmoadmin.sh index 8b772760..662c36f1 100644 --- a/ct/tasmoadmin.sh +++ b/ct/tasmoadmin.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/tautulli.sh b/ct/tautulli.sh index 8430f04a..55a628d3 100644 --- a/ct/tautulli.sh +++ b/ct/tautulli.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/tdarr.sh b/ct/tdarr.sh index 51b69f45..b658ec70 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index 8e6f042c..d69c81aa 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/transmission.sh b/ct/transmission.sh index 22638428..a7e234e4 100644 --- a/ct/transmission.sh +++ b/ct/transmission.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/trilium.sh b/ct/trilium.sh index 9a090607..d4ade959 100644 --- a/ct/trilium.sh +++ b/ct/trilium.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index bd89172b..6572c02c 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/umbrel.sh b/ct/umbrel.sh index 1638def3..62f9a471 100644 --- a/ct/umbrel.sh +++ b/ct/umbrel.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/unifi.sh b/ct/unifi.sh index 352a809d..820930c0 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/unmanic.sh b/ct/unmanic.sh index 4750f0ee..04134cee 100644 --- a/ct/unmanic.sh +++ b/ct/unmanic.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh index c0a14a46..17289c24 100644 --- a/ct/uptimekuma.sh +++ b/ct/uptimekuma.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 5b8e51fa..53b04287 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/whisparr.sh b/ct/whisparr.sh index 488f8197..1a8b9a01 100644 --- a/ct/whisparr.sh +++ b/ct/whisparr.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/whoogle.sh b/ct/whoogle.sh index 11b127df..5fa40ba2 100644 --- a/ct/whoogle.sh +++ b/ct/whoogle.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/wikijs.sh b/ct/wikijs.sh index 03feba32..dedff2d6 100644 --- a/ct/wikijs.sh +++ b/ct/wikijs.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/wireguard.sh b/ct/wireguard.sh index f78f4cda..c8cc7c6f 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/yunohost.sh b/ct/yunohost.sh index 2b0c6bbd..613de2f5 100644 --- a/ct/yunohost.sh +++ b/ct/yunohost.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index eebc630f..e3ae7ee8 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -40,8 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh index 1f36cbe4..8d3a771b 100644 --- a/ct/zoraxy.sh +++ b/ct/zoraxy.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/ct/zwave-js-ui.sh b/ct/zwave-js-ui.sh index 83adbc9d..3be12b44 100644 --- a/ct/zwave-js-ui.sh +++ b/ct/zwave-js-ui.sh @@ -39,8 +39,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" - APT_CACHER="no" - APT_CACHER_IP="none" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" diff --git a/misc/build.func b/misc/build.func index 56599ad4..96542c16 100644 --- a/misc/build.func +++ b/misc/build.func @@ -134,7 +134,8 @@ echo_default() { echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" - echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" + echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" + echo -e "${DGN}Using Apt-Cacher IP Address: ${BGN}Default${CL}" echo -e "${DGN}Disable IPv6: ${BGN}No${CL}" echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}" @@ -340,6 +341,13 @@ advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" fi + if APT_CACHER_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for default)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + APT_CACHER="${APT_CACHER_IP:+yes}" + echo -e "${DGN}Using APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" + else + exit-script + fi + if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then DISABLEIP6="yes" else @@ -498,6 +506,8 @@ build_container() { else export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)" fi + export CACHER="$APT_CACHER" + export CACHER_IP="$APT_CACHER_IP" export tz="$timezone" export DISABLEIPV6="$DISABLEIP6" export APPLICATION="$APP" @@ -580,4 +590,4 @@ description() { if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi -} +} \ No newline at end of file diff --git a/misc/install.func b/misc/install.func index d50237f4..380392a2 100644 --- a/misc/install.func +++ b/misc/install.func @@ -131,6 +131,9 @@ network_check() { # This function updates the Container OS by running apt-get update and upgrade update_os() { msg_info "Updating Container OS" + if [[ "$CACHER" == "yes" ]]; then + echo "Acquire::http { Proxy \"http://${CACHER_IP}:3142\"; };" >/etc/apt/apt.conf.d/00aptproxy + fi $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade msg_ok "Updated Container OS" @@ -164,4 +167,4 @@ EOF fi echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update chmod +x /usr/bin/update -} +} \ No newline at end of file From 5a5265e9c4f1757b89fa96e72f4edde1ae0145eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 15:32:09 -0500 Subject: [PATCH 5774/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75936efa..b54785d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-12 + +### Changed + +- **Apt-Cacher-NG LXC** + - NEW Script + ## 2024-01-09 ### Changed From fa8c991f94c3823d8b29ffa6e06ef7627115afc2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 16:44:28 -0500 Subject: [PATCH 5775/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b54785d3..938e2fc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - **Apt-Cacher-NG LXC** - NEW Script +- **New Feature** + - The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to reduce bandwidth usage and provide faster operating system updates. ## 2024-01-09 From 0ef40c100c3c7abc898e5d4fdd6fcfac0a1c1bfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 17:09:40 -0500 Subject: [PATCH 5776/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 938e2fc0..54c35cba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ - **Apt-Cacher-NG LXC** - NEW Script - **New Feature** - - The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to reduce bandwidth usage and provide faster operating system updates. + - The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to decrease bandwidth usage and expedite package installation and updates. ## 2024-01-09 From 20da249d7575d597e9aa2e5d5b7f907e21a01e95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jan 2024 18:24:04 -0500 Subject: [PATCH 5777/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54c35cba..70f4235e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ - **Apt-Cacher-NG LXC** - NEW Script - **New Feature** - - The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to decrease bandwidth usage and expedite package installation and updates. + - The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to decrease bandwidth usage and expedite package installation and updates. https://github.com/tteck/Proxmox/discussions/2332 ## 2024-01-09 From 8b340be22dbb66e1aecc593e454e079c52b728a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Jan 2024 06:30:23 -0500 Subject: [PATCH 5778/6505] Update zigbee2mqtt-install.sh use shallow clone --- install/zigbee2mqtt-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 7855e7e5..92b847a6 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -37,7 +37,7 @@ $STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Setting up Zigbee2MQTT Repository" -$STD git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt +$STD git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt msg_ok "Set up Zigbee2MQTT Repository" read -r -p "Switch to Edge/dev branch? (y/N) " prompt From 242dfe8f730df9c68c017bd7111d3bcbd0198388 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Jan 2024 20:57:10 -0500 Subject: [PATCH 5779/6505] Update haos-vm.sh fixes https://github.com/tteck/Proxmox/issues/2338 --- vm/haos-vm.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index dfa476b5..d1494a01 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -37,6 +37,7 @@ HOLD="-" CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" THIN="discard=on,ssd=1," +SPINNER_PID="" set -Eeuo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT From 3c515e9f8e8e6a7982d6252acf5c077ac56739c0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Jan 2024 21:11:58 -0500 Subject: [PATCH 5780/6505] Update build.func tweak --- misc/build.func | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 96542c16..d877d42b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -474,6 +474,7 @@ start() { echo -e "⚠ User exited script \n" exit fi + SPINNER_PID="" install_script fi @@ -590,4 +591,4 @@ description() { if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service fi -} \ No newline at end of file +} From bf687e884f4972e8dcb85294a93fd63012b986ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 Jan 2024 23:00:56 -0500 Subject: [PATCH 5781/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index d877d42b..d892cd66 100644 --- a/misc/build.func +++ b/misc/build.func @@ -582,7 +582,7 @@ EOF # This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "
    + pct set "$CTID" -description "
    # ${APP} LXC From a8eaa376c1736a1df57735ce388768a5f92af2f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 Jan 2024 23:04:56 -0500 Subject: [PATCH 5782/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index d892cd66..c4d077ba 100644 --- a/misc/build.func +++ b/misc/build.func @@ -582,7 +582,7 @@ EOF # This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "
    + pct set "$CTID" -description "
    # ${APP} LXC From 7191bcabd24ed464d73f47c833253cc7c9f00c09 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 Jan 2024 23:20:36 -0500 Subject: [PATCH 5783/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index c4d077ba..390c1c8e 100644 --- a/misc/build.func +++ b/misc/build.func @@ -582,7 +582,7 @@ EOF # This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "
    + pct set "$CTID" -description "
    " # ${APP} LXC From 72fb5c396ddecc4c083340b23d6a44186dc4a0af Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 Jan 2024 23:29:37 -0500 Subject: [PATCH 5784/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 390c1c8e..c4d077ba 100644 --- a/misc/build.func +++ b/misc/build.func @@ -582,7 +582,7 @@ EOF # This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "
    " + pct set "$CTID" -description "
    # ${APP} LXC From 87b7fc7a94c23b21ae0ec19c491e36f388d019d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Jan 2024 08:44:35 -0500 Subject: [PATCH 5785/6505] Update apt-cacher-ng-install.sh tweak `sed` command --- install/apt-cacher-ng-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/apt-cacher-ng-install.sh b/install/apt-cacher-ng-install.sh index 2cdf05a0..fa131ef8 100644 --- a/install/apt-cacher-ng-install.sh +++ b/install/apt-cacher-ng-install.sh @@ -21,7 +21,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Apt-Cacher NG" DEBIAN_FRONTEND=noninteractive $STD apt-get -o Dpkg::Options::="--force-confold" install -y apt-cacher-ng -sed -i 's/# \(PassThroughPattern: .* # this would allow CONNECT to everything\)/\1/' /etc/apt-cacher-ng/acng.conf +sed -i 's/# PassThroughPattern: .* # this would allow CONNECT to everything/PassThroughPattern: .* /' /etc/apt-cacher-ng/acng.conf systemctl enable -q --now apt-cacher-ng msg_ok "Installed Apt-Cacher NG" From 04f8092ac4800c4d8cf58d10858e6ab2079f3954 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Jan 2024 11:41:24 -0500 Subject: [PATCH 5786/6505] Create ntfy.sh --- ct/ntfy.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 ct/ntfy.sh diff --git a/ct/ntfy.sh b/ct/ntfy.sh new file mode 100644 index 00000000..d12e4b3d --- /dev/null +++ b/ct/ntfy.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ____ + ____ / /_/ __/_ __ + / __ \/ __/ /_/ / / / + / / / / /_/ __/ /_/ / +/_/ /_/\__/_/ \__, / + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="ntfy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}${CL} \n" From 1698598a7ecb59d59213ac7cbead290343acdd6b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Jan 2024 11:42:33 -0500 Subject: [PATCH 5787/6505] Create ntfy-install.sh --- install/ntfy-install.sh | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 install/ntfy-install.sh diff --git a/install/ntfy-install.sh b/install/ntfy-install.sh new file mode 100644 index 00000000..2cdd985d --- /dev/null +++ b/install/ntfy-install.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +$STD apt-get install -y apt-transport-https +msg_ok "Installed Dependencies" + +msg_info "Installing ntfy" +mkdir -p /etc/apt/keyrings +curl -fsSL https://archive.heckel.io/apt/pubkey.txt | gpg --dearmor -o /etc/apt/keyrings/archive.heckel.io.gpg +echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/archive.heckel.io.gpg] https://archive.heckel.io/apt debian main" >/etc/apt/sources.list.d/archive.heckel.io.list +$STD apt-get update +$STD apt-get install -y ntfy +systemctl enable -q --now ntfy +msg_ok "Installed ntfy" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From e71f2bf40d02de1d09ca2e5b696ac18350972c6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 03:41:46 -0500 Subject: [PATCH 5788/6505] Update haos-vm.sh tweak --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index d1494a01..d60fd484 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -449,7 +449,7 @@ qm set $VMID \ -efidisk0 ${DISK0_REF}${FORMAT} \ -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=32G \ -boot order=scsi0 \ - -description "
    + -description "
    # Home Assistant OS From fcafbf20778ac9069dddce185b45ee1007d2b4ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 04:44:55 -0500 Subject: [PATCH 5789/6505] Update CHANGELOG.md --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70f4235e..26921c38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-16 + +### Changed + +- **Website Improvements** + - Refine and correct pointers. + - Change hover colors to intuitively indicate categories/items. + - Implement opening links in new tabs for better navigation. + - Enhance the Copy button to better indicate that the command has been successfully copied. + - Introduce a Clear Search button. + - While not directly related to the website, it's worth mentioning that the logo in newly created LXC notes now serves as a link to the website, conveniently opening in a new tab. + ## 2024-01-12 ### Changed From 0c543874c08ade531ed57bf296c83986c3257f49 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 05:48:39 -0500 Subject: [PATCH 5790/6505] Update omada-install.sh tweak --- install/omada-install.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index ca97a7f3..b54ec2f2 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -37,18 +37,18 @@ $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) -latest_version=$(basename "$latest_url" | sed -e 's/.*ller_//;s/_Li.*//') +latest_version=$(basename "$latest_url") -msg_info "Installing Omada Controller ${latest_version}" +msg_info "Installing Omada Controller" wget -qL ${latest_url} -$STD dpkg -i Omada_SDN_Controller_${latest_version}_Linux_x64.deb -msg_ok "Installed Omada Controller ${latest_version}" +$STD dpkg -i ${latest_version} +msg_ok "Installed Omada Controller" motd_ssh customize msg_info "Cleaning up" -rm -rf Omada_SDN_Controller_${latest_version}_Linux_x64.deb mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +rm -rf ${latest_version} mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 693367e2782a6f631a311c8e7641ce7ea6d73284 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 05:53:10 -0500 Subject: [PATCH 5791/6505] Update omada.sh fixes https://github.com/tteck/Proxmox/issues/2349 --- ct/omada.sh | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/ct/omada.sh b/ct/omada.sh index 282d6508..82f28261 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -56,26 +56,17 @@ function update_script() { header_info if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; fi latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) -latest_version=$(basename "${latest_url}" | sed -e 's/.*ller_//;s/_Li.*//') +latest_version=$(basename "${latest_url}") if [ -z "${latest_version}" ]; then msg_error "It seems that the server (tp-link.com) might be down. Please try again at a later time." exit fi -installed_version=$(dpkg -l | grep omada | awk '{print $3}') - -if [ "v${installed_version}" = "${latest_version}" ]; then - msg_info "Installed version (v${installed_version}) is the same as the latest version (${latest_version})" - sleep 2 - msg_ok "Omada Controller is already up to date" - exit -else - echo -e "Updating Omada Controller to ${latest_version}" - wget -qL ${latest_url} - dpkg -i Omada_SDN_Controller_${latest_version}_Linux_x64.deb - rm -rf Omada_SDN_Controller_${latest_version}_Linux_x64.deb - echo -e "Updated Omada Controller to ${latest_version}" +echo -e "Updating Omada Controller" +wget -qL ${latest_url} +dpkg -i ${latest_version} +rm -rf ${latest_version} +echo -e "Updated Omada Controller" exit -fi } start From c5e9a48aa3e0cd7cd029ffb6ed696bd2f8f7f396 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 17:14:43 -0500 Subject: [PATCH 5792/6505] Update zigbee2mqtt-install.sh tweak dev branch --- install/zigbee2mqtt-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 92b847a6..e9b354b0 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -50,7 +50,9 @@ fi msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt if [[ $DEV == "y" ]]; then +$STD git fetch origin dev $STD git checkout dev +$STD git pull fi $STD npm ci msg_ok "Installed Zigbee2MQTT" From cbdfb1803ac89bc8e36556e3a77ba7165bf02935 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 17:21:13 -0500 Subject: [PATCH 5793/6505] Update zigbee2mqtt-install.sh remove `dev` option --- install/zigbee2mqtt-install.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index e9b354b0..277ce6ad 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -40,20 +40,8 @@ msg_info "Setting up Zigbee2MQTT Repository" $STD git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt msg_ok "Set up Zigbee2MQTT Repository" -read -r -p "Switch to Edge/dev branch? (y/N) " prompt -if [[ $prompt == "y" ]]; then - DEV="y" -else - DEV="n" -fi - msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt -if [[ $DEV == "y" ]]; then -$STD git fetch origin dev -$STD git checkout dev -$STD git pull -fi $STD npm ci msg_ok "Installed Zigbee2MQTT" From b816b9fc2df9186a0ed2ae7065755ea067571761 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 17:47:51 -0500 Subject: [PATCH 5794/6505] Update zigbee2mqtt-install.sh test `dev` branch --- install/zigbee2mqtt-install.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 277ce6ad..fa94476f 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -40,8 +40,20 @@ msg_info "Setting up Zigbee2MQTT Repository" $STD git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt msg_ok "Set up Zigbee2MQTT Repository" +read -r -p "Switch to Edge/dev branch? (y/N) " prompt +if [[ $prompt == "y" ]]; then + DEV="y" +else + DEV="n" +fi + msg_info "Installing Zigbee2MQTT" cd /opt/zigbee2mqtt +if [[ $DEV == "y" ]]; then +$STD git fetch origin dev:dev +$STD git checkout dev +$STD git pull +fi $STD npm ci msg_ok "Installed Zigbee2MQTT" From 2997b2f911aad8c564d6162182aa72f24fee4634 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 22:24:33 -0500 Subject: [PATCH 5795/6505] Update build.func fixes https://github.com/tteck/Proxmox/issues/2356 --- misc/build.func | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index c4d077ba..ef3eec77 100644 --- a/misc/build.func +++ b/misc/build.func @@ -572,7 +572,11 @@ EOF pct start "$CTID" msg_ok "Started LXC Container" if [ "$var_os" == "alpine" ]; then - sleep 2 + sleep 3 + pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories +http://dl-cdn.alpinelinux.org/alpine/latest-stable/main +http://dl-cdn.alpinelinux.org/alpine/latest-stable/community +EOF' pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit From 79b29951d7fd2e23db42b31b6a90cc5750454bd0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jan 2024 22:29:34 -0500 Subject: [PATCH 5796/6505] Update alpine-install.func moved to `build.func` --- misc/alpine-install.func | 4 ---- 1 file changed, 4 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 16bde1d4..3820d637 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -71,10 +71,6 @@ setting_up_container() { echo -e " 🖧 Check Network Settings" exit 1 fi - cat </etc/apk/repositories -https://dl-cdn.alpinelinux.org/alpine/latest-stable/main -https://dl-cdn.alpinelinux.org/alpine/latest-stable/community -EOF msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" } From 4b723d5a3f6eb4f96682dfd74866545a2c156157 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jan 2024 03:52:36 -0500 Subject: [PATCH 5797/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26921c38..03995e5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-17 + +### Changed + +- **ntfy LXC** + - NEW Script + ## 2024-01-16 ### Changed From f6e17e85768302d7d3b27a4c9118b4e63624be33 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jan 2024 12:48:15 -0500 Subject: [PATCH 5798/6505] Update sonarr-install.sh Change user:group from sonarr:media to root:root --- install/sonarr-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index 820b74f1..7f98864b 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -21,10 +21,7 @@ $STD apt-get install -y sqlite3 msg_ok "Installed Dependencies" msg_info "Installing Sonarr v4" -$STD groupadd media -$STD adduser --system --no-create-home --ingroup media sonarr mkdir -p /var/lib/sonarr/ -chown -R sonarr:media /var/lib/sonarr/ chmod 775 /var/lib/sonarr/ wget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=x64' tar -xzf SonarrV4.tar.gz @@ -39,9 +36,6 @@ cat </etc/systemd/system/sonarr.service Description=Sonarr Daemon After=syslog.target network.target [Service] -User=sonarr -Group=media -UMask=0002 Type=simple ExecStart=/opt/Sonarr/Sonarr -nobrowser -data=/var/lib/sonarr/ TimeoutStopSec=20 From 7aa885e220011524df29d29899304c6eb7126a01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jan 2024 14:00:59 -0500 Subject: [PATCH 5799/6505] Create hyperhdr-install.sh --- install/hyperhdr-install.sh | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 install/hyperhdr-install.sh diff --git a/install/hyperhdr-install.sh b/install/hyperhdr-install.sh new file mode 100644 index 00000000..4ced651b --- /dev/null +++ b/install/hyperhdr-install.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +msg_ok "Installed Dependencies" + +msg_info "Installing HyperHDR" +curl -fsSL https://awawa-dev.github.io/hyperhdr.public.apt.gpg.key >/usr/share/keyrings/hyperhdr.public.apt.gpg.key +chmod go+r /usr/share/keyrings/hyperhdr.public.apt.gpg.key +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hyperhdr.public.apt.gpg.key] https://awawa-dev.github.io $(awk -F= '/VERSION_CODENAME/ {print $2}' /etc/os-release) main" >/etc/apt/sources.list.d/hyperhdr.list +$STD apt-get update +$STD apt-get install -y hyperhdr +msg_ok "Installed HyperHDR" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From d5d245cf47792ea89efd3589d0083570732b2d65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jan 2024 14:01:29 -0500 Subject: [PATCH 5800/6505] Create hyperhdr.sh --- ct/hyperhdr.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ct/hyperhdr.sh diff --git a/ct/hyperhdr.sh b/ct/hyperhdr.sh new file mode 100644 index 00000000..233d7130 --- /dev/null +++ b/ct/hyperhdr.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ __ ______ ____ + / / / /_ ______ ___ _____/ / / / __ \/ __ \ + / /_/ / / / / __ \/ _ \/ ___/ /_/ / / / / /_/ / + / __ / /_/ / /_/ / __/ / / __ / /_/ / _, _/ +/_/ /_/\__, / .___/\___/_/ /_/ /_/_____/_/ |_| + /____/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="HyperHDR" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8090${CL} \n" From 2699f254575b7b91e3627a087412c91d750ace01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jan 2024 14:17:07 -0500 Subject: [PATCH 5801/6505] Update hyperhdr-install.sh Create service file --- install/hyperhdr-install.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/install/hyperhdr-install.sh b/install/hyperhdr-install.sh index 4ced651b..bca1ce2c 100644 --- a/install/hyperhdr-install.sh +++ b/install/hyperhdr-install.sh @@ -28,6 +28,24 @@ $STD apt-get update $STD apt-get install -y hyperhdr msg_ok "Installed HyperHDR" +msg_info "Creating Service" +cat </etc/systemd/system/hyperhdr.service +[Unit] +Description=HyperHDR Service +After=syslog.target network.target + +[Service] +Restart=on-failure +RestartSec=5 +Type=simple +ExecStart=/usr/bin/hyperhdr + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now hyperhdr +msg_ok "Created Service" + motd_ssh customize From ea9fe637c504a41a8b566572ada87f94e763dd55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jan 2024 14:36:28 -0500 Subject: [PATCH 5802/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03995e5a..c1993d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - **ntfy LXC** - NEW Script +- **HyperHDR LXC** + - NEW Script ## 2024-01-16 From 8ef47c526f18010c9cac0d610f3880e86cbe9af1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 Jan 2024 05:06:54 -0500 Subject: [PATCH 5803/6505] Update netdata.sh fixes https://github.com/tteck/Proxmox/issues/2359 --- misc/netdata.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/netdata.sh b/misc/netdata.sh index 3596f049..885cd42d 100644 --- a/misc/netdata.sh +++ b/misc/netdata.sh @@ -95,7 +95,7 @@ uninstall() { } if ! pveversion | grep -Eq "pve-manager/(8\.[0-9])"; then - msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE Version 8.0 or higher" echo -e "Exiting..." sleep 2 From c3bc20be71ec481f72bd28a3d6764823855ac513 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 Jan 2024 05:33:17 -0500 Subject: [PATCH 5804/6505] Update hyperhdr.sh tweak --- ct/hyperhdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/hyperhdr.sh b/ct/hyperhdr.sh index 233d7130..c32c168a 100644 --- a/ct/hyperhdr.sh +++ b/ct/hyperhdr.sh @@ -30,7 +30,7 @@ color catch_errors function default_settings() { - CT_TYPE="1" + CT_TYPE="0" PW="" CT_ID=$NEXTID HN=$NSAPP From 1459ffdb6fe99a848fd7e700e073233f73284b30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 Jan 2024 17:15:38 -0500 Subject: [PATCH 5805/6505] Update alpine-zigbee2mqtt-install.sh fix Zigbee2MQTT not starting --- install/alpine-zigbee2mqtt-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/alpine-zigbee2mqtt-install.sh b/install/alpine-zigbee2mqtt-install.sh index 2c805f23..078bc595 100644 --- a/install/alpine-zigbee2mqtt-install.sh +++ b/install/alpine-zigbee2mqtt-install.sh @@ -23,7 +23,8 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Zigbee2MQTT" $STD apk add zigbee2mqtt +sed -i -e 's/#datadir="\/var\/lib\/zigbee2mqtt"/datadir="\/etc\/zigbee2mqtt"/' -e 's/#command_user="zigbee2mqtt"/command_user="zigbee2mqtt"/' /etc/conf.d/zigbee2mqtt msg_ok "Installed Alpine-Zigbee2MQTT" motd_ssh -customize \ No newline at end of file +customize From ba752674f36bd388641056a498ef2a6261241ee2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 Jan 2024 17:25:48 -0500 Subject: [PATCH 5806/6505] Update alpine-zigbee2mqtt-install.sh restart service after `sed` command --- install/alpine-zigbee2mqtt-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-zigbee2mqtt-install.sh b/install/alpine-zigbee2mqtt-install.sh index 078bc595..cb5bb356 100644 --- a/install/alpine-zigbee2mqtt-install.sh +++ b/install/alpine-zigbee2mqtt-install.sh @@ -24,6 +24,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Zigbee2MQTT" $STD apk add zigbee2mqtt sed -i -e 's/#datadir="\/var\/lib\/zigbee2mqtt"/datadir="\/etc\/zigbee2mqtt"/' -e 's/#command_user="zigbee2mqtt"/command_user="zigbee2mqtt"/' /etc/conf.d/zigbee2mqtt +$STD rc-service zigbee2mqtt restart msg_ok "Installed Alpine-Zigbee2MQTT" motd_ssh From 638babe5c3d8076b456b1f968d2e1a76da48ea9c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 Jan 2024 19:41:25 -0500 Subject: [PATCH 5807/6505] Update alpine-zigbee2mqtt-install.sh tweaks --- install/alpine-zigbee2mqtt-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/install/alpine-zigbee2mqtt-install.sh b/install/alpine-zigbee2mqtt-install.sh index cb5bb356..a98f1da5 100644 --- a/install/alpine-zigbee2mqtt-install.sh +++ b/install/alpine-zigbee2mqtt-install.sh @@ -23,7 +23,11 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Zigbee2MQTT" $STD apk add zigbee2mqtt -sed -i -e 's/#datadir="\/var\/lib\/zigbee2mqtt"/datadir="\/etc\/zigbee2mqtt"/' -e 's/#command_user="zigbee2mqtt"/command_user="zigbee2mqtt"/' /etc/conf.d/zigbee2mqtt +mkdir -p /root/.z2m +ln -s /etc/zigbee2mqtt/ /root/.z2m +chown -R root:root /etc/zigbee2mqtt /root/.z2m +sed -i -e 's/#datadir="\/var\/lib\/zigbee2mqtt"/datadir="\/etc\/zigbee2mqtt"/' -e 's/#command_user="zigbee2mqtt"/command_user="root"/' /etc/conf.d/zigbee2mqtt +$STD rc-update add zigbee2mqtt $STD rc-service zigbee2mqtt restart msg_ok "Installed Alpine-Zigbee2MQTT" From 435de786c5873d053aac430f4fd3f6441e9e62ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 18 Jan 2024 23:58:55 -0500 Subject: [PATCH 5808/6505] Update nginxproxymanager.sh fixes https://github.com/tteck/Proxmox/issues/2362 --- ct/nginxproxymanager.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 3456304e..bfdcf8bf 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -136,6 +136,7 @@ function update_script() { msg_info "Building Frontend" cd ./frontend export NODE_ENV=development + yarn add -D sass-loader@10.5.2 &>/dev/null yarn install --network-timeout=30000 &>/dev/null yarn build &>/dev/null cp -r dist/* /app/frontend From d2b5fc83447f8e302601835289339d7e27a579bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Jan 2024 00:01:21 -0500 Subject: [PATCH 5809/6505] Update nginxproxymanager-install.sh - set sass-loader version --- install/nginxproxymanager-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index fcf6ebc7..2d0973d8 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -134,6 +134,7 @@ msg_ok "Set up Enviroment" msg_info "Building Frontend" cd ./frontend export NODE_ENV=development +$STD yarn add -D sass-loader@10.5.2 $STD yarn install --network-timeout=30000 $STD yarn build cp -r dist/* /app/frontend From c60490b8ba2ec03d7f3c518622022092a0c329f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Jan 2024 00:03:20 -0500 Subject: [PATCH 5810/6505] Update nginxproxymanager.sh - Reboot LXC if no GUI --- ct/nginxproxymanager.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index bfdcf8bf..675d59a1 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -186,4 +186,5 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:81${CL} \n" + ${BL}http://${IP}:81${CL} + Reboot LXC if no GUI\n" From 6f4501c7a31f12804dd5ae35ebd4cf33c8931beb Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Jan 2024 00:16:02 -0500 Subject: [PATCH 5811/6505] Update nginxproxymanager.sh tweak --- ct/nginxproxymanager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 675d59a1..98a62e86 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -187,4 +187,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:81${CL} - Reboot LXC if no GUI\n" + ${RD}Reboot LXC if no GUI${CL}\n" From 052b2f398294b5a055276ea5956d61688d0d2ab6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Jan 2024 13:17:58 -0500 Subject: [PATCH 5812/6505] Update haos-vm.sh - Change spinner --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index d60fd484..c4f54130 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -75,7 +75,7 @@ fi function spinner() { printf "\e[?25l" - spinner="/-\\|/-\\|" + spinner="◐◓◑◒" spin_i=0 while true; do printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" From e6e2b988544ce26c20c5056298d499cce5656945 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Jan 2024 20:55:44 -0500 Subject: [PATCH 5813/6505] Update apt-cacher-ng-install.sh remove space in sed command --- install/apt-cacher-ng-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/apt-cacher-ng-install.sh b/install/apt-cacher-ng-install.sh index fa131ef8..1d7572c2 100644 --- a/install/apt-cacher-ng-install.sh +++ b/install/apt-cacher-ng-install.sh @@ -21,7 +21,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Apt-Cacher NG" DEBIAN_FRONTEND=noninteractive $STD apt-get -o Dpkg::Options::="--force-confold" install -y apt-cacher-ng -sed -i 's/# PassThroughPattern: .* # this would allow CONNECT to everything/PassThroughPattern: .* /' /etc/apt-cacher-ng/acng.conf +sed -i 's/# PassThroughPattern: .* # this would allow CONNECT to everything/PassThroughPattern: .*/' /etc/apt-cacher-ng/acng.conf systemctl enable -q --now apt-cacher-ng msg_ok "Installed Apt-Cacher NG" From 1e713d7b7b3371502ddd2f1b68f2f6d0de038aba Mon Sep 17 00:00:00 2001 From: Madhur Ahuja Date: Sat, 20 Jan 2024 18:14:00 +0530 Subject: [PATCH 5814/6505] Add Cassandra script (#2367) --------- Co-authored-by: @madhur --- ct/cassandra.sh | 66 ++++++++++++++++++++++++++++++++++++ install/cassandra-install.sh | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 ct/cassandra.sh create mode 100644 install/cassandra-install.sh diff --git a/ct/cassandra.sh b/ct/cassandra.sh new file mode 100644 index 00000000..c47f0655 --- /dev/null +++ b/ct/cassandra.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ __ + / ____/___ _______________ _____ ____/ /________ _ + / / / __ `/ ___/ ___/ __ `/ __ \/ __ / ___/ __ `/ +/ /___/ /_/ (__ |__ ) /_/ / / / / /_/ / / / /_/ / +\____/\__,_/____/____/\__,_/_/ /_/\__,_/_/ \__,_/ +EOF +} +header_info +echo -e "Loading..." +APP="Cassandra" +var_disk="4" +var_cpu="1" +var_ram="2048" +var_os="debian" +var_version="12" +VERBOSE="yes" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/cassandra.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh new file mode 100644 index 00000000..15f05f91 --- /dev/null +++ b/install/cassandra-install.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y apt-transport-https +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing OpenJDK" +wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg +echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list +$STD apt-get update +$STD apt-get install -y temurin-8-jdk +msg_ok "Installed OpenJDK" + +msg_info "Installing Cassandra" +release=$(curl -s https://cassandra.apache.org/_/download.html | grep -oP '(?<=/cassandra/)[0-9]+\.[0-9]+\.[0-9]+' | head -n 1) +wget -qO- https://dlcdn.apache.org/cassandra/$release/apache-cassandra-${release}-bin.tar.gz | tar -xz -C /opt +mv /opt/apache-cassandra-${release} /opt/cassandra +sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /opt/cassandra/conf/cassandra.yaml +msg_ok "Installed Cassandra" + +msg_info "Creating Service" +cat </etc/systemd/system/cassandra.service +[Unit] +Description=Cassandra +After=network.target + +[Service] +PIDFile=/tmp/cassandra.pid +ExecStart=/opt/cassandra/bin/cassandra -p /tmp/cassandra.pid -R +StandardOutput=append:/tmp/cassandra.log +StandardError=append:/tmp/cassandra-error.log +LimitNOFILE=100000 +LimitMEMLOCK=infinity +LimitNPROC=32768 +LimitAS=infinity + +[Install] +WantedBy=default.target +EOF +systemctl enable -q --now cassandra.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 889ad6bc18262fb2b7cb783488111e4e41875316 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 07:53:49 -0500 Subject: [PATCH 5815/6505] Update cassandra.sh tweak --- ct/cassandra.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/cassandra.sh b/ct/cassandra.sh index c47f0655..ce6d27c2 100644 --- a/ct/cassandra.sh +++ b/ct/cassandra.sh @@ -8,11 +8,12 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ __ + ______ __ / ____/___ _______________ _____ ____/ /________ _ / / / __ `/ ___/ ___/ __ `/ __ \/ __ / ___/ __ `/ -/ /___/ /_/ (__ |__ ) /_/ / / / / /_/ / / / /_/ / -\____/\__,_/____/____/\__,_/_/ /_/\__,_/_/ \__,_/ +/ /___/ /_/ (__ |__ ) /_/ / / / / /_/ / / / /_/ / +\____/\__,_/____/____/\__,_/_/ /_/\__,_/_/ \__,_/ + EOF } header_info From 8f53044d24264ed3427feabfd52a9a0e54110647 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 08:48:48 -0500 Subject: [PATCH 5816/6505] Update cassandra-install.sh test alternative installation method --- install/cassandra-install.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh index 15f05f91..cc045709 100644 --- a/install/cassandra-install.sh +++ b/install/cassandra-install.sh @@ -29,10 +29,14 @@ $STD apt-get install -y temurin-8-jdk msg_ok "Installed OpenJDK" msg_info "Installing Cassandra" -release=$(curl -s https://cassandra.apache.org/_/download.html | grep -oP '(?<=/cassandra/)[0-9]+\.[0-9]+\.[0-9]+' | head -n 1) -wget -qO- https://dlcdn.apache.org/cassandra/$release/apache-cassandra-${release}-bin.tar.gz | tar -xz -C /opt -mv /opt/apache-cassandra-${release} /opt/cassandra -sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /opt/cassandra/conf/cassandra.yaml +#release=$(curl -s https://cassandra.apache.org/_/download.html | grep -oP '(?<=/cassandra/)[0-9]+\.[0-9]+\.[0-9]+' | head -n 1) +#wget -qO- https://dlcdn.apache.org/cassandra/$release/apache-cassandra-${release}-bin.tar.gz | tar -xz -C /opt +#mv /opt/apache-cassandra-${release} /opt/cassandra +#sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /opt/cassandra/conf/cassandra.yaml +wget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg +echo "deb https://debian.cassandra.apache.org 41x main" >/etc/apt/sources.list.d/cassandra.sources.list +$STD apt-get update +$STD apt-get cassandra cassandra-tools msg_ok "Installed Cassandra" msg_info "Creating Service" From 9675c2259af126f740f9c8c6b2d33fd18471bc8f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 08:52:42 -0500 Subject: [PATCH 5817/6505] Update cassandra-install.sh --- install/cassandra-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh index cc045709..7acf1666 100644 --- a/install/cassandra-install.sh +++ b/install/cassandra-install.sh @@ -36,7 +36,7 @@ msg_info "Installing Cassandra" wget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg echo "deb https://debian.cassandra.apache.org 41x main" >/etc/apt/sources.list.d/cassandra.sources.list $STD apt-get update -$STD apt-get cassandra cassandra-tools +$STD apt-get install cassandra cassandra-tools msg_ok "Installed Cassandra" msg_info "Creating Service" From c550d996bb4998e90df02811efa718e1a909e2a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 08:54:08 -0500 Subject: [PATCH 5818/6505] Update cassandra-install.sh --- install/cassandra-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh index 7acf1666..e0fb0c40 100644 --- a/install/cassandra-install.sh +++ b/install/cassandra-install.sh @@ -25,7 +25,7 @@ msg_info "Installing OpenJDK" wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list $STD apt-get update -$STD apt-get install -y temurin-8-jdk +$STD apt-get install -y temurin-11-jdk msg_ok "Installed OpenJDK" msg_info "Installing Cassandra" From b1dc1b8ea09b9afc01ba06c8c39938daddbe3b70 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 08:57:31 -0500 Subject: [PATCH 5819/6505] Update cassandra-install.sh --- install/cassandra-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh index e0fb0c40..5fb63419 100644 --- a/install/cassandra-install.sh +++ b/install/cassandra-install.sh @@ -36,7 +36,7 @@ msg_info "Installing Cassandra" wget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg echo "deb https://debian.cassandra.apache.org 41x main" >/etc/apt/sources.list.d/cassandra.sources.list $STD apt-get update -$STD apt-get install cassandra cassandra-tools +$STD apt-get install -y cassandra cassandra-tools msg_ok "Installed Cassandra" msg_info "Creating Service" From 71cafc9d0f3934085cdcdc2c55ec61802f6f60ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:11:09 -0500 Subject: [PATCH 5820/6505] Update cassandra-install.sh finalize installation --- install/cassandra-install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh index 5fb63419..a26e7dd1 100644 --- a/install/cassandra-install.sh +++ b/install/cassandra-install.sh @@ -29,14 +29,11 @@ $STD apt-get install -y temurin-11-jdk msg_ok "Installed OpenJDK" msg_info "Installing Cassandra" -#release=$(curl -s https://cassandra.apache.org/_/download.html | grep -oP '(?<=/cassandra/)[0-9]+\.[0-9]+\.[0-9]+' | head -n 1) -#wget -qO- https://dlcdn.apache.org/cassandra/$release/apache-cassandra-${release}-bin.tar.gz | tar -xz -C /opt -#mv /opt/apache-cassandra-${release} /opt/cassandra -#sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /opt/cassandra/conf/cassandra.yaml wget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg echo "deb https://debian.cassandra.apache.org 41x main" >/etc/apt/sources.list.d/cassandra.sources.list $STD apt-get update $STD apt-get install -y cassandra cassandra-tools +sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /etc/cassandra/cassandra.yaml msg_ok "Installed Cassandra" msg_info "Creating Service" From 967880c664304a32772fd97fc7d1d04011468333 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:13:32 -0500 Subject: [PATCH 5821/6505] Update cassandra-install.sh test without service file --- install/cassandra-install.sh | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh index a26e7dd1..5926b525 100644 --- a/install/cassandra-install.sh +++ b/install/cassandra-install.sh @@ -37,25 +37,8 @@ sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_int msg_ok "Installed Cassandra" msg_info "Creating Service" -cat </etc/systemd/system/cassandra.service -[Unit] -Description=Cassandra -After=network.target -[Service] -PIDFile=/tmp/cassandra.pid -ExecStart=/opt/cassandra/bin/cassandra -p /tmp/cassandra.pid -R -StandardOutput=append:/tmp/cassandra.log -StandardError=append:/tmp/cassandra-error.log -LimitNOFILE=100000 -LimitMEMLOCK=infinity -LimitNPROC=32768 -LimitAS=infinity - -[Install] -WantedBy=default.target -EOF -systemctl enable -q --now cassandra.service +#systemctl enable -q --now cassandra.service msg_ok "Created Service" motd_ssh From d0b60329f619c1a48d7be2da17674494ccf80519 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:23:21 -0500 Subject: [PATCH 5822/6505] Update cassandra-install.sh tweak --- install/cassandra-install.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/install/cassandra-install.sh b/install/cassandra-install.sh index 5926b525..76953f73 100644 --- a/install/cassandra-install.sh +++ b/install/cassandra-install.sh @@ -18,7 +18,7 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y apt-transport-https -$STD apt-get install -y gnupg +$STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Installing OpenJDK" @@ -36,11 +36,6 @@ $STD apt-get install -y cassandra cassandra-tools sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /etc/cassandra/cassandra.yaml msg_ok "Installed Cassandra" -msg_info "Creating Service" - -#systemctl enable -q --now cassandra.service -msg_ok "Created Service" - motd_ssh customize From 15b22bfc6922c533d327fd9c42755a08abee80d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:35:30 -0500 Subject: [PATCH 5823/6505] Update and rename cassandra.sh to apache-cassandra.sh tweak --- ct/{cassandra.sh => apache-cassandra.sh} | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) rename ct/{cassandra.sh => apache-cassandra.sh} (68%) diff --git a/ct/cassandra.sh b/ct/apache-cassandra.sh similarity index 68% rename from ct/cassandra.sh rename to ct/apache-cassandra.sh index ce6d27c2..35f83dff 100644 --- a/ct/cassandra.sh +++ b/ct/apache-cassandra.sh @@ -8,17 +8,18 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ __ - / ____/___ _______________ _____ ____/ /________ _ - / / / __ `/ ___/ ___/ __ `/ __ \/ __ / ___/ __ `/ -/ /___/ /_/ (__ |__ ) /_/ / / / / /_/ / / / /_/ / -\____/\__,_/____/____/\__,_/_/ /_/\__,_/_/ \__,_/ + ___ __ ______ __ + / | ____ ____ ______/ /_ ___ / ____/___ _______________ _____ ____/ /________ _ + / /| | / __ \/ __ `/ ___/ __ \/ _ \ / / / __ `/ ___/ ___/ __ `/ __ \/ __ / ___/ __ `/ + / ___ |/ /_/ / /_/ / /__/ / / / __/ / /___/ /_/ (__ |__ ) /_/ / / / / /_/ / / / /_/ / +/_/ |_/ .___/\__,_/\___/_/ /_/\___/ \____/\__,_/____/____/\__,_/_/ /_/\__,_/_/ \__,_/ + /_/ EOF } header_info echo -e "Loading..." -APP="Cassandra" +APP="Apache-Cassandra" var_disk="4" var_cpu="1" var_ram="2048" From 47c52291f729728a4ab8a10d8cd60061e8592295 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:36:13 -0500 Subject: [PATCH 5824/6505] Rename cassandra-install.sh to apache-cassandra-install.sh tweak --- install/{cassandra-install.sh => apache-cassandra-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename install/{cassandra-install.sh => apache-cassandra-install.sh} (100%) diff --git a/install/cassandra-install.sh b/install/apache-cassandra-install.sh similarity index 100% rename from install/cassandra-install.sh rename to install/apache-cassandra-install.sh From 7dec63e129e6621e3b9bb2b2effb2ea78e2130e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:36:52 -0500 Subject: [PATCH 5825/6505] Update apache-cassandra-install.sh tweak --- install/apache-cassandra-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/apache-cassandra-install.sh b/install/apache-cassandra-install.sh index 76953f73..8068e81f 100644 --- a/install/apache-cassandra-install.sh +++ b/install/apache-cassandra-install.sh @@ -28,13 +28,13 @@ $STD apt-get update $STD apt-get install -y temurin-11-jdk msg_ok "Installed OpenJDK" -msg_info "Installing Cassandra" +msg_info "Installing Apache Cassandra" wget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg echo "deb https://debian.cassandra.apache.org 41x main" >/etc/apt/sources.list.d/cassandra.sources.list $STD apt-get update $STD apt-get install -y cassandra cassandra-tools sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /etc/cassandra/cassandra.yaml -msg_ok "Installed Cassandra" +msg_ok "Installed Apache Cassandra" motd_ssh customize From 54093612da7b8882955754693dbd74595871097c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:45:29 -0500 Subject: [PATCH 5826/6505] Update apache-cassandra-install.sh tweak --- install/apache-cassandra-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/apache-cassandra-install.sh b/install/apache-cassandra-install.sh index 8068e81f..0cc837f0 100644 --- a/install/apache-cassandra-install.sh +++ b/install/apache-cassandra-install.sh @@ -21,12 +21,12 @@ $STD apt-get install -y apt-transport-https $STD apt-get install -y gpg msg_ok "Installed Dependencies" -msg_info "Installing OpenJDK" +msg_info "Installing Eclipse Temurin" wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list $STD apt-get update -$STD apt-get install -y temurin-11-jdk -msg_ok "Installed OpenJDK" +$STD apt-get install -y temurin-11-jdk-headless +msg_ok "Installed Eclipse Temurin" msg_info "Installing Apache Cassandra" wget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg From 7c65d49f045e5681cf38eec2fd22d25356e20ff7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 09:47:45 -0500 Subject: [PATCH 5827/6505] Update apache-cassandra-install.sh --- install/apache-cassandra-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/apache-cassandra-install.sh b/install/apache-cassandra-install.sh index 0cc837f0..070a773f 100644 --- a/install/apache-cassandra-install.sh +++ b/install/apache-cassandra-install.sh @@ -25,7 +25,7 @@ msg_info "Installing Eclipse Temurin" wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list $STD apt-get update -$STD apt-get install -y temurin-11-jdk-headless +$STD apt-get install -y temurin-11-jdk msg_ok "Installed Eclipse Temurin" msg_info "Installing Apache Cassandra" From 4653d4f81829d1d7a3f37b0be433031a1764d5ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 10:03:05 -0500 Subject: [PATCH 5828/6505] Update apache-cassandra-install.sh tweak --- install/apache-cassandra-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/apache-cassandra-install.sh b/install/apache-cassandra-install.sh index 070a773f..da0c1f40 100644 --- a/install/apache-cassandra-install.sh +++ b/install/apache-cassandra-install.sh @@ -21,7 +21,7 @@ $STD apt-get install -y apt-transport-https $STD apt-get install -y gpg msg_ok "Installed Dependencies" -msg_info "Installing Eclipse Temurin" +msg_info "Installing Eclipse Temurin (Patience)" wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list $STD apt-get update From 2806ab78f5b28b5f968ceaf06bb7f0ff93ffa29f Mon Sep 17 00:00:00 2001 From: Madhur Ahuja Date: Sat, 20 Jan 2024 21:12:09 +0530 Subject: [PATCH 5829/6505] Add script for redis (#2371) --- ct/redis.sh | 67 ++++++++++++++++++++++++++++++++++++++++ install/redis-install.sh | 40 ++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 ct/redis.sh create mode 100644 install/redis-install.sh diff --git a/ct/redis.sh b/ct/redis.sh new file mode 100644 index 00000000..c4621e20 --- /dev/null +++ b/ct/redis.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ ___ + / __ \___ ____/ (_)____ + / /_/ / _ \/ __ / / ___/ + / _, _/ __/ /_/ / (__ ) +/_/ |_|\___/\__,_/_/____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Redis" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +VERBOSE="yes" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /lib/systemd/system/redis-server.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/install/redis-install.sh b/install/redis-install.sh new file mode 100644 index 00000000..d62e7847 --- /dev/null +++ b/install/redis-install.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y apt-transport-https +$STD apt-get install -y gnupg +$STD apt-get install -y lsb-release +msg_ok "Installed Dependencies" + +msg_info "Installing Redis" +curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg +echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list +$STD apt-get update +$STD apt-get install -y redis +sed -i 's/^bind .*/bind 0.0.0.0/' /etc/redis/redis.conf +systemctl enable -q --now redis-server.service +msg_ok "Installed Redis" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From b971b48fe184a5cf961cf31e511281c6d3c4fd43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jan 2024 11:06:11 -0500 Subject: [PATCH 5830/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1993d52..c8106ee8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-20 + +### Changed + +- **Apache-Cassandra LXC** + - NEW Script +- **Redis LXC** + - NEW Script + ## 2024-01-17 ### Changed From 1a363ef9a579ec5eecb2e641bdd65952da7c9f06 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 04:23:22 -0500 Subject: [PATCH 5831/6505] Update haos-vm.sh tweak --- vm/haos-vm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index c4f54130..65733214 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -43,7 +43,7 @@ trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT function error_handler() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -91,14 +91,14 @@ function msg_info() { } function msg_ok() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } function msg_error() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" From 0d90ef3ea378cf04b7a4c4a7824888f9108e8de9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 04:28:42 -0500 Subject: [PATCH 5832/6505] Update build.func tweak --- misc/build.func | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index ef3eec77..e526ca57 100644 --- a/misc/build.func +++ b/misc/build.func @@ -27,7 +27,7 @@ catch_errors() { # This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message. error_handler() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -58,7 +58,7 @@ msg_info() { # This function displays a success message with a green color. msg_ok() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" @@ -66,7 +66,7 @@ msg_ok() { # This function displays a error message with a red color. msg_error() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" From 1782fad313daa8fef61bc919a63a666efa338e2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 04:30:01 -0500 Subject: [PATCH 5833/6505] Update install.func tweak --- misc/install.func | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/install.func b/misc/install.func index 380392a2..4f98236f 100644 --- a/misc/install.func +++ b/misc/install.func @@ -35,7 +35,7 @@ catch_errors() { # This function handles errors error_handler() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -69,7 +69,7 @@ msg_info() { # This function displays a success message with a green color. msg_ok() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" @@ -77,7 +77,7 @@ msg_ok() { # This function displays a error message with a red color. msg_error() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" @@ -167,4 +167,4 @@ EOF fi echo "bash -c \"\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\"" >/usr/bin/update chmod +x /usr/bin/update -} \ No newline at end of file +} From a6549aef642f037c14b550af2c1bb0344b697bbb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 04:31:14 -0500 Subject: [PATCH 5834/6505] Update create_lxc.sh tweak --- ct/create_lxc.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 9d41819d..010dffb8 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -25,7 +25,7 @@ trap 'error_handler $LINENO "$BASH_COMMAND"' ERR # This function handles errors function error_handler() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local exit_code="$?" local line_number="$1" @@ -55,7 +55,7 @@ function msg_info() { # This function displays a success message with a green color. function msg_ok() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CM} ${GN}${msg}${CL}" @@ -63,7 +63,7 @@ function msg_ok() { # This function displays a error message with a red color. function msg_error() { - if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID; fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi printf "\e[?25h" local msg="$1" echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" From 623f0b298b856e0e44138f7439c693b68f2b55b2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 05:43:47 -0500 Subject: [PATCH 5835/6505] Update nginxproxymanager-install.sh apply fixes --- install/nginxproxymanager-install.sh | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 2d0973d8..1c9d2972 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -79,8 +79,8 @@ ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx -sed -i "s+0.0.0+${RELEASE}+g" backend/package.json -sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json +sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json +sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") @@ -125,17 +125,12 @@ fi mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global -wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-noarch.tar.xz" -wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-x86_64.tar.xz" -tar -C / -Jxpf s6-overlay-noarch.tar.xz -tar -C / -Jxpf s6-overlay-x86_64.tar.xz msg_ok "Set up Enviroment" msg_info "Building Frontend" cd ./frontend -export NODE_ENV=development -$STD yarn add -D sass-loader@10.5.2 -$STD yarn install --network-timeout=30000 +$STD yarn install +$STD yarn upgrade $STD yarn build cp -r dist/* /app/frontend cp -r app-images/* /app/frontend/images @@ -189,12 +184,13 @@ customize msg_info "Starting Services" sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg -$STD systemctl enable --now openresty -$STD systemctl enable --now npm +systemctl enable -q --now openresty +systemctl enable -q --now npm msg_ok "Started Services" msg_info "Cleaning up" rm -rf ../nginx-proxy-manager-* s6-overlay-noarch.tar.xz s6-overlay-x86_64.tar.xz +systemctl restart openresty $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From a45c65cd145a3879a6f3ec8284cf7a0fe6943e50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 05:44:52 -0500 Subject: [PATCH 5836/6505] Update nginxproxymanager.sh apply fixes --- ct/nginxproxymanager.sh | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 98a62e86..1abfd3c6 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -86,8 +86,8 @@ function update_script() { ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx - sed -i "s+0.0.0+${RELEASE}+g" backend/package.json - sed -i "s+0.0.0+${RELEASE}+g" frontend/package.json + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do @@ -126,18 +126,13 @@ function update_script() { mkdir -p /app/global /app/frontend/images cp -r backend/* /app cp -r global/* /app/global - wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-noarch.tar.xz" - wget -q "https://github.com/just-containers/s6-overlay/releases/download/v3.1.5.0/s6-overlay-x86_64.tar.xz" - tar -C / -Jxpf s6-overlay-noarch.tar.xz - tar -C / -Jxpf s6-overlay-x86_64.tar.xz python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null msg_ok "Setup Enviroment" msg_info "Building Frontend" cd ./frontend - export NODE_ENV=development - yarn add -D sass-loader@10.5.2 &>/dev/null - yarn install --network-timeout=30000 &>/dev/null + yarn install &>/dev/null + yarn upgrade &>/dev/null yarn build &>/dev/null cp -r dist/* /app/frontend cp -r app-images/* /app/frontend/images @@ -186,5 +181,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:81${CL} - ${RD}Reboot LXC if no GUI${CL}\n" + ${BL}http://${IP}:81${CL}\n" From edf3803362cb7ad152fb386997def01edf5ef57e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 07:03:52 -0500 Subject: [PATCH 5837/6505] Update nginxproxymanager-install.sh - nvm v0.39.7 - node.js v16.20.2 - Transition to using pnpm instead of yarn. --- install/nginxproxymanager-install.sh | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 1c9d2972..fa50ec9b 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -54,15 +54,15 @@ $STD apt-get -y install openresty msg_ok "Installed Openresty" msg_info "Installing Node.js" -$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) +$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh) source ~/.bashrc -$STD nvm install 16.20.1 -ln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node +$STD nvm install 16.20.2 +ln -sf /root/.nvm/versions/node/v16.20.2/bin/node /usr/bin/node msg_ok "Installed Node.js" -msg_info "Installing Yarn" -$STD npm install -g yarn -msg_ok "Installed Yarn" +msg_info "Installing pnpm" +$STD npm install -g pnpm +msg_ok "Installed pnpm" RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | grep "tag_name" | @@ -129,9 +129,9 @@ msg_ok "Set up Enviroment" msg_info "Building Frontend" cd ./frontend -$STD yarn install -$STD yarn upgrade -$STD yarn build +$STD pnpm install +$STD pnpm upgrade +$STD pnpm run build cp -r dist/* /app/frontend cp -r app-images/* /app/frontend/images msg_ok "Built Frontend" @@ -154,8 +154,7 @@ if [ ! -f /app/config/production.json ]; then EOF fi cd /app -export NODE_ENV=development -$STD yarn install --network-timeout=30000 +$STD pnpm install msg_ok "Initialized Backend" msg_info "Creating Service" @@ -189,7 +188,7 @@ systemctl enable -q --now npm msg_ok "Started Services" msg_info "Cleaning up" -rm -rf ../nginx-proxy-manager-* s6-overlay-noarch.tar.xz s6-overlay-x86_64.tar.xz +rm -rf ../nginx-proxy-manager-* systemctl restart openresty $STD apt-get autoremove $STD apt-get autoclean From 9ef0ad7ec7ffce5d2402f971660779f141dab563 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 07:06:01 -0500 Subject: [PATCH 5838/6505] Update nginxproxymanager.sh - Transition to using pnpm instead of yarn. --- ct/nginxproxymanager.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 1abfd3c6..914613fd 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -129,11 +129,17 @@ function update_script() { python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null msg_ok "Setup Enviroment" + if ! command -v pnpm &> /dev/null; then + msg_info "Installing pnpm" + npm install -g pnpm &>/dev/null + msg_ok "Installed pnpm" + fi + msg_info "Building Frontend" cd ./frontend - yarn install &>/dev/null - yarn upgrade &>/dev/null - yarn build &>/dev/null + pnpm install &>/dev/null + pnpm upgrade &>/dev/null + pnpm run build &>/dev/null cp -r dist/* /app/frontend cp -r app-images/* /app/frontend/images msg_ok "Built Frontend" @@ -156,8 +162,7 @@ function update_script() { EOF fi cd /app - export NODE_ENV=development - yarn install --network-timeout=30000 &>/dev/null + pnpm install &>/dev/null msg_ok "Initialized Backend" msg_info "Starting Services" @@ -168,7 +173,7 @@ EOF msg_ok "Started Services" msg_info "Cleaning up" - rm -rf ~/nginx-proxy-manager-* s6-overlay-noarch.tar.xz s6-overlay-x86_64.tar.xz + rm -rf ~/nginx-proxy-manager-* msg_ok "Cleaned" msg_ok "Updated Successfully" From 14f4d9f852428e5ab1b5979387f541d63329c954 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 13:43:10 -0500 Subject: [PATCH 5839/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index fa50ec9b..52ee0e70 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -81,6 +81,8 @@ ln -sf /usr/local/openresty/nginx/ /etc/nginx sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json +sed -i 's|"fork-me": ".*"|"fork-me": "Proxmox VE Helper-Scripts"|' frontend/js/i18n/messages.json +sed -i "s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g" frontend/js/app/ui/footer/main.ejs sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") From bd3321fd8c55f4fcbb60e0d5a3776a100f216f43 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jan 2024 13:47:23 -0500 Subject: [PATCH 5840/6505] Update nginxproxymanager.sh tweak --- ct/nginxproxymanager.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 914613fd..4e286344 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -88,6 +88,8 @@ function update_script() { ln -sf /usr/local/openresty/nginx/ /etc/nginx sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json + sed -i 's|"fork-me": ".*"|"fork-me": "Proxmox VE Helper-Scripts"|' frontend/js/i18n/messages.json + sed -i "s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g" frontend/js/app/ui/footer/main.ejs sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do From e690bcf08ff2cd6fa3ae291dbfe1b8fa965cd5e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Jan 2024 04:39:31 -0500 Subject: [PATCH 5841/6505] Update agentdvr-install.sh - change service name - fixes https://github.com/tteck/Proxmox/issues/2379 --- install/agentdvr-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/agentdvr-install.sh b/install/agentdvr-install.sh index 239a57ff..69491da5 100644 --- a/install/agentdvr-install.sh +++ b/install/agentdvr-install.sh @@ -36,7 +36,7 @@ chmod +x ./Agent msg_ok "Installed AgentDVR" msg_info "Creating Service" -cat </etc/systemd/system/agentdvr.service +cat </etc/systemd/system/AgentDVR.service [Unit] Description=AgentDVR @@ -51,7 +51,7 @@ RestartSec=5 [Install] WantedBy=multi-user.target EOF -systemctl enable -q --now agentdvr.service +systemctl enable -q --now AgentDVR.service msg_ok "Created Service" motd_ssh From 3f5fc485e632d9552f9615b7fb2a42051e988ea2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Jan 2024 04:44:50 -0500 Subject: [PATCH 5842/6505] Update yunohost-install.sh fixes https://github.com/tteck/Proxmox/issues/2380 --- install/yunohost-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/yunohost-install.sh b/install/yunohost-install.sh index 606b0e21..0197eadb 100644 --- a/install/yunohost-install.sh +++ b/install/yunohost-install.sh @@ -24,6 +24,7 @@ $STD apt-get install -y ca-certificates msg_ok "Installed Dependencies" msg_info "Installing YunoHost (Patience)" +touch /etc/.pve-ignore.resolv.conf curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg $STD bash <(curl -fsSL https://install.yunohost.org) -a msg_ok "Installed YunoHost" From edd6eacdd3763c7eac7df9941505596851d4cd6e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Jan 2024 11:37:23 -0500 Subject: [PATCH 5843/6505] Update commafeed.sh add update path --- ct/commafeed.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ct/commafeed.sh b/ct/commafeed.sh index 0084964a..c5eeecad 100644 --- a/ct/commafeed.sh +++ b/ct/commafeed.sh @@ -55,7 +55,19 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/commafeed ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +msg_info "Stopping CommaFeed" +systemctl stop commafeed +msg_ok "Stopped CommaFeed" + +msg_info "Updating CommaFeed" +cd /opt/commafeed +rm commafeed.jar +wget -q https://github.com/Athou/commafeed/releases/latest/download/commafeed.jar +msg_ok "Updated CommaFeed" + +msg_info "Starting CommaFeed" +systemctl start commafeed +msg_ok "Update Completed Successfully" exit } From c1bd8facd14bbed1c33c28b5943207e8050489df Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Jan 2024 04:37:38 -0500 Subject: [PATCH 5844/6505] Update scrypted-install.sh node.js v20 --- install/scrypted-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 1e547297..79f0dba8 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -68,13 +68,12 @@ msg_ok "Installed GStreamer" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js/npm" $STD apt-get update $STD apt-get install -y nodejs -$STD apt-get install -y npm msg_ok "Installed Node.js/npm" msg_info "Updating Python3" From f227dc86843be23f95fe1ee3fd7e7372f367c381 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Jan 2024 05:22:04 -0500 Subject: [PATCH 5845/6505] Update scrypted-install.sh tweak --- install/scrypted-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 79f0dba8..60c05d38 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -71,10 +71,10 @@ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dea echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" -msg_info "Installing Node.js/npm" +msg_info "Installing Node.js" $STD apt-get update $STD apt-get install -y nodejs -msg_ok "Installed Node.js/npm" +msg_ok "Installed Node.js" msg_info "Updating Python3" $STD apt-get install -y \ From ecd7bd5dac99f9cbdf85067d16e31e17b8d2974a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Jan 2024 13:58:38 -0500 Subject: [PATCH 5846/6505] Update hyperhdr.sh fixes https://github.com/tteck/Proxmox/issues/2382 --- ct/hyperhdr.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/hyperhdr.sh b/ct/hyperhdr.sh index c32c168a..7c04a596 100644 --- a/ct/hyperhdr.sh +++ b/ct/hyperhdr.sh @@ -40,6 +40,8 @@ function default_settings() { BRG="vmbr0" NET="dhcp" GATE="" + APT_CACHER="" + APT_CACHER_IP="" DISABLEIP6="no" MTU="" SD="" From 241b7d019a55304071c4c34b6d353559786fee38 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Jan 2024 04:43:40 -0500 Subject: [PATCH 5847/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index eb514c7f..1e718f7d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -7,7 +7,7 @@ body: **IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure. - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. - If the default Linux distribution is not adhered to, script support will be discontinued. - - When encountering the error message `[ERROR] in line 24: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. + - When encountering the error message `[ERROR] in line 23: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. - For suggestions, questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions) - type: input id: guidelines From acec4f62939b86a1643f0cff0c0274d5d6297adf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Jan 2024 04:49:08 -0500 Subject: [PATCH 5848/6505] Update install.func tweak --- misc/install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index 4f98236f..739b5884 100644 --- a/misc/install.func +++ b/misc/install.func @@ -42,7 +42,7 @@ error_handler() { local command="$2" local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" echo -e "\n$error_message" - if [[ "$line_number" -eq 24 ]]; then + if [[ "$line_number" -eq 23 ]]; then echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n" fi } From f111479b006a86ee92e97c129a6c96e10dcfdcb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Jan 2024 12:39:50 -0500 Subject: [PATCH 5849/6505] Create new workflow --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..cbac5777 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: CI/CD + +on: + push: + branches: + - gh-pages + +jobs: + ci-cd: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: https://registry.npmjs.org/ + cache: npm + + - name: Install dependencies + run: npm install + + - name: Build and test + run: npm run build + + - name: Deploy to GitHub Pages + run: npm run deploy -- -m "Update GitHub Pages" From 2f2f297555c3ef1328c771d0a25710bb7db1e011 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Jan 2024 12:48:18 -0500 Subject: [PATCH 5850/6505] Update ci.yml tweak --- .github/workflows/ci.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cbac5777..8a34ea45 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,8 +9,13 @@ jobs: ci-cd: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - name: Checkout code + uses: actions/checkout@v3 + with: + node-version: 20 + + - name: Set up Node.js + uses: actions/setup-node@v3 with: node-version: 20 registry-url: https://registry.npmjs.org/ From d2f13f794067fa28c3cf7eb02ebf3b3becf68f65 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Jan 2024 12:51:09 -0500 Subject: [PATCH 5851/6505] Update ci.yml tweak --- .github/workflows/ci.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a34ea45..ad7c8af3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,11 +21,3 @@ jobs: registry-url: https://registry.npmjs.org/ cache: npm - - name: Install dependencies - run: npm install - - - name: Build and test - run: npm run build - - - name: Deploy to GitHub Pages - run: npm run deploy -- -m "Update GitHub Pages" From dc37502d1535945469f0024d0f2367518d6cb9a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 01:15:00 -0500 Subject: [PATCH 5852/6505] Update ci.yml --- .github/workflows/ci.yml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad7c8af3..dbd6cb68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: CI/CD +name: CI on: push: @@ -6,18 +6,8 @@ on: - gh-pages jobs: - ci-cd: + ci: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 - with: - node-version: 20 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 20 - registry-url: https://registry.npmjs.org/ - cache: npm - + uses: actions/checkout@v4 \ No newline at end of file From d094ffcfd30438d71374977eb20f0c9be74f571b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 01:29:36 -0500 Subject: [PATCH 5853/6505] Update ci.yml --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbd6cb68..2a483775 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,12 +2,13 @@ name: CI on: push: - branches: - - gh-pages + branches: [ "gh-pages" ] + + workflow_dispatch: jobs: - ci: + build: runs-on: ubuntu-latest + steps: - - name: Checkout code - uses: actions/checkout@v4 \ No newline at end of file + - uses: actions/checkout@v3 From 0c34f2ea9b6c63ef6dd639b6977f51d4c11a5759 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 01:49:53 -0500 Subject: [PATCH 5854/6505] Update ci.yml --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a483775..6972b44a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,8 @@ name: CI on: push: - branches: [ "gh-pages" ] + branches: + - gh-pages workflow_dispatch: From 86141db5e1ff5f36f35175f79f7b72dbf7cf9049 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 02:06:50 -0500 Subject: [PATCH 5855/6505] Update ci.yml --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6972b44a..8cb50a45 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,4 +12,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 20 + + - name: Checkout code + uses: actions/checkout@v3 From 928d13cb712b268c5d8eb89ffce974699c783ab1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 06:07:39 -0500 Subject: [PATCH 5856/6505] Update runtipi-install.sh fixes https://github.com/tteck/Proxmox/issues/2384 --- install/runtipi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/runtipi-install.sh b/install/runtipi-install.sh index f39dc1f4..584ea16b 100644 --- a/install/runtipi-install.sh +++ b/install/runtipi-install.sh @@ -25,9 +25,9 @@ mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" echo -e '{\n "log-driver": "journald"\n}' > "$DOCKER_CONFIG_PATH" cd /opt wget -q https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh -sed -i -e '/newgrp docker/d' -e '/exit 0/d' install.sh chmod +x install.sh $STD ./install.sh +chmod 666 /opt/runtipi/state/settings.json msg_ok "Installed Runtipi" motd_ssh From 09846607f21a7bbc94b6a7a5162419e06550ceb7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 12:15:19 -0500 Subject: [PATCH 5857/6505] Update unifi-install.sh fixes https://github.com/tteck/Proxmox/issues/2386 --- install/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 56423f9d..94807c3f 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -25,7 +25,7 @@ msg_info "Installing OpenJDK" wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list $STD apt-get update -$STD apt-get install -y temurin-17-jre +$STD apt-get install -y temurin-17-jdk msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" From 12c83f056f70a2212e6d903ec9b251504d28ca68 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 13:20:36 -0500 Subject: [PATCH 5858/6505] Create pairdrop-install.sh --- install/pairdrop-install.sh | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 install/pairdrop-install.sh diff --git a/install/pairdrop-install.sh b/install/pairdrop-install.sh new file mode 100644 index 00000000..8f8a8224 --- /dev/null +++ b/install/pairdrop-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y gpg +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing PairDrop" +git clone -q https://github.com/schlagmichdoch/PairDrop.git /opt/pairdrop +cd /opt/pairdrop +$STD npm install +msg_ok "Installed PairDrop" + +msg_info "Creating Service" +cat </etc/systemd/system/pairdrop.service +[Unit] +Description=PairDrop Service +After=network.target + +[Service] +ExecStart=npm start +WorkingDirectory=/opt/pairdrop +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now pairdrop.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 9d5d7ed3467cfae0285425c1bfc2d524bf03c272 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 13:21:45 -0500 Subject: [PATCH 5859/6505] Create pairdrop.sh --- ct/pairdrop.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 ct/pairdrop.sh diff --git a/ct/pairdrop.sh b/ct/pairdrop.sh new file mode 100644 index 00000000..a1680a8c --- /dev/null +++ b/ct/pairdrop.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ _ ____ + / __ \____ _(_)____/ __ \_________ ____ + / /_/ / __ `/ / ___/ / / / ___/ __ \/ __ \ + / ____/ /_/ / / / / /_/ / / / /_/ / /_/ / +/_/ \__,_/_/_/ /_____/_/ \____/ .___/ + /_/ +EOF +} +header_info +echo -e "Loading..." +APP="PairDrop" +var_disk="4" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/pairdrop ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +systemctl stop pairdrop +cd /opt/pairdrop +git pull +npm install +systemctl start pairdrop +msg_ok "Updated $APP" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From 702dbc7bbaded6d4a00e60dea5ecbad33f61a05c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Jan 2024 13:40:08 -0500 Subject: [PATCH 5860/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8106ee8..5fa38b2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-01-25 + +### Changed + +- **PairDrop LXC** + - NEW Script + ## 2024-01-20 ### Changed From 1597f560c7138397235dac6ca5dc54d19d96444d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Jan 2024 10:21:54 -0500 Subject: [PATCH 5861/6505] Update changedetection.sh When updating, update playwright also --- ct/changedetection.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 5fe9759a..e5fe9ecb 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -57,6 +57,7 @@ header_info if [[ ! -f /etc/systemd/system/changedetection.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" pip3 install changedetection.io --upgrade &>/dev/null +pip3 install playwright --upgrade &>/dev/null msg_ok "Updated Successfully" exit } From 67fa64069479a8fbd1796340425e35270add36be Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Jan 2024 13:17:04 -0500 Subject: [PATCH 5862/6505] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 36128c63..9a6ee17d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@
    - + + +

    Proxmox VE Helper-Scripts

    From 8a76e0b0d3003d20012294cbbef3098b9f6876f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Jan 2024 13:17:39 -0500 Subject: [PATCH 5863/6505] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index ae0755be..2b2bf02d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,5 +1,7 @@
    - + + +

    Contributing to Proxmox VE Helper Scripts

    From abac9a1952a42808b7a00e4bd898d16a14b053cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Jan 2024 13:18:07 -0500 Subject: [PATCH 5864/6505] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fa38b2a..6053f1a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@
    - + + +

    Change Log

    From f7ecf0028582cff40a7cd27c7fa860fd017dc08d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Jan 2024 13:18:30 -0500 Subject: [PATCH 5865/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 22d9c600..6e382223 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -1,5 +1,7 @@
    - + + +

    User Submitted Guides

    From 2a2dd14c9a4dd6622f8196193451e360d1978255 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Jan 2024 13:46:33 -0500 Subject: [PATCH 5866/6505] Update pimox-haos-vm.sh check for whiptail --- vm/pimox-haos-vm.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index 1347fcf6..f16a6338 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -71,6 +71,11 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null +if ! command -v whiptail &> /dev/null; then + echo "Installing whiptail..." + apt-get update &>/dev/null + apt-get install -y whiptail &>/dev/null +fi if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "PiMox HAOS VM" --yesno "This will create a New PiMox HAOS VM. Proceed?" 10 58); then echo "User selected Yes" else From 8d2e215c961fe427ca307eed22a2e41302022d8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 31 Jan 2024 17:27:20 -0500 Subject: [PATCH 5867/6505] Update homeassistant-core-install.sh Python 3.12.1 --- install/homeassistant-core-install.sh | 57 +++++++++++++-------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 3149cb0e..77e000f6 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies, (Patience)" +msg_info "Installing Dependencies (Patience)" $STD apt-get install -y \ git \ curl \ @@ -43,38 +43,35 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv - msg_ok "Updated Python3" -if [[ "$PCT_OSVERSION" == "11" ]]; then - msg_info "Installing pyenv" - $STD apt-get install -y \ - make \ - libreadline-dev \ - libsqlite3-dev \ - libncurses5-dev \ - libncursesw5-dev \ - xz-utils \ - tk-dev \ - llvm \ - libbz2-dev \ - libxml2-dev \ - libxmlsec1-dev \ - liblzma-dev - $STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv - set +e - echo 'export PYENV_ROOT="$HOME/.pyenv"' >>~/.bashrc - echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >>~/.bashrc - echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >>~/.bashrc - msg_ok "Installed pyenv" - . ~/.bashrc +msg_info "Installing pyenv" +$STD apt-get install -y \ + make \ + libreadline-dev \ + libsqlite3-dev \ + libncurses5-dev \ + libncursesw5-dev \ + xz-utils \ + tk-dev \ + llvm \ + libbz2-dev \ + libxml2-dev \ + libxmlsec1-dev \ + liblzma-dev +$STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv +set +e +echo 'export PYENV_ROOT="$HOME/.pyenv"' >>~/.bashrc +echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >>~/.bashrc +echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >>~/.bashrc +msg_ok "Installed pyenv" +. ~/.bashrc - set -e - msg_info "Installing Python 3.11.3 (Patience)" - $STD pyenv install 3.11.3 - pyenv global 3.11.3 - msg_ok "Installed Python 3.11.3" -fi +set -e +msg_info "Installing Python 3.12.1 (Patience)" +$STD pyenv install 3.12.1 +pyenv global 3.12.1 +msg_ok "Installed Python 3.12.1" msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant From 661411d8e8b091183521ee709280079eeb7ea685 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 1 Feb 2024 07:18:04 -0500 Subject: [PATCH 5868/6505] Update pialert-install.sh fixes https://github.com/tteck/Proxmox/issues/2415 --- install/pialert-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 195b16f4..0376ce94 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -19,12 +19,14 @@ $STD apt-get -y install \ mc \ curl \ apt-utils \ + avahi-utils \ lighttpd \ sqlite3 \ mmdb-bin \ arp-scan \ dnsutils \ net-tools \ + nbtscan \ libwww-perl \ nmap \ zip \ From 74c47c8b0793524ab2da45d3360960ea3c458c62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 2 Feb 2024 07:17:43 -0500 Subject: [PATCH 5869/6505] Create readeck.sh --- ct/readeck.sh | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ct/readeck.sh diff --git a/ct/readeck.sh b/ct/readeck.sh new file mode 100644 index 00000000..70a014c0 --- /dev/null +++ b/ct/readeck.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ __ + / __ \___ ____ _____/ /__ _____/ /__ + / /_/ / _ \/ __ `/ __ / _ \/ ___/ //_/ + / _, _/ __/ /_/ / /_/ / __/ /__/ ,< +/_/ |_|\___/\__,_/\__,_/\___/\___/_/|_| + +EOF +} +header_info +echo -e "Loading..." +APP="Readeck" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/readeck ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8000${CL}\n" From 65a9ed0aeaf781a9dd47fc164fe6095cd7a76232 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 2 Feb 2024 07:18:48 -0500 Subject: [PATCH 5870/6505] Create readeck-install.sh --- install/readeck-install.sh | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 install/readeck-install.sh diff --git a/install/readeck-install.sh b/install/readeck-install.sh new file mode 100644 index 00000000..2a1ead40 --- /dev/null +++ b/install/readeck-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Readeck" +mkdir -p /opt/readeck +cd /opt/readeck +wget -q -O readeck https://codeberg.org/readeck/readeck/releases/download/0.11.2/readeck-0.11.2-linux-amd64 +chmod a+x readeck +msg_ok "Installed Readeck" + +msg_info "Creating Service" +cat </etc/systemd/system/readeck.service +[Unit] +Description=Readeck Service +After=network.target + +[Service] +Environment=READECK_SERVER_HOST=0.0.0.0 +Environment=READECK_SERVER_PORT=8000 +ExecStart=/opt/readeck/./readeck serve +WorkingDirectory=/opt/readeck +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now readeck.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 29e012d282f0976b12f63d533e2c0b8b1f729aaf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 2 Feb 2024 07:33:17 -0500 Subject: [PATCH 5871/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6053f1a5..260110c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-02-02 + +### Changed + +- **Readeck LXC** + - NEW Script + ## 2024-01-25 ### Changed From 72de387b5ca9172208445ae192a479af46a1f9e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 2 Feb 2024 07:40:50 -0500 Subject: [PATCH 5872/6505] Update install.func update the script to include IPv6 connectivity considerations --- misc/install.func | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/misc/install.func b/misc/install.func index 739b5884..ba3c11df 100644 --- a/misc/install.func +++ b/misc/install.func @@ -112,16 +112,38 @@ setting_up_container() { network_check() { set +e trap - ERR - if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then msg_ok "Internet Connected"; else - msg_error "Internet NOT Connected" - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" +# Check if IPv4 is being used + if ip -o -4 addr show | grep -q "scope global"; then + if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then + msg_ok "IPv4 Internet Connected"; else - echo -e " 🖧 Check Network Settings" - exit 1 + msg_error "IPv4 Internet Not Connected"; + read -r -p "Would you like to continue anyway? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi fi fi + +# Check if IPv6 is being used + if ip -o -6 addr show | grep -q "scope global"; then + if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null; then + msg_ok "IPv6 Internet Connected"; + else + msg_error "IPv6 Internet Not Connected"; + read -r -p "Would you like to continue anyway? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" + else + echo -e " 🖧 Check Network Settings" + exit 1 + fi + fi + fi + RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }') if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}"; fi set -e From 5ed56e64d7080d97ccccf06d96f51642e01e01d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 2 Feb 2024 16:48:56 -0500 Subject: [PATCH 5873/6505] Update homeassistant-core-install.sh add `libavdevice-dev` `libavformat-dev` `libavcodec-dev` `libavutil-dev` `libavfilter-dev` dependencies --- install/homeassistant-core-install.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 77e000f6..6e4b4908 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -33,6 +33,11 @@ $STD apt-get install -y \ liblapack-dev \ dbus-broker \ libpcap-dev \ + libavdevice-dev \ + libavformat-dev \ + libavcodec-dev \ + libavutil-dev \ + libavfilter-dev \ libmariadb-dev-compat \ libatlas-base-dev msg_ok "Installed Dependencies" From f4b7aa6e4d5b8f0770536b503259cc1d5d645229 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 3 Feb 2024 14:02:13 -0500 Subject: [PATCH 5874/6505] Update dockge-install.sh tweak `homeassistant/compose.yaml` --- install/dockge-install.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/install/dockge-install.sh b/install/dockge-install.sh index d6985afd..f15949a4 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -62,19 +62,18 @@ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then msg_info "Adding Home Assistant compose.yaml" mkdir -p /opt/stacks/homeassistant cat </opt/stacks/homeassistant/compose.yaml -version: "3.3" +version: "3" services: - home-assistant: + homeassistant: container_name: homeassistant - privileged: true - restart: unless-stopped - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - /dev:/dev - - /etc/localtime:/etc/localtime:ro - - ./config:/config - network_mode: host image: ghcr.io/home-assistant/home-assistant:stable + volumes: + - ./config:/config + - /etc/localtime:/etc/localtime:ro + - /run/dbus:/run/dbus:ro + restart: unless-stopped + privileged: true + network_mode: host EOF msg_ok "Added Home Assistant compose.yaml" fi From 050015872794e556cb03653d13cf7e9894a5319d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Feb 2024 02:37:52 -0500 Subject: [PATCH 5875/6505] Update dockge-install.sh tweak Immich compose files --- install/dockge-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dockge-install.sh b/install/dockge-install.sh index f15949a4..235ae6fd 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -53,7 +53,7 @@ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then mkdir -p /opt/stacks/immich wget -q -O /opt/stacks/immich/compose.yaml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml wget -q -O /opt/stacks/immich/.env https://github.com/immich-app/immich/releases/latest/download/example.env - wget -q -O /opt/stacks/immich/hwaccel.yml https://github.com/immich-app/immich/releases/latest/download/hwaccel.yml + #wget -q -O /opt/stacks/immich/hwaccel.ml.yml https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml msg_ok "Added Immich compose.yaml" fi From 173b618fc892937e67f72dfd14ddc04376e20741 Mon Sep 17 00:00:00 2001 From: Bram Suurd <78373894+BramSuurdje@users.noreply.github.com> Date: Sun, 4 Feb 2024 21:49:15 +0100 Subject: [PATCH 5876/6505] Add option to install Unbound to Pi-hole (#2425) --- install/pihole-install.sh | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/install/pihole-install.sh b/install/pihole-install.sh index d6472459..f3c52e90 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -42,6 +42,64 @@ EOF $STD bash <(curl -fsSL https://install.pi-hole.net) --unattended msg_ok "Installed Pi-hole" +read -r -p "Would you like to add Unbound? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Installing Unbound" + $STD apt-get install -y unbound + cat </etc/unbound/unbound.conf.d/pi-hole.conf +server: + verbosity: 0 + interface: 0.0.0.0 + port: 5335 + do-ip6: no + do-ip4: yes + do-udp: yes + do-tcp: yes + num-threads: 1 + hide-identity: yes + hide-version: yes + harden-glue: yes + harden-dnssec-stripped: yes + harden-referral-path: yes + use-caps-for-id: no + harden-algo-downgrade: no + qname-minimisation: yes + aggressive-nsec: yes + rrset-roundrobin: yes + cache-min-ttl: 300 + cache-max-ttl: 14400 + msg-cache-slabs: 8 + rrset-cache-slabs: 8 + infra-cache-slabs: 8 + key-cache-slabs: 8 + serve-expired: yes + serve-expired-ttl: 3600 + edns-buffer-size: 1232 + prefetch: yes + prefetch-key: yes + target-fetch-policy: "3 2 1 1 1" + unwanted-reply-threshold: 10000000 + rrset-cache-size: 256m + msg-cache-size: 128m + so-rcvbuf: 1m + private-address: 192.168.0.0/16 + private-address: 169.254.0.0/16 + private-address: 172.16.0.0/12 + private-address: 10.0.0.0/8 + private-address: fd00::/8 + private-address: fe80::/10 +EOF + mkdir -p /etc/dnsmasq.d/ + cat </etc/dnsmasq.d/99-edns.conf +edns-packet-max=1232 +EOF + wget -q https://www.internic.net/domain/named.root >/var/lib/unbound/root.hints + sed -i -e 's/PIHOLE_DNS_1=8.8.8.8/PIHOLE_DNS_1=127.0.0.1#5335/' -e 's/PIHOLE_DNS_2=8.8.4.4/#PIHOLE_DNS_2=8.8.4.4/' /etc/pihole/setupVars.conf + systemctl enable -q --now unbound + systemctl restart pihole-FTL.service + msg_ok "Installed Unbound" +fi + motd_ssh customize From b054b86bf8ac55e67a8b621d309b6d6df8f2a7cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Feb 2024 15:54:17 -0500 Subject: [PATCH 5877/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 260110c5..edb40d35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-02-04 + +### Changed + +- **Pi-hole LXC** + - Option to add Unbound + ## 2024-02-02 ### Changed From 84b91141ff1433443892b4523f7b476540c13125 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Feb 2024 18:17:00 -0500 Subject: [PATCH 5878/6505] Update hyperion-install.sh fixes https://github.com/tteck/Proxmox/issues/2430 --- install/hyperion-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh index 04622a1d..19b8a88e 100644 --- a/install/hyperion-install.sh +++ b/install/hyperion-install.sh @@ -20,6 +20,8 @@ $STD apt-get install -y mc $STD apt-get install -y lsb-release $STD apt-get install -y gpg $STD apt-get install -y apt-transport-https +$STD apt-get install -y libpython3.9 + msg_ok "Installed Dependencies" msg_info "Installing Hyperion" From d09f40cfb5fd61964632a9493a8d47b0c00011ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Feb 2024 20:42:36 -0500 Subject: [PATCH 5879/6505] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index edb40d35..b8ddbd14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@

    All notable changes to this project will be documented in this file.

    - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +- 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Following Proxmox VE - Support Lifecycle** ## 2024-02-04 From 201f95fe88d4562286d67edf712bcb4a40bf3330 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 4 Feb 2024 20:48:36 -0500 Subject: [PATCH 5880/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ddbd14..1ac8ee5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@

    All notable changes to this project will be documented in this file.

    - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. -- 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Following Proxmox VE - Support Lifecycle** +- 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** ## 2024-02-04 From 4021d7912a46f5b1e7bc13506b5675f53c1be779 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 07:25:09 -0500 Subject: [PATCH 5881/6505] Update technitiumdns.sh .NET 8 runtime --- ct/technitiumdns.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh index d69c81aa..85775abd 100644 --- a/ct/technitiumdns.sh +++ b/ct/technitiumdns.sh @@ -57,11 +57,11 @@ header_info if [[ ! -d /etc/dns ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" -if ! dpkg -s aspnetcore-runtime-7.0 > /dev/null 2>&1; then - wget -q https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb +if ! dpkg -s aspnetcore-runtime-8.0 > /dev/null 2>&1; then + wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb &>/dev/null apt-get update &>/dev/null - apt-get install -y aspnetcore-runtime-7.0 &>/dev/null + apt-get install -y aspnetcore-runtime-8.0 &>/dev/null rm packages-microsoft-prod.deb fi bash <(curl -fsSL https://download.technitium.com/dns/install.sh) &>/dev/null From ac9a98df8c9a5e14ba96d1de48c60be42e0536c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 07:26:30 -0500 Subject: [PATCH 5882/6505] Update technitiumdns-install.sh .NET 8 runtime --- install/technitiumdns-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index bc9fade9..f157d841 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -24,7 +24,7 @@ wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod. $STD dpkg -i packages-microsoft-prod.deb rm -rf packages-microsoft-prod.deb $STD apt-get update -$STD apt-get install -y aspnetcore-runtime-7.0 +$STD apt-get install -y aspnetcore-runtime-8.0 msg_ok "Installed ASP.NET Core Runtime" msg_info "Installing Technitium DNS" From 082cf8ae6a10040b50c1aef41414dd6f57e9f034 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 11:15:52 -0500 Subject: [PATCH 5883/6505] Create gokapi-install.sh --- install/gokapi-install.sh | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 install/gokapi-install.sh diff --git a/install/gokapi-install.sh b/install/gokapi-install.sh new file mode 100644 index 00000000..d207aaf0 --- /dev/null +++ b/install/gokapi-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Gokapi" +LATEST=$(curl -sL https://api.github.com/repos/Forceu/Gokapi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +mkdir -p /opt/gokapi/{data,config} +wget -q https://github.com/Forceu/Gokapi/releases/download/$LATEST/gokapi-linux_amd64.zip +unzip -q gokapi-linux_amd64.zip -d /opt/gokapi +rm gokapi-linux_amd64.zip +chmod +x /opt/gokapi/gokapi-linux_amd64 +msg_ok "Installed Gokapi" + +msg_info "Creating Service" +cat </etc/systemd/system/gokapi.service +[Unit] +Description=gokapi + +[Service] +Type=simple +Environment=GOKAPI_DATA_DIR=/opt/gokapi/data +Environment=GOKAPI_CONFIG_DIR=/opt/gokapi/config +ExecStart=/opt/gokapi/gokapi-linux_amd64 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now gokapi +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 36ab1df27d1805d5eefec7ba6500c9eba757def2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 11:16:39 -0500 Subject: [PATCH 5884/6505] Create gokapi.sh --- ct/gokapi.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ct/gokapi.sh diff --git a/ct/gokapi.sh b/ct/gokapi.sh new file mode 100644 index 00000000..942cc560 --- /dev/null +++ b/ct/gokapi.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ __ _ + / ____/___ / /______ _____ (_) + / / __/ __ \/ //_/ __ `/ __ \/ / +/ /_/ / /_/ / ,< / /_/ / /_/ / / +\____/\____/_/|_|\__,_/ .___/_/ + /_/ +EOF +} +header_info +echo -e "Loading..." +APP="Gokapi" +var_disk="4" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/gokapi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +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}:53842/setup${CL} \n" From fb308e2bfd667f045f467845e9b5fa896374977e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 11:33:07 -0500 Subject: [PATCH 5885/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac8ee5b..8bbe2b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-02-05 + +### Changed + +- **Gokapi LXC** + - NEW Script + ## 2024-02-04 ### Changed From bfa4cd815e6af95f1a81421ef1be0eab5b58dccb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 18:10:55 -0500 Subject: [PATCH 5886/6505] Update nginxproxymanager-install.sh option to install v2.10.4 --- install/nginxproxymanager-install.sh | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 52ee0e70..5f690584 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -68,22 +68,32 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Downloading Nginx Proxy Manager v${RELEASE}" -wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz -cd ./nginx-proxy-manager-${RELEASE} -msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" - +read -r -p "Would you like to install an older version (v2.20.4)? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Downloading Nginx Proxy Manager v2.10.4" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.10.4 -O - | tar -xz + cd ./nginx-proxy-manager-2.10.4 + msg_ok "Downloaded Nginx Proxy Manager v2.10.4" +else + msg_info "Downloading Nginx Proxy Manager v${RELEASE}" + wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz + cd ./nginx-proxy-manager-${RELEASE} + msg_ok "Downloaded Nginx Proxy Manager v${RELEASE}" +fi msg_info "Setting up Enviroment" ln -sf /usr/bin/python3 /usr/bin/python ln -sf /usr/bin/certbot /opt/certbot/bin/certbot ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx ln -sf /usr/local/openresty/nginx/ /etc/nginx - -sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json -sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"2.10.4\"|" backend/package.json + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"2.10.4\"|" frontend/package.json +else + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json + sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json +fi sed -i 's|"fork-me": ".*"|"fork-me": "Proxmox VE Helper-Scripts"|' frontend/js/i18n/messages.json sed -i "s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g" frontend/js/app/ui/footer/main.ejs - sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf") for NGINX_CONF in $NGINX_CONFS; do From 65cf479b99deae11aed4e8fee482c19784790010 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 18:22:04 -0500 Subject: [PATCH 5887/6505] Update nginxproxymanager-install.sh --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 5f690584..48017b6f 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -68,7 +68,7 @@ RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-man grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -read -r -p "Would you like to install an older version (v2.20.4)? " prompt +read -r -p "Would you like to install an older version (v2.10.4)? " prompt if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then msg_info "Downloading Nginx Proxy Manager v2.10.4" wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.10.4 -O - | tar -xz From 65970a5c530ad4aadc737b8e26dcfc5d60af49bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 5 Feb 2024 18:38:10 -0500 Subject: [PATCH 5888/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bbe2b96..dbc5c28d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - **Gokapi LXC** - NEW Script +- **Nginx Proxy Manager LXC** + - Option to install v2.10.4 ## 2024-02-04 From a1deedd06627d24bb667c0f524f18a97a2cfc0ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 05:29:14 -0500 Subject: [PATCH 5889/6505] Update build.func Requires PVE Version 7.4-13 or higher --- misc/build.func | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index e526ca57..4853d771 100644 --- a/misc/build.func +++ b/misc/build.func @@ -88,9 +88,9 @@ pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7 (EOL 2024-07), refrain from creating Debian 12 LXCs. \nDefault distribution for $APP LXC is ${var_os} ${var_version}" 10 60 fi - if ! pveversion | grep -Eq "pve-manager/(7\.[0-9]|8\.[0-9])"; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.0 or higher" + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit From e0f8e23fd70d0724b5781d189dca75257d3a6a54 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 05:42:54 -0500 Subject: [PATCH 5890/6505] Update VMs - The scripts will only work with PVE versions 7.4-13 or higher. --- vm/debian-vm.sh | 4 ++-- vm/haos-vm.sh | 4 ++-- vm/mikrotik-routeros.sh | 4 ++-- vm/nextcloud-vm.sh | 4 ++-- vm/openwrt.sh | 4 ++-- vm/owncloud-vm.sh | 4 ++-- vm/pimox-haos-vm.sh | 4 ++-- vm/ubuntu-vm.sh | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index e390073b..c2efe13c 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -92,9 +92,9 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 65733214..75171c11 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -115,9 +115,9 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 5aba3c29..aca22423 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -62,9 +62,9 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo "Exiting..." sleep 3 exit diff --git a/vm/nextcloud-vm.sh b/vm/nextcloud-vm.sh index 5e3fce87..af90b388 100644 --- a/vm/nextcloud-vm.sh +++ b/vm/nextcloud-vm.sh @@ -91,9 +91,9 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit diff --git a/vm/openwrt.sh b/vm/openwrt.sh index cc920c5e..800cf4d4 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -157,9 +157,9 @@ function msg_error() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh index 72ac7ad4..136a5171 100644 --- a/vm/owncloud-vm.sh +++ b/vm/owncloud-vm.sh @@ -91,9 +91,9 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index f16a6338..8c8bebff 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -84,9 +84,9 @@ else exit fi function PVE_CHECK() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index 9e19c43d..5d36ba96 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -92,9 +92,9 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.[2-9]|8\.[0-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.2 or higher" + echo -e "Requires PVE Version 7.4-13 or higher" echo -e "Exiting..." sleep 2 exit From a4ac3e7065da5e113e3353f945ca30faa54359ad Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 05:53:37 -0500 Subject: [PATCH 5891/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbc5c28d..e075940c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-02-06 + +### Changed + +- **All Scripts** + - The scripts will only work with PVE versions 7.4-13 or higher. + ## 2024-02-05 ### Changed From ba8b38caebee8833152986ff5ed42776687b3170 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 07:51:52 -0500 Subject: [PATCH 5892/6505] Update nginxproxymanager.sh fixes https://github.com/tteck/Proxmox/issues/2441 --- ct/nginxproxymanager.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 4e286344..4045ff55 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -122,7 +122,6 @@ function update_script() { chown root /tmp/nginx echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then - echo -e "${CHECKMARK} \e[1;92m Generating dummy SSL Certificate... \e[0m" openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null fi mkdir -p /app/global /app/frontend/images From 9fb338f6ea30c898a069e49a5a7d90984d840219 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 09:59:27 -0500 Subject: [PATCH 5893/6505] Update unifi-install.sh update libssl --- install/unifi-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 94807c3f..1b2b75ad 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -29,8 +29,8 @@ $STD apt-get install -y temurin-17-jdk msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb +$STD dpkg -i libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list $STD apt-get update @@ -48,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +rm -rf libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 2ce1c183f45cdbec1129799b52c25a5b41aefb7a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 10:04:12 -0500 Subject: [PATCH 5894/6505] Update unifi-install.sh --- install/unifi-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 1b2b75ad..47c9173c 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -29,8 +29,8 @@ $STD apt-get install -y temurin-17-jdk msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb -$STD dpkg -i libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb +#wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb +#$STD dpkg -i libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list $STD apt-get update From 5bbfe8812e4025ba50b0f0d5a607ed8bf4f0b32a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 10:29:47 -0500 Subject: [PATCH 5895/6505] Update build.func Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later. --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 4853d771..1c34c992 100644 --- a/misc/build.func +++ b/misc/build.func @@ -90,7 +90,7 @@ pve_check() { fi if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit From 465996e7a2d2dc1018fbdd149669ec87730a144b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 10:32:38 -0500 Subject: [PATCH 5896/6505] Update VMs - Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later. --- vm/debian-vm.sh | 2 +- vm/haos-vm.sh | 2 +- vm/mikrotik-routeros.sh | 2 +- vm/nextcloud-vm.sh | 2 +- vm/openwrt.sh | 2 +- vm/owncloud-vm.sh | 2 +- vm/pimox-haos-vm.sh | 2 +- vm/ubuntu-vm.sh | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index c2efe13c..3f2db4f6 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -94,7 +94,7 @@ function check_root() { function pve_check() { if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 75171c11..fff4f939 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -117,7 +117,7 @@ function check_root() { function pve_check() { if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index aca22423..5c38d9ed 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -64,7 +64,7 @@ TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo "Exiting..." sleep 3 exit diff --git a/vm/nextcloud-vm.sh b/vm/nextcloud-vm.sh index af90b388..ff62c7df 100644 --- a/vm/nextcloud-vm.sh +++ b/vm/nextcloud-vm.sh @@ -93,7 +93,7 @@ function check_root() { function pve_check() { if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 800cf4d4..5ebb5ec4 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -159,7 +159,7 @@ function msg_error() { function pve_check() { if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh index 136a5171..7fbe8be6 100644 --- a/vm/owncloud-vm.sh +++ b/vm/owncloud-vm.sh @@ -93,7 +93,7 @@ function check_root() { function pve_check() { if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index 8c8bebff..fb0bfb31 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -86,7 +86,7 @@ fi function PVE_CHECK() { if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index 5d36ba96..be9edc88 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -94,7 +94,7 @@ function check_root() { function pve_check() { if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 7.4-13 or higher" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit From 57507a583c2d63b0e43e9e838a92e63d4c957163 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 10:42:40 -0500 Subject: [PATCH 5897/6505] Update unifi-install.sh --- install/unifi-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 47c9173c..bc42a295 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -29,8 +29,8 @@ $STD apt-get install -y temurin-17-jdk msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" -#wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb -#$STD dpkg -i libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list $STD apt-get update @@ -48,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf libssl-dev_1.1.1f-1ubuntu2.21_amd64.deb +rm -rf libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 236f90a1e092fc84a52a2e69bcc05e64572000c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 10:58:10 -0500 Subject: [PATCH 5898/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e075940c..d6953de6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ ### Changed - **All Scripts** - - The scripts will only work with PVE versions 7.4-13 or higher. + - The scripts will only work with PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later. ## 2024-02-05 From 345346118b554477cffed206a4c479f0adf22b36 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 12:25:35 -0500 Subject: [PATCH 5899/6505] Update omada-install.sh update libssl --- install/omada-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index b54ec2f2..4e78c5c7 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -30,8 +30,8 @@ $STD apt-get -y install zulu8-jdk msg_ok "Installed Azul Zulu" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" @@ -48,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf ${latest_version} mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +rm -rf ${latest_version} mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 80200dc39da486372c2859766d98f28c952be4c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 6 Feb 2024 12:28:54 -0500 Subject: [PATCH 5900/6505] Update deconz-install.sh update libssl --- install/deconz-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/deconz-install.sh b/install/deconz-install.sh index 80d938b3..328a9679 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -26,8 +26,8 @@ echo "deb [arch=amd64] http://phoscon.de/apt/deconz $VERSION main" >/etc/apt/sou msg_ok "Setup Phoscon Repository" msg_info "Installing deConz" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb $STD apt-get update $STD apt-get install -y deconz msg_ok "Installed deConz" @@ -56,7 +56,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb +rm -rf libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 47bc910e8f22bed8df97c71180877bec9108d9ea Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Feb 2024 05:46:19 -0500 Subject: [PATCH 5901/6505] Update readeck-install.sh install the latest version --- install/readeck-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/readeck-install.sh b/install/readeck-install.sh index 2a1ead40..8b1c287b 100644 --- a/install/readeck-install.sh +++ b/install/readeck-install.sh @@ -20,9 +20,10 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Readeck" +LATEST=$(curl -s https://codeberg.org/readeck/readeck/releases/ | grep -oP '(?<=Version )\d+\.\d+\.\d+' | head -1) mkdir -p /opt/readeck cd /opt/readeck -wget -q -O readeck https://codeberg.org/readeck/readeck/releases/download/0.11.2/readeck-0.11.2-linux-amd64 +wget -q -O readeck https://codeberg.org/readeck/readeck/releases/download/${LATEST}/readeck-${LATEST}-linux-amd64 chmod a+x readeck msg_ok "Installed Readeck" From ee3b69fffecc0f7b6c311ec978cbd084448c418e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Feb 2024 05:56:22 -0500 Subject: [PATCH 5902/6505] Update readeck.sh create update path --- ct/readeck.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ct/readeck.sh b/ct/readeck.sh index 70a014c0..1c01b161 100644 --- a/ct/readeck.sh +++ b/ct/readeck.sh @@ -55,7 +55,16 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/readeck ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +msg_info "Updating ${APP}" +LATEST=$(curl -s https://codeberg.org/readeck/readeck/releases/ | grep -oP '(?<=Version )\d+\.\d+\.\d+' | head -1 +) +systemctl stop readeck.service +rm -rf /opt/readeck/readeck +cd /opt/readeck +wget -q -O readeck https://codeberg.org/readeck/readeck/releases/download/${LATEST}/readeck-${LATEST}-linux-amd64 +chmod a+x readeck +systemctl start readeck.service +msg_ok "Updated ${APP}" exit } From f267ee196e4b00cc18cc68719c6e7bcf689138b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 7 Feb 2024 06:21:18 -0500 Subject: [PATCH 5903/6505] Update readeck.sh tweak --- ct/readeck.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/readeck.sh b/ct/readeck.sh index 1c01b161..cc5204ba 100644 --- a/ct/readeck.sh +++ b/ct/readeck.sh @@ -56,8 +56,7 @@ function update_script() { header_info if [[ ! -d /opt/readeck ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" -LATEST=$(curl -s https://codeberg.org/readeck/readeck/releases/ | grep -oP '(?<=Version )\d+\.\d+\.\d+' | head -1 -) +LATEST=$(curl -s https://codeberg.org/readeck/readeck/releases/ | grep -oP '(?<=Version )\d+\.\d+\.\d+' | head -1) systemctl stop readeck.service rm -rf /opt/readeck/readeck cd /opt/readeck From c0856c0d0c5ca18aecfab7a4788501ee03e4d53e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 8 Feb 2024 21:12:03 -0500 Subject: [PATCH 5904/6505] Update homeassistant-core-install.sh Compile Python from its source --- install/homeassistant-core-install.sh | 47 ++++++++++----------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 6e4b4908..327c773f 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -42,41 +42,30 @@ $STD apt-get install -y \ libatlas-base-dev msg_ok "Installed Dependencies" -msg_info "Updating Python3" -$STD apt-get install -y \ - python3 \ - python3-dev \ - python3-pip \ - python3-venv -msg_ok "Updated Python3" +RELEASE=$(curl -s https://www.python.org/downloads/ | grep -oP 'Download Python \K\d+\.\d+\.\d+' | head -1) -msg_info "Installing pyenv" +msg_info "Compiling Python ${RELEASE} from its source (Additional Patience)" +$STD apt-get remove -y python3 $STD apt-get install -y \ - make \ + checkinstall \ libreadline-dev \ - libsqlite3-dev \ - libncurses5-dev \ libncursesw5-dev \ - xz-utils \ + libssl-dev \ + libsqlite3-dev \ tk-dev \ - llvm \ - libbz2-dev \ - libxml2-dev \ - libxmlsec1-dev \ - liblzma-dev -$STD git clone https://github.com/pyenv/pyenv.git ~/.pyenv -set +e -echo 'export PYENV_ROOT="$HOME/.pyenv"' >>~/.bashrc -echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >>~/.bashrc -echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init --path)"\nfi' >>~/.bashrc -msg_ok "Installed pyenv" -. ~/.bashrc + libgdbm-dev \ + libc6-dev \ + libbz2-dev -set -e -msg_info "Installing Python 3.12.1 (Patience)" -$STD pyenv install 3.12.1 -pyenv global 3.12.1 -msg_ok "Installed Python 3.12.1" +wget -qO- https://www.python.org/ftp/python/${RELEASE}/Python-${RELEASE}.tar.xz | tar -xJ +cd Python-${RELEASE} +$STD ./configure --enable-optimizations +$STD make -j $(nproc) +$STD make altinstall +$STD update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.12 1 +cd ~ +rm -rf Python-${RELEASE} +msg_ok "Installed Python ${RELEASE}" msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant From be47eb1039b7dda6bfeaa83e91789830abfd9982 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Feb 2024 10:23:52 -0500 Subject: [PATCH 5905/6505] Update tdarr-install.sh add handbrake --- install/tdarr-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index 9c74faaf..f666cb55 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y handbrake-cli msg_ok "Installed Dependencies" if [[ "$CTTYPE" == "0" ]]; then From e81d51399c71c13f4bdcd3329d57fc54d7ec6192 Mon Sep 17 00:00:00 2001 From: Allard Katstra Date: Fri, 9 Feb 2024 17:06:22 +0100 Subject: [PATCH 5906/6505] Adding the "tools" directory to the backup before updating homer (#2460) --- ct/homer.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ct/homer.sh b/ct/homer.sh index f6b04d4d..7d02e053 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -62,7 +62,8 @@ msg_ok "Stopped ${APP}" msg_info "Backing up config.yml" cd ~ cp -R /opt/homer/assets/config.yml config.yml -msg_ok "Backed up config.yml" +cp -R /opt/homer/assets/tools tools +msg_ok "Backed up config.yml and tools directory" msg_info "Updating ${APP}" rm -rf /opt/homer/* @@ -73,10 +74,11 @@ msg_ok "Updated ${APP}" msg_info "Restoring conf.yml" cd ~ cp -R config.yml /opt/homer/assets -msg_ok "Restored conf.yml" +cp -R tools /opt/homer/assets +msg_ok "Restored config.yml and tools directory" msg_info "Cleaning" -rm -rf config.yml /opt/homer/homer.zip +rm -rf config.yml tools /opt/homer/homer.zip msg_ok "Cleaned" msg_info "Starting ${APP}" From 9f84dbf1bd8823806a17587b950e878c75967a87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Feb 2024 17:34:32 -0500 Subject: [PATCH 5907/6505] Update grocy-install.sh fixes https://github.com/tteck/Proxmox/issues/2463 --- install/grocy-install.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 526eeaff..091fa8d8 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -20,18 +20,18 @@ $STD apt-get install -y mc $STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" -msg_info "Installing PHP 8.1" +msg_info "Installing PHP 8.2" VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg echo -e "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main" >/etc/apt/sources.list.d/php.list $STD apt-get update -$STD apt-get install -y php8.1 -$STD apt-get install -y libapache2-mod-php8.1 -$STD apt-get install -y php8.1-sqlite3 -$STD apt-get install -y php8.1-gd -$STD apt-get install -y php8.1-intl -$STD apt-get install -y php8.1-mbstring -msg_ok "Installed PHP 8.1" +$STD apt-get install -y php8.2 +$STD apt-get install -y libapache2-mod-php8.2 +$STD apt-get install -y php8.2-sqlite3 +$STD apt-get install -y php8.2-gd +$STD apt-get install -y php8.2-intl +$STD apt-get install -y php8.2-mbstring +msg_ok "Installed PHP 8.2" msg_info "Installing grocy" latest=$(curl -s https://api.github.com/repos/grocy/grocy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') From f674b8af03102d71ead1ccc2b81c46789b08c5e0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Feb 2024 17:41:00 -0500 Subject: [PATCH 5908/6505] Update adguard.sh fixes https://github.com/tteck/Proxmox/issues/2462 --- ct/adguard.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ct/adguard.sh b/ct/adguard.sh index e9e667c9..b7a8fdd5 100644 --- a/ct/adguard.sh +++ b/ct/adguard.sh @@ -56,6 +56,10 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/AdGuardHome ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi wget -qL https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz msg_info "Stopping AdguardHome" systemctl stop AdGuardHome From 5d6007cdd99f754aa3bfb5ccf73788e7aa2008e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Feb 2024 20:37:41 -0500 Subject: [PATCH 5909/6505] Update homeassistant-core.sh tweak --- ct/homeassistant-core.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 375024e6..9864695e 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -78,7 +78,7 @@ function update_script() { echo -e "${GN}Updating to Stable Version${CL}" BR="" fi - if [[ "$PY" == "python3.10" ]]; then echo -e "⚠️ Home Assistant now requires Python 3.11 to run."; fi + if [[ "$PY" == "python3.11" ]]; then echo -e "⚠️ Home Assistant will soon require Python 3.12."; fi msg_info "Stopping Home Assistant" systemctl stop homeassistant From 1910de65689fe1b6db6ce595f0def7cb3f3bf1ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 9 Feb 2024 20:55:43 -0500 Subject: [PATCH 5910/6505] Update homeassistant-core.sh remove app daemon --- ct/homeassistant-core.sh | 73 ---------------------------------------- 1 file changed, 73 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 9864695e..b6567eb8 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -63,7 +63,6 @@ function update_script() { "1" "Update Core" ON \ "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ - "4" "Install/Update AppDaemon" OFF \ 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then @@ -136,78 +135,6 @@ WantedBy=default.target" >$service_path ${BL}http://$IP:8080${CL} admin|changeme\n" exit fi - if [ "$UPD" == "4" ]; then - clear - header_info - if [[ ! -d /srv/appdaemon ]]; then - msg_info "Installing AppDaemon" - mkdir /srv/appdaemon - cd /srv/appdaemon - python3 -m venv . - source bin/activate - pip install appdaemon &>/dev/null - mkdir -p /root/.homeassistant/appdaemon/apps - cat >/root/.homeassistant/appdaemon/appdaemon.yaml < - token: -http: - url: http://127.0.0.1:5050 -admin: -api: -EOF - msg_ok "Installed AppDaemon" - - msg_info "Creating Service" - cat >/etc/systemd/system/appdaemon.service </dev/null - msg_ok "Created Service" - - msg_ok "Completed Successfully!\n" - echo -e "AppDaemon should be reachable by going to the following URL. - ${BL}http://$IP:5050${CL}\n" - exit - else - msg_info "Upgrading AppDaemon" - msg_info "Stopping AppDaemon" - systemctl stop appdaemon - msg_ok "Stopped AppDaemon" - - msg_info "Updating AppDaemon" - source /srv/appdaemon/bin/activate - pip install --upgrade appdaemon &>/dev/null - msg_ok "Updated AppDaemon" - - msg_info "Starting AppDaemon" - systemctl start appdaemon - sleep 2 - msg_ok "Started AppDaemon" - msg_ok "Update Successful" - echo -e "\n Go to http://${IP}:5050 \n" - exit - fi - fi } start From 21cdc8306a4cb17160551aeaa665ced42513ec1d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Feb 2024 09:38:28 -0500 Subject: [PATCH 5911/6505] Update build.func add Channels to the VAAPI hardware transcoding group --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 1c34c992..77091c5c 100644 --- a/misc/build.func +++ b/misc/build.func @@ -554,7 +554,7 @@ EOF fi if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then + if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm From db3fe0e9ad35187a73c3c2e2e2f173c506883bd0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 10 Feb 2024 09:40:59 -0500 Subject: [PATCH 5912/6505] Update channels-install.sh add Hardware Acceleration --- install/channels-install.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/install/channels-install.sh b/install/channels-install.sh index 5836812c..7a2c6f7f 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -21,6 +21,20 @@ $STD apt-get install -y chromium $STD apt-get install -y xvfb msg_ok "Installed Dependencies" +if [[ "$CTTYPE" == "0" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install \ + va-driver-all \ + ocl-icd-libopencl1 \ + intel-opencl-icd + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render + msg_ok "Set Up Hardware Acceleration" +fi + msg_info "Installing Channels DVR Server (Patience)" cd /opt $STD bash <(curl -fsSL https://getchannels.com/dvr/setup.sh) From dcd35adf71b3950ca65262151ddc5b65c9bcc641 Mon Sep 17 00:00:00 2001 From: Bartosz Korczak Date: Sat, 10 Feb 2024 08:35:39 -0800 Subject: [PATCH 5913/6505] fix(n8n): add missing installation dependency (#2466) --- install/n8n-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 25cbce47..13aa5104 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -33,6 +33,7 @@ $STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Installing n8n (Patience)" +$STD npm install --global patch-package $STD npm install --global n8n msg_ok "Installed n8n" From 37d75286e02c32ac0c1e5c7f5089a2638f3fd78e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Feb 2024 09:23:03 -0500 Subject: [PATCH 5914/6505] Update unifi-install.sh test temurin-17-jre --- install/unifi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index bc42a295..9ff1d08f 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -25,7 +25,7 @@ msg_info "Installing OpenJDK" wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list $STD apt-get update -$STD apt-get install -y temurin-17-jdk +$STD apt-get install -y temurin-17-jre msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" From 84c404e632429241a9d50db1f2488d62f7384448 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Feb 2024 10:21:22 -0500 Subject: [PATCH 5915/6505] Create hivemq-install.sh --- install/hivemq-install.sh | 51 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 install/hivemq-install.sh diff --git a/install/hivemq-install.sh b/install/hivemq-install.sh new file mode 100644 index 00000000..46ca5aa0 --- /dev/null +++ b/install/hivemq-install.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +msg_ok "Installed Dependencies" + +msg_info "Installing OpenJDK" +wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg +echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list +$STD apt-get update +$STD apt-get install -y temurin-17-jre +msg_ok "Installed OpenJDK" + +msg_info "Installing HiveMQ CE" +RELEASE=$(curl -s https://api.github.com/repos/hivemq/hivemq-community-edition/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget -q https://github.com/hivemq/hivemq-community-edition/releases/download/${RELEASE}/hivemq-ce-${RELEASE}.zip +unzip -q hivemq-ce-${RELEASE}.zip +mkdir -p /opt/hivemq +mv hivemq-ce-${RELEASE}/* /opt/hivemq +useradd -d /opt/hivemq hivemq +chown -R hivemq:hivemq /opt/hivemq +chmod +x /opt/hivemq/bin/run.sh +cp /opt/hivemq/bin/init-script/hivemq.service /etc/systemd/system/hivemq.service +systemctl enable -q --now hivemq +msg_ok "Installed HiveMQ CE" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf hivemq-ce-${RELEASE}.zip +rm -rf ../hivemq-ce-${RELEASE} +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 1d5a3ddacac5ce7556e21a0a2795d1665e59893f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Feb 2024 10:23:58 -0500 Subject: [PATCH 5916/6505] Create hivemq.sh --- ct/hivemq.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ct/hivemq.sh diff --git a/ct/hivemq.sh b/ct/hivemq.sh new file mode 100644 index 00000000..80b79c81 --- /dev/null +++ b/ct/hivemq.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ __ _______ ____________ + / / / (_) _____ / |/ / __ \ / ____/ ____/ + / /_/ / / | / / _ \/ /|_/ / / / / / / / __/ + / __ / /| |/ / __/ / / / /_/ / / /___/ /___ +/_/ /_/_/ |___/\___/_/ /_/\___\_\ \____/_____/ + +EOF +} +header_info +echo -e "Loading..." +APP="HiveMQ" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" From e638845ffa6fc04032306fdd9c0a3273aab9ec94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Feb 2024 10:57:26 -0500 Subject: [PATCH 5917/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6953de6..0a636f18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-02-11 + +### Changed + +- **HiveMQ CE LXC** + - NEW Script + ## 2024-02-06 ### Changed From 4164d42b7c18f14b0dc5a46d34d0912dbb7346d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Feb 2024 13:36:28 -0500 Subject: [PATCH 5918/6505] Update hivemq-install.sh tcp and websockets --- install/hivemq-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/hivemq-install.sh b/install/hivemq-install.sh index 46ca5aa0..8e66f3b2 100644 --- a/install/hivemq-install.sh +++ b/install/hivemq-install.sh @@ -37,6 +37,8 @@ useradd -d /opt/hivemq hivemq chown -R hivemq:hivemq /opt/hivemq chmod +x /opt/hivemq/bin/run.sh cp /opt/hivemq/bin/init-script/hivemq.service /etc/systemd/system/hivemq.service +rm /opt/hivemq/conf/config.xml +mv /opt/hivemq/conf/examples/configuration/config-sample-tcp-and-websockets.xml /opt/hivemq/conf/config.xml systemctl enable -q --now hivemq msg_ok "Installed HiveMQ CE" From d5211aedeccdb3f65f5b9bc98f6933d24c018fbe Mon Sep 17 00:00:00 2001 From: JJ Date: Sun, 11 Feb 2024 22:55:49 +0100 Subject: [PATCH 5919/6505] Add Apache CouchDB (#2473) --- ct/apache-couchdb.sh | 70 +++++++++++++++++++++++++++++++ install/apache-couchdb-install.sh | 47 +++++++++++++++++++++ misc/build.func | 1 - 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 ct/apache-couchdb.sh create mode 100644 install/apache-couchdb-install.sh diff --git a/ct/apache-couchdb.sh b/ct/apache-couchdb.sh new file mode 100644 index 00000000..cd2c00af --- /dev/null +++ b/ct/apache-couchdb.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ ______ __ ____ ____ + / | ____ ____ ______/ /_ ___ / ____/___ __ _______/ /_ / __ \/ __ ) + / /| | / __ \/ __ `/ ___/ __ \/ _ \ / / / __ \/ / / / ___/ __ \/ / / / __ | + / ___ |/ /_/ / /_/ / /__/ / / / __/ / /___/ /_/ / /_/ / /__/ / / / /_/ / /_/ / +/_/ |_/ .___/\__,_/\___/_/ /_/\___/ \____/\____/\__,_/\___/_/ /_/_____/_____/ + /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Apache-CouchDB" +var_disk="10" +var_cpu="2" +var_ram="4096" +var_os="debian" +var_version="12" +VERBOSE="yes" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/couchdb.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5984/_utils/${CL} \n" diff --git a/install/apache-couchdb-install.sh b/install/apache-couchdb-install.sh new file mode 100644 index 00000000..41cfde57 --- /dev/null +++ b/install/apache-couchdb-install.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y apt-transport-https +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Installing Apache CouchDB" +ERLANG_COOKIE=$(openssl rand -base64 32) +ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)" +debconf-set-selections <<< "couchdb couchdb/cookie string $ERLANG_COOKIE" +debconf-set-selections <<< "couchdb couchdb/mode select standalone" +debconf-set-selections <<< "couchdb couchdb/bindaddress string 0.0.0.0" +debconf-set-selections <<< "couchdb couchdb/adminpass password $ADMIN_PASS" +debconf-set-selections <<< "couchdb couchdb/adminpass_again password $ADMIN_PASS" +curl -fsSL https://couchdb.apache.org/repo/keys.asc | gpg --dearmor -o /usr/share/keyrings/couchdb-archive-keyring.gpg +VERSION_CODENAME="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" +echo "deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main" >/etc/apt/sources.list.d/couchdb.sources.list +$STD apt-get update +$STD apt-get install -y couchdb +echo -e "CouchDB Erlang Cookie: \e[32m$ERLANG_COOKIE\e[0m" >>~/CouchDB.creds +echo -e "CouchDB Admin Password: \e[32m$ADMIN_PASS\e[0m" >>~/CouchDB.creds +msg_ok "Installed Apache CouchDB." + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/misc/build.func b/misc/build.func index 77091c5c..6bc7738e 100644 --- a/misc/build.func +++ b/misc/build.func @@ -55,7 +55,6 @@ msg_info() { SPINNER_PID=$! } - # This function displays a success message with a green color. msg_ok() { if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi From 302368a9124a47d9e93e07701c0637b269c6b432 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 11 Feb 2024 17:42:55 -0500 Subject: [PATCH 5920/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a636f18..b4c33cad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - **HiveMQ CE LXC** - NEW Script +- **Apache-CouchDB LXC** + - NEW Script ## 2024-02-06 From ffd2fc3b868ab802e14f63cd49e0659347c33461 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Feb 2024 05:53:26 -0500 Subject: [PATCH 5921/6505] Update install.func Check to see if the apt-cacher-ng proxy is available before attempting to use it. If it's not available, the system will directly communicate with the apt repositories. --- misc/install.func | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index ba3c11df..f19e7f12 100644 --- a/misc/install.func +++ b/misc/install.func @@ -154,7 +154,16 @@ network_check() { update_os() { msg_info "Updating Container OS" if [[ "$CACHER" == "yes" ]]; then - echo "Acquire::http { Proxy \"http://${CACHER_IP}:3142\"; };" >/etc/apt/apt.conf.d/00aptproxy + echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy + cat </usr/local/bin/apt-proxy-detect.sh +#!/bin/bash +if nc -w1 -z "${CACHER_IP}" 3142; then + echo -n "http://${CACHER_IP}:3142" +else + echo -n "DIRECT" +fi +EOF + chmod +x /usr/local/bin/apt-proxy-detect.sh fi $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade From 3093af9b4f0294b392f35ffb1302826efc80f4ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Feb 2024 06:47:26 -0500 Subject: [PATCH 5922/6505] Update alpine-docker.sh Alpine 3.19 --- ct/alpine-docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 49ee7518..6fe0c3bf 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -24,7 +24,7 @@ var_disk="2" var_cpu="1" var_ram="1024" var_os="alpine" -var_version="3.18" +var_version="3.19" variables color catch_errors From 749639b1f0da546143899cd0b81431bbabd68e69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Feb 2024 06:55:25 -0500 Subject: [PATCH 5923/6505] Update to Alpine 3.19 --- ct/alpine-grafana.sh | 2 +- ct/alpine-nextcloud.sh | 2 +- ct/alpine-vaultwarden.sh | 2 +- ct/alpine-zigbee2mqtt.sh | 2 +- ct/alpine.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 4382f131..b7e89aba 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -24,7 +24,7 @@ var_disk="0.5" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.18" +var_version="3.19" variables color catch_errors diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 5e9338ac..6def6e53 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -23,7 +23,7 @@ var_disk="2" var_cpu="2" var_ram="1024" var_os="alpine" -var_version="3.18" +var_version="3.19" variables color catch_errors diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 9ce6763a..23bb5f26 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -24,7 +24,7 @@ var_disk="0.3" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.18" +var_version="3.19" variables color catch_errors diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index 2767d924..eb98903a 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -24,7 +24,7 @@ var_disk="0.3" var_cpu="1" var_ram="256" var_os="alpine" -var_version="3.18" +var_version="3.19" variables color catch_errors diff --git a/ct/alpine.sh b/ct/alpine.sh index 85f3ad55..8a651555 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -24,7 +24,7 @@ var_disk="0.1" var_cpu="1" var_ram="512" var_os="alpine" -var_version="3.18" +var_version="3.19" variables color catch_errors From 453604d1b63c7896b17366bf7e233bc3806d2bad Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Feb 2024 07:17:23 -0500 Subject: [PATCH 5924/6505] Update build.func tweak --- misc/build.func | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/misc/build.func b/misc/build.func index 6bc7738e..daf5dc49 100644 --- a/misc/build.func +++ b/misc/build.func @@ -340,11 +340,13 @@ advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" fi - if APT_CACHER_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for default)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then - APT_CACHER="${APT_CACHER_IP:+yes}" - echo -e "${DGN}Using APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" - else - exit-script + if [ "$var_os" != "alpine" ]; then + if APT_CACHER_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for default)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then + APT_CACHER="${APT_CACHER_IP:+yes}" + echo -e "${DGN}Using APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" + else + exit-script + fi fi if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then From 25f88d586ca9420aaf5e56b8b34c09bd452c5094 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Feb 2024 10:36:02 -0500 Subject: [PATCH 5925/6505] Update build.func fixes https://github.com/tteck/Proxmox/issues/2478 --- misc/build.func | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index daf5dc49..d9dc8a70 100644 --- a/misc/build.func +++ b/misc/build.func @@ -340,7 +340,9 @@ advanced_settings() { echo -e "${DGN}Using Gateway IP Address: ${BGN}Default${CL}" fi - if [ "$var_os" != "alpine" ]; then + if [ "$var_os" == "alpine" ]; then + APT_CACHER="" + else if APT_CACHER_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for default)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then APT_CACHER="${APT_CACHER_IP:+yes}" echo -e "${DGN}Using APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}" From 1af3b37dd2ba4ae5d08610e43967cfa98f932392 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Feb 2024 10:38:37 -0500 Subject: [PATCH 5926/6505] Update build.func tweak --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index d9dc8a70..ace1a3e6 100644 --- a/misc/build.func +++ b/misc/build.func @@ -342,6 +342,7 @@ advanced_settings() { if [ "$var_os" == "alpine" ]; then APT_CACHER="" + APT_CACHER_IP="" else if APT_CACHER_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set APT-Cacher IP (leave blank for default)" 8 58 --title "APT-Cacher IP" 3>&1 1>&2 2>&3); then APT_CACHER="${APT_CACHER_IP:+yes}" From f5a1b23862a8b013fd56d7a7ddd6f8b253a8f978 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 12 Feb 2024 10:53:25 -0500 Subject: [PATCH 5927/6505] Update alpine-docker-install.sh add option to install Portainer Agent --- install/alpine-docker-install.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh index 5fa141b2..61cc27f7 100644 --- a/install/alpine-docker-install.sh +++ b/install/alpine-docker-install.sh @@ -32,12 +32,13 @@ get_latest_release() { } PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose") +PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent") read -r -p "Would you like to add Portainer? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" docker volume create portainer_data >/dev/null - $STD docker run -d \ + $STD docker run -d \ -p 8000:8000 \ -p 9443:9443 \ --name=portainer \ @@ -46,8 +47,20 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then -v portainer_data:/data \ portainer/portainer-ce:latest msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" +else + read -r -p "Would you like to add the Portainer Agent? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION" + $STD docker run -d \ + -p 9001:9001 \ + --name portainer_agent \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /var/lib/docker/volumes:/var/lib/docker/volumes \ + portainer/agent + msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" + fi fi - read -r -p "Would you like to add Docker Compose? " prompt if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" From 966ab2d26e880b0bfbc554c67f6238344baf56a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Feb 2024 05:35:43 -0500 Subject: [PATCH 5928/6505] Update post-pve-install.sh - add both Quincy and Reef Ceph repositories, both initially disabled - fixes https://github.com/tteck/Proxmox/issues/2484 --- misc/post-pve-install.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 18b86ca2..9b7380b3 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -99,7 +99,7 @@ EOF esac if [[ "${VERSION}" == "bookworm" ]]; then - CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription'(enabled) and 'enterprise'(disabled) repositories.\n \nCorrect 'ceph package sources?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nCorrect 'ceph package sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in @@ -107,7 +107,9 @@ EOF msg_info "Enabling 'ceph package repositories'" cat </etc/apt/sources.list.d/ceph.list # deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise -deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription +# deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription +# deb http://download.proxmox.com/debian/ceph-reef bookworm enterprise +# deb http://download.proxmox.com/debian/ceph-reef bookworm no-subscription EOF msg_ok "Enabled 'ceph package repositories'" ;; From 5d64448ac20efec2cc0ea6d1c45e5332b87acca2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 13 Feb 2024 05:46:59 -0500 Subject: [PATCH 5929/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 9b7380b3..21409e64 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -104,17 +104,17 @@ EOF "no" " " 3>&2 2>&1 1>&3) case $CHOICE in yes) - msg_info "Enabling 'ceph package repositories'" + msg_info "Correcting 'ceph package repositories'" cat </etc/apt/sources.list.d/ceph.list # deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise # deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription # deb http://download.proxmox.com/debian/ceph-reef bookworm enterprise # deb http://download.proxmox.com/debian/ceph-reef bookworm no-subscription EOF - msg_ok "Enabled 'ceph package repositories'" + msg_ok "Corrected 'ceph package repositories'" ;; no) - msg_error "Selected no to Enabling 'ceph package repositories'" + msg_error "Selected no to Correcting 'ceph package repositories'" ;; esac fi From 12454bdba78970b572505ea2c3412d4678ba39fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 14 Feb 2024 13:27:19 -0500 Subject: [PATCH 5930/6505] Update grocy.sh fixes https://github.com/tteck/Proxmox/issues/2496 --- ct/grocy.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ct/grocy.sh b/ct/grocy.sh index b9c11170..f28a9200 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -56,6 +56,11 @@ function update_script() { header_info if [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" +php_version=$(php -v | head -n 1 | awk '{print $2}') +if [[ ! $php_version == "8.3"* ]]; then + apt-get install -y php8.3 + update-alternatives --set php /usr/bin/php8.3 +fi bash /var/www/html/update.sh msg_ok "Updated Successfully" exit From 4d06a6019bc2b6fcd7007d43167c5c400db7f866 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Feb 2024 04:47:59 -0500 Subject: [PATCH 5931/6505] Update grocy.sh tweak --- ct/grocy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/grocy.sh b/ct/grocy.sh index f28a9200..153e760a 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -58,6 +58,7 @@ if [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then msg_error "No ${APP} msg_info "Updating ${APP}" php_version=$(php -v | head -n 1 | awk '{print $2}') if [[ ! $php_version == "8.3"* ]]; then + apt-get update apt-get install -y php8.3 update-alternatives --set php /usr/bin/php8.3 fi From c65bd939eb0722538e6d252a89f2cd7a3da17917 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Feb 2024 07:32:28 -0500 Subject: [PATCH 5932/6505] Update homeassistant-core.sh fixes https://github.com/tteck/Proxmox/issues/2501 --- ct/homeassistant-core.sh | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index b6567eb8..dbbfa463 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -107,12 +107,23 @@ function update_script() { exit fi if [ "$UPD" == "3" ]; then + read -r -p "Would you like to use No Authentication? " prompt msg_info "Installing FileBrowser" RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') - curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null - filebrowser config init -a '0.0.0.0' &>/dev/null - filebrowser config set -a '0.0.0.0' &>/dev/null - filebrowser users add admin changeme --perm.admin &>/dev/null + curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null + + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + filebrowser config init -a '0.0.0.0' &>/dev/null + filebrowser config set -a '0.0.0.0' &>/dev/null + filebrowser config init --auth.method=noauth &>/dev/null + filebrowser config set --auth.method=noauth &>/dev/null + filebrowser users add ID 1 --perm.admin &>/dev/null + else + filebrowser config init -a '0.0.0.0' &>/dev/null + filebrowser config set -a '0.0.0.0' &>/dev/null + filebrowser users add admin changeme --perm.admin &>/dev/null + fi + fi msg_ok "Installed FileBrowser" msg_info "Creating Service" From 15b8d2ec16a2295602600bc58775faed7ca76135 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Feb 2024 07:37:00 -0500 Subject: [PATCH 5933/6505] Update homeassistant-core.sh tweak --- ct/homeassistant-core.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index dbbfa463..884346fb 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -122,8 +122,7 @@ function update_script() { filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null filebrowser users add admin changeme --perm.admin &>/dev/null - fi - fi + fi msg_ok "Installed FileBrowser" msg_info "Creating Service" From d514c841932fffac840202c15b4b3b99f5284b47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Feb 2024 08:04:47 -0500 Subject: [PATCH 5934/6505] Update homeassistant-core.sh tweak --- ct/homeassistant-core.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 884346fb..d6fac29a 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -107,6 +107,7 @@ function update_script() { exit fi if [ "$UPD" == "3" ]; then + set +Eeuo pipefail read -r -p "Would you like to use No Authentication? " prompt msg_info "Installing FileBrowser" RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') From 1ccac3050b6a9c94953cd1c7c500f5c0a8db5f7d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Feb 2024 08:11:45 -0500 Subject: [PATCH 5935/6505] Update homeassistant-core.sh tweak --- ct/homeassistant-core.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index d6fac29a..738e2ea1 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -116,7 +116,6 @@ function update_script() { if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then filebrowser config init -a '0.0.0.0' &>/dev/null filebrowser config set -a '0.0.0.0' &>/dev/null - filebrowser config init --auth.method=noauth &>/dev/null filebrowser config set --auth.method=noauth &>/dev/null filebrowser users add ID 1 --perm.admin &>/dev/null else From 0002741cde0dc620ac9502f7d7ad736f3970e296 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 15 Feb 2024 23:04:55 -0500 Subject: [PATCH 5936/6505] Create fstrim.sh --- misc/fstrim.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 misc/fstrim.sh diff --git a/misc/fstrim.sh b/misc/fstrim.sh new file mode 100644 index 00000000..74134234 --- /dev/null +++ b/misc/fstrim.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info() { + clear + cat <<"EOF" + _______ __ __ ______ _ + / ____(_) /__ _______ _______/ /____ ____ ___ /_ __/____(_)___ ___ + / /_ / / / _ \/ ___/ / / / ___/ __/ _ \/ __ `__ \ / / / ___/ / __ `__ \ + / __/ / / / __(__ ) /_/ (__ ) /_/ __/ / / / / / / / / / / / / / / / / +/_/ /_/_/\___/____/\__, /____/\__/\___/_/ /_/ /_/ /_/ /_/ /_/_/ /_/ /_/ + /____/ +EOF +} +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +CM='\xE2\x9C\x94\033' +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +header_info +echo "Loading..." + +ROOT_FS=$(df -Th "/" | awk 'NR==2 {print $2}') +if [ "$ROOT_FS" != "ext4" ]; then + echo "Root filesystem is not ext4. Exiting script." + exit 1 +fi + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Filesystem Trim" --yesno "The selected containers will undergo the fstrim command. Proceed?" 10 58 || exit +NODE=$(hostname) +EXCLUDE_MENU=() +MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') +excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from trimming:\n" \ + 16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit + +function trim_container() { + local container=$1 + local name=$(pct exec "$container" hostname) + header_info + echo -e "${BL}[Info]${GN} Trimming ${name} ${CL} \n" + pct fstrim $container + sleep 1 +} + +for container in $(pct list | awk '{if(NR>1) print $1}'); do + if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}" + sleep 1 + else + template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") + if [ "$template" == "true" ]; then + header_info + echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container is a template ${CL} \n" + sleep 1 + continue + fi + trim_container $container + fi +done + +wait +header_info +echo -e "${GN} Finished, Selected Containers Trimmed. ${CL} \n" From 13ebab39971de888911d14a5b879586b6b138d95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 16 Feb 2024 10:49:37 -0500 Subject: [PATCH 5937/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4c33cad..d1439788 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-02-16 + +### Changed + +- **Proxmox VE LXC Filesystem Trim** + - NEW Script ([more info](https://github.com/tteck/Proxmox/discussions/2505#discussion-6226037)) + ## 2024-02-11 ### Changed From 8ce0ad13ab1618c36cd4a80a894a1bfa4c784645 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Feb 2024 05:47:38 -0500 Subject: [PATCH 5938/6505] Update fstrim.sh tweak --- misc/fstrim.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/fstrim.sh b/misc/fstrim.sh index 74134234..d6fcecb1 100644 --- a/misc/fstrim.sh +++ b/misc/fstrim.sh @@ -30,7 +30,7 @@ if [ "$ROOT_FS" != "ext4" ]; then exit 1 fi -whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Filesystem Trim" --yesno "The selected containers will undergo the fstrim command. Proceed?" 10 58 || exit +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Filesystem Trim" --yesno "The LXC containers will undergo the fstrim command. Proceed?" 10 58 || exit NODE=$(hostname) EXCLUDE_MENU=() MSG_MAX_LENGTH=0 @@ -70,4 +70,4 @@ done wait header_info -echo -e "${GN} Finished, Selected Containers Trimmed. ${CL} \n" +echo -e "${GN} Finished, LXC Containers Trimmed. ${CL} \n" From c7cf925187884417b3687085eb368e60f14e7f1f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Feb 2024 13:08:07 -0500 Subject: [PATCH 5939/6505] Update fstrim.sh display the data percentage used before and after trimming --- misc/fstrim.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/misc/fstrim.sh b/misc/fstrim.sh index d6fcecb1..e413961a 100644 --- a/misc/fstrim.sh +++ b/misc/fstrim.sh @@ -47,8 +47,12 @@ function trim_container() { local name=$(pct exec "$container" hostname) header_info echo -e "${BL}[Info]${GN} Trimming ${name} ${CL} \n" + local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"$container"'/) {gsub(/%/, "", $7); print $7}') + echo -e "${RD}Data before trim $before_trim%${CL}" pct fstrim $container - sleep 1 + local after_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"$container"'/) {gsub(/%/, "", $7); print $7}') + echo -e "${GN}Data after trim $after_trim%${CL}" + sleep 1.5 } for container in $(pct list | awk '{if(NR>1) print $1}'); do From 86da4aaabb15956aa0cbc10c53d80cb18c4024b4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Feb 2024 15:58:34 -0500 Subject: [PATCH 5940/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 21409e64..ad2227a1 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -99,7 +99,7 @@ EOF esac if [[ "${VERSION}" == "bookworm" ]]; then - CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\n \nCorrect 'ceph package sources?" 14 58 2 \ + CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories (initially disabled).\n \nCorrect 'ceph package sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) case $CHOICE in From c702652a000056c0d9189bffa8b6111b5088b0bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Feb 2024 15:59:54 -0500 Subject: [PATCH 5941/6505] Update fstrim.sh tweak --- misc/fstrim.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/fstrim.sh b/misc/fstrim.sh index e413961a..06430eee 100644 --- a/misc/fstrim.sh +++ b/misc/fstrim.sh @@ -44,7 +44,7 @@ excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title " function trim_container() { local container=$1 - local name=$(pct exec "$container" hostname) + local name=$(pct exec "$container" hostname 2>/dev/null || echo "No hostname because the container is not running") header_info echo -e "${BL}[Info]${GN} Trimming ${name} ${CL} \n" local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"$container"'/) {gsub(/%/, "", $7); print $7}') From 94cf9da7a1b23b5189b2b5a379b13a97bc8be94c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Feb 2024 19:50:07 -0500 Subject: [PATCH 5942/6505] Update mikrotik-routeros.sh add zfspool --- vm/mikrotik-routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 5c38d9ed..20fd1b92 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -251,7 +251,7 @@ nfs | dir) DISK_REF="$VMID/" DISK_IMPORT="-format qcow2" ;; -btrfs) +btrfs | zfspool) DISK_EXT=".raw" DISK_REF="$VMID/" DISK_FORMAT="subvol" From 8d55efd704e321f38aeba19004396e234774b61d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 17 Feb 2024 20:07:03 -0500 Subject: [PATCH 5943/6505] Update mikrotik-routeros.sh tweak --- vm/mikrotik-routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 20fd1b92..6f37776a 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -252,7 +252,7 @@ nfs | dir) DISK_IMPORT="-format qcow2" ;; btrfs | zfspool) - DISK_EXT=".raw" + DISK_EXT="" DISK_REF="$VMID/" DISK_FORMAT="subvol" DISK_IMPORT="-format raw" From a5b3aab72e466e7ec56bd100445777c5b8c54c87 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 09:51:55 -0500 Subject: [PATCH 5944/6505] Update fstrim.sh tweak --- misc/fstrim.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/fstrim.sh b/misc/fstrim.sh index 06430eee..b3fc2c52 100644 --- a/misc/fstrim.sh +++ b/misc/fstrim.sh @@ -47,14 +47,16 @@ function trim_container() { local name=$(pct exec "$container" hostname 2>/dev/null || echo "No hostname because the container is not running") header_info echo -e "${BL}[Info]${GN} Trimming ${name} ${CL} \n" - local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"$container"'/) {gsub(/%/, "", $7); print $7}') + local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"vm-$container"'/) {gsub(/%/, "", $7); print $7}') echo -e "${RD}Data before trim $before_trim%${CL}" pct fstrim $container - local after_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"$container"'/) {gsub(/%/, "", $7); print $7}') + local after_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"vm-$container"'/) {gsub(/%/, "", $7); print $7}') echo -e "${GN}Data after trim $after_trim%${CL}" sleep 1.5 } + + for container in $(pct list | awk '{if(NR>1) print $1}'); do if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then header_info From faad7f25cc85ca7a7d5190c389cc8c58376b1353 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 16:39:18 -0500 Subject: [PATCH 5945/6505] Update heimdalldashboard-install.sh test --- install/heimdalldashboard-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index afe39d6f..b909c201 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -27,7 +27,8 @@ $STD apt-get install -y php-xml $STD apt-get install -y php-intl msg_ok "Installed PHP" -RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +#RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +RELEASE=v2.5.8 msg_info "Installing Heimdall Dashboard ${RELEASE}" $STD curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" $STD tar xvzf ${RELEASE}.tar.gz From d806d87cfd9a033379a658b36abf4589996b1466 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 16:46:21 -0500 Subject: [PATCH 5946/6505] Update heimdalldashboard-install.sh test --- install/heimdalldashboard-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index b909c201..0281b262 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -32,9 +32,8 @@ RELEASE=v2.5.8 msg_info "Installing Heimdall Dashboard ${RELEASE}" $STD curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" $STD tar xvzf ${RELEASE}.tar.gz -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') +#VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +VER=2.5.8 rm -rf ${RELEASE}.tar.gz mv Heimdall-${VER} /opt/Heimdall msg_ok "Installed Heimdall Dashboard ${RELEASE}" From eb7491c6c19036473cdbf028cda831adc899311e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 17:12:01 -0500 Subject: [PATCH 5947/6505] Update heimdalldashboard-install.sh hard code v2.5.8 --- install/heimdalldashboard-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index 0281b262..75a29271 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -28,10 +28,10 @@ $STD apt-get install -y php-intl msg_ok "Installed PHP" #RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -RELEASE=v2.5.8 +RELEASE=V2.5.8 msg_info "Installing Heimdall Dashboard ${RELEASE}" -$STD curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" -$STD tar xvzf ${RELEASE}.tar.gz +wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz +tar xzf ${RELEASE}.tar.gz #VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') VER=2.5.8 rm -rf ${RELEASE}.tar.gz @@ -55,7 +55,7 @@ TimeoutStopSec=30 [Install] WantedBy=multi-user.target" >$service_path -$STD sudo systemctl enable --now heimdall.service +systemctl enable -q --now heimdall.service msg_ok "Created Service" motd_ssh From ccadb0d92ea69326ad155d2cb0b3b9bb746fdef1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 17:52:10 -0500 Subject: [PATCH 5948/6505] Update heimdalldashboard-install.sh php8.3 --- install/heimdalldashboard-install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index 75a29271..18a2cedb 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -17,15 +17,15 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" -msg_info "Installing PHP" -$STD apt-get install -y php -$STD apt-get install -y php-sqlite3 -$STD apt-get install -y php-zip -$STD apt-get install -y php-xml -$STD apt-get install -y php-intl -msg_ok "Installed PHP" +msg_info "Installing PHP8.3" +curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg +echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bookworm main" >/etc/apt/sources.list.d/php.list +$STD apt-get update +$STD apt-get install -y php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,sqlite3,zip,xml} +msg_ok "Installed PHP8.3" #RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') RELEASE=V2.5.8 From e880a9d8dbdefab2ab476720b46efeba15b82691 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 18:23:56 -0500 Subject: [PATCH 5949/6505] Update grocy.sh recode update function --- ct/grocy.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ct/grocy.sh b/ct/grocy.sh index 153e760a..fc48644b 100644 --- a/ct/grocy.sh +++ b/ct/grocy.sh @@ -55,13 +55,18 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP}" php_version=$(php -v | head -n 1 | awk '{print $2}') if [[ ! $php_version == "8.3"* ]]; then - apt-get update - apt-get install -y php8.3 - update-alternatives --set php /usr/bin/php8.3 + msg_info "Updating PHP" + curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg + echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bookworm main" >/etc/apt/sources.list.d/php.list + apt-get update + apt-get install -y php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} + systemctl reload apache2 + apt autoremove + msg_ok "Updated PHP" fi +msg_info "Updating ${APP}" bash /var/www/html/update.sh msg_ok "Updated Successfully" exit From 147d0ac8db7ac4db73f468f21866c610578a0751 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 18:25:35 -0500 Subject: [PATCH 5950/6505] Update grocy-install.sh php8.3 --- install/grocy-install.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 091fa8d8..015c60ea 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -20,18 +20,13 @@ $STD apt-get install -y mc $STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" -msg_info "Installing PHP 8.2" +msg_info "Installing PHP8.3" VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg echo -e "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main" >/etc/apt/sources.list.d/php.list $STD apt-get update -$STD apt-get install -y php8.2 -$STD apt-get install -y libapache2-mod-php8.2 -$STD apt-get install -y php8.2-sqlite3 -$STD apt-get install -y php8.2-gd -$STD apt-get install -y php8.2-intl -$STD apt-get install -y php8.2-mbstring -msg_ok "Installed PHP 8.2" +$STD apt-get install -y php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} +msg_ok "Installed PHP8.3" msg_info "Installing grocy" latest=$(curl -s https://api.github.com/repos/grocy/grocy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') From be77d96cce6b0d1227e57a2238b03221e6f51786 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 18:38:05 -0500 Subject: [PATCH 5951/6505] Update grocy-install.sh tweak --- install/grocy-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 015c60ea..57d38b21 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -25,7 +25,9 @@ VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg echo -e "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main" >/etc/apt/sources.list.d/php.list $STD apt-get update -$STD apt-get install -y php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} +$STD apt-get install -y php8.3 php8.3-{cli.bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} +a2enconf php8.3-fpm +systemctl reload apache2 msg_ok "Installed PHP8.3" msg_info "Installing grocy" From 75bcbacd9ca996e2b317e0f045c4e4e88b75d9cd Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 18:40:42 -0500 Subject: [PATCH 5952/6505] Update grocy-install.sh --- install/grocy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 57d38b21..54ea2300 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -25,7 +25,7 @@ VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg echo -e "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main" >/etc/apt/sources.list.d/php.list $STD apt-get update -$STD apt-get install -y php8.3 php8.3-{cli.bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} +$STD apt-get install -y php8.3 php8.3-{cli,bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} a2enconf php8.3-fpm systemctl reload apache2 msg_ok "Installed PHP8.3" From a804d47d2d14c7486aa4deeb35730c1bfd491d85 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 18:41:59 -0500 Subject: [PATCH 5953/6505] Update grocy-install.sh --- install/grocy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index 54ea2300..d86366a9 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -26,7 +26,7 @@ curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/ph echo -e "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main" >/etc/apt/sources.list.d/php.list $STD apt-get update $STD apt-get install -y php8.3 php8.3-{cli,bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} -a2enconf php8.3-fpm +$STD a2enconf php8.3-fpm systemctl reload apache2 msg_ok "Installed PHP8.3" From ceb3a131bffe70c71f66360190f6810401bd4b55 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 18:47:07 -0500 Subject: [PATCH 5954/6505] Update grocy-install.sh revert to PHP8.2 --- install/grocy-install.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/install/grocy-install.sh b/install/grocy-install.sh index d86366a9..f3dc7f57 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -20,15 +20,18 @@ $STD apt-get install -y mc $STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" -msg_info "Installing PHP8.3" +msg_info "Installing PHP8.2" VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg echo -e "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main" >/etc/apt/sources.list.d/php.list $STD apt-get update -$STD apt-get install -y php8.3 php8.3-{cli,bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml} -$STD a2enconf php8.3-fpm -systemctl reload apache2 -msg_ok "Installed PHP8.3" +$STD apt-get install -y php8.2 +$STD apt-get install -y libapache2-mod-php8.2 +$STD apt-get install -y php8.2-sqlite3 +$STD apt-get install -y php8.2-gd +$STD apt-get install -y php8.2-intl +$STD apt-get install -y php8.2-mbstring +msg_ok "Installed PHP8.2" msg_info "Installing grocy" latest=$(curl -s https://api.github.com/repos/grocy/grocy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') From 05c8093bd7f51e1586c4cabe732a6fc7b80687fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 19:39:58 -0500 Subject: [PATCH 5955/6505] Update heimdalldashboard.sh add warning --- ct/heimdalldashboard.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index b2d0645a..98ff9f22 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -55,6 +55,7 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/Heimdall ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "WARNING" "Currently, v2.6.0 breaks the application." 8 58 msg_info "Stopping ${APP}" systemctl disable heimdall.service &>/dev/null systemctl stop heimdall From b7bfe7df1436f655a3bf3eae24bd210095d96541 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 18 Feb 2024 20:46:59 -0500 Subject: [PATCH 5956/6505] Update heimdalldashboard.sh update warning --- ct/heimdalldashboard.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 98ff9f22..39fd7ba3 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -55,7 +55,11 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/Heimdall ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "WARNING" "Currently, v2.6.0 breaks the application." 8 58 +if ! whiptail --backtitle "Proxmox VE Helper Scripts" --title "WARNING" --yesno "Currently, v2.6.0 breaks the application. Proceed?" 10 58; then + clear + echo -e "⚠ User exited script \n" + exit +fi msg_info "Stopping ${APP}" systemctl disable heimdall.service &>/dev/null systemctl stop heimdall From b082f8a08e3b4e597bf069306194f597709c469c Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Feb 2024 04:43:10 -0500 Subject: [PATCH 5957/6505] Update fstrim.sh display CTID instead of hostname --- misc/fstrim.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/misc/fstrim.sh b/misc/fstrim.sh index b3fc2c52..6b445667 100644 --- a/misc/fstrim.sh +++ b/misc/fstrim.sh @@ -44,9 +44,8 @@ excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title " function trim_container() { local container=$1 - local name=$(pct exec "$container" hostname 2>/dev/null || echo "No hostname because the container is not running") header_info - echo -e "${BL}[Info]${GN} Trimming ${name} ${CL} \n" + echo -e "${BL}[Info]${GN} Trimming ${container} ${CL} \n" local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"vm-$container"'/) {gsub(/%/, "", $7); print $7}') echo -e "${RD}Data before trim $before_trim%${CL}" pct fstrim $container @@ -66,7 +65,7 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do template=$(pct config $container | grep -q "template:" && echo "true" || echo "false") if [ "$template" == "true" ]; then header_info - echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container is a template ${CL} \n" + echo -e "${BL}[Info]${GN} Skipping ${container} ${RD}$container is a template ${CL} \n" sleep 1 continue fi From 9478fffd5a0fbf87e869ceececa4377f9d5d3e17 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Feb 2024 13:13:44 -0500 Subject: [PATCH 5958/6505] Update fstrim.sh tweak --- misc/fstrim.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/fstrim.sh b/misc/fstrim.sh index 6b445667..5c0e2ae6 100644 --- a/misc/fstrim.sh +++ b/misc/fstrim.sh @@ -45,7 +45,7 @@ excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title " function trim_container() { local container=$1 header_info - echo -e "${BL}[Info]${GN} Trimming ${container} ${CL} \n" + echo -e "${BL}[Info]${GN} Trimming ${BL}$container${CL} \n" local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'"vm-$container"'/) {gsub(/%/, "", $7); print $7}') echo -e "${RD}Data before trim $before_trim%${CL}" pct fstrim $container From 822299b61030cfe291cd6b001be77505e7af40f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Feb 2024 13:27:56 -0500 Subject: [PATCH 5959/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1439788..28ce67a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-02-19 + +### Changed + +- **PairDrop LXC** + - Removed from the website ([more info](https://github.com/tteck/Proxmox/discussions/2516)) + ## 2024-02-16 ### Changed From 4aa5e12268e6ffad3a38601801c89aeba548f0dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Feb 2024 18:22:38 -0500 Subject: [PATCH 5960/6505] Update heimdalldashboard-install.sh release version hold --- install/heimdalldashboard-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index 18a2cedb..f101ba17 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -27,15 +27,14 @@ $STD apt-get update $STD apt-get install -y php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,sqlite3,zip,xml} msg_ok "Installed PHP8.3" -#RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -RELEASE=V2.5.8 +RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') msg_info "Installing Heimdall Dashboard ${RELEASE}" wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz tar xzf ${RELEASE}.tar.gz -#VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -VER=2.5.8 +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') rm -rf ${RELEASE}.tar.gz mv Heimdall-${VER} /opt/Heimdall +$STD apt-get install -y composer msg_ok "Installed Heimdall Dashboard ${RELEASE}" msg_info "Creating Service" @@ -56,6 +55,9 @@ TimeoutStopSec=30 [Install] WantedBy=multi-user.target" >$service_path systemctl enable -q --now heimdall.service +cd /opt/Heimdall +COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null +systemctl restart heimdall.service msg_ok "Created Service" motd_ssh From a4be2339535ad37a84e750739b9beb1d9160f937 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Feb 2024 18:24:40 -0500 Subject: [PATCH 5961/6505] Update heimdalldashboard.sh recode update function --- ct/heimdalldashboard.sh | 68 +++++++---------------------------------- 1 file changed, 11 insertions(+), 57 deletions(-) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index 39fd7ba3..bdc4889c 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -55,82 +55,36 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/Heimdall ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -if ! whiptail --backtitle "Proxmox VE Helper Scripts" --title "WARNING" --yesno "Currently, v2.6.0 breaks the application. Proceed?" 10 58; then - clear - echo -e "⚠ User exited script \n" - exit -fi msg_info "Stopping ${APP}" -systemctl disable heimdall.service &>/dev/null systemctl stop heimdall sleep 1 msg_ok "Stopped ${APP}" msg_info "Backing up Data" -if [ -d "/opt/Heimdall-2.4.6" ]; then - cp -R /opt/Heimdall-2.4.6/database database-backup - cp -R /opt/Heimdall-2.4.6/public public-backup -elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then - cp -R /opt/Heimdall-2.4.7b/database database-backup - cp -R /opt/Heimdall-2.4.7b/public public-backup -elif [[ -d "/opt/Heimdall-2.4.8" ]]; then - cp -R /opt/Heimdall-2.4.8/database database-backup - cp -R /opt/Heimdall-2.4.8/public public-backup -else - cp -R /opt/Heimdall/database database-backup - cp -R /opt/Heimdall/public public-backup -fi +cp -R /opt/Heimdall/database database-backup +cp -R /opt/Heimdall/public public-backup sleep 1 msg_ok "Backed up Data" RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') msg_info "Updating Heimdall Dashboard to ${RELEASE}" -curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" &>/dev/null -tar xvzf ${RELEASE}.tar.gz &>/dev/null -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | - grep "tag_name" | - awk '{print substr($2, 3, length($2)-4) }') - -if [ ! -d "/opt/Heimdall" ]; then - mv Heimdall-${VER} /opt/Heimdall -else - cp -R Heimdall-${VER}/* /opt/Heimdall -fi - -service_path="/etc/systemd/system/heimdall.service" -echo "[Unit] -Description=Heimdall -After=network.target -[Service] -Restart=always -RestartSec=5 -Type=simple -User=root -WorkingDirectory=/opt/Heimdall -ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0 -TimeoutStopSec=30 -[Install] -WantedBy=multi-user.target" >$service_path +wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz +tar xzf ${RELEASE}.tar.gz +VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +cp -R Heimdall-${VER}/* /opt/Heimdall +cd /opt/Heimdall +apt-get install -y composer &>/dev/null +COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null msg_ok "Updated Heimdall Dashboard to ${RELEASE}" 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 "Cleanup" -if [ -d "/opt/Heimdall-2.4.6" ]; then - rm -rf /opt/Heimdall-2.4.6 - rm -rf /opt/v2.4.6.tar.gz -elif [[ -d "/opt/Heimdall-2.4.7b" ]]; then - rm -rf /opt/Heimdall-2.4.7b - rm -rf /opt/v2.4.7b.tar.gz -elif [[ -d "/opt/Heimdall-2.4.8" ]]; then - rm -rf /opt/Heimdall-2.4.8 - rm -rf /opt/v2.4.8.tar.gz -fi - rm -rf ${RELEASE}.tar.gz rm -rf Heimdall-${VER} rm -rf public-backup @@ -140,7 +94,7 @@ sleep 1 msg_ok "Cleaned" msg_info "Starting ${APP}" -systemctl enable --now heimdall.service &>/dev/null +systemctl start heimdall.service sleep 2 msg_ok "Started ${APP}" msg_ok "Updated Successfully" From 25a9708fe3baca8771d3bb5c7afe210a86a6f121 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 19 Feb 2024 22:03:57 -0500 Subject: [PATCH 5962/6505] Update heimdalldashboard-install.sh use php8.2 --- install/heimdalldashboard-install.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index f101ba17..50515b9c 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -18,15 +18,10 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y apt-transport-https +$STD apt-get install -y composer +$STD apt-get install -y php8.2-{bz2,curl,sqlite3,zip,xml} msg_ok "Installed Dependencies" -msg_info "Installing PHP8.3" -curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg -echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bookworm main" >/etc/apt/sources.list.d/php.list -$STD apt-get update -$STD apt-get install -y php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,sqlite3,zip,xml} -msg_ok "Installed PHP8.3" - RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') msg_info "Installing Heimdall Dashboard ${RELEASE}" wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz @@ -34,7 +29,6 @@ tar xzf ${RELEASE}.tar.gz VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') rm -rf ${RELEASE}.tar.gz mv Heimdall-${VER} /opt/Heimdall -$STD apt-get install -y composer msg_ok "Installed Heimdall Dashboard ${RELEASE}" msg_info "Creating Service" From 2171405dc6db9d683814219ac11336b8e31771c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Feb 2024 07:26:31 -0500 Subject: [PATCH 5963/6505] Update plex-install.sh update keyring location --- install/plex-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/plex-install.sh b/install/plex-install.sh index ca8dca63..394bb6f0 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -38,8 +38,8 @@ if [[ "$CTTYPE" == "0" ]]; then fi msg_info "Setting Up Plex Media Server Repository" -wget -qO- https://downloads.plex.tv/plex-keys/PlexSign.key >/etc/apt/trusted.gpg.d/PlexSign.asc -echo "deb [arch=$(dpkg --print-architecture)] https://downloads.plex.tv/repo/deb/ public main" >/etc/apt/sources.list.d/plexmediaserver.list +wget -qO- https://downloads.plex.tv/plex-keys/PlexSign.key >/usr/share/keyrings/PlexSign.asc +echo "deb [signed-by=/usr/share/keyrings/PlexSign.asc] https://downloads.plex.tv/repo/deb/ public main" >/etc/apt/sources.list.d/plexmediaserver.list msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" From 35b57f4555166842547a99fed3675c4e8ba0c7f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Feb 2024 20:42:47 -0500 Subject: [PATCH 5964/6505] Update emby.sh Ubuntu 22.04 --- ct/emby.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/emby.sh b/ct/emby.sh index a063e0af..a8b5618a 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="ubuntu" -var_version="20.04" +var_version="22.04" variables color catch_errors From e23f2c60f8dd6acd75e4fe16bec7a2af0d4c3407 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Feb 2024 21:33:50 -0500 Subject: [PATCH 5965/6505] Update jellyfin-install.sh fix GID mismatch --- install/jellyfin-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index a8a61d20..fc918667 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -58,6 +58,7 @@ EOF # Install Jellyfin using the metapackage (which will fetch jellyfin-server, jellyfin-web, and jellyfin-ffmpeg5) $STD apt-get update $STD apt-get install -y jellyfin +sed -i '/^render:x:108:root,jellyfin$/d; s/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' /etc/group msg_ok "Installed Jellyfin" motd_ssh From ca280c5fac2db11c0c9758b1a91e767889a20133 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Feb 2024 21:35:20 -0500 Subject: [PATCH 5966/6505] Update emby-install.sh fix GID mismatch --- install/emby-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/emby-install.sh b/install/emby-install.sh index 9027437a..dda49ed9 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -42,6 +42,7 @@ LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releas msg_info "Installing Emby" wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb +sed -i '/^render:x:108:root,emby$/d; s/^ssl-cert:x:104:$/render:x:104:root,emby/' /etc/group msg_ok "Installed Emby" motd_ssh From f4bbf3bac038ef6505529488be88dbcf71a635f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Feb 2024 21:36:45 -0500 Subject: [PATCH 5967/6505] Update plex-install.sh fix GID mismatch --- install/plex-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/plex-install.sh b/install/plex-install.sh index 394bb6f0..64a895f3 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -45,6 +45,7 @@ msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver +sed -i '/^render:x:108:root$/d; s/^ssl-cert:x:104:plex$/render:x:104:root,plex/' /etc/group msg_ok "Installed Plex Media Server" motd_ssh From 8456deb1f8a3beebbe571cc0a7b912f055215882 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 20 Feb 2024 22:41:09 -0500 Subject: [PATCH 5968/6505] Improve GID mismatch fix - Emby - Jellyfin - Plex --- install/emby-install.sh | 2 +- install/jellyfin-install.sh | 2 +- install/plex-install.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/install/emby-install.sh b/install/emby-install.sh index dda49ed9..b4f6684b 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -42,7 +42,7 @@ LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releas msg_info "Installing Emby" wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb -sed -i '/^render:x:108:root,emby$/d; s/^ssl-cert:x:104:$/render:x:104:root,emby/' /etc/group +sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,emby/' -e 's/^render:x:108:root,emby$/ssl-cert:x:108:/' /etc/group msg_ok "Installed Emby" motd_ssh diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index fc918667..269daebd 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -58,7 +58,7 @@ EOF # Install Jellyfin using the metapackage (which will fetch jellyfin-server, jellyfin-web, and jellyfin-ffmpeg5) $STD apt-get update $STD apt-get install -y jellyfin -sed -i '/^render:x:108:root,jellyfin$/d; s/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' /etc/group +sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' -e 's/^render:x:108:root,jellyfin$/ssl-cert:x:108:/' /etc/group msg_ok "Installed Jellyfin" motd_ssh diff --git a/install/plex-install.sh b/install/plex-install.sh index 64a895f3..88ea2aca 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -45,7 +45,7 @@ msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver -sed -i '/^render:x:108:root$/d; s/^ssl-cert:x:104:plex$/render:x:104:root,plex/' /etc/group +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 msg_ok "Installed Plex Media Server" motd_ssh From 47b581ee38eca2f6952fb5d5e58843a9f5cbdbc5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 09:08:40 -0500 Subject: [PATCH 5969/6505] Update paperless-ngx-install.sh fixes https://github.com/tteck/Proxmox/issues/2525 --- install/paperless-ngx-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 5701601a..d4b12ca9 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -97,6 +97,7 @@ $STD python3 -m nltk.downloader -d /usr/share/nltk_data all msg_ok "Installed Natural Language Toolkit" msg_info "Setting up PostgreSQL database" +export LC_ALL=C.UTF-8 DB_NAME=paperlessdb DB_USER=paperless DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" From c0e3edc0c90479922583d98078b8fc43024e0946 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 11:05:58 -0500 Subject: [PATCH 5970/6505] Update install.func The script now checks IPv6 internet connectivity by attempting to ping "google.com" instead of Cloudflare's DNS IPv6 server address. --- misc/install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index f19e7f12..d6aaf6c4 100644 --- a/misc/install.func +++ b/misc/install.func @@ -130,7 +130,7 @@ network_check() { # Check if IPv6 is being used if ip -o -6 addr show | grep -q "scope global"; then - if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null; then + if ping -6 google.com &>/dev/null; then msg_ok "IPv6 Internet Connected"; else msg_error "IPv6 Internet Not Connected"; From 71ca43c7a2e7ca45f466034d3e2743329e895e7c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 12:19:48 -0500 Subject: [PATCH 5971/6505] Update install.func The script now checks for both IPv4 and IPv6 Internet connectivity and displays the results. Only if both IPv4 and IPv6 checks fail, it will then prompt the user. --- misc/install.func | 50 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/misc/install.func b/misc/install.func index d6aaf6c4..3deb63d1 100644 --- a/misc/install.func +++ b/misc/install.func @@ -112,35 +112,33 @@ setting_up_container() { network_check() { set +e trap - ERR -# Check if IPv4 is being used - if ip -o -4 addr show | grep -q "scope global"; then - if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then - msg_ok "IPv4 Internet Connected"; - else - msg_error "IPv4 Internet Not Connected"; - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi - fi + ipv4_connected=false + ipv6_connected=false + +# Check IPv4 connectivity + if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then + msg_ok "IPv4 Internet Connected"; + ipv4_connected=true + else + msg_error "IPv4 Internet Not Connected"; fi -# Check if IPv6 is being used - if ip -o -6 addr show | grep -q "scope global"; then - if ping -6 google.com &>/dev/null; then - msg_ok "IPv6 Internet Connected"; +# Check IPv6 connectivity + if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null; then + msg_ok "IPv6 Internet Connected"; + ipv6_connected=true + else + msg_error "IPv6 Internet Not Connected"; + fi + +# If both IPv4 and IPv6 checks fail, prompt the user + if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then + read -r -p "No Internet detected,would you like to continue anyway? " prompt + if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then + echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" else - msg_error "IPv6 Internet Not Connected"; - read -r -p "Would you like to continue anyway? " prompt - if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - echo -e " ⚠️ ${RD}Expect Issues Without Internet${CL}" - else - echo -e " 🖧 Check Network Settings" - exit 1 - fi + echo -e " 🖧 Check Network Settings" + exit 1 fi fi From 35bcc0e89440cf84ce46986098112fd592fb08b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 13:28:52 -0500 Subject: [PATCH 5972/6505] Update tdarr-install.sh fix GID mismatch --- install/tdarr-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index f666cb55..69321662 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -42,6 +42,7 @@ $STD unzip Tdarr_Updater.zip rm -rf Tdarr_Updater.zip chmod +x Tdarr_Updater ./Tdarr_Updater &>/dev/null +sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group msg_ok "Installed Tdarr" msg_info "Creating Service" From 779849f337ff78a8f318862d93f0dba82ab39917 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 13:44:40 -0500 Subject: [PATCH 5973/6505] Update scrypted-install.sh fix GID mismatch --- install/scrypted-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 60c05d38..a85c2271 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -110,6 +110,7 @@ fi msg_info "Installing Scrypted" $STD npx -y scrypted@latest install-server +sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group msg_ok "Installed Scrypted" msg_info "Creating Service" From fc41d79db4a321ce67bdd0e372b75cafddbc5169 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 14:10:55 -0500 Subject: [PATCH 5974/6505] Update channels-install.sh fix GID mismatch --- install/channels-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/channels-install.sh b/install/channels-install.sh index 7a2c6f7f..fcd6a65e 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -38,7 +38,7 @@ fi msg_info "Installing Channels DVR Server (Patience)" cd /opt $STD bash <(curl -fsSL https://getchannels.com/dvr/setup.sh) -# adduser $(id -u -n) video && adduser $(id -u -n) render +sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group msg_ok "Installed Channels DVR Server" motd_ssh From 26036763f7d53ed7a09513150b6bf72444fe4fa9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 14:21:01 -0500 Subject: [PATCH 5975/6505] Update unmanic-install.sh fix GID mismatch --- install/unmanic-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh index 6e9a6300..d5d1790a 100644 --- a/install/unmanic-install.sh +++ b/install/unmanic-install.sh @@ -37,6 +37,7 @@ fi msg_info "Installing Unmanic" $STD pip3 install unmanic +sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group msg_ok "Installed Unmanic" msg_info "Creating Service" From 6a0b31aee189598cea88fe6aaf5e61853e62ea24 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 15:10:23 -0500 Subject: [PATCH 5976/6505] Update channels-install.sh tweak --- install/channels-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/channels-install.sh b/install/channels-install.sh index fcd6a65e..548628af 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -25,7 +25,7 @@ if [[ "$CTTYPE" == "0" ]]; then msg_info "Setting Up Hardware Acceleration" $STD apt-get -y install \ va-driver-all \ - ocl-icd-libopencl1 \ + ocl-icd-libopencl1 \ intel-opencl-icd chgrp video /dev/dri chmod 755 /dev/dri From 8a057295938f7c74f67d27844a85ef38004160a7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 18:03:20 -0500 Subject: [PATCH 5977/6505] Update build.func Check if the shell is using bash shell --- misc/build.func | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/misc/build.func b/misc/build.func index ace1a3e6..98b4a97f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -82,6 +82,16 @@ check_root() { fi } +# Check if the shell is using bash +check_shell() { + if [[ "$(basename "$SHELL")" != "bash" ]]; then + msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell. + echo -e "\nExiting..." + sleep 2 + exit + fi +} + # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then From 8752a66c0317f49ca22925ead09291244b4be5df Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 18:21:51 -0500 Subject: [PATCH 5978/6505] Update build.func The use of the Bash shell is mandatory. --- misc/build.func | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/misc/build.func b/misc/build.func index 98b4a97f..410672cc 100644 --- a/misc/build.func +++ b/misc/build.func @@ -72,7 +72,7 @@ msg_error() { } # Run as root only -check_root() { +root_check() { if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then clear msg_error "Please run this script as root." @@ -83,7 +83,7 @@ check_root() { } # Check if the shell is using bash -check_shell() { +shell_check() { if [[ "$(basename "$SHELL")" != "bash" ]]; then msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell. echo -e "\nExiting..." @@ -460,10 +460,11 @@ advanced_settings() { } install_script() { - check_root - ssh_check - arch_check pve_check + shell_check + root_check + arch_check + ssh_check if systemctl is-active -q ping-instances.service; then systemctl -q stop ping-instances.service fi From 43de9ca99f8f007d01f2894f6e471c994d771455 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 18:26:12 -0500 Subject: [PATCH 5979/6505] Update build.func revert --- misc/build.func | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/misc/build.func b/misc/build.func index 410672cc..98b4a97f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -72,7 +72,7 @@ msg_error() { } # Run as root only -root_check() { +check_root() { if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then clear msg_error "Please run this script as root." @@ -83,7 +83,7 @@ root_check() { } # Check if the shell is using bash -shell_check() { +check_shell() { if [[ "$(basename "$SHELL")" != "bash" ]]; then msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell. echo -e "\nExiting..." @@ -460,11 +460,10 @@ advanced_settings() { } install_script() { - pve_check - shell_check - root_check - arch_check + check_root ssh_check + arch_check + pve_check if systemctl is-active -q ping-instances.service; then systemctl -q stop ping-instances.service fi From 998235e92da94844795cdb74e364d0353f1119cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 18:33:36 -0500 Subject: [PATCH 5980/6505] Update build.func revert --- misc/build.func | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/misc/build.func b/misc/build.func index 98b4a97f..ace1a3e6 100644 --- a/misc/build.func +++ b/misc/build.func @@ -82,16 +82,6 @@ check_root() { fi } -# Check if the shell is using bash -check_shell() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell. - echo -e "\nExiting..." - sleep 2 - exit - fi -} - # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then From 038f70f198c4f8d723b55930c183a0e401a4422b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 18:40:37 -0500 Subject: [PATCH 5981/6505] Update build.func To utilize these scripts, please switch to the Bash shell. --- misc/build.func | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/misc/build.func b/misc/build.func index ace1a3e6..f053639b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -82,6 +82,16 @@ check_root() { fi } +# Check if the shell is using bash +shell_check() { + if [[ "$(basename "$SHELL")" != "bash" ]]; then + msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell. + echo -e "\nExiting..." + sleep 2 + exit + fi +} + # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then @@ -450,6 +460,7 @@ advanced_settings() { } install_script() { + shell_check check_root ssh_check arch_check From f3e3958299d22416ae9e77ad1b4753f137563f02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 18:47:57 -0500 Subject: [PATCH 5982/6505] Update build.func --- misc/build.func | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/misc/build.func b/misc/build.func index f053639b..ace1a3e6 100644 --- a/misc/build.func +++ b/misc/build.func @@ -82,16 +82,6 @@ check_root() { fi } -# Check if the shell is using bash -shell_check() { - if [[ "$(basename "$SHELL")" != "bash" ]]; then - msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell. - echo -e "\nExiting..." - sleep 2 - exit - fi -} - # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then @@ -460,7 +450,6 @@ advanced_settings() { } install_script() { - shell_check check_root ssh_check arch_check From 0b604d204a174e567477e38ef75c6e4f1e90a9a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 19:51:36 -0500 Subject: [PATCH 5983/6505] Update build.func Check if the shell is using bash (retry) --- misc/build.func | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index ace1a3e6..fa98059e 100644 --- a/misc/build.func +++ b/misc/build.func @@ -71,8 +71,19 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" } +# Check if the shell is using bash +shell_check() { + if [[ "$(basename "$SHELL")" != "bash" ]]; then + clear + msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + # Run as root only -check_root() { +root_check() { if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then clear msg_error "Please run this script as root." @@ -450,10 +461,12 @@ advanced_settings() { } install_script() { - check_root - ssh_check - arch_check pve_check + shell_check + root_check + arch_check + ssh_check + if systemctl is-active -q ping-instances.service; then systemctl -q stop ping-instances.service fi From 27adffcbcb32c7d8a7e15364400f619f5095612a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 21 Feb 2024 20:47:15 -0500 Subject: [PATCH 5984/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28ce67a6..c90527ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,13 @@ ### Changed +- **All scripts** + - As of today, the scripts require the Bash shell specifically. ([more info](https://github.com/tteck/Proxmox/discussions/2536)) + +## 2024-02-19 + +### Changed + - **PairDrop LXC** - Removed from the website ([more info](https://github.com/tteck/Proxmox/discussions/2516)) From 03fbdbe74fed56a77bff1d2c9043b6a40433753f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Feb 2024 09:31:08 -0500 Subject: [PATCH 5985/6505] Update stirling-pdf-install.sh fixes https://github.com/tteck/Proxmox/issues/2540 --- install/stirling-pdf-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index 43cb89a8..cc26eec7 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -83,6 +83,7 @@ touch /opt/Stirling-PDF/.env mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ mv scripts /opt/Stirling-PDF/ ln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar +ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata msg_ok "Installed Stirling-PDF v$RELEASE" msg_info "Creating Service" From 57fca777b6ad390955600bd682eb125b5f61cc4b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Feb 2024 13:44:02 -0500 Subject: [PATCH 5986/6505] Update jellyfin-install.sh - add vainfo and intel-gpu-tools - code refactoring --- install/jellyfin-install.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index 269daebd..8b654903 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -22,14 +22,7 @@ msg_ok "Installed Dependencies" if [[ "$CTTYPE" == "0" ]]; then msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then - $STD apt-get install -y beignet-opencl-icd - else - $STD apt-get install -y intel-opencl-icd - fi + $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* From c6b13d0a36112f1d3906a2c5004c4f202b013f86 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Feb 2024 13:46:23 -0500 Subject: [PATCH 5987/6505] Update plex-install.sh - add vainfo and intel-gpu-tools - code refactoring --- install/plex-install.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/install/plex-install.sh b/install/plex-install.sh index 88ea2aca..fd6f0089 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -21,14 +21,7 @@ msg_ok "Installed Dependencies" if [[ "$CTTYPE" == "0" ]]; then msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then - $STD apt-get install -y beignet-opencl-icd - else - $STD apt-get install -y intel-opencl-icd - fi + $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* From ffb58a51111ba9aba26ad388724ca415de499a72 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Feb 2024 13:52:27 -0500 Subject: [PATCH 5988/6505] Update emby-install.sh - add vainfo and intel-gpu-tools - code refactoring --- install/emby-install.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/install/emby-install.sh b/install/emby-install.sh index b4f6684b..72158183 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -21,14 +21,7 @@ msg_ok "Installed Dependencies" if [[ "$CTTYPE" == "0" ]]; then msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 - if [[ ${PCT_OSVERSION} == "20.04" ]]; then - $STD apt-get install -y beignet-opencl-icd - else - $STD apt-get install -y intel-opencl-icd - fi + $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* From 9d9620249f8f501a6c969d6829f5d0ebec761a05 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 22 Feb 2024 23:44:30 -0500 Subject: [PATCH 5989/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index fa98059e..968cb83e 100644 --- a/misc/build.func +++ b/misc/build.func @@ -75,7 +75,7 @@ msg_error() { shell_check() { if [[ "$(basename "$SHELL")" != "bash" ]]; then clear - msg_error "Your current shell is not Bash. To utilize these scripts, please switch to the Bash shell." + msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." echo -e "\nExiting..." sleep 2 exit From 2d01721a759fd4401fecb5a1840c880e6aee02a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Feb 2024 01:22:11 -0500 Subject: [PATCH 5990/6505] Update CHANGELOG.md fix date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c90527ba..0f956a7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** -## 2024-02-19 +## 2024-02-21 ### Changed From f5f28231a74693eea6a38dea2b6476e2fb0317a8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Feb 2024 15:12:30 -0500 Subject: [PATCH 5991/6505] Update build.func tweak SSH message --- misc/build.func | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/misc/build.func b/misc/build.func index 968cb83e..604b0468 100644 --- a/misc/build.func +++ b/misc/build.func @@ -119,14 +119,13 @@ arch_check() { # This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit. ssh_check() { - if command -v pveversion >/dev/null 2>&1; then - if [ -n "${SSH_CLIENT:+x}" ]; then - if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then - echo "you've been warned" - else - clear - exit - fi + if command -v pveversion >/dev/null 2>&1 && [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?" 10 72; then + whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proceed using SSH" "You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue." 10 72 + else + clear + echo "Exiting due to SSH usage. Please consider using the Proxmox shell." + exit fi fi } From e845685b0c1fdce9d00e63c14c8177bb5a9e1a0c Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Sat, 24 Feb 2024 02:28:02 +0100 Subject: [PATCH 5992/6505] Add Tandoor Recipes LXC (#2551) --- ct/tandoor.sh | 90 +++++++++++++++++++++++ install/tandoor-install.sh | 142 +++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 ct/tandoor.sh create mode 100644 install/tandoor-install.sh diff --git a/ct/tandoor.sh b/ct/tandoor.sh new file mode 100644 index 00000000..3dba8b02 --- /dev/null +++ b/ct/tandoor.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ __ ____ _ + /_ __/___ _____ ____/ /___ ____ _____ / __ \___ _____(_)___ ___ _____ + / / / __ `/ __ \/ __ / __ \/ __ \/ ___/ / /_/ / _ \/ ___/ / __ \/ _ \/ ___/ + / / / /_/ / / / / /_/ / /_/ / /_/ / / / _, _/ __/ /__/ / /_/ / __(__ ) +/_/ \__,_/_/ /_/\__,_/\____/\____/_/ /_/ |_|\___/\___/_/ .___/\___/____/ + /_/ +EOF +} +header_info +echo -e "Loading..." +APP="Tandoor" +var_disk="10" +var_cpu="4" +var_ram="4096" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/tandoor ]]; then + msg_error "No ${APP} Installation Found!"; + exit; +fi +msg_info "Updating ${APP} LXC" +if cd /opt/tandoor && git pull | grep -q 'Already up to date'; then + msg_error "There is currently no update path available." +else + export $(cat /opt/tandoor/.env | grep "^[^#]" | xargs) + /opt/tandoor/bin/pip3 install -r requirements.txt >/dev/null 2>&1 + /opt/tandoor/bin/python3 manage.py migrate >/dev/null 2>&1 + /opt/tandoor/bin/python3 manage.py collectstatic --no-input >/dev/null 2>&1 + /opt/tandoor/bin/python3 manage.py collectstatic_js_reverse >/dev/null 2>&1 + cd /opt/tandoor/vue + yarn install >/dev/null 2>&1 + yarn build >/dev/null 2>&1 + sudo systemctl restart gunicorn_tandoor +fi +exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 2048 +pct set $CTID -cores 2 +msg_ok "Set Container to Normal Resources" + +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8002${CL} \n" diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh new file mode 100644 index 00000000..cc5796a5 --- /dev/null +++ b/install/tandoor-install.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y --no-install-recommends \ + postgresql \ + build-essential \ + libpq-dev \ + libmagic-dev \ + libzbar0 \ + nginx \ + libsasl2-dev \ + libldap2-dev \ + libssl-dev \ + gpg \ + curl \ + sudo \ + git \ + make \ + mc +msg_ok "Installed Dependencies" + +msg_info "Updating Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-setuptools \ + python3-pip +msg_ok "Updated Python3" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +$STD npm install -g yarn +msg_ok "Installed Node.js" + +msg_info "Installing Tandoor (Patience)" +$STD git clone https://github.com/vabene1111/recipes.git -b master /opt/tandoor +mkdir -p /opt/tandoor/{config,api,mediafiles,staticfiles} +$STD pip3 install -r /opt/tandoor/requirements.txt +cd /opt/tandoor/vue +$STD yarn install +$STD yarn build +wget -q https://raw.githubusercontent.com/vabene1111/recipes/develop/.env.template -O /opt/tandoor/.env +secret_key=$(openssl rand -base64 45 | sed 's/\//\\\//g') +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +sed -i "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|; s|POSTGRES_HOST=.*|POSTGRES_HOST=127.0.0.1|; s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|; s|STATIC_URL=.*|STATIC_URL=/staticfiles/|; s|MEDIA_URL=.*|MEDIA_URL=/mediafiles/|" /opt/tandoor/.env +msg_ok "Installed Tandoor" + +msg_info "Setting up PostgreSQL database" +DB_NAME=djangodb +DB_USER=djangouser +DB_ENCODING=utf8 +DB_TIMEZONE=UTC +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;" +$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;" +$STD sudo -u postgres psql -c "ALTER DATABASE $DB_NAME OWNER TO $DB_USER;" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO $DB_ENCODING;" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO $DB_TIMEZONE;" +$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" +echo "" >>~/tandoor.creds +echo -e "Tandoor Database Name: \e[32m$DB_NAME\e[0m" >>~/tandoor.creds +echo -e "Tandoor Database User: \e[32m$DB_USER\e[0m" >>~/tandoor.creds +echo -e "Tandoor Database Password: \e[32m$DB_PASS\e[0m" >>~/tandoor.creds +export $(cat /opt/tandoor/.env |grep "^[^#]" | xargs) +/usr/bin/python3 /opt/tandoor/manage.py migrate >/dev/null 2>&1 +/usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input >/dev/null 2>&1 +/usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse >/dev/null 2>&1 +msg_ok "Set up PostgreSQL database" + +msg_info "Creating Services" +cat </etc/systemd/system/gunicorn_tandoor.service +[Unit] +Description=gunicorn daemon for tandoor +After=network.target + +[Service] +Type=simple +Restart=always +RestartSec=3 +WorkingDirectory=/opt/tandoor +EnvironmentFile=/opt/tandoor/.env +ExecStart=/usr/local/bin/gunicorn --error-logfile /tmp/gunicorn_err.log --log-level debug --capture-output --bind unix:/opt/tandoor/tandoor.sock recipes.wsgi:application + +[Install] +WantedBy=multi-user.target +EOF + +cat << 'EOF' >/etc/nginx/conf.d/tandoor.conf +server { + listen 8002; + #access_log /var/log/nginx/access.log; + #error_log /var/log/nginx/error.log; + + # serve media files + location /static/ { + alias /opt/tandoor/staticfiles/; + } + + location /media/ { + alias /opt/tandoor/mediafiles/; + } + + location / { + proxy_set_header Host $http_host; + proxy_pass http://unix:/opt/tandoor/tandoor.sock; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +EOF +systemctl reload nginx +systemctl enable -q --now gunicorn_tandoor +msg_ok "Created Services" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 5860f048fad5aaa5bc3f963932dd0a1e02a37629 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 23 Feb 2024 20:36:27 -0500 Subject: [PATCH 5993/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f956a7d..9e6952e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-02-23 + +### Changed + +- **Tandoor Recipes LXC** + - NEW Script (Thanks @MickLesk) + ## 2024-02-21 ### Changed From bd94b1523475cd097c1e15edde2ea58d3ffc16b1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Feb 2024 04:51:46 -0500 Subject: [PATCH 5994/6505] Update tandoor-install.sh tweak --- install/tandoor-install.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index cc5796a5..08009216 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -61,16 +61,21 @@ cd /opt/tandoor/vue $STD yarn install $STD yarn build wget -q https://raw.githubusercontent.com/vabene1111/recipes/develop/.env.template -O /opt/tandoor/.env +DB_NAME=tandordb +DB_USER=tandoor +DB_ENCODING=utf8 +DB_TIMEZONE=UTC secret_key=$(openssl rand -base64 45 | sed 's/\//\\\//g') DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" -sed -i "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|; s|POSTGRES_HOST=.*|POSTGRES_HOST=127.0.0.1|; s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|; s|STATIC_URL=.*|STATIC_URL=/staticfiles/|; s|MEDIA_URL=.*|MEDIA_URL=/mediafiles/|" /opt/tandoor/.env +sed -i -e "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|g" \ + -e "s|POSTGRES_HOST=.*|POSTGRES_HOST=127.0.0.1|g" \ + -e "s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" \ + -e "s|POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" \ + -e "s|POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" \ + -e "\$a\STATIC_URL=/staticfiles\\nMEDIA_URL=/mediafiles" /opt/tandoor/.env msg_ok "Installed Tandoor" msg_info "Setting up PostgreSQL database" -DB_NAME=djangodb -DB_USER=djangouser -DB_ENCODING=utf8 -DB_TIMEZONE=UTC $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;" $STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;" From 6dc6d3cb14f2f5d51acbead405b5421d3b00b563 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Feb 2024 05:04:29 -0500 Subject: [PATCH 5995/6505] Update tandoor-install.sh tweak --- install/tandoor-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index 08009216..822eaa5b 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -61,8 +61,8 @@ cd /opt/tandoor/vue $STD yarn install $STD yarn build wget -q https://raw.githubusercontent.com/vabene1111/recipes/develop/.env.template -O /opt/tandoor/.env -DB_NAME=tandordb -DB_USER=tandoor +DB_NAME=djangodb +DB_USER=djangouser DB_ENCODING=utf8 DB_TIMEZONE=UTC secret_key=$(openssl rand -base64 45 | sed 's/\//\\\//g') From b1974f5e0e35cdc4e6355e3891fba1b322823a82 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Feb 2024 05:26:11 -0500 Subject: [PATCH 5996/6505] Update tandoor-install.sh fix sed --- install/tandoor-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index 822eaa5b..cc2c4900 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -72,7 +72,7 @@ sed -i -e "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|g" \ -e "s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" \ -e "s|POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" \ -e "s|POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" \ - -e "\$a\STATIC_URL=/staticfiles\\nMEDIA_URL=/mediafiles" /opt/tandoor/.env + -e "\$a\\STATIC_URL=/staticfiles/\nMEDIA_URL=/mediafiles/" /opt/tandoor/.env msg_ok "Installed Tandoor" msg_info "Setting up PostgreSQL database" From 50872c6d9f3a2829530ffde70cc2fc2d5fe77afa Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Feb 2024 07:15:47 -0500 Subject: [PATCH 5997/6505] Update tandoor-install.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Final tweaks 🤞🏻 --- install/tandoor-install.sh | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index cc2c4900..8af16863 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -61,29 +61,23 @@ cd /opt/tandoor/vue $STD yarn install $STD yarn build wget -q https://raw.githubusercontent.com/vabene1111/recipes/develop/.env.template -O /opt/tandoor/.env -DB_NAME=djangodb -DB_USER=djangouser +DB_NAME=db_recipes +DB_USER=tandoor DB_ENCODING=utf8 DB_TIMEZONE=UTC secret_key=$(openssl rand -base64 45 | sed 's/\//\\\//g') DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" sed -i -e "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|g" \ - -e "s|POSTGRES_HOST=.*|POSTGRES_HOST=127.0.0.1|g" \ + -e "s|POSTGRES_HOST=.*|POSTGRES_HOST=localhost|g" \ -e "s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" \ -e "s|POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" \ -e "s|POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" \ - -e "\$a\\STATIC_URL=/staticfiles/\nMEDIA_URL=/mediafiles/" /opt/tandoor/.env + -e "\$a\STATIC_URL=/staticfiles/" /opt/tandoor/.env msg_ok "Installed Tandoor" msg_info "Setting up PostgreSQL database" -$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;" -$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';" -$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;" -$STD sudo -u postgres psql -c "ALTER DATABASE $DB_NAME OWNER TO $DB_USER;" -$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO $DB_ENCODING;" -$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" -$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO $DB_TIMEZONE;" -$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" +$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" echo "" >>~/tandoor.creds echo -e "Tandoor Database Name: \e[32m$DB_NAME\e[0m" >>~/tandoor.creds echo -e "Tandoor Database User: \e[32m$DB_USER\e[0m" >>~/tandoor.creds From 966517ef447239e2b1cacfb4e36c00b071d66a20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Feb 2024 09:48:47 -0500 Subject: [PATCH 5998/6505] Update tandoor-install.sh Debug off --- install/tandoor-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index 8af16863..cb5bfc49 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -72,7 +72,8 @@ sed -i -e "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|g" \ -e "s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" \ -e "s|POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" \ -e "s|POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" \ - -e "\$a\STATIC_URL=/staticfiles/" /opt/tandoor/.env + -e "\$a\STATIC_URL=/staticfiles/" \ + -e "\$a\DEBUG=0" /opt/tandoor/.env msg_ok "Installed Tandoor" msg_info "Setting up PostgreSQL database" From 76d43006d6a6588b556a3770f30c775e4988d564 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Feb 2024 10:11:37 -0500 Subject: [PATCH 5999/6505] Update tandoor-install.sh tweak --- install/tandoor-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index cb5bfc49..198b5651 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -73,7 +73,7 @@ sed -i -e "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|g" \ -e "s|POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" \ -e "s|POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" \ -e "\$a\STATIC_URL=/staticfiles/" \ - -e "\$a\DEBUG=0" /opt/tandoor/.env + -e "\$a\# DEBUG=0" /opt/tandoor/.env msg_ok "Installed Tandoor" msg_info "Setting up PostgreSQL database" From 526b5e7b54290c6705c0270a5604f2a06d51549c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 24 Feb 2024 11:30:49 -0500 Subject: [PATCH 6000/6505] Update tandoor-install.sh PostgreSQL 16 --- install/tandoor-install.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index 198b5651..509121e4 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -16,7 +16,6 @@ update_os msg_info "Installing Dependencies (Patience)" $STD apt-get install -y --no-install-recommends \ - postgresql \ build-essential \ libpq-dev \ libmagic-dev \ @@ -72,11 +71,14 @@ sed -i -e "s|SECRET_KEY=.*|SECRET_KEY=$secret_key|g" \ -e "s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" \ -e "s|POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" \ -e "s|POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" \ - -e "\$a\STATIC_URL=/staticfiles/" \ - -e "\$a\# DEBUG=0" /opt/tandoor/.env + -e "\$a\STATIC_URL=/staticfiles/" /opt/tandoor/.env msg_ok "Installed Tandoor" -msg_info "Setting up PostgreSQL database" +msg_info "Install/Set up PostgreSQL Database" +curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc|gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg +echo "deb https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" >/etc/apt/sources.list.d/pgdg.list +$STD apt-get update +$STD apt-get install -y postgresql-16 $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" echo "" >>~/tandoor.creds @@ -87,7 +89,7 @@ export $(cat /opt/tandoor/.env |grep "^[^#]" | xargs) /usr/bin/python3 /opt/tandoor/manage.py migrate >/dev/null 2>&1 /usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input >/dev/null 2>&1 /usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse >/dev/null 2>&1 -msg_ok "Set up PostgreSQL database" +msg_ok "Set up PostgreSQL Database" msg_info "Creating Services" cat </etc/systemd/system/gunicorn_tandoor.service From ae79d3a3325b65c0a9b032311c8102d3aae28a50 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 26 Feb 2024 16:41:27 +0500 Subject: [PATCH 6001/6505] Add Mafl Dashboard (#2562) --- ct/mafl.sh | 73 +++++++++++++++++++++++++++++++++++++ install/mafl-install.sh | 81 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 ct/mafl.sh create mode 100644 install/mafl-install.sh diff --git a/ct/mafl.sh b/ct/mafl.sh new file mode 100644 index 00000000..19012b6a --- /dev/null +++ b/ct/mafl.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ ___ ______ + / |/ /___ _/ __/ / + / /|_/ / __ `/ /_/ / + / / / / /_/ / __/ / +/_/ /_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Mafl" +var_disk="6" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + header_info + if [[ ! -d /opt/mafl ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + msg_error "There is currently no update path available." + exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 1024 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/install/mafl-install.sh b/install/mafl-install.sh new file mode 100644 index 00000000..63f30288 --- /dev/null +++ b/install/mafl-install.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y make +$STD apt-get install -y g++ +$STD apt-get install -y gcc +$STD apt-get install -y ca-certificates +$STD apt-get install -y gnupg +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +$STD npm install -g npm@latest +$STD npm install -g yarn +msg_ok "Installed Node.js" + +RELEASE=$(curl -s https://api.github.com/repos/hywax/mafl/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Installing Mafl v${RELEASE}" +wget -q https://github.com/hywax/mafl/archive/refs/tags/v${RELEASE}.tar.gz +tar -xzf v${RELEASE}.tar.gz +mkdir -p /opt/mafl/data +wget -q -O /opt/mafl/data/config.yml https://raw.githubusercontent.com/hywax/mafl/main/.example/config.yml +mv mafl-${RELEASE}/* /opt/mafl +rm -rf mafl-${RELEASE} +cd /opt/mafl +export NUXT_TELEMETRY_DISABLED=true +$STD yarn install +$STD yarn build +msg_ok "Installed Mafl v${RELEASE}" + +msg_info "Creating Service" +cat </etc/systemd/system/mafl.service +[Unit] +Description=Mafl +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +WorkingDirectory=/opt/mafl/ +ExecStart=yarn preview + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now mafl +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From a31a44b271a0123ca328c23d5f0e99a307f4b004 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Feb 2024 07:03:12 -0500 Subject: [PATCH 6002/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e6952e6..dfb16224 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-02-26 + +### Changed + +- **Mafl LXC** + - NEW Script + ## 2024-02-23 ### Changed From b88dc1338313d9eca530adf82a8546b3af192850 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Feb 2024 14:04:12 -0500 Subject: [PATCH 6003/6505] Update changedetection.sh `systemctl restart changedetection` after update --- ct/changedetection.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index e5fe9ecb..4eda7b24 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -58,6 +58,7 @@ if [[ ! -f /etc/systemd/system/changedetection.service ]]; then msg_error "No ${ msg_info "Updating ${APP} LXC" pip3 install changedetection.io --upgrade &>/dev/null pip3 install playwright --upgrade &>/dev/null +systemctl restart changedetection msg_ok "Updated Successfully" exit } From 58f69adbd8e4f3b0f64b8e4a77d4483d109fe5e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 26 Feb 2024 15:15:17 -0500 Subject: [PATCH 6004/6505] Update mariadb-install.sh - remove Adminer - fixes https://github.com/tteck/Proxmox/issues/2565 --- install/mariadb-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index 310b6c26..047d1d05 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -27,15 +27,6 @@ sed -i 's/^# *\(port *=.*\)/\1/' /etc/mysql/my.cnf sed -i 's/^bind-address/#bind-address/g' /etc/mysql/mariadb.conf.d/50-server.cnf msg_ok "Installed MariaDB" -read -r -p "Would you like to add Adminer? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then - msg_info "Installing Adminer" - $STD apt install -y adminer - $STD a2enconf adminer - systemctl reload apache2 - msg_ok "Installed Adminer" -fi - motd_ssh customize From 0c963550c49b41a4733004ecb6400f1791044068 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Feb 2024 11:28:05 -0500 Subject: [PATCH 6005/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 6e382223..a78e4099 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -34,3 +34,5 @@ [iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs) [Proxmox + NetData]() + +[Proxmox Homelab Series]() From d77cffd0068d2a60b03fd620c8fbf39af558bef7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 27 Feb 2024 11:29:22 -0500 Subject: [PATCH 6006/6505] Update USER_SUBMITTED_GUIDES.md --- USER_SUBMITTED_GUIDES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index a78e4099..8ac04a12 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -35,4 +35,4 @@ [Proxmox + NetData]() -[Proxmox Homelab Series]() +[Proxmox Homelab Series]() From 7759ecf7ddc1bbd698140f3ab2434608253785a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Feb 2024 09:06:25 -0500 Subject: [PATCH 6007/6505] Update unifi-install.sh update libssl --- install/unifi-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 9ff1d08f..32327d4d 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -29,8 +29,8 @@ $STD apt-get install -y temurin-17-jre msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb +$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list $STD apt-get update @@ -48,7 +48,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +rm -rf libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 7f02d0e51b8b3c4a631b4e1fce85914b2b5f810e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Feb 2024 09:41:51 -0500 Subject: [PATCH 6008/6505] Update unifi-install.sh always download latest libssl --- install/unifi-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 32327d4d..ad1d1efb 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -29,7 +29,8 @@ $STD apt-get install -y temurin-17-jre msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb +libssl=$(curl -fsSL "http://security.ubuntu.com/ubuntu/pool/main/o/openssl/" | grep -o 'libssl1\.1_1\.1\.1f-1ubuntu2\.2[^"]*amd64\.deb' | head -n1) +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/$libssl $STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list From 0567a46afd9660fd37d22fe819dbf35e266437a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Feb 2024 15:37:33 -0500 Subject: [PATCH 6009/6505] Update unifi-install.sh tweak --- install/unifi-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index ad1d1efb..54fbef00 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -31,7 +31,7 @@ msg_ok "Installed OpenJDK" msg_info "Installing MongoDB" libssl=$(curl -fsSL "http://security.ubuntu.com/ubuntu/pool/main/o/openssl/" | grep -o 'libssl1\.1_1\.1\.1f-1ubuntu2\.2[^"]*amd64\.deb' | head -n1) wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/$libssl -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb +$STD dpkg -i $libssl wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list $STD apt-get update @@ -49,7 +49,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf libssl1.1_1.1.1f-1ubuntu2.22_amd64.deb +rm -rf $libssl $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 9cad7288c94889034b612a26d0980b2a5d93bfa6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Feb 2024 17:11:59 -0500 Subject: [PATCH 6010/6505] Update deconz-install.sh fixes https://github.com/tteck/Proxmox/issues/2578 --- install/deconz-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install/deconz-install.sh b/install/deconz-install.sh index 328a9679..614129e7 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -26,8 +26,9 @@ echo "deb [arch=amd64] http://phoscon.de/apt/deconz $VERSION main" >/etc/apt/sou msg_ok "Setup Phoscon Repository" msg_info "Installing deConz" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +libssl=$(curl -fsSL "http://security.ubuntu.com/ubuntu/pool/main/o/openssl/" | grep -o 'libssl1\.1_1\.1\.1f-1ubuntu2\.2[^"]*amd64\.deb' | head -n1) +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/$libssl +$STD dpkg -i $libssl $STD apt-get update $STD apt-get install -y deconz msg_ok "Installed deConz" @@ -56,7 +57,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +rm -rf $libssl $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From e5ec531d4f1a383ef7d4f9468457e0bb3a08e096 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 28 Feb 2024 17:13:07 -0500 Subject: [PATCH 6011/6505] Update omada-install.sh update libssl --- install/omada-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index 4e78c5c7..b27f3728 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -30,8 +30,9 @@ $STD apt-get -y install zulu8-jdk msg_ok "Installed Azul Zulu" msg_info "Installing MongoDB" -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb -$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +libssl=$(curl -fsSL "http://security.ubuntu.com/ubuntu/pool/main/o/openssl/" | grep -o 'libssl1\.1_1\.1\.1f-1ubuntu2\.2[^"]*amd64\.deb' | head -n1) +wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/$libssl +$STD dpkg -i $libssl wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" @@ -48,7 +49,7 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf ${latest_version} mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2.21_amd64.deb +rm -rf ${latest_version} mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb $libssl $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From dd4d449c953b95c195dbd7e6b9d8e23ac2f8ab04 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Mar 2024 04:30:17 -0500 Subject: [PATCH 6012/6505] Update omada-install.sh tweak --- install/omada-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/omada-install.sh b/install/omada-install.sh index b27f3728..d3768a98 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -37,7 +37,7 @@ wget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiv $STD dpkg -i mongodb-org-server_3.6.23_amd64.deb msg_ok "Installed MongoDB" -latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) +latest_url=$(curl -fsSL "https://www.tp-link.com/en/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) latest_version=$(basename "$latest_url") msg_info "Installing Omada Controller" From 05dc5371243fac3891ff14b1a67cecf03d85b061 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Mar 2024 04:31:17 -0500 Subject: [PATCH 6013/6505] Update omada.sh tweak --- ct/omada.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omada.sh b/ct/omada.sh index 82f28261..c664953e 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -55,7 +55,7 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/tplink ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -latest_url=$(curl -fsSL "https://www.tp-link.com/us/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) +latest_url=$(curl -fsSL "https://www.tp-link.com/en/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1) latest_version=$(basename "${latest_url}") if [ -z "${latest_version}" ]; then msg_error "It seems that the server (tp-link.com) might be down. Please try again at a later time." From 57d06ad2bef3e2dc01a4ba16297d830096203d2c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Mar 2024 04:48:34 -0500 Subject: [PATCH 6014/6505] Update home-assistant-core-copy-data-home-assistant-core.sh Stop both containers. --- .../home-assistant-core-copy-data-home-assistant-core.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh index c0cf2868..68c388ed 100644 --- a/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh +++ b/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh @@ -83,6 +83,10 @@ whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" -- $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) Version: 2022.10.03" 13 50 || exit info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" +if [ $(pct status $CTID_FROM | sed 's/.* //') == 'running' ]; then + msg "Stopping '$CTID_FROM'..." + pct stop $CTID_FROM +fi if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then msg "Stopping '$CTID_TO'..." pct stop $CTID_TO From 55a107b29ff839a864b5deebc0182d6f4d069d31 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Mar 2024 09:23:54 -0500 Subject: [PATCH 6015/6505] Update emby-install.sh set static version --- install/emby-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install/emby-install.sh b/install/emby-install.sh index 72158183..83245643 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -33,8 +33,9 @@ fi LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Installing Emby" -wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb -$STD dpkg -i emby-server-deb_${LATEST}_amd64.deb +#wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb +wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/4.8.1.0/emby-server-deb_4.8.1.0_amd64.deb +$STD dpkg -i emby-server-deb_4.8.1.0_amd64.deb sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,emby/' -e 's/^render:x:108:root,emby$/ssl-cert:x:108:/' /etc/group msg_ok "Installed Emby" @@ -44,5 +45,5 @@ customize msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean -rm emby-server-deb_${LATEST}_amd64.deb +rm emby-server-deb_4.8.1.0_amd64.deb msg_ok "Cleaned" From 89d9b9ca9f0b749243b51b0be3e9bc96f7ce7007 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 1 Mar 2024 09:25:32 -0500 Subject: [PATCH 6016/6505] Update emby.sh set static version --- ct/emby.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/emby.sh b/ct/emby.sh index a8b5618a..b198f002 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -61,9 +61,9 @@ systemctl stop emby-server msg_ok "Stopped ${APP}" msg_info "Updating ${APP}" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null -dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null -rm emby-server-deb_${LATEST}_amd64.deb +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.8.1.0/emby-server-deb_4.8.1.0_amd64.deb &>/dev/null +dpkg -i emby-server-deb_4.8.1.0_amd64.deb &>/dev/null +rm emby-server-deb_4.8.1.0_amd64.deb msg_ok "Updated ${APP}" msg_info "Starting ${APP}" From 9e7b96e9dfcd3efc7a303205e30b67aaf81e684c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Mar 2024 06:22:50 -0500 Subject: [PATCH 6017/6505] Update grafana.sh tweak --- ct/grafana.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ct/grafana.sh b/ct/grafana.sh index 085cb4ee..b5ea2aa9 100644 --- a/ct/grafana.sh +++ b/ct/grafana.sh @@ -56,9 +56,6 @@ function update_script() { header_info if [[ ! -f /etc/apt/sources.list.d/grafana.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" -apt-key del 4E40DDF6D76E284A4A6780E48C8C34C524098CB6 -wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key -echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee /etc/apt/sources.list.d/grafana.list apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated Successfully" From 7b1738ca7b6bb5b022f6cb1dafbb2ef094a85133 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Mar 2024 07:44:41 -0500 Subject: [PATCH 6018/6505] Update nginxproxymanager-install.sh set pnpm version --- install/nginxproxymanager-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 48017b6f..cf7ca741 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -61,7 +61,7 @@ ln -sf /root/.nvm/versions/node/v16.20.2/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing pnpm" -$STD npm install -g pnpm +$STD npm install -g pnpm@8.15 msg_ok "Installed pnpm" RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | From 511fd50ebb53dbb2f5a45f604bc6eff24b7607d9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Mar 2024 18:02:12 -0500 Subject: [PATCH 6019/6505] Update emby-install.sh install the latest version --- install/emby-install.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/install/emby-install.sh b/install/emby-install.sh index 83245643..72158183 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -33,9 +33,8 @@ fi LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Installing Emby" -#wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb -wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/4.8.1.0/emby-server-deb_4.8.1.0_amd64.deb -$STD dpkg -i emby-server-deb_4.8.1.0_amd64.deb +wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb +$STD dpkg -i emby-server-deb_${LATEST}_amd64.deb sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,emby/' -e 's/^render:x:108:root,emby$/ssl-cert:x:108:/' /etc/group msg_ok "Installed Emby" @@ -45,5 +44,5 @@ customize msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean -rm emby-server-deb_4.8.1.0_amd64.deb +rm emby-server-deb_${LATEST}_amd64.deb msg_ok "Cleaned" From 912f0e01ba9c90ed295da298ef926925d325b575 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 3 Mar 2024 18:03:28 -0500 Subject: [PATCH 6020/6505] Update emby.sh tweak --- ct/emby.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/emby.sh b/ct/emby.sh index b198f002..a8b5618a 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -61,9 +61,9 @@ systemctl stop emby-server msg_ok "Stopped ${APP}" msg_info "Updating ${APP}" -wget https://github.com/MediaBrowser/Emby.Releases/releases/download/4.8.1.0/emby-server-deb_4.8.1.0_amd64.deb &>/dev/null -dpkg -i emby-server-deb_4.8.1.0_amd64.deb &>/dev/null -rm emby-server-deb_4.8.1.0_amd64.deb +wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null +dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null +rm emby-server-deb_${LATEST}_amd64.deb msg_ok "Updated ${APP}" msg_info "Starting ${APP}" From c7e4f370c612f2385c38a9d5ed35404f7a5091b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Mar 2024 05:31:07 -0500 Subject: [PATCH 6021/6505] Update prometheus.sh fixes https://github.com/tteck/Proxmox/issues/2607 --- ct/prometheus.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ct/prometheus.sh b/ct/prometheus.sh index ae519078..b2230eaa 100644 --- a/ct/prometheus.sh +++ b/ct/prometheus.sh @@ -55,10 +55,7 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/systemd/system/prometheus.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Successfully" +msg_error "There is currently no update path available." exit } From a6b415bc3691e949edcecc829cf2abf4d1a88956 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Mar 2024 05:50:36 -0500 Subject: [PATCH 6022/6505] Update code-server.sh fixes https://github.com/tteck/Proxmox/issues/2608 --- misc/code-server.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/code-server.sh b/misc/code-server.sh index 6ae2d024..cbc140d9 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -47,6 +47,7 @@ function error_exit() { clear header_info if command -v pveversion >/dev/null 2>&1; then echo -e "⚠️ Can't Install on Proxmox "; exit; fi +if [ -e /etc/alpine-release ]; then echo -e "⚠️ Can't Install on Alpine"; exit; fi while true; do read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn case $yn in From 8bbb33b97b51bca78e64bc73d745a309f5405e74 Mon Sep 17 00:00:00 2001 From: Matthew Date: Wed, 6 Mar 2024 13:58:29 +0000 Subject: [PATCH 6023/6505] Update photoprism-install.sh (#2609) add rawtherapee dependency to enable raw image conversion --- install/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 2f80b6cc..d1d950ad 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -25,6 +25,7 @@ $STD apt-get install -y libjpeg-dev $STD apt-get install -y libtiff-dev $STD apt-get install -y imagemagick $STD apt-get install -y darktable +$STD apt-get install -y rawtherapee msg_ok "Installed Dependencies" From ea1e30dfa928debfc513c8e823c1eae5d9e92dd5 Mon Sep 17 00:00:00 2001 From: Matthew Date: Wed, 6 Mar 2024 14:14:05 +0000 Subject: [PATCH 6024/6505] Update photoprism-install.sh (#2610) For some reason it seems as though the binaries as part of `libheif1` install not to `/usr/local/bin` but to `/usr/local` and so were not on the path, therefore the default value of photoprism's `--heifconvert-bin` / `$PHOTOPRISM_HEIFCONVERT_BIN` (`heif-convert`) would not be resolved --- install/photoprism-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index d1d950ad..a7bec81f 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -27,6 +27,8 @@ $STD apt-get install -y imagemagick $STD apt-get install -y darktable $STD apt-get install -y rawtherapee +echo 'export PATH=/usr/local:$PATH' >>~/.bashrc +export PATH=/usr/local:$PATH msg_ok "Installed Dependencies" msg_info "Installing PhotoPrism (Patience)" From 183340bc853089e0a3800a4da527b6b9614bb175 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Mar 2024 18:45:37 -0500 Subject: [PATCH 6025/6505] Update dashy-install.sh fixes https://github.com/tteck/Proxmox/issues/2614 --- install/dashy-install.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 2962161d..d0709fb5 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -17,7 +17,6 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y git msg_ok "Installed Dependencies" msg_info "Installing Node.js (Patience)" @@ -35,10 +34,12 @@ ln -sf /usr/local/bin/yarn /usr/bin/yarn msg_ok "Installed Yarn" msg_info "Installing Dashy (Patience)" -$STD git clone https://github.com/Lissy93/dashy.git -cd /dashy +mkdir -p /opt/dashy +#RELEASE=$(curl -s https://api.github.com/repos/Lissy93/dashy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +#wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 +wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/2.1.1.tar.gz | tar -xz -C /opt/dashy --strip-components=1 +cd /opt/dashy $STD yarn -export NODE_OPTIONS=--max-old-space-size=1000 $STD yarn build msg_ok "Installed Dashy" @@ -49,7 +50,7 @@ Description=dashy [Service] Type=simple -WorkingDirectory=/dashy +WorkingDirectory=/opt/dashy ExecStart=/usr/bin/yarn start [Install] WantedBy=multi-user.target From 321660487de3d1df302c47e0ba21a999db28020b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 6 Mar 2024 18:48:53 -0500 Subject: [PATCH 6026/6505] Update dashy.sh There is currently no update path available. --- ct/dashy.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index 759b8805..23a28334 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -54,7 +54,9 @@ function default_settings() { function update_script() { header_info -if [[ ! -d /dashy/public/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if [[ ! -d /opt/dashy/public/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit msg_info "Stopping ${APP}" systemctl stop dashy msg_ok "Stopped ${APP}" From 64bf64ff183c0aed9d19ca08cecee033ba025277 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 10:16:49 -0500 Subject: [PATCH 6027/6505] Update mqtt-install.sh fixes https://github.com/tteck/Proxmox/issues/2617 --- install/mqtt-install.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 860c70bb..c9b372b3 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -22,8 +22,11 @@ msg_ok "Installed Dependencies" msg_info "Installing Mosquitto MQTT Broker" if [ "$PCT_OSTYPE" == "debian" ]; then VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" - wget -qO- http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key >/etc/apt/trusted.gpg.d/mosquitto-repo.asc - wget -qO /etc/apt/sources.list.d/mosquitto-${VERSION}.list http://repo.mosquitto.org/debian/mosquitto-${VERSION}.list + # wget -qO- http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key >/etc/apt/trusted.gpg.d/mosquitto-repo.asc + # wget -qO /etc/apt/sources.list.d/mosquitto-${VERSION}.list http://repo.mosquitto.org/debian/mosquitto-${VERSION}.list + gpg --keyserver keyserver.ubuntu.com --recv-keys 779B22DFB3E717B7 >/dev/null 2>&1 + gpg --export 779B22DFB3E717B7 | tee /etc/apt/trusted.gpg.d/mosquitto.gpg >/dev/null 2>&1 + echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mosquitto.gpg] https://repo.mosquitto.org/debian ${VERSION} main" >/etc/apt/sources.list.d/mosquitto-${VERSION}.list $STD apt-get update fi $STD apt-get -y install mosquitto From d9736097bbf8a5f3fbe647a1b1c63c646316004b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 10:25:59 -0500 Subject: [PATCH 6028/6505] Update mqtt-install.sh test --- install/mqtt-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index c9b372b3..48cff6f1 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -21,12 +21,14 @@ msg_ok "Installed Dependencies" msg_info "Installing Mosquitto MQTT Broker" if [ "$PCT_OSTYPE" == "debian" ]; then + set +Eeuo pipefail VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" # wget -qO- http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key >/etc/apt/trusted.gpg.d/mosquitto-repo.asc # wget -qO /etc/apt/sources.list.d/mosquitto-${VERSION}.list http://repo.mosquitto.org/debian/mosquitto-${VERSION}.list gpg --keyserver keyserver.ubuntu.com --recv-keys 779B22DFB3E717B7 >/dev/null 2>&1 gpg --export 779B22DFB3E717B7 | tee /etc/apt/trusted.gpg.d/mosquitto.gpg >/dev/null 2>&1 echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mosquitto.gpg] https://repo.mosquitto.org/debian ${VERSION} main" >/etc/apt/sources.list.d/mosquitto-${VERSION}.list + set -Eeuo pipefail $STD apt-get update fi $STD apt-get -y install mosquitto From 6e0f3742852bec6d02e6ea2b47ea43480fb20957 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 10:29:48 -0500 Subject: [PATCH 6029/6505] Update mqtt-install.sh add gpg --- install/mqtt-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 48cff6f1..1f1d0d31 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -17,18 +17,17 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Installing Mosquitto MQTT Broker" if [ "$PCT_OSTYPE" == "debian" ]; then - set +Eeuo pipefail VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" # wget -qO- http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key >/etc/apt/trusted.gpg.d/mosquitto-repo.asc # wget -qO /etc/apt/sources.list.d/mosquitto-${VERSION}.list http://repo.mosquitto.org/debian/mosquitto-${VERSION}.list gpg --keyserver keyserver.ubuntu.com --recv-keys 779B22DFB3E717B7 >/dev/null 2>&1 gpg --export 779B22DFB3E717B7 | tee /etc/apt/trusted.gpg.d/mosquitto.gpg >/dev/null 2>&1 echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mosquitto.gpg] https://repo.mosquitto.org/debian ${VERSION} main" >/etc/apt/sources.list.d/mosquitto-${VERSION}.list - set -Eeuo pipefail $STD apt-get update fi $STD apt-get -y install mosquitto From 87cee4cd57cb8d2191d6d63a4ad344a2642c048b Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 13:29:01 -0500 Subject: [PATCH 6030/6505] Update changedetection-install.sh add jpeg-dev, libjpeg --- install/changedetection-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index e670943b..8bca81a4 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -23,6 +23,8 @@ $STD apt-get install -y \ dumb-init \ gconf-service \ libatk-bridge2.0-0 \ + jpeg-dev \ + libjpeg \ libasound2 \ libatk1.0-0 \ libcairo2 \ From 1edd9bfb391d22d00377d2c4020cf0a8571df1a2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 13:38:36 -0500 Subject: [PATCH 6031/6505] Update changedetection-install.sh revert --- install/changedetection-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 8bca81a4..e670943b 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -23,8 +23,6 @@ $STD apt-get install -y \ dumb-init \ gconf-service \ libatk-bridge2.0-0 \ - jpeg-dev \ - libjpeg \ libasound2 \ libatk1.0-0 \ libcairo2 \ From 8b03579df9999f8de8c934a5fb609b3ab7981961 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 13:58:07 -0500 Subject: [PATCH 6032/6505] Update tandoor-install.sh fixes https://github.com/tteck/Proxmox/issues/2621 --- install/tandoor-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index 509121e4..87fdd91b 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -127,7 +127,6 @@ server { location / { proxy_set_header Host $http_host; proxy_pass http://unix:/opt/tandoor/tandoor.sock; - proxy_set_header X-Forwarded-Proto $scheme; } } EOF From 02afb23aed629f35c98452a75b26a740cee6a4d3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 14:17:39 -0500 Subject: [PATCH 6033/6505] Update changedetection-install.sh add libjpeg-dev --- install/changedetection-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index e670943b..d685153a 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -22,6 +22,7 @@ $STD apt-get install -y \ build-essential \ dumb-init \ gconf-service \ + libjpeg-dev \ libatk-bridge2.0-0 \ libasound2 \ libatk1.0-0 \ From a4a692f4495f4ac2b7a480a26821462ce11e20e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 14:24:49 -0500 Subject: [PATCH 6034/6505] Update changedetection.sh if libjpeg-dev is not installed, install it --- ct/changedetection.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ct/changedetection.sh b/ct/changedetection.sh index 4eda7b24..b6f42369 100644 --- a/ct/changedetection.sh +++ b/ct/changedetection.sh @@ -56,6 +56,10 @@ function update_script() { header_info if [[ ! -f /etc/systemd/system/changedetection.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP} LXC" +if ! dpkg -s libjpeg-dev >/dev/null 2>&1; then + apt-get update + apt-get install -y libjpeg-dev +fi pip3 install changedetection.io --upgrade &>/dev/null pip3 install playwright --upgrade &>/dev/null systemctl restart changedetection From f14b6f49d7ec903298829a5e42ecb85f7f4e5479 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 15:10:25 -0500 Subject: [PATCH 6035/6505] Update mqtt-install.sh update keys --- install/mqtt-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 1f1d0d31..c9c9c164 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -25,8 +25,8 @@ if [ "$PCT_OSTYPE" == "debian" ]; then VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" # wget -qO- http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key >/etc/apt/trusted.gpg.d/mosquitto-repo.asc # wget -qO /etc/apt/sources.list.d/mosquitto-${VERSION}.list http://repo.mosquitto.org/debian/mosquitto-${VERSION}.list - gpg --keyserver keyserver.ubuntu.com --recv-keys 779B22DFB3E717B7 >/dev/null 2>&1 - gpg --export 779B22DFB3E717B7 | tee /etc/apt/trusted.gpg.d/mosquitto.gpg >/dev/null 2>&1 + gpg --keyserver keyserver.ubuntu.com --recv-keys 61611AE430993623 >/dev/null 2>&1 + gpg --export 61611AE430993623 | tee /etc/apt/trusted.gpg.d/mosquitto.gpg >/dev/null 2>&1 echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mosquitto.gpg] https://repo.mosquitto.org/debian ${VERSION} main" >/etc/apt/sources.list.d/mosquitto-${VERSION}.list $STD apt-get update fi From b58ae2b8924b554a9d4fcd404f3dede9c6ed3ba8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 15:22:55 -0500 Subject: [PATCH 6036/6505] Update mqtt-install.sh go back to basic install --- install/mqtt-install.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index c9c9c164..18362faa 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -21,15 +21,6 @@ $STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Installing Mosquitto MQTT Broker" -if [ "$PCT_OSTYPE" == "debian" ]; then - VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" - # wget -qO- http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key >/etc/apt/trusted.gpg.d/mosquitto-repo.asc - # wget -qO /etc/apt/sources.list.d/mosquitto-${VERSION}.list http://repo.mosquitto.org/debian/mosquitto-${VERSION}.list - gpg --keyserver keyserver.ubuntu.com --recv-keys 61611AE430993623 >/dev/null 2>&1 - gpg --export 61611AE430993623 | tee /etc/apt/trusted.gpg.d/mosquitto.gpg >/dev/null 2>&1 - echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mosquitto.gpg] https://repo.mosquitto.org/debian ${VERSION} main" >/etc/apt/sources.list.d/mosquitto-${VERSION}.list - $STD apt-get update -fi $STD apt-get -y install mosquitto $STD apt-get -y install mosquitto-clients cat </etc/mosquitto/conf.d/default.conf From 78bc2006bc1519a3aef51f2d51daaf0606fc5922 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 17:09:11 -0500 Subject: [PATCH 6037/6505] Update post-pve-install.sh Requires Proxmox Virtual Environment Version 8.1.1 or later. --- misc/post-pve-install.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index ad2227a1..ea166360 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -46,7 +46,6 @@ msg_error() { start_routines() { header_info - VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SOURCES" --menu "The package manager will use the correct sources to update and install packages on your Proxmox VE server.\n \nCorrect Proxmox VE sources?" 14 58 2 \ "yes" " " \ @@ -55,10 +54,11 @@ start_routines() { yes) msg_info "Correcting Proxmox VE Sources" cat </etc/apt/sources.list -deb http://ftp.debian.org/debian ${VERSION} main contrib -deb http://ftp.debian.org/debian ${VERSION}-updates main contrib -deb http://security.debian.org/debian-security ${VERSION}-security main contrib +deb http://deb.debian.org/debian bookworm main contrib +deb http://deb.debian.org/debian bookworm-updates main contrib +deb http://security.debian.org/debian-security bookworm-security main contrib EOF +echo 'APT::Get::Update::SourceListWarnings::NonFreeFirmware "false";' >/etc/apt/apt.conf.d/no-bookworm-firmware.conf msg_ok "Corrected Proxmox VE Sources" ;; no) @@ -73,7 +73,7 @@ EOF yes) msg_info "Disabling 'pve-enterprise' repository" cat </etc/apt/sources.list.d/pve-enterprise.list -# deb https://enterprise.proxmox.com/debian/pve ${VERSION} pve-enterprise +# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise EOF msg_ok "Disabled 'pve-enterprise' repository" ;; @@ -89,7 +89,7 @@ EOF yes) msg_info "Enabling 'pve-no-subscription' repository" cat </etc/apt/sources.list.d/pve-install-repo.list -deb http://download.proxmox.com/debian/pve ${VERSION} pve-no-subscription +deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription EOF msg_ok "Enabled 'pve-no-subscription' repository" ;; @@ -98,7 +98,6 @@ EOF ;; esac - if [[ "${VERSION}" == "bookworm" ]]; then CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CEPH PACKAGE REPOSITORIES" --menu "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories (initially disabled).\n \nCorrect 'ceph package sources?" 14 58 2 \ "yes" " " \ "no" " " 3>&2 2>&1 1>&3) @@ -117,7 +116,6 @@ EOF msg_error "Selected no to Correcting 'ceph package repositories'" ;; esac - fi CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PVETEST" --menu "The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\n \nAdd (Disabled) 'pvetest' repository?" 14 58 2 \ "yes" " " \ @@ -126,7 +124,7 @@ EOF yes) msg_info "Adding 'pvetest' repository and set disabled" cat </etc/apt/sources.list.d/pvetest-for-beta.list -# deb http://download.proxmox.com/debian/pve ${VERSION} pvetest +# deb http://download.proxmox.com/debian/pve bookworm pvetest EOF msg_ok "Added 'pvetest' repository" ;; @@ -233,9 +231,11 @@ while true; do esac done -if ! command -v pveversion >/dev/null 2>&1; then - header_info - msg_error "\n No PVE Detected!\n" +if ! pveversion | grep -Eq "pve-manager/(8.1.[1-9])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1.1 or later." + echo -e "Exiting..." + sleep 2 exit fi From 4ea5186921dd846dab6582c71e6d534bcdecf0cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 8 Mar 2024 17:12:21 -0500 Subject: [PATCH 6038/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb16224..76d301a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-03-08 + +### Changed + +- **Proxmox VE Post Install** + - Requires Proxmox Virtual Environment Version 8.1.1 or later. + ## 2024-02-26 ### Changed From b12a98e5a3e647217bb481342041ae9ea6958eb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 9 Mar 2024 12:03:52 -0500 Subject: [PATCH 6039/6505] Update build.func remove Lunar, add Mantic --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 604b0468..f21ad361 100644 --- a/misc/build.func +++ b/misc/build.func @@ -205,7 +205,7 @@ advanced_settings() { if var_version=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "20.04" "Focal" OFF \ "22.04" "Jammy" OFF \ - "23.04" "Lunar" OFF \ + "23.10" "Mantic" OFF \ 3>&1 1>&2 2>&3); then if [ -n "$var_version" ]; then echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" From e5010e747b8fea9b9b94024050bd2ab635ab2a20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Mar 2024 07:10:39 -0400 Subject: [PATCH 6040/6505] Update n8n-install.sh Set environment option "N8N_SECURE_COOKIE=false" --- install/n8n-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 13aa5104..32298692 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -44,6 +44,7 @@ Description=n8n [Service] Type=simple +Environment="N8N_SECURE_COOKIE=false" ExecStart=n8n start [Install] WantedBy=multi-user.target From 8e71d636efbe44d8a7fedb017762fdf4aec485fa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Mar 2024 07:15:41 -0400 Subject: [PATCH 6041/6505] Update n8n.sh add storage --- ct/n8n.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/n8n.sh b/ct/n8n.sh index 5c5feeae..3abc7328 100644 --- a/ct/n8n.sh +++ b/ct/n8n.sh @@ -20,7 +20,7 @@ EOF header_info echo -e "Loading..." APP="n8n" -var_disk="3" +var_disk="6" var_cpu="2" var_ram="2048" var_os="debian" From afb664eadc91e79c102c1135af279aa392bc4ba3 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:59:12 +0100 Subject: [PATCH 6042/6505] Create a Wastebin LXC (#2640) --- ct/wastebin.sh | 107 ++++++++++++++++++++++++++++++++++++ install/wastebin-install.sh | 65 ++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 ct/wastebin.sh create mode 100644 install/wastebin-install.sh diff --git a/ct/wastebin.sh b/ct/wastebin.sh new file mode 100644 index 00000000..be4b5aef --- /dev/null +++ b/ct/wastebin.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/matze/wastebin + + +function header_info { +clear +cat <<"EOF" + _ __ __ __ _ +| | / /___ ______/ /____ / /_ (_)___ +| | /| / / __ `/ ___/ __/ _ \/ __ \/ / __ \ +| |/ |/ / /_/ (__ ) /_/ __/ /_/ / / / / / +|__/|__/\__,_/____/\__/\___/_.___/_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Wastebin" +var_disk="4" +var_cpu="4" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/wastebin ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi +msg_info "Stopping Wastebin" +systemctl stop wastebin +msg_ok "Wastebin Stopped" + +msg_info "Updating Wastebin" +RELEASE=$(curl -s https://api.github.com/repos/matze/wastebin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +cd /opt +if [ -d wastebin_bak ]; then + rm -rf wastebin_bak +fi +mv wastebin wastebin_bak +wget -q "https://github.com/matze/wastebin/archive/refs/tags/${RELEASE}.zip" +unzip -q ${RELEASE}.zip +mv wastebin-${RELEASE} /opt/wastebin +cd /opt/wastebin +cargo update -q +cargo build -q --release +msg_ok "Updated Wastebin" + +msg_info "Starting Wastebin" +systemctl start wastebin +msg_ok "Started Wastebin" + +msg_info "Cleaning Up" +cd /opt +rm -R ${RELEASE}.zip +rm -R wastebin_bak +msg_ok "Cleaned" +msg_ok "Updated Successfully" +exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -cores 2 +msg_ok "Set Container to Normal Resources" + +msg_ok "Completed Successfully!\n" +echo -e "${APP} Setup should be reachable by going to the following URL. + ${BL}http://${IP}:8088${CL} \n" diff --git a/install/wastebin-install.sh b/install/wastebin-install.sh new file mode 100644 index 00000000..5e6827ce --- /dev/null +++ b/install/wastebin-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/matze/wastebin + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y --no-install-recommends \ + build-essential \ + curl \ + sudo \ + git \ + make \ + mc +msg_ok "Installed Dependencies" + +msg_info "Installing Rust (Patience)" +$STD bash <(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs) -y +source ~/.cargo/env +msg_ok "Installed Rust" + +RELEASE=$(curl -s https://api.github.com/repos/matze/wastebin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget -q "https://github.com/matze/wastebin/archive/refs/tags/${RELEASE}.zip" +unzip -q ${RELEASE}.zip +mv wastebin-${RELEASE} /opt/wastebin +rm -R ${RELEASE}.zip +cd /opt/wastebin +cargo build -q --release +msg_ok "Installed Wastebin" + +msg_info "Creating Service" +cat </etc/systemd/system/wastebin.service +[Unit] +Description=Start Wastebin Service +After=network.target + +[Service] +User=root +WorkingDirectory=/opt/wastebin +ExecStart=/root/.cargo/bin/cargo run --release --quiet + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now wastebin.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From dfb691ebbcd75f16d1f3054d11daca2800ec9776 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Mar 2024 11:04:26 -0400 Subject: [PATCH 6043/6505] Update wastebin-install.sh maybe I was wrong about `unzip` --- install/wastebin-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/wastebin-install.sh b/install/wastebin-install.sh index 5e6827ce..b83bb4fe 100644 --- a/install/wastebin-install.sh +++ b/install/wastebin-install.sh @@ -18,6 +18,7 @@ update_os msg_info "Installing Dependencies (Patience)" $STD apt-get install -y --no-install-recommends \ build-essential \ + unzip \ curl \ sudo \ git \ From f38cfcd00278e4acb94d17e6f242430caff7df22 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Mar 2024 11:42:27 -0400 Subject: [PATCH 6044/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76d301a4..d45a4eb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-03-11 + +### Changed + +- **Wastebin LXC** + - NEW Script + ## 2024-03-08 ### Changed From ee82bc777d93d761c9d154594cb2365b27226d4b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 11 Mar 2024 11:55:47 -0400 Subject: [PATCH 6045/6505] Update wastebin-install.sh tweak --- install/wastebin-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/wastebin-install.sh b/install/wastebin-install.sh index b83bb4fe..25e5b592 100644 --- a/install/wastebin-install.sh +++ b/install/wastebin-install.sh @@ -31,6 +31,7 @@ $STD bash <(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs) -y source ~/.cargo/env msg_ok "Installed Rust" +msg_info "Installing Wastebin (Patience)" RELEASE=$(curl -s https://api.github.com/repos/matze/wastebin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget -q "https://github.com/matze/wastebin/archive/refs/tags/${RELEASE}.zip" unzip -q ${RELEASE}.zip From e15d82fb7c9c2a4cd6988c27c8c28d12747a6a92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Mar 2024 12:47:31 -0400 Subject: [PATCH 6046/6505] Update tandoor.sh fix update function --- ct/tandoor.sh | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/ct/tandoor.sh b/ct/tandoor.sh index 3dba8b02..29085af5 100644 --- a/ct/tandoor.sh +++ b/ct/tandoor.sh @@ -54,26 +54,25 @@ function default_settings() { } function update_script() { -header_info -if [[ ! -d /opt/tandoor ]]; then - msg_error "No ${APP} Installation Found!"; - exit; -fi -msg_info "Updating ${APP} LXC" -if cd /opt/tandoor && git pull | grep -q 'Already up to date'; then - msg_error "There is currently no update path available." -else + header_info + if [[ ! -d /opt/tandoor ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + if cd /opt/tandoor && git pull | grep -q 'Already up to date'; then + msg_ok "There is currently no update available." + else + msg_info "Updating ${APP} (Patience)" export $(cat /opt/tandoor/.env | grep "^[^#]" | xargs) - /opt/tandoor/bin/pip3 install -r requirements.txt >/dev/null 2>&1 - /opt/tandoor/bin/python3 manage.py migrate >/dev/null 2>&1 - /opt/tandoor/bin/python3 manage.py collectstatic --no-input >/dev/null 2>&1 - /opt/tandoor/bin/python3 manage.py collectstatic_js_reverse >/dev/null 2>&1 + cd /opt/tandoor/ + pip3 install -r requirements.txt >/dev/null 2>&1 + /usr/bin/python3 /opt/tandoor/manage.py migrate >/dev/null 2>&1 + /usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input >/dev/null 2>&1 + /usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse >/dev/null 2>&1 cd /opt/tandoor/vue yarn install >/dev/null 2>&1 yarn build >/dev/null 2>&1 - sudo systemctl restart gunicorn_tandoor -fi -exit + systemctl restart gunicorn_tandoor + msg_ok "Updated ${APP}" + fi + exit } start From 16070912baccad3e32114bcaff1a0fc34df2b9e5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Mar 2024 19:29:59 -0400 Subject: [PATCH 6047/6505] Update homeassistant-core-install.sh tweak --- install/homeassistant-core-install.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 327c773f..bb0fbba2 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -44,7 +44,7 @@ msg_ok "Installed Dependencies" RELEASE=$(curl -s https://www.python.org/downloads/ | grep -oP 'Download Python \K\d+\.\d+\.\d+' | head -1) -msg_info "Compiling Python ${RELEASE} from its source (Additional Patience)" +msg_info "Compiling Python 3.12 from its source (Additional Patience)" $STD apt-get remove -y python3 $STD apt-get install -y \ checkinstall \ @@ -57,15 +57,16 @@ $STD apt-get install -y \ libc6-dev \ libbz2-dev -wget -qO- https://www.python.org/ftp/python/${RELEASE}/Python-${RELEASE}.tar.xz | tar -xJ -cd Python-${RELEASE} +#wget -qO- https://www.python.org/ftp/python/${RELEASE}/Python-${RELEASE}.tar.xz | tar -xJ +wget -qO- https://www.python.org/ftp/python/3.12.2/Python-3.12.2.tar.xz | tar -xJ +cd Python-3.12.2 $STD ./configure --enable-optimizations $STD make -j $(nproc) $STD make altinstall $STD update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.12 1 cd ~ -rm -rf Python-${RELEASE} -msg_ok "Installed Python ${RELEASE}" +rm -rf Python-3.12.2 +msg_ok "Installed Python 3.12" msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant From 47769455a7495d2fca6f88f772f6c0b86fd1019e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Mar 2024 19:35:15 -0400 Subject: [PATCH 6048/6505] Update homeassistant-core-install.sh tweak --- install/homeassistant-core-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index bb0fbba2..99027611 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -42,7 +42,7 @@ $STD apt-get install -y \ libatlas-base-dev msg_ok "Installed Dependencies" -RELEASE=$(curl -s https://www.python.org/downloads/ | grep -oP 'Download Python \K\d+\.\d+\.\d+' | head -1) +#RELEASE=$(curl -s https://www.python.org/downloads/ | grep -oP 'Download Python \K\d+\.\d+\.\d+' | head -1) msg_info "Compiling Python 3.12 from its source (Additional Patience)" $STD apt-get remove -y python3 From 74b2a1bf2afe4820d7a21bb6b83087bb4582e494 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Mar 2024 19:58:55 -0400 Subject: [PATCH 6049/6505] Update homeassistant-core.sh tweak --- ct/homeassistant-core.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 738e2ea1..8c926968 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -20,8 +20,8 @@ header_info echo -e "Loading..." APP="Home Assistant-Core" var_disk="8" -var_cpu="2" -var_ram="1024" +var_cpu="4" +var_ram="2048" var_os="debian" var_version="12" variables @@ -147,6 +147,11 @@ WantedBy=default.target" >$service_path fi } +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 1024 +pct set $CTID -cores 2 +msg_ok "Set Container to Normal Resources" + start build_container description From 89da288a7f01ffdc716b3308ce0400718ca773d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Mar 2024 20:33:47 -0400 Subject: [PATCH 6050/6505] Update homeassistant-core.sh tweak --- ct/homeassistant-core.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 8c926968..d56ba5a1 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -147,15 +147,15 @@ WantedBy=default.target" >$service_path fi } +start +build_container +description + msg_info "Setting Container to Normal Resources" pct set $CTID -memory 1024 pct set $CTID -cores 2 msg_ok "Set Container to Normal Resources" -start -build_container -description - msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL}" From e2bb08fcf722121d50a9476076d893594015ce58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 12 Mar 2024 20:36:08 -0400 Subject: [PATCH 6051/6505] Update homeassistant-core.sh tweak --- ct/homeassistant-core.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index d56ba5a1..738e2ea1 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -20,8 +20,8 @@ header_info echo -e "Loading..." APP="Home Assistant-Core" var_disk="8" -var_cpu="4" -var_ram="2048" +var_cpu="2" +var_ram="1024" var_os="debian" var_version="12" variables @@ -151,11 +151,6 @@ start build_container description -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 1024 -pct set $CTID -cores 2 -msg_ok "Set Container to Normal Resources" - msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8123${CL}" From 46cc3fe9856ce546b1c7c00553efba7d321ad486 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Mar 2024 04:24:42 -0400 Subject: [PATCH 6052/6505] Create flowiseai-install.sh --- install/flowiseai-install.sh | 57 ++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 install/flowiseai-install.sh diff --git a/install/flowiseai-install.sh b/install/flowiseai-install.sh new file mode 100644 index 00000000..04e97500 --- /dev/null +++ b/install/flowiseai-install.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +msg_ok "Installed Dependencies" + +msg_info "Installing Node.js" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing FlowiseAI (Patience)" +$STD npm install -g flowise +msg_ok "Installed FlowiseAI" + +msg_info "Creating Service" +cat </etc/systemd/system/flowise.service +[Unit] +Description=FlowiseAI +After=network.target + +[Service] +ExecStart=npx flowise start +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now flowise.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 80b2392f8e120ae7094396d91769d913b7ad9990 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Mar 2024 04:26:51 -0400 Subject: [PATCH 6053/6505] Create flowiseai.sh --- ct/flowiseai.sh | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 ct/flowiseai.sh diff --git a/ct/flowiseai.sh b/ct/flowiseai.sh new file mode 100644 index 00000000..42c70fdd --- /dev/null +++ b/ct/flowiseai.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ _ ___ ____ + / ____/ /___ _ __(_)_______ / | / _/ + / /_ / / __ \ | /| / / / ___/ _ \/ /| | / / + / __/ / / /_/ / |/ |/ / (__ ) __/ ___ |_/ / +/_/ /_/\____/|__/|__/_/____/\___/_/ |_/___/ + +EOF +} +header_info +echo -e "Loading..." +APP="FlowiseAI" +var_disk="10" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/flowise.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +systemctl stop flowise +npm install -g flowise --upgrade +systemctl start flowise +msg_ok "Updated ${APP}" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" From e8fcc7ec3d77257774ed02cd99b5c8d61bd810ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Mar 2024 04:55:12 -0400 Subject: [PATCH 6054/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d45a4eb8..d20067ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-03-13 + +### Changed + +- **FlowiseAI LXC** + - NEW Script + ## 2024-03-11 ### Changed From 6a77af66a49fd644ecce879cf4993611db77dcff Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Mar 2024 06:57:42 -0400 Subject: [PATCH 6055/6505] Update flowiseai-install.sh test --- install/flowiseai-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/flowiseai-install.sh b/install/flowiseai-install.sh index 04e97500..0ac6e298 100644 --- a/install/flowiseai-install.sh +++ b/install/flowiseai-install.sh @@ -30,6 +30,8 @@ msg_ok "Installed Node.js" msg_info "Installing FlowiseAI (Patience)" $STD npm install -g flowise +mkdir -p /opt/flowiseai +wget -q https://raw.githubusercontent.com/FlowiseAI/Flowise/main/packages/server/.env.example -O /opt/flowiseai/.env msg_ok "Installed FlowiseAI" msg_info "Creating Service" @@ -39,6 +41,7 @@ Description=FlowiseAI After=network.target [Service] +EnvironmentFile=/opt/flowiseai/.env ExecStart=npx flowise start Restart=always From 58b75e0dd8096ea4225e1c1ba8de2bd32a7d86f6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 13 Mar 2024 17:40:53 -0400 Subject: [PATCH 6056/6505] Update dashy.sh fix update --- ct/dashy.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index 23a28334..b06a3955 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -63,11 +63,11 @@ msg_ok "Stopped ${APP}" msg_info "Backing up conf.yml" cd ~ -cp -R /dashy/public/conf.yml conf.yml +cp -R /opt/dashy/public/conf.yml conf.yml msg_ok "Backed up conf.yml" msg_info "Updating Dashy" -cd /dashy +cd /opt/dashy git merge &>/dev/null git pull origin master &>/dev/null yarn &>/dev/null @@ -76,7 +76,7 @@ msg_ok "Updated Dashy" msg_info "Restoring conf.yml" cd ~ -cp -R conf.yml /dashy/public +cp -R conf.yml /opt/dashy/public msg_ok "Restored conf.yml" msg_info "Cleaning" From 019a80d7a1c005ce4726a32e3fb0f17db6eae5cb Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 14 Mar 2024 18:01:34 +0500 Subject: [PATCH 6057/6505] Mafl Dashboard update script (#2657) --- ct/mafl.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ct/mafl.sh b/ct/mafl.sh index 19012b6a..2dfee171 100644 --- a/ct/mafl.sh +++ b/ct/mafl.sh @@ -55,7 +55,19 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/mafl ]]; then msg_error "No ${APP} Installation Found!"; exit; fi - msg_error "There is currently no update path available." + + RELEASE=$(curl -s https://api.github.com/repos/hywax/mafl/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + msg_info "Updating Mafl to v${RELEASE} (Patience)" + systemctl stop mafl + wget -q https://github.com/hywax/mafl/archive/refs/tags/v${RELEASE}.tar.gz + tar -xzf v${RELEASE}.tar.gz + cp -r mafl-${RELEASE}/* /opt/mafl/ + rm -rf mafl-${RELEASE} + cd /opt/mafl + yarn install + yarn build + systemctl start mafl + msg_ok "Updated Mafl to v${RELEASE}" exit } From 2dffbc92c8e56db818d280cc6af046f07aadeda8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Mar 2024 09:35:22 -0400 Subject: [PATCH 6058/6505] Update nginxproxymanager.sh move "Installing pnpm" to the top of the script --- ct/nginxproxymanager.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 4045ff55..0abbfc1e 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -59,6 +59,11 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi + if ! command -v pnpm &> /dev/null; then + msg_info "Installing pnpm" + npm install -g pnpm &>/dev/null + msg_ok "Installed pnpm" + fi RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') @@ -130,12 +135,6 @@ function update_script() { python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null msg_ok "Setup Enviroment" - if ! command -v pnpm &> /dev/null; then - msg_info "Installing pnpm" - npm install -g pnpm &>/dev/null - msg_ok "Installed pnpm" - fi - msg_info "Building Frontend" cd ./frontend pnpm install &>/dev/null From 8d87cc6aaacd6e5d0609932601fa2074191e8239 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Mar 2024 09:37:32 -0400 Subject: [PATCH 6059/6505] Update nginxproxymanager.sh set pnpm version to 8.15 --- ct/nginxproxymanager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 0abbfc1e..16061a18 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -61,7 +61,7 @@ function update_script() { fi if ! command -v pnpm &> /dev/null; then msg_info "Installing pnpm" - npm install -g pnpm &>/dev/null + npm install -g pnpm@8.15 &>/dev/null msg_ok "Installed pnpm" fi RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest | From 6037d381ef3f061357b6d689f5fa89df26310c59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 14 Mar 2024 12:25:19 -0400 Subject: [PATCH 6060/6505] Update heimdalldashboard-install.sh tweak install --- install/heimdalldashboard-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/heimdalldashboard-install.sh b/install/heimdalldashboard-install.sh index 50515b9c..644e0c57 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdalldashboard-install.sh @@ -29,6 +29,9 @@ tar xzf ${RELEASE}.tar.gz VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') rm -rf ${RELEASE}.tar.gz mv Heimdall-${VER} /opt/Heimdall +cd /opt/Heimdall +cp .env.example .env +$STD php artisan key:generate msg_ok "Installed Heimdall Dashboard ${RELEASE}" msg_info "Creating Service" From bbb26ca3fc99fe38a6eff1519a5cdb1116b62f0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 02:39:57 -0400 Subject: [PATCH 6061/6505] Create welcome.yml --- .github/workflows/welcome.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/welcome.yml diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml new file mode 100644 index 00000000..b53aa90c --- /dev/null +++ b/.github/workflows/welcome.yml @@ -0,0 +1,25 @@ +name: Welcome +on: + pull_request: + types: [opened, closed] + issues: + types: [opened] +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: wow-actions/welcome@v1 + with: + FIRST_ISSUE: | + 👋 @{{ author }} + Thanks for opening your first issue here! Be sure to follow the issue template! + + FIRST_PR: | + 👋 @{{ author }} + Thanks for opening this pull request! Please check out our contributing guidelines. + + FIRST_PR_MERGED: | + 🎉 @{{ author }} + Congrats on merging your first pull request! We here at behaviorbot are proud of you! + + STAR_MESSAGE: If you like this project, please ⭐ our repo. From 66c685425f1265c1028681dbfedc1f7ed253a7b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 02:43:25 -0400 Subject: [PATCH 6062/6505] Create main.yml --- .github/workflows/main.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..bfc9cd8c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,16 @@ +on: + issues: + types: [opened, edited] + +jobs: + auto_close_issues: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Automatically close issues that don't follow the issue template + uses: lucasbento/auto-close-issues@v1.0.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + issue-close-message: "@${issue.user.login}: hello! :wave:\n\nThis issue is being automatically closed because it does not follow the issue template." # optional property + closed-issues-label: "🙁 Not following issue template" # optional property From a9b9f17aa3bf9e2a523ddec01829d5f6bffc648c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 02:50:50 -0400 Subject: [PATCH 6063/6505] Update main.yml --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bfc9cd8c..f0d08fd4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,6 +11,5 @@ jobs: - name: Automatically close issues that don't follow the issue template uses: lucasbento/auto-close-issues@v1.0.2 with: - github-token: ${{ secrets.GITHUB_TOKEN }} issue-close-message: "@${issue.user.login}: hello! :wave:\n\nThis issue is being automatically closed because it does not follow the issue template." # optional property closed-issues-label: "🙁 Not following issue template" # optional property From f0da879ae678e764072c85eb5978880ebcd20106 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 03:05:55 -0400 Subject: [PATCH 6064/6505] Update main.yml --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f0d08fd4..bfc9cd8c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,5 +11,6 @@ jobs: - name: Automatically close issues that don't follow the issue template uses: lucasbento/auto-close-issues@v1.0.2 with: + github-token: ${{ secrets.GITHUB_TOKEN }} issue-close-message: "@${issue.user.login}: hello! :wave:\n\nThis issue is being automatically closed because it does not follow the issue template." # optional property closed-issues-label: "🙁 Not following issue template" # optional property From d503898b77f326856c181b5548c68bbba3a73782 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 03:17:37 -0400 Subject: [PATCH 6065/6505] Update main.yml --- .github/workflows/main.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bfc9cd8c..8fea4324 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,7 +1,8 @@ +# Close any issue that does not match any of the issue templates +name: 🎯 Close Incomplete Issues on: issues: types: [opened, edited] - jobs: auto_close_issues: runs-on: ubuntu-latest @@ -11,6 +12,10 @@ jobs: - name: Automatically close issues that don't follow the issue template uses: lucasbento/auto-close-issues@v1.0.2 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - issue-close-message: "@${issue.user.login}: hello! :wave:\n\nThis issue is being automatically closed because it does not follow the issue template." # optional property - closed-issues-label: "🙁 Not following issue template" # optional property + github-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + closed-issues-label: '🙁 Auto-Closed' + issue-close-message: | + Hello @${issue.user.login} + Unfortunately your issue does not follow the format outlined in the template, and has therefore been auto-closed. + To ensure that all relevant info is included, please either update or recreate your issue, and complete the sub-headings provided. + Thank you :) From 9e2064b6657b349792c312adf1763cb14a65a9a9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 03:30:01 -0400 Subject: [PATCH 6066/6505] Update and rename main.yml to close-incomplete-issues.yml --- .github/workflows/{main.yml => close-incomplete-issues.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{main.yml => close-incomplete-issues.yml} (91%) diff --git a/.github/workflows/main.yml b/.github/workflows/close-incomplete-issues.yml similarity index 91% rename from .github/workflows/main.yml rename to .github/workflows/close-incomplete-issues.yml index 8fea4324..d97a8a56 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/close-incomplete-issues.yml @@ -12,7 +12,7 @@ jobs: - name: Automatically close issues that don't follow the issue template uses: lucasbento/auto-close-issues@v1.0.2 with: - github-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} closed-issues-label: '🙁 Auto-Closed' issue-close-message: | Hello @${issue.user.login} From 7654134e5e8174aabac2cfb1106ebdfb6c81bddb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 04:34:56 -0400 Subject: [PATCH 6067/6505] Update close-incomplete-issues.yml --- .github/workflows/close-incomplete-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/close-incomplete-issues.yml b/.github/workflows/close-incomplete-issues.yml index d97a8a56..87e0af60 100644 --- a/.github/workflows/close-incomplete-issues.yml +++ b/.github/workflows/close-incomplete-issues.yml @@ -13,7 +13,7 @@ jobs: uses: lucasbento/auto-close-issues@v1.0.2 with: github-token: ${{ secrets.GITHUB_TOKEN }} - closed-issues-label: '🙁 Auto-Closed' + closed-issues-label: 'Non-conforming Issue' issue-close-message: | Hello @${issue.user.login} Unfortunately your issue does not follow the format outlined in the template, and has therefore been auto-closed. From 3e01ebf221c77b1e6e29bedd63e69969f6464c77 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 05:59:46 -0400 Subject: [PATCH 6068/6505] Create config.yml --- .github/ISSUE_TEMPLATE/config.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..09abbdf7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Helper-Scripts Community Support + url: https://github.com/tteck/Proxmox/discussions + about: Please ask and answer questions here. From e1ac6d87f67646e72145d34cffc0ee6d40011c6a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 06:00:59 -0400 Subject: [PATCH 6069/6505] Delete .github/workflows/ci.yml --- .github/workflows/ci.yml | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 8cb50a45..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: CI - -on: - push: - branches: - - gh-pages - - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 20 - - - name: Checkout code - uses: actions/checkout@v3 From 3fdffb65407d72d0ec455d2a818002f209c0659a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 06:01:16 -0400 Subject: [PATCH 6070/6505] Delete .github/workflows/close-incomplete-issues.yml --- .github/workflows/close-incomplete-issues.yml | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 .github/workflows/close-incomplete-issues.yml diff --git a/.github/workflows/close-incomplete-issues.yml b/.github/workflows/close-incomplete-issues.yml deleted file mode 100644 index 87e0af60..00000000 --- a/.github/workflows/close-incomplete-issues.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Close any issue that does not match any of the issue templates -name: 🎯 Close Incomplete Issues -on: - issues: - types: [opened, edited] -jobs: - auto_close_issues: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: Automatically close issues that don't follow the issue template - uses: lucasbento/auto-close-issues@v1.0.2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - closed-issues-label: 'Non-conforming Issue' - issue-close-message: | - Hello @${issue.user.login} - Unfortunately your issue does not follow the format outlined in the template, and has therefore been auto-closed. - To ensure that all relevant info is included, please either update or recreate your issue, and complete the sub-headings provided. - Thank you :) From 39586380af4f79400aed7b8d6e0d962db278e631 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 06:12:05 -0400 Subject: [PATCH 6071/6505] Update bug_report.yaml --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 1e718f7d..4b2c8bcc 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,5 +1,5 @@ name: Problems with a script. -description: Generate a report on an issue pertaining specifically to a script. For other inquires please share them in the Discussions section. Blank issues will be closed immediately. +description: Generate a report on an issue pertaining specifically to a script. For other inquires please share them in the Discussions section. body: - type: markdown attributes: From aed9fdee7fced81daf1da517a99f050858858759 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 06:55:17 -0400 Subject: [PATCH 6072/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 4b2c8bcc..6b73c929 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -35,7 +35,7 @@ body: - Debian 12 - Ubuntu 20.04 - Ubuntu 22.04 - - Ubuntu 23.04 + - Ubuntu 23.10 - type: textarea id: screenshot attributes: From 1d6c0acf0dfa872d1c768818185bfdb1a06426f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 07:20:07 -0400 Subject: [PATCH 6073/6505] Update pull_request_template.md tweak --- .github/pull_request_template.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4bf88433..39173ba0 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -10,7 +10,9 @@ Fixes # (issue) Please delete options that are not relevant. -- [ ] Bug fix -- [ ] New feature -- [ ] New Script +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] New Script (Develop a new script or set of scripts that are fully functional and thoroughly tested) +- [ ] I have performed a self-review of my code, adhering to established codebase patterns and conventions. - [ ] This change requires a documentation update From 2fa12a1b97aaf04c91a3cfb467c37c4d2f48080e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 09:59:56 -0400 Subject: [PATCH 6074/6505] Delete .github/workflows/welcome.yml --- .github/workflows/welcome.yml | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 .github/workflows/welcome.yml diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml deleted file mode 100644 index b53aa90c..00000000 --- a/.github/workflows/welcome.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Welcome -on: - pull_request: - types: [opened, closed] - issues: - types: [opened] -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: wow-actions/welcome@v1 - with: - FIRST_ISSUE: | - 👋 @{{ author }} - Thanks for opening your first issue here! Be sure to follow the issue template! - - FIRST_PR: | - 👋 @{{ author }} - Thanks for opening this pull request! Please check out our contributing guidelines. - - FIRST_PR_MERGED: | - 🎉 @{{ author }} - Congrats on merging your first pull request! We here at behaviorbot are proud of you! - - STAR_MESSAGE: If you like this project, please ⭐ our repo. From 75532e028c9b834c5f9632999f698ebdde951506 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 10:47:20 -0400 Subject: [PATCH 6075/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 6b73c929..3de356ea 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -27,10 +27,19 @@ body: validations: required: true attributes: - label: Which Linux distribution are you employing? + label: What settings are you currently utilizing? options: - - Default Settings + - Advanced Settings + - type: dropdown + id: distribution + validations: + required: true + attributes: + label: Which Linux distribution are you employing? + options: + - - Debian 11 - Debian 12 - Ubuntu 20.04 From da027417e9d8d7cc2c2d18a594b34d9b58f0dfaf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 10:47:55 -0400 Subject: [PATCH 6076/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 3de356ea..6d9be1f5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -23,7 +23,7 @@ body: validations: required: true - type: dropdown - id: distribution + id: settings validations: required: true attributes: From 8e76d536d817d59f7f11a9984ebcf13c0d3956ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 11:35:40 -0400 Subject: [PATCH 6077/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 6d9be1f5..346fb93b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -32,6 +32,9 @@ body: - - Default Settings - Advanced Settings + - type: markdown + attributes: + value: (if Advanced Settings, please try Default Settings before creating an issue) - type: dropdown id: distribution validations: From 8a72055ebe00c4610e29003329ebaaf7341b348f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 19 Mar 2024 22:08:01 -0400 Subject: [PATCH 6078/6505] Update unifi-install.sh - Code refactoring - MongoDB version 7.0.7 --- install/unifi-install.sh | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 54fbef00..29b1b9c6 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -21,26 +21,23 @@ $STD apt-get install -y apt-transport-https $STD apt-get install -y gnupg msg_ok "Installed Dependencies" -msg_info "Installing OpenJDK" +msg_info "Installing Eclipse Temurin JRE" wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg -echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list +echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main" >/etc/apt/sources.list.d/adoptium.list $STD apt-get update $STD apt-get install -y temurin-17-jre -msg_ok "Installed OpenJDK" +msg_ok "Installed Eclipse Temurin JRE" msg_info "Installing MongoDB" -libssl=$(curl -fsSL "http://security.ubuntu.com/ubuntu/pool/main/o/openssl/" | grep -o 'libssl1\.1_1\.1\.1f-1ubuntu2\.2[^"]*amd64\.deb' | head -n1) -wget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/$libssl -$STD dpkg -i $libssl -wget -qO- https://pgp.mongodb.com/server-4.4.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg -echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main' >/etc/apt/sources.list.d/mongodb-org-4.4.list +wget -qO- https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-7.0.gpg +echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] http://repo.mongodb.org/apt/debian bookworm/mongodb-org/7.0 main" >/etc/apt/sources.list.d/mongodb-org-7.0.list $STD apt-get update $STD apt-get install -y mongodb-org msg_ok "Installed MongoDB" msg_info "Installing UniFi Network Application" wget -qO /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ui.com/unifi/unifi-repo.gpg -echo 'deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/unifi-repo.gpg] https://www.ui.com/downloads/unifi/debian stable ubiquiti' >/etc/apt/sources.list.d/100-ubnt-unifi.list +echo "deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/unifi-repo.gpg] https://www.ui.com/downloads/unifi/debian stable ubiquiti" >/etc/apt/sources.list.d/100-ubnt-unifi.list $STD apt-get update $STD apt-get install -y unifi msg_ok "Installed UniFi Network Application" @@ -49,7 +46,6 @@ motd_ssh customize msg_info "Cleaning up" -rm -rf $libssl $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" From 6d9d710de86531c22cae498b570c628e334d1d52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Mar 2024 05:25:47 -0400 Subject: [PATCH 6079/6505] Update config.yml --- .github/ISSUE_TEMPLATE/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 09abbdf7..0eb07a0e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,11 @@ blank_issues_enabled: false contact_links: + - name: Failure to comply with the following guidelines may result in immediate closure. + about: | + - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. + - If the default Linux distribution is not adhered to, script support will be discontinued. + - When encountering the error message `[ERROR] in line 23: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. + - For suggestions, questions, or feature/script requests, please share them in Helper-Scripts Community Support. - name: Helper-Scripts Community Support url: https://github.com/tteck/Proxmox/discussions about: Please ask and answer questions here. From 1657890c8e20747d1d1474f22f74f4809075b180 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Mar 2024 05:26:36 -0400 Subject: [PATCH 6080/6505] Update config.yml --- .github/ISSUE_TEMPLATE/config.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 0eb07a0e..09abbdf7 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,5 @@ blank_issues_enabled: false contact_links: - - name: Failure to comply with the following guidelines may result in immediate closure. - about: | - - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one. - - If the default Linux distribution is not adhered to, script support will be discontinued. - - When encountering the error message `[ERROR] in line 23: exit code *: while executing command "$@" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue. - - For suggestions, questions, or feature/script requests, please share them in Helper-Scripts Community Support. - name: Helper-Scripts Community Support url: https://github.com/tteck/Proxmox/discussions about: Please ask and answer questions here. From 6c5503b5006cd5def5140312cef7b80adfb9b5e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 20 Mar 2024 14:55:27 -0400 Subject: [PATCH 6081/6505] Update unifi-install.sh tweak --- install/unifi-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 29b1b9c6..61460b7d 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -35,12 +35,12 @@ $STD apt-get update $STD apt-get install -y mongodb-org msg_ok "Installed MongoDB" -msg_info "Installing UniFi Network Application" +msg_info "Installing UniFi Network Server" wget -qO /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ui.com/unifi/unifi-repo.gpg echo "deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/unifi-repo.gpg] https://www.ui.com/downloads/unifi/debian stable ubiquiti" >/etc/apt/sources.list.d/100-ubnt-unifi.list $STD apt-get update $STD apt-get install -y unifi -msg_ok "Installed UniFi Network Application" +msg_ok "Installed UniFi Network Server" motd_ssh customize From c5ddb590d771ba3f31335d4723cd5c26994823cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 21 Mar 2024 17:11:00 -0400 Subject: [PATCH 6082/6505] Update tandoor-install.sh fixes https://github.com/tteck/Proxmox/issues/2685 --- install/tandoor-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index 87fdd91b..fa0e0ac3 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -114,7 +114,7 @@ server { listen 8002; #access_log /var/log/nginx/access.log; #error_log /var/log/nginx/error.log; - + client_max_body_size 128M; # serve media files location /static/ { alias /opt/tandoor/staticfiles/; From 59dfb89db7e7878f302163ae40341d0193520c7e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Mar 2024 00:01:39 -0400 Subject: [PATCH 6083/6505] Update hyperion-install.sh update install to utilize Debian 12 --- install/hyperion-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh index 19b8a88e..3ac24e5a 100644 --- a/install/hyperion-install.sh +++ b/install/hyperion-install.sh @@ -20,13 +20,13 @@ $STD apt-get install -y mc $STD apt-get install -y lsb-release $STD apt-get install -y gpg $STD apt-get install -y apt-transport-https -$STD apt-get install -y libpython3.9 +$STD apt-get install -y libpython3.11 msg_ok "Installed Dependencies" msg_info "Installing Hyperion" -wget -qO- https://apt.hyperion-project.org/hyperion.pub.key | gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg -sh -c 'echo "deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.hyperion-project.org/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/hyperion.list' +wget -qO- https://releases.hyperion-project.org/hyperion.pub.key | gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg +echo "deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.releases.hyperion-project.org/ $(lsb_release -cs) main" >/etc/apt/sources.list.d/hyperion.list $STD apt-get update $STD apt-get install -y hyperion $STD systemctl enable --now hyperion@root.service From 9f32d30f6be6c71de1265cce9fec7ddc2ce0352e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 22 Mar 2024 00:02:32 -0400 Subject: [PATCH 6084/6505] Update hyperion.sh default Debian 12 --- ct/hyperion.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/hyperion.sh b/ct/hyperion.sh index 9bb9a141..4edd8dd8 100644 --- a/ct/hyperion.sh +++ b/ct/hyperion.sh @@ -24,7 +24,7 @@ var_disk="2" var_cpu="1" var_ram="512" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 32904ccfed7e4a2148d15f4d2a3adc1dd07c6ad5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Mar 2024 11:09:09 -0400 Subject: [PATCH 6085/6505] Create smokeping-install.sh --- install/smokeping-install.sh | 77 ++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 install/smokeping-install.sh diff --git a/install/smokeping-install.sh b/install/smokeping-install.sh new file mode 100644 index 00000000..3a214b6c --- /dev/null +++ b/install/smokeping-install.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing SmokePing" +$STD apt-get install -y smokeping +cat </etc/smokeping/config.d/Targets +*** Targets *** +probe = FPing +menu = Top +title = Network Latency Grapher +remark = Welcome to SmokePing. ++ Local +menu = Local +title = Local Network (ICMP) +++ LocalMachine +menu = Local Machine +title = This host +host = localhost ++ DNS +menu = DNS latency +title = DNS latency (ICMP) +++ Google +title = Google +host = 8.8.8.8 +++ Cloudflare +title = Cloudflare +host = 1.1.1.1 +++ Quad9 +title = Quad9 +host = 9.9.9.9 +++ OpenDNS +title = OpenDNS +host = 208.67.222.222 ++ HTTP +menu = HTTP latency +title = HTTP latency (ICMP) +++ Github +host = github.com +++ Discord +host = discord.com +++ Google +host = google.com +++ Cloudflare +host = cloudflare.com +++ Amazon +host = amazon.com +++ Netflix +host = netflix.com +EOF +systemctl restart smokeping +msg_ok "Installed SmokePing" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From d467d4ce5f2792ba8e47f1e8ba97c4f9492e877a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Mar 2024 11:10:19 -0400 Subject: [PATCH 6086/6505] Create Smokeping.sh --- ct/Smokeping.sh | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 ct/Smokeping.sh diff --git a/ct/Smokeping.sh b/ct/Smokeping.sh new file mode 100644 index 00000000..8da7d96c --- /dev/null +++ b/ct/Smokeping.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ __ ____ _ + / ___/____ ___ ____ / /_____ / __ \(_)___ ____ _ + \__ \/ __ `__ \/ __ \/ //_/ _ \/ /_/ / / __ \/ __ `/ + ___/ / / / / / / /_/ / ,< / __/ ____/ / / / / /_/ / +/____/_/ /_/ /_/\____/_/|_|\___/_/ /_/_/ /_/\__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="SmokePing" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if ! command -v smokeping &> /dev/null; then msg_error "No ${APP} Installation Found!"; exit; fi + +msg_info "Updating ${APP}" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Successfully" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}/smokeping${CL} \n" From 31b7a8209482329685ebcd37e212741949065507 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Mar 2024 11:12:30 -0400 Subject: [PATCH 6087/6505] Rename Smokeping.sh to smokeping.sh --- ct/{Smokeping.sh => smokeping.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{Smokeping.sh => smokeping.sh} (100%) diff --git a/ct/Smokeping.sh b/ct/smokeping.sh similarity index 100% rename from ct/Smokeping.sh rename to ct/smokeping.sh From 8e129001c728ed6d2cd9d600c45611ef26aa121d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 24 Mar 2024 11:21:00 -0400 Subject: [PATCH 6088/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d20067ea..3bf618bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-03-24 + +### Changed + +- **SmokePing LXC** + - NEW Script + ## 2024-03-13 ### Changed From a807d87e84b855f5b3937b6af33e22c7a8db1d58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 09:48:54 -0400 Subject: [PATCH 6089/6505] Create mediamtx-install.sh --- install/mediamtx-install.sh | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 install/mediamtx-install.sh diff --git a/install/mediamtx-install.sh b/install/mediamtx-install.sh new file mode 100644 index 00000000..6adbb6ee --- /dev/null +++ b/install/mediamtx-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing MediaMTX" +RELEASE=$(curl -s https://api.github.com/repos/bluenviron/mediamtx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +mkdir -p /opt/mediamtx +cd /opt/mediamtx +wget -q https://github.com/bluenviron/mediamtx/releases/download/${RELEASE}/mediamtx_${RELEASE}_linux_amd64.tar.gz +tar xzf mediamtx_${RELEASE}_linux_amd64.tar.gz +rm -rf mediamtx_${RELEASE}_linux_amd64.tar.gz +msg_ok "Installed MediaMTX" + +msg_info "Creating Service" +cat </etc/systemd/system/mediamtx.service +[Unit] +Description=MediaMTX +After=syslog.target network-online.target + +[Service] +ExecStart=/opt/mediamtx/./mediamtx +WorkingDirectory=/opt/mediamtx +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now mediamtx.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 018ab69a33552b693395197e1dde86f534752bfb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 09:49:50 -0400 Subject: [PATCH 6090/6505] Create mediamtx.sh --- ct/mediamtx.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ct/mediamtx.sh diff --git a/ct/mediamtx.sh b/ct/mediamtx.sh new file mode 100644 index 00000000..db8508ff --- /dev/null +++ b/ct/mediamtx.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ ___ __ __________ __ + / |/ /__ ____/ (_)___ _/ |/ /_ __/ |/ / + / /|_/ / _ \/ __ / / __ `/ /|_/ / / / | / + / / / / __/ /_/ / / /_/ / / / / / / / | +/_/ /_/\___/\__,_/_/\__,_/_/ /_/ /_/ /_/|_| + +EOF +} +header_info +echo -e "Loading..." +APP="MediaMTX" +var_disk="2" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/mediamtx/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" From 12b0a0bf503e729a08f05e1a20ccea9fc6835529 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 09:58:50 -0400 Subject: [PATCH 6091/6505] Update mediamtx-install.sh add ffmpeg --- install/mediamtx-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/mediamtx-install.sh b/install/mediamtx-install.sh index 6adbb6ee..c41d4afd 100644 --- a/install/mediamtx-install.sh +++ b/install/mediamtx-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y ffmpeg msg_ok "Installed Dependencies" msg_info "Installing MediaMTX" From 2f836f4e6dcc5252efa508717e73c926ad9e40d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 10:21:02 -0400 Subject: [PATCH 6092/6505] Update mediamtx.sh add additional storage --- ct/mediamtx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mediamtx.sh b/ct/mediamtx.sh index db8508ff..83e660eb 100644 --- a/ct/mediamtx.sh +++ b/ct/mediamtx.sh @@ -20,7 +20,7 @@ EOF header_info echo -e "Loading..." APP="MediaMTX" -var_disk="2" +var_disk="4" var_cpu="2" var_ram="2048" var_os="debian" From f25189933db460c7edf281e5cecb7d16ce6fb2e8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 10:36:28 -0400 Subject: [PATCH 6093/6505] Update post-pve-install.sh allow any PVE 8 --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index ea166360..09e89908 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -231,7 +231,7 @@ while true; do esac done -if ! pveversion | grep -Eq "pve-manager/(8.1.[1-9])"; then +if ! pveversion | grep -Eq "pve-manager/8\.[0-2]+\.[0-9]+"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires Proxmox Virtual Environment Version 8.1.1 or later." echo -e "Exiting..." From fe416bc6ff536779787931062a01dba01fd7e289 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 10:48:31 -0400 Subject: [PATCH 6094/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 09e89908..254c6b8b 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -231,7 +231,7 @@ while true; do esac done -if ! pveversion | grep -Eq "pve-manager/8\.[0-2]+\.[0-9]+"; then +if ! pveversion | grep -Eq "pve-manager/8\.[0-2]\.[0-9]"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires Proxmox Virtual Environment Version 8.1.1 or later." echo -e "Exiting..." From d65fd07f508cacd9151c5d0f79a73d0f3741d2fb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 10:49:49 -0400 Subject: [PATCH 6095/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 254c6b8b..1ae4b3b6 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -233,7 +233,7 @@ done if ! pveversion | grep -Eq "pve-manager/8\.[0-2]\.[0-9]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.0 or later." echo -e "Exiting..." sleep 2 exit From cff9b233c7ba8a7e1c641307e65ad64b05f4181e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 10:56:23 -0400 Subject: [PATCH 6096/6505] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bf618bf..b447f06a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,14 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-03-25 + +### Changed + +- **Proxmox VE Post Install** + - ~Requires Proxmox Virtual Environment Version 8.1.1 or later.~ + - Requires Proxmox Virtual Environment Version 8.0 or later. + ## 2024-03-24 ### Changed From b6f8d7f6241db0d6cdfeb8cf040b3e6cf03197ae Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 13:16:19 -0400 Subject: [PATCH 6097/6505] Create pbs-install.sh --- install/pbs-install.sh | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 install/pbs-install.sh diff --git a/install/pbs-install.sh b/install/pbs-install.sh new file mode 100644 index 00000000..83978159 --- /dev/null +++ b/install/pbs-install.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Proxmox Backup Server" +wget https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg +cat <>/etc/apt/sources.list +deb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription +EOF +$STD apt-get update +$STD apt-get install -y proxmox-backup-server +msg_ok "Installed Proxmox Backup Server" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 3b1dd2efc07c5d15279041d2b4069efd78dd13e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 13:17:52 -0400 Subject: [PATCH 6098/6505] Create pbs.sh --- pbs.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 pbs.sh diff --git a/pbs.sh b/pbs.sh new file mode 100644 index 00000000..97ffd5a4 --- /dev/null +++ b/pbs.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ ____ __ _____ + / __ \_________ _ ______ ___ ____ _ __ / __ )____ ______/ /____ ______ / ___/___ ______ _____ _____ + / /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ / __ / __ `/ ___/ //_/ / / / __ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ + / ____/ / / /_/ /> < / /_/ / /_/ / /__/ ,< / /_/ / /_/ / ___/ / __/ / | |/ / __/ / +/_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| /_____/\__,_/\___/_/|_|\__,_/ .___/ /____/\___/_/ |___/\___/_/ + /_/ +EOF +} +header_info +echo -e "Loading..." +APP="PBS" +var_disk="10" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8007${CL} \n" From c0ca12e712e5a1a39bc791b3334b3924c825e5f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 13:21:06 -0400 Subject: [PATCH 6099/6505] Create pbs.sh --- ct/pbs.sh | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 ct/pbs.sh diff --git a/ct/pbs.sh b/ct/pbs.sh new file mode 100644 index 00000000..97ffd5a4 --- /dev/null +++ b/ct/pbs.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ ____ __ _____ + / __ \_________ _ ______ ___ ____ _ __ / __ )____ ______/ /____ ______ / ___/___ ______ _____ _____ + / /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ / __ / __ `/ ___/ //_/ / / / __ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ + / ____/ / / /_/ /> < / /_/ / /_/ / /__/ ,< / /_/ / /_/ / ___/ / __/ / | |/ / __/ / +/_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| /_____/\__,_/\___/_/|_|\__,_/ .___/ /____/\___/_/ |___/\___/_/ + /_/ +EOF +} +header_info +echo -e "Loading..." +APP="PBS" +var_disk="10" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8007${CL} \n" From d5d314e5ebdc80d7ecf203614a10e14edcb09df4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 13:24:13 -0400 Subject: [PATCH 6100/6505] Update pbs-install.sh tweak --- install/pbs-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/pbs-install.sh b/install/pbs-install.sh index 83978159..99203391 100644 --- a/install/pbs-install.sh +++ b/install/pbs-install.sh @@ -20,7 +20,7 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Proxmox Backup Server" -wget https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg +wget -q https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg cat <>/etc/apt/sources.list deb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription EOF From 6445e0eac36b68afb733124ee9a948512efb6ebc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 14:37:08 -0400 Subject: [PATCH 6101/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b447f06a..1a644b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ - **Proxmox VE Post Install** - ~Requires Proxmox Virtual Environment Version 8.1.1 or later.~ - Requires Proxmox Virtual Environment Version 8.0 or later. +- **Proxmox Backup Server LXC** + - NEW Script ## 2024-03-24 From e1e0b4af9ee5c58b69c4362f697aaedf7299f4ed Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 25 Mar 2024 14:58:49 -0400 Subject: [PATCH 6102/6505] Delete pbs.sh found the stray --- pbs.sh | 72 ---------------------------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 pbs.sh diff --git a/pbs.sh b/pbs.sh deleted file mode 100644 index 97ffd5a4..00000000 --- a/pbs.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash - -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2024 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - ____ ____ __ _____ - / __ \_________ _ ______ ___ ____ _ __ / __ )____ ______/ /____ ______ / ___/___ ______ _____ _____ - / /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ / __ / __ `/ ___/ //_/ / / / __ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ - / ____/ / / /_/ /> < / /_/ / /_/ / /__/ ,< / /_/ / /_/ / ___/ / __/ / | |/ / __/ / -/_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| /_____/\__,_/\___/_/|_|\__,_/ .___/ /____/\___/_/ |___/\___/_/ - /_/ -EOF -} -header_info -echo -e "Loading..." -APP="PBS" -var_disk="10" -var_cpu="2" -var_ram="2048" -var_os="debian" -var_version="12" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET="dhcp" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { -header_info -if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" -exit -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8007${CL} \n" From 23e6b80a9e7c63beb1c7075822fff143a3522329 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 26 Mar 2024 09:19:43 -0400 Subject: [PATCH 6103/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a644b76..173aca78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-03-26 + +### Changed + +- **MediaMTX LXC** + - NEW Script + ## 2024-03-25 ### Changed From 98e8955ec1db4424df229083a8d1c8d7e513ee3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 27 Mar 2024 12:46:31 -0400 Subject: [PATCH 6104/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 1ae4b3b6..572b4811 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -231,7 +231,7 @@ while true; do esac done -if ! pveversion | grep -Eq "pve-manager/8\.[0-2]\.[0-9]"; then +if ! pveversion | grep -Eq "pve-manager/8\.[0-2]\."; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires Proxmox Virtual Environment Version 8.0 or later." echo -e "Exiting..." From 21d0e96b56d766467b14ec808db7b421dad0d87d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Mar 2024 13:02:34 -0400 Subject: [PATCH 6105/6505] Update post-pve-install.sh tweak --- misc/post-pve-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index 572b4811..ec8d7d98 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -231,7 +231,7 @@ while true; do esac done -if ! pveversion | grep -Eq "pve-manager/8\.[0-2]\."; then +if ! pveversion | grep -Eq "pve-manager/8.[0-2]"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires Proxmox Virtual Environment Version 8.0 or later." echo -e "Exiting..." From 597162b0a819ff75f0faaef506192479df987e20 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 29 Mar 2024 15:00:38 -0400 Subject: [PATCH 6106/6505] Update tdarr-install.sh Download the latest `Tdarr_Updater` --- install/tdarr-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index 69321662..f4f45d04 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -37,7 +37,8 @@ fi msg_info "Installing Tdarr" mkdir -p /opt/tdarr cd /opt/tdarr -wget -q https://f000.backblazeb2.com/file/tdarrs/versions/2.00.15/linux_x64/Tdarr_Updater.zip +RELEASE=$(curl -s https://f000.backblazeb2.com/file/tdarrs/versions.json | grep -oP '(?<="Tdarr_Updater": ")[^"]+' | grep linux_x64 | head -n 1) +wget -q $RELEASE $STD unzip Tdarr_Updater.zip rm -rf Tdarr_Updater.zip chmod +x Tdarr_Updater From 4ba3233dc0d6bd30dedb891db1d99f1ed9874aa8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Mar 2024 08:13:34 -0400 Subject: [PATCH 6107/6505] Update build.func Add Frigate to the VAAPI hardware transcoding group --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index f21ad361..bac97de5 100644 --- a/misc/build.func +++ b/misc/build.func @@ -570,7 +570,7 @@ EOF fi if [ "$CT_TYPE" == "0" ]; then - if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then + if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then cat <>$LXC_CONFIG # VAAPI hardware transcoding lxc.cgroup2.devices.allow: c 226:0 rwm From f956273fc57f6dc5c0f47724221a5bc79d8151f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Sat, 30 Mar 2024 08:15:03 -0400 Subject: [PATCH 6108/6505] Add Frigate scripts (#2714) --- ct/frigate.sh | 72 +++++++++++++++ install/frigate-install.sh | 181 +++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 ct/frigate.sh create mode 100644 install/frigate-install.sh diff --git a/ct/frigate.sh b/ct/frigate.sh new file mode 100644 index 00000000..77474314 --- /dev/null +++ b/ct/frigate.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Authors: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ______ _ __ + / ____/____(_)___ _____ _/ /____ + / /_ / ___/ / __ `/ __ `/ __/ _ \ + / __/ / / / / /_/ / /_/ / /_/ __/ +/_/ /_/ /_/\__, /\__,_/\__/\___/ + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Frigate" +var_disk="20" +var_cpu="4" +var_ram="4096" +var_os="debian" +var_version="11" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -f /etc/systemd/system/frigate.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + msg_error "There is currently no update path available." + exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 1024 +pct set $CTID -cores 2 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" diff --git a/install/frigate-install.sh b/install/frigate-install.sh new file mode 100644 index 00000000..b30749e8 --- /dev/null +++ b/install/frigate-install.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Authors: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y {curl,sudo,mc,git,gpg,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb2,libtbb-dev,libdc1394-22-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev} +msg_ok "Installed Dependencies" + +msg_info "Installing Python3 Dependencies" +$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils} +wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py +$STD python3 get-pip.py --quiet "pip" +msg_ok "Installed Python3 Dependencies" + +msg_info "Installing Node.js" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing go2rtc" +mkdir -p /usr/local/go2rtc/bin +cd /usr/local/go2rtc/bin +wget -qO go2rtc "https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64" +chmod +x go2rtc +$STD ln -svf /usr/local/go2rtc/bin/go2rtc /usr/local/bin/go2rtc +msg_ok "Installed go2rtc" + +if [[ "$CTTYPE" == "0" ]]; then + msg_info "Setting Up Hardware Acceleration" + $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} + chgrp video /dev/dri + chmod 755 /dev/dri + chmod 660 /dev/dri/* + $STD adduser $(id -u -n) video + $STD adduser $(id -u -n) render + msg_ok "Set Up Hardware Acceleration" +fi + +RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) +msg_info "Installing Frigate $RELEASE (Perseverance)" +cd ~ +mkdir -p /opt/frigate/models +wget -q https://github.com/blakeblackshear/frigate/archive/refs/tags/${RELEASE}.tar.gz -O frigate.tar.gz +tar -xzf frigate.tar.gz -C /opt/frigate --strip-components 1 +rm -rf frigate.tar.gz +cd /opt/frigate +$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt +cp -a /opt/frigate/docker/main/rootfs/. / +export TARGETARCH="amd64" +echo 'libc6 libraries/restart-without-asking boolean true' | debconf-set-selections +$STD /opt/frigate/docker/main/install_deps.sh +$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg +$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe +$STD pip3 install -U /wheels/*.whl +ldconfig +$STD pip3 install -r /opt/frigate/docker/main/requirements-dev.txt +$STD /opt/frigate/.devcontainer/initialize.sh +$STD make version +cd /opt/frigate/web +$STD npm install +$STD npm run build +cp -r /opt/frigate/web/dist/* /opt/frigate/web/ +cp -r /opt/frigate/config/. /config +sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run +msg_ok "Installed Frigate $RELEASE" + +msg_info "Installing Object Detection Models (Resilience)" +$STD pip install -r /opt/frigate/docker/main/requirements-ov.txt +cd /opt/frigate/models +export ENABLE_ANALYTICS=NO +$STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 +cd .. +export CCACHE_DIR=/root/.ccache +export CCACHE_MAXSIZE=2G +wget -q https://github.com/libusb/libusb/archive/v1.0.26.zip +unzip -q v1.0.26.zip +cd libusb-1.0.26 +$STD ./bootstrap.sh +$STD ./configure --disable-udev --enable-shared +$STD make -j $(nproc --all) +cd /opt/frigate/libusb-1.0.26/libusb +mkdir -p /usr/local/lib +$STD /bin/bash ../libtool --mode=install /usr/bin/install -c libusb-1.0.la '/usr/local/lib' +mkdir -p /usr/local/include/libusb-1.0 +$STD /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0' +ldconfig +cd ~ +wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite +wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite +cp /opt/frigate/labelmap.txt /labelmap.txt +cp -r /opt/frigate/models/public/ssdlite_mobilenet_v2 openvino-model +wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt -O openvino-model/coco_91cl_bkgr.txt +sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt +wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite +cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt +msg_ok "Installed Object Detection Models" + +msg_info "Building Nginx with Custom Modules" +$STD /opt/frigate/docker/main/build_nginx.sh +sed -i 's/exec nginx/exec \/usr\/local\/nginx\/sbin\/nginx/g' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run +sed -i 's/error_log \/dev\/stdout warn\;/error_log nginx\.err warn\;/' /usr/local/nginx/conf/nginx.conf +sed -i 's/access_log \/dev\/stdout main\;/access_log nginx\.log main\;/' /usr/local/nginx/conf/nginx.conf +msg_ok "Built Nginx" + +msg_info "Creating Services" +cat </etc/systemd/system/go2rtc.service +[Unit] +Description=go2rtc service +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now go2rtc +sleep 3 +cat </etc/systemd/system/frigate.service +[Unit] +Description=Frigate service +After=go2rtc.service +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now frigate +sleep 3 +cat </etc/systemd/system/nginx.service +[Unit] +Description=Nginx service +After=frigate.service +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now nginx +msg_ok "Configured Services" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 90463f5aafbbf31c4b431cc19801a80a2aadc3e4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 30 Mar 2024 11:15:57 -0400 Subject: [PATCH 6109/6505] Update frigate-install.sh Remove libusb zip --- install/frigate-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index b30749e8..0115afbe 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -88,6 +88,7 @@ export CCACHE_DIR=/root/.ccache export CCACHE_MAXSIZE=2G wget -q https://github.com/libusb/libusb/archive/v1.0.26.zip unzip -q v1.0.26.zip +rm v1.0.26.zip cd libusb-1.0.26 $STD ./bootstrap.sh $STD ./configure --disable-udev --enable-shared From a16f31bbcab91571d27e2945d2b03fe7933dc114 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 04:09:29 -0400 Subject: [PATCH 6110/6505] Update bug_report.yaml Add Alpine --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 346fb93b..3789546e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -43,6 +43,7 @@ body: label: Which Linux distribution are you employing? options: - + - Alpine - Debian 11 - Debian 12 - Ubuntu 20.04 From 35837f056d38b0a607402f0afc5ae54b807d8ef9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 06:30:21 -0400 Subject: [PATCH 6111/6505] Update frigate.sh keep 4vCPUs --- ct/frigate.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/frigate.sh b/ct/frigate.sh index 77474314..7ac4e1d6 100644 --- a/ct/frigate.sh +++ b/ct/frigate.sh @@ -65,7 +65,6 @@ description msg_info "Setting Container to Normal Resources" pct set $CTID -memory 1024 -pct set $CTID -cores 2 msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. From 6e3e49337b2e377084549c24052780365e9faa42 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 06:36:57 -0400 Subject: [PATCH 6112/6505] Update frigate-install.sh - Download new input file - Create new config.yml - Link `/config/config.yml` and `/opt/frigate/config/config.yml` - Create log directories - Fix GID mismatch --- install/frigate-install.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 0115afbe..6c5b372d 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -76,6 +76,34 @@ $STD npm run build cp -r /opt/frigate/web/dist/* /opt/frigate/web/ cp -r /opt/frigate/config/. /config sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run +wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 +cat </config/config.yml +mqtt: + enabled: false +model: + path: /root/cpu_model.tflite +cameras: + test: + ffmpeg: + inputs: + - path: /media/frigate/person-bicycle-car-detection.mp4 + input_args: -re -stream_loop -1 -fflags +genpts + roles: + - detect + - rtmp + detect: + height: 1080 + width: 1920 + fps: 5 +EOF + +ln -sf /config/config.yml /opt/frigate/config/config.yml + +mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} +touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} +chmod -R 777 /dev/shm + +sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group msg_ok "Installed Frigate $RELEASE" msg_info "Installing Object Detection Models (Resilience)" From 6c9f829ee9ad62ae37b5d0d838e86a454bdda0db Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 06:48:02 -0400 Subject: [PATCH 6113/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 6c5b372d..fcc94fcb 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -76,7 +76,7 @@ $STD npm run build cp -r /opt/frigate/web/dist/* /opt/frigate/web/ cp -r /opt/frigate/config/. /config sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run -wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 +wget -qO /root/media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 cat </config/config.yml mqtt: enabled: false @@ -96,13 +96,10 @@ cameras: width: 1920 fps: 5 EOF - ln -sf /config/config.yml /opt/frigate/config/config.yml - mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} chmod -R 777 /dev/shm - sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group msg_ok "Installed Frigate $RELEASE" From 3817e9372fa6517f84799998963c7322badcb8ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 06:58:08 -0400 Subject: [PATCH 6114/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index fcc94fcb..96637a8c 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -76,7 +76,6 @@ $STD npm run build cp -r /opt/frigate/web/dist/* /opt/frigate/web/ cp -r /opt/frigate/config/. /config sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run -wget -qO /root/media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 cat </config/config.yml mqtt: enabled: false @@ -133,6 +132,7 @@ wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/datase sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt +wget -qO /root/media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 msg_ok "Installed Object Detection Models" msg_info "Building Nginx with Custom Modules" From 980fb26b416ae72c696da8dbf2ec28bf88caf66b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 07:05:24 -0400 Subject: [PATCH 6115/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 96637a8c..5542cca0 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -132,7 +132,7 @@ wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/datase sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt -wget -qO /root/media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 +wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 msg_ok "Installed Object Detection Models" msg_info "Building Nginx with Custom Modules" From 3233fbf5f592adcd7fa898e2df7478642de961f5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 07:19:13 -0400 Subject: [PATCH 6116/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 5542cca0..c4cb35fd 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -132,6 +132,7 @@ wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/datase sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt +mkdir -p /media/frigate wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 msg_ok "Installed Object Detection Models" From 8ee221974b31ac7480099352656dda7ea0b893b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 08:19:44 -0400 Subject: [PATCH 6117/6505] Update frigate-install.sh Add `hwaccel_args: preset-vaapi` to `config.yml` --- install/frigate-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index c4cb35fd..9170e5f5 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -84,6 +84,7 @@ model: cameras: test: ffmpeg: + #hwaccel_args: preset-vaapi inputs: - path: /media/frigate/person-bicycle-car-detection.mp4 input_args: -re -stream_loop -1 -fflags +genpts From 6dcc29afa7b5697741bd1fc8d3bf404730eef43a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 12:43:15 -0400 Subject: [PATCH 6118/6505] Update frigate-install.sh Fix logs --- install/frigate-install.sh | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 9170e5f5..aba91e05 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -97,9 +97,6 @@ cameras: fps: 5 EOF ln -sf /config/config.yml /opt/frigate/config/config.yml -mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} -touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} -chmod -R 777 /dev/shm sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group msg_ok "Installed Frigate $RELEASE" @@ -145,10 +142,24 @@ sed -i 's/access_log \/dev\/stdout main\;/access_log nginx\.log main\;/' /usr/lo msg_ok "Built Nginx" msg_info "Creating Services" +cat </etc/systemd/system/create_directories.service +[Unit] +Description=Create necessary directories for logs + +[Service] +Type=oneshot +ExecStart=/bin/bash -c '/bin/mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} && /bin/touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} && /bin/chmod -R 777 /dev/shm/logs' + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now create_directories +sleep 3 cat </etc/systemd/system/go2rtc.service [Unit] Description=go2rtc service After=network.target +After=create_directories.service StartLimitIntervalSec=0 [Service] @@ -157,6 +168,8 @@ Restart=always RestartSec=1 User=root ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run +StandardOutput=file:/dev/shm/logs/go2rtc/current +StandardError=file:/dev/shm/logs/go2rtc/current [Install] WantedBy=multi-user.target @@ -167,6 +180,7 @@ cat </etc/systemd/system/frigate.service [Unit] Description=Frigate service After=go2rtc.service +After=create_directories.service StartLimitIntervalSec=0 [Service] @@ -175,6 +189,8 @@ Restart=always RestartSec=1 User=root ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run +StandardOutput=file:/dev/shm/logs/frigate/current +StandardError=file:/dev/shm/logs/frigate/current [Install] WantedBy=multi-user.target @@ -185,6 +201,7 @@ cat </etc/systemd/system/nginx.service [Unit] Description=Nginx service After=frigate.service +After=create_directories.service StartLimitIntervalSec=0 [Service] @@ -193,6 +210,8 @@ Restart=always RestartSec=1 User=root ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run +StandardOutput=file:/dev/shm/logs/nginx/current +StandardError=file:/dev/shm/logs/nginx/current [Install] WantedBy=multi-user.target From ac34991ea7ea9032e6c76236a5333432b28d9913 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 16:01:36 -0400 Subject: [PATCH 6119/6505] Update prowlarr.sh "There is currently no update path available." --- ct/prowlarr.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh index a2a54ad1..610928f8 100644 --- a/ct/prowlarr.sh +++ b/ct/prowlarr.sh @@ -55,10 +55,7 @@ function default_settings() { function update_script() { header_info if [[ ! -d /var/lib/prowlarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP LXC" +msg_error "There is currently no update path available." exit } From 4be1d23dcda39a13aa5025a94aec4627ae3ac2aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 16:37:15 -0400 Subject: [PATCH 6120/6505] Update frigate.sh Add go2rtc port --- ct/frigate.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/frigate.sh b/ct/frigate.sh index 7ac4e1d6..f3483013 100644 --- a/ct/frigate.sh +++ b/ct/frigate.sh @@ -69,3 +69,5 @@ msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5000${CL} \n" +echo -e "go2rtc should be reachable by going to the following URL. + ${BL}http://${IP}:1984${CL} \n" From d01a18dbafe4a909c92f1f0610f9cf51e96685f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 1 Apr 2024 21:24:31 -0400 Subject: [PATCH 6121/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 173aca78..9070bd82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-01 + +### Changed + +- **Frigate LXC** + - NEW Script + ## 2024-03-26 ### Changed From 2e36b903ada6c7ec0b5185e43edaf1e811d3207f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Apr 2024 11:05:06 -0400 Subject: [PATCH 6122/6505] Update install.func slow spinner --- misc/install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index 3deb63d1..578bf0a8 100644 --- a/misc/install.func +++ b/misc/install.func @@ -54,7 +54,7 @@ spinner() { spin_i=0 while true; do printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" - sleep 0.1 + sleep 0.2 done } From 3bcf2cece6474889f149cd09048272f7837a35cc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Apr 2024 02:42:06 -0400 Subject: [PATCH 6123/6505] Update pihole-install.sh tweak --- install/pihole-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/pihole-install.sh b/install/pihole-install.sh index f3c52e90..84649dba 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -93,7 +93,7 @@ EOF cat </etc/dnsmasq.d/99-edns.conf edns-packet-max=1232 EOF - wget -q https://www.internic.net/domain/named.root >/var/lib/unbound/root.hints + wget -qO /var/lib/unbound/root.hints https://www.internic.net/domain/named.root sed -i -e 's/PIHOLE_DNS_1=8.8.8.8/PIHOLE_DNS_1=127.0.0.1#5335/' -e 's/PIHOLE_DNS_2=8.8.4.4/#PIHOLE_DNS_2=8.8.4.4/' /etc/pihole/setupVars.conf systemctl enable -q --now unbound systemctl restart pihole-FTL.service From 4103d40622b4cf80775381595c9ed4b80f9fdbe3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Apr 2024 03:07:32 -0400 Subject: [PATCH 6124/6505] Update pihole-install.sh add root-hints --- install/pihole-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/pihole-install.sh b/install/pihole-install.sh index 84649dba..52bb0b09 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -73,6 +73,7 @@ server: infra-cache-slabs: 8 key-cache-slabs: 8 serve-expired: yes + root-hints: /var/lib/unbound/root.hints serve-expired-ttl: 3600 edns-buffer-size: 1232 prefetch: yes From b2136739860380d152dfc6eeb5292b43af1e991a Mon Sep 17 00:00:00 2001 From: MountyMapleSyrup <159492850+MountyMapleSyrup@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:12:03 -0400 Subject: [PATCH 6125/6505] Adding a Script for LazyLibrarian (#2723) --- ct/lazylibrarian.sh | 81 ++++++++++++++++++++++++++++++++ install/lazylibrarian-install.sh | 62 ++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 ct/lazylibrarian.sh create mode 100644 install/lazylibrarian-install.sh diff --git a/ct/lazylibrarian.sh b/ct/lazylibrarian.sh new file mode 100644 index 00000000..9f29dc43 --- /dev/null +++ b/ct/lazylibrarian.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MountyMapleSyrup (MountyMapleSyrup) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ _ __ _ + / / ____ _____ __ __/ / (_) /_ _________ ______(_)___ _____ + / / / __ `/_ / / / / / / / / __ \/ ___/ __ `/ ___/ / __ `/ __ \ + / /___/ /_/ / / /_/ /_/ / /___/ / /_/ / / / /_/ / / / / /_/ / / / / +/_____/\__,_/ /___/\__, /_____/_/_.___/_/ \__,_/_/ /_/\__,_/_/ /_/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="LazyLibrarian" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/LazyLibrarian/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping LazyLibrarian" +systemctl stop lazylibrarian +msg_ok "LazyLibrarian Stopped" + +msg_info "Updating $APP LXC" +git -C /opt/LazyLibrarian pull origin master &>/dev/null +msg_ok "Updated $APP LXC" + +msg_info "Starting LazyLibrarian" +systemctl start lazylibrarian +msg_ok "Started LazyLibrarian" + +msg_ok "Updated Successfully" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5299${CL} \n" diff --git a/install/lazylibrarian-install.sh b/install/lazylibrarian-install.sh new file mode 100644 index 00000000..817d63cc --- /dev/null +++ b/install/lazylibrarian-install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MountyMapleSyrup (MountyMapleSyrup) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Installing Python3 Dependencies" +$STD apt-get install -y pip +$STD apt-get install -y python3-irc +$STD pip install jaraco.stream +$STD pip install python-Levenshtein +$STD pip install soupsieve +msg_ok "Installed Python3 Dependencies" + +msg_info "Installing LazyLibrarian" +mkdir -p /opt/LazyLibrarian/ +chmod 775 /opt/LazyLibrarian/ +$STD git clone https://gitlab.com/LazyLibrarian/LazyLibrarian /opt/LazyLibrarian +msg_ok "Installed LazyLibrarian" + +msg_info "Creating Service" +cat </etc/systemd/system/lazylibrarian.service +[Unit] +Description=LazyLibrarian Daemon +After=syslog.target network.target +[Service] +UMask=0002 +Type=simple +ExecStart=/usr/bin/python3 /opt/LazyLibrarian/LazyLibrarian.py +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now -q lazylibrarian +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 306f2f41210ea97aa75e394dd8b572a64e82e355 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Apr 2024 12:43:17 -0400 Subject: [PATCH 6126/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9070bd82..b024a723 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-03 + +### Changed + +- **LazyLibrarian LXC** + - NEW Script + ## 2024-04-01 ### Changed From 3ffdd988f2f389b99524382be90c1f5ca2f424d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Apr 2024 18:01:14 -0400 Subject: [PATCH 6127/6505] Create actualbudget-install.sh --- install/actualbudget-install.sh | 65 +++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 install/actualbudget-install.sh diff --git a/install/actualbudget-install.sh b/install/actualbudget-install.sh new file mode 100644 index 00000000..0f000ed9 --- /dev/null +++ b/install/actualbudget-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +$STD npm install --global yarn +msg_ok "Installed Node.js" + +msg_info "Installing Actual Budget" +$STD git clone https://github.com/actualbudget/actual-server.git /opt/actualbudget +cd /opt/actualbudget +$STD yarn install +msg_ok "Installed Actual Budget" + +msg_info "Creating Service" +cat </etc/systemd/system/actualbudget.service +[Unit] +Description=Actual Budget Service +After=network.target + +[Service] +Type=exec +WorkingDirectory=/opt/actualbudget +ExecStart=/usr/bin/yarn start + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now actualbudget.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From cc7d0920d5e6d7707d6ca7fcf08e7d4e46d7011e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Apr 2024 18:02:35 -0400 Subject: [PATCH 6128/6505] Create actualbudget.sh --- ct/actualbudget.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 ct/actualbudget.sh diff --git a/ct/actualbudget.sh b/ct/actualbudget.sh new file mode 100644 index 00000000..e9fedbf9 --- /dev/null +++ b/ct/actualbudget.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ __ __ ____ __ __ + / | _____/ /___ ______ _/ / / __ )__ ______/ /___ ____ / /_ + / /| |/ ___/ __/ / / / __ `/ / / __ / / / / __ / __ `/ _ \/ __/ + / ___ / /__/ /_/ /_/ / /_/ / / / /_/ / /_/ / /_/ / /_/ / __/ /_ +/_/ |_\___/\__/\__,_/\__,_/_/ /_____/\__,_/\__,_/\__, /\___/\__/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Actual Budget" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/actualbudget ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +systemctl stop actualbudget.service +/opt/actualbudget +git pull +yarn install +systemctl start actualbudget.service +msg_ok "Successfully Updated ${APP}" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5006${CL} \n" From 6f7427ff0e929ef742f477042a880cad83bf5f41 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Apr 2024 18:31:23 -0400 Subject: [PATCH 6129/6505] Update lazylibrarian-install.sh tweak --- install/lazylibrarian-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/lazylibrarian-install.sh b/install/lazylibrarian-install.sh index 817d63cc..98595c26 100644 --- a/install/lazylibrarian-install.sh +++ b/install/lazylibrarian-install.sh @@ -30,8 +30,6 @@ $STD pip install soupsieve msg_ok "Installed Python3 Dependencies" msg_info "Installing LazyLibrarian" -mkdir -p /opt/LazyLibrarian/ -chmod 775 /opt/LazyLibrarian/ $STD git clone https://gitlab.com/LazyLibrarian/LazyLibrarian /opt/LazyLibrarian msg_ok "Installed LazyLibrarian" From 957aaf8fa13e6cc8b1428e30bd9c079d077909ba Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Apr 2024 10:18:49 -0400 Subject: [PATCH 6130/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b024a723..52aefbaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-04 + +### Changed + +- **Actual Budget LXC** + - NEW Script + ## 2024-04-03 ### Changed From 43c369f3d24cb7d9281eb757d50cb48c6661abfd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Apr 2024 13:43:42 -0400 Subject: [PATCH 6131/6505] Create medusa-install.sh --- install/medusa-install.sh | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 install/medusa-install.sh diff --git a/install/medusa-install.sh b/install/medusa-install.sh new file mode 100644 index 00000000..93952a53 --- /dev/null +++ b/install/medusa-install.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +$STD apt-get install -y git-core +$STD apt-get install -y mediainfo +cat </etc/apt/sources.list.d/non-free.list +deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware +EOF +$STD apt-get update +$STD apt-get install -y unrar +rm /etc/apt/sources.list.d/non-free.list +msg_ok "Installed Dependencies" + +msg_info "Installing MiroTalk" +$STD git clone https://github.com/pymedusa/Medusa.git /opt/medusa +msg_ok "Installed MiroTalk" + +msg_info "Creating Service" +cat </etc/systemd/system/medusa.service +[Unit] +Description=Medusa Daemon +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/python3 /opt/medusa/start.py -q --nolaunch --datadir=/opt/medusa +TimeoutStopSec=25 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now medusa.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From e471e0f1627f2dc9da982c836be54cc4a727f139 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Apr 2024 13:44:34 -0400 Subject: [PATCH 6132/6505] Create medusa.sh --- ct/medusa.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 ct/medusa.sh diff --git a/ct/medusa.sh b/ct/medusa.sh new file mode 100644 index 00000000..d617a114 --- /dev/null +++ b/ct/medusa.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ __ + / |/ /__ ____/ /_ ___________ _ + / /|_/ / _ \/ __ / / / / ___/ __ `/ + / / / / __/ /_/ / /_/ (__ ) /_/ / +/_/ /_/\___/\__,_/\__,_/____/\__,_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Medusa" +var_disk="6" +var_cpu="2" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/medusa ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +systemctl stop medusa.service +/opt/medusa +git pull +systemctl start medusa.service +msg_ok "Successfully Updated ${APP}" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8081${CL} \n" From d127e4dfeb172df7d9265d1957511decbce77070 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Apr 2024 13:47:55 -0400 Subject: [PATCH 6133/6505] Update medusa-install.sh tweak --- install/medusa-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/medusa-install.sh b/install/medusa-install.sh index 93952a53..c2152c07 100644 --- a/install/medusa-install.sh +++ b/install/medusa-install.sh @@ -28,9 +28,9 @@ $STD apt-get install -y unrar rm /etc/apt/sources.list.d/non-free.list msg_ok "Installed Dependencies" -msg_info "Installing MiroTalk" +msg_info "Installing Medusa" $STD git clone https://github.com/pymedusa/Medusa.git /opt/medusa -msg_ok "Installed MiroTalk" +msg_ok "Installed Medusa" msg_info "Creating Service" cat </etc/systemd/system/medusa.service From 05c3945097981d22e160fd68cbb5c66759f22e95 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Apr 2024 04:05:47 -0400 Subject: [PATCH 6134/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52aefbaa..8a288a4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-05 + +### Changed + +- **Medusa LXC** + - NEW Script + ## 2024-04-04 ### Changed From f74e5e9a11fbad5813a3c59af80d11cdce7a8e1c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Apr 2024 05:07:46 -0400 Subject: [PATCH 6135/6505] Update nginxproxymanager.sh Maintain compatibility with older versions of Node.js fixes https://github.com/tteck/Proxmox/issues/2733 --- ct/nginxproxymanager.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 16061a18..a65e8623 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -61,6 +61,7 @@ function update_script() { fi if ! command -v pnpm &> /dev/null; then msg_info "Installing pnpm" + export NODE_OPTIONS=--openssl-legacy-provider npm install -g pnpm@8.15 &>/dev/null msg_ok "Installed pnpm" fi From 463641e544eafb7ab318768042415d15e8ab1b1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Apr 2024 06:43:16 -0400 Subject: [PATCH 6136/6505] Create watchyourlan-install.sh --- install/watchyourlan-install.sh | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 install/watchyourlan-install.sh diff --git a/install/watchyourlan-install.sh b/install/watchyourlan-install.sh new file mode 100644 index 00000000..78fcf57a --- /dev/null +++ b/install/watchyourlan-install.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y {curl,sudo,mc,gpg,arp-scan,ieee-data,libwww-perl} +msg_ok "Installed Dependencies" + +msg_info "Installing WatchYourLAN" +RELEASE=$(curl -s https://api.github.com/repos/aceberg/WatchYourLAN/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) +wget -q https://github.com/aceberg/WatchYourLAN/releases/download/$RELEASE/watchyourlan_${RELEASE}_linux_amd64.deb +$STD dpkg -i watchyourlan_${RELEASE}_linux_amd64.deb +rm watchyourlan_${RELEASE}_linux_amd64.deb +mkdir /data +cat </data/config.yaml +arp_timeout: "500" +auth: false +auth_expire: 7d +auth_password: "" +auth_user: "" +color: dark +dbpath: /data/db.sqlite +guiip: 0.0.0.0 +guiport: "8840" +history_days: "30" +iface: eth0 +ignoreip: "no" +loglevel: verbose +shoutrrr_url: "" +theme: solar +timeout: 60 +EOF +msg_ok "Installed WatchYourLAN" + +msg_info "Creating Service" +sed -i 's|/etc/watchyourlan/config.yaml|/data/config.yaml|' /lib/systemd/system/watchyourlan.service +systemctl enable -q --now watchyourlan.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From 9f184bd9c99e9cc2b9ff26ab6ba80cc91bdea8dc Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Apr 2024 06:44:37 -0400 Subject: [PATCH 6137/6505] Create watchyourlan.sh --- ct/watchyourlan.sh | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 ct/watchyourlan.sh diff --git a/ct/watchyourlan.sh b/ct/watchyourlan.sh new file mode 100644 index 00000000..93eba4d1 --- /dev/null +++ b/ct/watchyourlan.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ __ ____ __ __ ___ _ __ +| | / /___ _/ /______/ /\ \/ /___ __ _______/ / / | / | / / +| | /| / / __ `/ __/ ___/ __ \ / __ \/ / / / ___/ / / /| | / |/ / +| |/ |/ / /_/ / /_/ /__/ / / / / /_/ / /_/ / / / /___/ ___ |/ /| / +|__/|__/\__,_/\__/\___/_/ /_/_/\____/\__,_/_/ /_____/_/ |_/_/ |_/ + +EOF +} +header_info +echo -e "Loading..." +APP="WatchYourLAN" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /lib/systemd/system/watchyourlan.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +systemctl stop watchyourlan.service +cp -R /data/config.yaml config.yaml +RELEASE=$(curl -s https://api.github.com/repos/aceberg/WatchYourLAN/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) +wget -q https://github.com/aceberg/WatchYourLAN/releases/download/$RELEASE/watchyourlan_${RELEASE}_linux_amd64.deb +dpkg -i watchyourlan_${RELEASE}_linux_amd64.deb +cp -R config.yaml /data/config.yaml +sed -i 's|/etc/watchyourlan/config.yaml|/data/config.yaml|' /lib/systemd/system/watchyourlan.service +rm watchyourlan_${RELEASE}_linux_amd64.deb config.yaml +systemctl enable -q --now watchyourlan.service +msg_ok "Updated $APP" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8840${CL} \n" From 466fae49a30cb20f10580e81819ccfac32e6dfb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Apr 2024 08:43:31 -0400 Subject: [PATCH 6138/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index aba91e05..b22fbb9d 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -121,7 +121,7 @@ $STD /bin/bash ../libtool --mode=install /usr/bin/install -c libusb-1.0.la '/us mkdir -p /usr/local/include/libusb-1.0 $STD /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0' ldconfig -cd ~ +cd / wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite cp /opt/frigate/labelmap.txt /labelmap.txt From fe0b379ed1526adccfb5c0f7488eba1a05fce866 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Apr 2024 16:19:04 -0400 Subject: [PATCH 6139/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a288a4c..4f39f106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - **Medusa LXC** - NEW Script +- **WatchYourLAN LXC** + - NEW Script ## 2024-04-04 From 932b69a8c47299048d49cb1167d7726091223008 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 6 Apr 2024 09:05:33 -0400 Subject: [PATCH 6140/6505] Update sabnzbd-install.sh fixes https://github.com/tteck/Proxmox/issues/2739 --- install/sabnzbd-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 00bd1141..b206c82f 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -19,10 +19,12 @@ $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y par2 $STD apt-get install -y p7zip-full -RELEASE=$(curl -s http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/ | grep -oP 'href="\K[^"]*unrar_7\.\d+\.\d+-\d+_amd64\.deb' | head -1) -wget -q http://http.us.debian.org/debian/pool/non-free/u/unrar-nonfree/$RELEASE -$STD dpkg -i unrar*.deb -rm unrar*.deb +cat </etc/apt/sources.list.d/non-free.list +deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware +EOF +$STD apt-get update +$STD apt-get install -y unrar +rm /etc/apt/sources.list.d/non-free.list msg_ok "Installed Dependencies" msg_info "Updating Python3" From 2847d9cc9a121c2eba55cccc93b1413f1a3a652a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Mon, 8 Apr 2024 14:44:02 -0400 Subject: [PATCH 6141/6505] Fix CPU model path in basic config (model now downloaded at root of filesystem) (#2758) --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index b22fbb9d..84b5dcc0 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -80,7 +80,7 @@ cat </config/config.yml mqtt: enabled: false model: - path: /root/cpu_model.tflite + path: /cpu_model.tflite cameras: test: ffmpeg: From 1cded8c053f9f1bb202881b95d714faaa68b6399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Mon, 8 Apr 2024 21:21:08 -0400 Subject: [PATCH 6142/6505] Fix openvino model generation in Frigate install script (#2762) * get pip from APT * Add openvino model conversion to make it readily available --- install/frigate-install.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 84b5dcc0..63830910 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -18,9 +18,7 @@ $STD apt-get install -y {curl,sudo,mc,git,gpg,automake,build-essential,xz-utils, msg_ok "Installed Dependencies" msg_info "Installing Python3 Dependencies" -$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils} -wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py -$STD python3 get-pip.py --quiet "pip" +$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils,python3-pip} msg_ok "Installed Python3 Dependencies" msg_info "Installing Node.js" @@ -104,7 +102,8 @@ msg_info "Installing Object Detection Models (Resilience)" $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt cd /opt/frigate/models export ENABLE_ANALYTICS=NO -$STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 +$STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 --num_attempts 2 +$STD /usr/local/bin/omz_converter --name ssdlite_mobilenet_v2 --precision FP16 --mo /usr/local/bin/mo cd .. export CCACHE_DIR=/root/.ccache export CCACHE_MAXSIZE=2G From 55175f9b315372cf961be494c9125f0bfaacbf0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Mon, 8 Apr 2024 21:41:54 -0400 Subject: [PATCH 6143/6505] Update default config to leverage openvino (#2763) --- install/frigate-install.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 63830910..98141d85 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -77,8 +77,18 @@ sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s cat </config/config.yml mqtt: enabled: false +detectors: + ov: + type: openvino + device: AUTO + model: + path: /openvino-model/FP16/ssdlite_mobilenet_v2.xml model: - path: /cpu_model.tflite + width: 300 + height: 300 + input_tensor: nhwc + input_pixel_format: bgr + labelmap_path: /openvino-model/coco_91cl_bkgr.txt cameras: test: ffmpeg: From 112353334dd384d7bee5cc88bac375bc07e39f4d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 17:22:24 -0400 Subject: [PATCH 6144/6505] Update linkwarden.sh Add `yarn prisma generate` to the update process. --- ct/linkwarden.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index e2bf2fa5..ba109a09 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -66,6 +66,7 @@ fi git pull yarn npx playwright install-deps +yarn prisma generate yarn build yarn prisma migrate deploy systemctl start linkwarden From a6add9a72767f05f5eced7c2fa193fe7f88a30de Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 17:56:35 -0400 Subject: [PATCH 6145/6505] Update linkwarden.sh Tweak `function update_script()` --- ct/linkwarden.sh | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh index ba109a09..e5c0494a 100644 --- a/ct/linkwarden.sh +++ b/ct/linkwarden.sh @@ -55,22 +55,31 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/linkwarden ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP" -systemctl stop linkwarden -cd /opt/linkwarden -if git pull | grep -q 'Already up to date'; then - msg_ok "Already up to date" + +RELEASE=$(curl -s https://api.github.com/repos/linkwarden/linkwarden/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Stopping ${APP}" + systemctl stop linkwarden + msg_ok "Stopped ${APP}" + + msg_info "Updating ${APP} to ${RELEASE}" + cd /opt/linkwarden + git pull + yarn + npx playwright install-deps + yarn prisma generate + yarn build + yarn prisma migrate deploy + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" + + msg_info "Starting ${APP}" systemctl start linkwarden - exit + msg_ok "Started ${APP}" + msg_ok "Updated Successfully" +else + msg_ok "No update required. ${APP} is already at ${RELEASE}." fi -git pull -yarn -npx playwright install-deps -yarn prisma generate -yarn build -yarn prisma migrate deploy -systemctl start linkwarden -msg_ok "Updated $APP" exit } From 1ccb2de7f6d68e2c0f0b3e341c88ee26eb0aef5f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 18:33:28 -0400 Subject: [PATCH 6146/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f39f106..856fed84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-09 + +### Changed + +- **PairDrop LXC** + - Add back to website + ## 2024-04-05 ### Changed From c52eec1a8e607cf5ec4b5b8c3f6fcbad65ac1efe Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 19:35:36 -0400 Subject: [PATCH 6147/6505] Update ombi-install.sh tweak --- install/ombi-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/ombi-install.sh b/install/ombi-install.sh index c5e631e7..f2659917 100644 --- a/install/ombi-install.sh +++ b/install/ombi-install.sh @@ -20,9 +20,9 @@ $STD apt-get install -y mc msg_ok "Installed Dependencies" msg_info "Installing Ombi" -LATEST=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) -# wget -q https://github.com/Ombi-app/Ombi/releases/download/${LATEST}/linux-x64.tar.gz -wget -q https://github.com/Ombi-app/Ombi/releases/download/v4.43.2/linux-x64.tar.gz +RELEASE=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +wget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz +#wget -q https://github.com/Ombi-app/Ombi/releases/download/v4.43.2/linux-x64.tar.gz mkdir -p /opt/ombi tar -xzf linux-x64.tar.gz -C /opt/ombi msg_ok "Installed Ombi" From 98ee62bca03837bfad36a689359a0ea4035514b7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 19:36:46 -0400 Subject: [PATCH 6148/6505] Update ombi.sh Add update path --- ct/ombi.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/ct/ombi.sh b/ct/ombi.sh index 658182dc..27da5680 100644 --- a/ct/ombi.sh +++ b/ct/ombi.sh @@ -55,7 +55,25 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/ombi ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +RELEASE=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Stopping ${APP}" + systemctl stop ombi + msg_ok "Stopped ${APP}" + + msg_info "Updating ${APP} to ${RELEASE}" + wget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz + tar -xzf linux-x64.tar.gz -C /opt/ombi + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" + + msg_info "Starting ${APP}" + systemctl start ombi + msg_ok "Started ${APP}" + msg_ok "Updated Successfully" +else + msg_ok "No update required. ${APP} ia already at ${RELEASE}." +fi exit } From 38bca8fe176476b07594abd39489aa45f69181d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 19:43:59 -0400 Subject: [PATCH 6149/6505] Update ombi-install.sh tweak --- install/ombi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ombi-install.sh b/install/ombi-install.sh index f2659917..624beeda 100644 --- a/install/ombi-install.sh +++ b/install/ombi-install.sh @@ -22,7 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Ombi" RELEASE=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) wget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz -#wget -q https://github.com/Ombi-app/Ombi/releases/download/v4.43.2/linux-x64.tar.gz +echo "${RELEASE}" >/opt/${APP}_version.txt mkdir -p /opt/ombi tar -xzf linux-x64.tar.gz -C /opt/ombi msg_ok "Installed Ombi" From 0e02de596fea6747227dd74612ccaea40f15c972 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 19:49:55 -0400 Subject: [PATCH 6150/6505] Update ombi-install.sh revert --- install/ombi-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ombi-install.sh b/install/ombi-install.sh index 624beeda..9f29d972 100644 --- a/install/ombi-install.sh +++ b/install/ombi-install.sh @@ -22,7 +22,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Ombi" RELEASE=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) wget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz -echo "${RELEASE}" >/opt/${APP}_version.txt +#echo "${RELEASE}" >/opt/${app}_version.txt mkdir -p /opt/ombi tar -xzf linux-x64.tar.gz -C /opt/ombi msg_ok "Installed Ombi" From ba68b641de1f1c0e5a742537e7f85b40a1d3424a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 20:18:26 -0400 Subject: [PATCH 6151/6505] Update ombi-install.sh tweak --- install/ombi-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/ombi-install.sh b/install/ombi-install.sh index 9f29d972..ff313504 100644 --- a/install/ombi-install.sh +++ b/install/ombi-install.sh @@ -22,9 +22,10 @@ msg_ok "Installed Dependencies" msg_info "Installing Ombi" RELEASE=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '"tag_name":' | cut -d'"' -f4) wget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz -#echo "${RELEASE}" >/opt/${app}_version.txt +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt mkdir -p /opt/ombi tar -xzf linux-x64.tar.gz -C /opt/ombi +rm -rf linux-x64.tar.gz msg_ok "Installed Ombi" msg_info "Creating Service" From f77d5f01fb32fef64654837e870d9796fc4afe3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 20:21:39 -0400 Subject: [PATCH 6152/6505] Update ombi.sh Remove `.tar.gz` --- ct/ombi.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/ombi.sh b/ct/ombi.sh index 27da5680..4e53aa6b 100644 --- a/ct/ombi.sh +++ b/ct/ombi.sh @@ -64,6 +64,7 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP} msg_info "Updating ${APP} to ${RELEASE}" wget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz tar -xzf linux-x64.tar.gz -C /opt/ombi + rm -rf linux-x64.tar.gz echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated ${APP} to ${RELEASE}" From 594dc7e19ca081d6ea3a309dd303dcb6659572df Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 9 Apr 2024 20:27:12 -0400 Subject: [PATCH 6153/6505] Update linkwarden-install.sh tweak --- install/linkwarden-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh index 6ad52ab0..c01c289f 100644 --- a/install/linkwarden-install.sh +++ b/install/linkwarden-install.sh @@ -70,6 +70,8 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then fi msg_info "Installing Linkwarden (Patience)" +RELEASE=$(curl -s https://api.github.com/repos/linkwarden/linkwarden/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt $STD yarn $STD npx playwright install-deps IP=$(hostname -I | awk '{print $1}') From a9742f18cdd098dad51c225235af3d9d816c8945 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Apr 2024 06:56:56 -0400 Subject: [PATCH 6154/6505] Update heimdalldashboard.sh tweak update function --- ct/heimdalldashboard.sh | 79 +++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index bdc4889c..d79ac706 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -55,49 +55,50 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/Heimdall ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Stopping ${APP}" -systemctl stop heimdall -sleep 1 -msg_ok "Stopped ${APP}" - -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" - RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') -msg_info "Updating Heimdall Dashboard to ${RELEASE}" -wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz -tar xzf ${RELEASE}.tar.gz -VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -cp -R Heimdall-${VER}/* /opt/Heimdall -cd /opt/Heimdall -apt-get install -y composer &>/dev/null -COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null -msg_ok "Updated Heimdall Dashboard to ${RELEASE}" +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Stopping ${APP}" + systemctl stop heimdall + sleep 1 + msg_ok "Stopped ${APP}" -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 "Backing up Data" + cp -R /opt/Heimdall/database database-backup + cp -R /opt/Heimdall/public public-backup + sleep 1 + msg_ok "Backed up Data" -msg_info "Cleanup" -rm -rf ${RELEASE}.tar.gz -rm -rf Heimdall-${VER} -rm -rf public-backup -rm -rf database-backup -rm -rf Heimdall -sleep 1 -msg_ok "Cleaned" + msg_info "Updating Heimdall Dashboard to ${RELEASE}" + echo "${RELEASE}" >/opt/${APP}_version.txt + wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz + tar xzf ${RELEASE}.tar.gz + VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + cp -R Heimdall-${VER}/* /opt/Heimdall + cd /opt/Heimdall + apt-get install -y composer &>/dev/null + COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null + msg_ok "Updated Heimdall Dashboard to ${RELEASE}" -msg_info "Starting ${APP}" -systemctl start heimdall.service -sleep 2 -msg_ok "Started ${APP}" -msg_ok "Updated Successfully" + 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 "Cleanup" + rm -rf {${RELEASE}.tar.gz,Heimdall-${VER},public-backup,database-backup,Heimdall} + sleep 1 + msg_ok "Cleaned" + + msg_info "Starting ${APP}" + systemctl start heimdall.service + sleep 2 + msg_ok "Started ${APP}" + msg_ok "Updated Successfully" +else + msg_ok "No update required. ${APP} ia already at ${RELEASE}." +fi exit } From a6e5eefb3450c2cae57203af97e2de0c8f022bd8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Apr 2024 07:00:25 -0400 Subject: [PATCH 6155/6505] Update heimdalldashboard.sh tweak --- ct/heimdalldashboard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/heimdalldashboard.sh b/ct/heimdalldashboard.sh index d79ac706..338251c0 100644 --- a/ct/heimdalldashboard.sh +++ b/ct/heimdalldashboard.sh @@ -18,7 +18,7 @@ EOF } header_info echo -e "Loading..." -APP="Heimdall Dashboard" +APP="Heimdall-Dashboard" var_disk="2" var_cpu="1" var_ram="512" From 9c0f6b6a0c8fa1ae8f178633857790727feb4ddc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Apr 2024 07:07:48 -0400 Subject: [PATCH 6156/6505] Update and rename heimdalldashboard-install.sh to heimdall-dashboard-install.sh --- ...eimdalldashboard-install.sh => heimdall-dashboard-install.sh} | 1 + 1 file changed, 1 insertion(+) rename install/{heimdalldashboard-install.sh => heimdall-dashboard-install.sh} (97%) diff --git a/install/heimdalldashboard-install.sh b/install/heimdall-dashboard-install.sh similarity index 97% rename from install/heimdalldashboard-install.sh rename to install/heimdall-dashboard-install.sh index 644e0c57..a7d87559 100644 --- a/install/heimdalldashboard-install.sh +++ b/install/heimdall-dashboard-install.sh @@ -23,6 +23,7 @@ $STD apt-get install -y php8.2-{bz2,curl,sqlite3,zip,xml} msg_ok "Installed Dependencies" RELEASE=$(curl -sX GET "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]') +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_info "Installing Heimdall Dashboard ${RELEASE}" wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz tar xzf ${RELEASE}.tar.gz From 2ef0f9f5c6d984cd2dd1e1341bde0ef319c346f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Apr 2024 07:13:55 -0400 Subject: [PATCH 6157/6505] Rename heimdalldashboard.sh to heimdall-dashboard.sh --- ct/{heimdalldashboard.sh => heimdall-dashboard.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ct/{heimdalldashboard.sh => heimdall-dashboard.sh} (100%) diff --git a/ct/heimdalldashboard.sh b/ct/heimdall-dashboard.sh similarity index 100% rename from ct/heimdalldashboard.sh rename to ct/heimdall-dashboard.sh From a38c9f84e09fe72d17e8b37dabe992fd440a5ae1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Apr 2024 07:20:01 -0400 Subject: [PATCH 6158/6505] Update heimdall-dashboard.sh fix fat finger --- ct/heimdall-dashboard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/heimdall-dashboard.sh b/ct/heimdall-dashboard.sh index 338251c0..68843941 100644 --- a/ct/heimdall-dashboard.sh +++ b/ct/heimdall-dashboard.sh @@ -97,7 +97,7 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP} msg_ok "Started ${APP}" msg_ok "Updated Successfully" else - msg_ok "No update required. ${APP} ia already at ${RELEASE}." + msg_ok "No update required. ${APP} is already at ${RELEASE}." fi exit } From de9beedd52d30e84841bdd437e736abffc794911 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Apr 2024 07:34:23 -0400 Subject: [PATCH 6159/6505] Update heimdall-dashboard.sh tweak --- ct/heimdall-dashboard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/heimdall-dashboard.sh b/ct/heimdall-dashboard.sh index 68843941..04db1ea7 100644 --- a/ct/heimdall-dashboard.sh +++ b/ct/heimdall-dashboard.sh @@ -69,7 +69,6 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP} msg_ok "Backed up Data" msg_info "Updating Heimdall Dashboard to ${RELEASE}" - echo "${RELEASE}" >/opt/${APP}_version.txt wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz tar xzf ${RELEASE}.tar.gz VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') @@ -77,6 +76,7 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP} cd /opt/Heimdall apt-get install -y composer &>/dev/null COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null + echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated Heimdall Dashboard to ${RELEASE}" msg_info "Restoring Data" From 4fecdcaa6a438bf024701a0f1773e31104922475 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 10 Apr 2024 20:02:02 -0400 Subject: [PATCH 6160/6505] Update filebrowser.sh add `curl` --- misc/filebrowser.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/filebrowser.sh b/misc/filebrowser.sh index f15d0537..c4cc0e8d 100644 --- a/misc/filebrowser.sh +++ b/misc/filebrowser.sh @@ -65,6 +65,7 @@ function msg_ok() { read -r -p "Would you like to use No Authentication? " prompt msg_info "Installing ${APP}" +apt-get install -y curl &>/dev/null RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null From 9c19734b5b3e0910bc2fa3dc60867251003b58bd Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Apr 2024 14:43:56 -0400 Subject: [PATCH 6161/6505] Update actualbudget.sh Increase build resources for weak CPUs --- ct/actualbudget.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ct/actualbudget.sh b/ct/actualbudget.sh index e9fedbf9..20ee5cdc 100644 --- a/ct/actualbudget.sh +++ b/ct/actualbudget.sh @@ -20,8 +20,8 @@ header_info echo -e "Loading..." APP="Actual Budget" var_disk="4" -var_cpu="1" -var_ram="1024" +var_cpu="2" +var_ram="2048" var_os="debian" var_version="12" variables @@ -68,7 +68,10 @@ exit start build_container description - +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 1024 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5006${CL} \n" From 42bd22d96d3d164373db62948e8f855ecea1fc5a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 11 Apr 2024 19:14:56 -0400 Subject: [PATCH 6162/6505] Update pimox-haos-vm.sh fix `function PVE_CHECK()` --- vm/pimox-haos-vm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index fb0bfb31..3810f14c 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -84,9 +84,8 @@ else exit fi function PVE_CHECK() { - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/7.[0-4]"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." sleep 2 exit From 170066a73bde55f1e8ec7e48bb826f769cd7038a Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Apr 2024 06:30:20 -0400 Subject: [PATCH 6163/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 856fed84..eb93dad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-12 + +### Changed + +- **OpenMediaVault LXC** + - Removed from website + ## 2024-04-09 ### Changed From f956428321918506ea213c28dbb67baf6e88c4fa Mon Sep 17 00:00:00 2001 From: Ryan Freeman Date: Fri, 12 Apr 2024 17:13:39 +0100 Subject: [PATCH 6164/6505] Update pihole.sh to update PiHole service (#2781) Add pihole update functionality --- ct/pihole.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ct/pihole.sh b/ct/pihole.sh index 57c5e9c0..a9f23124 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -55,11 +55,12 @@ function default_settings() { function update_script() { header_info if [[ ! -d /etc/pihole ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated Successfully" +msg_info "Updating ${APP}" +set +e +pihole -up +msg_ok "Updated ${APP}" exit +fi } start From f984003ea8d53df515e57ac9cc0eca3e85d7dbef Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Apr 2024 17:04:27 -0400 Subject: [PATCH 6165/6505] Update pihole.sh Fixes https://github.com/tteck/Proxmox/issues/2783 --- ct/pihole.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/pihole.sh b/ct/pihole.sh index a9f23124..bd66c313 100644 --- a/ct/pihole.sh +++ b/ct/pihole.sh @@ -60,7 +60,6 @@ set +e pihole -up msg_ok "Updated ${APP}" exit -fi } start From 02efa7c07a807af0f57215ef2eb09efad9ae4333 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 Apr 2024 23:53:22 -0400 Subject: [PATCH 6166/6505] Update homarr-install.sh fix install --- install/homarr-install.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 0a7db8fa..2eb0ab4e 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -36,13 +36,15 @@ $STD npm install -g yarn msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" -mkdir -p /opt/homarr -RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -q -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | $STD tar -xz -C /opt && mv /opt/homarr-${RELEASE}/* /opt/homarr -rm -rf /opt/homarr-${RELEASE} +$STD git clone -b dev https://github.com/ajnart/homarr.git /opt/homarr +cat </opt/homarr/.env +DATABASE_URL="file:./database/db.sqlite" +NEXTAUTH_URL="http://localhost:3000" +NEXTAUTH_SECRET="$(openssl rand -base64 32)" +NEXT_PUBLIC_DISABLE_ANALYTICS="true" +DEFAULT_COLOR_SCHEME="dark" +EOF cd /opt/homarr -wget -q -O /opt/homarr/.env https://raw.githubusercontent.com/ajnart/homarr/dev/.env.example -sed -i 's|NEXTAUTH_SECRET="[^"]*"|NEXTAUTH_SECRET="'"$(openssl rand -base64 32)"'"|' /opt/homarr/.env $STD yarn install $STD yarn build $STD yarn db:migrate From 9f8c93a41627ad6b3fc546559e0f70c848fb95e2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 14 Apr 2024 23:53:59 -0400 Subject: [PATCH 6167/6505] Update homarr.sh modify `function update_script()` --- ct/homarr.sh | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/ct/homarr.sh b/ct/homarr.sh index a81bad4f..a42089f9 100644 --- a/ct/homarr.sh +++ b/ct/homarr.sh @@ -57,19 +57,15 @@ header_info if [[ ! -d /opt/homarr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating $APP (Patience)" systemctl stop homarr -rm -rf /root/data-homarr-backup -rm -rf /root/database-homarr-backup -cp -R /opt/homarr/data /root/data-homarr-backup -cp -R /opt/homarr/database /root/database-homarr-backup -RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -wget -q -O- https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.tar.gz | tar -xz -C /opt -cp -R /opt/homarr-${RELEASE}/* /opt/homarr -cp -R /root/data-homarr-backup/* /opt/homarr/data -cp -R /root/database-homarr-backup/* /opt/homarr/database -rm -rf /opt/homarr-${RELEASE} cd /opt/homarr -yarn install &>/dev/null -yarn build &>/dev/null +if ! git pull; then + echo "Already up to date." + systemctl start homarr + echo "No update required." + exit +fi +yarn install +yarn build systemctl start homarr msg_ok "Updated $APP" exit From 42a256ca0eb62d85ec1bb9e33f7e70a0800a1886 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 00:03:10 -0400 Subject: [PATCH 6168/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb93dad0..f94d0f1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,13 @@ ### Changed +- **Homarr LXC** + - Add back to website + +## 2024-04-12 + +### Changed + - **OpenMediaVault LXC** - Removed from website From a256d4f9b608ea9a719bfe5f5a1a08b95dd19cb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 00:33:25 -0400 Subject: [PATCH 6169/6505] Update umbrel-install.sh tweak --- install/umbrel-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/umbrel-install.sh b/install/umbrel-install.sh index 7ad1d5af..f0411f49 100644 --- a/install/umbrel-install.sh +++ b/install/umbrel-install.sh @@ -32,6 +32,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +#$STD apt-get autoremove +#$STD apt-get autoclean msg_ok "Cleaned" From 95573a728547eef48773032774e3831b4521d32e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 00:49:15 -0400 Subject: [PATCH 6170/6505] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f94d0f1f..51c26620 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,14 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** -## 2024-04-12 +## 2024-04-15 ### Changed - **Homarr LXC** - Add back to website +- **Umbrel LXC** + - Add back to website ## 2024-04-12 From 4efb41620cf48224b91ae31b2eaf61c4be517353 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 01:01:45 -0400 Subject: [PATCH 6171/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51c26620..922ba2fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ - Add back to website - **Umbrel LXC** - Add back to website +- **OpenMediaVault LXC** + - Add back to website ## 2024-04-12 From edbaa1fbdc28d32662f5c5e6a895905bca1dd45b Mon Sep 17 00:00:00 2001 From: Ryan Freeman Date: Mon, 15 Apr 2024 13:27:12 +0100 Subject: [PATCH 6172/6505] iVentoy - updated (#2790) * Create iventoy.sh * Create iventoy-install.sh --- ct/iventoy.sh | 85 ++++++++++++++++++++++++++++++++++++++ install/iventoy-install.sh | 60 +++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 ct/iventoy.sh create mode 100644 install/iventoy-install.sh diff --git a/ct/iventoy.sh b/ct/iventoy.sh new file mode 100644 index 00000000..54e3dc6d --- /dev/null +++ b/ct/iventoy.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ _ __ __ + (_) | / /__ ____ / /_____ __ __ + / /| | / / _ \/ __ \/ __/ __ \/ / / / + / / | |/ / __/ / / / /_/ /_/ / /_/ / +/_/ |___/\___/_/ /_/\__/\____/\__, / + /____/ + +EOF +} +header_info +echo -e "Loading..." +APP="iVentoy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/iventoy ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ${APP} LXC" +systemctl stop iventoy.service +msg_ok "Stopped ${APP} LXC" + +msg_info "Updating ${APP} LXC" +rm -rf /opt/iventoy +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +wget -q $(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep download | grep linux-free | cut -d\" -f4) +tar -C /opt/iventoy -xzf iventoy*.tar.gz +rm -rf iventoy*.tar.gz +msg_ok "Updated ${APP} LXC" + +msg_info "Starting ${APP} LXC" +systemctl start iventoy.service +msg_ok "Started ${APP} LXC" +msg_ok "Updated Successfully" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:26000/ ${CL} \n" diff --git a/install/iventoy-install.sh b/install/iventoy-install.sh new file mode 100644 index 00000000..791438e5 --- /dev/null +++ b/install/iventoy-install.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing iVentoy" +mkdir -p /opt/iventoy/ + +wget -q $(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep download | grep linux-free | cut -d\" -f4) +tar -C /opt/iventoy -xzf iventoy*.tar.gz +rm -rf iventoy*.tar.gz + +msg_ok "Installed iVentoy" + +msg_info "Creating Service" +service_path="/etc/systemd/system/iventoy.service" +echo "# /etc/systemd/system/iventoy.service +[Unit] +Description=iVentoy PXE Booter +Documentation=https://www.iventoy.com +Wants=network-online.target + +[Service] +Type=forking +Environment=IVENTOY_API_ALL=1 +Environment=IVENTOY_AUTO_RUN=1 +Environment=LIBRARY_PATH=/opt/iventoy/lib/lin64 +Environment=LD_LIBRARY_PATH=/opt/iventoy/lib/lin64 +ExecStart=sh ./iventoy.sh -R start +WorkingDirectory=/opt/iventoy +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q iventoy.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From dbe21ab5396ecdba8776cb4cd6334687aa45ab62 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 08:35:06 -0400 Subject: [PATCH 6173/6505] Update iventoy-install.sh tweak --- install/iventoy-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/iventoy-install.sh b/install/iventoy-install.sh index 791438e5..6c48ab46 100644 --- a/install/iventoy-install.sh +++ b/install/iventoy-install.sh @@ -29,8 +29,7 @@ rm -rf iventoy*.tar.gz msg_ok "Installed iVentoy" msg_info "Creating Service" -service_path="/etc/systemd/system/iventoy.service" -echo "# /etc/systemd/system/iventoy.service +cat </etc/systemd/system/iventoy.service [Unit] Description=iVentoy PXE Booter Documentation=https://www.iventoy.com @@ -47,8 +46,9 @@ WorkingDirectory=/opt/iventoy Restart=on-failure [Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q iventoy.service +WantedBy=multi-user.target +EOF +systemctl enable -q --now iventoy.service msg_ok "Created Service" motd_ssh From 6d296e0fdf655ea950faca8bb553386d2b0a23f3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 08:55:40 -0400 Subject: [PATCH 6174/6505] Update iventoy-install.sh tweak --- install/iventoy-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/iventoy-install.sh b/install/iventoy-install.sh index 6c48ab46..d5534e59 100644 --- a/install/iventoy-install.sh +++ b/install/iventoy-install.sh @@ -21,11 +21,10 @@ msg_ok "Installed Dependencies" msg_info "Installing iVentoy" mkdir -p /opt/iventoy/ - wget -q $(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep download | grep linux-free | cut -d\" -f4) -tar -C /opt/iventoy -xzf iventoy*.tar.gz +tar -xzf iventoy*.tar.gz +mv iventoy-* /opt/iventoy rm -rf iventoy*.tar.gz - msg_ok "Installed iVentoy" msg_info "Creating Service" From 22d755d66f25170bb5f6c1d428cf2ccdecc5eebb Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 09:00:29 -0400 Subject: [PATCH 6175/6505] Delete install/iventoy-install.sh non-functional --- install/iventoy-install.sh | 59 -------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 install/iventoy-install.sh diff --git a/install/iventoy-install.sh b/install/iventoy-install.sh deleted file mode 100644 index d5534e59..00000000 --- a/install/iventoy-install.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2024 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -msg_ok "Installed Dependencies" - -msg_info "Installing iVentoy" -mkdir -p /opt/iventoy/ -wget -q $(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep download | grep linux-free | cut -d\" -f4) -tar -xzf iventoy*.tar.gz -mv iventoy-* /opt/iventoy -rm -rf iventoy*.tar.gz -msg_ok "Installed iVentoy" - -msg_info "Creating Service" -cat </etc/systemd/system/iventoy.service -[Unit] -Description=iVentoy PXE Booter -Documentation=https://www.iventoy.com -Wants=network-online.target - -[Service] -Type=forking -Environment=IVENTOY_API_ALL=1 -Environment=IVENTOY_AUTO_RUN=1 -Environment=LIBRARY_PATH=/opt/iventoy/lib/lin64 -Environment=LD_LIBRARY_PATH=/opt/iventoy/lib/lin64 -ExecStart=sh ./iventoy.sh -R start -WorkingDirectory=/opt/iventoy -Restart=on-failure - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now iventoy.service -msg_ok "Created Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" From 9fc3901444fbbd3f7f1145568127ec9df539f58e Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 15 Apr 2024 09:00:55 -0400 Subject: [PATCH 6176/6505] Delete ct/iventoy.sh non-functional --- ct/iventoy.sh | 85 --------------------------------------------------- 1 file changed, 85 deletions(-) delete mode 100644 ct/iventoy.sh diff --git a/ct/iventoy.sh b/ct/iventoy.sh deleted file mode 100644 index 54e3dc6d..00000000 --- a/ct/iventoy.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2024 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - _ _ __ __ - (_) | / /__ ____ / /_____ __ __ - / /| | / / _ \/ __ \/ __/ __ \/ / / / - / / | |/ / __/ / / / /_/ /_/ / /_/ / -/_/ |___/\___/_/ /_/\__/\____/\__, / - /____/ - -EOF -} -header_info -echo -e "Loading..." -APP="iVentoy" -var_disk="2" -var_cpu="1" -var_ram="512" -var_os="debian" -var_version="12" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET="dhcp" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { -header_info -if [[ ! -d /opt/iventoy ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Stopping ${APP} LXC" -systemctl stop iventoy.service -msg_ok "Stopped ${APP} LXC" - -msg_info "Updating ${APP} LXC" -rm -rf /opt/iventoy -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -wget -q $(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep download | grep linux-free | cut -d\" -f4) -tar -C /opt/iventoy -xzf iventoy*.tar.gz -rm -rf iventoy*.tar.gz -msg_ok "Updated ${APP} LXC" - -msg_info "Starting ${APP} LXC" -systemctl start iventoy.service -msg_ok "Started ${APP} LXC" -msg_ok "Updated Successfully" -exit -} - -start -build_container -description - -msg_ok "Completed Successfully!\n" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:26000/ ${CL} \n" From 9cfad87e3ba0ba91f6fc324d202af81a42ac76ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Mon, 15 Apr 2024 12:47:22 -0400 Subject: [PATCH 6177/6505] Mount frigate video cache into memory to avoid hard drive overheating and overuse (#2795) --- install/frigate-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 98141d85..85b07c87 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -106,6 +106,7 @@ cameras: EOF ln -sf /config/config.yml /opt/frigate/config/config.yml sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group +echo "tmpfs /tmp/cache tmpfs defaults 0 0" >> /etc/fstab msg_ok "Installed Frigate $RELEASE" msg_info "Installing Object Detection Models (Resilience)" From 049a8096d339bec4fdedcb9c84b6d40aae91ea90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Tue, 16 Apr 2024 05:39:00 -0400 Subject: [PATCH 6178/6505] Check CPU AVX instruction support before installing OpenVino model (#2796) --- install/frigate-install.sh | 53 ++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 85b07c87..fef31f83 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -77,18 +77,6 @@ sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s cat </config/config.yml mqtt: enabled: false -detectors: - ov: - type: openvino - device: AUTO - model: - path: /openvino-model/FP16/ssdlite_mobilenet_v2.xml -model: - width: 300 - height: 300 - input_tensor: nhwc - input_pixel_format: bgr - labelmap_path: /openvino-model/coco_91cl_bkgr.txt cameras: test: ffmpeg: @@ -109,13 +97,38 @@ sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/ echo "tmpfs /tmp/cache tmpfs defaults 0 0" >> /etc/fstab msg_ok "Installed Frigate $RELEASE" -msg_info "Installing Object Detection Models (Resilience)" -$STD pip install -r /opt/frigate/docker/main/requirements-ov.txt -cd /opt/frigate/models -export ENABLE_ANALYTICS=NO -$STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 --num_attempts 2 -$STD /usr/local/bin/omz_converter --name ssdlite_mobilenet_v2 --precision FP16 --mo /usr/local/bin/mo -cd .. +if grep -q -o -m1 'avx[^ ]*' /proc/cpuinfo; then + echo -e "AVX support detected" + msg_info "Installing Openvino Object Detection Model (Resilience)" + $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt + cd /opt/frigate/models + export ENABLE_ANALYTICS=NO + $STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 --num_attempts 2 + $STD /usr/local/bin/omz_converter --name ssdlite_mobilenet_v2 --precision FP16 --mo /usr/local/bin/mo + cat <>/config/config.yml +detectors: + ov: + type: openvino + device: AUTO + model: + path: /openvino-model/FP16/ssdlite_mobilenet_v2.xml +model: + width: 300 + height: 300 + input_tensor: nhwc + input_pixel_format: bgr + labelmap_path: /openvino-model/coco_91cl_bkgr.txt +EOF + msg_ok "Installed Openvino Object Detection Model (Resilience)" +else + cat <>/config/config.yml +model: + path: /cpu_model.tflite +EOF +fi + +msg_info "Installing Coral Object Detection Model (Resilience)" +cd /opt/frigate export CCACHE_DIR=/root/.ccache export CCACHE_MAXSIZE=2G wget -q https://github.com/libusb/libusb/archive/v1.0.26.zip @@ -142,7 +155,7 @@ wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/class cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt mkdir -p /media/frigate wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 -msg_ok "Installed Object Detection Models" +msg_ok "Installed Coral Object Detection Model" msg_info "Building Nginx with Custom Modules" $STD /opt/frigate/docker/main/build_nginx.sh From b6b1e8db4afe55ba91606f477dde2526964c7eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Tue, 16 Apr 2024 16:09:11 -0400 Subject: [PATCH 6179/6505] Move the remaining openvino commands in the AVX conditional block (copy the model and labels in the appropriate folder) (#2801) --- install/frigate-install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index fef31f83..500320a9 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -105,6 +105,10 @@ if grep -q -o -m1 'avx[^ ]*' /proc/cpuinfo; then export ENABLE_ANALYTICS=NO $STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 --num_attempts 2 $STD /usr/local/bin/omz_converter --name ssdlite_mobilenet_v2 --precision FP16 --mo /usr/local/bin/mo + cd / + cp -r /opt/frigate/models/public/ssdlite_mobilenet_v2 openvino-model + wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt -O openvino-model/coco_91cl_bkgr.txt + sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt cat <>/config/config.yml detectors: ov: @@ -148,9 +152,6 @@ cd / wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite cp /opt/frigate/labelmap.txt /labelmap.txt -cp -r /opt/frigate/models/public/ssdlite_mobilenet_v2 openvino-model -wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt -O openvino-model/coco_91cl_bkgr.txt -sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt mkdir -p /media/frigate From 77c92e0102fc110fdb0ce4826903df5506c1fe9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Apr 2024 23:39:56 -0400 Subject: [PATCH 6180/6505] Update hw-acceleration.sh tweak --- misc/hw-acceleration.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 24d2e2de..7b61a0a1 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -4,6 +4,8 @@ # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE +# Execute within the Proxmox shell +# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hw-acceleration.sh)" set -e function header_info { @@ -39,9 +41,9 @@ function msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -if ! pveversion | grep -Eq "pve-manager/(8\.[0-9])"; then +if ! pveversion | grep -Eq "pve-manager/(8\.[1-3])"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE Version 8.0 or higher" + echo -e "Requires PVE Version 8.1 or higher" echo -e "Exiting..." sleep 2 exit @@ -83,11 +85,11 @@ lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF -read -r -p "Do you need the intel-media-va-driver-non-free driver (Sources change)? " prompt +read -r -p "Do you need the intel-media-va-driver-non-free driver (Non-free Sources Added)? " prompt if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then header_info msg_info "Installing Hardware Acceleration (non-free)" - pct exec ${privileged_container} -- bash -c "cat </etc/apt/sources.list + pct exec ${privileged_container} -- bash -c "cat </etc/apt/sources.list.d/non-free.list deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware deb-src http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware @@ -99,7 +101,7 @@ deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware EOF" - pct exec ${privileged_container} -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get update && $STD apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render" + pct exec ${privileged_container} -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get update && $STD apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render" msg_ok "Installed Hardware Acceleration (non-free)" else header_info From 07a3a8aa79d532b3b48055b148ac000bf22124d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Apr 2024 00:00:49 -0400 Subject: [PATCH 6181/6505] Update hw-acceleration.sh tweak --- misc/hw-acceleration.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/hw-acceleration.sh b/misc/hw-acceleration.sh index 7b61a0a1..19a0b140 100644 --- a/misc/hw-acceleration.sh +++ b/misc/hw-acceleration.sh @@ -85,7 +85,7 @@ lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF -read -r -p "Do you need the intel-media-va-driver-non-free driver (Non-free Sources Added)? " prompt +read -r -p "Do you need the intel-media-va-driver-non-free driver (Debian 12 only)? " prompt if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then header_info msg_info "Installing Hardware Acceleration (non-free)" From 00f661c9f54d0539694ad824998120419601656b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Wed, 17 Apr 2024 13:21:26 -0400 Subject: [PATCH 6182/6505] [Frigate] Update Nginx config to output access and error logs to the service log file (/dev/shm) (#2808) --- install/frigate-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 500320a9..f8a4aa62 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -161,8 +161,8 @@ msg_ok "Installed Coral Object Detection Model" msg_info "Building Nginx with Custom Modules" $STD /opt/frigate/docker/main/build_nginx.sh sed -i 's/exec nginx/exec \/usr\/local\/nginx\/sbin\/nginx/g' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run -sed -i 's/error_log \/dev\/stdout warn\;/error_log nginx\.err warn\;/' /usr/local/nginx/conf/nginx.conf -sed -i 's/access_log \/dev\/stdout main\;/access_log nginx\.log main\;/' /usr/local/nginx/conf/nginx.conf +sed -i 's/error_log \/dev\/stdout warn\;/error_log \/dev\/shm\/logs\/nginx\/current warn\;/' /usr/local/nginx/conf/nginx.conf +sed -i 's/access_log \/dev\/stdout main\;/access_log \/dev\/shm\/logs\/nginx\/current main\;/' /usr/local/nginx/conf/nginx.conf msg_ok "Built Nginx" msg_info "Creating Services" From 39a1c119402cd8ebff8b5f1cdf9ebf99807257cd Mon Sep 17 00:00:00 2001 From: Marc Cizeron <60599068+marc-cizeron@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:21:36 +0200 Subject: [PATCH 6183/6505] Update actualbudget.sh (#2817) Fix update function --- ct/actualbudget.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/actualbudget.sh b/ct/actualbudget.sh index 20ee5cdc..b4ff4d62 100644 --- a/ct/actualbudget.sh +++ b/ct/actualbudget.sh @@ -57,7 +57,7 @@ header_info if [[ ! -d /opt/actualbudget ]]; then msg_error "No ${APP} Installation Found!"; exit; fi msg_info "Updating ${APP}" systemctl stop actualbudget.service -/opt/actualbudget +cd /opt/actualbudget git pull yarn install systemctl start actualbudget.service From fb4fdab433790bf6a1871fa4f1ab76c5355c16c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Fri, 19 Apr 2024 10:48:10 -0400 Subject: [PATCH 6184/6505] Clear log files upon service restart to avoid misleading log rewrites (#2819) --- install/frigate-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index f8a4aa62..ce3c81a0 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -191,6 +191,7 @@ Type=simple Restart=always RestartSec=1 User=root +ExecStartPre=+rm /dev/shm/logs/go2rtc/current ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run StandardOutput=file:/dev/shm/logs/go2rtc/current StandardError=file:/dev/shm/logs/go2rtc/current @@ -212,6 +213,7 @@ Type=simple Restart=always RestartSec=1 User=root +ExecStartPre=+rm /dev/shm/logs/frigate/current ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run StandardOutput=file:/dev/shm/logs/frigate/current StandardError=file:/dev/shm/logs/frigate/current @@ -233,6 +235,7 @@ Type=simple Restart=always RestartSec=1 User=root +ExecStartPre=+rm /dev/shm/logs/nginx/current ExecStart=bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run StandardOutput=file:/dev/shm/logs/nginx/current StandardError=file:/dev/shm/logs/nginx/current From ff3216aa92749f702ca344e9dd605b34fafc422c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Apr 2024 11:04:50 -0400 Subject: [PATCH 6185/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index ce3c81a0..2d9598f3 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -98,7 +98,7 @@ echo "tmpfs /tmp/cache tmpfs defaults 0 0" >> /etc/fstab msg_ok "Installed Frigate $RELEASE" if grep -q -o -m1 'avx[^ ]*' /proc/cpuinfo; then - echo -e "AVX support detected" + msg_ok "AVX support detected" msg_info "Installing Openvino Object Detection Model (Resilience)" $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt cd /opt/frigate/models From 6f6d83c2617f15a931faaeb831b0867270c5076e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Apr 2024 11:06:40 -0400 Subject: [PATCH 6186/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 2d9598f3..5166413e 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -123,7 +123,7 @@ model: input_pixel_format: bgr labelmap_path: /openvino-model/coco_91cl_bkgr.txt EOF - msg_ok "Installed Openvino Object Detection Model (Resilience)" + msg_ok "Installed Openvino Object Detection Model" else cat <>/config/config.yml model: From 45205da9a621f2166b88a29cd6eb07416e291366 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 19 Apr 2024 11:30:27 -0400 Subject: [PATCH 6187/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 5166413e..383b8370 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -98,7 +98,7 @@ echo "tmpfs /tmp/cache tmpfs defaults 0 0" >> /etc/fstab msg_ok "Installed Frigate $RELEASE" if grep -q -o -m1 'avx[^ ]*' /proc/cpuinfo; then - msg_ok "AVX support detected" + msg_ok "AVX Support Detected" msg_info "Installing Openvino Object Detection Model (Resilience)" $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt cd /opt/frigate/models @@ -131,7 +131,7 @@ model: EOF fi -msg_info "Installing Coral Object Detection Model (Resilience)" +msg_info "Installing Coral Object Detection Model (Patience)" cd /opt/frigate export CCACHE_DIR=/root/.ccache export CCACHE_MAXSIZE=2G From da964fcacc3227ef1f5c84e90cf1ee4c997261c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Sat, 20 Apr 2024 03:17:37 -0400 Subject: [PATCH 6188/6505] Add scripts for Calibre-web (#2812) --- ct/calibre-web.sh | 166 +++++++++++++++++++++++++++++++++ install/calibre-web-install.sh | 64 +++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 ct/calibre-web.sh create mode 100644 install/calibre-web-install.sh diff --git a/ct/calibre-web.sh b/ct/calibre-web.sh new file mode 100644 index 00000000..d4ae2740 --- /dev/null +++ b/ct/calibre-web.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: remz1337 +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ ___ __ __ + / ____/___ _/ (_) /_ ________ _ _____ / /_ + / / / __ `/ / / __ \/ ___/ _ \_____| | /| / / _ \/ __ \ +/ /___/ /_/ / / / /_/ / / / __/_____/ |/ |/ / __/ /_/ / +\____/\__,_/_/_/_.___/_/ \___/ |__/|__/\___/_.___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Calibre-web" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -f /etc/systemd/system/cps.service ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + header_info + msg_info "Updating $APP LXC" + systemctl stop cps + cd /opt/kepubify + rm kepubify-linux-64bit + curl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-64bit &>/dev/null + chmod +x kepubify-linux-64bit + rm /opt/calibre-web/metadata.db + wget https://github.com/janeczku/calibre-web/raw/master/library/metadata.db -P /opt/calibre-web + menu_array=("1" "Enables gdrive as storage backend for your ebooks" OFF \ + "2" "Enables sending emails via a googlemail account without enabling insecure apps" OFF \ + "3" "Enables displaying of additional author infos on the authors page" OFF \ + "4" "Enables login via LDAP server" OFF \ + "5" "Enables login via google or github oauth" OFF \ + "6" "Enables extracting of metadata from epub, fb2, pdf files, and also extraction of covers from cbr, cbz, cbt files" OFF \ + "7" "Enables extracting of metadata from cbr, cbz, cbt files" OFF \ + "8" "Enables syncing with your kobo reader" OFF ) + if [ -f "/opt/calibre-web/options.txt" ]; then + cps_options="$(cat /opt/calibre-web/options.txt)" + IFS=',' read -ra ADDR <<< "$cps_options" + for i in "${ADDR[@]}"; do + if [ $i == "gdrive" ]; then + line=0 + elif [ $i == "gmail" ]; then + line=1 + elif [ $i == "goodreads" ]; then + line=2 + elif [ $i == "ldap" ]; then + line=3 + elif [ $i == "oauth" ]; then + line=4 + elif [ $i == "metadata" ]; then + line=5 + elif [ $i == "comics" ]; then + line=6 + elif [ $i == "kobo" ]; then + line=7 + fi + array_index=$(( 3*line + 2 )) + menu_array[$array_index]=ON + done + fi + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi + CHOICES=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CALIBRE-WEB OPTIONS" --separate-output --checklist "Choose Additional Options" 15 125 8 "${menu_array[@]}" 3>&1 1>&2 2>&3) + spinner & + SPINNER_PID=$! + if [ ! -z "$CHOICES" ]; then + declare -a options + for CHOICE in $CHOICES; do + case "$CHOICE" in + "1") + options+=( gdrive ) + ;; + "2") + options+=( gmail ) + ;; + "3") + options+=( goodreads ) + ;; + "4") + options+=( ldap ) + apt-get install -qqy libldap2-dev libsasl2-dev + ;; + "5") + options+=( oauth ) + ;; + "6") + options+=( metadata ) + ;; + "7") + options+=( comics ) + ;; + "8") + options+=( kobo ) + ;; + *) + echo "Unsupported item $CHOICE!" >&2 + exit 1 + ;; + esac + done + fi + if [ ! -z "$options" ] && [ ${#options[@]} -gt 0 ]; then + cps_options=$(IFS=, ; echo "${options[*]}") + echo $cps_options > /opt/calibre-web/options.txt + pip install --upgrade calibreweb[$cps_options] + else + rm /opt/calibre-web/options.txt 2> /dev/null + pip install --upgrade calibreweb + fi + systemctl start cps + msg_ok "Updated $APP LXC" + exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 512 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8083${CL} \n" diff --git a/install/calibre-web-install.sh b/install/calibre-web-install.sh new file mode 100644 index 00000000..1e2be2f6 --- /dev/null +++ b/install/calibre-web-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: remz1337 +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y python3 python3-pip imagemagick +msg_ok "Installed Dependencies" + +msg_info "Installing calibre-web" +mkdir -p /opt/kepubify +cd /opt/kepubify +curl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-64bit &>/dev/null +chmod +x kepubify-linux-64bit +mkdir -p /opt/calibre-web +$STD wget https://github.com/janeczku/calibre-web/raw/master/library/metadata.db -P /opt/calibre-web +$STD pip install calibreweb +msg_ok "Installed calibre-web" + +msg_info "Creating Service" +service_path="/etc/systemd/system/cps.service" +echo "[Unit] +Description=Calibre-Web Server +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/calibre-web +ExecStart=/usr/local/bin/cps +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path +systemctl enable --now -q cps.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" + +echo -e "Default login for Calibre-web: + user: ${BL}admin${CL} + password: ${BL}admin123${CL}" +echo -e "${YW}Run the update script inside the container to install calibre-web optional dependencies (such as ldap or kobo support).${CL}" \ No newline at end of file From e3b4543ef5e069d1323e1eff8d5aee9c1247b86c Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:18:51 +1000 Subject: [PATCH 6189/6505] Aria2 LXC - Updated (#2826) --- ct/aria2.sh | 74 ++++++++++++++++++++++++++++++ install/aria2-install.sh | 98 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 ct/aria2.sh create mode 100644 install/aria2-install.sh diff --git a/ct/aria2.sh b/ct/aria2.sh new file mode 100644 index 00000000..51f601f9 --- /dev/null +++ b/ct/aria2.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ___ _ ___ + / | _____(_)___ |__ \ + / /| | / ___/ / __ `/_/ / + / ___ |/ / / / /_/ / __/ +/_/ |_/_/ /_/\__,_/____/ + + +EOF +} +header_info +echo -e "Loading..." +APP="Aria2" +var_disk="8" +var_cpu="2" +var_ram="1028" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be accessible via the following IP. + ${BL}http://${IP}:6800${CL}" +echo -e "AriaNG should be reachable by going to the following URL. + ${BL}http://${IP}:6880${CL} \n" diff --git a/install/aria2-install.sh b/install/aria2-install.sh new file mode 100644 index 00000000..e57b9e8a --- /dev/null +++ b/install/aria2-install.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Aria2" +$STD apt-get install -y aria2 +msg_ok "Installed Aria2" + +read -r -p "Would you like to add AriaNG? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Installing AriaNG" + $STD apt-get install -y nginx + systemctl disable -q --now nginx + wget -q "$(curl -s https://api.github.com/repos/mayswind/ariang/releases/latest | grep download | grep AllInOne.zip | cut -d\" -f4)" + $STD unzip AriaNg-*-AllInOne.zip -d /var/www + rm /etc/nginx/sites-enabled/* + cat </etc/nginx/conf.d/ariang.conf +server { + listen 6880 default_server; + listen [::]:6880 default_server; + + server_name _; + + root /var/www; + index index.html; + + location / { + try_files \$uri \$uri/ =404; + } +} +EOF + cp /lib/systemd/system/nginx.service /lib/systemd/system/ariang.service + msg_ok "Installed AriaNG" +fi + +msg_info "Creating Service" +mkdir /root/downloads +rpc_secret=$(openssl rand -base64 8) +echo "rpc-secret: $rpc_secret" >>~/rpc.secret +cat </root/aria2.daemon +dir=/root/downloads +file-allocation=falloc +max-connection-per-server=4 +max-concurrent-downloads=2 +max-overall-download-limit=0 +min-split-size=25M +rpc-allow-origin-all=true +rpc-secret=${rpc_secret} +input-file=/var/tmp/aria2c.session +save-session=/var/tmp/aria2c.session +EOF + +cat </etc/systemd/system/aria2.service +[Unit] +Description=Aria2c download manager +After=network.target + +[Service] +Type=simple +User=root +Group=root +ExecStartPre=/usr/bin/env touch /var/tmp/aria2c.session +ExecStart=/usr/bin/aria2c --console-log-level=warn --enable-rpc --rpc-listen-all --conf-path=/root/aria2.daemon +TimeoutStopSec=20 +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now aria2.service +systemctl enable -q --now ariang +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm AriaNg-*-AllInOne.zip +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" \ No newline at end of file From 337c1c700ab258cad54c6d095de27184ce4e4d9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Apr 2024 03:20:54 -0400 Subject: [PATCH 6190/6505] Update aria2.sh tweak --- ct/aria2.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ct/aria2.sh b/ct/aria2.sh index 51f601f9..c04ecc5d 100644 --- a/ct/aria2.sh +++ b/ct/aria2.sh @@ -8,13 +8,11 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ___ _ ___ + ___ _ ___ / | _____(_)___ |__ \ / /| | / ___/ / __ `/_/ / - / ___ |/ / / / /_/ / __/ -/_/ |_/_/ /_/\__,_/____/ - - + / ___ |/ / / / /_/ / __/ +/_/ |_/_/ /_/\__,_/____/ EOF } header_info @@ -70,5 +68,3 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be accessible via the following IP. ${BL}http://${IP}:6800${CL}" -echo -e "AriaNG should be reachable by going to the following URL. - ${BL}http://${IP}:6880${CL} \n" From 7a72c82ece3a6b21fc630cb615db5d704b123bc2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Apr 2024 03:22:18 -0400 Subject: [PATCH 6191/6505] Update calibre-web.sh tweak --- ct/calibre-web.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/calibre-web.sh b/ct/calibre-web.sh index d4ae2740..6f309f54 100644 --- a/ct/calibre-web.sh +++ b/ct/calibre-web.sh @@ -9,12 +9,12 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ ___ __ __ - / ____/___ _/ (_) /_ ________ _ _____ / /_ + ______ ___ __ __ + / ____/___ _/ (_) /_ ________ _ _____ / /_ / / / __ `/ / / __ \/ ___/ _ \_____| | /| / / _ \/ __ \ / /___/ /_/ / / / /_/ / / / __/_____/ |/ |/ / __/ /_/ / -\____/\__,_/_/_/_.___/_/ \___/ |__/|__/\___/_.___/ - +\____/\__,_/_/_/_.___/_/ \___/ |__/|__/\___/_.___/ + EOF } header_info From b7051d1fc01ff8c4b74b5bf78439a36b6e91c4ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Apr 2024 03:34:32 -0400 Subject: [PATCH 6192/6505] Update calibre-web-install.sh tweak --- install/calibre-web-install.sh | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/install/calibre-web-install.sh b/install/calibre-web-install.sh index 1e2be2f6..834c989f 100644 --- a/install/calibre-web-install.sh +++ b/install/calibre-web-install.sh @@ -18,22 +18,29 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y python3 python3-pip imagemagick +$STD apt-get install -y imagemagick msg_ok "Installed Dependencies" -msg_info "Installing calibre-web" +msg_info "Installing Python Dependencies" +$STD apt-get -y install python3-pip +msg_ok "Installed Python Dependencies" + +msg_info "Installing Kepubify" mkdir -p /opt/kepubify cd /opt/kepubify curl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-64bit &>/dev/null chmod +x kepubify-linux-64bit +msg_ok "Installed Kepubify" + +msg_info "Installing Calibre-Web" mkdir -p /opt/calibre-web $STD wget https://github.com/janeczku/calibre-web/raw/master/library/metadata.db -P /opt/calibre-web $STD pip install calibreweb -msg_ok "Installed calibre-web" +msg_ok "Installed Calibre-Web" msg_info "Creating Service" -service_path="/etc/systemd/system/cps.service" -echo "[Unit] +cat </etc/systemd/system/cps.service +[Unit] Description=Calibre-Web Server After=network.target @@ -46,8 +53,9 @@ KillMode=process Restart=on-failure [Install] -WantedBy=multi-user.target" >$service_path -systemctl enable --now -q cps.service +WantedBy=multi-user.target +EOF +systemctl enable -q --now cps.service msg_ok "Created Service" motd_ssh @@ -57,8 +65,3 @@ msg_info "Cleaning up" $STD apt-get autoremove $STD apt-get autoclean msg_ok "Cleaned" - -echo -e "Default login for Calibre-web: - user: ${BL}admin${CL} - password: ${BL}admin123${CL}" -echo -e "${YW}Run the update script inside the container to install calibre-web optional dependencies (such as ldap or kobo support).${CL}" \ No newline at end of file From 486041a4d0299ab421affc8ef21cce9068f2afb1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Apr 2024 03:38:08 -0400 Subject: [PATCH 6193/6505] Update calibre-web.sh tweak --- ct/calibre-web.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/calibre-web.sh b/ct/calibre-web.sh index 6f309f54..bee859ab 100644 --- a/ct/calibre-web.sh +++ b/ct/calibre-web.sh @@ -9,11 +9,11 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ ___ __ __ - / ____/___ _/ (_) /_ ________ _ _____ / /_ - / / / __ `/ / / __ \/ ___/ _ \_____| | /| / / _ \/ __ \ -/ /___/ /_/ / / / /_/ / / / __/_____/ |/ |/ / __/ /_/ / -\____/\__,_/_/_/_.___/_/ \___/ |__/|__/\___/_.___/ + ______ ___ __ _ __ __ + / ____/___ _/ (_) /_ ________ | | / /__ / /_ + / / / __ `/ / / __ \/ ___/ _ \___| | /| / / _ \/ __ \ +/ /___/ /_/ / / / /_/ / / / __/___/ |/ |/ / __/ /_/ / +\____/\__,_/_/_/_.___/_/ \___/ |__/|__/\___/_.___/ EOF } From 96230582748bc9881cc201963932e3b9a44fd638 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Apr 2024 03:38:40 -0400 Subject: [PATCH 6194/6505] Update calibre-web.sh --- ct/calibre-web.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/calibre-web.sh b/ct/calibre-web.sh index bee859ab..69752501 100644 --- a/ct/calibre-web.sh +++ b/ct/calibre-web.sh @@ -19,7 +19,7 @@ EOF } header_info echo -e "Loading..." -APP="Calibre-web" +APP="Calibre-Web" var_disk="4" var_cpu="2" var_ram="2048" From 82b6e743f140b62ae218ffca78438baa265449fe Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Apr 2024 04:01:18 -0400 Subject: [PATCH 6195/6505] Update pimox-haos-vm.sh Remove `function PVE_CHECK()` --- vm/pimox-haos-vm.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/vm/pimox-haos-vm.sh b/vm/pimox-haos-vm.sh index 3810f14c..4e1c4766 100644 --- a/vm/pimox-haos-vm.sh +++ b/vm/pimox-haos-vm.sh @@ -83,14 +83,6 @@ else echo -e "⚠ User exited script \n" exit fi -function PVE_CHECK() { - if ! pveversion | grep -Eq "pve-manager/7.[0-4]"; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Exiting..." - sleep 2 - exit - fi -} function ARCH_CHECK() { ARCH=$(dpkg --print-architecture) if [[ "$ARCH" == "amd64" ]]; then @@ -257,7 +249,6 @@ function START_SCRIPT() { fi } ARCH_CHECK -PVE_CHECK START_SCRIPT while read -r line; do TAG=$(echo $line | awk '{print $1}') From 4ccf823d7abf445c9aac43e217504f9386426b96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 09:11:46 -0400 Subject: [PATCH 6196/6505] Update install.func Spinner update --- misc/install.func | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/misc/install.func b/misc/install.func index 578bf0a8..ab0b7d5d 100644 --- a/misc/install.func +++ b/misc/install.func @@ -12,7 +12,7 @@ color() { CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" - HOLD="-" + HOLD=" " } # This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to "yes" @@ -49,13 +49,13 @@ error_handler() { # This function displays a spinner. spinner() { - printf "\e[?25l" - spinner="/-\\|/-\\|" - spin_i=0 - while true; do - printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" - sleep 0.2 - done + local chars="/-\|" + local spin_i=0 + printf "\e[?25l" + while true; do + printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}" + sleep 0.1 + done } # This function displays an informational message with a yellow color. From bdb7126a38c3dfe40e34de65f0da2621107cc702 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 09:12:55 -0400 Subject: [PATCH 6197/6505] Update create_lxc.sh Spinner update --- ct/create_lxc.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh index 010dffb8..f5218600 100644 --- a/ct/create_lxc.sh +++ b/ct/create_lxc.sh @@ -17,7 +17,7 @@ CL=$(echo "\033[m") CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" -HOLD="-" +HOLD=" " # This sets error handling options and defines the error_handler function to handle errors set -Eeuo pipefail @@ -36,13 +36,13 @@ function error_handler() { # This function displays a spinner. function spinner() { - printf "\e[?25l" - spinner="/-\\|/-\\|" - spin_i=0 - while true; do - printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" - sleep 0.1 - done + local chars="/-\|" + local spin_i=0 + printf "\e[?25l" + while true; do + printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}" + sleep 0.1 + done } # This function displays an informational message with a yellow color. From dafa19a6086abb41d8c3f9656f26169ba2ef34b3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 09:14:33 -0400 Subject: [PATCH 6198/6505] Update build.func Spinner update --- misc/build.func | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/misc/build.func b/misc/build.func index bac97de5..c259eeaa 100644 --- a/misc/build.func +++ b/misc/build.func @@ -16,7 +16,7 @@ color() { CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" BFR="\\r\\033[K" - HOLD="-" + HOLD=" " } # This function enables error handling in the script by setting options and defining a trap for the ERR signal. @@ -38,13 +38,13 @@ error_handler() { # This function displays a spinner. spinner() { - printf "\e[?25l" - spinner="/-\\|/-\\|" - spin_i=0 - while true; do - printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" - sleep 0.1 - done + local chars="/-\|" + local spin_i=0 + printf "\e[?25l" + while true; do + printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}" + sleep 0.1 + done } # This function displays an informational message with a yellow color. From 80482414c4f8596b7c234f451f1fe4a70a84c714 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 10:34:30 -0400 Subject: [PATCH 6199/6505] Update aria2.sh Correct port --- ct/aria2.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/aria2.sh b/ct/aria2.sh index c04ecc5d..a0ad7ac5 100644 --- a/ct/aria2.sh +++ b/ct/aria2.sh @@ -67,4 +67,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be accessible via the following IP. - ${BL}http://${IP}:6800${CL}" + ${BL}http://${IP}:6880${CL}" From f17592cfc73109ea5873da0f5bfe9dce9615a1d7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 10:35:54 -0400 Subject: [PATCH 6200/6505] Update aria2.sh tweak --- ct/aria2.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/aria2.sh b/ct/aria2.sh index a0ad7ac5..7fc96b97 100644 --- a/ct/aria2.sh +++ b/ct/aria2.sh @@ -66,5 +66,5 @@ build_container description msg_ok "Completed Successfully!\n" -echo -e "${APP} should be accessible via the following IP. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:6880${CL}" From 7ebc6ea84f402e20a706debf0a2986cf7ece84a4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 11:25:36 -0400 Subject: [PATCH 6201/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 922ba2fa..6cae7987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-21 + +### Changed + +- **Aria2 LXC** + - NEW Script + ## 2024-04-15 ### Changed From 1fb93b326fd028b7fb15fd7d6a6e5f245e787be6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 23:11:42 -0400 Subject: [PATCH 6202/6505] Update dashy.sh Update `function update_script()` --- ct/dashy.sh | 65 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index b06a3955..314802db 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -55,38 +55,49 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/dashy/public/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." -exit -msg_info "Stopping ${APP}" -systemctl stop dashy -msg_ok "Stopped ${APP}" -msg_info "Backing up conf.yml" -cd ~ -cp -R /opt/dashy/public/conf.yml conf.yml -msg_ok "Backed up conf.yml" +RELEASE=$(curl -sL https://api.github.com/repos/Lissy93/dashy/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Stopping ${APP}" + systemctl stop dashy + msg_ok "Stopped ${APP}" -msg_info "Updating Dashy" -cd /opt/dashy -git merge &>/dev/null -git pull origin master &>/dev/null -yarn &>/dev/null -yarn build &>/dev/null -msg_ok "Updated Dashy" + msg_info "Backing up conf.yml" + cd ~ + if [[ -f /opt/dashy/public/conf.yml ]]; then + cp -R /opt/dashy/public/conf.yml conf.yml + else + cp -R /opt/dashy/user-data/conf.yml conf.yml + fi + msg_ok "Backed up conf.yml" -msg_info "Restoring conf.yml" -cd ~ -cp -R conf.yml /opt/dashy/public -msg_ok "Restored conf.yml" + msg_info "Updating ${APP} to ${RELEASE}" + rm -rf /opt/dashy + mkdir -p /opt/dashy + wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 + sed -i 's/NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build/NODE_OPTIONS=yarn vue-cli-service build/' /opt/dashy/package.json + cd /opt/dashy + yarn &>/dev/null + yarn build &>/dev/null + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" -msg_info "Cleaning" -rm -rf conf.yml -msg_ok "Cleaned" + msg_info "Restoring conf.yml" + cd ~ + cp -R conf.yml /opt/dashy/user-data + msg_ok "Restored conf.yml" -msg_info "Starting Dashy" -systemctl start dashy -msg_ok "Started Dashy" -msg_ok "Updated Successfully" + msg_info "Cleaning" + rm -rf conf.yml /opt/dashy/public/conf.yml + msg_ok "Cleaned" + + msg_info "Starting Dashy" + systemctl start dashy + msg_ok "Started Dashy" + msg_ok "Updated Successfully" +else + msg_ok "No update required. ${APP} is already at ${RELEASE}" +fi exit } From 67cad1583bd862f558fdd29f91acf7a05f927c12 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Apr 2024 23:13:45 -0400 Subject: [PATCH 6203/6505] Update dashy-install.sh tweak --- install/dashy-install.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index d0709fb5..fce07cc5 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -29,19 +29,20 @@ ln -sf /usr/local/bin/node /usr/bin/node msg_ok "Installed Node.js" msg_info "Installing Yarn" -$STD npm install --global yarn +$STD npm install -g yarn ln -sf /usr/local/bin/yarn /usr/bin/yarn msg_ok "Installed Yarn" -msg_info "Installing Dashy (Patience)" +RELEASE=$(curl -s https://api.github.com/repos/Lissy93/dashy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +msg_info "Installing Dashy ${RELEASE} (Patience)" mkdir -p /opt/dashy -#RELEASE=$(curl -s https://api.github.com/repos/Lissy93/dashy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -#wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 -wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/2.1.1.tar.gz | tar -xz -C /opt/dashy --strip-components=1 +wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 cd /opt/dashy +sed -i 's/NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build/NODE_OPTIONS=yarn vue-cli-service build/' /opt/dashy/package.json $STD yarn $STD yarn build -msg_ok "Installed Dashy" +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed Dashy ${RELEASE}" msg_info "Creating Service" cat </etc/systemd/system/dashy.service From c042b7c5278f503712c628622d6da2d9c5b0301a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Apr 2024 06:38:43 -0400 Subject: [PATCH 6204/6505] Update haos-vm.sh Spinner update --- vm/haos-vm.sh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index fff4f939..ceb9f0d8 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -33,7 +33,7 @@ GN=$(echo "\033[1;92m") DGN=$(echo "\033[32m") CL=$(echo "\033[m") BFR="\\r\\033[K" -HOLD="-" +HOLD=" " CM="${GN}✓${CL}" CROSS="${RD}✗${CL}" THIN="discard=on,ssd=1," @@ -74,13 +74,13 @@ else fi function spinner() { - printf "\e[?25l" - spinner="◐◓◑◒" - spin_i=0 - while true; do - printf "\b%s" "${spinner:spin_i++%${#spinner}:1}" - sleep 0.1 - done + local chars="/-\|" + local spin_i=0 + printf "\e[?25l" + while true; do + printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}" + sleep 0.1 + done } function msg_info() { @@ -396,6 +396,8 @@ elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else while [ -z "${STORAGE:+x}" ]; do + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi + printf "\e[?25h" STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \ From bf4a04528b971288994d38b5fcd5ff468ea20c88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Apr 2024 06:55:18 -0400 Subject: [PATCH 6205/6505] Update build.func - Check for spaces and length in passwords - fixes https://github.com/tteck/Proxmox/issues/2843 --- misc/build.func | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/misc/build.func b/misc/build.func index c259eeaa..785fb6a6 100644 --- a/misc/build.func +++ b/misc/build.func @@ -230,17 +230,24 @@ advanced_settings() { fi done - if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z $PW1 ]; then - PW1="Automatic Login" - PW="" + while true; do + if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if [ -z "$PW1" ]; then + PW1="Automatic Login" + PW="" + elif [[ "$PW1" == *" "* ]]; then + whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 + elif [ "${#PW1}" -lt 5 ]; then + whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + break + fi else - PW="-password $PW1" + exit-script fi - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - else - exit-script - fi + done if CT_ID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then if [ -z "$CT_ID" ]; then From cfd4c979a1fb6e1733a53a1c47066d788d27708e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Apr 2024 07:23:12 -0400 Subject: [PATCH 6206/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 785fb6a6..93d99410 100644 --- a/misc/build.func +++ b/misc/build.func @@ -237,7 +237,7 @@ advanced_settings() { PW="" elif [[ "$PW1" == *" "* ]]; then whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 - elif [ "${#PW1}" -lt 5 ]; then + elif [ ${#PW1} -ge 1 ] && [ ${#PW1} -lt 5 ]; then whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 else PW="-password $PW1" From c073351b4c9bd91c1fbb7f7172c3b9a79d47de61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Apr 2024 07:35:57 -0400 Subject: [PATCH 6207/6505] Update build.func tweak --- misc/build.func | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/misc/build.func b/misc/build.func index 93d99410..439055ff 100644 --- a/misc/build.func +++ b/misc/build.func @@ -232,15 +232,19 @@ advanced_settings() { while true; do if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then - if [ -z "$PW1" ]; then + if [[ ! -z "$PW1" ]]; then + if [[ "$PW1" == *" "* ]]; then + whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 + elif [ ${#PW1} -lt 5 ]; then + whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 + else + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" + break + fi + else PW1="Automatic Login" PW="" - elif [[ "$PW1" == *" "* ]]; then - whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 - elif [ ${#PW1} -ge 1 ] && [ ${#PW1} -lt 5 ]; then - whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 - else - PW="-password $PW1" echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" break fi @@ -249,6 +253,7 @@ advanced_settings() { fi done + if CT_ID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then if [ -z "$CT_ID" ]; then CT_ID="$NEXTID" From dc6c21a85f5f6917fb6f2f90392fa4d260914116 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Apr 2024 10:34:50 -0400 Subject: [PATCH 6208/6505] Update homepage-install.sh Refactor --- install/homepage-install.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 7e7dc650..8d2bf340 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -17,11 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y make -$STD apt-get install -y g++ -$STD apt-get install -y gcc -$STD apt-get install -y ca-certificates -$STD apt-get install -y gnupg +$STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" @@ -47,11 +43,12 @@ cd /opt/homepage cp /opt/homepage/src/skeleton/* /opt/homepage/config $STD pnpm install $STD pnpm build +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_ok "Installed Homepage v${RELEASE}" msg_info "Creating Service" -service_path="/etc/systemd/system/homepage.service" -echo "[Unit] +cat </etc/systemd/system/homepage.service +[Unit] Description=Homepage After=network.target StartLimitIntervalSec=0 @@ -63,8 +60,9 @@ User=root WorkingDirectory=/opt/homepage/ ExecStart=pnpm start [Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now homepage +WantedBy=multi-user.target +EOF +systemctl enable -q --now homepage msg_ok "Created Service" motd_ssh From f20d65a606f6b6cd5f524f3f6151a9045591767d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 23 Apr 2024 10:36:16 -0400 Subject: [PATCH 6209/6505] Update homepage.sh Refactor --- ct/homepage.sh | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/ct/homepage.sh b/ct/homepage.sh index 5107f65b..dca0e9c4 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -55,26 +55,31 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/homepage ]]; then msg_error "No ${APP} Installation Found!"; exit; fi - if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then - if ! command -v npm >/dev/null 2>&1; then - echo "Installing NPM..." - apt-get install -y npm >/dev/null 2>&1 - echo "Installed NPM..." - fi +if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then + if ! command -v npm >/dev/null 2>&1; then + echo "Installing NPM..." + apt-get install -y npm >/dev/null 2>&1 + npm install -g pnpm >/dev/null 2>&1 + echo "Installed NPM..." fi +fi RELEASE=$(curl -s https://api.github.com/repos/gethomepage/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Updating Homepage to v${RELEASE} (Patience)" -systemctl stop homepage -wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz -tar -xzf v${RELEASE}.tar.gz -cp -r homepage-${RELEASE}/* /opt/homepage/ -rm -rf homepage-${RELEASE} -cd /opt/homepage -npx update-browserslist-db@latest -pnpm install -pnpm build -systemctl start homepage -msg_ok "Updated Homepage to v${RELEASE}" +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Updating Homepage to v${RELEASE} (Patience)" + systemctl stop homepage + wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz + tar -xzf v${RELEASE}.tar.gz + cp -r homepage-${RELEASE}/* /opt/homepage/ + rm -rf homepage-${RELEASE} + cd /opt/homepage + npx update-browserslist-db@latest + pnpm install + pnpm build + systemctl start homepage + msg_ok "Updated Homepage to v${RELEASE}" +else + msg_ok "No update required. ${APP} is already at ${RELEASE}" +fi exit } From 3ff48e3dae61fa813f224f61dad9e1d498d43ae8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Apr 2024 09:11:59 -0400 Subject: [PATCH 6210/6505] Update build.func Add 8.2 to `pve_check()` --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 439055ff..d23bc2a2 100644 --- a/misc/build.func +++ b/misc/build.func @@ -98,7 +98,7 @@ pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7 (EOL 2024-07), refrain from creating Debian 12 LXCs. \nDefault distribution for $APP LXC is ${var_os} ${var_version}" 10 60 fi - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[0-2])"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." From 93f791e59246c6805abaaf08747ab7afe94335d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Apr 2024 09:43:00 -0400 Subject: [PATCH 6211/6505] Add PVE 8.2 to `pve_check()` --- misc/build.func | 2 +- vm/debian-vm.sh | 2 +- vm/haos-vm.sh | 2 +- vm/nextcloud-vm.sh | 2 +- vm/openwrt.sh | 2 +- vm/owncloud-vm.sh | 2 +- vm/ubuntu-vm.sh | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/misc/build.func b/misc/build.func index d23bc2a2..8d09d8fa 100644 --- a/misc/build.func +++ b/misc/build.func @@ -98,7 +98,7 @@ pve_check() { if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7 (EOL 2024-07), refrain from creating Debian 12 LXCs. \nDefault distribution for $APP LXC is ${var_os} ${var_version}" 10 60 fi - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[0-2])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index 3f2db4f6..6a20b717 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -92,7 +92,7 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index ceb9f0d8..4c82712a 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -115,7 +115,7 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." diff --git a/vm/nextcloud-vm.sh b/vm/nextcloud-vm.sh index ff62c7df..23cc5606 100644 --- a/vm/nextcloud-vm.sh +++ b/vm/nextcloud-vm.sh @@ -91,7 +91,7 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 5ebb5ec4..0afca1cb 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -157,7 +157,7 @@ function msg_error() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh index 7fbe8be6..006a4649 100644 --- a/vm/owncloud-vm.sh +++ b/vm/owncloud-vm.sh @@ -91,7 +91,7 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu-vm.sh index be9edc88..5fffcf0d 100644 --- a/vm/ubuntu-vm.sh +++ b/vm/ubuntu-vm.sh @@ -92,7 +92,7 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then msg_error "This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo -e "Exiting..." From c828d38ba4611f3483082badc944cb944cd2a47e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Apr 2024 10:29:14 -0400 Subject: [PATCH 6212/6505] Create traccar-install.sh --- install/traccar-install.sh | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 install/traccar-install.sh diff --git a/install/traccar-install.sh b/install/traccar-install.sh new file mode 100644 index 00000000..3a9b9eea --- /dev/null +++ b/install/traccar-install.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/traccar/traccar/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Installing Traccar v${RELEASE}" +wget -q https://github.com/traccar/traccar/releases/download/v${RELEASE}/traccar-linux-64-${RELEASE}.zip +$STD unzip traccar-linux-64-${RELEASE}.zip +$STD ./traccar.run +systemctl enable -q --now traccar +rm -rf README.txt traccar-linux-64-${RELEASE}.zip traccar.run +msg_ok "Installed Traccar v${RELEASE}" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From ef6abf4bd6b20d94d00828e0dc659a976340a540 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Apr 2024 10:30:09 -0400 Subject: [PATCH 6213/6505] Create traccar.sh --- ct/traccar.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/traccar.sh diff --git a/ct/traccar.sh b/ct/traccar.sh new file mode 100644 index 00000000..1b62939a --- /dev/null +++ b/ct/traccar.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ + /_ __/________ _______________ ______ + / / / ___/ __ `/ ___/ ___/ __ `/ ___/ + / / / / / /_/ / /__/ /__/ /_/ / / +/_/ /_/ \__,_/\___/\___/\__,_/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Traccar" +var_disk="2" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/traccar ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8082${CL} \n" From 18bdaad1090a719e99d71b26d8372bf2dfdf30d6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 24 Apr 2024 11:50:31 -0400 Subject: [PATCH 6214/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cae7987..f11c828c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-24 + +### Changed + +- **Traccar LXC** + - NEW Script +- **Calibre-Web LXC** + - NEW Script + ## 2024-04-21 ### Changed From 8651919e59c9b0a8a39f9da10bbe18942ad1b867 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 14:36:47 -0400 Subject: [PATCH 6215/6505] Update build.func Refactor for future unprivileged hardware transcoding --- misc/build.func | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/misc/build.func b/misc/build.func index 8d09d8fa..656dfedb 100644 --- a/misc/build.func +++ b/misc/build.func @@ -593,6 +593,22 @@ lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file EOF fi + else + if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then + if [[ -e "/dev/dri/card0" ]]; then + cat <>$LXC_CONFIG +# VAAPI hardware transcoding +dev0: /dev/dri/card0,gid=44 +dev1: /dev/dri/renderD128,gid=104 +EOF + else + cat <>$LXC_CONFIG +# VAAPI hardware transcoding +dev0: /dev/dri/card1,gid=44 +dev1: /dev/dri/renderD128,gid=104 +EOF + fi + fi fi # This starts the container and executes -install.sh From faf98bc1f8ada8d141078322ad1be06cb1a46cc5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 14:42:39 -0400 Subject: [PATCH 6216/6505] Update jellyfin-install.sh Refactor to support unprivileged hardware transcoding. --- install/jellyfin-install.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index 8b654903..ab6bf92d 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -20,16 +20,16 @@ $STD apt-get install -y gnupg $STD apt-get install -y mc msg_ok "Installed Dependencies" +msg_info "Setting Up Hardware Acceleration" +$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} if [[ "$CTTYPE" == "0" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* $STD adduser $(id -u -n) video $STD adduser $(id -u -n) render - msg_ok "Set Up Hardware Acceleration" fi +msg_ok "Set Up Hardware Acceleration" msg_info "Installing Jellyfin" VERSION="$( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release )" @@ -51,7 +51,11 @@ EOF # Install Jellyfin using the metapackage (which will fetch jellyfin-server, jellyfin-web, and jellyfin-ffmpeg5) $STD apt-get update $STD apt-get install -y jellyfin -sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' -e 's/^render:x:108:root,jellyfin$/ssl-cert:x:108:/' /etc/group +if [[ "$CTTYPE" == "0" ]]; then + sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' -e 's/^render:x:108:root,jellyfin$/ssl-cert:x:108:/' /etc/group +else + sed -i -e 's/^ssl-cert:x:104:$/render:x:104:jellyfin/' -e 's/^render:x:108:jellyfin$/ssl-cert:x:108:/' /etc/group +fi msg_ok "Installed Jellyfin" motd_ssh From 781a2094019498bc6e1a63fff2c8d9737a2857ac Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 14:44:43 -0400 Subject: [PATCH 6217/6505] Update jellyfin.sh Default settings are now unprivileged --- ct/jellyfin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh index 6f5dfc8b..079836c2 100644 --- a/ct/jellyfin.sh +++ b/ct/jellyfin.sh @@ -30,7 +30,7 @@ color catch_errors function default_settings() { - CT_TYPE="0" + CT_TYPE="1" PW="" CT_ID=$NEXTID HN=$NSAPP From b9a45ab5a60e8b33fb8a878f56ab5aa16686362d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 14:57:04 -0400 Subject: [PATCH 6218/6505] Update CHANGELOG.md --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f11c828c..984a4523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,17 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-25 + +### Changed + +- **Jellyfin LXC** + - Default settings are now **Unprivileged** + - Unprivileged Hardware Acceleration + - Groups are set automatically + - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44` + - Set the GID for `/dev/dri/renderD128` to `104` + ## 2024-04-24 ### Changed From 6280950c31b79147187c633b989fde0f12bf7bf2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 14:58:59 -0400 Subject: [PATCH 6219/6505] Update plex-install.sh Refactor to support unprivileged hardware transcoding. --- install/plex-install.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/install/plex-install.sh b/install/plex-install.sh index fd6f0089..e253be5a 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -19,16 +19,16 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" +msg_info "Setting Up Hardware Acceleration" +$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} if [[ "$CTTYPE" == "0" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* $STD adduser $(id -u -n) video $STD adduser $(id -u -n) render - msg_ok "Set Up Hardware Acceleration" fi +msg_ok "Set Up Hardware Acceleration" msg_info "Setting Up Plex Media Server Repository" wget -qO- https://downloads.plex.tv/plex-keys/PlexSign.key >/usr/share/keyrings/PlexSign.asc @@ -38,7 +38,11 @@ msg_ok "Set Up Plex Media Server Repository" msg_info "Installing Plex Media Server" $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" install -y plexmediaserver -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 +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 From 7d7dd643fa48133ac985afb17f2d2125cf50c7e1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 14:59:54 -0400 Subject: [PATCH 6220/6505] Update plex.sh Default settings are now unprivileged --- ct/plex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/plex.sh b/ct/plex.sh index 998fe17c..c112078e 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="0" + CT_TYPE="1" PW="" CT_ID=$NEXTID HN=$NSAPP From b2b32c826e83194f6623fe8608dcc1d0c108ddcf Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 15:01:40 -0400 Subject: [PATCH 6221/6505] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 984a4523..0f0853d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,12 @@ - Groups are set automatically - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44` - Set the GID for `/dev/dri/renderD128` to `104` +- **Plex LXC** + - Default settings are now **Unprivileged** + - Unprivileged Hardware Acceleration + - Groups are set automatically + - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44` + - Set the GID for `/dev/dri/renderD128` to `104` ## 2024-04-24 From 8f243c444e8cca7c0090d4b00311665ac55d075b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 25 Apr 2024 15:15:31 -0400 Subject: [PATCH 6222/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f0853d6..58c83fbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,12 +20,14 @@ - Groups are set automatically - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44` - Set the GID for `/dev/dri/renderD128` to `104` + - Not tested <8.2 - **Plex LXC** - Default settings are now **Unprivileged** - Unprivileged Hardware Acceleration - Groups are set automatically - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44` - Set the GID for `/dev/dri/renderD128` to `104` + - Not tested <8.2 ## 2024-04-24 From 105fa6e8c458f85f6a3e951db730615b0bbb1505 Mon Sep 17 00:00:00 2001 From: NiceDevil <17103076+nicedevil007@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:25:27 +0200 Subject: [PATCH 6223/6505] Updated PostgreSQL (#2860) Updated Setup lines for PostgreSQL to match the ones from tandoor directly => https://docs.tandoor.dev/install/manual/#setup-postgresql. --- install/tandoor-install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index fa0e0ac3..e317b9ab 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -81,6 +81,9 @@ $STD apt-get update $STD apt-get install -y postgresql-16 $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" echo "" >>~/tandoor.creds echo -e "Tandoor Database Name: \e[32m$DB_NAME\e[0m" >>~/tandoor.creds echo -e "Tandoor Database User: \e[32m$DB_USER\e[0m" >>~/tandoor.creds From afe93a2b48675ad2032216e36423004a153d5d96 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Apr 2024 00:47:18 -0400 Subject: [PATCH 6224/6505] Update code-server.sh Add `curl` --- misc/code-server.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/code-server.sh b/misc/code-server.sh index cbc140d9..919ea863 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -69,6 +69,7 @@ function msg_ok() { msg_info "Installing Dependencies" apt-get update &>/dev/null +apt-get install -y curl &>/dev/null apt-get install -y git &>/dev/null msg_ok "Installed Dependencies" From e857886838ead3254d3f4ec82b6d8274e11c298e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Apr 2024 01:04:05 -0400 Subject: [PATCH 6225/6505] Update code-server.sh tweak --- misc/code-server.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/code-server.sh b/misc/code-server.sh index 919ea863..0eb46dcf 100644 --- a/misc/code-server.sh +++ b/misc/code-server.sh @@ -79,17 +79,17 @@ VERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest msg_info "Installing Code-Server v${VERSION}" curl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_amd64.deb &>/dev/null -sudo dpkg -i code-server_${VERSION}_amd64.deb &>/dev/null +dpkg -i code-server_${VERSION}_amd64.deb &>/dev/null rm -rf code-server_${VERSION}_amd64.deb mkdir -p ~/.config/code-server/ -sudo systemctl enable --now code-server@$USER &>/dev/null +systemctl enable -q --now code-server@$USER cat <~/.config/code-server/config.yaml bind-addr: 0.0.0.0:8680 auth: none password: cert: false EOF -sudo systemctl restart code-server@$USER +systemctl restart code-server@$USER msg_ok "Installed Code-Server v${VERSION} on $hostname" echo -e "${APP} should be reachable by going to the following URL. From 4883cd7afeb2498e9fcb5e1918d9a41f484f90af Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Apr 2024 02:29:25 -0400 Subject: [PATCH 6226/6505] Create glances.sh --- misc/glances.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 misc/glances.sh diff --git a/misc/glances.sh b/misc/glances.sh new file mode 100644 index 00000000..88bcf576 --- /dev/null +++ b/misc/glances.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ________ + / ____/ /___ _____ ________ _____ + / / __/ / __ `/ __ \/ ___/ _ \/ ___/ +/ /_/ / / /_/ / / / / /__/ __(__ ) +\____/_/\__,_/_/ /_/\___/\___/____/ + +EOF +} +IP=$(hostname -I | awk '{print $1}') +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD=" " +CM="${GN}✓${CL}" +APP="Glances" +hostname="$(hostname)" + +header_info +while true; do + read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done + +spinner() { + local chars="/-\|" + local spin_i=0 + printf "\e[?25l" + while true; do + printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}" + sleep 0.1 + done +} + +msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg} " + spinner & + SPINNER_PID=$! +} + +msg_ok() { + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi + printf "\e[?25h" + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +msg_info "Installing $APP" +bash -c "$(wget -qLO - https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/install.sh)" &>/dev/null +cat </etc/systemd/system/glances.service +[Unit] +Description=Glances - An eye on your system +After=network.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/glances -w +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now glances.service +msg_ok "Installed $APP on $hostname" + +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://$IP:61208${CL} \n" From 8895888df211b0af4347248d77e3dafa31e8b3dd Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Apr 2024 02:33:40 -0400 Subject: [PATCH 6227/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58c83fbf..e50e96b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-26 + +### Changed + +- **Glances** + - NEW Script + ## 2024-04-25 ### Changed From 95b7607d4eb77f0f81066c22edeccb53979907db Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Apr 2024 16:36:39 -0400 Subject: [PATCH 6228/6505] Update nginxproxymanager-install.sh Add certbot-dns-multi 4.16.1 --- install/nginxproxymanager-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index cf7ca741..0adf8f10 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -37,9 +37,8 @@ $STD apt-get install -y \ python3-pip \ python3-venv \ python3-cffi \ - python3-certbot \ - python3-certbot-dns-cloudflare -$STD pip3 install certbot_dns_porkbun + python3-certbot +$STD pip3 install certbot-dns-multi $STD pip3 install certbot-dns-duckdns $STD python3 -m venv /opt/certbot/ msg_ok "Installed Python Dependencies" From ccc91c033727ab23d2e824860d3a1af47213926f Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Apr 2024 16:53:52 -0400 Subject: [PATCH 6229/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 0adf8f10..714aae70 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -39,7 +39,6 @@ $STD apt-get install -y \ python3-cffi \ python3-certbot $STD pip3 install certbot-dns-multi -$STD pip3 install certbot-dns-duckdns $STD python3 -m venv /opt/certbot/ msg_ok "Installed Python Dependencies" From 1672c7fc0eb6e61a51f6a93c21fedb962efafcec Mon Sep 17 00:00:00 2001 From: Luke Hoggatt <37279082+hoggatt@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:28:52 -0500 Subject: [PATCH 6230/6505] Allow Updating WGDashboard (#2866) --- ct/wireguard.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index c8cc7c6f..1fb935f1 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -68,7 +68,11 @@ exit fi if [ "$UPD" == "2" ]; then if [[ -f /etc/systemd/system/wg-dashboard.service ]]; then - msg_error "Existing WGDashboard Installation Found!"; + msg_info "Updating WGDashboard" + cd /etc/wgdashboard/src + yes "Y" | sudo ./wgd.sh update &>/dev/null + sudo chmod u+x wgd.sh + msg_ok "Updated Successfully" exit fi IP=$(hostname -I | awk '{print $1}') From aacc2b76e44e719fa04ec55b97baa1553f78a5be Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 26 Apr 2024 22:36:31 -0400 Subject: [PATCH 6231/6505] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e50e96b9..eebf34e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,14 +27,14 @@ - Groups are set automatically - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44` - Set the GID for `/dev/dri/renderD128` to `104` - - Not tested <8.2 + - Not tested <8.1.11 - **Plex LXC** - Default settings are now **Unprivileged** - Unprivileged Hardware Acceleration - Groups are set automatically - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44` - Set the GID for `/dev/dri/renderD128` to `104` - - Not tested <8.2 + - Not tested <8.1.11 ## 2024-04-24 From d22dd105fbb2795e6a7340e288a0af0a3e49c7ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Apr 2024 06:39:42 -0400 Subject: [PATCH 6232/6505] Update frigate-install.sh - Set up Unprivileged Hardware Acceleration - Use GUI Device Passthrough for TPU Devices --- install/frigate-install.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 383b8370..e5fe5f09 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -37,16 +37,16 @@ chmod +x go2rtc $STD ln -svf /usr/local/go2rtc/bin/go2rtc /usr/local/bin/go2rtc msg_ok "Installed go2rtc" +msg_info "Setting Up Hardware Acceleration" +$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} if [[ "$CTTYPE" == "0" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* $STD adduser $(id -u -n) video $STD adduser $(id -u -n) render - msg_ok "Set Up Hardware Acceleration" fi +msg_ok "Set Up Hardware Acceleration" RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) msg_info "Installing Frigate $RELEASE (Perseverance)" @@ -93,7 +93,11 @@ cameras: fps: 5 EOF ln -sf /config/config.yml /opt/frigate/config/config.yml -sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group +if [[ "$CTTYPE" == "0" ]]; then + sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group +else + sed -i -e 's/^kvm:x:104:$/render:x:104:frigate/' -e 's/^render:x:105:$/kvm:x:105:/' /etc/group +fi echo "tmpfs /tmp/cache tmpfs defaults 0 0" >> /etc/fstab msg_ok "Installed Frigate $RELEASE" From 38c144951f4f805ecf7455372019024b2138d4a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Apr 2024 07:02:40 -0400 Subject: [PATCH 6233/6505] Rename ubuntu-vm.sh to ubuntu2204-vm.sh --- vm/{ubuntu-vm.sh => ubuntu2204-vm.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename vm/{ubuntu-vm.sh => ubuntu2204-vm.sh} (100%) diff --git a/vm/ubuntu-vm.sh b/vm/ubuntu2204-vm.sh similarity index 100% rename from vm/ubuntu-vm.sh rename to vm/ubuntu2204-vm.sh From 0f9d3dea8a117705272bb05b8e40c88ca9e013d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Apr 2024 07:13:49 -0400 Subject: [PATCH 6234/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eebf34e3..7eecae7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-27 + +### Changed + +- **Frigate LXC** + - Unprivileged Hardware Acceleration (https://github.com/tteck/Proxmox/discussions/2711#discussioncomment-9244629) + ## 2024-04-26 ### Changed From 0ea0ee56f494fd368ff73c873d879d6496a904d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Apr 2024 07:17:35 -0400 Subject: [PATCH 6235/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eecae7f..73899557 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ ### Changed - **Frigate LXC** - - Unprivileged Hardware Acceleration (https://github.com/tteck/Proxmox/discussions/2711#discussioncomment-9244629) + - Unprivileged Hardware Acceleration https://github.com/tteck/Proxmox/discussions/2711#discussioncomment-9244629 ## 2024-04-26 From a07e2e9dc676e57970682af51af824cf442faba3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Apr 2024 10:47:51 -0400 Subject: [PATCH 6236/6505] Update mikrotik-routeros.sh fix pve check --- vm/mikrotik-routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 6f37776a..15e702f5 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -62,7 +62,7 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - if ! pveversion | grep -Eq "pve-manager/(7.4-[1][3-9]|8.1.[1-9])"; then + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then echo "⚠ This version of Proxmox Virtual Environment is not supported" echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." echo "Exiting..." From fff310fe16c69d6e3dde508b5eb18d8403139ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Ruz=20Nieto?= <40019177+aruznieto@users.noreply.github.com> Date: Sat, 27 Apr 2024 16:58:18 +0200 Subject: [PATCH 6237/6505] Create ubuntu2404-vm.sh (#2868) --- vm/ubuntu2404-vm.sh | 428 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 vm/ubuntu2404-vm.sh diff --git a/vm/ubuntu2404-vm.sh b/vm/ubuntu2404-vm.sh new file mode 100644 index 00000000..7869d189 --- /dev/null +++ b/vm/ubuntu2404-vm.sh @@ -0,0 +1,428 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ ____ __ ___ __ __ ____ __ __ _ ____ ___ + / / / / /_ __ ______ / /___ __ |__ \/ // / / __ \/ // / | | / / |/ / + / / / / __ \/ / / / __ \/ __/ / / / __/ / // /_ / / / / // /_ | | / / /|_/ / +/ /_/ / /_/ / /_/ / / / / /_/ /_/ / / __/__ __// /_/ /__ __/ | |/ / / / / +\____/_.___/\__,_/_/ /_/\__/\__,_/ /____/ /_/ (_)____/ /_/ |___/_/ /_/ + +EOF +} +header_info +echo -e "\n Loading..." +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +NEXTID=$(pvesh get /cluster/nextid) + +YW=$(echo "\033[33m") +BL=$(echo "\033[36m") +HA=$(echo "\033[1;34m") +RD=$(echo "\033[01;31m") +BGN=$(echo "\033[4;92m") +GN=$(echo "\033[1;92m") +DGN=$(echo "\033[32m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +CROSS="${RD}✗${CL}" +THIN="discard=on,ssd=1," +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +trap cleanup EXIT +function error_handler() { + local exit_code="$?" + local line_number="$1" + local command="$2" + local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" + echo -e "\n$error_message\n" + cleanup_vmid +} + +function cleanup_vmid() { + if qm status $VMID &>/dev/null; then + qm stop $VMID &>/dev/null + qm destroy $VMID &>/dev/null + fi +} + +function cleanup() { + popd >/dev/null + rm -rf $TEMP_DIR +} + +TEMP_DIR=$(mktemp -d) +pushd $TEMP_DIR >/dev/null +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Ubuntu 24.04 VM" --yesno "This will create a New Ubuntu 24.04 VM. Proceed?" 10 58; then + : +else + header_info && echo -e "⚠ User exited script \n" && exit +fi + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +function msg_error() { + local msg="$1" + echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" +} + +function check_root() { + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi +} + +function pve_check() { + if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function arch_check() { + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + msg_error "This script will not work with PiMox! \n" + echo -e "Exiting..." + sleep 2 + exit + fi +} + +function ssh_check() { + if command -v pveversion >/dev/null 2>&1; then + if [ -n "${SSH_CLIENT:+x}" ]; then + if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then + echo "you've been warned" + else + clear + exit + fi + fi + fi +} + +function exit-script() { + clear + echo -e "⚠ User exited script \n" + exit +} + +function default_settings() { + VMID="$NEXTID" + FORMAT=",efitype=4m" + MACHINE="" + DISK_CACHE="" + HN="ubuntu" + CPU_TYPE="" + CORE_COUNT="2" + RAM_SIZE="2048" + BRG="vmbr0" + MAC="$GEN_MAC" + VLAN="" + MTU="" + START_VM="no" + echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}" + echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}" + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}" + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}" + echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}" + echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}" + echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}" + echo -e "${DGN}Using VLAN: ${BGN}Default${CL}" + echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}" + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + echo -e "${BL}Creating an Ubuntu 24.04 VM using the above default settings${CL}" +} + +function advanced_settings() { + while true; do + if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z "$VMID" ]; then + VMID="$NEXTID" + fi + if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then + echo -e "${CROSS}${RD} ID $VMID is already in use${CL}" + sleep 2 + continue + fi + echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}" + break + else + exit-script + fi + done + + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ + "i440fx" "Machine i440fx" ON \ + "q35" "Machine q35" OFF \ + 3>&1 1>&2 2>&3); then + if [ $MACH = q35 ]; then + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT="" + MACHINE=" -machine q35" + else + echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}" + FORMAT=",efitype=4m" + MACHINE="" + fi + else + exit-script + fi + + if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "None (Default)" ON \ + "1" "Write Through" OFF \ + 3>&1 1>&2 2>&3); then + if [ $DISK_CACHE = "1" ]; then + echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}" + DISK_CACHE="cache=writethrough," + else + echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}" + DISK_CACHE="" + fi + else + exit-script + fi + + if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 ubuntu --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VM_NAME ]; then + HN="ubuntu" + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + else + HN=$(echo ${VM_NAME,,} | tr -d ' ') + echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}" + fi + else + exit-script + fi + + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ + "0" "KVM64 (Default)" ON \ + "1" "Host" OFF \ + 3>&1 1>&2 2>&3); then + if [ $CPU_TYPE1 = "1" ]; then + echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}" + CPU_TYPE=" -cpu host" + else + echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}" + CPU_TYPE="" + fi + else + exit-script + fi + + if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $CORE_COUNT ]; then + CORE_COUNT="2" + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + else + echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}" + fi + else + exit-script + fi + + if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $RAM_SIZE ]; then + RAM_SIZE="2048" + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + else + echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}" + fi + else + exit-script + fi + + if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $BRG ]; then + BRG="vmbr0" + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + else + echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}" + fi + else + exit-script + fi + + if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MAC1 ]; then + MAC="$GEN_MAC" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}" + else + MAC="$MAC1" + echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" + fi + else + exit-script + fi + + if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $VLAN1 ]; then + VLAN1="Default" + VLAN="" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + else + VLAN=",tag=$VLAN1" + echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" + fi + else + exit-script + fi + + if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then + if [ -z $MTU1 ]; then + MTU1="Default" + MTU="" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + else + MTU=",mtu=$MTU1" + echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}" + fi + else + exit-script + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then + echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}" + START_VM="yes" + else + echo -e "${DGN}Start VM when completed: ${BGN}no${CL}" + START_VM="no" + fi + + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create an Ubuntu 24.04 VM?" --no-button Do-Over 10 58); then + echo -e "${RD}Creating an Ubuntu 24.04 VM using the above advanced settings${CL}" + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +function start_script() { + if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then + header_info + echo -e "${BL}Using Default Settings${CL}" + default_settings + else + header_info + echo -e "${RD}Using Advanced Settings${CL}" + advanced_settings + fi +} + +check_root +arch_check +pve_check +ssh_check +start_script + +msg_info "Validating Storage" +while read -r line; do + TAG=$(echo $line | awk '{print $1}') + TYPE=$(echo $line | awk '{printf "%-10s", $2}') + FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') + ITEM=" Type: $TYPE Free: $FREE " + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + STORAGE_MENU+=("$TAG" "$ITEM" "OFF") +done < <(pvesm status -content images | awk 'NR>1') +VALID=$(pvesm status -content images | awk 'NR>1') +if [ -z "$VALID" ]; then + msg_error "Unable to detect a valid storage location." + exit +elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + STORAGE=${STORAGE_MENU[0]} +else + while [ -z "${STORAGE:+x}" ]; do + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ + "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit + done +fi +msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." +msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." +msg_info "Retrieving the URL for the Ubuntu 24.04 Disk Image" +URL=https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img +sleep 2 +msg_ok "${CL}${BL}${URL}${CL}" +wget -q --show-progress $URL +echo -en "\e[1A\e[0K" +FILE=$(basename $URL) +msg_ok "Downloaded ${CL}${BL}${FILE}${CL}" + +STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') +case $STORAGE_TYPE in +nfs | dir) + DISK_EXT=".qcow2" + DISK_REF="$VMID/" + DISK_IMPORT="-format qcow2" + THIN="" + ;; +btrfs) + DISK_EXT=".raw" + DISK_REF="$VMID/" + DISK_IMPORT="-format raw" + FORMAT=",efitype=4m" + THIN="" + ;; +esac +for i in {0,1}; do + disk="DISK$i" + eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} + eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} +done + +msg_info "Creating a Ubuntu 24.04 VM" +qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ + -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci +pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null +qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \ + -ide2 ${STORAGE}:cloudinit \ + -boot order=scsi0 \ + -serial0 socket \ + -description "
    + + # Ubuntu 24.04 VM + + +
    " >/dev/null +msg_ok "Created a Ubuntu 24.04 VM ${CL}${BL}(${HN})" +if [ "$START_VM" == "yes" ]; then + msg_info "Starting Ubuntu 24.04 VM" + qm start $VMID + msg_ok "Started Ubuntu 24.04 VM" +fi +msg_ok "Completed Successfully!\n" +echo -e "Setup Cloud-Init before starting \n +More info at https://github.com/tteck/Proxmox/discussions/2072 \n" From 93aa096169306d99939bd6c919ac1216dcb31674 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Apr 2024 11:06:02 -0400 Subject: [PATCH 6238/6505] Update glances.sh fixes https://github.com/tteck/Proxmox/issues/2870 --- misc/glances.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/glances.sh b/misc/glances.sh index 88bcf576..c40af8b4 100644 --- a/misc/glances.sh +++ b/misc/glances.sh @@ -65,6 +65,7 @@ msg_ok() { } msg_info "Installing $APP" +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED bash -c "$(wget -qLO - https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/install.sh)" &>/dev/null cat </etc/systemd/system/glances.service [Unit] From 51b39f269bbc2ea3a72dcbcbde986c5f4121cb93 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 27 Apr 2024 11:14:30 -0400 Subject: [PATCH 6239/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73899557..8c2bd0dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - **Frigate LXC** - Unprivileged Hardware Acceleration https://github.com/tteck/Proxmox/discussions/2711#discussioncomment-9244629 +- **Ubuntu 24.04 VM** + - NEW Script ## 2024-04-26 From 39ac55d024a76525468bfde6f94be33b88ef1bbc Mon Sep 17 00:00:00 2001 From: Tchoupinax Date: Sat, 27 Apr 2024 17:45:08 +0200 Subject: [PATCH 6240/6505] feat: script improvement on routerOS and OpenWRT (#2869) --- vm/openwrt.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/openwrt.sh b/vm/openwrt.sh index 0afca1cb..e3e32e9e 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -475,6 +475,7 @@ qm set $VMID \ -efidisk0 ${DISK0_REF},efitype=4m,size=4M \ -scsi0 ${DISK1_REF},size=512M \ -boot order=scsi0 \ + -tags proxmox-helper-scripts \ -description "
    # OpenWRT From 5d6cec1dd7925cba2ef94a20596721d98d71216e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Apr 2024 06:25:43 -0400 Subject: [PATCH 6241/6505] Update scrypted-install.sh Add Unprivileged Hardware Acceleration --- install/scrypted-install.sh | 38 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index a85c2271..6e54f790 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -35,22 +35,20 @@ $STD apt-get -y install \ sudo \ mc \ ca-certificates \ - gnupg + gpg msg_ok "Installed Dependencies" +msg_info "Setting Up Hardware Acceleration" +$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} if [[ "$CTTYPE" == "0" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - intel-opencl-icd chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* $STD adduser $(id -u -n) video $STD adduser $(id -u -n) render - msg_ok "Set Up Hardware Acceleration" fi +msg_ok "Set Up Hardware Acceleration" + msg_info "Installing GStreamer (Patience)" $STD apt-get -y install \ gstreamer1.0-tools \ @@ -98,24 +96,19 @@ $STD python3 -m pip install --upgrade pip $STD python3 -m pip install aiofiles debugpy typing_extensions typing msg_ok "Installed Python3 Dependencies" -read -r -p "Would you like to add Coral Edge TPU support? " prompt -if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then -msg_info "Adding Coral Edge TPU Support" -wget -qO /etc/apt/trusted.gpg.d/coral-repo.asc "https://packages.cloud.google.com/apt/doc/apt-key.gpg" -echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" >/etc/apt/sources.list.d/coral-edgetpu.list -$STD apt-get -y update -$STD apt-get -y install libedgetpu1-std -msg_ok "Coral Edge TPU Support Added" -fi - msg_info "Installing Scrypted" $STD npx -y scrypted@latest install-server -sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group + +if [[ "$CTTYPE" == "0" ]]; then + sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group +else + sed -i -e 's/^sgx:x:104:$/render:x:104:/' -e 's/^render:x:106:$/sgx:x:106:/' /etc/group +fi msg_ok "Installed Scrypted" msg_info "Creating Service" -service_path="/etc/systemd/system/scrypted.service" -echo "[Unit] +cat </etc/systemd/system/scrypted.service +[Unit] Description=Scrypted service After=network.target @@ -128,8 +121,9 @@ Restart=on-failure RestartSec=3 [Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable --now scrypted.service +WantedBy=multi-user.target +EOF +systemctl enable -q --now scrypted.service msg_ok "Created Service" motd_ssh From 90f696461e8c4b68a6196963904a48c64122dafb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Apr 2024 06:56:08 -0400 Subject: [PATCH 6242/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c2bd0dd..a2646902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-28 + +### Changed + +- **Scrypted LXC** + - Unprivileged Hardware Acceleration + ## 2024-04-27 ### Changed From 6c3c39b79ca19f5fc0dea2d21bc695135fed54ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Apr 2024 09:06:03 -0400 Subject: [PATCH 6243/6505] Update emby-install.sh Add Unprivileged Hardware Acceleration --- install/emby-install.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/install/emby-install.sh b/install/emby-install.sh index 72158183..99f5ebfe 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -19,23 +19,27 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" +msg_info "Setting Up Hardware Acceleration" +$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} if [[ "$CTTYPE" == "0" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* $STD adduser $(id -u -n) video $STD adduser $(id -u -n) render - msg_ok "Set Up Hardware Acceleration" fi +msg_ok "Set Up Hardware Acceleration" LATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4) msg_info "Installing Emby" wget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb -sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,emby/' -e 's/^render:x:108:root,emby$/ssl-cert:x:108:/' /etc/group +if [[ "$CTTYPE" == "0" ]]; then + sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,emby/' -e 's/^render:x:108:root,emby$/ssl-cert:x:108:/' /etc/group +else + sed -i -e 's/^ssl-cert:x:104:$/render:x:104:emby/' -e 's/^render:x:108:emby$/ssl-cert:x:108:/' /etc/group +fi msg_ok "Installed Emby" motd_ssh From a75f383568f70ecc5178f01b1a576020efc1bdb9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Apr 2024 09:07:07 -0400 Subject: [PATCH 6244/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2646902..79b0c035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - **Scrypted LXC** - Unprivileged Hardware Acceleration +- **Emby LXC** + - Unprivileged Hardware Acceleration ## 2024-04-27 From 869a95d22137bfc491d958263d602b1f283f477b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Apr 2024 17:42:47 -0400 Subject: [PATCH 6245/6505] Update glances.sh Add uninstall function --- misc/glances.sh | 84 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 19 deletions(-) diff --git a/misc/glances.sh b/misc/glances.sh index c40af8b4..8a0309be 100644 --- a/misc/glances.sh +++ b/misc/glances.sh @@ -29,17 +29,8 @@ HOLD=" " CM="${GN}✓${CL}" APP="Glances" hostname="$(hostname)" - -header_info -while true; do - read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done - +silent() { "$@" >/dev/null 2>&1; } +set -e spinner() { local chars="/-\|" local spin_i=0 @@ -64,10 +55,27 @@ msg_ok() { echo -e "${BFR} ${CM} ${GN}${msg}${CL}" } -msg_info "Installing $APP" -rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED -bash -c "$(wget -qLO - https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/install.sh)" &>/dev/null -cat </etc/systemd/system/glances.service +install() { + header_info + while true; do + read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac + done + header_info + read -r -p "Verbose mode? " prompt + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + STD="" + else + STD="silent" + fi + msg_info "Installing $APP" + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED + $STD bash -c "$(wget -qLO - https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/install.sh)" + cat </etc/systemd/system/glances.service [Unit] Description=Glances - An eye on your system After=network.target @@ -80,8 +88,46 @@ Restart=on-failure [Install] WantedBy=multi-user.target EOF -systemctl enable -q --now glances.service -msg_ok "Installed $APP on $hostname" + systemctl enable -q --now glances.service + msg_ok "Installed $APP on $hostname" -echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://$IP:61208${CL} \n" + echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://$IP:61208${CL} \n" +} +uninstall() { + header_info + read -r -p "Verbose mode? " prompt + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + STD="" + else + STD="silent" + fi + header_info + + msg_info "Uninstalling $APP" + if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi + systemctl disable -q --now glances + bash -c "$(wget -qLO - https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/uninstall.sh)" + rm -rf /etc/systemd/system/glances.service + msg_ok "Uninstalled $APP" + msg_ok "Completed Successfully!\n" +} + +OPTIONS=(Install "Install $APP" \ + Uninstall "Uninstall $APP") + +CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$APP" --menu "Select an option:" 10 58 2 \ + "${OPTIONS[@]}" 3>&1 1>&2 2>&3) + +case $CHOICE in + "Install") + install + ;; + "Uninstall") + uninstall + ;; + *) + echo "Exiting..." + exit 0 + ;; +esac From 01c54ab916ee39b064fbc46b06739f88ee867819 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 28 Apr 2024 17:49:04 -0400 Subject: [PATCH 6246/6505] Update glances.sh tweak --- misc/glances.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/misc/glances.sh b/misc/glances.sh index 8a0309be..31840977 100644 --- a/misc/glances.sh +++ b/misc/glances.sh @@ -96,14 +96,6 @@ EOF } uninstall() { header_info - read -r -p "Verbose mode? " prompt - if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then - STD="" - else - STD="silent" - fi - header_info - msg_info "Uninstalling $APP" if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi systemctl disable -q --now glances From 169201a7517ed18a7066628e8df1c3b317efe80b Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:10:05 +0200 Subject: [PATCH 6247/6505] Add new LXC: ErsatzTV (#2876) --- ct/ersatztv.sh | 91 +++++++++++++++++++++++++++++++++++++ install/ersatztv-install.sh | 64 ++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 ct/ersatztv.sh create mode 100644 install/ersatztv-install.sh diff --git a/ct/ersatztv.sh b/ct/ersatztv.sh new file mode 100644 index 00000000..de21b8ef --- /dev/null +++ b/ct/ersatztv.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/ErsatzTV/ErsatzTV/ + + +function header_info { +clear +cat <<"EOF" + ______ __ _______ __ + / ____/_____________ _/ /_____/_ __/ | / / + / __/ / ___/ ___/ __ `/ __/_ / / / | | / / + / /___/ / (__ ) /_/ / /_ / /_/ / | |/ / +/_____/_/ /____/\__,_/\__/ /___/_/ |___/ + +EOF +} +header_info +echo -e "Loading..." +APP="ErsatzTV" +var_disk="5" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} +function update_script() { +header_info +if [[ ! -d /opt/ErsatzTV ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi +msg_info "Stopping ErsatzTV" +systemctl stop ersatzTV +msg_ok "Stopped ErsatzTV" + +msg_info "Updating ErsatzTV" +RELEASE=$(curl -s https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1) +if [ -d /opt/ErsatzTV/ErsatzTV_bak ]; then + rm -rf /opt/ErsatzTV/ErsatzTV_bak +fi +mv /opt/ErsatzTV/ErsatzTV /opt/ErsatzTV/ErsatzTV_bak +wget -qO- "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz" | tar -xz -C /opt +mv "/opt/ErsatzTV-${RELEASE}-linux-x64" /opt/ErsatzTV +msg_ok "Updated ErsatzTV" + +msg_info "Starting ErsatzTV" +systemctl start ersatzTV +msg_ok "Started ErsatzTV" +msg_ok "Updated Successfully" +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}:8409${CL} \n" diff --git a/install/ersatztv-install.sh b/install/ersatztv-install.sh new file mode 100644 index 00000000..53a9c3ed --- /dev/null +++ b/install/ersatztv-install.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/ErsatzTV/ErsatzTV + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y --no-install-recommends \ + ffmpeg \ + build-essential \ + unzip \ + pkg-config \ + curl \ + sudo \ + git \ + make \ + mc +msg_ok "Installed Dependencies" + + +msg_info "Installing ErsatzTV " +RELEASE=$(curl -s https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1) +wget -qO- "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz" | tar -xz -C /opt +mv "/opt/ErsatzTV-${RELEASE}-linux-x64" /opt/ErsatzTV +msg_ok "Installed ErsatzTV" + +msg_info "Creating Service" +cat </etc/systemd/system/ersatzTV.service +[Unit] +Description=ErsatzTV Service +After=multi-user.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/ErsatzTV +ExecStart=/opt/ErsatzTV/ErsatzTV +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target +EOF +systemctl -q --now enable ersatzTV.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" From cae357cc262d2b26a39a81249faa469225c43188 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 29 Apr 2024 10:39:51 -0400 Subject: [PATCH 6248/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79b0c035..a538c184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-29 + +### Changed + +- **ErsatzTV LXC** + - NEW Script + ## 2024-04-28 ### Changed From 90003e72f383b116439270dbd74593b5ef7bb78a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Apr 2024 05:48:46 -0400 Subject: [PATCH 6249/6505] Update tdarr-install.sh Add Unprivileged Hardware Acceleration --- install/tdarr-install.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index f4f45d04..adf423cb 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -20,19 +20,16 @@ $STD apt-get install -y mc $STD apt-get install -y handbrake-cli msg_ok "Installed Dependencies" +msg_info "Setting Up Hardware Acceleration" +$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools} if [[ "$CTTYPE" == "0" ]]; then - msg_info "Setting Up Hardware Acceleration" - $STD apt-get -y install \ - va-driver-all \ - ocl-icd-libopencl1 \ - intel-opencl-icd chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* $STD adduser $(id -u -n) video $STD adduser $(id -u -n) render - msg_ok "Set Up Hardware Acceleration" fi +msg_ok "Set Up Hardware Acceleration" msg_info "Installing Tdarr" mkdir -p /opt/tdarr @@ -43,7 +40,12 @@ $STD unzip Tdarr_Updater.zip rm -rf Tdarr_Updater.zip chmod +x Tdarr_Updater ./Tdarr_Updater &>/dev/null -sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group +if [[ "$CTTYPE" == "0" ]]; then + sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group +else + sed -i -e 's/^sgx:x:104:$/render:x:104:/' -e 's/^render:x:106:$/sgx:x:106:/' /etc/group +fi + msg_ok "Installed Tdarr" msg_info "Creating Service" From f041d5edead43360d8ae571376d97e87a6df59cf Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Apr 2024 05:49:53 -0400 Subject: [PATCH 6250/6505] Update tdarr.sh Default settings are now Unprivileged --- ct/tdarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/tdarr.sh b/ct/tdarr.sh index b658ec70..11bc2880 100644 --- a/ct/tdarr.sh +++ b/ct/tdarr.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="0" + CT_TYPE="1" PW="" CT_ID=$NEXTID HN=$NSAPP From bd029543c89672b8cded1d3470667847ffc8515f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Apr 2024 05:59:53 -0400 Subject: [PATCH 6251/6505] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a538c184..5237884c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,14 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-04-30 + +### Changed + +- **Tdarr LXC** + - Default settings are now **Unprivileged** + - Unprivileged Hardware Acceleration + ## 2024-04-29 ### Changed From 46be5a9b744cfc8691dab056f819572be84139c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 30 Apr 2024 06:07:35 -0400 Subject: [PATCH 6252/6505] Update emby.sh Default settings are now Unprivileged --- ct/emby.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/emby.sh b/ct/emby.sh index a8b5618a..092a44a4 100644 --- a/ct/emby.sh +++ b/ct/emby.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="0" + CT_TYPE="1" PW="" CT_ID=$NEXTID HN=$NSAPP From e13303d2fc564c5748ef28f6f99f3fd8d3fa6973 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 May 2024 14:01:24 -0400 Subject: [PATCH 6253/6505] Update nextcloudpi-install.sh - Add `lbzip2` - testing --- install/nextcloudpi-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh index 9a53a287..9a846d45 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y lbzip2 msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" From adb7bc55f4831c927ac71d658ce40b630d35857d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 May 2024 14:16:32 -0400 Subject: [PATCH 6254/6505] Update nextcloudpi.sh Default Debian 12 --- ct/nextcloudpi.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh index e4312b20..7255de3d 100644 --- a/ct/nextcloudpi.sh +++ b/ct/nextcloudpi.sh @@ -23,7 +23,7 @@ var_disk="8" var_cpu="2" var_ram="2048" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From ace4a8e43f1d83444a272357125965487cbb79b0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 1 May 2024 14:38:15 -0400 Subject: [PATCH 6255/6505] Update build.func fixes https://github.com/tteck/Proxmox/issues/2894 --- misc/build.func | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index 656dfedb..f58149c1 100644 --- a/misc/build.func +++ b/misc/build.func @@ -595,18 +595,20 @@ EOF fi else if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then - if [[ -e "/dev/dri/card0" ]]; then + if [[ -e "/dev/dri/renderD128" ]]; then + if [[ -e "/dev/dri/card0" ]]; then cat <>$LXC_CONFIG # VAAPI hardware transcoding dev0: /dev/dri/card0,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF - else + else cat <>$LXC_CONFIG # VAAPI hardware transcoding dev0: /dev/dri/card1,gid=44 dev1: /dev/dri/renderD128,gid=104 EOF + fi fi fi fi From ee8fea07be3f2e8a7e4290c33656d9d22eac85a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 08:18:52 -0400 Subject: [PATCH 6256/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5237884c..de034739 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-02 + +### Changed + +- **NextCloudPi LXC** + - Removed from website + ## 2024-04-30 ### Changed From c8205964310dbf72a08b1e182a28fd65a3f7c034 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 12:25:07 -0400 Subject: [PATCH 6257/6505] Update nextcloudpi-install.sh test --- install/nextcloudpi-install.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh index 9a846d45..24306f24 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-install.sh @@ -17,15 +17,20 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y lbzip2 msg_ok "Installed Dependencies" msg_info "Installing NextCloudPi (Patience)" +$STD apt-get install -y systemd-resolved +systemctl enable -q --now systemd-resolved +cat <<'EOF' >/etc/systemd/resolved.conf +[Resolve] +DNS=8.8.8.8 +FallbackDNS=8.8.4.4 +EOF +systemctl restart systemd-resolved $STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) -sed -i "s/3 => 'nextcloudpi.lan',/3 => '0.0.0.0',/g" /var/www/nextcloud/config/config.php -sed -i '{s|root:/usr/sbin/nologin|root:/bin/bash|g}' /etc/passwd -sed -i 's/memory_limit = .*/memory_limit = 512M/' /etc/php/8.1/fpm/php.ini /etc/php/8.1/cli/php.ini -service apache2 restart +systemctl disable -q --now systemd-resolved +$STD apt-get remove -y systemd-resolved msg_ok "Installed NextCloudPi" motd_ssh From f5ceaccd6dfdb3118cc81938ba30e259b198e659 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 12:37:15 -0400 Subject: [PATCH 6258/6505] Update nextcloudpi-install.sh tweak --- install/nextcloudpi-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/nextcloudpi-install.sh b/install/nextcloudpi-install.sh index 24306f24..ca1871dd 100644 --- a/install/nextcloudpi-install.sh +++ b/install/nextcloudpi-install.sh @@ -37,6 +37,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" From 1ed8a8b5b3a1485a2b541bd56c53950547d05768 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 13:08:23 -0400 Subject: [PATCH 6259/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de034739..5237884c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,13 +10,6 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** -## 2024-05-02 - -### Changed - -- **NextCloudPi LXC** - - Removed from website - ## 2024-04-30 ### Changed From 64a33de1189d08ef4dd1ca05ff773ab258c8bebc Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 13:26:16 -0400 Subject: [PATCH 6260/6505] Add '-y` flag --- install/actualbudget-install.sh | 4 ++-- install/adguard-install.sh | 4 ++-- install/agentdvr-install.sh | 4 ++-- install/apache-cassandra-install.sh | 4 ++-- install/apache-couchdb-install.sh | 4 ++-- install/apt-cacher-ng-install.sh | 4 ++-- install/audiobookshelf-install.sh | 4 ++-- install/autobrr-install.sh | 4 ++-- install/blocky-install.sh | 4 ++-- install/calibre-web-install.sh | 4 ++-- install/casaos-install.sh | 4 ++-- install/changedetection-install.sh | 4 ++-- install/channels-install.sh | 4 ++-- install/cloudflared-install.sh | 4 ++-- install/cronicle-install.sh | 4 ++-- install/dashy-install.sh | 4 ++-- install/debian-install.sh | 4 ++-- install/deluge-install.sh | 4 ++-- install/docker-install.sh | 4 ++-- install/dockge-install.sh | 4 ++-- install/ersatztv-install.sh | 4 ++-- install/esphome-install.sh | 4 ++-- install/fhem-install.sh | 4 ++-- install/flowiseai-install.sh | 4 ++-- install/frigate-install.sh | 4 ++-- install/go2rtc-install.sh | 4 ++-- install/gokapi-install.sh | 4 ++-- install/gotify-install.sh | 4 ++-- install/grafana-install.sh | 4 ++-- install/heimdall-dashboard-install.sh | 4 ++-- install/homarr-install.sh | 4 ++-- install/homeassistant-core-install.sh | 4 ++-- install/homeassistant-install.sh | 4 ++-- install/homebridge-install.sh | 4 ++-- install/homepage-install.sh | 4 ++-- install/homer-install.sh | 4 ++-- install/hyperhdr-install.sh | 4 ++-- install/influxdb-install.sh | 4 ++-- install/iobroker-install.sh | 4 ++-- install/jackett-install.sh | 4 ++-- install/jellyfin-install.sh | 4 ++-- install/jellyseerr-install.sh | 4 ++-- install/k0s-install.sh | 4 ++-- install/kavita-install.sh | 4 ++-- install/keycloak-install.sh | 4 ++-- install/lazylibrarian-install.sh | 4 ++-- install/linkwarden-install.sh | 4 ++-- install/mafl-install.sh | 4 ++-- install/magicmirror-install.sh | 4 ++-- install/mariadb-install.sh | 4 ++-- install/mediamtx-install.sh | 4 ++-- install/medusa-install.sh | 4 ++-- install/meshcentral-install.sh | 4 ++-- install/motioneye-install.sh | 4 ++-- install/mqtt-install.sh | 4 ++-- install/n8n-install.sh | 4 ++-- install/nocodb-install.sh | 4 ++-- install/node-red-install.sh | 4 ++-- install/ntfy-install.sh | 4 ++-- install/octoprint-install.sh | 4 ++-- install/ombi-install.sh | 4 ++-- install/omv-install.sh | 4 ++-- install/openhab-install.sh | 4 ++-- install/openobserve-install.sh | 4 ++-- install/overseerr-install.sh | 4 ++-- install/owncast-install.sh | 4 ++-- install/pairdrop-install.sh | 4 ++-- install/pbs-install.sh | 4 ++-- install/photoprism-install.sh | 4 ++-- install/pialert-install.sh | 4 ++-- install/pihole-install.sh | 4 ++-- install/pingvin-install.sh | 4 ++-- install/plex-install.sh | 4 ++-- install/podman-homeassistant-install.sh | 4 ++-- install/podman-install.sh | 4 ++-- install/postgresql-install.sh | 4 ++-- install/qbittorrent-install.sh | 4 ++-- install/rdtclient-install.sh | 4 ++-- install/readeck-install.sh | 4 ++-- install/redis-install.sh | 4 ++-- install/rtsptoweb-install.sh | 4 ++-- install/sabnzbd-install.sh | 4 ++-- install/scrypted-install.sh | 4 ++-- install/shinobi-install.sh | 4 ++-- install/smokeping-install.sh | 4 ++-- install/sonarr-install.sh | 4 ++-- install/syncthing-install.sh | 4 ++-- install/tandoor-install.sh | 4 ++-- install/tasmoadmin-install.sh | 4 ++-- install/tautulli-install.sh | 4 ++-- install/technitiumdns-install.sh | 4 ++-- install/traccar-install.sh | 4 ++-- install/transmission-install.sh | 4 ++-- install/ubuntu-install.sh | 4 ++-- install/unifi-install.sh | 4 ++-- install/unmanic-install.sh | 4 ++-- install/uptimekuma-install.sh | 4 ++-- install/vaultwarden-install.sh | 4 ++-- install/wastebin-install.sh | 4 ++-- install/watchyourlan-install.sh | 4 ++-- install/whoogle-install.sh | 4 ++-- install/wikijs-install.sh | 4 ++-- install/wireguard-install.sh | 4 ++-- install/yunohost-install.sh | 4 ++-- install/zigbee2mqtt-install.sh | 4 ++-- 105 files changed, 210 insertions(+), 210 deletions(-) diff --git a/install/actualbudget-install.sh b/install/actualbudget-install.sh index 0f000ed9..fbd07867 100644 --- a/install/actualbudget-install.sh +++ b/install/actualbudget-install.sh @@ -60,6 +60,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/adguard-install.sh b/install/adguard-install.sh index 263aa52b..ef3688cf 100644 --- a/install/adguard-install.sh +++ b/install/adguard-install.sh @@ -51,6 +51,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/agentdvr-install.sh b/install/agentdvr-install.sh index 69491da5..f0c431a0 100644 --- a/install/agentdvr-install.sh +++ b/install/agentdvr-install.sh @@ -58,6 +58,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/apache-cassandra-install.sh b/install/apache-cassandra-install.sh index da0c1f40..35c49486 100644 --- a/install/apache-cassandra-install.sh +++ b/install/apache-cassandra-install.sh @@ -40,6 +40,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/apache-couchdb-install.sh b/install/apache-couchdb-install.sh index 41cfde57..94902056 100644 --- a/install/apache-couchdb-install.sh +++ b/install/apache-couchdb-install.sh @@ -42,6 +42,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/apt-cacher-ng-install.sh b/install/apt-cacher-ng-install.sh index 1d7572c2..b8e29316 100644 --- a/install/apt-cacher-ng-install.sh +++ b/install/apt-cacher-ng-install.sh @@ -29,6 +29,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/audiobookshelf-install.sh b/install/audiobookshelf-install.sh index 1b26fd10..cd9346e3 100644 --- a/install/audiobookshelf-install.sh +++ b/install/audiobookshelf-install.sh @@ -31,6 +31,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/autobrr-install.sh b/install/autobrr-install.sh index c8883ddd..510d1c0a 100644 --- a/install/autobrr-install.sh +++ b/install/autobrr-install.sh @@ -52,6 +52,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/blocky-install.sh b/install/blocky-install.sh index 86523055..d3ba2b50 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -285,6 +285,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/calibre-web-install.sh b/install/calibre-web-install.sh index 834c989f..6d2b1445 100644 --- a/install/calibre-web-install.sh +++ b/install/calibre-web-install.sh @@ -62,6 +62,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/casaos-install.sh b/install/casaos-install.sh index 50027c6c..e7e07a61 100644 --- a/install/casaos-install.sh +++ b/install/casaos-install.sh @@ -30,6 +30,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index d685153a..95050bd7 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -157,6 +157,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/channels-install.sh b/install/channels-install.sh index 548628af..3c5e2d9d 100644 --- a/install/channels-install.sh +++ b/install/channels-install.sh @@ -45,6 +45,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/cloudflared-install.sh b/install/cloudflared-install.sh index dc792cee..abd45e47 100644 --- a/install/cloudflared-install.sh +++ b/install/cloudflared-install.sh @@ -32,6 +32,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/cronicle-install.sh b/install/cronicle-install.sh index 0763bdd8..c3ea5a8a 100644 --- a/install/cronicle-install.sh +++ b/install/cronicle-install.sh @@ -50,6 +50,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/dashy-install.sh b/install/dashy-install.sh index fce07cc5..d2bbc833 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -63,6 +63,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/debian-install.sh b/install/debian-install.sh index 18fd5940..bb89300e 100644 --- a/install/debian-install.sh +++ b/install/debian-install.sh @@ -23,6 +23,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" \ No newline at end of file diff --git a/install/deluge-install.sh b/install/deluge-install.sh index eceb49ce..a08580fc 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -71,6 +71,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/docker-install.sh b/install/docker-install.sh index 6744aac8..b6b110ae 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -76,6 +76,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/dockge-install.sh b/install/dockge-install.sh index 235ae6fd..3cb46245 100644 --- a/install/dockge-install.sh +++ b/install/dockge-install.sh @@ -82,6 +82,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/ersatztv-install.sh b/install/ersatztv-install.sh index 53a9c3ed..e4068612 100644 --- a/install/ersatztv-install.sh +++ b/install/ersatztv-install.sh @@ -59,6 +59,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/esphome-install.sh b/install/esphome-install.sh index 7c603425..a5732a84 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -54,6 +54,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/fhem-install.sh b/install/fhem-install.sh index ea98bf4d..ccc078fe 100644 --- a/install/fhem-install.sh +++ b/install/fhem-install.sh @@ -35,6 +35,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/flowiseai-install.sh b/install/flowiseai-install.sh index 0ac6e298..31807365 100644 --- a/install/flowiseai-install.sh +++ b/install/flowiseai-install.sh @@ -55,6 +55,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/frigate-install.sh b/install/frigate-install.sh index e5fe5f09..ed9be712 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -254,6 +254,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/go2rtc-install.sh b/install/go2rtc-install.sh index e50c6d76..8c5f1072 100644 --- a/install/go2rtc-install.sh +++ b/install/go2rtc-install.sh @@ -46,6 +46,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/gokapi-install.sh b/install/gokapi-install.sh index d207aaf0..26fe6338 100644 --- a/install/gokapi-install.sh +++ b/install/gokapi-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/gotify-install.sh b/install/gotify-install.sh index dfdd110b..674013f8 100644 --- a/install/gotify-install.sh +++ b/install/gotify-install.sh @@ -52,6 +52,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/grafana-install.sh b/install/grafana-install.sh index 81083b84..88627730 100644 --- a/install/grafana-install.sh +++ b/install/grafana-install.sh @@ -38,6 +38,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/heimdall-dashboard-install.sh b/install/heimdall-dashboard-install.sh index a7d87559..951bef8b 100644 --- a/install/heimdall-dashboard-install.sh +++ b/install/heimdall-dashboard-install.sh @@ -62,6 +62,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/homarr-install.sh b/install/homarr-install.sh index 2eb0ab4e..c1dcf22e 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -72,6 +72,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 99027611..126d62e4 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -102,6 +102,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 729fadeb..8d78d316 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -85,6 +85,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/homebridge-install.sh b/install/homebridge-install.sh index b18510ed..76ac86fc 100644 --- a/install/homebridge-install.sh +++ b/install/homebridge-install.sh @@ -35,6 +35,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 8d2bf340..4f6d5d91 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -69,6 +69,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/homer-install.sh b/install/homer-install.sh index 82071cf4..cab3080c 100644 --- a/install/homer-install.sh +++ b/install/homer-install.sh @@ -48,6 +48,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/hyperhdr-install.sh b/install/hyperhdr-install.sh index bca1ce2c..05759f54 100644 --- a/install/hyperhdr-install.sh +++ b/install/hyperhdr-install.sh @@ -50,6 +50,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh index 71e4e0f5..c43ba7fb 100644 --- a/install/influxdb-install.sh +++ b/install/influxdb-install.sh @@ -58,6 +58,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/iobroker-install.sh b/install/iobroker-install.sh index 09a59a58..8673c135 100644 --- a/install/iobroker-install.sh +++ b/install/iobroker-install.sh @@ -40,6 +40,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/jackett-install.sh b/install/jackett-install.sh index bb928687..36fcc7c0 100644 --- a/install/jackett-install.sh +++ b/install/jackett-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/jellyfin-install.sh b/install/jellyfin-install.sh index ab6bf92d..0b91e060 100644 --- a/install/jellyfin-install.sh +++ b/install/jellyfin-install.sh @@ -62,6 +62,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 7a0f1a2c..6cc2d14c 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -73,6 +73,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/k0s-install.sh b/install/k0s-install.sh index 14ec64cb..8ad44b52 100644 --- a/install/k0s-install.sh +++ b/install/k0s-install.sh @@ -38,6 +38,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/kavita-install.sh b/install/kavita-install.sh index 17e208ae..b354f171 100644 --- a/install/kavita-install.sh +++ b/install/kavita-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh index ea7d0f91..536a2bb8 100644 --- a/install/keycloak-install.sh +++ b/install/keycloak-install.sh @@ -47,6 +47,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/lazylibrarian-install.sh b/install/lazylibrarian-install.sh index 98595c26..ce10041e 100644 --- a/install/lazylibrarian-install.sh +++ b/install/lazylibrarian-install.sh @@ -55,6 +55,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh index c01c289f..eaae6bfd 100644 --- a/install/linkwarden-install.sh +++ b/install/linkwarden-install.sh @@ -107,6 +107,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/mafl-install.sh b/install/mafl-install.sh index 63f30288..da27b266 100644 --- a/install/mafl-install.sh +++ b/install/mafl-install.sh @@ -76,6 +76,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/magicmirror-install.sh b/install/magicmirror-install.sh index 5bb2e3f5..5ba0dff2 100644 --- a/install/magicmirror-install.sh +++ b/install/magicmirror-install.sh @@ -156,6 +156,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/mariadb-install.sh b/install/mariadb-install.sh index 047d1d05..46ecf9df 100644 --- a/install/mariadb-install.sh +++ b/install/mariadb-install.sh @@ -31,6 +31,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/mediamtx-install.sh b/install/mediamtx-install.sh index c41d4afd..66db3047 100644 --- a/install/mediamtx-install.sh +++ b/install/mediamtx-install.sh @@ -50,6 +50,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/medusa-install.sh b/install/medusa-install.sh index c2152c07..34bed0af 100644 --- a/install/medusa-install.sh +++ b/install/medusa-install.sh @@ -55,6 +55,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/meshcentral-install.sh b/install/meshcentral-install.sh index 13ac00db..c482f9a2 100644 --- a/install/meshcentral-install.sh +++ b/install/meshcentral-install.sh @@ -43,6 +43,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index e3908f4a..fe854002 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -57,6 +57,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/mqtt-install.sh b/install/mqtt-install.sh index 18362faa..61a01fbe 100644 --- a/install/mqtt-install.sh +++ b/install/mqtt-install.sh @@ -35,6 +35,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/n8n-install.sh b/install/n8n-install.sh index 32298692..811c166d 100644 --- a/install/n8n-install.sh +++ b/install/n8n-install.sh @@ -56,6 +56,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/nocodb-install.sh b/install/nocodb-install.sh index 3040f638..612d7983 100644 --- a/install/nocodb-install.sh +++ b/install/nocodb-install.sh @@ -47,6 +47,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/node-red-install.sh b/install/node-red-install.sh index 6da4981f..8ca280be 100644 --- a/install/node-red-install.sh +++ b/install/node-red-install.sh @@ -72,6 +72,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/ntfy-install.sh b/install/ntfy-install.sh index 2cdd985d..578e8966 100644 --- a/install/ntfy-install.sh +++ b/install/ntfy-install.sh @@ -34,6 +34,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh index fd093734..1cbcf0ae 100644 --- a/install/octoprint-install.sh +++ b/install/octoprint-install.sh @@ -74,6 +74,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/ombi-install.sh b/install/ombi-install.sh index ff313504..f42e528b 100644 --- a/install/ombi-install.sh +++ b/install/ombi-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/omv-install.sh b/install/omv-install.sh index 9ea46931..29482264 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -47,6 +47,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/openhab-install.sh b/install/openhab-install.sh index d21657e8..40661c6c 100644 --- a/install/openhab-install.sh +++ b/install/openhab-install.sh @@ -44,6 +44,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/openobserve-install.sh b/install/openobserve-install.sh index 7a52415d..7fff763e 100644 --- a/install/openobserve-install.sh +++ b/install/openobserve-install.sh @@ -55,6 +55,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/overseerr-install.sh b/install/overseerr-install.sh index 8d752044..dd65cd67 100644 --- a/install/overseerr-install.sh +++ b/install/overseerr-install.sh @@ -65,6 +65,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/owncast-install.sh b/install/owncast-install.sh index d03683e3..ca6f30c3 100644 --- a/install/owncast-install.sh +++ b/install/owncast-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/pairdrop-install.sh b/install/pairdrop-install.sh index 8f8a8224..75070cd7 100644 --- a/install/pairdrop-install.sh +++ b/install/pairdrop-install.sh @@ -59,6 +59,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/pbs-install.sh b/install/pbs-install.sh index 99203391..5f5dc017 100644 --- a/install/pbs-install.sh +++ b/install/pbs-install.sh @@ -32,6 +32,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index a7bec81f..e16cb6ee 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -76,6 +76,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/pialert-install.sh b/install/pialert-install.sh index 0376ce94..f90ea6b8 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -96,6 +96,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/pihole-install.sh b/install/pihole-install.sh index 52bb0b09..7f79ff8c 100644 --- a/install/pihole-install.sh +++ b/install/pihole-install.sh @@ -105,6 +105,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/pingvin-install.sh b/install/pingvin-install.sh index e271f9e1..c848cfb3 100644 --- a/install/pingvin-install.sh +++ b/install/pingvin-install.sh @@ -53,6 +53,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/plex-install.sh b/install/plex-install.sh index e253be5a..1ca8b0d9 100644 --- a/install/plex-install.sh +++ b/install/plex-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/podman-homeassistant-install.sh b/install/podman-homeassistant-install.sh index c74e27cc..a82d852e 100644 --- a/install/podman-homeassistant-install.sh +++ b/install/podman-homeassistant-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/podman-install.sh b/install/podman-install.sh index 78ae842f..1ef11fdd 100644 --- a/install/podman-install.sh +++ b/install/podman-install.sh @@ -29,6 +29,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/postgresql-install.sh b/install/postgresql-install.sh index 393d694a..3cf51532 100644 --- a/install/postgresql-install.sh +++ b/install/postgresql-install.sh @@ -146,6 +146,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/qbittorrent-install.sh b/install/qbittorrent-install.sh index 3c5b6469..a1c0064f 100644 --- a/install/qbittorrent-install.sh +++ b/install/qbittorrent-install.sh @@ -49,6 +49,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/rdtclient-install.sh b/install/rdtclient-install.sh index a077cb51..652998aa 100644 --- a/install/rdtclient-install.sh +++ b/install/rdtclient-install.sh @@ -58,6 +58,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/readeck-install.sh b/install/readeck-install.sh index 8b1c287b..dbc1d5e8 100644 --- a/install/readeck-install.sh +++ b/install/readeck-install.sh @@ -50,6 +50,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/redis-install.sh b/install/redis-install.sh index d62e7847..053e2088 100644 --- a/install/redis-install.sh +++ b/install/redis-install.sh @@ -35,6 +35,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/rtsptoweb-install.sh b/install/rtsptoweb-install.sh index a5b669d5..d8e5ecab 100644 --- a/install/rtsptoweb-install.sh +++ b/install/rtsptoweb-install.sh @@ -56,6 +56,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index b206c82f..63e919c9 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -62,6 +62,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 6e54f790..2ac2d72e 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -130,6 +130,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh index 4b9a51ab..82545835 100644 --- a/install/shinobi-install.sh +++ b/install/shinobi-install.sh @@ -80,6 +80,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/smokeping-install.sh b/install/smokeping-install.sh index 3a214b6c..0df5c842 100644 --- a/install/smokeping-install.sh +++ b/install/smokeping-install.sh @@ -72,6 +72,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/sonarr-install.sh b/install/sonarr-install.sh index 7f98864b..79060e79 100644 --- a/install/sonarr-install.sh +++ b/install/sonarr-install.sh @@ -51,6 +51,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/syncthing-install.sh b/install/syncthing-install.sh index 3709513c..11b45673 100644 --- a/install/syncthing-install.sh +++ b/install/syncthing-install.sh @@ -36,6 +36,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index e317b9ab..abbf06e7 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -141,6 +141,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/tasmoadmin-install.sh b/install/tasmoadmin-install.sh index bc934e24..f0302945 100644 --- a/install/tasmoadmin-install.sh +++ b/install/tasmoadmin-install.sh @@ -59,6 +59,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index d31ea075..d431918d 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -61,6 +61,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/technitiumdns-install.sh b/install/technitiumdns-install.sh index f157d841..12ea927d 100644 --- a/install/technitiumdns-install.sh +++ b/install/technitiumdns-install.sh @@ -35,6 +35,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/traccar-install.sh b/install/traccar-install.sh index 3a9b9eea..f68d365e 100644 --- a/install/traccar-install.sh +++ b/install/traccar-install.sh @@ -32,6 +32,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/transmission-install.sh b/install/transmission-install.sh index 10d90352..2550bb00 100644 --- a/install/transmission-install.sh +++ b/install/transmission-install.sh @@ -31,6 +31,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/ubuntu-install.sh b/install/ubuntu-install.sh index 9aa8705c..841dd3f3 100644 --- a/install/ubuntu-install.sh +++ b/install/ubuntu-install.sh @@ -23,6 +23,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/unifi-install.sh b/install/unifi-install.sh index 61460b7d..5341ee58 100644 --- a/install/unifi-install.sh +++ b/install/unifi-install.sh @@ -46,6 +46,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/unmanic-install.sh b/install/unmanic-install.sh index d5d1790a..70b73dc8 100644 --- a/install/unmanic-install.sh +++ b/install/unmanic-install.sh @@ -64,6 +64,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/uptimekuma-install.sh b/install/uptimekuma-install.sh index 8c4e90ea..4a429191 100644 --- a/install/uptimekuma-install.sh +++ b/install/uptimekuma-install.sh @@ -61,6 +61,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/vaultwarden-install.sh b/install/vaultwarden-install.sh index 64f8a460..c76297e3 100644 --- a/install/vaultwarden-install.sh +++ b/install/vaultwarden-install.sh @@ -114,6 +114,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/wastebin-install.sh b/install/wastebin-install.sh index 25e5b592..227b1095 100644 --- a/install/wastebin-install.sh +++ b/install/wastebin-install.sh @@ -62,6 +62,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/watchyourlan-install.sh b/install/watchyourlan-install.sh index 78fcf57a..c54342c5 100644 --- a/install/watchyourlan-install.sh +++ b/install/watchyourlan-install.sh @@ -52,6 +52,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index b1bdedbb..fac08400 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -48,6 +48,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/wikijs-install.sh b/install/wikijs-install.sh index 3a4507a3..fe95122e 100644 --- a/install/wikijs-install.sh +++ b/install/wikijs-install.sh @@ -78,6 +78,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/wireguard-install.sh b/install/wireguard-install.sh index 2b94a801..7cd00403 100644 --- a/install/wireguard-install.sh +++ b/install/wireguard-install.sh @@ -44,6 +44,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/yunohost-install.sh b/install/yunohost-install.sh index 0197eadb..75cdc55c 100644 --- a/install/yunohost-install.sh +++ b/install/yunohost-install.sh @@ -33,6 +33,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index fa94476f..55acdcbc 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -79,6 +79,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" From c476436a9d21be33979f91cd722c5a780bca87d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 16:40:23 -0400 Subject: [PATCH 6261/6505] Update omv-install.sh OMV 7 --- install/omv-install.sh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/install/omv-install.sh b/install/omv-install.sh index 29482264..64f6b955 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -17,22 +17,14 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y gnupg +$STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Installing OpenMediaVault (Patience)" wget -qO- https://packages.openmediavault.org/public/archive.key | gpg --dearmor >"/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.gpg" cat </etc/apt/sources.list.d/openmediavault.list -deb https://packages.openmediavault.org/public shaitan main -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main -## Uncomment the following line to add software from the proposed repository. -# deb https://packages.openmediavault.org/public shaitan-proposed main -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan-proposed main -## This software is not part of OpenMediaVault, but is offered by third-party -## developers as a service to OpenMediaVault users. -# deb https://packages.openmediavault.org/public shaitan partner -# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner +deb [signed-by=/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.gpg] http://packages.openmediavault.org/public sandworm main EOF export LANG=C.UTF-8 From 1320434a1a66c1e787e9a0932956282335f76e52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 16:40:57 -0400 Subject: [PATCH 6262/6505] Update omv.sh Default Debian 12 --- ct/omv.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omv.sh b/ct/omv.sh index 318a1699..525a35db 100644 --- a/ct/omv.sh +++ b/ct/omv.sh @@ -24,7 +24,7 @@ var_disk="4" var_cpu="2" var_ram="1024" var_os="debian" -var_version="11" +var_version="12" variables color catch_errors From 817d51a4eee4b92264ae99313724c3f56007be94 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 17:04:52 -0400 Subject: [PATCH 6263/6505] Update omv-install.sh tweak --- install/omv-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/omv-install.sh b/install/omv-install.sh index 64f6b955..2fb700ae 100644 --- a/install/omv-install.sh +++ b/install/omv-install.sh @@ -32,7 +32,7 @@ export DEBIAN_FRONTEND=noninteractive export APT_LISTCHANGES_FRONTEND=none $STD apt-get update apt-get -y --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends --option DPkg::Options::="--force-confdef" --option DPkg::Options::="--force-confold" install openmediavault-keyring openmediavault &>/dev/null -omv-confdbadm populate +omv-confdbadm populate &>/dev/null msg_ok "Installed OpenMediaVault" motd_ssh From 39d8721d367b7a5e5ee0045e13ac1c1834f2ab58 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 2 May 2024 17:20:44 -0400 Subject: [PATCH 6264/6505] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5237884c..9837da10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,14 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-02 + +### Changed + +- **OpenMediaVault LXC** + - Set Debian 12 as default + - OpenMediaVault 7 (sandworm) + ## 2024-04-30 ### Changed From 7faf0443b1106fe47b1f500940ea0607cb0563f2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 May 2024 03:02:49 -0400 Subject: [PATCH 6265/6505] Update alpine-grafana.sh Add storage --- ct/alpine-grafana.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index b7e89aba..97e5ebde 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -20,7 +20,7 @@ EOF header_info echo -e "Loading..." APP="Alpine-Grafana" -var_disk="0.5" +var_disk="1" var_cpu="1" var_ram="256" var_os="alpine" From c349da6859444c1f95b0b8c8ec61fdf1572d7a4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 May 2024 03:07:02 -0400 Subject: [PATCH 6266/6505] Update build.func Add Ubuntu 24.04 --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index f58149c1..ff2410c5 100644 --- a/misc/build.func +++ b/misc/build.func @@ -205,7 +205,7 @@ advanced_settings() { if var_version=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ "20.04" "Focal" OFF \ "22.04" "Jammy" OFF \ - "23.10" "Mantic" OFF \ + "24.04" "Noble" OFF \ 3>&1 1>&2 2>&3); then if [ -n "$var_version" ]; then echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}" From bb965d681caae2962573e008d4f5a5682a2079ff Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 May 2024 03:51:09 -0400 Subject: [PATCH 6267/6505] Update nginxproxymanager-install.sh Add back `python3-certbot-dns-cloudflare` --- install/nginxproxymanager-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 714aae70..ae267817 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -37,7 +37,8 @@ $STD apt-get install -y \ python3-pip \ python3-venv \ python3-cffi \ - python3-certbot + python3-certbot \ + python3-certbot-dns-cloudflare $STD pip3 install certbot-dns-multi $STD python3 -m venv /opt/certbot/ msg_ok "Installed Python Dependencies" From 6cb9e1db0aa317926e040ca53cb61adb821e0784 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 May 2024 05:32:14 -0400 Subject: [PATCH 6268/6505] Update flowiseai.sh fixes https://github.com/tteck/Proxmox/issues/2906 --- ct/flowiseai.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ct/flowiseai.sh b/ct/flowiseai.sh index 42c70fdd..4dc58f6b 100644 --- a/ct/flowiseai.sh +++ b/ct/flowiseai.sh @@ -20,8 +20,8 @@ header_info echo -e "Loading..." APP="FlowiseAI" var_disk="10" -var_cpu="2" -var_ram="2048" +var_cpu="4" +var_ram="4096" var_os="debian" var_version="12" variables @@ -67,6 +67,10 @@ start build_container description +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 2048 +pct set $CTID -cores 2 +msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" From 4a1ccb5d3dea601ef8d97d1719605d0b05a683cf Mon Sep 17 00:00:00 2001 From: Scorpoon <22363852+Scorpoon@users.noreply.github.com> Date: Sat, 4 May 2024 13:10:28 +0200 Subject: [PATCH 6269/6505] Write version into Homepage_version.txt file after update (#2908) --- ct/homepage.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homepage.sh b/ct/homepage.sh index dca0e9c4..54efa660 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -76,6 +76,7 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP} pnpm install pnpm build systemctl start homepage + echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated Homepage to v${RELEASE}" else msg_ok "No update required. ${APP} is already at ${RELEASE}" From dc222ec2517441521b1941ff5fe044382cb9e5a5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 4 May 2024 15:07:46 -0400 Subject: [PATCH 6270/6505] Update nginxproxymanager.sh Increase vCPUs to 2 during build --- ct/nginxproxymanager.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index a65e8623..75969716 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -21,7 +21,7 @@ header_info echo -e "Loading..." APP="Nginx Proxy Manager" var_disk="4" -var_cpu="1" +var_cpu="2" var_ram="1024" var_os="debian" var_version="12" @@ -185,6 +185,9 @@ start build_container description +msg_info "Setting Container to Normal Resources" +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:81${CL}\n" From 43ee7501adb36fceec6ae8207c271081e8e31888 Mon Sep 17 00:00:00 2001 From: Scorpoon <22363852+Scorpoon@users.noreply.github.com> Date: Sun, 5 May 2024 15:05:44 +0200 Subject: [PATCH 6271/6505] New LXC: Fenrus - another personal home page / dashboard (#2913) --- ct/fenrus.sh | 92 +++++++++++++++++++++++++++++++++++++++ install/fenrus-install.sh | 69 +++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 ct/fenrus.sh create mode 100644 install/fenrus-install.sh diff --git a/ct/fenrus.sh b/ct/fenrus.sh new file mode 100644 index 00000000..596f8f48 --- /dev/null +++ b/ct/fenrus.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: Scorpoon +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/revenz/Fenrus + +function header_info { +clear +cat <<"EOF" + ______ + / ____/__ ____ _______ _______ + / /_ / _ \/ __ \/ ___/ / / / ___/ + / __/ / __/ / / / / / /_/ (__ ) +/_/ \___/_/ /_/_/ \__,_/____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Fenrus" +var_disk="4" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/${APP} ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP}" +systemctl stop ${APP} +git clone https://github.com/revenz/Fenrus.git +cd Fenrus || exit +gitVersionNumber=$(git rev-parse HEAD) + +if [[ "${gitVersionNumber}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + mkdir /opt/fenrus-data-backup + cp -r "/opt/${APP}/data/" /opt/fenrus-data-backup/data + if [[ ! -d /opt/fenrus-data-backup/data ]]; then msg_error "Backup of data folder failed! exiting..."; rm -r /opt/fenrus-data-backup/; exit; fi + export DOTNET_CLI_TELEMETRY_OPTOUT=1 + dotnet publish -c Release -o "/opt/${APP}/" Fenrus.csproj + cp -r /opt/fenrus-data-backup/data/ "/opt/${APP}/" + echo "${gitVersionNumber}" >"/opt/${APP}_version.txt" + rm -r /opt/fenrus-data-backup/ + msg_ok "Updated $APP" +else + msg_ok "No update required. ${APP} is already up to date" +fi +cd .. +rm -r Fenrus/ + +systemctl start ${APP} +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:5000${CL} \n" \ No newline at end of file diff --git a/install/fenrus-install.sh b/install/fenrus-install.sh new file mode 100644 index 00000000..2ef110e6 --- /dev/null +++ b/install/fenrus-install.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: Scorpoon +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/revenz/Fenrus + + + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y curl +$STD apt-get install -y git +msg_ok "Installed Dependencies" + +msg_info "Installing ASP.NET Core 7 SDK" +var_os=$(grep "^ID=" /etc/os-release | cut -d'=' -f2 | tr -d '"') +var_version=$(grep "^VERSION_ID=" /etc/os-release | cut -d'=' -f2 | tr -d '"') +if [ "${var_os}" = "debian" ]; then + wget -q "https://packages.microsoft.com/config/debian/$var_version/packages-microsoft-prod.deb" + $STD dpkg -i packages-microsoft-prod.deb + rm packages-microsoft-prod.deb +fi +$STD apt-get update +$STD apt-get install -y dotnet-sdk-7.0 +msg_ok "Installed ASP.NET Core 7 SDK" + +msg_info "Installing ${APPLICATION}" +git clone -q https://github.com/revenz/Fenrus.git /opt/${APPLICATION} +cd /opt/${APPLICATION} +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +dotnet publish -c Release -o "/opt/${APPLICATION}/" Fenrus.csproj +msg_ok "Installed ${APPLICATION}" + +msg_info "Creating Service" +cat </etc/systemd/system/"${APPLICATION}".service +[Unit] +Description=${APPLICATION} + +[Service] +WorkingDirectory=/opt/${APPLICATION} +ExecStart=/usr/bin/dotnet Fenrus.dll --urls=http://*:5000 +SyslogIdentifier=${APPLICATION} +User=root + +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable -q --now ${APPLICATION} +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file From e4d8b624526121a6370927952d88a98fd283016e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 May 2024 09:06:59 -0400 Subject: [PATCH 6272/6505] Update fenrus.sh tweak --- ct/fenrus.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ct/fenrus.sh b/ct/fenrus.sh index 596f8f48..1b0e1848 100644 --- a/ct/fenrus.sh +++ b/ct/fenrus.sh @@ -5,7 +5,6 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build # Co-Author: Scorpoon # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE -# Source: https://github.com/revenz/Fenrus function header_info { clear @@ -89,4 +88,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:5000${CL} \n" \ No newline at end of file + ${BL}http://${IP}:5000${CL} \n" From b9cc6a09a3c5372417efdb6564e6c2c70f8970f7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 May 2024 09:16:40 -0400 Subject: [PATCH 6273/6505] Update fenrus-install.sh tweak --- install/fenrus-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/fenrus-install.sh b/install/fenrus-install.sh index 2ef110e6..4e4c249d 100644 --- a/install/fenrus-install.sh +++ b/install/fenrus-install.sh @@ -39,8 +39,8 @@ msg_ok "Installed ASP.NET Core 7 SDK" msg_info "Installing ${APPLICATION}" git clone -q https://github.com/revenz/Fenrus.git /opt/${APPLICATION} cd /opt/${APPLICATION} -export DOTNET_CLI_TELEMETRY_OPTOUT=1 -dotnet publish -c Release -o "/opt/${APPLICATION}/" Fenrus.csproj +#export DOTNET_CLI_TELEMETRY_OPTOUT=1 +$STD dotnet publish -c Release -o "/opt/${APPLICATION}/" Fenrus.csproj msg_ok "Installed ${APPLICATION}" msg_info "Creating Service" @@ -66,4 +66,4 @@ customize msg_info "Cleaning up" $STD apt-get -y autoremove $STD apt-get -y autoclean -msg_ok "Cleaned" \ No newline at end of file +msg_ok "Cleaned" From 410794f05554e3c719c204f7dc0bad9983a5bcff Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 May 2024 09:25:30 -0400 Subject: [PATCH 6274/6505] Update fenrus-install.sh tweak --- install/fenrus-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/fenrus-install.sh b/install/fenrus-install.sh index 4e4c249d..fa0f9500 100644 --- a/install/fenrus-install.sh +++ b/install/fenrus-install.sh @@ -39,7 +39,6 @@ msg_ok "Installed ASP.NET Core 7 SDK" msg_info "Installing ${APPLICATION}" git clone -q https://github.com/revenz/Fenrus.git /opt/${APPLICATION} cd /opt/${APPLICATION} -#export DOTNET_CLI_TELEMETRY_OPTOUT=1 $STD dotnet publish -c Release -o "/opt/${APPLICATION}/" Fenrus.csproj msg_ok "Installed ${APPLICATION}" From 3c463d4ce157f07451c044d26d5c26fbb81c05f9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 May 2024 09:29:21 -0400 Subject: [PATCH 6275/6505] Update fenrus.sh Add "There is currently no update path available." until fully tested --- ct/fenrus.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ct/fenrus.sh b/ct/fenrus.sh index 1b0e1848..0f5e4d17 100644 --- a/ct/fenrus.sh +++ b/ct/fenrus.sh @@ -9,12 +9,12 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - ______ + ______ / ____/__ ____ _______ _______ / /_ / _ \/ __ \/ ___/ / / / ___/ - / __/ / __/ / / / / / /_/ (__ ) -/_/ \___/_/ /_/_/ \__,_/____/ - + / __/ / __/ / / / / / /_/ (__ ) +/_/ \___/_/ /_/_/ \__,_/____/ + EOF } header_info @@ -56,6 +56,8 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/${APP} ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit msg_info "Updating ${APP}" systemctl stop ${APP} git clone https://github.com/revenz/Fenrus.git From 831d62390d36fc43ff444d5ecad1b2ac11aef06d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 May 2024 09:55:41 -0400 Subject: [PATCH 6276/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9837da10..bf0fb4a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-05 + +### Changed + +- **Fenrus LXC** + - NEW Script + ## 2024-05-02 ### Changed From a5c5628bed898f4ed0d23a220dd40656dab7da61 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 5 May 2024 14:29:05 -0400 Subject: [PATCH 6277/6505] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 733d43ad..86316b3f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2023 tteck +Copyright (c) 2021-2024 tteck Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 830fddb2a92236080f192966cc8185e7c0f09227 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 May 2024 13:23:52 -0400 Subject: [PATCH 6278/6505] Update wireguard.sh fixes https://github.com/tteck/Proxmox/issues/2919 --- ct/wireguard.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 1fb935f1..b8efa7cc 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -70,8 +70,8 @@ if [ "$UPD" == "2" ]; then if [[ -f /etc/systemd/system/wg-dashboard.service ]]; then msg_info "Updating WGDashboard" cd /etc/wgdashboard/src - yes "Y" | sudo ./wgd.sh update &>/dev/null - sudo chmod u+x wgd.sh + chmod u+x wgd.sh + ./wgd.sh update msg_ok "Updated Successfully" exit fi @@ -91,9 +91,9 @@ WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/lat git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null cd /etc/wgdashboard/src -sudo chmod u+x wgd.sh -sudo ./wgd.sh install &>/dev/null -sudo chmod -R 755 /etc/wireguard +chmod u+x wgd.sh +./wgd.sh install &>/dev/null +chmod -R 755 /etc/wireguard msg_ok "Installed WGDashboard" msg_info "Creating Service" From 5793283ea4b8e48daece9b55a7dcd392c6bcbc51 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 May 2024 13:25:19 -0400 Subject: [PATCH 6279/6505] Update wireguard.sh --- ct/wireguard.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index b8efa7cc..b5137ca6 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -68,7 +68,6 @@ exit fi if [ "$UPD" == "2" ]; then if [[ -f /etc/systemd/system/wg-dashboard.service ]]; then - msg_info "Updating WGDashboard" cd /etc/wgdashboard/src chmod u+x wgd.sh ./wgd.sh update From cfc6ca13effd79cdd8a27c31bb171f2b37f88491 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 6 May 2024 13:26:03 -0400 Subject: [PATCH 6280/6505] Update wireguard.sh tweak --- ct/wireguard.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index b5137ca6..23e75b80 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -63,7 +63,6 @@ if [ "$UPD" == "1" ]; then msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null -msg_ok "Updated Successfully" exit fi if [ "$UPD" == "2" ]; then From b950a06b5f1ef01e4500589502c708e3aa9b794e Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 11:41:57 -0400 Subject: [PATCH 6281/6505] Update paperless-ngx.sh Clean old code. --- ct/paperless-ngx.sh | 55 +++++++++------------------------------------ 1 file changed, 11 insertions(+), 44 deletions(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 4d05d1d2..7b5c8304 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -59,7 +59,6 @@ function update_script() { exit fi RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - SER=/etc/systemd/system/paperless-task-queue.service UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update Paperless-ngx to $RELEASE" ON \ @@ -67,64 +66,32 @@ function update_script() { 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then - msg_info "Stopping Paperless-ngx" - systemctl stop paperless-consumer paperless-webserver paperless-scheduler - if [ -f "$SER" ]; then - systemctl stop paperless-task-queue.service - fi - sleep 1 - msg_ok "Stopped Paperless-ngx" + echo -e "Stopping all Paperless-ngx Services" + systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service + msg_ok "Stopped all Paperless-ngx Services" - msg_info "Updating to ${RELEASE}" + echo -e "Updating to ${RELEASE}" cd ~ - if [ "$(dpkg -l | awk '/libmariadb-dev-compat/ {print }' | wc -l)" != 1 ]; then apt-get install -y libmariadb-dev-compat; fi &>/dev/null - wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz &>/dev/null - tar -xf paperless-ngx-$RELEASE.tar.xz &>/dev/null + wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz + tar -xf paperless-ngx-$RELEASE.tar.xz cp -r /opt/paperless/paperless.conf paperless-ngx/ cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless - pip install -r requirements.txt &>/dev/null + pip install -r requirements.txt cd /opt/paperless/src - /usr/bin/python3 manage.py migrate &>/dev/null - if [ -f "$SER" ]; then - msg_ok "paperless-task-queue.service Exists." - else - cat </etc/systemd/system/paperless-task-queue.service -[Unit] -Description=Paperless Celery Workers -Requires=redis.service -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless worker --loglevel INFO -[Install] -WantedBy=multi-user.target -EOF - systemctl enable paperless-task-queue &>/dev/null - msg_ok "paperless-task-queue.service Created." - fi - cat </etc/systemd/system/paperless-scheduler.service -[Unit] -Description=Paperless Celery beat -Requires=redis.service -[Service] -WorkingDirectory=/opt/paperless/src -ExecStart=celery --app paperless beat --loglevel INFO -[Install] -WantedBy=multi-user.target -EOF + /usr/bin/python3 manage.py migrate msg_ok "Updated to ${RELEASE}" - msg_info "Cleaning up" + echo -e "Cleaning up" cd ~ rm paperless-ngx-$RELEASE.tar.xz rm -rf paperless-ngx msg_ok "Cleaned" - msg_info "Starting Paperless-ngx" - systemctl daemon-reload + echo -e "Starting all Paperless-ngx Services" systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service sleep 1 - msg_ok "Started Paperless-ngx" + msg_ok "Started all Paperless-ngx Services" msg_ok "Updated Successfully!\n" exit fi From 3e6c0944fbec08c0e2cc3047d555bc20b0066719 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 12:13:47 -0400 Subject: [PATCH 6282/6505] Update paperless-ngx.sh test removing `migrate` --- ct/paperless-ngx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 7b5c8304..caaf0fe8 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -78,8 +78,8 @@ function update_script() { cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless pip install -r requirements.txt - cd /opt/paperless/src - /usr/bin/python3 manage.py migrate + #cd /opt/paperless/src + #/usr/bin/python3 manage.py migrate msg_ok "Updated to ${RELEASE}" echo -e "Cleaning up" From afd070a691460afeb2f0e31f835f1551a1585fe6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 12:35:00 -0400 Subject: [PATCH 6283/6505] Update paperless-ngx-install.sh set db to `utf8` --- install/paperless-ngx-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index d4b12ca9..b462cfd4 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -97,13 +97,15 @@ $STD python3 -m nltk.downloader -d /usr/share/nltk_data all msg_ok "Installed Natural Language Toolkit" msg_info "Setting up PostgreSQL database" -export LC_ALL=C.UTF-8 DB_NAME=paperlessdb DB_USER=paperless DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" echo "" >>~/paperless.creds echo -e "Paperless-ngx Database User: \e[32m$DB_USER\e[0m" >>~/paperless.creds echo -e "Paperless-ngx Database Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds From aa96a47efccdc123460d84b3e725c8fb77a3210a Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 12:40:52 -0400 Subject: [PATCH 6284/6505] Update paperless-ngx-install.sh tweak --- install/paperless-ngx-install.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index b462cfd4..23d8aa1b 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -13,15 +13,6 @@ setting_up_container network_check update_os -msg_info "Installing Python3" -$STD apt-get install -y --no-install-recommends \ - python3 \ - python3-pip \ - python3-dev \ - python3-setuptools \ - python3-wheel -msg_ok "Installed Python3" - msg_info "Installing Dependencies (Patience)" $STD apt-get install -y --no-install-recommends \ redis \ @@ -49,6 +40,15 @@ $STD apt-get install -y --no-install-recommends \ mc msg_ok "Installed Dependencies" +msg_info "Installing Python3 Dependencies" +$STD apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + python3-dev \ + python3-setuptools \ + python3-wheel +msg_ok "Installed Python3 Dependencies" + msg_info "Installing OCR Dependencies (Patience)" $STD apt-get install -y --no-install-recommends \ unpaper \ From e62f657d31b0095505b1c818b2366ca63bc6ad3f Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 12:54:28 -0400 Subject: [PATCH 6285/6505] Update paperless-ngx.sh set none verbose --- ct/paperless-ngx.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index caaf0fe8..fdb49961 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -66,29 +66,29 @@ function update_script() { 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then - echo -e "Stopping all Paperless-ngx Services" + msg_info "Stopping all Paperless-ngx Services" systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service msg_ok "Stopped all Paperless-ngx Services" - echo -e "Updating to ${RELEASE}" + msg_info "Updating to ${RELEASE}" cd ~ - wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz + wget -q https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz tar -xf paperless-ngx-$RELEASE.tar.xz cp -r /opt/paperless/paperless.conf paperless-ngx/ cp -r paperless-ngx/* /opt/paperless/ cd /opt/paperless - pip install -r requirements.txt - #cd /opt/paperless/src - #/usr/bin/python3 manage.py migrate + pip install -r requirements.txt &>/dev/null + cd /opt/paperless/src + /usr/bin/python3 manage.py migrate &>/dev/null msg_ok "Updated to ${RELEASE}" - echo -e "Cleaning up" + msg_info "Cleaning up" cd ~ rm paperless-ngx-$RELEASE.tar.xz rm -rf paperless-ngx msg_ok "Cleaned" - echo -e "Starting all Paperless-ngx Services" + msg_info "Starting all Paperless-ngx Services" systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service sleep 1 msg_ok "Started all Paperless-ngx Services" From 897c7bd867ce36b9595f78f9d6f45db6e616a455 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 13:12:26 -0400 Subject: [PATCH 6286/6505] Update frigate-install.sh another attempt to fix `Segmentation fault` --- install/frigate-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index ed9be712..b5b53ca7 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -43,8 +43,6 @@ if [[ "$CTTYPE" == "0" ]]; then chgrp video /dev/dri chmod 755 /dev/dri chmod 660 /dev/dri/* - $STD adduser $(id -u -n) video - $STD adduser $(id -u -n) render fi msg_ok "Set Up Hardware Acceleration" From 7924744bc25c3058cb38cc5c038483acbeecdc7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 14:01:21 -0400 Subject: [PATCH 6287/6505] Update omada.sh set default unprivileged --- ct/omada.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/omada.sh b/ct/omada.sh index c664953e..5c637de8 100644 --- a/ct/omada.sh +++ b/ct/omada.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="0" + CT_TYPE="1" PW="" CT_ID=$NEXTID HN=$NSAPP From 450c2a6d24b861f4e6269e6d22765ffdf20062c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 14:01:44 -0400 Subject: [PATCH 6288/6505] Update ubuntu.sh set default unprivileged --- ct/ubuntu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh index 6572c02c..448ca243 100644 --- a/ct/ubuntu.sh +++ b/ct/ubuntu.sh @@ -29,7 +29,7 @@ color catch_errors function default_settings() { - CT_TYPE="0" + CT_TYPE="1" PW="" CT_ID=$NEXTID HN=$NSAPP From 9b96a64401a6592d80f58eb9d0e4a8384912b9cc Mon Sep 17 00:00:00 2001 From: Bram Suurd <78373894+BramSuurdje@users.noreply.github.com> Date: Tue, 7 May 2024 23:13:55 +0200 Subject: [PATCH 6289/6505] Pocketbase LXC script (#2929) --- ct/pocketbase.sh | 62 +++++++++++++++++++++++++++++++++++ install/pocketbase-install.sh | 54 ++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 ct/pocketbase.sh create mode 100644 install/pocketbase-install.sh diff --git a/ct/pocketbase.sh b/ct/pocketbase.sh new file mode 100644 index 00000000..f3f8e7e0 --- /dev/null +++ b/ct/pocketbase.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ __ + ____ ____ _____/ /_____ / /_/ /_ ____ _________ + / __ \/ __ \/ ___/ //_/ _ \/ __/ __ \/ __ `/ ___/ _ \ + / /_/ / /_/ / /__/ ,< / __/ /_/ /_/ / /_/ (__ ) __/ + / .___/\____/\___/_/|_|\___/\__/_.___/\__,_/____/\___/ +/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Pocketbase" +var_disk="8" +var_cpu="1" +var_ram="512" +var_os="ubuntu" +var_version="22.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8080/_" diff --git a/install/pocketbase-install.sh b/install/pocketbase-install.sh new file mode 100644 index 00000000..29bf8813 --- /dev/null +++ b/install/pocketbase-install.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Pocketbase" +RELEASE=$(curl -s https://api.github.com/repos/pocketbase/pocketbase/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q https://github.com/pocketbase/pocketbase/releases/download/v${RELEASE}/pocketbase_${RELEASE}_linux_amd64.zip -O /tmp/pocketbase.zip +mkdir -p /opt/pocketbase/{pb_public,pb_migrations,pb_hooks} +unzip -q -o /tmp/pocketbase.zip -d /opt/pocketbase + +cat </etc/systemd/system/pocketbase.service +[Unit] +Description = pocketbase + +[Service] +Type = simple +LimitNOFILE = 4096 +Restart = always +RestartSec = 5s +StandardOutput = append:/opt/pocketbase/errors.log +StandardError = append:/opt/pocketbase/errors.log +ExecStart = /opt/pocketbase/pocketbase serve --http=0.0.0.0:8080 + +[Install] +WantedBy = multi-user.target +EOF + +systemctl enable -q --now pocketbase.service +msg_ok "Installed Pocketbase" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From c3cd3636e6f01be17faaa58b7b8e2d991fa648bc Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 17:19:03 -0400 Subject: [PATCH 6290/6505] Update pocketbase.sh tweak --- ct/pocketbase.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/pocketbase.sh b/ct/pocketbase.sh index f3f8e7e0..31e281ed 100644 --- a/ct/pocketbase.sh +++ b/ct/pocketbase.sh @@ -59,4 +59,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:8080/_" + ${BL}http://${IP}:8080/_${CL}" From 0209c9a7cd78adb50a1234a458573e8f518dc403 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 17:22:49 -0400 Subject: [PATCH 6291/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf0fb4a0..30f4dce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-07 + +### Changed + +- **pocketbase LXC** + - NEW Script + ## 2024-05-05 ### Changed From 4a3616692910fb31083e00bf6afaf3502ab30c47 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 17:25:53 -0400 Subject: [PATCH 6292/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30f4dce1..e50fb838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ ### Changed -- **pocketbase LXC** +- **Pocketbase LXC** - NEW Script ## 2024-05-05 From 1aff71d17f51b674c350f4a9f84ad8a5591e9224 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 7 May 2024 21:22:04 -0400 Subject: [PATCH 6293/6505] Update pocketbase.sh tweak --- ct/pocketbase.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ct/pocketbase.sh b/ct/pocketbase.sh index 31e281ed..df3858c3 100644 --- a/ct/pocketbase.sh +++ b/ct/pocketbase.sh @@ -8,12 +8,11 @@ source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build function header_info { clear cat <<"EOF" - __ __ __ - ____ ____ _____/ /_____ / /_/ /_ ____ _________ - / __ \/ __ \/ ___/ //_/ _ \/ __/ __ \/ __ `/ ___/ _ \ - / /_/ / /_/ / /__/ ,< / __/ /_/ /_/ / /_/ (__ ) __/ - / .___/\____/\___/_/|_|\___/\__/_.___/\__,_/____/\___/ -/_/ + ____ __ __ __ + / __ \____ _____/ /_____ / /_/ /_ ____ _________ + / /_/ / __ \/ ___/ //_/ _ \/ __/ __ \/ __ `/ ___/ _ \ + / ____/ /_/ / /__/ ,< / __/ /_/ /_/ / /_/ (__ ) __/ +/_/ \____/\___/_/|_|\___/\__/_.___/\__,_/____/\___/ EOF } From fc997a9f366abeb26d41b8306ee2c733234dbba7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 00:08:39 -0400 Subject: [PATCH 6294/6505] Create kernel-pin.sh --- misc/kernel-pin.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 misc/kernel-pin.sh diff --git a/misc/kernel-pin.sh b/misc/kernel-pin.sh new file mode 100644 index 00000000..a2a15ede --- /dev/null +++ b/misc/kernel-pin.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + __ __ __ ____ _ + / //_/__ _________ ___ / / / __ \(_)___ + / ,< / _ \/ ___/ __ \/ _ \/ / / /_/ / / __ \ + / /| / __/ / / / / / __/ / / ____/ / / / / +/_/ |_\___/_/ /_/ /_/\___/_/ /_/ /_/_/ /_/ + +EOF +} +YW=$(echo "\033[33m") +RD=$(echo "\033[01;31m") +GN=$(echo "\033[1;92m") +CL=$(echo "\033[m") +BFR="\\r\\033[K" +HOLD="-" +CM="${GN}✓${CL}" +current_kernel=$(uname -r) +available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 16, length($2)-22)}') +header_info + +function msg_info() { + local msg="$1" + echo -ne " ${HOLD} ${YW}${msg}..." +} + +function msg_ok() { + local msg="$1" + echo -e "${BFR} ${CM} ${GN}${msg}${CL}" +} + +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Pin" --yesno "This will Pin/Unpin Kernel Images, Proceed?" 10 68 || exit + + KERNEL_MENU=() + MSG_MAX_LENGTH=0 +while read -r TAG ITEM; do + OFFSET=2 + ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET + KERNEL_MENU+=("$TAG" "$ITEM " "OFF") +done < <(echo "$available_kernels") + +pin_kernel=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current Kernel $current_kernel" --radiolist "\nSelect Kernel to pin:\nCancel to Unpin any Kernel" 16 $((MSG_MAX_LENGTH + 58)) 6 "${KERNEL_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit +[ -z "$pin_kernel" ] && { + whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Kernel Selected" --msgbox "It appears that no Kernel was selected\nUnpinning any pinned Kernel" 10 68 + msg_info "Unpinning any Kernel" + proxmox-boot-tool kernel unpin &>/dev/null + msg_ok "Unpinned any Kernel\n" + proxmox-boot-tool kernel list + echo "" + msg_ok "Finished\n" + echo -e "${RD} REBOOT${CL}" + exit +} +whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE Kernel Pin" --yesno "Would you like to pin the $pin_kernel Kernel?" 10 68 || exit + +msg_info "Pinning $pin_kernel" +proxmox-boot-tool kernel pin $pin_kernel &>/dev/null +msg_ok "Successfully Pinned $pin_kernel\n" +proxmox-boot-tool kernel list +echo "" +msg_ok "Finished\n" +echo -e "${RD} REBOOT${CL}" From d5b91a44d0ff90ddedb01d43ba3b2e5910a1c6e9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 00:26:06 -0400 Subject: [PATCH 6295/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e50fb838..0321be19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-08 + +### Changed + +- **Kernel Pin** + - NEW Script + ## 2024-05-07 ### Changed From f830b228a80b6a0098649cee3ec1b544d8b1f100 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 01:18:26 -0400 Subject: [PATCH 6296/6505] Update homeassistant-core-install.sh Add Python wrapper for the Google WebRTC Voice Activity Detector --- install/homeassistant-core-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index 126d62e4..f9d8de47 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -74,6 +74,7 @@ cd /srv/homeassistant python3 -m venv . source bin/activate $STD pip install --upgrade pip +$STD pip install webrtcvad $STD python3 -m pip install wheel $STD pip install homeassistant $STD pip install mysqlclient From ee97a5f73440bde6ab1913f3c9c0a967d7272f35 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 01:22:57 -0400 Subject: [PATCH 6297/6505] Update homeassistant-core-install.sh Make changes to use Ubuntu 24.04 only --- install/homeassistant-core-install.sh | 56 +-------------------------- 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index f9d8de47..abaee900 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -14,66 +14,14 @@ network_check update_os msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y \ - git \ - curl \ - sudo \ - mc \ - bluez \ - libffi-dev \ - libssl-dev \ - libjpeg-dev \ - zlib1g-dev \ - autoconf \ - build-essential \ - libopenjp2-7 \ - libturbojpeg0-dev \ - ffmpeg \ - liblapack3 \ - liblapack-dev \ - dbus-broker \ - libpcap-dev \ - libavdevice-dev \ - libavformat-dev \ - libavcodec-dev \ - libavutil-dev \ - libavfilter-dev \ - libmariadb-dev-compat \ - libatlas-base-dev +$STD apt-get install -y {git,curl,sudo,mc,bluez,libffi-dev,libssl-dev,libjpeg-dev,zlib1g-dev,autoconf,build-essential,libopenjp2-7,libturbojpeg0-dev,ffmpeg,liblapack3,liblapack-dev,dbus-broker,libpcap-dev,libavdevice-dev,libavformat-dev,libavcodec-dev,libavutil-dev,libavfilter-dev,libmariadb-dev-compat,libatlas-base-dev,python3-pip,python3.12-venv} msg_ok "Installed Dependencies" -#RELEASE=$(curl -s https://www.python.org/downloads/ | grep -oP 'Download Python \K\d+\.\d+\.\d+' | head -1) - -msg_info "Compiling Python 3.12 from its source (Additional Patience)" -$STD apt-get remove -y python3 -$STD apt-get install -y \ - checkinstall \ - libreadline-dev \ - libncursesw5-dev \ - libssl-dev \ - libsqlite3-dev \ - tk-dev \ - libgdbm-dev \ - libc6-dev \ - libbz2-dev - -#wget -qO- https://www.python.org/ftp/python/${RELEASE}/Python-${RELEASE}.tar.xz | tar -xJ -wget -qO- https://www.python.org/ftp/python/3.12.2/Python-3.12.2.tar.xz | tar -xJ -cd Python-3.12.2 -$STD ./configure --enable-optimizations -$STD make -j $(nproc) -$STD make altinstall -$STD update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.12 1 -cd ~ -rm -rf Python-3.12.2 -msg_ok "Installed Python 3.12" - msg_info "Installing Home Assistant-Core" mkdir /srv/homeassistant cd /srv/homeassistant python3 -m venv . source bin/activate -$STD pip install --upgrade pip $STD pip install webrtcvad $STD python3 -m pip install wheel $STD pip install homeassistant @@ -96,7 +44,7 @@ RestartForceExitStatus=100 [Install] WantedBy=multi-user.target EOF -$STD systemctl enable --now homeassistant +systemctl enable -q --now homeassistant msg_ok "Created Service" motd_ssh From 497994381f2a65259cd313a20045a6a65ad9daae Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 01:23:59 -0400 Subject: [PATCH 6298/6505] Update homeassistant-core.sh Default Ubuntu 24.04 --- ct/homeassistant-core.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh index 738e2ea1..01c1c36f 100644 --- a/ct/homeassistant-core.sh +++ b/ct/homeassistant-core.sh @@ -22,8 +22,8 @@ APP="Home Assistant-Core" var_disk="8" var_cpu="2" var_ram="1024" -var_os="debian" -var_version="12" +var_os="ubuntu" +var_version="24.04" variables color catch_errors From 98aaaf5bd1bb50f8da0b6aa02ace05e810d97400 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 01:34:34 -0400 Subject: [PATCH 6299/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0321be19..4433fd31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - **Kernel Pin** - NEW Script +- **Home Assistant Core LXC** + - Ubuntu 24.04 ONLY ## 2024-05-07 From c1a3b142b038430c8e3dd1436fcc19bb58fcda53 Mon Sep 17 00:00:00 2001 From: Davide Alberani Date: Wed, 8 May 2024 15:43:17 +0200 Subject: [PATCH 6300/6505] avoid warning messages in cron logs (#2932) --- misc/update-lxcs-cron.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs-cron.sh b/misc/update-lxcs-cron.sh index de5fded8..ebd6e972 100644 --- a/misc/update-lxcs-cron.sh +++ b/misc/update-lxcs-cron.sh @@ -22,7 +22,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt-get upgrade --dry-run && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y" ;; esac } From 0a392dc70ae4b0b337e7a03617d0385d31728c83 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 10:03:34 -0400 Subject: [PATCH 6301/6505] Delete misc/edge-kernel.sh No longer needed --- misc/edge-kernel.sh | 168 -------------------------------------------- 1 file changed, 168 deletions(-) delete mode 100644 misc/edge-kernel.sh diff --git a/misc/edge-kernel.sh b/misc/edge-kernel.sh deleted file mode 100644 index fa24386d..00000000 --- a/misc/edge-kernel.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2024 tteck -# Author: tteck (tteckster) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -# bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/edge-kernel.sh)" -function header_info { -cat <<"EOF" - ____ _ ________ ______ __ __ __ __ - / __ \ | / / ____/ / ____/___/ /___ ____ / //_/__ _________ ___ / /____ - / /_/ / | / / __/ / __/ / __ / __ `/ _ \ / ,< / _ \/ ___/ __ \/ _ \/ / ___/ - / ____/| |/ / /___ / /___/ /_/ / /_/ / __/ / /| / __/ / / / / / __/ (__ ) -/_/ |___/_____/ /_____/\__,_/\__, /\___/ /_/ |_\___/_/ /_/ /_/\___/_/____/ - /____/ - -EOF -} -set -e -KERNEL_ON=$(uname -r) -PVE_KERNEL=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) -EDGE_KERNEL=$(dpkg --list | grep 'kernel-.*-edge' | awk '{print substr($2, 12, length($2)-1) }' | tac | head -n 1) -VER=$(curl -s https://api.github.com/repos/fabianishere/pve-edge-kernel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-9) }') -KER=$(curl -s https://api.github.com/repos/fabianishere/pve-edge-kernel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-6) }') -clear -header_info -while true; do - read -p "This is a Proxmox Edge Kernel Tool, USE AT YOUR OWN RISK. Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac -done -clear -header_info -show_menu() { - normal=$(echo "\033[m") - safe=$(echo "\033[32m") - menu=$(echo "\033[36m") - number=$(echo "\033[33m") - bgred=$(echo "\033[41m") - fgred=$(echo "\033[31m") - proxmox-boot-tool kernel list - echo -e "\nCurrent Kernel: ${menu}${KERNEL_ON}${normal}" - printf "\n${menu}*********************************************${normal}\n" - printf "${menu}**${number} 1)${normal} Install Proxmox Edge Kernel ${menu}${KER}${normal} & Reboot\n" - printf "${menu}**${number} 2)${normal} Switch to Proxmox VE 7 ${menu}${PVE_KERNEL}${normal} Kernel & Reboot\n" - printf "${menu}**${number} 3)${normal} Switch to Proxmox Edge ${menu}${EDGE_KERNEL}${normal} Kernel & Reboot\n" - printf "${menu}**${number} 4)${normal} Unpin Current Kernel\n" - printf "${menu}**${number} 5)${normal} Remove All Current ${menu}${VER}*${normal} Proxmox Edge Kernels & Reboot\n" - printf "${menu}*********************************************${normal}\n" - printf "Please choose an option from the menu, or ${fgred}x${normal} to exit." - read opt -} -option_picked() { - msgcolor=$(echo "\033[01;31m") - normal=$(echo "\033[00;00m") - message=${@:-"${normal}Error: No message passed"} - printf "${msgcolor}${message}${normal}\n" -} -clear -header_info -show_menu -while [ "$opt" != "" ]; do - if [ "$opt" = "" ]; then - exit - else - case $opt in - 1) - while true; do - read -p "Are you sure you want to Install Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac - done - clear - option_picked "Installing Proxmox Edge Kernel & Rebooting" - apt-get install -y gnupg - curl -1sLf 'https://dl.cloudsmith.io/public/pve-edge/kernel/gpg.8EC01CCF309B98E7.key' | apt-key add - - echo "deb https://dl.cloudsmith.io/public/pve-edge/kernel/deb/debian bullseye main" >/etc/apt/sources.list.d/pve-edge-kernel.list - apt-get -y update - apt-get -y install pve-kernel-${VER}-edge - reboot - break - ;; - 2) - while true; do - read -p "Are you sure you want to Switch to Proxmox VE 7 ${PVE_KERNEL} Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac - done - clear - option_picked "Switching to Proxmox VE 7 Kernel & Rebooting" - proxmox-boot-tool kernel pin ${PVE_KERNEL} - reboot - break - ;; - 3) - while true; do - read -p "Are you sure you want to Switch to Proxmox ${EDGE_KERNEL} Edge Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac - done - clear - option_picked "Switching to Proxmox Edge Kernel & Rebooting" - proxmox-boot-tool kernel pin ${EDGE_KERNEL} - reboot - break - ;; - 4) - while true; do - read -p "Are you sure you want to Unpin the Current Kernel? Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac - done - clear - option_picked "Unpinning Current Kernel" - proxmox-boot-tool kernel unpin - clear - break - ;; - 5) - while true; do - read -p "Are you sure you want to Remove Proxmox Edge Kernel & Reboot? Proceed(y/n)?" yn - case $yn in - [Yy]*) break ;; - [Nn]*) exit ;; - *) echo "Please answer yes or no." ;; - esac - done - clear - option_picked "Removing Proxmox Edge Kernel & Rebooting" - apt --purge remove -y pve-kernel-${VER}*edge pve-headers-${VER}*edge - rm -rf /etc/apt/sources.list.d/pve-edge-kernel.list - proxmox-boot-tool kernel unpin - reboot - break - ;; - x) - exit - ;; - \n) - exit - ;; - *) - clear - option_picked "Please choose an option from the menu" - header_info - show_menu - ;; - esac - fi -done -header_info -show_menu From c13b868ddaf4ac13a589c6176bd383a0fa2c3aed Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 12:40:27 -0400 Subject: [PATCH 6302/6505] Update paperless-ngx-install.sh ensure UTF8 --- install/paperless-ngx-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 23d8aa1b..2dfee033 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -102,7 +102,7 @@ DB_USER=paperless DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" -$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" From d0439cde1cc908faffcc49413f7aca4d05df57a0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 13:30:07 -0400 Subject: [PATCH 6303/6505] Update paperless-ngx-install.sh tweak --- install/paperless-ngx-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 2dfee033..44df6824 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -90,6 +90,7 @@ sed -i -e "s|#PAPERLESS_CONSUMPTION_DIR=../consume|PAPERLESS_CONSUMPTION_DIR=/op sed -i -e "s|#PAPERLESS_DATA_DIR=../data|PAPERLESS_DATA_DIR=/opt/paperless/data|" /opt/paperless/paperless.conf sed -i -e "s|#PAPERLESS_MEDIA_ROOT=../media|PAPERLESS_MEDIA_ROOT=/opt/paperless/media|" /opt/paperless/paperless.conf sed -i -e "s|#PAPERLESS_STATICDIR=../static|PAPERLESS_STATICDIR=/opt/paperless/static|" /opt/paperless/paperless.conf +echo "${Paperlessngx}" >/opt/${APPLICATION}_version.txt msg_ok "Installed Paperless-ngx" msg_info "Installing Natural Language Toolkit (Patience)" From 5204ad7e16cd9c7cbed5850e89a04ea8e52c07cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 13:34:01 -0400 Subject: [PATCH 6304/6505] Update paperless-ngx.sh add version check --- ct/paperless-ngx.sh | 52 ++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index fdb49961..0e3b90d5 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -66,33 +66,37 @@ function update_script() { 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then - msg_info "Stopping all Paperless-ngx Services" - systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service - msg_ok "Stopped all Paperless-ngx Services" + if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Stopping all Paperless-ngx Services" + systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service + msg_ok "Stopped all Paperless-ngx Services" - msg_info "Updating to ${RELEASE}" - cd ~ - wget -q https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz - tar -xf paperless-ngx-$RELEASE.tar.xz - cp -r /opt/paperless/paperless.conf paperless-ngx/ - cp -r paperless-ngx/* /opt/paperless/ - cd /opt/paperless - pip install -r requirements.txt &>/dev/null - cd /opt/paperless/src - /usr/bin/python3 manage.py migrate &>/dev/null - msg_ok "Updated to ${RELEASE}" + msg_info "Updating to ${RELEASE}" + cd ~ + wget -q https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz + tar -xf paperless-ngx-$RELEASE.tar.xz + cp -r /opt/paperless/paperless.conf paperless-ngx/ + cp -r paperless-ngx/* /opt/paperless/ + cd /opt/paperless + pip install -r requirements.txt &>/dev/null + cd /opt/paperless/src + /usr/bin/python3 manage.py migrate &>/dev/null + msg_ok "Updated to ${RELEASE}" - msg_info "Cleaning up" - cd ~ - rm paperless-ngx-$RELEASE.tar.xz - rm -rf paperless-ngx - msg_ok "Cleaned" + msg_info "Cleaning up" + cd ~ + rm paperless-ngx-$RELEASE.tar.xz + rm -rf paperless-ngx + msg_ok "Cleaned" - msg_info "Starting all Paperless-ngx Services" - systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service - sleep 1 - msg_ok "Started all Paperless-ngx Services" - msg_ok "Updated Successfully!\n" + msg_info "Starting all Paperless-ngx Services" + systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service + sleep 1 + msg_ok "Started all Paperless-ngx Services" + msg_ok "Updated Successfully!\n" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi exit fi if [ "$UPD" == "2" ]; then From ef4d18f8705a22d1b8f2e8152bd5b4a2b60cfc5b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 13:48:08 -0400 Subject: [PATCH 6305/6505] Update paperless-ngx.sh tweak --- ct/paperless-ngx.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 0e3b90d5..d23986b1 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -81,6 +81,7 @@ function update_script() { pip install -r requirements.txt &>/dev/null cd /opt/paperless/src /usr/bin/python3 manage.py migrate &>/dev/null + echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated to ${RELEASE}" msg_info "Cleaning up" From bd94aad7fa7d54f75c680af47fb01896046d9d8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 14:42:24 -0400 Subject: [PATCH 6306/6505] Update paperless-ngx.sh tweak --- ct/paperless-ngx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index d23986b1..07badf17 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -66,7 +66,7 @@ function update_script() { 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then - if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt 2>/dev/null ]]; then msg_info "Stopping all Paperless-ngx Services" systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service msg_ok "Stopped all Paperless-ngx Services" From d46076cab98ea07325e767d1668efd5a8be01266 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 8 May 2024 15:48:02 -0400 Subject: [PATCH 6307/6505] Update paperless-ngx.sh - fix syntax error in conditional expression - fixes https://github.com/tteck/Proxmox/issues/2938 --- ct/paperless-ngx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh index 07badf17..d23986b1 100644 --- a/ct/paperless-ngx.sh +++ b/ct/paperless-ngx.sh @@ -66,7 +66,7 @@ function update_script() { 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then - if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt 2>/dev/null ]]; then + if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then msg_info "Stopping all Paperless-ngx Services" systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service msg_ok "Stopped all Paperless-ngx Services" From bd564168981e62973670de354de496b04ede9efb Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 03:32:09 -0400 Subject: [PATCH 6308/6505] Update bug_report.yaml tweak --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 3789546e..26e62e89 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -48,7 +48,7 @@ body: - Debian 12 - Ubuntu 20.04 - Ubuntu 22.04 - - Ubuntu 23.10 + - Ubuntu 24.04 - type: textarea id: screenshot attributes: From 12bd10bef3a2682acc1868960ef219ad49b6cc9a Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 09:13:13 -0400 Subject: [PATCH 6309/6505] Update wireguard.sh "There is currently no update path available." --- ct/wireguard.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index 23e75b80..f2dc848a 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -60,9 +60,7 @@ UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radio 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null +msg_error "There is currently no update path available." exit fi if [ "$UPD" == "2" ]; then From 0e01ceb460c72f096402c4f44e67471de6ef6628 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 09:26:17 -0400 Subject: [PATCH 6310/6505] Update wireguard.sh fix update --- ct/wireguard.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ct/wireguard.sh b/ct/wireguard.sh index f2dc848a..5feee4ac 100644 --- a/ct/wireguard.sh +++ b/ct/wireguard.sh @@ -60,7 +60,10 @@ UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radio 3>&1 1>&2 2>&3) header_info if [ "$UPD" == "1" ]; then -msg_error "There is currently no update path available." +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated ${APP} LXC" exit fi if [ "$UPD" == "2" ]; then From 91985329f6ec95cc969f8af27ac319daf442d941 Mon Sep 17 00:00:00 2001 From: Bram Suurd <78373894+BramSuurdje@users.noreply.github.com> Date: Thu, 9 May 2024 18:01:00 +0200 Subject: [PATCH 6311/6505] New LXC: umami (#2946) --- ct/umami.sh | 61 ++++++++++++++++++++++++++++ install/umami-install.sh | 85 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 ct/umami.sh create mode 100644 install/umami-install.sh diff --git a/ct/umami.sh b/ct/umami.sh new file mode 100644 index 00000000..312a504f --- /dev/null +++ b/ct/umami.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ + __ ______ ___ ____ _____ ___ (_) + / / / / __ `__ \/ __ `/ __ `__ \/ / +/ /_/ / / / / / / /_/ / / / / / / / +\__,_/_/ /_/ /_/\__,_/_/ /_/ /_/_/ + +EOF +} +header_info +echo -e "Loading..." +APP="umami" +var_disk="8" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" \ No newline at end of file diff --git a/install/umami-install.sh b/install/umami-install.sh new file mode 100644 index 00000000..ce8f008d --- /dev/null +++ b/install/umami-install.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y gpg +$STD apt-get install -y postgresql +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +$STD npm install -g yarn +msg_ok "Installed Node.js" + +msg_info "Setting up postgresql" +DB_NAME=umamidb +DB_USER=umami +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" +sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" +sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" +sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" +sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" +echo "" >umami.creds +echo -e "umami Database User: \e[32m$DB_USER\e[0m" >>umami.creds +echo -e "umami Database Password: \e[32m$DB_PASS\e[0m" >>umami.creds +echo -e "umami Database Name: \e[32m$DB_NAME\e[0m" >>umami.creds +msg_ok "Set up postgresql" + +msg_info "Installing Umami (Patience)" +git clone -q https://github.com/umami-software/umami.git /opt/umami +cd /opt/umami +$STD yarn install +echo -e "DATABASE_URL=postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME" >>/opt/umami/.env +$STD yarn run build +msg_ok "Installed Umami" + +msg_info "Creating Service" +cat </etc/systemd/system/umami.service +echo "[Unit] +Description=umami + +[Service] +Type=simple +Restart=always +User=root +WorkingDirectory=/opt/umami +ExecStart=/usr/bin/yarn run start + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now umami.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file From 9483d83c5ed4a4d1168448a8e98a223bb225d484 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 12:08:07 -0400 Subject: [PATCH 6312/6505] Update umami-install.sh silent postgres commands --- install/umami-install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install/umami-install.sh b/install/umami-install.sh index ce8f008d..1ac1c1ca 100644 --- a/install/umami-install.sh +++ b/install/umami-install.sh @@ -39,11 +39,11 @@ DB_NAME=umamidb DB_USER=umami DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" -sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" -sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" -sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" -sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" -sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" +$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" echo "" >umami.creds echo -e "umami Database User: \e[32m$DB_USER\e[0m" >>umami.creds echo -e "umami Database Password: \e[32m$DB_PASS\e[0m" >>umami.creds @@ -82,4 +82,4 @@ customize msg_info "Cleaning up" $STD apt-get -y autoremove $STD apt-get -y autoclean -msg_ok "Cleaned" \ No newline at end of file +msg_ok "Cleaned" From afe90a8417912d543e5aa0fafe5fd77a8c9c6cca Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 12:11:23 -0400 Subject: [PATCH 6313/6505] Update umami.sh adjust resources --- ct/umami.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/umami.sh b/ct/umami.sh index 312a504f..c921f892 100644 --- a/ct/umami.sh +++ b/ct/umami.sh @@ -19,9 +19,9 @@ EOF header_info echo -e "Loading..." APP="umami" -var_disk="8" -var_cpu="1" -var_ram="512" +var_disk="12" +var_cpu="2" +var_ram="1024" var_os="debian" var_version="12" variables @@ -58,4 +58,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. - ${BL}http://${IP}:3000${CL} \n" \ No newline at end of file + ${BL}http://${IP}:3000${CL} \n" From f8b5fbe3deb2a4f68fbef4bae941c071f354fbec Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 12:25:01 -0400 Subject: [PATCH 6314/6505] Update umami.sh adjust resources for the build --- ct/umami.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ct/umami.sh b/ct/umami.sh index c921f892..3ea2d323 100644 --- a/ct/umami.sh +++ b/ct/umami.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="umami" var_disk="12" var_cpu="2" -var_ram="1024" +var_ram="2048" var_os="debian" var_version="12" variables @@ -56,6 +56,10 @@ start build_container description +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 1024 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:3000${CL} \n" From 5ecfd4e1b5dfdc707756ab732e9546ffde3a5f6d Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 13:07:09 -0400 Subject: [PATCH 6315/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4433fd31..d1e6b77f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-09 + +### Changed + +- **Umami LXC** + - NEW Script + ## 2024-05-08 ### Changed From 4bce8ff991850a463905e614a8f1ec1864f1347b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 9 May 2024 15:02:29 -0400 Subject: [PATCH 6316/6505] Update install.func tweak --- misc/install.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/install.func b/misc/install.func index ab0b7d5d..80a5c2e2 100644 --- a/misc/install.func +++ b/misc/install.func @@ -171,7 +171,7 @@ EOF # This function modifies the message of the day (motd) and SSH settings motd_ssh() { echo "export TERM='xterm-256color'" >>/root/.bashrc - echo -e "$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\n" >/etc/motd + echo -e "$APPLICATION LXC provided by https://helper-scripts.com/\n" >/etc/motd chmod -x /etc/update-motd.d/* if [[ "${SSH_ROOT}" == "yes" ]]; then sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config From 549f8484109ab747b00c120307de7f46158b8c8c Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 May 2024 14:21:33 -0400 Subject: [PATCH 6317/6505] Update umami.sh tweak --- ct/umami.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/umami.sh b/ct/umami.sh index 3ea2d323..9f94d0b9 100644 --- a/ct/umami.sh +++ b/ct/umami.sh @@ -18,7 +18,7 @@ EOF } header_info echo -e "Loading..." -APP="umami" +APP="Umami" var_disk="12" var_cpu="2" var_ram="2048" From d80084b9a6694f564d0393dbaae35a18eb2207f1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 10 May 2024 18:00:42 -0400 Subject: [PATCH 6318/6505] Update pocketbase.sh switch distribution to Debian 12 --- ct/pocketbase.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/pocketbase.sh b/ct/pocketbase.sh index df3858c3..d7cae744 100644 --- a/ct/pocketbase.sh +++ b/ct/pocketbase.sh @@ -22,8 +22,8 @@ APP="Pocketbase" var_disk="8" var_cpu="1" var_ram="512" -var_os="ubuntu" -var_version="22.04" +var_os="debian" +var_version="12" variables color catch_errors From f1ef008fccbcaad09da7fadc855f646ce73ef737 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 May 2024 19:22:24 -0400 Subject: [PATCH 6319/6505] Create caddy-install.sh --- install/caddy-install.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 install/caddy-install.sh diff --git a/install/caddy-install.sh b/install/caddy-install.sh new file mode 100644 index 00000000..88fb8b1a --- /dev/null +++ b/install/caddy-install.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y {debian-keyring,debian-archive-keyring,apt-transport-https,gpg,curl,sudo,mc} +msg_ok "Installed Dependencies" + +msg_info "Installing Caddy" +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' >/etc/apt/sources.list.d/caddy-stable.list +$STD apt-get update +$STD apt-get install -y caddy +msg_ok "Installed Caddy" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 9a3f19eece34b94375f84b4f2ccca0819cf39aa6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 May 2024 19:23:25 -0400 Subject: [PATCH 6320/6505] Create caddy.sh --- ct/caddy.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ct/caddy.sh diff --git a/ct/caddy.sh b/ct/caddy.sh new file mode 100644 index 00000000..6df98d39 --- /dev/null +++ b/ct/caddy.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ __ __ + / ____/___ _____/ /___/ /_ __ + / / / __ `/ __ / __ / / / / +/ /___/ /_/ / /_/ / /_/ / /_/ / +\____/\__,_/\__,_/\__,_/\__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Caddy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /etc/caddy ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" From 3fb1a23cd3e67eae21b96d4ce33f6f1f9749648d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 11 May 2024 19:29:59 -0400 Subject: [PATCH 6321/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1e6b77f..4664ad7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-11 + +### Changed + +- **Caddy LXC** + - NEW Script + ## 2024-05-09 ### Changed From 218c3b2cc97acc284e4a30e32f620b0699e2b27a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 12 May 2024 06:36:55 -0400 Subject: [PATCH 6322/6505] Update zoraxy.sh Adjust build resources --- ct/zoraxy.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh index 8d3a771b..efcd250a 100644 --- a/ct/zoraxy.sh +++ b/ct/zoraxy.sh @@ -19,8 +19,8 @@ EOF header_info echo -e "Loading..." APP="Zoraxy" -var_disk="4" -var_cpu="2" +var_disk="6" +var_cpu="4" var_ram="2048" var_os="debian" var_version="12" @@ -63,6 +63,9 @@ start build_container description +msg_info "Setting Container to Normal Resources" +pct set $CTID -cores 2 +msg_ok "Set Container to Normal Resources" msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:8000${CL} \n" From 368e8f2d58ba1fa0743452dd071b4eb18eda0caf Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 May 2024 05:28:18 -0400 Subject: [PATCH 6323/6505] Create headscale-install.sh --- install/headscale-install.sh | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 install/headscale-install.sh diff --git a/install/headscale-install.sh b/install/headscale-install.sh new file mode 100644 index 00000000..cead9fb7 --- /dev/null +++ b/install/headscale-install.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/juanfont/headscale/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Installing ${APPLICATION} v${RELEASE}" +wget -q https://github.com/juanfont/headscale/releases/download/v${RELEASE}/headscale_${RELEASE}_linux_amd64.deb +$STD dpkg -i headscale_${RELEASE}_linux_amd64.deb +systemctl enable -q --now headscale +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed ${APPLICATION} v${RELEASE}" + +motd_ssh +customize + +msg_info "Cleaning up" +rm headscale_${RELEASE}_linux_amd64.deb +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 12173c3d14b4de234bcc0a9e7e032690ac0b4901 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 May 2024 05:29:24 -0400 Subject: [PATCH 6324/6505] Create headscale.sh --- ct/headscale.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 ct/headscale.sh diff --git a/ct/headscale.sh b/ct/headscale.sh new file mode 100644 index 00000000..f50347eb --- /dev/null +++ b/ct/headscale.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ __ __ + / / / /__ ____ _____/ /_____________ _/ /__ + / /_/ / _ \/ __ `/ __ / ___/ ___/ __ `/ / _ \ + / __ / __/ /_/ / /_/ (__ ) /__/ /_/ / / __/ +/_/ /_/\___/\__,_/\__,_/____/\___/\__,_/_/\___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Headscale" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /etc/headscale ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + +RELEASE=$(curl -s https://api.github.com/repos/juanfont/headscale/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Stopping ${APP}" + systemctl stop headscale + msg_ok "Stopped ${APP}" + + msg_info "Updating $APP to v${RELEASE}" + wget -q https://github.com/juanfont/headscale/releases/download/v${RELEASE}/headscale_${RELEASE}_linux_amd64.deb + dpkg -i headscale_${RELEASE}_linux_amd64.deb + rm headscale_${RELEASE}_linux_amd64.deb + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated $APP to ${RELEASE}" + + msg_info "Starting ${APP}" + systemctl start headscale + msg_ok "Started ${APP}" + msg_ok "Updated Successfully" +else + msg_ok "No update required. ${APP} is already at ${RELEASE}" +fi +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" From b3cf19141f9a680412df4a1079f6d8226659481a Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 May 2024 05:44:58 -0400 Subject: [PATCH 6325/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4664ad7d..fbadff7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-13 + +### Changed + +- **Headscale LXC** + - NEW Script + ## 2024-05-11 ### Changed From a04fd986dcded900f52a654ffd33427154f9e798 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 May 2024 11:09:27 -0400 Subject: [PATCH 6326/6505] Update vaultwarden.sh - increase RAM during build to 5GB - fixes https://github.com/tteck/Proxmox/issues/2977 --- ct/vaultwarden.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 53b04287..b5cb6fa5 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="Vaultwarden" var_disk="6" var_cpu="4" -var_ram="4096" +var_ram="5120" var_os="debian" var_version="12" variables From 4d3afc012b9faed809fd0e320b44d7a116ac252b Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 May 2024 20:00:04 -0400 Subject: [PATCH 6327/6505] Update frigate-install.sh Change the RELEASE= command in an attempt to fix the Segmentation fault --- install/frigate-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index b5b53ca7..37484ccb 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -45,8 +45,8 @@ if [[ "$CTTYPE" == "0" ]]; then chmod 660 /dev/dri/* fi msg_ok "Set Up Hardware Acceleration" - -RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) +RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | sed -n 's/.*"tag_name": "\(.*\)",/\1/p') +#RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) msg_info "Installing Frigate $RELEASE (Perseverance)" cd ~ mkdir -p /opt/frigate/models From 48ae95bdead7e0d8f2fcec1687e4786bbeb25aa3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 13 May 2024 20:17:10 -0400 Subject: [PATCH 6328/6505] Update frigate-install.sh revert --- install/frigate-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 37484ccb..bfb4c380 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -45,8 +45,8 @@ if [[ "$CTTYPE" == "0" ]]; then chmod 660 /dev/dri/* fi msg_ok "Set Up Hardware Acceleration" -RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | sed -n 's/.*"tag_name": "\(.*\)",/\1/p') -#RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) +#RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | sed -n 's/.*"tag_name": "\(.*\)",/\1/p') +RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) msg_info "Installing Frigate $RELEASE (Perseverance)" cd ~ mkdir -p /opt/frigate/models From 6c4e2aa7fea3e7799223341d0cafea165a778159 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 May 2024 01:27:16 -0400 Subject: [PATCH 6329/6505] Update frigate-install.sh Another attempt to fix the Segmentation fault --- install/frigate-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index bfb4c380..defac274 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -14,7 +14,7 @@ network_check update_os msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y {curl,sudo,mc,git,gpg,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb2,libtbb-dev,libdc1394-22-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev} +$STD apt-get install -y {curl,sudo,mc,git,gpg,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb2,libtbb-dev,libdc1394-22-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq} msg_ok "Installed Dependencies" msg_info "Installing Python3 Dependencies" @@ -45,8 +45,8 @@ if [[ "$CTTYPE" == "0" ]]; then chmod 660 /dev/dri/* fi msg_ok "Set Up Hardware Acceleration" -#RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | sed -n 's/.*"tag_name": "\(.*\)",/\1/p') -RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) +RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | jq -r '.tag_name') +#RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) msg_info "Installing Frigate $RELEASE (Perseverance)" cd ~ mkdir -p /opt/frigate/models From 36fd84660150bd0ab83afc53e9262c88a8ac0e4c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 May 2024 02:00:33 -0400 Subject: [PATCH 6330/6505] Update frigate-install.sh stop spinner during "Installing Frigate" --- install/frigate-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index defac274..d67cadba 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -48,6 +48,7 @@ msg_ok "Set Up Hardware Acceleration" RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | jq -r '.tag_name') #RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) msg_info "Installing Frigate $RELEASE (Perseverance)" +if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi cd ~ mkdir -p /opt/frigate/models wget -q https://github.com/blakeblackshear/frigate/archive/refs/tags/${RELEASE}.tar.gz -O frigate.tar.gz From db157d02e4ee930c3610b3bc58a8c9e73093d150 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 14 May 2024 02:13:07 -0400 Subject: [PATCH 6331/6505] Update frigate-install.sh tweak --- install/frigate-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index d67cadba..50847e70 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -46,7 +46,7 @@ if [[ "$CTTYPE" == "0" ]]; then fi msg_ok "Set Up Hardware Acceleration" RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | jq -r '.tag_name') -#RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4) +msg_ok "Stop spinner to prevent segmentation fault" msg_info "Installing Frigate $RELEASE (Perseverance)" if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi cd ~ From ca8b655c812ab4d4779b060b3568eb1bbdb2004f Mon Sep 17 00:00:00 2001 From: Bram Suurd <78373894+BramSuurdje@users.noreply.github.com> Date: Thu, 16 May 2024 12:12:32 +0200 Subject: [PATCH 6332/6505] Add LXC: Iventoy (#2988) --- ct/iventoy.sh | 67 ++++++++++++++++++++++++++++++++++++++ install/iventoy-install.sh | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 ct/iventoy.sh create mode 100644 install/iventoy-install.sh diff --git a/ct/iventoy.sh b/ct/iventoy.sh new file mode 100644 index 00000000..08e067ab --- /dev/null +++ b/ct/iventoy.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ _ __ __ + (_) | / /__ ____ / /_____ __ __ + / /| | / / _ \/ __ \/ __/ __ \/ / / / + / / | |/ / __/ / / / /_/ /_/ / /_/ / +/_/ |___/\___/_/ /_/\__/\____/\__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="iVentoy" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="0" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +if [[ ! -d /opt/iventoy ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_error "There is currently no update path available." +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:26000/ ${CL} \n" \ No newline at end of file diff --git a/install/iventoy-install.sh b/install/iventoy-install.sh new file mode 100644 index 00000000..02601d7e --- /dev/null +++ b/install/iventoy-install.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Installing iVentoy v${RELEASE}" +mkdir -p /opt/iventoy/ +wget -q https://github.com/ventoy/PXE/releases/download/v${RELEASE}/iventoy-${RELEASE}-linux-free.tar.gz +tar -C /tmp -xzf iventoy*.tar.gz +mv /tmp/iventoy*/* /opt/iventoy/ +rm -rf iventoy*.tar.gz +msg_ok "Installed iVentoy" + +msg_info "Creating Service" +cat </etc/systemd/system/iventoy.service +[Unit] +Description =iVentoy PXE Booter +Documentation =https://www.iventoy.com +Wants =network-online.target +[Service] +Type =forking +Environment =IVENTOY_API_ALL=1 +Environment =IVENTOY_AUTO_RUN=1 +Environment =LIBRARY_PATH=/opt/iventoy/lib/lin64 +Environment =LD_LIBRARY_PATH=/opt/iventoy/lib/lin64 +ExecStart =sh ./iventoy.sh -R start +WorkingDirectory =/opt/iventoy +Restart =on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now iventoy.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file From 9dac75a48b936680e2d6d959ce7e8c252d53953c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 16 May 2024 08:05:02 -0400 Subject: [PATCH 6333/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbadff7a..f74f74da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-16 + +### Changed + +- **iVentoy LXC** + - NEW Script + ## 2024-05-13 ### Changed From 26ba9ea323793663a5fdfa442440cba999637a2e Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 May 2024 04:20:46 -0400 Subject: [PATCH 6334/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f74f74da..064f42aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-17 + +### Changed + +- **New Website** + - We have officially moved to [Helper-Scripts.com](https://helper-scripts.com) + ## 2024-05-16 ### Changed From 990e299b3520fa2f6d100423157e417a1d6600d4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 17 May 2024 09:56:31 -0400 Subject: [PATCH 6335/6505] Update pve8-upgrade.sh fix version check --- misc/pve8-upgrade.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index f4a79136..86aaee2f 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -124,10 +124,10 @@ if ! command -v pveversion >/dev/null 2>&1; then exit fi -if ! pveversion | grep -Eq "pve-manager/(7\.4-(13|14|15|16|17))"; then +if ! pveversion | grep -Eq "pve-manager/(7\.4-(16|17|18|19))"; then header_info msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e " PVE Version 7.4-13 or higher is required." + echo -e " PVE Version 7.4-16 or higher is required." echo -e "\nExiting..." sleep 3 exit From 906b6c07d238027ee299f8addc87905ad7f5adc0 Mon Sep 17 00:00:00 2001 From: xairoo Date: Sat, 18 May 2024 16:32:33 +0200 Subject: [PATCH 6336/6505] MongoDB LXC added (#3004) --- ct/mongodb.sh | 69 ++++++++++++++++++++++++++++++++++++++ install/mongodb-install.sh | 38 +++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 ct/mongodb.sh create mode 100644 install/mongodb-install.sh diff --git a/ct/mongodb.sh b/ct/mongodb.sh new file mode 100644 index 00000000..128c0893 --- /dev/null +++ b/ct/mongodb.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ ____ ____ + / |/ /___ ____ ____ _____ / __ \/ __ ) + / /|_/ / __ \/ __ \/ __ `/ __ \/ / / / __ | + / / / / /_/ / / / / /_/ / /_/ / /_/ / /_/ / +/_/ /_/\____/_/ /_/\__, /\____/_____/_____/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="MongoDB" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/mongodb-org-7.0.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating ${APP} LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated Successfully" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" diff --git a/install/mongodb-install.sh b/install/mongodb-install.sh new file mode 100644 index 00000000..92cfffea --- /dev/null +++ b/install/mongodb-install.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y gnupg +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing MongoDB" +wget -qO- https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-7.0.gpg +echo "deb [signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] http://repo.mongodb.org/apt/debian $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/7.0 main" >/etc/apt/sources.list.d/mongodb-org-7.0.list +$STD apt-get update +$STD apt-get install -y mongodb-org +sed -i 's/bindIp: 127.0.0.1/bindIp 0.0.0.0/' /etc/mongod.conf +systemctl enable -q --now mongod.service +msg_ok "Installed MongoDB" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From b91c8a79c5e7cbcefafc316b7cfa4e8138a4152d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 May 2024 10:42:46 -0400 Subject: [PATCH 6337/6505] Update mongodb.sh tweak --- ct/mongodb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/mongodb.sh b/ct/mongodb.sh index 128c0893..5b88ca4b 100644 --- a/ct/mongodb.sh +++ b/ct/mongodb.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="MongoDB" var_disk="4" var_cpu="1" -var_ram="1024" +var_ram="512" var_os="debian" var_version="12" variables From a4fed89490667768069c617785df1914e1933f0c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 May 2024 11:31:56 -0400 Subject: [PATCH 6338/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 064f42aa..bf93a397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-18 + +### Changed + +- **MongoDB LXC** + - NEW Script + ## 2024-05-17 ### Changed From ef87f69fa0a68c7f26c8b71b9ab61b20a68fa2fd Mon Sep 17 00:00:00 2001 From: xairoo Date: Sat, 18 May 2024 18:42:59 +0200 Subject: [PATCH 6339/6505] Debian title style fixed (#3006) There was an extra `_` on the `n` --- ct/debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/debian.sh b/ct/debian.sh index adfd810e..2472b0ac 100644 --- a/ct/debian.sh +++ b/ct/debian.sh @@ -9,7 +9,7 @@ function header_info { clear cat <<"EOF" ____ __ _ - / __ \___ / /_ (_)___ _____ + / __ \___ / /_ (_)___ ____ / / / / _ \/ __ \/ / __ `/ __ \ / /_/ / __/ /_/ / / /_/ / / / / /_____/\___/_.___/_/\__,_/_/ /_/ From 1b842f22cfff1f11eca08d5f8485e0e6f323dc04 Mon Sep 17 00:00:00 2001 From: xairoo Date: Sat, 18 May 2024 19:21:25 +0200 Subject: [PATCH 6340/6505] `sed` for YAML config fixed (#3007) Added missing `:` which is required for the YAML config. --- install/mongodb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/mongodb-install.sh b/install/mongodb-install.sh index 92cfffea..6839ae51 100644 --- a/install/mongodb-install.sh +++ b/install/mongodb-install.sh @@ -25,7 +25,7 @@ wget -qO- https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor >/us echo "deb [signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] http://repo.mongodb.org/apt/debian $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/7.0 main" >/etc/apt/sources.list.d/mongodb-org-7.0.list $STD apt-get update $STD apt-get install -y mongodb-org -sed -i 's/bindIp: 127.0.0.1/bindIp 0.0.0.0/' /etc/mongod.conf +sed -i 's/bindIp: 127.0.0.1/bindIp: 0.0.0.0/' /etc/mongod.conf systemctl enable -q --now mongod.service msg_ok "Installed MongoDB" From 0cd751d75c3d6ffe3c2c618a7b6b44b99076b468 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 18 May 2024 13:36:05 -0400 Subject: [PATCH 6341/6505] Update iventoy-install.sh create `data` and `iso` directories. --- install/iventoy-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/iventoy-install.sh b/install/iventoy-install.sh index 02601d7e..3c3e3953 100644 --- a/install/iventoy-install.sh +++ b/install/iventoy-install.sh @@ -21,7 +21,7 @@ msg_ok "Installed Dependencies" RELEASE=$(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') msg_info "Installing iVentoy v${RELEASE}" -mkdir -p /opt/iventoy/ +mkdir -p /opt/iventoy/{data,iso} wget -q https://github.com/ventoy/PXE/releases/download/v${RELEASE}/iventoy-${RELEASE}-linux-free.tar.gz tar -C /tmp -xzf iventoy*.tar.gz mv /tmp/iventoy*/* /opt/iventoy/ @@ -55,4 +55,4 @@ customize msg_info "Cleaning up" $STD apt-get -y autoremove $STD apt-get -y autoclean -msg_ok "Cleaned" \ No newline at end of file +msg_ok "Cleaned" From 22780bbf58348554422a853d055fd33b20d76ce0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 May 2024 07:30:05 -0400 Subject: [PATCH 6342/6505] Update umami-install.sh tweak --- install/umami-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/umami-install.sh b/install/umami-install.sh index 1ac1c1ca..943c0413 100644 --- a/install/umami-install.sh +++ b/install/umami-install.sh @@ -44,10 +44,10 @@ $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCO $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" -echo "" >umami.creds -echo -e "umami Database User: \e[32m$DB_USER\e[0m" >>umami.creds -echo -e "umami Database Password: \e[32m$DB_PASS\e[0m" >>umami.creds -echo -e "umami Database Name: \e[32m$DB_NAME\e[0m" >>umami.creds +echo "" >~/umami.creds +echo -e "umami Database User: \e[32m$DB_USER\e[0m" >>~/umami.creds +echo -e "umami Database Password: \e[32m$DB_PASS\e[0m" >>~/umami.creds +echo -e "umami Database Name: \e[32m$DB_NAME\e[0m" >>~/umami.creds msg_ok "Set up postgresql" msg_info "Installing Umami (Patience)" From 8b0400bd9492e80fc702e5e4fa8d915cbe67907e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 May 2024 12:19:12 -0400 Subject: [PATCH 6343/6505] Update redis-install.sh tweak --- install/redis-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/redis-install.sh b/install/redis-install.sh index 053e2088..18354ed9 100644 --- a/install/redis-install.sh +++ b/install/redis-install.sh @@ -24,7 +24,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Redis" curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg -echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list +echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" >/etc/apt/sources.list.d/redis.list $STD apt-get update $STD apt-get install -y redis sed -i 's/^bind .*/bind 0.0.0.0/' /etc/redis/redis.conf From dc01c8bdcd0024b92bd787e6ba4dc47f8f5cbaad Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 May 2024 12:27:11 -0400 Subject: [PATCH 6344/6505] Update redis-install.sh tweak --- install/redis-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/redis-install.sh b/install/redis-install.sh index 18354ed9..488d787a 100644 --- a/install/redis-install.sh +++ b/install/redis-install.sh @@ -18,12 +18,12 @@ $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc $STD apt-get install -y apt-transport-https -$STD apt-get install -y gnupg +$STD apt-get install -y gpg $STD apt-get install -y lsb-release msg_ok "Installed Dependencies" msg_info "Installing Redis" -curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg +wget -qO- https://packages.redis.io/gpg | gpg --dearmor >/usr/share/keyrings/redis-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" >/etc/apt/sources.list.d/redis.list $STD apt-get update $STD apt-get install -y redis From 08032f165f77d3a1b2f4517de9f8c1bd9d290916 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 May 2024 18:06:50 -0400 Subject: [PATCH 6345/6505] Update add-tailscale-lxc.sh Code refactoring --- misc/add-tailscale-lxc.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh index e5bcfaec..13307333 100644 --- a/misc/add-tailscale-lxc.sh +++ b/misc/add-tailscale-lxc.sh @@ -59,8 +59,14 @@ lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file EOF header_info msg "Installing Tailscale..." -lxc-attach -n $CTID -- bash -c "$(curl -fsSL https://tailscale.com/install.sh)" &>/dev/null || exit -msg "Installed Tailscale" -sleep 2 -msg "\e[1;32m ✔ Completed Successfully!\e[0m" +pct exec "$CTID" -- bash -c ' +ID=$(grep "^ID=" /etc/os-release | cut -d"=" -f2) +VER=$(grep "^VERSION_CODENAME=" /etc/os-release | cut -d"=" -f2) +wget -qO- https://pkgs.tailscale.com/stable/$ID/$VER.noarmor.gpg >/usr/share/keyrings/tailscale-archive-keyring.gpg +echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/$ID $VER main" >/etc/apt/sources.list.d/tailscale.list +apt-get update &>/dev/null +apt-get install -y tailscale &>/dev/null +' || exit +msg "\e[1;32m ✔ Installed Tailscale\e[0m" + msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run tailscale up in the LXC console\e[0m" From 8c09fafa6e2d206c9373325ba08a12633e88f8b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 May 2024 18:08:25 -0400 Subject: [PATCH 6346/6505] Create add-netbird-lxc.sh --- misc/add-netbird-lxc.sh | 71 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 misc/add-netbird-lxc.sh diff --git a/misc/add-netbird-lxc.sh b/misc/add-netbird-lxc.sh new file mode 100644 index 00000000..05427106 --- /dev/null +++ b/misc/add-netbird-lxc.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ __ ____ _ __ + / | / /__ / /_/ __ )(_)________/ / + / |/ / _ \/ __/ __ / / ___/ __ / + / /| / __/ /_/ /_/ / / / / /_/ / +/_/ |_/\___/\__/_____/_/_/ \__,_/ + +EOF +} +header_info +set -e +while true; do + read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn + case $yn in + [Yy]*) break ;; + [Nn]*) exit ;; + *) echo "Please answer yes or no." ;; + esac +done +header_info +echo "Loading..." +function msg() { + local TEXT="$1" + echo -e "$TEXT" +} + +NODE=$(hostname) +MSG_MAX_LENGTH=0 +while read -r line; do + TAG=$(echo "$line" | awk '{print $1}') + ITEM=$(echo "$line" | awk '{print substr($0,36)}') + OFFSET=2 + if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then + MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) + fi + CTID_MENU+=("$TAG" "$ITEM " "OFF") +done < <(pct list | awk 'NR>1') + +while [ -z "${CTID:+x}" ]; do + CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --radiolist \ + "\nSelect a container to add NetBird to:\n" \ + 16 $(($MSG_MAX_LENGTH + 23)) 6 \ + "${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit +done + +CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf +cat <>$CTID_CONFIG_PATH +lxc.cgroup2.devices.allow: c 10:200 rwm +lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file +EOF +header_info +msg "Installing NetBird..." +pct exec "$CTID" -- bash -c ' +apt install -y ca-certificates gpg &>/dev/null +wget -qO- https://pkgs.netbird.io/debian/public.key | gpg --dearmor >/usr/share/keyrings/netbird-archive-keyring.gpg +echo "deb [signed-by=/usr/share/keyrings/netbird-archive-keyring.gpg] https://pkgs.netbird.io/debian stable main" >/etc/apt/sources.list.d/netbird.list +apt-get update &>/dev/null +apt-get install -y netbird-ui &>/dev/null +' || exit +msg "\e[1;32m ✔ Installed NetBird.\e[0m" +sleep 2 +msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run netbird up in the LXC console\e[0m" From b503418cdb62c7cbadf9a04235de061f9dfd9abc Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 May 2024 18:21:43 -0400 Subject: [PATCH 6347/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf93a397..9c41a84e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-19 + +### Changed + +- **Netbird** + - NEW Script +- **Tailscale** + - Refactor Code + ## 2024-05-18 ### Changed From 2a8a65e7544e8a9cbfacaf5246d4f643e798b8db Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 19 May 2024 20:30:22 -0400 Subject: [PATCH 6348/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c41a84e..37a99022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ ### Changed -- **Netbird** +- **NetBird** - NEW Script - **Tailscale** - Refactor Code From 07585658b0edea4dce99e7b41420164d83e488d4 Mon Sep 17 00:00:00 2001 From: Uzurka <101745008+Uzurka@users.noreply.github.com> Date: Mon, 20 May 2024 10:19:48 +0200 Subject: [PATCH 6349/6505] Added Traefik (#3021) --- ct/traefik.sh | 77 ++++++++++++++++++++++++ install/traefik-install.sh | 117 +++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 ct/traefik.sh create mode 100644 install/traefik-install.sh diff --git a/ct/traefik.sh b/ct/traefik.sh new file mode 100644 index 00000000..8b393c1e --- /dev/null +++ b/ct/traefik.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ______ _____ __ + /_ __/________ ____ / __(_) /__ + / / / ___/ __ `/ _ \/ /_/ / //_/ + / / / / / /_/ / __/ __/ / ,< +/_/ /_/ \__,_/\___/_/ /_/_/|_| + +EOF +} +header_info +echo -e "Loading..." +APP="Traefik" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/systemd/system/traefik.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz + tar -C /tmp -xzf traefik*.tar.gz + mv /tmp/traefik*/traefik /usr/bin/ + rm -rf traefik*.tar.gz + msg_ok "Updated $APP LXC" +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} should be reachable by going to the following URL. + ${BL}http://${IP}:8080${CL} \n" diff --git a/install/traefik-install.sh b/install/traefik-install.sh new file mode 100644 index 00000000..6696be22 --- /dev/null +++ b/install/traefik-install.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +$STD apt-get install -y apt-transport-https +msg_ok "Installed Dependencies" + +RELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Installing Traefik v${RELEASE}" +mkdir -p /etc/traefik/{conf.d,ssl} +wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz +tar -C /tmp -xzf traefik*.tar.gz +mv /tmp/traefik /usr/bin/ +rm -rf traefik*.tar.gz +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed Traefik v${RELEASE}" + +msg_info "Creating Traefik configuration" +cat </etc/traefik/traefik.yaml +providers: + file: + directory: /etc/traefik/conf.d/ + +entryPoints: + web: + address: ':80' + http: + redirections: + entryPoint: + to: websecure + scheme: https + websecure: + address: ':443' + http: + middlewares: + - crowdsec-bouncer@file + tls: + certResolver: letsencrypt + traefik: + address: ':8080' + +certificatesResolvers: + letsencrypt: + acme: + email: "foo@bar.com" + storage: /etc/traefik/ssl/acme.json + tlsChallenge: {} + +api: + dashboard: true + insecure: true + +log: + filePath: /var/log/traefik/traefik.log + format: json + level: INFO + +accessLog: + filePath: /var/log/traefik/traefik-access.log + format: json + filters: + statusCodes: + - "200" + - "400-599" + retryAttempts: true + minDuration: "10ms" + bufferingSize: 0 + fields: + headers: + defaultMode: drop + names: + User-Agent: keep +EOF +msg_ok "Created Traefik configuration" + +msg_info "Creating Service" +cat </etc/systemd/system/traefik.service +[Unit] +Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience + +[Service] +Type=notify +ExecStart=/usr/bin/traefik --configFile=/etc/traefik/traefik.yaml +Restart=on-failure +ExecReload=/bin/kill -USR1 \$MAINPID + +[Install] +WantedBy=multi-user.target +EOF + +systemctl enable -q --now traefik.service +msg_ok "Created Service" + + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From e746d7c340c815f5f85edbf1f8d9bbd09f38cafc Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 20 May 2024 04:31:59 -0400 Subject: [PATCH 6350/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37a99022..2640af1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-20 + +### Changed + +- **Traefik LXC** + - NEW Script + ## 2024-05-19 ### Changed From bf08d0a4352d71de2e2aee6d7432878535d69561 Mon Sep 17 00:00:00 2001 From: Uzurka <101745008+Uzurka@users.noreply.github.com> Date: Mon, 20 May 2024 10:37:06 +0200 Subject: [PATCH 6351/6505] Fixed Traefik : forgot to remove Crowdsec middleware in default config (#3022) --- install/traefik-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/traefik-install.sh b/install/traefik-install.sh index 6696be22..b8346196 100644 --- a/install/traefik-install.sh +++ b/install/traefik-install.sh @@ -48,8 +48,6 @@ entryPoints: websecure: address: ':443' http: - middlewares: - - crowdsec-bouncer@file tls: certResolver: letsencrypt traefik: From 3af40c52381715eeab5b0aa0d4ef30df1f977dfe Mon Sep 17 00:00:00 2001 From: Marco Cunha Date: Tue, 21 May 2024 00:38:47 +0100 Subject: [PATCH 6352/6505] Ensure logrotate doesn't use non-existing npm user (#3026) Upstream uses a dedicated user to run NPM. Ensure we do not try to user the missing user to rotate logs [which fails]. --- install/nginxproxymanager-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index ae267817..4a0873a8 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -193,6 +193,7 @@ customize msg_info "Starting Services" sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf +sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg systemctl enable -q --now openresty systemctl enable -q --now npm From d8c14cc5feb68cbe18b935ded9bab57545304b3d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 May 2024 11:16:19 -0400 Subject: [PATCH 6353/6505] Update README.md add Website Terms of Use --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a6ee17d..b38943ab 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

    Proxmox VE Helper-Scripts

    - Website | + Website Terms of Use | Contribute | Guides | Changelog | From 2f6ed335755a760e8fc4ff11787200bee80bb560 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 21 May 2024 12:33:57 -0400 Subject: [PATCH 6354/6505] Update traefik.sh add missing `RELEASE` variable --- ct/traefik.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/traefik.sh b/ct/traefik.sh index 8b393c1e..84a9d44a 100644 --- a/ct/traefik.sh +++ b/ct/traefik.sh @@ -55,6 +55,7 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/systemd/system/traefik.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +RELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') msg_info "Updating $APP LXC" if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz From 7c5f4335fdd339f811bca4b8c49f5c6052245c53 Mon Sep 17 00:00:00 2001 From: Uzurka <101745008+Uzurka@users.noreply.github.com> Date: Wed, 22 May 2024 00:20:26 +0200 Subject: [PATCH 6355/6505] Discussion #3030 Fix (#3031) --- ct/traefik.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/traefik.sh b/ct/traefik.sh index 84a9d44a..503d51dc 100644 --- a/ct/traefik.sh +++ b/ct/traefik.sh @@ -60,7 +60,7 @@ msg_info "Updating $APP LXC" if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz tar -C /tmp -xzf traefik*.tar.gz - mv /tmp/traefik*/traefik /usr/bin/ + mv /tmp/traefik /usr/bin/ rm -rf traefik*.tar.gz msg_ok "Updated $APP LXC" else From 73291211a885df94a8419d3fa38ecbff05f9ab3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 May 2024 00:15:23 -0400 Subject: [PATCH 6356/6505] Update README.md Tweak --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b38943ab..b9869fc8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@

    Proxmox VE Helper-Scripts

    - Website Terms of Use | + Terms of Use | + Website | Contribute | Guides | Changelog | From d468fc6c1f0bb379f824b193113e872db72401d2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 22 May 2024 11:07:28 -0400 Subject: [PATCH 6357/6505] Update build.func temporally set Alpine repositories to "3.19" from "latest-stable" --- misc/build.func | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/build.func b/misc/build.func index ff2410c5..efe81211 100644 --- a/misc/build.func +++ b/misc/build.func @@ -620,8 +620,10 @@ EOF if [ "$var_os" == "alpine" ]; then sleep 3 pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories -http://dl-cdn.alpinelinux.org/alpine/latest-stable/main -http://dl-cdn.alpinelinux.org/alpine/latest-stable/community +#http://dl-cdn.alpinelinux.org/alpine/latest-stable/main +#http://dl-cdn.alpinelinux.org/alpine/latest-stable/community +http://dl-cdn.alpinelinux.org/alpine/v3.19/main +http://dl-cdn.alpinelinux.org/alpine/v3.19/community EOF' pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi From 6b33fdd9f5c93e9eff2157b8895887a74f63fbd6 Mon Sep 17 00:00:00 2001 From: Marco Cunha Date: Thu, 23 May 2024 12:54:34 +0100 Subject: [PATCH 6358/6505] Disable "running as root" warning in Jackett WebUI/Logs (#3043) Upstream checks if running under root and displays alert in both startup logs and WebUI. This environment variable disables that behavior. --- install/jackett-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/jackett-install.sh b/install/jackett-install.sh index 36fcc7c0..6f3645aa 100644 --- a/install/jackett-install.sh +++ b/install/jackett-install.sh @@ -39,6 +39,7 @@ Type=simple WorkingDirectory=/opt/Jackett ExecStart=/bin/sh /opt/Jackett/jackett_launcher.sh TimeoutStopSec=30 +Environment="DisableRootWarning=true" [Install] WantedBy=multi-user.target EOF From 326f9f500b84db11c45ee63b9626140c514b32b9 Mon Sep 17 00:00:00 2001 From: cvroque <65680394+cvroque@users.noreply.github.com> Date: Thu, 23 May 2024 11:53:56 -0300 Subject: [PATCH 6359/6505] Update zoraxy.sh (#3044) --- ct/zoraxy.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh index efcd250a..1efc3331 100644 --- a/ct/zoraxy.sh +++ b/ct/zoraxy.sh @@ -55,7 +55,19 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/zoraxy/src ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_error "There is currently no update path available." +msg_info "Updating $APP" +systemctl stop zoraxy +cd /opt/zoraxy/src +if ! git pull; then + echo "Already up to date." + systemctl start zoraxy + echo "No update required." + exit +fi +go mod tidy +go build +systemctl start zoraxy +msg_ok "Updated $APP" exit } From b6e83bcae28fb3f27a50387c810a78ecb1dc3323 Mon Sep 17 00:00:00 2001 From: Brett England Date: Thu, 23 May 2024 17:05:02 -0400 Subject: [PATCH 6360/6505] Update photoprism-install.sh (#3049) fixes https://github.com/tteck/Proxmox/issues/3048 --- install/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index e16cb6ee..9737f0ec 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -26,6 +26,7 @@ $STD apt-get install -y libtiff-dev $STD apt-get install -y imagemagick $STD apt-get install -y darktable $STD apt-get install -y rawtherapee +$STD apt-get install -y libvips42 echo 'export PATH=/usr/local:$PATH' >>~/.bashrc export PATH=/usr/local:$PATH From 0e24893e52aef3b6988cfe413ea36edf8c2a9aed Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 May 2024 21:38:21 -0400 Subject: [PATCH 6361/6505] Create bunkerweb.sh --- ct/bunkerweb.sh | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 ct/bunkerweb.sh diff --git a/ct/bunkerweb.sh b/ct/bunkerweb.sh new file mode 100644 index 00000000..a6a53f86 --- /dev/null +++ b/ct/bunkerweb.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ _ __ __ + / __ )__ ______ / /_____ ____| | / /__ / /_ + / __ / / / / __ \/ //_/ _ \/ ___/ | /| / / _ \/ __ \ + / /_/ / /_/ / / / / ,< / __/ / | |/ |/ / __/ /_/ / +/_____/\__,_/_/ /_/_/|_|\___/_/ |__/|__/\___/_.___/ + +EOF +} +header_info +echo -e "Loading..." +APP="BunkerWeb" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /etc/bunkerweb ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP" +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}/setup${CL} \n" From 14798991b47ff444bcc4e00c45150ccff86cfe1b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 May 2024 21:39:30 -0400 Subject: [PATCH 6362/6505] Create bunkerweb-install.sh --- install/bunkerweb-install.sh | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 install/bunkerweb-install.sh diff --git a/install/bunkerweb-install.sh b/install/bunkerweb-install.sh new file mode 100644 index 00000000..ac8595da --- /dev/null +++ b/install/bunkerweb-install.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gnupg2 +$STD apt-get install -y ca-certificates +$STD apt-get install -y lsb-release +$STD apt-get install -y debian-archive-keyring +msg_ok "Installed Dependencies" + +msg_info "Installing Nginx v1.20.0" +wget -qO- https://nginx.org/keys/nginx_signing.key | gpg --dearmor >/usr/share/keyrings/nginx-archive-keyring.gpg +echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian `lsb_release -cs` nginx" >/etc/apt/sources.list.d/nginx.list +$STD apt-get update +$STD apt-get install -y nginx=1.24.0-1~$(lsb_release -cs) +msg_ok "Installed Nginx v1.20.0" + +msg_info "Installing BunkerWeb v1.5.7" +export UI_WIZARD=1 +$STD curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash +$STD apt-get install -y bunkerweb=1.5.7 +#$STD apt-mark hold nginx bunkerweb +msg_ok "Installed BunkerWeb v1.5.7" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 31ae6d829c073d1fffb91b88c664af83865629a6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 May 2024 21:43:30 -0400 Subject: [PATCH 6363/6505] Update bunkerweb-install.sh tweak --- install/bunkerweb-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/bunkerweb-install.sh b/install/bunkerweb-install.sh index ac8595da..f0a8d4aa 100644 --- a/install/bunkerweb-install.sh +++ b/install/bunkerweb-install.sh @@ -32,7 +32,7 @@ msg_ok "Installed Nginx v1.20.0" msg_info "Installing BunkerWeb v1.5.7" export UI_WIZARD=1 -$STD curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash +curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash &>/dev/null $STD apt-get install -y bunkerweb=1.5.7 #$STD apt-mark hold nginx bunkerweb msg_ok "Installed BunkerWeb v1.5.7" From e5788637b75ef46975732cd39b463a98ca259fc9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 May 2024 22:02:46 -0400 Subject: [PATCH 6364/6505] Update bunkerweb.sh tweak --- ct/bunkerweb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/bunkerweb.sh b/ct/bunkerweb.sh index a6a53f86..701d6d83 100644 --- a/ct/bunkerweb.sh +++ b/ct/bunkerweb.sh @@ -20,7 +20,7 @@ header_info echo -e "Loading..." APP="BunkerWeb" var_disk="4" -var_cpu="1" +var_cpu="2" var_ram="1024" var_os="debian" var_version="12" From 5efcac2bc5f86ce118180493d0f8546b41248ac2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 23 May 2024 22:03:42 -0400 Subject: [PATCH 6365/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2640af1d..ee22badf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-23 + +### Changed + +- **BunkerWeb LXC** + - NEW Script + ## 2024-05-20 ### Changed From ea135820e36f70e49920cf6beaad5f6192381019 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 24 May 2024 11:47:34 -0400 Subject: [PATCH 6366/6505] Update photoprism.sh add `libvips42` to update --- ct/photoprism.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/photoprism.sh b/ct/photoprism.sh index 26e0c729..593fe362 100644 --- a/ct/photoprism.sh +++ b/ct/photoprism.sh @@ -64,6 +64,7 @@ function update_script() { msg_ok "Stopped PhotoPrism" msg_info "Updating PhotoPrism" + apt-get install -y libvips42 &>/dev/null wget -q -cO - https://dl.photoprism.app/pkg/linux/amd64.tar.gz | tar -xzf - -C /opt/photoprism --strip-components=1 msg_ok "Updated PhotoPrism" From acfb3eee043f733070e5cd46af7ab14b67d6311e Mon Sep 17 00:00:00 2001 From: Simon Albrecht Date: Sat, 25 May 2024 14:11:31 +0200 Subject: [PATCH 6367/6505] Add Threadfin (#3062) --- ct/threadfin.sh | 73 ++++++++++++++++++++++++++++++++++++ install/threadfin-install.sh | 55 +++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 ct/threadfin.sh create mode 100644 install/threadfin-install.sh diff --git a/ct/threadfin.sh b/ct/threadfin.sh new file mode 100644 index 00000000..e870e26c --- /dev/null +++ b/ct/threadfin.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ _______ + /_ __/ /_ ________ ____ _____/ / __(_)___ + / / / __ \/ ___/ _ \/ __ `/ __ / /_/ / __ \ + / / / / / / / / __/ /_/ / /_/ / __/ / / / / +/_/ /_/ /_/_/ \___/\__,_/\__,_/_/ /_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Threadfin" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/threadfin ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +systemctl stop threadfin.service +wget -q -O /opt/threadfin/threadfin 'https://github.com/Threadfin/Threadfin/releases/latest/download/Threadfin_linux_amd64' +chmod +x /opt/threadfin/threadfin +systemctl start threadfin.service +msg_ok "Updated $APP" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:34400/web${CL} \n" diff --git a/install/threadfin-install.sh b/install/threadfin-install.sh new file mode 100644 index 00000000..5fb8211d --- /dev/null +++ b/install/threadfin-install.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y curl +$STD apt-get install -y ffmpeg +$STD apt-get install -y vlc +msg_ok "Installed Dependencies" + +msg_info "Installing Threadfin" +mkdir -p /opt/threadfin +wget -q -O /opt/threadfin/threadfin 'https://github.com/Threadfin/Threadfin/releases/latest/download/Threadfin_linux_amd64' +chmod +x /opt/threadfin/threadfin + +msg_ok "Installed Threadfin" + +msg_info "Creating Service" +cat </etc/systemd/system/threadfin.service +[Unit] +Description=Threadfin: M3U Proxy for Plex DVR and Emby/Jellyfin Live TV +After=syslog.target network.target +[Service] +Type=simple +WorkingDirectory=/opt/threadfin +ExecStart=/opt/threadfin/threadfin +TimeoutStopSec=20 +KillMode=process +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now threadfin.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 0bd8035461454d5a4a7d4d8a33c817ecc86c8832 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 May 2024 08:29:34 -0400 Subject: [PATCH 6368/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee22badf..df5ba212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-25 + +### Changed + +- **Threadfin LXC** + - NEW Script + ## 2024-05-23 ### Changed From 574226d993cf649ac5f529068bfd1dc0cda1161f Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 May 2024 09:11:10 -0400 Subject: [PATCH 6369/6505] Update build.func add @asylumexp repo for ARM64 support. --- misc/build.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/build.func b/misc/build.func index efe81211..cd87d2c7 100644 --- a/misc/build.func +++ b/misc/build.func @@ -111,6 +111,7 @@ pve_check() { arch_check() { if [ "$(dpkg --print-architecture)" != "amd64" ]; then echo -e "\n ${CROSS} This script will not work with PiMox! \n" + echo -e "\n Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" echo -e "Exiting..." sleep 2 exit From a94bc0234ffe57dc5fee51d64c887d9c480e5643 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 25 May 2024 13:51:52 -0400 Subject: [PATCH 6370/6505] Update linkwarden-install.sh fixes https://github.com/tteck/Proxmox/issues/3065 --- install/linkwarden-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh index eaae6bfd..9d5c455d 100644 --- a/install/linkwarden-install.sh +++ b/install/linkwarden-install.sh @@ -42,7 +42,7 @@ msg_ok "Cloned Linkwarden Repository" msg_info "Setting up PostgreSQL DB" DB_NAME=linkwardendb DB_USER=linkwarden -DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +DB_PASS="$(openssl rand -base64 18 | tr -d '/' | cut -c1-13)" $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;" From d5031be72905f876fbb69d63dbba92cdc51bf7db Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 May 2024 04:59:56 -0400 Subject: [PATCH 6371/6505] Create notifiarr-install.com --- install/notifiarr-install.com | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 install/notifiarr-install.com diff --git a/install/notifiarr-install.com b/install/notifiarr-install.com new file mode 100644 index 00000000..3968d535 --- /dev/null +++ b/install/notifiarr-install.com @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +msg_ok "Installed Dependencies" + +msg_info "Installing Notifiarr" +$STD groupadd notifiarr +$STD useradd -g notifiarr notifiarr +wget -qO- https://packagecloud.io/golift/pkgs/gpgkey | gpg --dearmor >/usr/share/keyrings/golift-archive-keyring.gpg +echo "deb [signed-by=/usr/share/keyrings/golift-archive-keyring.gpg] https://packagecloud.io/golift/pkgs/ubuntu focal main" >/etc/apt/sources.list.d/golift.list +$STD apt-get install -y notifiarr +msg_ok "Installed Notifiarr" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 47b6fd5e8aa921f486a63170088ffe800e26be02 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 May 2024 05:01:01 -0400 Subject: [PATCH 6372/6505] Create notifiarr.sh --- ct/notifiarr.sh | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 ct/notifiarr.sh diff --git a/ct/notifiarr.sh b/ct/notifiarr.sh new file mode 100644 index 00000000..09f3d170 --- /dev/null +++ b/ct/notifiarr.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _ __ __ _ _____ + / | / /___ / /_(_) __(_)___ ___________ + / |/ / __ \/ __/ / /_/ / __ `/ ___/ ___/ + / /| / /_/ / /_/ / __/ / /_/ / / / / +/_/ |_/\____/\__/_/_/ /_/\__,_/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="Notifiarr" +var_disk="2" +var_cpu="1" +var_ram="512" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/apt/sources.list.d/golift.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP" +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}:5454${CL} \n" From 80046821af85d7fca7f33ca93c18a74bb8fd54c5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 May 2024 05:03:40 -0400 Subject: [PATCH 6373/6505] Rename notifiarr-install.com to notifiarr-install.sh --- install/{notifiarr-install.com => notifiarr-install.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename install/{notifiarr-install.com => notifiarr-install.sh} (100%) diff --git a/install/notifiarr-install.com b/install/notifiarr-install.sh similarity index 100% rename from install/notifiarr-install.com rename to install/notifiarr-install.sh From 3dce2fb7ddde9c6aa428a7c99758c42b1fc2e806 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 May 2024 05:08:19 -0400 Subject: [PATCH 6374/6505] Update notifiarr-install.sh tweak --- install/notifiarr-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/notifiarr-install.sh b/install/notifiarr-install.sh index 3968d535..5ebac2b8 100644 --- a/install/notifiarr-install.sh +++ b/install/notifiarr-install.sh @@ -21,8 +21,8 @@ $STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Installing Notifiarr" -$STD groupadd notifiarr -$STD useradd -g notifiarr notifiarr +groupadd notifiarr &>/dev/null +useradd -g notifiarr notifiarr &>/dev/null wget -qO- https://packagecloud.io/golift/pkgs/gpgkey | gpg --dearmor >/usr/share/keyrings/golift-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/golift-archive-keyring.gpg] https://packagecloud.io/golift/pkgs/ubuntu focal main" >/etc/apt/sources.list.d/golift.list $STD apt-get install -y notifiarr From 37ac28da06fec64577978e4e239b5caf10784a7b Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 May 2024 05:12:08 -0400 Subject: [PATCH 6375/6505] Update notifiarr-install.sh tweak --- install/notifiarr-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install/notifiarr-install.sh b/install/notifiarr-install.sh index 5ebac2b8..a90217c0 100644 --- a/install/notifiarr-install.sh +++ b/install/notifiarr-install.sh @@ -21,10 +21,11 @@ $STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Installing Notifiarr" -groupadd notifiarr &>/dev/null -useradd -g notifiarr notifiarr &>/dev/null +$STD groupadd notifiarr +$STD useradd -g notifiarr notifiarr wget -qO- https://packagecloud.io/golift/pkgs/gpgkey | gpg --dearmor >/usr/share/keyrings/golift-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/golift-archive-keyring.gpg] https://packagecloud.io/golift/pkgs/ubuntu focal main" >/etc/apt/sources.list.d/golift.list +$STD apt-get update $STD apt-get install -y notifiarr msg_ok "Installed Notifiarr" From 7ba1459286dd2115d319ed81c0b6d791e7fcd2c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 May 2024 05:15:57 -0400 Subject: [PATCH 6376/6505] Update notifiarr.sh tweak --- ct/notifiarr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/notifiarr.sh b/ct/notifiarr.sh index 09f3d170..ac63e454 100644 --- a/ct/notifiarr.sh +++ b/ct/notifiarr.sh @@ -67,5 +67,5 @@ build_container description msg_ok "Completed Successfully!\n" -echo -e "${APP} setup should be reachable by going to the following URL. +echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5454${CL} \n" From 7446dc4c73708a5130a93cb5fdb1c01c8f3d8bd3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 28 May 2024 05:24:16 -0400 Subject: [PATCH 6377/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index df5ba212..12d94730 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-28 + +### Changed + +- **Notifiarr LXC** + - NEW Script + ## 2024-05-25 ### Changed From a95657947db0f0c183422a95b09a2f4a919cacca Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 29 May 2024 15:28:58 -0400 Subject: [PATCH 6378/6505] Update zoraxy.sh fix update --- ct/zoraxy.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/ct/zoraxy.sh b/ct/zoraxy.sh index 1efc3331..84a40785 100644 --- a/ct/zoraxy.sh +++ b/ct/zoraxy.sh @@ -58,16 +58,15 @@ if [[ ! -d /opt/zoraxy/src ]]; then msg_error "No ${APP} Installation Found!"; e msg_info "Updating $APP" systemctl stop zoraxy cd /opt/zoraxy/src -if ! git pull; then - echo "Already up to date." - systemctl start zoraxy - echo "No update required." - exit +systemctl stop zoraxy +if git pull | grep -q 'Already up to date.'; then + msg_ok "Already up to date. No update required." +else + go mod tidy + go build + msg_ok "Updated $APP" fi -go mod tidy -go build systemctl start zoraxy -msg_ok "Updated $APP" exit } From 0fb8716ebebd74f789f0bd05da62254d64bb90e2 Mon Sep 17 00:00:00 2001 From: barremian <61056521+barremian@users.noreply.github.com> Date: Thu, 30 May 2024 09:08:40 +0200 Subject: [PATCH 6379/6505] Add Forgejo LXC (#3088) --- ct/forgejo.sh | 89 ++++++++++++++++++++++++++++++++++++++ install/forgejo-install.sh | 69 +++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 ct/forgejo.sh create mode 100644 install/forgejo-install.sh diff --git a/ct/forgejo.sh b/ct/forgejo.sh new file mode 100644 index 00000000..9df120ba --- /dev/null +++ b/ct/forgejo.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { + clear + cat <<"EOF" + ______ _ + / ____/___ _________ ___ (_)___ + / /_ / __ \/ ___/ __ `/ _ \ / / __ \ + / __/ / /_/ / / / /_/ / __/ / / /_/ / +/_/ \____/_/ \__, /\___/_/ /\____/ + /____/ /___/ + +EOF +} +header_info +echo -e "Loading..." +APP="Forgejo" +var_disk="10" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/forgejo ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Stopping ${APP}" +systemctl stop forgejo +msg_ok "Stopped ${APP}" + +msg_info "Updating ${APP}" +RELEASE=$(curl -s https://codeberg.org/api/v1/repos/forgejo/forgejo/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') +wget -qO forgejo-$RELEASE-linux-amd64 "https://codeberg.org/forgejo/forgejo/releases/download/v${RELEASE}/forgejo-${RELEASE}-linux-amd64" +rm -rf /opt/forgejo/* +cp -r forgejo-$RELEASE-linux-amd64 /opt/forgejo/forgejo-$RELEASE-linux-amd64 +chmod +x /opt/forgejo/forgejo-$RELEASE-linux-amd64 +ln -sf /opt/forgejo/forgejo-$RELEASE-linux-amd64 /usr/local/bin/forgejo +msg_ok "Updated ${APP}" + +msg_info "Cleaning" +rm -rf forgejo-$RELEASE-linux-amd64 +msg_ok "Cleaned" + +msg_info "Starting ${APP}" +systemctl start forgejo +msg_ok "Started ${APP}" +msg_ok "Updated Successfully" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/install/forgejo-install.sh b/install/forgejo-install.sh new file mode 100644 index 00000000..b3bec0e5 --- /dev/null +++ b/install/forgejo-install.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y git +$STD apt-get install -y git-lfs +msg_ok "Installed Dependencies" + +msg_info "Installing Forgejo" +mkdir -p /opt/forgejo +RELEASE=$(curl -s https://codeberg.org/api/v1/repos/forgejo/forgejo/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//') +wget -qO /opt/forgejo/forgejo-$RELEASE-linux-amd64 "https://codeberg.org/forgejo/forgejo/releases/download/v${RELEASE}/forgejo-${RELEASE}-linux-amd64" +chmod +x /opt/forgejo/forgejo-$RELEASE-linux-amd64 +ln -sf /opt/forgejo/forgejo-$RELEASE-linux-amd64 /usr/local/bin/forgejo +msg_ok "Installed Forgejo" + +msg_info "Setting up Forgejo" +$STD adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git +mkdir /var/lib/forgejo +chown git:git /var/lib/forgejo +chmod 750 /var/lib/forgejo +mkdir /etc/forgejo +chown root:git /etc/forgejo +chmod 770 /etc/forgejo +msg_ok "Setup Forgejo" + +msg_info "Creating Service" +cat </etc/systemd/system/forgejo.service +[Unit] +Description=Forgejo +After=syslog.target +After=network.target +[Service] +RestartSec=2s +Type=simple +User=git +Group=git +WorkingDirectory=/var/lib/forgejo/ +ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini +Restart=always +Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/forgejo +[Install] +WantedBy=multi-user.target +EOF +$STD systemctl enable -q --now forgejo +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From ad1cbf085e5863129a8d07e784d22a481cf0eeca Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 03:36:43 -0400 Subject: [PATCH 6380/6505] Update forgejo-install.sh tweak --- install/forgejo-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/forgejo-install.sh b/install/forgejo-install.sh index b3bec0e5..a2e28169 100644 --- a/install/forgejo-install.sh +++ b/install/forgejo-install.sh @@ -57,7 +57,7 @@ Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/forgejo [Install] WantedBy=multi-user.target EOF -$STD systemctl enable -q --now forgejo +systemctl enable -q --now forgejo msg_ok "Created Service" motd_ssh From 17f54c5f8b5c04d9e3a5abc9c741906c69965dc1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 03:37:59 -0400 Subject: [PATCH 6381/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12d94730..d2b6e065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-30 + +### Changed + +- **Forgejo LXC** + - NEW Script + ## 2024-05-28 ### Changed From e842d2ec3d8f358eed443be2ecbecb2f3b4137d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 13:14:37 -0400 Subject: [PATCH 6382/6505] Update USER_SUBMITTED_GUIDES.md add Techno Tim --- USER_SUBMITTED_GUIDES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USER_SUBMITTED_GUIDES.md b/USER_SUBMITTED_GUIDES.md index 8ac04a12..e3c8ffdd 100644 --- a/USER_SUBMITTED_GUIDES.md +++ b/USER_SUBMITTED_GUIDES.md @@ -7,6 +7,8 @@ In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. +[Proxmox Automation with Proxmox Helper Scripts!](https://www.youtube.com/watch?v=kcpu4z5eSEU) + [Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835) [How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/) From 9bbe81fe4279fd83a64597271e1c0769257e6225 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 21:05:15 -0400 Subject: [PATCH 6383/6505] Update dashy-install.sh update node.js to 20.x --- install/dashy-install.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index d2bbc833..aa85ef4b 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -19,13 +19,15 @@ $STD apt-get install -y sudo $STD apt-get install -y mc msg_ok "Installed Dependencies" -msg_info "Installing Node.js (Patience)" -$STD apt-get install -y npm -$STD npm cache clean -f -$STD npm install -g n -$STD n 16.20.1 -$STD npm install -g pnpm -ln -sf /usr/local/bin/node /usr/bin/node +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs msg_ok "Installed Node.js" msg_info "Installing Yarn" From 22c03c89d310f2dc3417c91e9fd47da85a6b9af5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 21:09:11 -0400 Subject: [PATCH 6384/6505] Update dashy-install.sh add gpg --- install/dashy-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index aa85ef4b..992161ff 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc +$STD apt-get install -y gpg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" From faf133ffed2a8d2c7b98e186e0b3f6b7f1fda2aa Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 21:27:36 -0400 Subject: [PATCH 6385/6505] Update dashy-install.sh tweak --- install/dashy-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 992161ff..4ae6bf5d 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -33,7 +33,6 @@ msg_ok "Installed Node.js" msg_info "Installing Yarn" $STD npm install -g yarn -ln -sf /usr/local/bin/yarn /usr/bin/yarn msg_ok "Installed Yarn" RELEASE=$(curl -s https://api.github.com/repos/Lissy93/dashy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From 44fc9b43cc756cc908a0c289e77b682bfa73f23c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 21:40:23 -0400 Subject: [PATCH 6386/6505] Update dashy-install.sh tweak --- install/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 4ae6bf5d..4436e6aa 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -40,7 +40,7 @@ msg_info "Installing Dashy ${RELEASE} (Patience)" mkdir -p /opt/dashy wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 cd /opt/dashy -sed -i 's/NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build/NODE_OPTIONS=yarn vue-cli-service build/' /opt/dashy/package.json +#sed -i 's/NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build/NODE_OPTIONS=yarn vue-cli-service build/' /opt/dashy/package.json $STD yarn $STD yarn build echo "${RELEASE}" >/opt/${APPLICATION}_version.txt From 3dd1da2cf14f9829d31916b31810a8941c675f69 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 22:04:10 -0400 Subject: [PATCH 6387/6505] Update dashy-install.sh test --- install/dashy-install.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 4436e6aa..4db71a27 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -41,8 +41,10 @@ mkdir -p /opt/dashy wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 cd /opt/dashy #sed -i 's/NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build/NODE_OPTIONS=yarn vue-cli-service build/' /opt/dashy/package.json -$STD yarn -$STD yarn build +#$STD yarn +#$STD yarn build +$STD npm install +$STD npm run build echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_ok "Installed Dashy ${RELEASE}" From 2e268c2f49e7d40399973db07b692c2ef72392c7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 22:12:34 -0400 Subject: [PATCH 6388/6505] Update dashy-install.sh fix install --- install/dashy-install.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index 4db71a27..d7c31367 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -31,18 +31,11 @@ $STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" -msg_info "Installing Yarn" -$STD npm install -g yarn -msg_ok "Installed Yarn" - RELEASE=$(curl -s https://api.github.com/repos/Lissy93/dashy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') msg_info "Installing Dashy ${RELEASE} (Patience)" mkdir -p /opt/dashy wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 cd /opt/dashy -#sed -i 's/NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build/NODE_OPTIONS=yarn vue-cli-service build/' /opt/dashy/package.json -#$STD yarn -#$STD yarn build $STD npm install $STD npm run build echo "${RELEASE}" >/opt/${APPLICATION}_version.txt From 0812983a6460b5372c793e1205c5748edcc1b896 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 22:22:30 -0400 Subject: [PATCH 6389/6505] Update dashy-install.sh fix service --- install/dashy-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dashy-install.sh b/install/dashy-install.sh index d7c31367..a81749ae 100644 --- a/install/dashy-install.sh +++ b/install/dashy-install.sh @@ -49,7 +49,7 @@ Description=dashy [Service] Type=simple WorkingDirectory=/opt/dashy -ExecStart=/usr/bin/yarn start +ExecStart=/usr/bin/npm start [Install] WantedBy=multi-user.target EOF From 37f42468ba295b42f4cd636fb31d8eacbd2703ab Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 30 May 2024 22:29:14 -0400 Subject: [PATCH 6390/6505] Update dashy.sh fix update Breaking Change --- ct/dashy.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ct/dashy.sh b/ct/dashy.sh index 314802db..60ea57db 100644 --- a/ct/dashy.sh +++ b/ct/dashy.sh @@ -75,10 +75,9 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP} rm -rf /opt/dashy mkdir -p /opt/dashy wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1 - sed -i 's/NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build/NODE_OPTIONS=yarn vue-cli-service build/' /opt/dashy/package.json cd /opt/dashy - yarn &>/dev/null - yarn build &>/dev/null + npm install &>/dev/null + npm run build &>/dev/null echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated ${APP} to ${RELEASE}" From fc9dff220b4ea426d3a75178ad8accacae4683ca Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 May 2024 16:00:33 -0400 Subject: [PATCH 6391/6505] Update build.func Mask passwords Closes https://github.com/tteck/Proxmox/issues/3103 --- misc/build.func | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index cd87d2c7..7a5bffd5 100644 --- a/misc/build.func +++ b/misc/build.func @@ -232,16 +232,24 @@ advanced_settings() { done while true; do - if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then + if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD (leave blank for automatic login)" 3>&1 1>&2 2>&3); then if [[ ! -z "$PW1" ]]; then if [[ "$PW1" == *" "* ]]; then whiptail --msgbox "Password cannot contain spaces. Please try again." 8 58 elif [ ${#PW1} -lt 5 ]; then whiptail --msgbox "Password must be at least 5 characters long. Please try again." 8 58 else - PW="-password $PW1" - echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" - break + if PW2=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "\nVerify Root Password" 9 58 --title "PASSWORD VERIFICATION" 3>&1 1>&2 2>&3); then + if [[ "$PW1" == "$PW2" ]]; then + PW="-password $PW1" + echo -e "${DGN}Using Root Password: ${BGN}********${CL}" + break + else + whiptail --msgbox "Passwords do not match. Please try again." 8 58 + fi + else + exit-script + fi fi else PW1="Automatic Login" From 5e515c1e23156617e16219668d5dea8e839542ce Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 31 May 2024 16:48:07 -0400 Subject: [PATCH 6392/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2b6e065..7fa13f54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-05-31 + +### Changed + +- **Advanced Settings** + - Passwords are now masked + ## 2024-05-30 ### Changed From d5c0d165dac3480acde3ec8d3e39f0bdb6ed140b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 2 Jun 2024 08:00:22 -0400 Subject: [PATCH 6393/6505] tweak --- install/aria2-install.sh | 4 ++-- install/bazarr-install.sh | 4 ++-- install/commafeed-install.sh | 4 ++-- install/deconz-install.sh | 4 ++-- install/emby-install.sh | 4 ++-- install/grocy-install.sh | 4 ++-- install/hivemq-install.sh | 4 ++-- install/lidarr-install.sh | 4 ++-- install/navidrome-install.sh | 4 ++-- install/nginxproxymanager-install.sh | 4 ++-- install/omada-install.sh | 4 ++-- install/paperless-ngx-install.sh | 4 ++-- install/prometheus-install.sh | 4 ++-- install/prowlarr-install.sh | 4 ++-- install/radarr-install.sh | 4 ++-- install/readarr-install.sh | 4 ++-- install/runtipi-install.sh | 4 ++-- install/sftpgo-install.sh | 4 ++-- install/stirling-pdf-install.sh | 4 ++-- install/tdarr-install.sh | 4 ++-- install/trilium-install.sh | 4 ++-- install/whisparr-install.sh | 4 ++-- install/zoraxy-install.sh | 4 ++-- install/zwave-js-ui-install.sh | 4 ++-- 24 files changed, 48 insertions(+), 48 deletions(-) diff --git a/install/aria2-install.sh b/install/aria2-install.sh index e57b9e8a..f246bc9d 100644 --- a/install/aria2-install.sh +++ b/install/aria2-install.sh @@ -93,6 +93,6 @@ customize msg_info "Cleaning up" rm AriaNg-*-AllInOne.zip -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" \ No newline at end of file diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh index 812ecefe..5f5e6ac4 100755 --- a/install/bazarr-install.sh +++ b/install/bazarr-install.sh @@ -62,6 +62,6 @@ customize msg_info "Cleaning up" rm -rf bazarr.zip -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" \ No newline at end of file diff --git a/install/commafeed-install.sh b/install/commafeed-install.sh index 3df462f0..8db106e7 100644 --- a/install/commafeed-install.sh +++ b/install/commafeed-install.sh @@ -55,6 +55,6 @@ customize msg_info "Cleaning up" rm -rf zulu-repo_1.0.0-3_all.deb -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/deconz-install.sh b/install/deconz-install.sh index 614129e7..203f5191 100644 --- a/install/deconz-install.sh +++ b/install/deconz-install.sh @@ -58,6 +58,6 @@ customize msg_info "Cleaning up" rm -rf $libssl -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/emby-install.sh b/install/emby-install.sh index 99f5ebfe..bc6ba9be 100644 --- a/install/emby-install.sh +++ b/install/emby-install.sh @@ -46,7 +46,7 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean rm emby-server-deb_${LATEST}_amd64.deb msg_ok "Cleaned" diff --git a/install/grocy-install.sh b/install/grocy-install.sh index f3dc7f57..e47eb8bc 100644 --- a/install/grocy-install.sh +++ b/install/grocy-install.sh @@ -65,7 +65,7 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean rm -rf /root/grocy_${latest}.zip msg_ok "Cleaned" diff --git a/install/hivemq-install.sh b/install/hivemq-install.sh index 8e66f3b2..5234a49b 100644 --- a/install/hivemq-install.sh +++ b/install/hivemq-install.sh @@ -48,6 +48,6 @@ customize msg_info "Cleaning up" rm -rf hivemq-ce-${RELEASE}.zip rm -rf ../hivemq-ce-${RELEASE} -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/lidarr-install.sh b/install/lidarr-install.sh index 846b4de0..0970ef18 100644 --- a/install/lidarr-install.sh +++ b/install/lidarr-install.sh @@ -55,6 +55,6 @@ customize msg_info "Cleaning up" rm -rf Lidarr.master.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh index 50f68d5b..42235dc8 100644 --- a/install/navidrome-install.sh +++ b/install/navidrome-install.sh @@ -76,7 +76,7 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean rm -rf /root/Navidrome.tar.gz msg_ok "Cleaned" diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 4a0873a8..663c9607 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -202,6 +202,6 @@ msg_ok "Started Services" msg_info "Cleaning up" rm -rf ../nginx-proxy-manager-* systemctl restart openresty -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/omada-install.sh b/install/omada-install.sh index d3768a98..8bd0f1f9 100644 --- a/install/omada-install.sh +++ b/install/omada-install.sh @@ -50,6 +50,6 @@ customize msg_info "Cleaning up" rm -rf ${latest_version} mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb $libssl -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 44df6824..2a92400c 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -220,6 +220,6 @@ customize msg_info "Cleaning up" rm -rf /opt/paperless/docker -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/prometheus-install.sh b/install/prometheus-install.sh index a04baa6f..5d2e95cd 100644 --- a/install/prometheus-install.sh +++ b/install/prometheus-install.sh @@ -58,7 +58,7 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean rm -rf ../prometheus-${RELEASE}.linux-amd64 ../prometheus-${RELEASE}.linux-amd64.tar.gz msg_ok "Cleaned" diff --git a/install/prowlarr-install.sh b/install/prowlarr-install.sh index 7270f471..39a56fac 100644 --- a/install/prowlarr-install.sh +++ b/install/prowlarr-install.sh @@ -53,6 +53,6 @@ customize msg_info "Cleaning up" rm -rf Prowlarr.master.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/radarr-install.sh b/install/radarr-install.sh index 4839b90a..dc074251 100644 --- a/install/radarr-install.sh +++ b/install/radarr-install.sh @@ -53,6 +53,6 @@ customize msg_info "Cleaning up" rm -rf Radarr.master.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/readarr-install.sh b/install/readarr-install.sh index 9ba9bc21..c3afc66d 100644 --- a/install/readarr-install.sh +++ b/install/readarr-install.sh @@ -53,6 +53,6 @@ customize msg_info "Cleaning up" rm -rf Readarr.develop.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/runtipi-install.sh b/install/runtipi-install.sh index 584ea16b..f39bb3af 100644 --- a/install/runtipi-install.sh +++ b/install/runtipi-install.sh @@ -35,6 +35,6 @@ customize msg_info "Cleaning up" rm /opt/install.sh -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/sftpgo-install.sh b/install/sftpgo-install.sh index cba32803..809ac74c 100644 --- a/install/sftpgo-install.sh +++ b/install/sftpgo-install.sh @@ -42,6 +42,6 @@ customize msg_info "Cleaning up" rm -rf $RELEASE -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index cc26eec7..f0c802a2 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -115,6 +115,6 @@ customize msg_info "Cleaning up" rm -rf v$RELEASE.tar.gz /zulu-repo_1.0.0-3_all.deb -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/tdarr-install.sh b/install/tdarr-install.sh index adf423cb..dccd9428 100644 --- a/install/tdarr-install.sh +++ b/install/tdarr-install.sh @@ -99,6 +99,6 @@ customize msg_info "Cleaning up" rm -rf Tdarr_Updater.zip -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/trilium-install.sh b/install/trilium-install.sh index cf6a37f0..6e7861a6 100644 --- a/install/trilium-install.sh +++ b/install/trilium-install.sh @@ -53,7 +53,7 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean rm -rf /root/trilium-linux-x64-server-$RELEASE.tar.xz msg_ok "Cleaned" diff --git a/install/whisparr-install.sh b/install/whisparr-install.sh index 66cb5010..16d20893 100644 --- a/install/whisparr-install.sh +++ b/install/whisparr-install.sh @@ -53,6 +53,6 @@ customize msg_info "Cleaning up" rm -rf Whisparr.develop.*.tar.gz -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/zoraxy-install.sh b/install/zoraxy-install.sh index 0938abc2..73787ed1 100644 --- a/install/zoraxy-install.sh +++ b/install/zoraxy-install.sh @@ -58,6 +58,6 @@ customize msg_info "Cleaning up" rm -rf $RELEASE -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/zwave-js-ui-install.sh b/install/zwave-js-ui-install.sh index 0b20538c..c1966ed4 100644 --- a/install/zwave-js-ui-install.sh +++ b/install/zwave-js-ui-install.sh @@ -48,6 +48,6 @@ customize msg_info "Cleaning up" rm zwave-js-ui-${RELEASE}-linux.zip -$STD apt-get autoremove -$STD apt-get autoclean +$STD apt-get -y autoremove +$STD apt-get -y autoclean msg_ok "Cleaned" From 2f5c95d0ec8b14501cf8ec30e903006fb535c131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Tue, 4 Jun 2024 02:28:39 -0400 Subject: [PATCH 6394/6505] Add Flaresolverr script (#3124) --- ct/flaresolverr.sh | 86 +++++++++++++++++++++++++++++++++ install/flaresolverr-install.sh | 65 +++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 ct/flaresolverr.sh create mode 100644 install/flaresolverr-install.sh diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh new file mode 100644 index 00000000..880b2426 --- /dev/null +++ b/ct/flaresolverr.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/remz1337/Proxmox/remz/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: remz1337 +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ________ _____ __ + / ____/ /___ _________ / ___/____ / / _____ __________ + / /_ / / __ `/ ___/ _ \\__ \/ __ \/ / | / / _ \/ ___/ ___/ + / __/ / / /_/ / / / __/__/ / /_/ / /| |/ / __/ / / / +/_/ /_/\__,_/_/ \___/____/\____/_/ |___/\___/_/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="FlareSolverr" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + header_info + msg_info "Updating $APP LXC" + systemctl stop flaresolverr + + # install flaresolverr + RELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) + wget -q https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz + tar -xzf flaresolverr_linux_x64.tar.gz -C /opt + rm flaresolverr_linux_x64.tar.gz + + systemctl start flaresolverr + msg_ok "Updated $APP LXC" + exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 512 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:8191${CL} \n" diff --git a/install/flaresolverr-install.sh b/install/flaresolverr-install.sh new file mode 100644 index 00000000..abc8207a --- /dev/null +++ b/install/flaresolverr-install.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: remz1337 +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y apt-transport-https wget gpg xvfb +msg_ok "Installed Dependencies" + +msg_info "Installing Chrome" +wget -qO- https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg +echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list +$STD apt update +$STD apt install -y google-chrome-stable +msg_ok "Installed Chrome" + +msg_info "Installing FlareSolverr" +RELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +$STD wget -q https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz +$STD tar -xzf flaresolverr_linux_x64.tar.gz -C /opt +$STD rm flaresolverr_linux_x64.tar.gz +msg_ok "Installed FlareSolverr" + +msg_info "Creating Service" +cat </etc/systemd/system/flaresolverr.service +[Unit] +Description=FlareSolverr +After=network.target +[Service] +SyslogIdentifier=flaresolverr +Restart=always +RestartSec=5 +Type=simple +Environment="LOG_LEVEL=info" +Environment="CAPTCHA_SOLVER=none" +WorkingDirectory=/opt/flaresolverr +ExecStart=/opt/flaresolverr/flaresolverr +TimeoutStopSec=30 +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now flaresolverr.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" \ No newline at end of file From df89bf0cfbaea2ad189459d97140cdabf8f032b9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Jun 2024 02:31:08 -0400 Subject: [PATCH 6395/6505] Update flaresolverr-install.sh tweak --- install/flaresolverr-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/install/flaresolverr-install.sh b/install/flaresolverr-install.sh index abc8207a..3195cc51 100644 --- a/install/flaresolverr-install.sh +++ b/install/flaresolverr-install.sh @@ -18,7 +18,9 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y apt-transport-https wget gpg xvfb +$STD apt-get install -y apt-transport-https +$STD apt-get install -y gpg +$STD apt-get install -y xvfb msg_ok "Installed Dependencies" msg_info "Installing Chrome" @@ -60,6 +62,6 @@ motd_ssh customize msg_info "Cleaning up" -$STD apt-get autoremove -$STD apt-get autoclean -msg_ok "Cleaned" \ No newline at end of file +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From cabfa3ba2fafa1d703ab53b70d2b8749a60322eb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Jun 2024 02:36:46 -0400 Subject: [PATCH 6396/6505] Update flaresolverr-install.sh add version.txt --- install/flaresolverr-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/flaresolverr-install.sh b/install/flaresolverr-install.sh index 3195cc51..93c7fdd4 100644 --- a/install/flaresolverr-install.sh +++ b/install/flaresolverr-install.sh @@ -35,6 +35,7 @@ RELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest - $STD wget -q https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz $STD tar -xzf flaresolverr_linux_x64.tar.gz -C /opt $STD rm flaresolverr_linux_x64.tar.gz +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_ok "Installed FlareSolverr" msg_info "Creating Service" From 99f50a5bc28e21c40040c5bf36f6d6dd7003c62d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Jun 2024 02:46:33 -0400 Subject: [PATCH 6397/6505] Update flaresolverr.sh refactor update --- ct/flaresolverr.sh | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh index 880b2426..eb5b267f 100644 --- a/ct/flaresolverr.sh +++ b/ct/flaresolverr.sh @@ -54,22 +54,21 @@ function default_settings() { } function update_script() { - if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi header_info - msg_info "Updating $APP LXC" - systemctl stop flaresolverr - - # install flaresolverr + if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi RELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) - wget -q https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz - tar -xzf flaresolverr_linux_x64.tar.gz -C /opt - rm flaresolverr_linux_x64.tar.gz - - systemctl start flaresolverr - msg_ok "Updated $APP LXC" + if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Updating $APP LXC" + systemctl stop flaresolverr + wget -q https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz + tar -xzf flaresolverr_linux_x64.tar.gz -C /opt + rm flaresolverr_linux_x64.tar.gz + systemctl start flaresolverr + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated $APP LXC" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi exit } From fc0fbeea701478d043f1b85f500608e2948d79cb Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Jun 2024 03:00:08 -0400 Subject: [PATCH 6398/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fa13f54..0e7d2872 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-06-04 + +### Changed + +- **FlareSolverr LXC** + - NEW Script + ## 2024-05-31 ### Changed From d2805145050d28f9f182eac14eda3dd490a644b5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 4 Jun 2024 21:04:48 -0400 Subject: [PATCH 6399/6505] Update flaresolverr.sh fix build source!! --- ct/flaresolverr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh index eb5b267f..85cc927a 100644 --- a/ct/flaresolverr.sh +++ b/ct/flaresolverr.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/remz1337/Proxmox/remz/misc/build.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # Co-Author: remz1337 From 3c79305bca9a55d68b8263c72f12c042283234d7 Mon Sep 17 00:00:00 2001 From: navels Date: Wed, 5 Jun 2024 02:44:50 -0700 Subject: [PATCH 6400/6505] Update Jackett app when updating Jackett LXC. (#3137) --- ct/jackett.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ct/jackett.sh b/ct/jackett.sh index 096eef89..2ef1598c 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -59,6 +59,15 @@ msg_info "Updating ${APP} LXC" apt-get update &>/dev/null apt-get -y upgrade &>/dev/null msg_ok "Updated ${APP} LXC" +msg_info "Updating ${APP}" +RELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz +systemctl stop jackett +rm -rf /opt/Jackett +tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt +rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz +systemctl start jackett +msg_ok "Updated ${APP} to ${RELEASE}" exit } From 5ed048c9fa2a35980bccf0ebd548b1affc045d01 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Jun 2024 05:48:26 -0400 Subject: [PATCH 6401/6505] Update jackett-install.sh add version.txt --- install/jackett-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/jackett-install.sh b/install/jackett-install.sh index 6f3645aa..8dd59167 100644 --- a/install/jackett-install.sh +++ b/install/jackett-install.sh @@ -24,6 +24,7 @@ RELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_ok "Installed Jackett" msg_info "Creating Service" From 7babad2098c3e619e1adbfc5e0c7afe826fd6b0b Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Jun 2024 05:52:10 -0400 Subject: [PATCH 6402/6505] Update jackett.sh refactor update --- ct/jackett.sh | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/ct/jackett.sh b/ct/jackett.sh index 2ef1598c..45984240 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -55,19 +55,20 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/systemd/system/jackett.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating ${APP} LXC" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated ${APP} LXC" -msg_info "Updating ${APP}" RELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) -wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz -systemctl stop jackett -rm -rf /opt/Jackett -tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt -rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz -systemctl start jackett -msg_ok "Updated ${APP} to ${RELEASE}" +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Updating ${APP}" + wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz + systemctl stop jackett + rm -rf /opt/Jackett + tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt + rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz + systemctl start jackett + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" +else + msg_ok "No update required. ${APP} is already at ${RELEASE}" +fi exit } From 4a2447bed6157a6aa1c1358b8abd6b4ed12d3a2d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Jun 2024 06:05:34 -0400 Subject: [PATCH 6403/6505] Update homepage-install.sh tweak --- install/homepage-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/homepage-install.sh b/install/homepage-install.sh index 4f6d5d91..3221324f 100644 --- a/install/homepage-install.sh +++ b/install/homepage-install.sh @@ -36,6 +36,7 @@ RELEASE=$(curl -s https://api.github.com/repos/gethomepage/homepage/releases/lat msg_info "Installing Homepage v${RELEASE} (Patience)" wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz $STD tar -xzf v${RELEASE}.tar.gz +rm -rf v${RELEASE}.tar.gz mkdir -p /opt/homepage/config mv homepage-${RELEASE}/* /opt/homepage rm -rf homepage-${RELEASE} From 20a1d1ea69af473f7d13db48dcfd7c9ddab92c92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 5 Jun 2024 06:07:02 -0400 Subject: [PATCH 6404/6505] Update homepage.sh fixes https://github.com/tteck/Proxmox/issues/3138 --- ct/homepage.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/homepage.sh b/ct/homepage.sh index 54efa660..716da76b 100644 --- a/ct/homepage.sh +++ b/ct/homepage.sh @@ -69,6 +69,7 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP} systemctl stop homepage wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz tar -xzf v${RELEASE}.tar.gz + rm -rf v${RELEASE}.tar.gz cp -r homepage-${RELEASE}/* /opt/homepage/ rm -rf homepage-${RELEASE} cd /opt/homepage From f396b6153f027725748f19f29bcf5d00406adb1d Mon Sep 17 00:00:00 2001 From: navels Date: Thu, 6 Jun 2024 00:46:09 -0700 Subject: [PATCH 6405/6505] Update jackett.sh (#3140) Prevent error if version file doesn't exist --- ct/jackett.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/jackett.sh b/ct/jackett.sh index 45984240..278373d0 100644 --- a/ct/jackett.sh +++ b/ct/jackett.sh @@ -56,7 +56,7 @@ function update_script() { header_info if [[ ! -f /etc/systemd/system/jackett.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi RELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) -if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then +if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then msg_info "Updating ${APP}" wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz systemctl stop jackett From cd1d295ae1e87d3c5b0f3bd87143167fe346bb3c Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Jun 2024 09:37:19 -0400 Subject: [PATCH 6406/6505] Update microcode.sh update get current microcode version --- misc/microcode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/microcode.sh b/misc/microcode.sh index 083e9c89..44ad9b54 100644 --- a/misc/microcode.sh +++ b/misc/microcode.sh @@ -30,7 +30,7 @@ msg_ok() { echo -e "${BFR} ${CM} ${GN}$1${CL}"; } msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; } header_info -current_microcode=$(journalctl -k | grep -oP "microcode: updated early: [^ ]+ -> \K[^,]+, date = [^ ]+" | head -n 1) +current_microcode=$(journalctl -k | grep -i 'microcode: Current revision:' | grep -oP 'Current revision: \K0x[0-9a-f]+') [ -z "$current_microcode" ] && current_microcode="Not found." intel() { From b40696c41ac49e64503b7aa09711d3fd2b5d436b Mon Sep 17 00:00:00 2001 From: Sayed Ali Alawi <75791634+oldhunterr@users.noreply.github.com> Date: Thu, 6 Jun 2024 17:23:43 +0300 Subject: [PATCH 6407/6505] added Petio (#3142) remove .zip after unzip. make script "silent" --- ct/petio.sh | 73 ++++++++++++++++++++++++++++++++++++++ install/petio-install.sh | 75 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 ct/petio.sh create mode 100644 install/petio-install.sh diff --git a/ct/petio.sh b/ct/petio.sh new file mode 100644 index 00000000..040b0c9b --- /dev/null +++ b/ct/petio.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ _ + / __ \___ / /_(_)___ + / /_/ / _ \/ __/ / __ \ + / ____/ __/ /_/ / /_/ / +/_/ \___/\__/_/\____/ + +EOF +} +header_info +echo -e "Loading..." +APP="Petio" +var_disk="4" +var_cpu="2" +var_ram="1024" +var_os="ubuntu" +var_version="20.04" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/Petio ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP" +systemctl stop petio.service +wget https://petio.tv/releases/latest -O petio-latest.zip +unzip petio-latest.zip -d /opt/Petio +systemctl start petio.service +msg_ok "Updated $APP" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:7777${CL} \n" diff --git a/install/petio-install.sh b/install/petio-install.sh new file mode 100644 index 00000000..05499bd5 --- /dev/null +++ b/install/petio-install.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y gnupg +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing MongoDB 4.4" +wget -qO- https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-4.4.gpg +# Determine OS ID +OS_ID=$(grep '^ID=' /etc/os-release | cut -d'=' -f2) + +if [ "$OS_ID" = "debian" ]; then +echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-4.4.gpg ] http://repo.mongodb.org/apt/debian $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/4.4 main" > /etc/apt/sources.list.d/mongodb-org-4.4.list +else +echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/ubuntu $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/4.4 multiverse" > /etc/apt/sources.list.d/mongodb-org-4.4.list +fi + +$STD apt-get update +$STD apt-get install -y mongodb-org +sed -i 's/bindIp: 127.0.0.1/bindIp: 0.0.0.0/' /etc/mongod.conf +systemctl enable -q --now mongod.service +msg_ok "MongoDB 4.4 Installed" + + +msg_info "Installing Petio" +useradd -M --shell=/bin/false petio +mkdir /opt/Petio +wget -q https://petio.tv/releases/latest -O petio-latest.zip +$STD unzip -q petio-latest.zip -d /opt/Petio +rm -rf petio-latest.zip +chown -R petio:petio /opt/Petio +msg_ok "Installed Petio" + +msg_info "Creating Service" +cat </etc/systemd/system/petio.service +[Unit] +Description=Petio a content request system +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=on-failure +RestartSec=1 +ExecStart=/opt/Petio/bin/petio-linux +User=petio + +EOF +systemctl enable -q --now petio.service +msg_ok "Created Service" + + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 32375279fd59f2a78a7b2e2ad7e5483c709943c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Jun 2024 10:35:34 -0400 Subject: [PATCH 6408/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e7d2872..fa848bf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. - 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** +## 2024-06-06 + +### Changed + +- **Petio LXC** + - NEW Script + ## 2024-06-04 ### Changed From 7d224a726f9fb3a653b82d3c5dca1d3caf8db18f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Jun 2024 17:16:23 -0400 Subject: [PATCH 6409/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa848bf2..05711bb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - **Petio LXC** - NEW Script +- **Website** + - Important notices will now be displayed on the landing page. ## 2024-06-04 From c10903942f397c576eaf650c749819036c67fd2b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Jun 2024 17:20:21 -0400 Subject: [PATCH 6410/6505] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05711bb7..e0a9c672 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@

    All notable changes to this project will be documented in this file.

    - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. -- 🚨 **The scripts in the repository will no longer provide support for Proxmox VE 7 starting from July 2024 (scripts will not execute on PVE7). Subsequent Proxmox VE - Support Lifecycle** ## 2024-06-06 From 0a35b1a5bb3bb8c61aa1e8f95e14048667263101 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 6 Jun 2024 22:24:44 -0400 Subject: [PATCH 6411/6505] Update iventoy-install.sh fix spacing in service file --- install/iventoy-install.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/install/iventoy-install.sh b/install/iventoy-install.sh index 3c3e3953..ea58b59d 100644 --- a/install/iventoy-install.sh +++ b/install/iventoy-install.sh @@ -31,18 +31,18 @@ msg_ok "Installed iVentoy" msg_info "Creating Service" cat </etc/systemd/system/iventoy.service [Unit] -Description =iVentoy PXE Booter -Documentation =https://www.iventoy.com -Wants =network-online.target +Description=iVentoy PXE Booter +Documentation=https://www.iventoy.com +Wants=network-online.target [Service] -Type =forking -Environment =IVENTOY_API_ALL=1 -Environment =IVENTOY_AUTO_RUN=1 -Environment =LIBRARY_PATH=/opt/iventoy/lib/lin64 -Environment =LD_LIBRARY_PATH=/opt/iventoy/lib/lin64 -ExecStart =sh ./iventoy.sh -R start -WorkingDirectory =/opt/iventoy -Restart =on-failure +Type=forking +Environment=IVENTOY_API_ALL=1 +Environment=IVENTOY_AUTO_RUN=1 +Environment=LIBRARY_PATH=/opt/iventoy/lib/lin64 +Environment=LD_LIBRARY_PATH=/opt/iventoy/lib/lin64 +ExecStart=sh ./iventoy.sh -R start +WorkingDirectory=/opt/iventoy +Restart=on-failure [Install] WantedBy=multi-user.target EOF From 9ba59e0b561c9289aa712e7b9872432ec150b48b Mon Sep 17 00:00:00 2001 From: Ryan Date: Sun, 9 Jun 2024 03:23:59 -0400 Subject: [PATCH 6412/6505] Correct ceph enterprise urls (#3157) --- misc/post-pve-install.sh | 4 ++-- misc/pve8-upgrade.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/post-pve-install.sh b/misc/post-pve-install.sh index ec8d7d98..f142b850 100644 --- a/misc/post-pve-install.sh +++ b/misc/post-pve-install.sh @@ -105,9 +105,9 @@ EOF yes) msg_info "Correcting 'ceph package repositories'" cat </etc/apt/sources.list.d/ceph.list -# deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise +# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise # deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription -# deb http://download.proxmox.com/debian/ceph-reef bookworm enterprise +# deb https://enterprise.proxmox.com/debian/ceph-reef bookworm enterprise # deb http://download.proxmox.com/debian/ceph-reef bookworm no-subscription EOF msg_ok "Corrected 'ceph package repositories'" diff --git a/misc/pve8-upgrade.sh b/misc/pve8-upgrade.sh index 86aaee2f..360b339b 100644 --- a/misc/pve8-upgrade.sh +++ b/misc/pve8-upgrade.sh @@ -73,7 +73,7 @@ EOF whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "PVE8 CEPH PACKAGE REPOSITORIES" "The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories." 10 58 msg_info "Enabling 'ceph package repositories'" cat </etc/apt/sources.list.d/ceph.list -# deb http://download.proxmox.com/debian/ceph-quincy bookworm enterprise +# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription EOF msg_ok "Enabled 'ceph package repositories'" From 21c1240c8cde15dad5d323275f6089db49c3eaa4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 10 Jun 2024 17:17:58 -0400 Subject: [PATCH 6413/6505] Update umami-install.sh tweak --- install/umami-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/umami-install.sh b/install/umami-install.sh index 943c0413..8fd103b2 100644 --- a/install/umami-install.sh +++ b/install/umami-install.sh @@ -45,6 +45,8 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8' $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" echo "" >~/umami.creds +echo "Umami Database Credentials" >>~/umami.creds +echo "" >>~/umami.creds echo -e "umami Database User: \e[32m$DB_USER\e[0m" >>~/umami.creds echo -e "umami Database Password: \e[32m$DB_PASS\e[0m" >>~/umami.creds echo -e "umami Database Name: \e[32m$DB_NAME\e[0m" >>~/umami.creds From 9a3a05f75a0542fb5a74dc098546e263ae5eafd9 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jun 2024 13:30:12 -0400 Subject: [PATCH 6414/6505] Create zabbix.sh --- ct/zabbix.sh | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 ct/zabbix.sh diff --git a/ct/zabbix.sh b/ct/zabbix.sh new file mode 100644 index 00000000..3eb578d0 --- /dev/null +++ b/ct/zabbix.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ __ __ _ +/__ / ____ _/ /_ / /_ (_) __ + / / / __ `/ __ \/ __ \/ / |/_/ + / /__/ /_/ / /_/ / /_/ / /> < +/____/\__,_/_.___/_.___/_/_/|_| + +EOF +} +header_info +echo -e "Loading..." +APP="Zabbix" +var_disk="6" +var_cpu="2" +var_ram="4096" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /etc/zabbix/zabbix_server.conf ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +msg_info "Updating $APP LXC" +apt-get update &>/dev/null +apt-get -y upgrade &>/dev/null +msg_ok "Updated $APP LXC" +exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}/zabbix${CL} \n" From 5bc0ddda2205acfa9f2afeaac7f089a26bd25b92 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jun 2024 13:31:22 -0400 Subject: [PATCH 6415/6505] Create zabbix-install.sh --- install/zabbix-install.sh | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 install/zabbix-install.sh diff --git a/install/zabbix-install.sh b/install/zabbix-install.sh new file mode 100644 index 00000000..31416f1d --- /dev/null +++ b/install/zabbix-install.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +msg_ok "Installed Dependencies" + +msg_info "Installing Zabbix" +wget -q https://repo.zabbix.com/zabbix/7.0/debian/pool/main/z/zabbix-release/zabbix-release_7.0-1+debian12_all.deb +$STD dpkg -i zabbix-release_7.0-1+debian12_all.deb +rm zabbix-release_7.0-1+debian12_all.deb +$STD apt-get update +$STD apt-get install -y zabbix-server-pgsql zabbix-frontend-php php8.2-pgsql zabbix-apache-conf zabbix-sql-scripts zabbix-agent +msg_ok "Installed Zabbix" + +msg_info "Setting up PostgreSQL" +$STD apt-get install -y postgresql +DB_NAME=zabbixdb +DB_USER=zabbix +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" +$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" +$STD zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | sudo -u $DB_USER psql $DB_NAME +sed -i "s/^DBName=.*/DBName=$DB_NAME/" /etc/zabbix/zabbix_server.conf +sed -i "s/^DBUser=.*/DBUser=$DB_USER/" /etc/zabbix/zabbix_server.conf +sed -i "s/^# DBPassword=.*/DBPassword=$DB_PASS/" /etc/zabbix/zabbix_server.conf +echo "" >~/zabbix.creds +echo "zabbix Database Credentials" >>~/zabbix.creds +echo "" >>~/zabbix.creds +echo -e "zabbix Database User: \e[32m$DB_USER\e[0m" >>~/zabbix.creds +echo -e "zabbix Database Password: \e[32m$DB_PASS\e[0m" >>~/zabbix.creds +echo -e "zabbix Database Name: \e[32m$DB_NAME\e[0m" >>~/zabbix.creds +msg_ok "Set up PostgreSQL" + +msg_info "Starting Services" +systemctl restart zabbix-server zabbix-agent apache2 +systemctl enable -q zabbix-server zabbix-agent apache2 +msg_ok "Started Services" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From fd114369e9bebc5031af83a90adc97edba3c6693 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jun 2024 13:50:59 -0400 Subject: [PATCH 6416/6505] Update zabbix-install.sh Escape Special Characters --- install/zabbix-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/zabbix-install.sh b/install/zabbix-install.sh index 31416f1d..e70bbed9 100644 --- a/install/zabbix-install.sh +++ b/install/zabbix-install.sh @@ -31,7 +31,8 @@ msg_info "Setting up PostgreSQL" $STD apt-get install -y postgresql DB_NAME=zabbixdb DB_USER=zabbix -DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +RAW_PASS="$(openssl rand -base64 18 | cut -c1-13)" +DB_PASS=$(printf '%s\n' "$RAW_PASS" | sed 's/[&/\]/\\&/g') $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" From 79b138cc6de0f102a9cf6d7998f96ad3c92aec84 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jun 2024 14:19:41 -0400 Subject: [PATCH 6417/6505] Update zabbix-install.sh tweak --- install/zabbix-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/zabbix-install.sh b/install/zabbix-install.sh index e70bbed9..3648f99f 100644 --- a/install/zabbix-install.sh +++ b/install/zabbix-install.sh @@ -31,8 +31,7 @@ msg_info "Setting up PostgreSQL" $STD apt-get install -y postgresql DB_NAME=zabbixdb DB_USER=zabbix -RAW_PASS="$(openssl rand -base64 18 | cut -c1-13)" -DB_PASS=$(printf '%s\n' "$RAW_PASS" | sed 's/[&/\]/\\&/g') +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" From 7ea8bdfb95253c0fba6d7118eb7d18712fa5f472 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jun 2024 15:25:47 -0400 Subject: [PATCH 6418/6505] Update zabbix-install.sh tweak --- install/zabbix-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/zabbix-install.sh b/install/zabbix-install.sh index 3648f99f..c7123dea 100644 --- a/install/zabbix-install.sh +++ b/install/zabbix-install.sh @@ -37,7 +37,7 @@ $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCO $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'" -$STD zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | sudo -u $DB_USER psql $DB_NAME +zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | sudo -u $DB_USER psql $DB_NAME &>/dev/null sed -i "s/^DBName=.*/DBName=$DB_NAME/" /etc/zabbix/zabbix_server.conf sed -i "s/^DBUser=.*/DBUser=$DB_USER/" /etc/zabbix/zabbix_server.conf sed -i "s/^# DBPassword=.*/DBPassword=$DB_PASS/" /etc/zabbix/zabbix_server.conf From 5e5e2c96a509efccbc52c9a4dbfb71cf71ab4f9d Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 11 Jun 2024 15:47:26 -0400 Subject: [PATCH 6419/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0a9c672..99febfbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-06-11 + +### Changed + +- **Zabbix LXC** + - NEW Script + ## 2024-06-06 ### Changed From 60951ff58f1c05a6d31cd6f42837c5297f42cdcb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jun 2024 07:34:42 -0400 Subject: [PATCH 6420/6505] Update homer.sh fixes https://github.com/tteck/Proxmox/issues/3175 --- ct/homer.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ct/homer.sh b/ct/homer.sh index 7d02e053..bfec3090 100644 --- a/ct/homer.sh +++ b/ct/homer.sh @@ -59,11 +59,11 @@ msg_info "Stopping ${APP}" systemctl stop homer msg_ok "Stopped ${APP}" -msg_info "Backing up config.yml" +msg_info "Backing up assets directory" cd ~ -cp -R /opt/homer/assets/config.yml config.yml -cp -R /opt/homer/assets/tools tools -msg_ok "Backed up config.yml and tools directory" +mkdir -p assets-backup +cp -R /opt/homer/assets/. assets-backup +msg_ok "Backed up assets directory" msg_info "Updating ${APP}" rm -rf /opt/homer/* @@ -71,14 +71,14 @@ cd /opt/homer wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip unzip homer.zip &>/dev/null msg_ok "Updated ${APP}" -msg_info "Restoring conf.yml" + +msg_info "Restoring assets directory" cd ~ -cp -R config.yml /opt/homer/assets -cp -R tools /opt/homer/assets -msg_ok "Restored config.yml and tools directory" +cp -Rf assets-backup/. /opt/homer/assets/ +msg_ok "Restored assets directory" msg_info "Cleaning" -rm -rf config.yml tools /opt/homer/homer.zip +rm -rf assets-backup /opt/homer/homer.zip msg_ok "Cleaned" msg_info "Starting ${APP}" From 1a937b10f297abd8f35ee99f02523f7eb87c3612 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:42:04 +0200 Subject: [PATCH 6421/6505] Add new LXC: Matterbridge (#3178) --- ct/matterbridge.sh | 97 +++++++++++++++++++++++++++++++++ install/matterbridge-install.sh | 85 +++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 ct/matterbridge.sh create mode 100644 install/matterbridge-install.sh diff --git a/ct/matterbridge.sh b/ct/matterbridge.sh new file mode 100644 index 00000000..e0d04f26 --- /dev/null +++ b/ct/matterbridge.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ __ __ __ _ __ + / |/ /___ _/ /_/ /____ _____/ /_ _____(_)___/ /___ ____ + / /|_/ / __ `/ __/ __/ _ \/ ___/ __ \/ ___/ / __ / __ `/ _ \ + / / / / /_/ / /_/ /_/ __/ / / /_/ / / / / /_/ / /_/ / __/ +/_/ /_/\__,_/\__/\__/\___/_/ /_.___/_/ /_/\__,_/\__, /\___/ + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Matterbridge" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/matterbridge ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + +RELEASE=$(curl -s https://api.github.com/repos/Luligu/matterbridge/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}') +if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping ${APP} Service" + systemctl stop matterbridge + msg_ok "Stopped ${APP} Service" + + msg_info "Updating ${APP} to ${RELEASE}" + cd /opt/matterbridge + wget -q "https://github.com/Luligu/matterbridge/archive/refs/tags/${RELEASE}.zip" + unzip -q ${RELEASE}.zip + mv matterbridge-${RELEASE} /opt/matterbridge + cd /opt/matterbridge + npm ci >/dev/null 2>&1 + npm run build >/dev/null 2>&1 + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" + + msg_info "Cleaning up" + rm /opt/${RELEASE}.zip + msg_ok "Cleaned" + + msg_info "Starting ${APP} Service" + systemctl start matterbridge + sleep 1 + msg_ok "Started ${APP} Service" + msg_ok "Updated Successfully!\n" +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}:8283${CL} \n" diff --git a/install/matterbridge-install.sh b/install/matterbridge-install.sh new file mode 100644 index 00000000..47948471 --- /dev/null +++ b/install/matterbridge-install.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/Luligu/matterbridge/ + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y --no-install-recommends \ + build-essential \ + unzip \ + curl \ + sudo \ + git \ + make \ + gnupg \ + ca-certificates \ + mc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Install Matterbridge" +RELEASE=$(curl -s https://api.github.com/repos/Luligu/matterbridge/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget -q "https://github.com/Luligu/matterbridge/archive/refs/tags/${RELEASE}.zip" +unzip -q ${RELEASE}.zip +mv matterbridge-${RELEASE} /opt/matterbridge +rm -R ${RELEASE}.zip +cd /opt/matterbridge +$STD npm ci +$STD npm run build +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed Matterbridge" + +msg_info "Creating Service" +cat </etc/systemd/system/matterbridge.service +[Unit] +Description=matterbridge +After=network-online.target + +[Service] +Type=simple +ExecStart=/usr/bin/npm run start:bridge +WorkingDirectory=/opt/matterbridge +StandardOutput=inherit +StandardError=inherit +Restart=always +RestartSec=10s +TimeoutStopSec=30s +User=root +Environment=PATH=/usr/bin:/usr/local/bin:/opt/matterbridge/bin +Environment=NODE_ENV=production + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now matterbridge.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 4020e1b6aed529a04bba95788bab52f423373d3e Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:51:47 +0200 Subject: [PATCH 6422/6505] Add new LXC: MeTube (#3179) --- ct/metube.sh | 100 ++++++++++++++++++++++++++++++++++++++ install/metube-install.sh | 92 +++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 ct/metube.sh create mode 100644 install/metube-install.sh diff --git a/ct/metube.sh b/ct/metube.sh new file mode 100644 index 00000000..57d8b46b --- /dev/null +++ b/ct/metube.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ ______ __ + / |/ /__/_ __/_ __/ /_ ___ + / /|_/ / _ \/ / / / / / __ \/ _ \ + / / / / __/ / / /_/ / /_/ / __/ +/_/ /_/\___/_/ \__,_/_.___/\___/ + +EOF +} +header_info +echo -e "Loading..." +APP="MeTube" +var_disk="10" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/metube ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi +msg_info "Stopping ${APP} Service" +systemctl stop metube +msg_ok "Stopped ${APP} Service" + +msg_info "Updating ${APP} to latest Git" +cd /opt +if [ -d metube_bak ]; then + rm -rf metube_bak +fi +mv metube metube_bak +git clone https://github.com/alexta69/metube /opt/metube >/dev/null 2>&1 +cd /opt/metube/ui +npm install >/dev/null 2>&1 +node_modules/.bin/ng build >/dev/null 2>&1 +cd /opt/metube +cp /opt/metube_bak/.env /opt/metube/ +pip3 install pipenv >/dev/null 2>&1 +pipenv install >/dev/null 2>&1 + +if [ -d "/opt/metube_bak" ]; then +rm -rf /opt/metube_bak +fi +msg_ok "Updated ${APP} to latest Git" + +msg_info "Starting ${APP} Service" +systemctl start metube +sleep 1 +msg_ok "Started ${APP} Service" +msg_ok "Updated Successfully!\n" +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}:8081${CL} \n" \ No newline at end of file diff --git a/install/metube-install.sh b/install/metube-install.sh new file mode 100644 index 00000000..0c418e5d --- /dev/null +++ b/install/metube-install.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/alexta69/metube + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y --no-install-recommends \ + build-essential \ + curl \ + sudo \ + ffmpeg \ + git \ + make \ + gnupg \ + ca-certificates \ + mc +msg_ok "Installed Dependencies" + +msg_info "Installing Python3" +$STD apt-get install -y \ + python3 \ + python3-dev \ + python3-pip \ + python3-venv +msg_ok "Installed Python3" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing MeTube" +$STD git clone https://github.com/alexta69/metube /opt/metube +cd /opt/metube/ui +$STD npm install +$STD node_modules/.bin/ng build +cd /opt/metube +$STD pip3 install pipenv +$STD pipenv install +mkdir -p /opt/metube_downloads /opt/metube_downloads/.metube /opt/metube_downloads/music /opt/metube_downloads/videos +cat </opt/metube/.env +DOWNLOAD_DIR=/opt/metube_downloads +STATE_DIR=/opt/metube_downloads/.metube +TEMP_DIR=/opt/metube_downloads +EOF +msg_ok "Installed MeTube" + +msg_info "Creating Service" +cat </etc/systemd/system/metube.service +[Unit] +Description=Metube - YouTube Downloader +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/metube +EnvironmentFile=/opt/metube/.env +ExecStart=/usr/local/bin/pipenv run python3 app/main.py +Restart=always +User=root + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now metube.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file From 421bccfee844d9fcd304f2c7d519bf60af089c30 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jun 2024 12:58:35 -0400 Subject: [PATCH 6423/6505] Update README.md tweak --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index b9869fc8..9401c778 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@

    Proxmox VE Helper-Scripts

    - Terms of Use | - Website | + Website | Contribute | Guides | Changelog | From 814a9158194b1dc21af23a653434ccc05b68fc5d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jun 2024 12:58:43 -0400 Subject: [PATCH 6424/6505] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99febfbd..372c1e21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,15 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-06-12 + +### Changed + +- **Matterbridge LXC** + - NEW Script +- **Website** + - Reopen the gh-pages site (https://tteck.github.io/Proxmox/) + ## 2024-06-11 ### Changed From c2fe08030770c023bb551c7a7b6454240a16d394 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jun 2024 14:18:07 -0400 Subject: [PATCH 6425/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 372c1e21..c9e02441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ### Changed +- **MeTube LXC** + - NEW Script - **Matterbridge LXC** - NEW Script - **Website** From 3a455a9e9ee272f5a039950df675af230f739d5d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 12 Jun 2024 22:46:08 +0200 Subject: [PATCH 6426/6505] Fix YtDL_Options (Filename to long) (#3183) --- install/metube-install.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/install/metube-install.sh b/install/metube-install.sh index 0c418e5d..726f3f77 100644 --- a/install/metube-install.sh +++ b/install/metube-install.sh @@ -19,6 +19,11 @@ msg_info "Installing Dependencies" $STD apt-get install -y --no-install-recommends \ build-essential \ curl \ + aria2 \ + coreutils \ + gcc \ + g++ \ + musl-dev \ sudo \ ffmpeg \ git \ @@ -60,6 +65,7 @@ cat </opt/metube/.env DOWNLOAD_DIR=/opt/metube_downloads STATE_DIR=/opt/metube_downloads/.metube TEMP_DIR=/opt/metube_downloads +YTDL_OPTIONS={"trim_file_name":10} EOF msg_ok "Installed MeTube" @@ -89,4 +95,4 @@ customize msg_info "Cleaning up" $STD apt-get -y autoremove $STD apt-get -y autoclean -msg_ok "Cleaned" \ No newline at end of file +msg_ok "Cleaned" From 7dca71d2969adc61c9acd82bede390a641f5a27e Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 12 Jun 2024 17:55:37 -0400 Subject: [PATCH 6427/6505] Update calibre-web-install.sh fixes https://github.com/tteck/Proxmox/issues/3184 --- install/calibre-web-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/calibre-web-install.sh b/install/calibre-web-install.sh index 6d2b1445..cdc5653f 100644 --- a/install/calibre-web-install.sh +++ b/install/calibre-web-install.sh @@ -36,6 +36,7 @@ msg_info "Installing Calibre-Web" mkdir -p /opt/calibre-web $STD wget https://github.com/janeczku/calibre-web/raw/master/library/metadata.db -P /opt/calibre-web $STD pip install calibreweb +$STD pip install jsonschema msg_ok "Installed Calibre-Web" msg_info "Creating Service" From ea1864306907b0948349e6a5e38f176b0c373b00 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 13 Jun 2024 13:38:29 +0200 Subject: [PATCH 6428/6505] Add new LXC: Spoolman (#3186) --- ct/spoolman.sh | 103 ++++++++++++++++++++++++++++++++++++ install/spoolman-install.sh | 75 ++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 ct/spoolman.sh create mode 100644 install/spoolman-install.sh diff --git a/ct/spoolman.sh b/ct/spoolman.sh new file mode 100644 index 00000000..dadff3bf --- /dev/null +++ b/ct/spoolman.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ __ + / ___/____ ____ ____ / /___ ___ ____ _____ + \__ \/ __ \/ __ \/ __ \/ / __ `__ \/ __ `/ __ \ + ___/ / /_/ / /_/ / /_/ / / / / / / / /_/ / / / / +/____/ .___/\____/\____/_/_/ /_/ /_/\__,_/_/ /_/ + /_/ +EOF +} +header_info +echo -e "Loading..." +APP="Spoolman" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/spoolman ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi +RELEASE=$(wget -q https://github.com/Donkie/Spoolman/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + + msg_info "Stopping ${APP} Service" + systemctl stop spoolman + msg_ok "Stopped ${APP} Service" + + msg_info "Updating ${APP} to ${RELEASE}" + cd /opt + rm -rf spoolman_bak + mv spoolman spoolman_bak + wget -q https://github.com/Donkie/Spoolman/releases/download/${RELEASE}/spoolman.zip + unzip -q spoolman.zip -d spoolman + cd spoolman + pip3 install -r requirements.txt >/dev/null 2>&1 + cp .env.example .env + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" + + msg_info "Starting ${APP} Service" + systemctl start spoolman + msg_ok "Started ${APP} Service" + + msg_info "Cleaning up" + rm -rf /opt/spoolman.zip + msg_ok "Cleaned" + + msg_ok "Updated Successfully!\n" +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}:7912${CL} \n" diff --git a/install/spoolman-install.sh b/install/spoolman-install.sh new file mode 100644 index 00000000..dc2bc31d --- /dev/null +++ b/install/spoolman-install.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/Donkie/Spoolman + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + build-essential \ + curl \ + sudo \ + make \ + libpq-dev \ + gpg \ + ca-certificates \ + mc +msg_ok "Installed Dependencies" + +msg_info "Installing Python3" +$STD apt-get install -y \ + python3-dev \ + python3-setuptools \ + python3-wheel \ + python3-pip +msg_ok "Installed Python3" + +msg_info "Installing Spoolman" +cd /opt +RELEASE=$(wget -q https://github.com/Donkie/Spoolman/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +cd /opt +wget -q https://github.com/Donkie/Spoolman/releases/download/$RELEASE/spoolman.zip +unzip -q spoolman.zip -d spoolman +rm -rf spoolman.zip +cd spoolman +$STD pip3 install -r requirements.txt +cp .env.example .env +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed Spoolman" + +msg_info "Creating Service" +cat </etc/systemd/system/spoolman.service +[Unit] +Description=Spoolman +After=network.target +[Service] +Type=simple +WorkingDirectory=/opt/spoolman +EnvironmentFile=/opt/spoolman/.env +ExecStart=uvicorn spoolman.main:app --host 0.0.0.0 --port 7912 +Restart=always +User=root +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now spoolman.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From b6f8e46eaa0989757993eeb1b371ec1fbb7741c2 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jun 2024 08:01:37 -0400 Subject: [PATCH 6429/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9e02441..e3b83613 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-06-13 + +### Changed + +- **Spoolman LXC** + - NEW Script + ## 2024-06-12 ### Changed From 8caf9598b4bb244b68bfe505dcc24602b9b8b19f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jun 2024 08:14:03 -0400 Subject: [PATCH 6430/6505] Update paperless-ngx-install.sh tweak --- install/paperless-ngx-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh index 2a92400c..7edabf2b 100644 --- a/install/paperless-ngx-install.sh +++ b/install/paperless-ngx-install.sh @@ -172,6 +172,7 @@ cat </etc/systemd/system/paperless-task-queue.service [Unit] Description=Paperless Celery Workers Requires=redis.service +After=postgresql.service [Service] WorkingDirectory=/opt/paperless/src From d3ff7c36e10d4984a648966b9b4c113f087b7102 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jun 2024 17:36:02 -0400 Subject: [PATCH 6431/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3b83613..1c1b5566 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ### Changed +- **Website** + - If the Changelog has changed recently, the link on the website will pulse. - **Spoolman LXC** - NEW Script From 5886f1240eac74257c1fe8fcc06759c129a5b076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20B=C3=A9dard-Couture?= Date: Thu, 13 Jun 2024 22:33:41 -0400 Subject: [PATCH 6432/6505] Add Peanut script (#3185) --- ct/peanut.sh | 89 +++++++++++++++++++++++++++++++++++++++ install/peanut-install.sh | 79 ++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 ct/peanut.sh create mode 100644 install/peanut-install.sh diff --git a/ct/peanut.sh b/ct/peanut.sh new file mode 100644 index 00000000..02744844 --- /dev/null +++ b/ct/peanut.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/remz1337/Proxmox/remz/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: remz1337 +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ + / __ \___ ____ _____ __ __/ /_ + / /_/ / _ \/ __ `/ __ \/ / / / __/ + / ____/ __/ /_/ / / / / /_/ / /_ +/_/ \___/\__,_/_/ /_/\__,_/\__/ + +EOF +} +header_info +echo -e "Loading..." +APP="Peanut" +var_disk="4" +var_cpu="2" +var_ram="2048" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + header_info + if [[ ! -f /etc/systemd/system/peanut.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + RELEASE=$(curl -sL https://api.github.com/repos/Brandawg93/PeaNUT/releases/latest | grep '"tag_name":' | cut -d'"' -f4) + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Updating $APP LXC" + systemctl stop peanut + wget -qO peanut.tar.gz https://api.github.com/repos/Brandawg93/PeaNUT/tarball/${RELEASE} + tar -xzf peanut.tar.gz -C /opt/peanut --strip-components 1 + rm peanut.tar.gz + cd /opt/peanut + pnpm i &>/dev/null + pnpm run build &>/dev/null + cp -r .next/static .next/standalone/.next/ + systemctl start peanut + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated $APP to ${RELEASE}" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi + exit +} + +start +build_container +description + +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 1024 +pct set $CTID -cores 1 +msg_ok "Set Container to Normal Resources" +msg_ok "Completed Successfully!\n" +echo -e "${APP} should be reachable by going to the following URL. + ${BL}http://${IP}:3000${CL} \n" diff --git a/install/peanut-install.sh b/install/peanut-install.sh new file mode 100644 index 00000000..f32e764f --- /dev/null +++ b/install/peanut-install.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: remz1337 +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +msg_ok "Installed Dependencies" + +msg_info "Installing Node.js" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing NUT" +$STD apt-get install -y nut-client +msg_ok "Installed NUT" + +msg_info "Installing Peanut" +RELEASE=$(curl -sL https://api.github.com/repos/Brandawg93/PeaNUT/releases/latest | grep '"tag_name":' | cut -d'"' -f4) +wget -qO peanut.tar.gz https://api.github.com/repos/Brandawg93/PeaNUT/tarball/${RELEASE} +mkdir -p /opt/peanut +tar -xzf peanut.tar.gz -C /opt/peanut --strip-components 1 +rm peanut.tar.gz +cd /opt/peanut +$STD npm install -g pnpm +$STD pnpm i +$STD pnpm run build +cp -r .next/static .next/standalone/.next/ +msg_ok "Installed Peanut" + +msg_info "Creating Service" +cat </etc/systemd/system/peanut.service +[Unit] +Description=Peanut +After=network.target +[Service] +SyslogIdentifier=peanut +Restart=always +RestartSec=5 +Type=simple +Environment="NODE_ENV=production" +Environment="NUT_HOST=localhost" +Environment="NUT_PORT=3493" +Environment="WEB_HOST=0.0.0.0" +Environment="WEB_PORT=3000" +WorkingDirectory=/opt/peanut +ExecStart=node /opt/peanut/.next/standalone/server.js +TimeoutStopSec=30 +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now peanut.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file From 0e284df495ffa52a7e68648f4078fd217e63c46b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jun 2024 22:36:43 -0400 Subject: [PATCH 6433/6505] Update peanut.sh tweak --- ct/peanut.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ct/peanut.sh b/ct/peanut.sh index 02744844..751ad2da 100644 --- a/ct/peanut.sh +++ b/ct/peanut.sh @@ -9,17 +9,17 @@ source <(curl -s https://raw.githubusercontent.com/remz1337/Proxmox/remz/misc/bu function header_info { clear cat <<"EOF" - ____ __ - / __ \___ ____ _____ __ __/ /_ - / /_/ / _ \/ __ `/ __ \/ / / / __/ - / ____/ __/ /_/ / / / / /_/ / /_ -/_/ \___/\__,_/_/ /_/\__,_/\__/ + ____ _ ____ ________ + / __ \___ ____ _/ | / / / / /_ __/ + / /_/ / _ \/ __ `/ |/ / / / / / / + / ____/ __/ /_/ / /| / /_/ / / / +/_/ \___/\__,_/_/ |_/\____/ /_/ EOF } header_info echo -e "Loading..." -APP="Peanut" +APP="PeaNUT" var_disk="4" var_cpu="2" var_ram="2048" @@ -58,7 +58,7 @@ function update_script() { if [[ ! -f /etc/systemd/system/peanut.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi RELEASE=$(curl -sL https://api.github.com/repos/Brandawg93/PeaNUT/releases/latest | grep '"tag_name":' | cut -d'"' -f4) if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - msg_info "Updating $APP LXC" + msg_info "Updating $APP to ${RELEASE}" systemctl stop peanut wget -qO peanut.tar.gz https://api.github.com/repos/Brandawg93/PeaNUT/tarball/${RELEASE} tar -xzf peanut.tar.gz -C /opt/peanut --strip-components 1 From 2131ee2c3b593eec0d31588a1fde4797c6cdbea4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 13 Jun 2024 22:52:22 -0400 Subject: [PATCH 6434/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c1b5566..19ca6e9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ### Changed +- **PeaNUT LXC** + - NEW Script - **Website** - If the Changelog has changed recently, the link on the website will pulse. - **Spoolman LXC** From 3885ca059009d2e41f5c22b174880969b71e857d Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Jun 2024 04:32:26 -0400 Subject: [PATCH 6435/6505] Update peanut.sh fix source --- ct/peanut.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/peanut.sh b/ct/peanut.sh index 751ad2da..fb2975d7 100644 --- a/ct/peanut.sh +++ b/ct/peanut.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/remz1337/Proxmox/remz/misc/build.func) +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) # Copyright (c) 2021-2024 tteck # Author: tteck (tteckster) # Co-Author: remz1337 From dbbc2ed0a47e94043934f466af0704bbb88e307d Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:06:18 +0200 Subject: [PATCH 6436/6505] Add new LXC: MySpeed (#3195) --- ct/myspeed.sh | 103 +++++++++++++++++++++++++++++++++++++ install/myspeed-install.sh | 76 +++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 ct/myspeed.sh create mode 100644 install/myspeed-install.sh diff --git a/ct/myspeed.sh b/ct/myspeed.sh new file mode 100644 index 00000000..23c98878 --- /dev/null +++ b/ct/myspeed.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ ___ _____ __ + / |/ /_ __/ ___/____ ___ ___ ____/ / + / /|_/ / / / /\__ \/ __ \/ _ \/ _ \/ __ / + / / / / /_/ /___/ / /_/ / __/ __/ /_/ / +/_/ /_/\__, //____/ .___/\___/\___/\__,_/ + /____/ /_/ + +EOF +} +header_info +echo -e "Loading..." +APP="MySpeed" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -d /opt/myspeed ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi +RELEASE=$(wget -q https://github.com/gnmyt/myspeed/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) +if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + + msg_info "Stopping ${APP} Service" + systemctl stop myspeed + msg_ok "Stopped ${APP} Service" + + msg_info "Updating ${APP} to ${RELEASE}" + cd /opt + rm -rf myspeed_bak + mv myspeed myspeed_bak + wget -q https://github.com/gnmyt/myspeed/releases/download/v$RELEASE/MySpeed-$RELEASE.zip + unzip -q MySpeed-$RELEASE.zip -d myspeed + cd myspeed + npm install >/dev/null 2>&1 + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" + + msg_info "Starting ${APP} Service" + systemctl start myspeed + msg_ok "Started ${APP} Service" + + msg_info "Cleaning up" + rm -rf MySpeed-$RELEASE.zip + msg_ok "Cleaned" + + msg_ok "Updated Successfully!\n" +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}:5216${CL} \n" diff --git a/install/myspeed-install.sh b/install/myspeed-install.sh new file mode 100644 index 00000000..45ef62a6 --- /dev/null +++ b/install/myspeed-install.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/gnmyt/myspeed + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + sudo \ + make \ + gpg \ + ca-certificates \ + mc +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing MySpeed" +RELEASE=$(wget -q https://github.com/gnmyt/myspeed/releases/latest -O - | grep "title>Release" | cut -d " " -f 5) +cd /opt +wget -q https://github.com/gnmyt/myspeed/releases/download/v$RELEASE/MySpeed-$RELEASE.zip +unzip -q MySpeed-$RELEASE.zip -d myspeed +cd myspeed +$STD npm install +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed MySpeed" + +msg_info "Creating Service" +cat </etc/systemd/system/myspeed.service +[Unit] +Description=MySpeed +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/node server +Restart=always +User=root +Environment=NODE_ENV=production +WorkingDirectory=/opt/myspeed + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now myspeed.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +rm -rf /opt/MySpeed-$RELEASE.zip +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file From 54bb719223ea844c81835525bad8ebf7b6c98197 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Jun 2024 06:20:48 -0400 Subject: [PATCH 6437/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19ca6e9c..97339872 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-06-14 + +### Changed + +- **MySpeed LXC** + - NEW Script + ## 2024-06-13 ### Changed From 53b24ef7b77f38a77d8ba3ba4b7bd6c458d4f1d5 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 14 Jun 2024 11:10:47 -0400 Subject: [PATCH 6438/6505] Update build.func tweak --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 7a5bffd5..e8e98f4b 100644 --- a/misc/build.func +++ b/misc/build.func @@ -647,7 +647,7 @@ description() { # ${APP} LXC - +

    " if [[ -f /etc/systemd/system/ping-instances.service ]]; then systemctl start ping-instances.service From 8a61cad71f0e36a81094bd4ccb527c5ed919f5c1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 21 Jun 2024 05:16:23 -0400 Subject: [PATCH 6439/6505] Update umami.sh add update path --- ct/umami.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ct/umami.sh b/ct/umami.sh index 9f94d0b9..065f4516 100644 --- a/ct/umami.sh +++ b/ct/umami.sh @@ -52,6 +52,33 @@ function default_settings() { echo_default } +function update_script() { +header_info +if [[ ! -d /opt/umami ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi + +msg_info "Stopping ${APP}" +systemctl stop umami +msg_ok "Stopped $APP" + +msg_info "Updating ${APP}" +cd /opt/umami +git pull +yarn install +yarn build +msg_ok "Updated ${APP}" + +msg_info "Starting ${APP}" +systemctl start umami +msg_ok "Started ${APP}" + +msg_ok "Updated Successfully" +exit +} + start build_container description From dafe17ac953fc38cfc855b57a71ade36ae9f3881 Mon Sep 17 00:00:00 2001 From: Matt Alexander Date: Fri, 21 Jun 2024 17:08:46 -0700 Subject: [PATCH 6440/6505] Fix mikrotik-routeros when using nfs (#3247) --- vm/mikrotik-routeros.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index 15e702f5..af4fd0c2 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -254,13 +254,12 @@ nfs | dir) btrfs | zfspool) DISK_EXT="" DISK_REF="$VMID/" - DISK_FORMAT="subvol" DISK_IMPORT="-format raw" ;; esac DISK_VAR="vm-${VMID}-disk-0${DISK_EXT:-}" -DISK_REF="${STORAGE}:${DISK_VAR:-}" +DISK_REF="${STORAGE}:${DISK_REF:-}${DISK_VAR:-}" msg_ok "Extracted Mikrotik RouterOS CHR Disk Image" msg_info "Creating Mikrotik RouterOS CHR VM" From 72d70d7842029d6d8d22df1b7d0e02c2d20c4adb Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jun 2024 16:52:35 -0400 Subject: [PATCH 6441/6505] Update actualbudget.sh fixes https://github.com/tteck/Proxmox/issues/3250 --- ct/actualbudget.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/actualbudget.sh b/ct/actualbudget.sh index b4ff4d62..1f1e201d 100644 --- a/ct/actualbudget.sh +++ b/ct/actualbudget.sh @@ -58,8 +58,8 @@ if [[ ! -d /opt/actualbudget ]]; then msg_error "No ${APP} Installation Found!"; msg_info "Updating ${APP}" systemctl stop actualbudget.service cd /opt/actualbudget -git pull -yarn install +git pull &>/dev/null +yarn install &>/dev/null systemctl start actualbudget.service msg_ok "Successfully Updated ${APP}" exit From 9c475a02088e436112d4458218d508157011811a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 22 Jun 2024 17:30:53 -0400 Subject: [PATCH 6442/6505] Update petio-install.sh tweak service file --- install/petio-install.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/install/petio-install.sh b/install/petio-install.sh index 05499bd5..0de03f15 100644 --- a/install/petio-install.sh +++ b/install/petio-install.sh @@ -51,15 +51,18 @@ msg_info "Creating Service" cat </etc/systemd/system/petio.service [Unit] Description=Petio a content request system -After=network.target -StartLimitIntervalSec=0 +After=network.target mongod.service [Service] Type=simple +User=petio Restart=on-failure RestartSec=1 ExecStart=/opt/Petio/bin/petio-linux -User=petio + +[Install] +WantedBy=multi-user.target + EOF systemctl enable -q --now petio.service From 26fd770db5d06eedd4de86a2d6107e506642f194 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jun 2024 20:36:40 -0400 Subject: [PATCH 6443/6505] Update jellyseerr-install.sh from yarn to pnpm --- install/jellyseerr-install.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 6cc2d14c..76465f27 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -33,15 +33,16 @@ $STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" -msg_info "Installing Yarn" -$STD npm install -g yarn -msg_ok "Installed Yarn" +msg_info "Installing pnpm" +$STD npm install -g pnpm +msg_ok "Installed pnpm" msg_info "Installing Jellyseerr (Patience)" git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr cd /opt/jellyseerr -$STD yarn install -$STD yarn build +git checkout main +$STD CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile +$STD pnpm build mkdir -p /etc/jellyseerr/ cat </etc/jellyseerr/jellyseerr.conf PORT=5055 From 8228d24027a288fe172a2fd7f04d54d44fdf5f52 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jun 2024 20:39:07 -0400 Subject: [PATCH 6444/6505] Update jellyseerr.sh increase build resources --- ct/jellyseerr.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index 14768ed1..36f352d0 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="Jellyseerr" var_disk="8" var_cpu="2" -var_ram="2048" +var_ram="4096" var_os="debian" var_version="12" variables @@ -77,6 +77,10 @@ start build_container description +msg_info "Setting Container to Normal Resources" +pct set $CTID -memory 2048 +msg_ok "Set Container to Normal Resources" + msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5055${CL} \n" From d81fc402a0d5acfdbd4d1bb792367bd047f44870 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jun 2024 20:53:26 -0400 Subject: [PATCH 6445/6505] Update jellyseerr-install.sh tweak --- install/jellyseerr-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 76465f27..388a8572 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -40,7 +40,6 @@ msg_ok "Installed pnpm" msg_info "Installing Jellyseerr (Patience)" git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr cd /opt/jellyseerr -git checkout main $STD CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile $STD pnpm build mkdir -p /etc/jellyseerr/ From 39313455e646170b0fff732ba8b50843fdd70bc4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jun 2024 20:57:38 -0400 Subject: [PATCH 6446/6505] Update jellyseerr-install.sh tweak --- install/jellyseerr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 388a8572..bac5d94b 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -40,7 +40,7 @@ msg_ok "Installed pnpm" msg_info "Installing Jellyseerr (Patience)" git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr cd /opt/jellyseerr -$STD CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile +CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile &>/dev/null $STD pnpm build mkdir -p /etc/jellyseerr/ cat </etc/jellyseerr/jellyseerr.conf From be8dbcc094e0e43021c2212a951b208f7aa9e5f8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 23 Jun 2024 21:07:40 -0400 Subject: [PATCH 6447/6505] Update jellyseerr-install.sh fix service --- install/jellyseerr-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index bac5d94b..5de57a62 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -53,15 +53,17 @@ msg_ok "Installed Jellyseerr" msg_info "Creating Service" cat </etc/systemd/system/jellyseerr.service [Unit] -Description=jellyseerr Service -After=network.target +Description=Jellyseerr Service +Wants=network-online.target +After=network-online.target [Service] EnvironmentFile=/etc/jellyseerr/jellyseerr.conf Environment=NODE_ENV=production Type=exec +Restart=on-failure WorkingDirectory=/opt/jellyseerr -ExecStart=/usr/bin/yarn start +ExecStart=/usr/bin/node dist/index.js [Install] WantedBy=multi-user.target From 4a135f4ecd48e12babe00de177d236d3d2fb88ee Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 25 Jun 2024 15:45:34 -0400 Subject: [PATCH 6448/6505] Update alpine-docker-install.sh fixes https://github.com/tteck/Proxmox/issues/3261 --- install/alpine-docker-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/alpine-docker-install.sh b/install/alpine-docker-install.sh index 61cc27f7..58431201 100644 --- a/install/alpine-docker-install.sh +++ b/install/alpine-docker-install.sh @@ -17,6 +17,7 @@ msg_info "Installing Dependencies" $STD apk add newt $STD apk add curl $STD apk add openssh +$STD apk add tzdata $STD apk add nano $STD apk add mc msg_ok "Installed Dependencies" From 3639db4e94a78db2d9f2d8d58671fbe3bcd62d70 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:09:56 +0200 Subject: [PATCH 6449/6505] Add new LXC: Scrutiny (#3260) --- ct/scrutiny.sh | 190 ++++++++++++++++++++++++++++++++++++ install/scrutiny-install.sh | 63 ++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 ct/scrutiny.sh create mode 100644 install/scrutiny-install.sh diff --git a/ct/scrutiny.sh b/ct/scrutiny.sh new file mode 100644 index 00000000..9b22fb8b --- /dev/null +++ b/ct/scrutiny.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + _____ __ _ + / ___/____________ __/ /_(_)___ __ __ + \__ \/ ___/ ___/ / / / __/ / __ \/ / / / + ___/ / /__/ / / /_/ / /_/ / / / / /_/ / +/____/\___/_/ \__,_/\__/_/_/ /_/\__, / + /____/ +EOF +} +header_info +echo -e "Loading..." +APP="Scrutiny" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { + if [[ ! -d /opt/scrutiny ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + RELEASE=$(curl -s https://api.github.com/repos/AnalogJ/scrutiny/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + + UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Scrutiny Management" --radiolist --cancel-button Exit-Script "Spacebar = Select" 15 70 4 \ + "1" "Update Scrutiny to $RELEASE" ON \ + "2" "Start Scrutiny Webapp" OFF \ + "3" "Create/Start Scrutiny Collector" OFF \ + "4" "Change Scrutiny Settings" OFF \ + 3>&1 1>&2 2>&3) + header_info + + if [ "$UPD" == "1" ]; then + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + + msg_info "Stopping all Scrutiny Services" + WEBAPP_ACTIVE=$(systemctl is-active scrutiny.service) + COLLECTOR_ACTIVE=$(systemctl is-active scrutiny_collector.service) + systemctl stop scrutiny.service scrutiny_collector.service + msg_ok "Stopped all Scrutiny Services" + + msg_info "Updating to ${RELEASE}" + cd /opt + rm -rf scrutiny_bak + mv scrutiny scrutiny_bak + mkdir -p /opt/scrutiny/web /opt/scrutiny/bin + wget -q -O /opt/scrutiny/bin/scrutiny-web-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-linux-amd64" + wget -q -O /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-collector-metrics-linux-amd64" + wget -q -O /opt/scrutiny/web/scrutiny-web-frontend.tar.gz "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-frontend.tar.gz" + cd /opt/scrutiny/web && tar xvzf scrutiny-web-frontend.tar.gz --strip-components 1 -C . + chmod +x /opt/scrutiny/bin/scrutiny-web-linux-amd64 + chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 + echo "${RELEASE}" > /opt/scrutiny_version.txt + msg_ok "Updated Scrutiny to $RELEASE" + + msg_info "Cleaning up" + rm -f /opt/scrutiny/web/scrutiny-web-frontend.tar.gz + msg_ok "Cleaned" + + if [ "$WEBAPP_ACTIVE" == "active" ]; then + msg_info "Starting Scrutiny Webapp Service" + systemctl start scrutiny.service + msg_ok "Started Scrutiny Webapp Service" + fi + + if [ "$COLLECTOR_ACTIVE" == "active" ]; then + msg_info "Starting Scrutiny Collector Service" + systemctl start scrutiny_collector.service + msg_ok "Started Scrutiny Collector Service" + fi + + msg_ok "Updated Successfully!\n" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi + exit + fi +if [ "$UPD" == "2" ]; then + msg_info "Checking for Scrutiny Webapp Service" + if systemctl list-units --full -all | grep -Fq 'scrutiny.service'; then + msg_info "Stopping Scrutiny Webapp Service" + systemctl stop scrutiny.service + msg_ok "Stopped Scrutiny Webapp Service" + else + msg_info "Scrutiny Webapp Service not found, creating..." + cat </etc/systemd/system/scrutiny.service +[Unit] +Description=Scrutiny - Hard Drive Monitoring and Webapp +After=network.target + +[Service] +Type=simple +ExecStart=/opt/scrutiny/bin/scrutiny-web-linux-amd64 start --config /opt/scrutiny/config/scrutiny.yaml +Restart=always +User=root + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q scrutiny.service + msg_ok "Created Scrutiny Webapp Service" + fi + + msg_info "Starting Scrutiny Webapp Service" + systemctl start scrutiny.service + msg_ok "Started Scrutiny Webapp Service" + exit +fi + +if [ "$UPD" == "3" ]; then + msg_info "Checking for Scrutiny Collector Service" + if systemctl list-units --full -all | grep -Fq 'scrutiny_collector.service'; then + msg_info "Stopping Scrutiny Collector Service" + systemctl stop scrutiny_collector.service + msg_ok "Stopped Scrutiny Collector Service" + else + msg_info "Scrutiny Collector Service not found, creating..." + wget -q -O /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-collector-metrics-linux-amd64" + chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 + cat </etc/systemd/system/scrutiny_collector.service +[Unit] +Description=Scrutiny Collector +After=network.target + +[Service] +Type=simple +ExecStart=/opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 run --api-endpoint "http://localhost:8080" +Restart=always +User=root + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q scrutiny_collector.service + msg_ok "Created Scrutiny Collector Service" + fi + + msg_info "Starting Scrutiny Collector Service" + systemctl start scrutiny_collector.service + msg_ok "Started Scrutiny Collector Service" + exit +fi +if [ "$UPD" == "4" ]; then + nano /opt/scrutiny/config/scrutiny.yaml + exit +fi +} + +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}:8080${CL} \n" diff --git a/install/scrutiny-install.sh b/install/scrutiny-install.sh new file mode 100644 index 00000000..5e534e87 --- /dev/null +++ b/install/scrutiny-install.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://github.com/AnalogJ/scrutiny + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + sudo \ + curl \ + smartmontools \ + make \ + mc +msg_ok "Installed Dependencies" + +msg_info "Installing Scrutiny WebApp" +mkdir -p /opt/scrutiny/{config,web,bin} +RELEASE=$(curl -s https://api.github.com/repos/analogj/scrutiny/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +echo "${RELEASE}" >/opt/${APP}_version.txt +wget -q -O /opt/scrutiny/config/scrutiny.yaml https://raw.githubusercontent.com/AnalogJ/scrutiny/master/example.scrutiny.yaml +wget -q -O /opt/scrutiny/bin/scrutiny-web-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-linux-amd64" +wget -q -O /opt/scrutiny/web/scrutiny-web-frontend.tar.gz "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-frontend.tar.gz" +cd /opt/scrutiny/web +tar xzf scrutiny-web-frontend.tar.gz --strip-components 1 -C . +chmod +x /opt/scrutiny/bin/scrutiny-web-linux-amd64 +msg_ok "Installed Scrutiny WebApp" + +msg_info "Setup Service" +cat </etc/systemd/system/scrutiny.service +[Unit] +Description=Scrutiny - Hard Drive Monitoring and Webapp +After=network.target + +[Service] +Type=simple +ExecStart=/opt/scrutiny/bin/scrutiny-web-linux-amd64 start --config /opt/scrutiny/config/scrutiny.yaml +Restart=always +User=root + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now scrutiny.service +msg_ok "Created and enabled Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From a87b6c8a2b9d8da418a96a11b3ba454622b850c6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jun 2024 12:15:18 -0400 Subject: [PATCH 6450/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97339872..f236110d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-06-26 + +### Changed + +- **Scrutiny LXC** + - NEW Script + ## 2024-06-14 ### Changed From a40795a5d46c6257fc8058ce6fcd1e224be674bb Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 26 Jun 2024 12:40:15 -0400 Subject: [PATCH 6451/6505] Update scrutiny-install.sh fixes https://github.com/tteck/Proxmox/issues/3269 --- install/scrutiny-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/scrutiny-install.sh b/install/scrutiny-install.sh index 5e534e87..d155854b 100644 --- a/install/scrutiny-install.sh +++ b/install/scrutiny-install.sh @@ -27,7 +27,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Scrutiny WebApp" mkdir -p /opt/scrutiny/{config,web,bin} RELEASE=$(curl -s https://api.github.com/repos/analogj/scrutiny/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -echo "${RELEASE}" >/opt/${APP}_version.txt +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt wget -q -O /opt/scrutiny/config/scrutiny.yaml https://raw.githubusercontent.com/AnalogJ/scrutiny/master/example.scrutiny.yaml wget -q -O /opt/scrutiny/bin/scrutiny-web-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-linux-amd64" wget -q -O /opt/scrutiny/web/scrutiny-web-frontend.tar.gz "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-frontend.tar.gz" From 344d6ac008f06e6d4ad34adbc8febdb31c9f48ff Mon Sep 17 00:00:00 2001 From: Evan Owen Date: Thu, 27 Jun 2024 06:55:51 -0400 Subject: [PATCH 6452/6505] Add new LXC: Kubo for IPFS (#3270) --- ct/kubo.sh | 81 +++++++++++++++++++++++++++++++++++++++++ install/kubo-install.sh | 61 +++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 ct/kubo.sh create mode 100644 install/kubo-install.sh diff --git a/ct/kubo.sh b/ct/kubo.sh new file mode 100644 index 00000000..e792b791 --- /dev/null +++ b/ct/kubo.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: ulmentflam +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + __ __ __ + / //_/_ __/ /_ ____ + / ,< / / / / __ \/ __ \ + / /| / /_/ / /_/ / /_/ / +/_/ |_\__,_/_.___/\____/ +EOF +} +header_info +echo -e "Loading..." +APP="Kubo" +var_disk="4" +var_cpu="2" +var_ram="4096" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + +function update_script() { +header_info +if [[ ! -f /usr/local/kubo ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +RELEASE=$(wget -q https://github.com/ipfs/kubo/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + msg_info "Updating $APP LXC" + apt-get update &>/dev/null + apt-get -y upgrade &>/dev/null + wget -q "https://github.com/ipfs/kubo/releases/download/${RELEASE}/kubo_${RELEASE}_linux-amd64.tar.gz" + tar -xzf "kubo_${RELEASE}_linux-amd64.tar.gz" -C /usr/local + systemctl restart ipfs.service + echo "${RELEASE}" >/opt/${APP}_version.txt + rm "kubo_${RELEASE}_linux-amd64.tar.gz" + msg_ok "Updated $APP LXC" +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} should be reachable by going to the following URL. + ${BL}http://${IP}:5001/webui ${CL} \n" diff --git a/install/kubo-install.sh b/install/kubo-install.sh new file mode 100644 index 00000000..390674c1 --- /dev/null +++ b/install/kubo-install.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck (tteckster) +# Co-Author: ulmentflam +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y curl +$STD apt-get install -y sudo +$STD apt-get install -y mc +$STD apt-get install -y gpg +msg_ok "Installed Dependencies" + +msg_info "Installing IPFS" +RELEASE=$(wget -q https://github.com/ipfs/kubo/releases/latest -O - | grep "title>Release" | cut -d " " -f 4) +$STD wget -q "https://github.com/ipfs/kubo/releases/download/${RELEASE}/kubo_${RELEASE}_linux-amd64.tar.gz" +tar -xzf "kubo_${RELEASE}_linux-amd64.tar.gz" -C /usr/local +$STD ln -s /usr/local/kubo/ipfs /usr/local/bin/ipfs +$STD ipfs init +ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001 +ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080 +LXCIP=$(hostname -I | awk '{print $1}') +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"http://${LXCIP}:5001\", \"http://localhost:3000\", \"http://127.0.0.1:5001\", \"https://webui.ipfs.io\", \"http://0.0.0.0:5001\"]" +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST"]' +echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" +$STD rm "kubo_${RELEASE}_linux-amd64.tar.gz" +msg_ok "Installed IPFS" + +msg_info "Creating Service" +cat </etc/systemd/system/ipfs.service +[Unit] +Description=IPFS Daemon +After=syslog.target network.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/ipfs daemon +Restart=on-failure +[Install] +WantedBy=multi-user.target +EOF +systemctl enable --now -q ipfs.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 8a52575039756e0220e8dc0da20942bc49bcf3d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jun 2024 06:57:54 -0400 Subject: [PATCH 6453/6505] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f236110d..51f481f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. +## 2024-06-27 + +### Changed + +- **Kubo LXC** + - NEW Script + ## 2024-06-26 ### Changed From 89aba152757755da7cbef7a89750273c43706591 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:27:28 +0200 Subject: [PATCH 6454/6505] Add new LXC: RabbitMQ (#3268) --- ct/rabbitmq.sh | 85 +++++++++++++++++++++++++++++++++++++ install/rabbitmq-install.sh | 81 +++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 ct/rabbitmq.sh create mode 100644 install/rabbitmq-install.sh diff --git a/ct/rabbitmq.sh b/ct/rabbitmq.sh new file mode 100644 index 00000000..ff31111e --- /dev/null +++ b/ct/rabbitmq.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE + +function header_info { +clear +cat <<"EOF" + ____ __ __ _ __ __ _______ + / __ \____ _/ /_ / /_ (_) /_/ |/ / __ \ + / /_/ / __ `/ __ \/ __ \/ / __/ /|_/ / / / / + / _, _/ /_/ / /_/ / /_/ / / /_/ / / / /_/ / +/_/ |_|\__,_/_.___/_.___/_/\__/_/ /_/\___\_\ + +EOF +} +header_info +echo -e "Loading..." +APP="RabbitMQ" +var_disk="4" +var_cpu="1" +var_ram="1024" +var_os="debian" +var_version="12" +variables +color +catch_errors + +function default_settings() { + CT_TYPE="1" + PW="" + CT_ID=$NEXTID + HN=$NSAPP + DISK_SIZE="$var_disk" + CORE_COUNT="$var_cpu" + RAM_SIZE="$var_ram" + BRG="vmbr0" + NET="dhcp" + GATE="" + APT_CACHER="" + APT_CACHER_IP="" + DISABLEIP6="no" + MTU="" + SD="" + NS="" + MAC="" + VLAN="" + SSH="no" + VERB="no" + echo_default +} + + +function update_script() { +header_info +if [[ ! -d /etc/rabbitmq ]]; then msg_error "No ${APP} Installation Found!"; exit; fi +if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then + read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt + [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit +fi +msg_info "Stopping ${APP} Service" +systemctl stop rabbitmq-server +msg_ok "Stopped ${APP} Service" + +msg_info "Updating..." +apt install --only-upgrade rabbitmq-server &>/dev/null +msg_ok "Update Successfully" + +msg_info "Starting ${APP}" +systemctl start rabbitmq-server +msg_ok "Started ${APP}" +msg_ok "Updated Successfully" +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}:15672${CL} \n" diff --git a/install/rabbitmq-install.sh b/install/rabbitmq-install.sh new file mode 100644 index 00000000..5824c0f5 --- /dev/null +++ b/install/rabbitmq-install.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 tteck +# Author: tteck +# Co-Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/tteck/Proxmox/raw/main/LICENSE +# Source: https://www.rabbitmq.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + sudo \ + lsb-release \ + curl \ + gnupg \ + apt-transport-https \ + make \ + mc +msg_ok "Installed Dependencies" + +msg_info "Adding RabbitMQ signing key" +wget -qO- "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | gpg --dearmor >/usr/share/keyrings/com.rabbitmq.team.gpg +wget -qO- "https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-erlang.E495BB49CC4BBE5B.key" | gpg --dearmor >/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg +wget -qO- "https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-server.9F4587F226208342.key" | gpg --dearmor >/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg +msg_ok "Signing keys added" + +msg_info "Adding RabbitMQ repository" +cat </etc/apt/sources.list.d/rabbitmq.list +## Provides modern Erlang/OTP releases from a Cloudsmith mirror +deb [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian $(lsb_release -cs) main +deb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian $(lsb_release -cs) main + +## Provides RabbitMQ from a Cloudsmith mirror +deb [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian $(lsb_release -cs) main +deb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian $(lsb_release -cs) main +EOF +msg_ok "RabbitMQ repository added" + +msg_info "Updating package list" +$STD apt-get update -y +msg_ok "Package list updated" + +msg_info "Installing Erlang & RabbitMQ server" +$STD apt-get install -y erlang-base \ + erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \ + erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \ + erlang-runtime-tools erlang-snmp erlang-ssl \ + erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl \ + rabbitmq-server +msg_ok "RabbitMQ server installed" + +msg_info "Starting RabbitMQ service" +systemctl enable -q --now rabbitmq-server +msg_ok "RabbitMQ service started" + +msg_info "Enabling RabbitMQ management plugin" +$STD rabbitmq-plugins enable rabbitmq_management +$STD rabbitmqctl enable_feature_flag all +msg_ok "RabbitMQ management plugin enabled" + +msg_info "Create User" +$STD rabbitmqctl add_user proxmox proxmox +$STD rabbitmqctl set_user_tags proxmox administrator +$STD rabbitmqctl set_permissions -p / proxmox ".*" ".*" ".*" +msg_ok "Created User" + +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" From 5d0e18634fa29240d10f1a76a3393e1f0537c708 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jun 2024 07:30:40 -0400 Subject: [PATCH 6455/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51f481f5..0ac80add 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ - **Kubo LXC** - NEW Script +- **RabbitMQ LXC** + - NEW Script ## 2024-06-26 From 59c78c03acd1d3156f76e9d1a7f361bb92cc165b Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jun 2024 11:05:48 -0400 Subject: [PATCH 6456/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac80add..1f562642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ - NEW Script - **RabbitMQ LXC** - NEW Script +- **Scruyiny LXC** + - Removed from website, broken. ## 2024-06-26 From 943be5301a65b29eaa68837b9025963a3652148f Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jun 2024 11:06:12 -0400 Subject: [PATCH 6457/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f562642..ca9f1043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ - NEW Script - **RabbitMQ LXC** - NEW Script -- **Scruyiny LXC** +- **Scrutiny LXC** - Removed from website, broken. ## 2024-06-26 From eb9bff22c3f84138f07823ecee5ca0a2eec0b469 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:25:08 +1000 Subject: [PATCH 6458/6505] Fix Scrutiny service start failure (#3278) --- install/scrutiny-install.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/install/scrutiny-install.sh b/install/scrutiny-install.sh index d155854b..068ff84f 100644 --- a/install/scrutiny-install.sh +++ b/install/scrutiny-install.sh @@ -21,9 +21,23 @@ $STD apt-get install -y \ curl \ smartmontools \ make \ - mc + mc \ + lsb-base \ + lsb-release \ + gnupg2 msg_ok "Installed Dependencies" +msg_info "Setting up InfluxDB Repository" +wget -qO- https://repos.influxdata.com/influxdata-archive_compat.key | gpg --dearmor > /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg +echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list +msg_ok "Set up InfluxDB Repository" + +msg_info "Installing InfluxDB" +$STD apt-get update +$STD apt-get install -y influxdb2 +systemctl enable -q --now influxdb +msg_ok "Installed InfluxDB" + msg_info "Installing Scrutiny WebApp" mkdir -p /opt/scrutiny/{config,web,bin} RELEASE=$(curl -s https://api.github.com/repos/analogj/scrutiny/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') From 2ec2831d5f89f856b3535140a49bb351b6c6b718 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jun 2024 20:32:13 -0400 Subject: [PATCH 6459/6505] Update influxdb-install.sh tweak --- install/influxdb-install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/influxdb-install.sh b/install/influxdb-install.sh index c43ba7fb..a1edf820 100644 --- a/install/influxdb-install.sh +++ b/install/influxdb-install.sh @@ -23,9 +23,8 @@ $STD apt-get install -y gnupg2 msg_ok "Installed Dependencies" msg_info "Setting up InfluxDB Repository" -wget -q https://repos.influxdata.com/influxdata-archive_compat.key -cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null -sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list' +wget -qO- https://repos.influxdata.com/influxdata-archive_compat.key | gpg --dearmor > /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg +echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list msg_ok "Set up InfluxDB Repository" read -r -p "Which version of InfluxDB to install? (1 or 2) " prompt From 00f7e0b287dcb4622cde49af363d6031e734b1e3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 27 Jun 2024 22:41:46 -0400 Subject: [PATCH 6460/6505] Update tautulli-install.sh tweak --- install/tautulli-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index d431918d..23d7e4aa 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -31,7 +31,7 @@ msg_ok "Updated Python3" msg_info "Installing Tautulli" cd /opt $STD git clone https://github.com/Tautulli/Tautulli.git -python3 -m pip install -q -r /opt/Tautulli/requirements.txt +$STD pip install -q -r /opt/Tautulli/requirements.txt $STD pip install pyopenssl msg_ok "Installed Tautulli" From 9b42be526d4b3f89976fbe6ce95f275525c8f055 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Jun 2024 06:56:20 -0400 Subject: [PATCH 6461/6505] Delete install/scrutiny-install.sh Does not function --- install/scrutiny-install.sh | 77 ------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 install/scrutiny-install.sh diff --git a/install/scrutiny-install.sh b/install/scrutiny-install.sh deleted file mode 100644 index 068ff84f..00000000 --- a/install/scrutiny-install.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2024 tteck -# Author: tteck -# Co-Author: MickLesk (Canbiz) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE -# Source: https://github.com/AnalogJ/scrutiny - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_info "Installing Dependencies" -$STD apt-get install -y \ - sudo \ - curl \ - smartmontools \ - make \ - mc \ - lsb-base \ - lsb-release \ - gnupg2 -msg_ok "Installed Dependencies" - -msg_info "Setting up InfluxDB Repository" -wget -qO- https://repos.influxdata.com/influxdata-archive_compat.key | gpg --dearmor > /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg -echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" > /etc/apt/sources.list.d/influxdata.list -msg_ok "Set up InfluxDB Repository" - -msg_info "Installing InfluxDB" -$STD apt-get update -$STD apt-get install -y influxdb2 -systemctl enable -q --now influxdb -msg_ok "Installed InfluxDB" - -msg_info "Installing Scrutiny WebApp" -mkdir -p /opt/scrutiny/{config,web,bin} -RELEASE=$(curl -s https://api.github.com/repos/analogj/scrutiny/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -echo "${RELEASE}" >/opt/${APPLICATION}_version.txt -wget -q -O /opt/scrutiny/config/scrutiny.yaml https://raw.githubusercontent.com/AnalogJ/scrutiny/master/example.scrutiny.yaml -wget -q -O /opt/scrutiny/bin/scrutiny-web-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-linux-amd64" -wget -q -O /opt/scrutiny/web/scrutiny-web-frontend.tar.gz "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-frontend.tar.gz" -cd /opt/scrutiny/web -tar xzf scrutiny-web-frontend.tar.gz --strip-components 1 -C . -chmod +x /opt/scrutiny/bin/scrutiny-web-linux-amd64 -msg_ok "Installed Scrutiny WebApp" - -msg_info "Setup Service" -cat </etc/systemd/system/scrutiny.service -[Unit] -Description=Scrutiny - Hard Drive Monitoring and Webapp -After=network.target - -[Service] -Type=simple -ExecStart=/opt/scrutiny/bin/scrutiny-web-linux-amd64 start --config /opt/scrutiny/config/scrutiny.yaml -Restart=always -User=root - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now scrutiny.service -msg_ok "Created and enabled Service" - -motd_ssh -customize - -msg_info "Cleaning up" -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" From 946fad73b9856bff437daff50a7dc27cb5863666 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 28 Jun 2024 06:57:03 -0400 Subject: [PATCH 6462/6505] Delete ct/scrutiny.sh Does not function --- ct/scrutiny.sh | 190 ------------------------------------------------- 1 file changed, 190 deletions(-) delete mode 100644 ct/scrutiny.sh diff --git a/ct/scrutiny.sh b/ct/scrutiny.sh deleted file mode 100644 index 9b22fb8b..00000000 --- a/ct/scrutiny.sh +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env bash -source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func) -# Copyright (c) 2021-2024 tteck -# Author: tteck -# Co-Author: MickLesk (Canbiz) -# License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE - -function header_info { -clear -cat <<"EOF" - _____ __ _ - / ___/____________ __/ /_(_)___ __ __ - \__ \/ ___/ ___/ / / / __/ / __ \/ / / / - ___/ / /__/ / / /_/ / /_/ / / / / /_/ / -/____/\___/_/ \__,_/\__/_/_/ /_/\__, / - /____/ -EOF -} -header_info -echo -e "Loading..." -APP="Scrutiny" -var_disk="4" -var_cpu="1" -var_ram="1024" -var_os="debian" -var_version="12" -variables -color -catch_errors - -function default_settings() { - CT_TYPE="1" - PW="" - CT_ID=$NEXTID - HN=$NSAPP - DISK_SIZE="$var_disk" - CORE_COUNT="$var_cpu" - RAM_SIZE="$var_ram" - BRG="vmbr0" - NET="dhcp" - GATE="" - APT_CACHER="" - APT_CACHER_IP="" - DISABLEIP6="no" - MTU="" - SD="" - NS="" - MAC="" - VLAN="" - SSH="no" - VERB="no" - echo_default -} - -function update_script() { - if [[ ! -d /opt/scrutiny ]]; then msg_error "No ${APP} Installation Found!"; exit; fi - RELEASE=$(curl -s https://api.github.com/repos/AnalogJ/scrutiny/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Scrutiny Management" --radiolist --cancel-button Exit-Script "Spacebar = Select" 15 70 4 \ - "1" "Update Scrutiny to $RELEASE" ON \ - "2" "Start Scrutiny Webapp" OFF \ - "3" "Create/Start Scrutiny Collector" OFF \ - "4" "Change Scrutiny Settings" OFF \ - 3>&1 1>&2 2>&3) - header_info - - if [ "$UPD" == "1" ]; then - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - - msg_info "Stopping all Scrutiny Services" - WEBAPP_ACTIVE=$(systemctl is-active scrutiny.service) - COLLECTOR_ACTIVE=$(systemctl is-active scrutiny_collector.service) - systemctl stop scrutiny.service scrutiny_collector.service - msg_ok "Stopped all Scrutiny Services" - - msg_info "Updating to ${RELEASE}" - cd /opt - rm -rf scrutiny_bak - mv scrutiny scrutiny_bak - mkdir -p /opt/scrutiny/web /opt/scrutiny/bin - wget -q -O /opt/scrutiny/bin/scrutiny-web-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-linux-amd64" - wget -q -O /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-collector-metrics-linux-amd64" - wget -q -O /opt/scrutiny/web/scrutiny-web-frontend.tar.gz "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-web-frontend.tar.gz" - cd /opt/scrutiny/web && tar xvzf scrutiny-web-frontend.tar.gz --strip-components 1 -C . - chmod +x /opt/scrutiny/bin/scrutiny-web-linux-amd64 - chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 - echo "${RELEASE}" > /opt/scrutiny_version.txt - msg_ok "Updated Scrutiny to $RELEASE" - - msg_info "Cleaning up" - rm -f /opt/scrutiny/web/scrutiny-web-frontend.tar.gz - msg_ok "Cleaned" - - if [ "$WEBAPP_ACTIVE" == "active" ]; then - msg_info "Starting Scrutiny Webapp Service" - systemctl start scrutiny.service - msg_ok "Started Scrutiny Webapp Service" - fi - - if [ "$COLLECTOR_ACTIVE" == "active" ]; then - msg_info "Starting Scrutiny Collector Service" - systemctl start scrutiny_collector.service - msg_ok "Started Scrutiny Collector Service" - fi - - msg_ok "Updated Successfully!\n" - else - msg_ok "No update required. ${APP} is already at ${RELEASE}" - fi - exit - fi -if [ "$UPD" == "2" ]; then - msg_info "Checking for Scrutiny Webapp Service" - if systemctl list-units --full -all | grep -Fq 'scrutiny.service'; then - msg_info "Stopping Scrutiny Webapp Service" - systemctl stop scrutiny.service - msg_ok "Stopped Scrutiny Webapp Service" - else - msg_info "Scrutiny Webapp Service not found, creating..." - cat </etc/systemd/system/scrutiny.service -[Unit] -Description=Scrutiny - Hard Drive Monitoring and Webapp -After=network.target - -[Service] -Type=simple -ExecStart=/opt/scrutiny/bin/scrutiny-web-linux-amd64 start --config /opt/scrutiny/config/scrutiny.yaml -Restart=always -User=root - -[Install] -WantedBy=multi-user.target -EOF - systemctl enable -q scrutiny.service - msg_ok "Created Scrutiny Webapp Service" - fi - - msg_info "Starting Scrutiny Webapp Service" - systemctl start scrutiny.service - msg_ok "Started Scrutiny Webapp Service" - exit -fi - -if [ "$UPD" == "3" ]; then - msg_info "Checking for Scrutiny Collector Service" - if systemctl list-units --full -all | grep -Fq 'scrutiny_collector.service'; then - msg_info "Stopping Scrutiny Collector Service" - systemctl stop scrutiny_collector.service - msg_ok "Stopped Scrutiny Collector Service" - else - msg_info "Scrutiny Collector Service not found, creating..." - wget -q -O /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 "https://github.com/AnalogJ/scrutiny/releases/download/${RELEASE}/scrutiny-collector-metrics-linux-amd64" - chmod +x /opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 - cat </etc/systemd/system/scrutiny_collector.service -[Unit] -Description=Scrutiny Collector -After=network.target - -[Service] -Type=simple -ExecStart=/opt/scrutiny/bin/scrutiny-collector-metrics-linux-amd64 run --api-endpoint "http://localhost:8080" -Restart=always -User=root - -[Install] -WantedBy=multi-user.target -EOF - systemctl enable -q scrutiny_collector.service - msg_ok "Created Scrutiny Collector Service" - fi - - msg_info "Starting Scrutiny Collector Service" - systemctl start scrutiny_collector.service - msg_ok "Started Scrutiny Collector Service" - exit -fi -if [ "$UPD" == "4" ]; then - nano /opt/scrutiny/config/scrutiny.yaml - exit -fi -} - -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}:8080${CL} \n" From 122271dd34a5dcecd1550f3d5afa9b34f57c430d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jun 2024 07:29:11 -0400 Subject: [PATCH 6463/6505] Update frigate-install.sh Update TensorFlow Lite URL fixes https://github.com/tteck/Proxmox/issues/3285 --- install/frigate-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 50847e70..52b3cb2d 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -45,6 +45,7 @@ if [[ "$CTTYPE" == "0" ]]; then chmod 660 /dev/dri/* fi msg_ok "Set Up Hardware Acceleration" + RELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | jq -r '.tag_name') msg_ok "Stop spinner to prevent segmentation fault" msg_info "Installing Frigate $RELEASE (Perseverance)" @@ -155,7 +156,10 @@ cd / wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite cp /opt/frigate/labelmap.txt /labelmap.txt -wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite +wget -qO yamnet-tflite-classification-tflite-v1.tar.gz https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download +tar xzf yamnet-tflite-classification-tflite-v1.tar.gz +rm -rf yamnet-tflite-classification-tflite-v1.tar.gz +mv 1.tflite cpu_audio_model.tflite cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt mkdir -p /media/frigate wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 From a078adfaea00044fc89ea110259a75cb6df935d1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jun 2024 11:03:54 -0400 Subject: [PATCH 6464/6505] Update install.func tweak --- misc/install.func | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/install.func b/misc/install.func index 80a5c2e2..c698e258 100644 --- a/misc/install.func +++ b/misc/install.func @@ -165,6 +165,7 @@ EOF fi $STD apt-get update $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade + rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Container OS" } From 482f60f90a7e8e00516c475158658a9c58c23899 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jun 2024 11:10:12 -0400 Subject: [PATCH 6465/6505] Update sabnzbd-install.sh tweak --- install/sabnzbd-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sabnzbd-install.sh b/install/sabnzbd-install.sh index 63e919c9..efeb7c0f 100644 --- a/install/sabnzbd-install.sh +++ b/install/sabnzbd-install.sh @@ -29,10 +29,10 @@ msg_ok "Installed Dependencies" msg_info "Updating Python3" $STD apt-get install -y \ - python3 \ python3-dev \ python3-pip $STD apt-get install -y python3-setuptools +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing SABnzbd" From ecb4294a184812b5b68f5d58fbaf65c7aad0bc4a Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jun 2024 11:18:26 -0400 Subject: [PATCH 6466/6505] fix EXTERNALLY-MANAGED --- install/bazarr-install.sh | 1 + install/changedetection-install.sh | 1 + install/deluge-install.sh | 1 + install/esphome-install.sh | 1 + install/homeassistant-install.sh | 1 + install/motioneye-install.sh | 1 + install/octoprint-install.sh | 1 + install/scrypted-install.sh | 1 + install/tandoor-install.sh | 1 + install/tautulli-install.sh | 1 + install/whoogle-install.sh | 1 + 11 files changed, 11 insertions(+) diff --git a/install/bazarr-install.sh b/install/bazarr-install.sh index 5f5e6ac4..a4ee4cbb 100755 --- a/install/bazarr-install.sh +++ b/install/bazarr-install.sh @@ -24,6 +24,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing Bazarr" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 95050bd7..5a10f779 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -52,6 +52,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" diff --git a/install/deluge-install.sh b/install/deluge-install.sh index a08580fc..979b22b6 100644 --- a/install/deluge-install.sh +++ b/install/deluge-install.sh @@ -25,6 +25,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing Deluge" diff --git a/install/esphome-install.sh b/install/esphome-install.sh index a5732a84..301d9bbb 100644 --- a/install/esphome-install.sh +++ b/install/esphome-install.sh @@ -26,6 +26,7 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing ESPHome" diff --git a/install/homeassistant-install.sh b/install/homeassistant-install.sh index 8d78d316..088fc4d3 100644 --- a/install/homeassistant-install.sh +++ b/install/homeassistant-install.sh @@ -25,6 +25,7 @@ $STD apt-get install -y \ python3-dev \ python3-pip \ python3-venv +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing runlike" diff --git a/install/motioneye-install.sh b/install/motioneye-install.sh index fe854002..99e24413 100644 --- a/install/motioneye-install.sh +++ b/install/motioneye-install.sh @@ -26,6 +26,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing Motion" diff --git a/install/octoprint-install.sh b/install/octoprint-install.sh index 1cbcf0ae..ac9eacfb 100644 --- a/install/octoprint-install.sh +++ b/install/octoprint-install.sh @@ -30,6 +30,7 @@ $STD apt-get install -y \ python3-venv $STD apt-get install -y python3-setuptools +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Creating user octoprint" diff --git a/install/scrypted-install.sh b/install/scrypted-install.sh index 2ac2d72e..ad71ba92 100644 --- a/install/scrypted-install.sh +++ b/install/scrypted-install.sh @@ -79,6 +79,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing Python3 Dependencies" diff --git a/install/tandoor-install.sh b/install/tandoor-install.sh index abbf06e7..53f88333 100644 --- a/install/tandoor-install.sh +++ b/install/tandoor-install.sh @@ -38,6 +38,7 @@ $STD apt-get install -y \ python3-dev \ python3-setuptools \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Setting up Node.js Repository" diff --git a/install/tautulli-install.sh b/install/tautulli-install.sh index 23d7e4aa..23408390 100644 --- a/install/tautulli-install.sh +++ b/install/tautulli-install.sh @@ -26,6 +26,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing Tautulli" diff --git a/install/whoogle-install.sh b/install/whoogle-install.sh index fac08400..f3516d32 100644 --- a/install/whoogle-install.sh +++ b/install/whoogle-install.sh @@ -24,6 +24,7 @@ $STD apt-get install -y \ python3 \ python3-dev \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Python3" msg_info "Installing Whoogle" From 7d142d593e7c748b8507db9c681302a7ecdd9f06 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jun 2024 12:15:00 -0400 Subject: [PATCH 6467/6505] Update update-lxcs.sh tweak --- misc/update-lxcs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs.sh b/misc/update-lxcs.sh index 3c54ce3f..9167186e 100644 --- a/misc/update-lxcs.sh +++ b/misc/update-lxcs.sh @@ -67,7 +67,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED" ;; esac } From 59b2d529a2da518672f4ebf9f521714055ff841e Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 29 Jun 2024 12:16:30 -0400 Subject: [PATCH 6468/6505] Update update-lxcs-cron.sh tweak --- misc/update-lxcs-cron.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/update-lxcs-cron.sh b/misc/update-lxcs-cron.sh index ebd6e972..23c44852 100644 --- a/misc/update-lxcs-cron.sh +++ b/misc/update-lxcs-cron.sh @@ -22,7 +22,7 @@ function update_container() { alpine) pct exec "$container" -- ash -c "apk update && apk upgrade" ;; archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;; fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;; - ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt-get upgrade --dry-run && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y" ;; + ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt-get upgrade --dry-run && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -y; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED" ;; esac } From 8322aede45d7c230430dcc923e09b92f47f7a848 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jun 2024 07:49:13 -0400 Subject: [PATCH 6469/6505] Update nginxproxymanager-install.sh tweak --- install/nginxproxymanager-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh index 663c9607..4314e293 100644 --- a/install/nginxproxymanager-install.sh +++ b/install/nginxproxymanager-install.sh @@ -41,6 +41,7 @@ $STD apt-get install -y \ python3-certbot-dns-cloudflare $STD pip3 install certbot-dns-multi $STD python3 -m venv /opt/certbot/ +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Installed Python Dependencies" VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" From 1769a3f40babc0f02358d2e77fc636ed8e4f2109 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jun 2024 08:29:55 -0400 Subject: [PATCH 6470/6505] Tweak for Debian 12.6 fix EXTERNALLY-MANAGED --- install/calibre-web-install.sh | 1 + install/pialert-install.sh | 1 + install/stirling-pdf-install.sh | 1 + 3 files changed, 3 insertions(+) diff --git a/install/calibre-web-install.sh b/install/calibre-web-install.sh index cdc5653f..1f42bbaf 100644 --- a/install/calibre-web-install.sh +++ b/install/calibre-web-install.sh @@ -23,6 +23,7 @@ msg_ok "Installed Dependencies" msg_info "Installing Python Dependencies" $STD apt-get -y install python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Installed Python Dependencies" msg_info "Installing Kepubify" diff --git a/install/pialert-install.sh b/install/pialert-install.sh index f90ea6b8..d08f16f7 100644 --- a/install/pialert-install.sh +++ b/install/pialert-install.sh @@ -50,6 +50,7 @@ msg_info "Installing Python Dependencies" $STD apt-get -y install \ python3-pip \ python3-requests +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED $STD pip3 install mac-vendor-lookup $STD pip3 install fritzconnection $STD pip3 install cryptography diff --git a/install/stirling-pdf-install.sh b/install/stirling-pdf-install.sh index f0c802a2..88456a66 100644 --- a/install/stirling-pdf-install.sh +++ b/install/stirling-pdf-install.sh @@ -42,6 +42,7 @@ msg_info "Installing Python Dependencies" $STD apt-get install -y \ python3 \ python3-pip +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED $STD pip3 install \ uno \ opencv-python-headless \ From 8fd1727fa8119ee4685dbf740368df8822cdad25 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jun 2024 09:09:08 -0400 Subject: [PATCH 6471/6505] Update alpine-nextcloud.sh Remove "update" option fixes https://github.com/tteck/Proxmox/issues/3298 --- ct/alpine-nextcloud.sh | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index 6def6e53..c683cfe2 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -60,12 +60,10 @@ function update_script() { if ! apk -e info newt >/dev/null 2>&1; then apk add -q newt fi - RELEASE=$(curl -s https://api.github.com/repos/nextcloud/server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') while true; do CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ - "1" "Update Nextcloud to $RELEASE" OFF \ - "2" "Nextcloud Login Credentials" ON \ - "3" "Renew Self-signed Certificate" OFF \ + "1" "Nextcloud Login Credentials" ON \ + "2" "Renew Self-signed Certificate" OFF \ 3>&1 1>&2 2>&3) exit_status=$? if [ $exit_status == 1 ]; then @@ -75,22 +73,10 @@ function update_script() { header_info case $CHOICE in 1) - apk update && apk upgrade - if ! apk -e info php82-sodium >/dev/null 2>&1; then - apk add -q php82-sodium - fi - if ! apk -e info php82-bz2 >/dev/null 2>&1; then - apk add -q php82-bz2 - fi - su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ upgrade' - su nextcloud -s /bin/sh -c 'php82 /usr/share/webapps/nextcloud/occ db:add-missing-indices' - exit - ;; - 2) cat nextcloud.creds exit ;; - 3) + 2) openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj "/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local" > /dev/null 2>&1 rc-service nginx restart exit From c29768de514897da677e65e72e03439fb6308350 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jun 2024 09:35:33 -0400 Subject: [PATCH 6472/6505] Update build.func switch Alpine repositories to http://dl-cdn.alpinelinux.org/alpine/latest-stable/main http://dl-cdn.alpinelinux.org/alpine/latest-stable/community from http://dl-cdn.alpinelinux.org/alpine/v3.19/main http://dl-cdn.alpinelinux.org/alpine/v3.19/community --- misc/build.func | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/build.func b/misc/build.func index e8e98f4b..c7c501e7 100644 --- a/misc/build.func +++ b/misc/build.func @@ -629,10 +629,10 @@ EOF if [ "$var_os" == "alpine" ]; then sleep 3 pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories -#http://dl-cdn.alpinelinux.org/alpine/latest-stable/main -#http://dl-cdn.alpinelinux.org/alpine/latest-stable/community -http://dl-cdn.alpinelinux.org/alpine/v3.19/main -http://dl-cdn.alpinelinux.org/alpine/v3.19/community +http://dl-cdn.alpinelinux.org/alpine/latest-stable/main +http://dl-cdn.alpinelinux.org/alpine/latest-stable/community +#http://dl-cdn.alpinelinux.org/alpine/v3.19/main +#http://dl-cdn.alpinelinux.org/alpine/v3.19/community EOF' pct exec "$CTID" -- ash -c "apk add bash >/dev/null" fi From d3f71d078d71764e98ac566cf6b7faf70be08471 Mon Sep 17 00:00:00 2001 From: nazgul6 Date: Sun, 30 Jun 2024 15:43:59 +0200 Subject: [PATCH 6473/6505] Updated debian 12 image (#3299) --- vm/debian-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index 6a20b717..5061d4ac 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -370,7 +370,7 @@ fi msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image" -URL=https://cloud.debian.org/images/cloud/bookworm/20231228-1609/debian-12-nocloud-amd64-20231228-1609.qcow2 +URL=https://cloud.debian.org/images/cloud/bookworm/20240507-1740/debian-12-nocloud-amd64-20240507-1740.qcow2 sleep 2 msg_ok "${CL}${BL}${URL}${CL}" wget -q --show-progress $URL From 39ea1d4a20b83c07d084ebafdc811eec3548f289 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jun 2024 10:18:37 -0400 Subject: [PATCH 6474/6505] Require PVE 8.1 or later --- misc/build.func | 9 +++------ vm/debian-vm.sh | 6 +++--- vm/haos-vm.sh | 6 +++--- vm/mikrotik-routeros.sh | 10 +++++----- vm/nextcloud-vm.sh | 6 +++--- vm/openwrt.sh | 8 ++++---- vm/owncloud-vm.sh | 6 +++--- vm/ubuntu2204-vm.sh | 6 +++--- vm/ubuntu2404-vm.sh | 6 +++--- 9 files changed, 30 insertions(+), 33 deletions(-) diff --git a/misc/build.func b/misc/build.func index c7c501e7..b650a6c0 100644 --- a/misc/build.func +++ b/misc/build.func @@ -95,16 +95,13 @@ root_check() { # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. pve_check() { - if [ $(pveversion | grep "pve-manager/8" | wc -l) -ne 1 ]; then - whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Proxmox VE 7 Detected" "You are currently using Proxmox VE 7 (EOL 2024-07), refrain from creating Debian 12 LXCs. \nDefault distribution for $APP LXC is ${var_os} ${var_version}" 10 60 - fi - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } # This function checks the system architecture and exits if it's not "amd64". diff --git a/vm/debian-vm.sh b/vm/debian-vm.sh index 5061d4ac..d6159317 100644 --- a/vm/debian-vm.sh +++ b/vm/debian-vm.sh @@ -92,13 +92,13 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } function arch_check() { diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 4c82712a..bad50312 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -115,13 +115,13 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } function arch_check() { diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index af4fd0c2..f9e05f33 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -62,11 +62,11 @@ function cleanup() { } TEMP_DIR=$(mktemp -d) pushd $TEMP_DIR >/dev/null - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then - echo "⚠ This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." - echo "Exiting..." - sleep 3 +if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." + echo -e "Exiting..." + sleep 2 exit fi if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "Mikrotik RouterOS CHR VM" --yesno "This will create a New Mikrotik RouterOS CHR VM. Proceed?" 10 58); then diff --git a/vm/nextcloud-vm.sh b/vm/nextcloud-vm.sh index 23cc5606..1e50c37d 100644 --- a/vm/nextcloud-vm.sh +++ b/vm/nextcloud-vm.sh @@ -91,13 +91,13 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } function arch_check() { diff --git a/vm/openwrt.sh b/vm/openwrt.sh index e3e32e9e..3cdd38f3 100644 --- a/vm/openwrt.sh +++ b/vm/openwrt.sh @@ -157,13 +157,13 @@ function msg_error() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then - echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then + msg_error "This version of Proxmox Virtual Environment is not supported" + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } function arch_check() { diff --git a/vm/owncloud-vm.sh b/vm/owncloud-vm.sh index 006a4649..871f5eeb 100644 --- a/vm/owncloud-vm.sh +++ b/vm/owncloud-vm.sh @@ -91,13 +91,13 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } function arch_check() { diff --git a/vm/ubuntu2204-vm.sh b/vm/ubuntu2204-vm.sh index 5fffcf0d..cb6884d8 100644 --- a/vm/ubuntu2204-vm.sh +++ b/vm/ubuntu2204-vm.sh @@ -92,13 +92,13 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } function arch_check() { diff --git a/vm/ubuntu2404-vm.sh b/vm/ubuntu2404-vm.sh index 7869d189..c3dd1750 100644 --- a/vm/ubuntu2404-vm.sh +++ b/vm/ubuntu2404-vm.sh @@ -92,13 +92,13 @@ function check_root() { } function pve_check() { - if ! pveversion | grep -Eq "pve-manager/(7\.4-(1[3-8])|8\.[1-2])"; then + if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then msg_error "This version of Proxmox Virtual Environment is not supported" - echo -e "Requires PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later." + echo -e "Requires Proxmox Virtual Environment Version 8.1 or later." echo -e "Exiting..." sleep 2 exit - fi +fi } function arch_check() { From 6e6a86aaa9d134d7e94efee9fff62c2cfea0b11c Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 30 Jun 2024 11:50:59 -0400 Subject: [PATCH 6475/6505] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca9f1043..8d29cea1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,14 @@ - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. + +## 2024-06-30 + +### Changed + +- **All Scripts** + - Requires Proxmox Virtual Environment version 8.1 or later. + ## 2024-06-27 ### Changed From eab4160c33137b8e999dea7df0821f9e0988a48c Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Jul 2024 02:59:33 -0400 Subject: [PATCH 6476/6505] Update frigate-install.sh fixes https://github.com/tteck/Proxmox/issues/3315 --- install/frigate-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/frigate-install.sh b/install/frigate-install.sh index 52b3cb2d..f9765286 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -60,6 +60,7 @@ $STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-whe cp -a /opt/frigate/docker/main/rootfs/. / export TARGETARCH="amd64" echo 'libc6 libraries/restart-without-asking boolean true' | debconf-set-selections +wget -q -O /opt/frigate/docker/main/install_deps.sh https://raw.githubusercontent.com/blakeblackshear/frigate/dev/docker/main/install_deps.sh $STD /opt/frigate/docker/main/install_deps.sh $STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg $STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe From 5fcae037c20885d431959313c573057f0a488699 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 2 Jul 2024 20:23:52 -0400 Subject: [PATCH 6477/6505] Update photoprism-install.sh tweak --- install/photoprism-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/photoprism-install.sh b/install/photoprism-install.sh index 9737f0ec..8e0df7ab 100644 --- a/install/photoprism-install.sh +++ b/install/photoprism-install.sh @@ -51,6 +51,7 @@ PHOTOPRISM_STORAGE_PATH='/opt/photoprism/storage' PHOTOPRISM_ORIGINALS_PATH='/opt/photoprism/photos/originals' PHOTOPRISM_IMPORT_PATH='/opt/photoprism/photos/import' EOF +ln -sf /opt/photoprism/bin/photoprism /usr/local/bin/photoprism msg_ok "Installed PhotoPrism" msg_info "Creating Service" From ef27851d31944d10995b3cf75f508c2dfbbf11b6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 09:06:30 -0400 Subject: [PATCH 6478/6505] Update bunkerweb.sh tweak `function update_script()` --- ct/bunkerweb.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ct/bunkerweb.sh b/ct/bunkerweb.sh index 701d6d83..3873484f 100644 --- a/ct/bunkerweb.sh +++ b/ct/bunkerweb.sh @@ -55,10 +55,18 @@ function default_settings() { function update_script() { header_info if [[ ! -d /etc/bunkerweb ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -msg_info "Updating $APP" -apt-get update &>/dev/null -apt-get -y upgrade &>/dev/null -msg_ok "Updated $APP" +RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + + msg_info "Updating ${APP} to ${RELEASE}" + apt-get install nginx -y + apt-get install -y bunkerweb=${RELEASE} + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Updated ${APP} to ${RELEASE}" + +else + msg_ok "No update required. ${APP} is already at ${RELEASE}" +fi exit } From 85418addac13e6860b0a6f45bd04a7f83b64be1a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 09:21:41 -0400 Subject: [PATCH 6479/6505] Update bunkerweb-install.sh always install the newest release --- install/bunkerweb-install.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/install/bunkerweb-install.sh b/install/bunkerweb-install.sh index f0a8d4aa..d25539cd 100644 --- a/install/bunkerweb-install.sh +++ b/install/bunkerweb-install.sh @@ -23,19 +23,20 @@ $STD apt-get install -y lsb-release $STD apt-get install -y debian-archive-keyring msg_ok "Installed Dependencies" -msg_info "Installing Nginx v1.20.0" +msg_info "Installing Nginx" wget -qO- https://nginx.org/keys/nginx_signing.key | gpg --dearmor >/usr/share/keyrings/nginx-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian `lsb_release -cs` nginx" >/etc/apt/sources.list.d/nginx.list $STD apt-get update -$STD apt-get install -y nginx=1.24.0-1~$(lsb_release -cs) -msg_ok "Installed Nginx v1.20.0" +$STD apt-get install -y nginx +msg_ok "Installed Nginx" -msg_info "Installing BunkerWeb v1.5.7" +RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +msg_info "Installing BunkerWeb v$(RELEASE}" export UI_WIZARD=1 curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash &>/dev/null -$STD apt-get install -y bunkerweb=1.5.7 -#$STD apt-mark hold nginx bunkerweb -msg_ok "Installed BunkerWeb v1.5.7" +$STD apt-get install -y bunkerweb=$(RELEASE} +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed BunkerWeb v$(RELEASE}" motd_ssh customize From 5ef5f0086ee25b476fe3c96b3d9bf2dcd97f8f50 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 09:26:20 -0400 Subject: [PATCH 6480/6505] Update bunkerweb.sh - works for 1.5.8 and newer - if the update fails with 1.5.7 execute `RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') apt-get install -y bunkerweb=${RELEASE}` in the LXC console --- ct/bunkerweb.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/bunkerweb.sh b/ct/bunkerweb.sh index 3873484f..121aaab9 100644 --- a/ct/bunkerweb.sh +++ b/ct/bunkerweb.sh @@ -55,6 +55,7 @@ function default_settings() { function update_script() { header_info if [[ ! -d /etc/bunkerweb ]]; then msg_error "No ${APP} Installation Found!"; exit; fi + RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then From 15be0761ff4d0577313e5be58396f2817bc948fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 09:38:44 -0400 Subject: [PATCH 6481/6505] Update bunkerweb-install.sh fix curly braces --- install/bunkerweb-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/bunkerweb-install.sh b/install/bunkerweb-install.sh index d25539cd..29ed74bd 100644 --- a/install/bunkerweb-install.sh +++ b/install/bunkerweb-install.sh @@ -25,18 +25,18 @@ msg_ok "Installed Dependencies" msg_info "Installing Nginx" wget -qO- https://nginx.org/keys/nginx_signing.key | gpg --dearmor >/usr/share/keyrings/nginx-archive-keyring.gpg -echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian `lsb_release -cs` nginx" >/etc/apt/sources.list.d/nginx.list +echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian $(lsb_release -cs) nginx" >/etc/apt/sources.list.d/nginx.list $STD apt-get update $STD apt-get install -y nginx msg_ok "Installed Nginx" RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Installing BunkerWeb v$(RELEASE}" +msg_info "Installing BunkerWeb v${RELEASE}" export UI_WIZARD=1 curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash &>/dev/null -$STD apt-get install -y bunkerweb=$(RELEASE} +$STD apt-get install -y bunkerweb=${RELEASE} echo "${RELEASE}" >/opt/${APPLICATION}_version.txt -msg_ok "Installed BunkerWeb v$(RELEASE}" +msg_ok "Installed BunkerWeb v${RELEASE}" motd_ssh customize From 7daad62fad96ab832dcdaac975b3e6a8a5538822 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 10:01:49 -0400 Subject: [PATCH 6482/6505] Update bunkerweb-install.sh hold bunkerweb version --- install/bunkerweb-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/bunkerweb-install.sh b/install/bunkerweb-install.sh index 29ed74bd..20ccd2b4 100644 --- a/install/bunkerweb-install.sh +++ b/install/bunkerweb-install.sh @@ -35,6 +35,7 @@ msg_info "Installing BunkerWeb v${RELEASE}" export UI_WIZARD=1 curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash &>/dev/null $STD apt-get install -y bunkerweb=${RELEASE} +$STD apt-mark hold bunkerweb echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_ok "Installed BunkerWeb v${RELEASE}" From e6b86f3d47058af503a008feec0b9423394676fc Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 10:04:23 -0400 Subject: [PATCH 6483/6505] Update bunkerweb.sh tweak --- ct/bunkerweb.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ct/bunkerweb.sh b/ct/bunkerweb.sh index 121aaab9..9e155974 100644 --- a/ct/bunkerweb.sh +++ b/ct/bunkerweb.sh @@ -60,8 +60,11 @@ RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/late if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then msg_info "Updating ${APP} to ${RELEASE}" + apt-get update apt-get install nginx -y + apt-mark unhold bunkerweb apt-get install -y bunkerweb=${RELEASE} + apt-mark hold bunkerweb echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated ${APP} to ${RELEASE}" From f64e8ef47b6153db164df71a3e162eab3b1e22d8 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 10:22:46 -0400 Subject: [PATCH 6484/6505] Update bunkerweb-install.sh change the "hold" method --- install/bunkerweb-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/install/bunkerweb-install.sh b/install/bunkerweb-install.sh index 20ccd2b4..a26cb424 100644 --- a/install/bunkerweb-install.sh +++ b/install/bunkerweb-install.sh @@ -35,7 +35,11 @@ msg_info "Installing BunkerWeb v${RELEASE}" export UI_WIZARD=1 curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash &>/dev/null $STD apt-get install -y bunkerweb=${RELEASE} -$STD apt-mark hold bunkerweb +cat </etc/apt/preferences.d/bunkerweb +Package: bunkerweb +Pin: version ${RELEASE} +Pin-Priority: 1001 +EOF echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_ok "Installed BunkerWeb v${RELEASE}" From fc5ea73e450190b915aa5298f423b77a8a8baad3 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 10:24:42 -0400 Subject: [PATCH 6485/6505] Update bunkerweb.sh change the "hold" method --- ct/bunkerweb.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ct/bunkerweb.sh b/ct/bunkerweb.sh index 9e155974..14e8a2a6 100644 --- a/ct/bunkerweb.sh +++ b/ct/bunkerweb.sh @@ -60,11 +60,14 @@ RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/late if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then msg_info "Updating ${APP} to ${RELEASE}" + cat </etc/apt/preferences.d/bunkerweb +Package: bunkerweb +Pin: version ${RELEASE} +Pin-Priority: 1001 +EOF apt-get update apt-get install nginx -y - apt-mark unhold bunkerweb apt-get install -y bunkerweb=${RELEASE} - apt-mark hold bunkerweb echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Updated ${APP} to ${RELEASE}" From 65968509182c9f25c7445eaeed3f9ca22f441b8d Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 13:12:59 -0400 Subject: [PATCH 6486/6505] Update traefik-install.sh hard-code version --- install/traefik-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/traefik-install.sh b/install/traefik-install.sh index b8346196..7b5c44b3 100644 --- a/install/traefik-install.sh +++ b/install/traefik-install.sh @@ -21,7 +21,7 @@ $STD apt-get install -y gpg $STD apt-get install -y apt-transport-https msg_ok "Installed Dependencies" -RELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +RELEASE=3.0.4 #$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') msg_info "Installing Traefik v${RELEASE}" mkdir -p /etc/traefik/{conf.d,ssl} wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz From 496b9bf92ce8ba1a8995bfce0f6f9f8cbee0d49a Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 3 Jul 2024 13:14:12 -0400 Subject: [PATCH 6487/6505] Update traefik.sh hard-code version --- ct/traefik.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/traefik.sh b/ct/traefik.sh index 503d51dc..0da650d1 100644 --- a/ct/traefik.sh +++ b/ct/traefik.sh @@ -55,7 +55,7 @@ function default_settings() { function update_script() { header_info if [[ ! -f /etc/systemd/system/traefik.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -RELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +RELEASE=3.0.4 #$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') msg_info "Updating $APP LXC" if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz From dad9da5e678618114e100762589ef41d7284b749 Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Jul 2024 10:55:39 -0400 Subject: [PATCH 6488/6505] Update jellyseerr.sh tweak update (main branch) --- ct/jellyseerr.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh index 36f352d0..5f3548bf 100644 --- a/ct/jellyseerr.sh +++ b/ct/jellyseerr.sh @@ -21,7 +21,7 @@ echo -e "Loading..." APP="Jellyseerr" var_disk="8" var_cpu="2" -var_ram="4096" +var_ram="2048" var_os="debian" var_version="12" variables @@ -66,7 +66,7 @@ then systemctl start jellyseerr exit fi -yarn install &>/dev/null +CYPRESS_INSTALL_BINARY=0 yarn install --frozen-lockfile --network-timeout 1000000 &>/dev/null yarn build &>/dev/null systemctl start jellyseerr msg_ok "Updated $APP" @@ -77,10 +77,6 @@ start build_container description -msg_info "Setting Container to Normal Resources" -pct set $CTID -memory 2048 -msg_ok "Set Container to Normal Resources" - msg_ok "Completed Successfully!\n" echo -e "${APP} should be reachable by going to the following URL. ${BL}http://${IP}:5055${CL} \n" From 8562dd1b9360933789e25c85a1705e5dfe02f02e Mon Sep 17 00:00:00 2001 From: tteckster Date: Thu, 4 Jul 2024 10:56:52 -0400 Subject: [PATCH 6489/6505] Update jellyseerr-install.sh switch back to the main branch --- install/jellyseerr-install.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/install/jellyseerr-install.sh b/install/jellyseerr-install.sh index 5de57a62..38ae8b22 100644 --- a/install/jellyseerr-install.sh +++ b/install/jellyseerr-install.sh @@ -33,15 +33,17 @@ $STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" -msg_info "Installing pnpm" -$STD npm install -g pnpm -msg_ok "Installed pnpm" +msg_info "Installing Yarn" +$STD npm install -g yarn +msg_ok "Installed Yarn" msg_info "Installing Jellyseerr (Patience)" git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr cd /opt/jellyseerr -CYPRESS_INSTALL_BINARY=0 pnpm install --frozen-lockfile &>/dev/null -$STD pnpm build +$STD git checkout main +CYPRESS_INSTALL_BINARY=0 yarn install --frozen-lockfile --network-timeout 1000000 &>/dev/null +$STD yarn install +$STD yarn build mkdir -p /etc/jellyseerr/ cat </etc/jellyseerr/jellyseerr.conf PORT=5055 @@ -53,17 +55,15 @@ msg_ok "Installed Jellyseerr" msg_info "Creating Service" cat </etc/systemd/system/jellyseerr.service [Unit] -Description=Jellyseerr Service -Wants=network-online.target -After=network-online.target +Description=jellyseerr Service +After=network.target [Service] EnvironmentFile=/etc/jellyseerr/jellyseerr.conf Environment=NODE_ENV=production Type=exec -Restart=on-failure WorkingDirectory=/opt/jellyseerr -ExecStart=/usr/bin/node dist/index.js +ExecStart=/usr/bin/yarn start [Install] WantedBy=multi-user.target From 186f186e8b6c8d706adc8a110646f93147e35448 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 5 Jul 2024 01:09:30 -0400 Subject: [PATCH 6490/6505] Update pingvin.sh fixes https://github.com/tteck/Proxmox/issues/3331 --- ct/pingvin.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ct/pingvin.sh b/ct/pingvin.sh index ff582d2f..0cce4f60 100644 --- a/ct/pingvin.sh +++ b/ct/pingvin.sh @@ -64,8 +64,10 @@ cd /opt/pingvin-share git fetch --tags git checkout $(git describe --tags `git rev-list --tags --max-count=1`) &>/dev/null cd backend +npm install &>/dev/null npm run build &>/dev/null cd ../frontend +npm install &>/dev/null npm run build &>/dev/null msg_ok "Updated Pingvin Share" From 3a65f89cabc38d8b76f536b566a621227dce5454 Mon Sep 17 00:00:00 2001 From: Mathijs Groothuis Date: Sun, 7 Jul 2024 17:50:10 +0200 Subject: [PATCH 6491/6505] Update calibre-web.sh (#3346) --- ct/calibre-web.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/calibre-web.sh b/ct/calibre-web.sh index 69752501..5cf87184 100644 --- a/ct/calibre-web.sh +++ b/ct/calibre-web.sh @@ -65,8 +65,6 @@ function update_script() { rm kepubify-linux-64bit curl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-64bit &>/dev/null chmod +x kepubify-linux-64bit - rm /opt/calibre-web/metadata.db - wget https://github.com/janeczku/calibre-web/raw/master/library/metadata.db -P /opt/calibre-web menu_array=("1" "Enables gdrive as storage backend for your ebooks" OFF \ "2" "Enables sending emails via a googlemail account without enabling insecure apps" OFF \ "3" "Enables displaying of additional author infos on the authors page" OFF \ From 22c7801217482eb9f0ecfc37f2c0ebe6cdf14351 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 7 Jul 2024 16:40:15 -0400 Subject: [PATCH 6492/6505] Update mikrotik-routeros.sh chr-7.15.2 --- vm/mikrotik-routeros.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mikrotik-routeros.sh b/vm/mikrotik-routeros.sh index f9e05f33..29b41892 100644 --- a/vm/mikrotik-routeros.sh +++ b/vm/mikrotik-routeros.sh @@ -234,7 +234,7 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." msg_info "Getting URL for Mikrotik RouterOS CHR Disk Image" -URL=https://download.mikrotik.com/routeros/7.12.1/chr-7.12.1.img.zip +URL=https://download.mikrotik.com/routeros/7.15.2/chr-7.15.2.img.zip sleep 2 msg_ok "${CL}${BL}${URL}${CL}" From 8892fd960f33b0683e12560ebcc458e71a88d4a1 Mon Sep 17 00:00:00 2001 From: tteckster Date: Fri, 12 Jul 2024 23:44:56 -0400 Subject: [PATCH 6493/6505] Update CHANGELOG.md --- CHANGELOG.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d29cea1..50c1f491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,12 @@
    -

    Change Log

    +

    Changelog

    All notable changes to this project will be documented in this file.

    +- I keep the website source private to prevent _**copycat**_ sites from exploiting the project's popularity with potentially malicious intent. Please only trust information from https://Helper-Scripts.com/ or https://tteck.github.io/Proxmox/. + - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. @@ -14,16 +16,16 @@ ### Changed -- **All Scripts** +- **All Scripts** [(Commit)](https://github.com/tteck/Proxmox/commit/39ea1d4a20b83c07d084ebafdc811eec3548f289) - Requires Proxmox Virtual Environment version 8.1 or later. ## 2024-06-27 ### Changed -- **Kubo LXC** +- **Kubo LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/kubo-install.sh) - NEW Script -- **RabbitMQ LXC** +- **RabbitMQ LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/rabbitmq-install.sh) - NEW Script - **Scrutiny LXC** - Removed from website, broken. @@ -39,27 +41,27 @@ ### Changed -- **MySpeed LXC** +- **MySpeed LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/myspeed-install.sh) - NEW Script ## 2024-06-13 ### Changed -- **PeaNUT LXC** +- **PeaNUT LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/peanut-install.sh) - NEW Script - **Website** - If the Changelog has changed recently, the link on the website will pulse. -- **Spoolman LXC** +- **Spoolman LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/spoolman-install.sh) - NEW Script ## 2024-06-12 ### Changed -- **MeTube LXC** +- **MeTube LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/metube-install.sh) - NEW Script -- **Matterbridge LXC** +- **Matterbridge LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/matterbridge-install.sh) - NEW Script - **Website** - Reopen the gh-pages site (https://tteck.github.io/Proxmox/) @@ -68,14 +70,14 @@ ### Changed -- **Zabbix LXC** +- **Zabbix LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/zabbix-install.sh) - NEW Script ## 2024-06-06 ### Changed -- **Petio LXC** +- **Petio LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/petio-install.sh) - NEW Script - **Website** - Important notices will now be displayed on the landing page. @@ -84,14 +86,14 @@ ### Changed -- **FlareSolverr LXC** +- **FlareSolverr LXC** [(View Source)](https://raw.githubusercontent.com/tteck/Proxmox/main/install/flaresolverr-install.sh) - NEW Script ## 2024-05-31 ### Changed -- **Advanced Settings** +- **Advanced Settings** [(Commit)](https://github.com/tteck/Proxmox/commit/fc9dff220b4ea426d3a75178ad8accacae4683ca) - Passwords are now masked ## 2024-05-30 From 19fef65ac02bfabd16d56b052564183f35bf7419 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Jul 2024 00:26:39 -0400 Subject: [PATCH 6494/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50c1f491..e2728cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@

    All notable changes to this project will be documented in this file.

    -- I keep the website source private to prevent _**copycat**_ sites from exploiting the project's popularity with potentially malicious intent. Please only trust information from https://Helper-Scripts.com/ or https://tteck.github.io/Proxmox/. +- The website source is kept private to prevent _**copycat**_ sites from exploiting the project's popularity with potentially malicious intent. Please only trust information from https://Helper-Scripts.com/ or https://tteck.github.io/Proxmox/. - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. From 2446b6599f3182b9a0ce81d8d8acc119613d826d Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Jul 2024 13:28:19 -0400 Subject: [PATCH 6495/6505] Update pingvin-install.sh fixes https://github.com/tteck/Proxmox/issues/3373 --- install/pingvin-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/pingvin-install.sh b/install/pingvin-install.sh index c848cfb3..4430cc21 100644 --- a/install/pingvin-install.sh +++ b/install/pingvin-install.sh @@ -43,6 +43,7 @@ $STD npm install $STD npm run build $STD pm2 start --name="pingvin-share-backend" npm -- run prod cd ../frontend +sed -i '/"admin.config.smtp.allow-unauthorized-certificates":\|admin.config.smtp.allow-unauthorized-certificates.description":/,+1d' ./src/i18n/translations/fr-FR.ts $STD npm install $STD npm run build $STD pm2 start --name="pingvin-share-frontend" npm -- run start From e3da97472e64584846fae33b8b2c572000efa85b Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 13 Jul 2024 16:11:36 -0400 Subject: [PATCH 6496/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2728cd0..01d7d169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@

    All notable changes to this project will be documented in this file.

    -- The website source is kept private to prevent _**copycat**_ sites from exploiting the project's popularity with potentially malicious intent. Please only trust information from https://Helper-Scripts.com/ or https://tteck.github.io/Proxmox/. +- The website source is private and will not be made open-source to help prevent copycat/coat-tailing sites from exploiting the project's popularity with potentially malicious intent. Please only trust information from https://Helper-Scripts.com/ or https://tteck.github.io/Proxmox/. - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. From bf40c30fffee07424aba152aba05aa6403089725 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jul 2024 01:19:16 -0400 Subject: [PATCH 6497/6505] Update haos-vm.sh add local-zfs --- vm/haos-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index bad50312..90bb9751 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -428,7 +428,7 @@ nfs | dir) DISK_IMPORT="-format raw" THIN="" ;; -btrfs) +btrfs | local-zfs) DISK_EXT=".raw" DISK_REF="$VMID/" DISK_IMPORT="-format raw" From 9cbd0f30376787e49d3972fdbc0af6872467c1e6 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jul 2024 11:27:55 -0400 Subject: [PATCH 6498/6505] Update install.func fixes https://github.com/tteck/Proxmox/issues/3386 --- misc/install.func | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/install.func b/misc/install.func index c698e258..660ea2c4 100644 --- a/misc/install.func +++ b/misc/install.func @@ -87,7 +87,10 @@ msg_error() { setting_up_container() { msg_info "Setting up Container OS" sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen + locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1) + echo "LANG=${locale_line}" >/etc/default/locale locale-gen >/dev/null + export LANG=${locale_line} echo $tz >/etc/timezone ln -sf /usr/share/zoneinfo/$tz /etc/localtime for ((i = RETRY_NUM; i > 0; i--)); do From 00a8f07170baae216a04a2617d9411d0fc2fd1d0 Mon Sep 17 00:00:00 2001 From: tteckster Date: Tue, 16 Jul 2024 14:04:50 -0400 Subject: [PATCH 6499/6505] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01d7d169..517cda16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@

    All notable changes to this project will be documented in this file.

    -- The website source is private and will not be made open-source to help prevent copycat/coat-tailing sites from exploiting the project's popularity with potentially malicious intent. Please only trust information from https://Helper-Scripts.com/ or https://tteck.github.io/Proxmox/. +- Be cautious of copycat or coat-tailing sites that exploit the project's popularity with potentially malicious intent. Please only trust information from https://Helper-Scripts.com/ or https://tteck.github.io/Proxmox/. - All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment. From 9deea7a9830bb1457c1f051ca5f1e7c7d6d127e7 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jul 2024 13:32:26 -0400 Subject: [PATCH 6500/6505] Update vaultwarden.sh add Admin Token to `/opt/vaultwarden/data/config.json` --- ct/vaultwarden.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index b5cb6fa5..413cd5fa 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -127,7 +127,9 @@ function update_script() { if [[ -z "$NEWTOKEN" ]]; then exit; fi if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) - sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env + for file in /opt/vaultwarden/.env /opt/vaultwarden/data/config.json; do + sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" "$file" + done systemctl restart vaultwarden fi exit From cfa1b2e04d9056fe96981677bd856f7111ad9495 Mon Sep 17 00:00:00 2001 From: tteckster Date: Wed, 17 Jul 2024 13:48:42 -0400 Subject: [PATCH 6501/6505] Update vaultwarden.sh tweak --- ct/vaultwarden.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index 413cd5fa..f7901b79 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -127,9 +127,10 @@ function update_script() { if [[ -z "$NEWTOKEN" ]]; then exit; fi if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) - for file in /opt/vaultwarden/.env /opt/vaultwarden/data/config.json; do - sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" "$file" - done + sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env + if [[ -f /opt/vaultwarden/data/config.json ]]; then + sed -i "s|\"admin_token\":.*|\"admin_token\": \"${TOKEN}\"|" /opt/vaultwarden/data/config.json + fi systemctl restart vaultwarden fi exit From 2febf2c39bbdca74507a864b632908f4c14a8265 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jul 2024 06:20:20 -0400 Subject: [PATCH 6502/6505] Update unifi.sh add AVX instruction set check --- ct/unifi.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ct/unifi.sh b/ct/unifi.sh index 820930c0..cec984c5 100644 --- a/ct/unifi.sh +++ b/ct/unifi.sh @@ -17,6 +17,10 @@ cat <<"EOF" EOF } header_info +if ! grep -q -m1 'avx[^ ]*' /proc/cpuinfo; then + echo "AVX instruction set is not supported on this CPU." + exit +fi echo -e "Loading..." APP="Unifi" var_disk="8" From 6c155c7463a3c22bc73aed0165ba879f5d70dff4 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sat, 20 Jul 2024 12:44:27 -0400 Subject: [PATCH 6503/6505] Update ersatztv.sh Refactor `function update_script ()` fixes https://github.com/tteck/Proxmox/issues/3404 --- ct/ersatztv.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ct/ersatztv.sh b/ct/ersatztv.sh index de21b8ef..81ea5b7b 100644 --- a/ct/ersatztv.sh +++ b/ct/ersatztv.sh @@ -57,22 +57,20 @@ function default_settings() { function update_script() { header_info if [[ ! -d /opt/ErsatzTV ]]; then msg_error "No ${APP} Installation Found!"; exit; fi -if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then - read -r -p "Warning: Storage is dangerously low, continue anyway? " prompt - [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit -fi + msg_info "Stopping ErsatzTV" systemctl stop ersatzTV msg_ok "Stopped ErsatzTV" msg_info "Updating ErsatzTV" RELEASE=$(curl -s https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1) -if [ -d /opt/ErsatzTV/ErsatzTV_bak ]; then - rm -rf /opt/ErsatzTV/ErsatzTV_bak -fi -mv /opt/ErsatzTV/ErsatzTV /opt/ErsatzTV/ErsatzTV_bak +cp -R /opt/ErsatzTV/ ErsatzTV-backup +rm ErsatzTV-backup/ErsatzTV +rm -rf /opt/ErsatzTV wget -qO- "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz" | tar -xz -C /opt mv "/opt/ErsatzTV-${RELEASE}-linux-x64" /opt/ErsatzTV +cp -R ErsatzTV-backup/* /opt/ErsatzTV/ +rm -rf ErsatzTV-backup msg_ok "Updated ErsatzTV" msg_info "Starting ErsatzTV" From 80fb3ee841717c94088d9cb77bbaaf8c43186a88 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 21 Jul 2024 07:11:36 -0400 Subject: [PATCH 6504/6505] Update update-lxcs-cron.sh fixes https://github.com/tteck/Proxmox/issues/3408 --- misc/update-lxcs-cron.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/update-lxcs-cron.sh b/misc/update-lxcs-cron.sh index 23c44852..04827734 100644 --- a/misc/update-lxcs-cron.sh +++ b/misc/update-lxcs-cron.sh @@ -35,7 +35,6 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do fi done if [ "$excluded" == true ]; then - header_info echo -e "[Info] Skipping $container" sleep 1 else From d18e37166dd52fa8074281add9f96979b9b1cf59 Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 22 Jul 2024 06:39:34 -0400 Subject: [PATCH 6505/6505] Update bunkerweb-install.sh Refactor to eliminate script execution within another script, making the code easier to review. --- install/bunkerweb-install.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/install/bunkerweb-install.sh b/install/bunkerweb-install.sh index a26cb424..4f15709c 100644 --- a/install/bunkerweb-install.sh +++ b/install/bunkerweb-install.sh @@ -17,10 +17,9 @@ msg_info "Installing Dependencies" $STD apt-get install -y curl $STD apt-get install -y sudo $STD apt-get install -y mc -$STD apt-get install -y gnupg2 -$STD apt-get install -y ca-certificates +$STD apt-get install -y gpg +$STD apt-get install -y apt-transport-https $STD apt-get install -y lsb-release -$STD apt-get install -y debian-archive-keyring msg_ok "Installed Dependencies" msg_info "Installing Nginx" @@ -31,9 +30,11 @@ $STD apt-get install -y nginx msg_ok "Installed Nginx" RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') -msg_info "Installing BunkerWeb v${RELEASE}" +msg_info "Installing BunkerWeb v${RELEASE} (Patience)" +curl -fsSL "https://repo.bunkerweb.io/bunkerity/bunkerweb/gpgkey" | gpg --dearmor >/etc/apt/keyrings/bunkerity_bunkerweb-archive-keyring.gpg +echo "deb [signed-by=/etc/apt/keyrings/bunkerity_bunkerweb-archive-keyring.gpg] https://repo.bunkerweb.io/bunkerity/bunkerweb/debian/ bookworm main" >/etc/apt/sources.list.d/bunkerity_bunkerweb.list +$STD apt-get update export UI_WIZARD=1 -curl -sSL https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | bash &>/dev/null $STD apt-get install -y bunkerweb=${RELEASE} cat </etc/apt/preferences.d/bunkerweb Package: bunkerweb

    From 4b976b31dcaf7b992a266aa0eb143e193c244272 Mon Sep 17 00:00:00 2001 From: tteckster Date: Sun, 26 Nov 2023 18:30:31 -0500 Subject: [PATCH 5580/6505] Delete misc/images/tths.png --- misc/images/tths.png | Bin 25593 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 misc/images/tths.png diff --git a/misc/images/tths.png b/misc/images/tths.png deleted file mode 100644 index d70a0cd0d4383540c5559346be8865d9385f9d1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25593 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 Date: Mon, 27 Nov 2023 08:42:54 -0500 Subject: [PATCH 5581/6505] Add files via upload --- misc/images/logo-81x112.png | Bin 0 -> 5483 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/images/logo-81x112.png diff --git a/misc/images/logo-81x112.png b/misc/images/logo-81x112.png new file mode 100644 index 0000000000000000000000000000000000000000..04bcb8d11c300e0ce0857a7060d6d2bcc5b0e17c GIT binary patch literal 5483 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 literal 0 HcmV?d00001 From 33bd34458f7b29d8e79c505b82b3dd9940f1d2db Mon Sep 17 00:00:00 2001 From: tteckster Date: Mon, 27 Nov 2023 09:01:41 -0500 Subject: [PATCH 5582/6505] Update build.func tweak --- misc/build.func | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/misc/build.func b/misc/build.func index 78f3c74d..243fa3c5 100644 --- a/misc/build.func +++ b/misc/build.func @@ -573,9 +573,12 @@ EOF # This function sets the description of the container. description() { IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) - pct set "$CTID" -description "# ${APP} LXC - ### https://tteck.github.io/Proxmox/ - " + pct set "$CTID" -description "

    n@m8YXQEz2*`HIz>xy#$H$Ih7aN1ZFO$sH&g` zSmffm3R@tC@sB5|2D;LtUJEPU@wpT;44V1bSBKxG;PxI_c^6>0`Ljp-0m~8=o$=L5 z0^9Uc(?`OZ)DmtnA>&e^tkeqmNylyRyOpFmuXd*9t^TYMEj8xMY~*KKDVzJeWuKHqbqEpppkNmB6|qk z`1j$A9U|+5?ZYewZ7AI=a(q4Us4=C#Gmol)N_*C-LYSgSW#qS;ql!a=_dAADJt@8R z-H0=+guaNkh-7o4X5+;C_%J9?eYtGLBQ5`q79NaY2yA81=&w_y{qNTd9ppIpjiVc! z&~=+k>5C?$$1@P_aC4^Op{wC8&~Lw+rLAP%f zC}FDpU-+waYC)WX3RIWQ1AzJNzjJT?d4f`gZ}4Bngiy%o7d}U5zfJQnJsk4&gBR71 zLSfgx;vwH>2Jj{+&sAVKyh1uBhMcgcT&=59=K&Mv9hN_hr!!ipVzM)xlIN`q@kz*npZblBD zH{a}QUY^Vxj2eiD1fWzy`zBn~R3!FFKTmw|Mjt=j*6n?P*+DzTR$ zWm$P89lf*X39W$|i9C$LN7L&PPAw8X2ma}=SV= zbrKp^eP67hy@(u8>Se*6!r*VlgQL!Gb<7qw1;}7?a*vVWyK^KS^&3-J3|}!#%(d@x zsK4$C*;-dJ8nE4fr?>u0s^g%N;c0rd)Ps_5#A6Su%>%YnH}v@#yKP>g-ilv3&p~AS zmU^lTY%w+*DPD7+P1c&ShG)NuN7|&THd`2n7RIfcMU?5cC-IZ_iu~BANE%T#7r^q5 zi0qc&zH}~42hN&j8qAYbD`PPJ{&@Eu7+eLcLk@BR7kJ|7{g^G|0r!;Ka{$;smg&?yNg$U6x<*F^})U0YZz)%@-bR z(6{t(d}mGpbORyhGJ=oF9JfjylY5jsrDyZww%Ej>+hK34@>$?3oZP?Dj$BZj<4Q6= zOCdgj9`H@yFysY4Ey+Of#aO4bZfyYDA7&QlAgo!1<26^0Uv|-GzG-L2_Ubkeg zR}uD&qwHm${2Mu$>d4F)kZeM^)|GzprOchV%~Ao;5C`!R@=FKJ{tK($!>>uy7*Ua-0RF5KgOW!76X#H8?bPTF zQb1D#K%VQ`t{+%MY1V`+y&t>zvNuV^aEGKfc!e&5`Dld*E?QZw2&m%<5RXaW&34mN zwoBvbWqblQZ`rOapZ$;+d6!@GWSgFd55JFC>^ZJCwc&rr9jfW`np18d&T*len@kC` zpndnRG;?6U_IdZCgRW}L^46?6V_3FwE9QWM_b8ObfHgH)oiTKWt=)pF_(X8|_C)Hl zu^BzAitnoeUbR&hjLhzLYQI;~vGYOKTD(l1$MQ1qR?ByiwfrmcKxW(s+DH^eH zyPv?G-PWOe`v?)>?XJ6A-$T*(p zZd65gmx6#+nFy*t-gRdr?q1uquo_A5r(cc|j=j9PJGV4NY)AJwx;U~##pacW8_)7T zj5;~6=7ZiM`eRTcKV`Be2FZ?^Sd{dQ5A8*yPU9okliq$;L-a!$L)nNul)O^1WYt|KIRG67?iyP&?eq=iO!L0@!aMu$KtTBe(u+289 zN2$veby$8|`gLmXYINJEB)(*x6&J<~fg$L~$zw4B)Ll@&^Uujuf~5Uf6zxy^XRM(m zIX+b9uClRJwZSKcuP-}*LSpnnNUb_UhxikY%yr#YD`46`F!Wf3#gi})sYz|ch&ZV) ztfZ*HLE7>7!XqPE?rl~%=9q&vY7%C15M0iM{gq!2FDZKe!eu7sOw^>IK9mm2=O3ax zp^-UZCB5PdQ8ea0Rj!qpV1r%DhFBI1!#tii2HGRN@gC_>p33kww=@ z>VKFV;hEbHESFh;Bq8?{6+-9at?b3 z6FnHCeM}J=P89D~X*+-`SW`FeRna<%rwRM{@FnO#n~_xVZIVB@_keesu6q89CgH0Q zEKsDLkH?vYh{tz>MRgAqsqy_DjA5SH@HU|PojtVfVF?13x3=eTC0Jb`#SqLaB*Puk z_2xK<@Mec2vHY+X+2IskvWebaKe+G!c{cL%rN z-ZuIr0ACK6S?dCdYM@Y@r!{zW?|uAA8F=6Yd>C02^F2;EU1}`GuDS88#^?H{l!PmN z$ZbF$n$<*|(l;NV$9&Pk_zX!lg?VOZXkvsRIdWdF3du!&V+&hQh20wD#;JVkx*=I8 zDHPdew*6Lp9F_rAcmP7nNz5wlzcL2UCyFyeuvqOBZemGq9`P9qx|H}!K4O%V)k1MA z*%a7J@QW7yYTS0Y#N#qCWM-VO#zJ>eYFL#SL;iTO46`j~pdmR0S@6sxk8A{?(`RiL z|M+HHlT<=cbHesU6IaGIgPezh)O61m8N^Q3nDn?_jOGs2o*T)@=2&C-UbuV#Kji12DHUd|ItPNpY z_ksXdKxaOa61}BB)aLp{U*d2#D`fN5z(rQ5W3dh%l+3{|-;nXMd=!4Bphe&UQ}mh{ zfR6v&IZt}{tk2d6`Z>CiJx50Iho*vR?&)p@Q2D@L%XJ^NCPqP|{up4TjOzTy99-i5 zlak_wlS`L^35#O+=`r~{q-BSn46A$!GTI;|A}DDT;k8qt=>($GNXp*j(KnH{D(Bej z$C*Un%r{KiC>Amd+fF3bP=6z?w@iM#Cepp}G?LYKo*Hb?q{(&gUSJ^IfGzs}+`?on zymULkC{N!3gx3O5P#;(DP;$(gnS>kqK(VP;K76$CkKqI zU}kJJnOiX=bA^g1bcN;$E5LH456~M`M^G*D>OYvl7hLrzSosXlU5y}T64=ZkT|nv~ z(+Lo8EL3+CFuL*Im2mYQAYY*FMiI9MBqppl9^Mm*hB#6BqR)R4q%u}>B|Bsuu+mIU ztN7y;XH5!+R-4Uxce`6j3qSZ1rNyhrWd?@)H+Q%GkP>_$n9>jZ_uT46Xe~a36Y)>j z=DTk!3Lk-O>0lOq>Qq6W%fmt2tly)b-s>m5qLUY(*XsM94=vGs6BJ*p!mVw}-3V`F z7iS7G>#L_~pd7ca%f_#s*wwH9v-L@wi2v*n_Z=kDK(DuOt8=^2IcGj$CF>lqrNLne zvW{YG=$l9mTe7PYtB3$EgIR)a`n-m~av2taRmO1#B9*2$bIdH3g_S5rgMz<0Pg(Bm zY_AhzEqsKw_r=0Gq%ffP@SuVuv{?z4)lvvgNi=SD$YOCcsm^ZUg%Br}fJXUn->Ltk zBxYCWyI8A(`^H<0hTk?dgg-C6M2WiB0AUK02yO=GZ??uvx9VdnY4N3DD3G`3``xW- zI@zK}I%@B3vsDTVuuGCKssh%q9*Y$2)Q0=aTxcMM(9Zy z{OfOH5FB|HssIOIAxvD_Ip@;bMsk|;F>JbVi6aIXb)_}J@f3N9z^G#UHQi0VtwP5t zQ$wk9Mayx0;H8Z7ySHiY-4}};+UH!90M+{1)9oZ*v5ZtX#${Y$*(N?=9OWf`6hyS` zbi+CSnq1|XsTl=23vy*^K}=eoP#p1MIiIL^Yps~`)x2s9%wHP~YU}Q)J7IhLQvkPJ zZXwBH506NpXw>vn#r>)2Ss^^)vfX&WNDmh@>rPg=7lUl?|8gxG)PA#I9Gmnpw7)CT zjJVNmQRf^`Jua1^e0ETru)c5?t!Ic^W9SwTog|qzP=RJ#Q``4R3beRgn%`O>zL?DM zl{hf)rNgBuGtzXdP=?<-vps%*lWw()^btvOgmEG0CZNQ_mZqR3$m!LOgTRs=ra)um z@fuVNslUO4O%)dK2-LiU&8l)T2+VW4`(Y9m@E2+v5?VSnf|0(4Vt(4y;zs(FqZ`T| zB8L`y@;!$Bpri=gg4o^Bs!~#9twN2E`8NT9f*#%;2#Gal%oxjX2%GDw52S0cfigAc zB;jxxm8s@Hc`o!BzprLWoQv|X{eu33<%b^MouC_zs9icpj>0or!Q)#A5zFnsKNq^EO4v6V9@13sNFyr2k7CO(ry!G4t9?C{$B}TmcwN2gczy9b<8SkjP@XX&ZA8zQ zvNaLgBLI@^Xw2l}_LiuLv+WjxP^3p$L?ebYPz3V-!J=imB94SAccJ2T3v-i;UC51g zbazJFojx-QvonT=0E;qp-t?sFwY#Zaw4$qZfl6Ww*4W)5)+<6T(tQ$+Q5m^(5i{?D zHtc)R_5B8o0BqiLMY?kycXKuiMF@|gF9>W&x(KHMRXR7DAGE) z6GIo7SOz}DlUE;8a7rwkE7gFOCUz6&V(Hhp3xZ7M>kB2DZ$XT%4dN_}+Ntw;{H1U6 zjnTB+i~tQ;RJ6ahL7p^!R23*KaUjS{HYk(0AidYF*^R501T1YAF^lLoKg{=_*R zbogh`pLj=le697jK*d;M(tQ^EZXex5TZ60emqD&1EqBbA7`IsV??6v0+GGnUKqL47 z$n81L`U8D^lL>d)soL?-tCM=ju1E*>Bzm@|R*t{nwL5L&7@|hM`}f-e)jL*xdCm9n zmGdghsZBr@P(gAR)5^ZN*y566(e*)z4eoE41!hvOV8KAcMw3C+gAzt#Mr0|!H7?Y$ zP!1*K7Gu^9m%fB8@8(@YRT;jxaG;~b^kpI zobU1Rd%O>}qF4`LAg5bt0SW93dp|)DTvR4nnaC(1ly&VTj6H+vK_OgImGHDuQ6PmH zEkUKC;woAI1KtI&;ClcQA~r;fh*)vTrK0Z_4EZyRDaY?7jCnx==*MqG3@TXk)r3ta z)ZX+Bf?2;BF)U$Oz_f^M1>-)IFz*pn$Wf{2j7voy%9V74mG3Lq8G8rEN(N_aBy*hz zF;@#AJja+Eu{p)XZ3`J(H-&IQ?O=@YCxr2(caS)MlR@AJ#1)7$u(Rl~k-?F0jBy}? zV<&{dM=t;UGyc`(qEW8p56m(_Cc$KeYk|>ql$Am)2GQ1~Vw9qpbcMlG%?&&x7ar8kFCsM~5iGzXI;Ve3#e2es6&L zz7v-J8pgjN8UJYXE?ECj*!~{4{a(2J3-AN}PjLGK@MHf?Sbq4^9~*t-8^3Dj6WB92 zIJ0yS$l9$d7DZv@qDT-s{e)~Vv$Dj2_3OQ$2rh;4PrVrR!|3&WNRMGi+P4h7HO6dFU<6q#%AN(J*+RpuddRa+m0Io_74G2qF(jsD5t)~Ts6h=mF z!Z9$D-Q?uVdNxaRgO%qaB}T|}VFI`_(2;pby=U3nCFe^wJEfY9mJH{5 z1alJpE-~R#;-{H#u`jj$9@M4guIeXq##}V4O!JhW^LZx;3S*)c}|{4;U3fw~21y{Wd=5@EWnr5Z}mfwYpwDI$eD4Rnv*n~~*+aQCR$-`nI8QchDFsgz>Ldedp zl@+mw!YYbX(SrFXQS^Mld0$ho;79(X|1H9XiV^?oOp@wwY$2U&6qQg$WZ&_~L^ED>G)kk2vk7 z`--XW#u!_$_8ka&69yM7&dxoqnP9A5FuP#){R@oc3#KP*PZ(e9qMRSnafr+jtfEwy z4qP4p03ZNKL_t(QKSj-im(T}waOUdZQXX>c>;LDk<#U7s>nJOOIQGQRnf$ZMKV5bL zW)d-5m(_C&ZGWb$v*qXMiF9EmW%Y#=Qfd(os*+EcNFmiwT%I59gAm?jj({1SC7e!Y zk~sPaa~Y21fSK}hG&D={ILYLXDwlm`IeyGshHRfuPM=g>SWhWGOENok6Fzq)JuY8S zPG2PbF8#~O&!L;}Tg#$uLXz>nuUtn8>yKFG|Cw1x9sRpM*#EVwf7!qPPk!wlzxU`* zKKDN;S*j4gD?|>@XvoZ&#`+1F9G(rqGVDQL8C7w{YhiBCW(s-!Fj?44yzVeQ89jwG zYbbV!Mgn9|RBtnduu#ZloG#kLIA=}wN;#}_vQo&aQD96&FBt*!-QL>>m}y%(y{G^I zr%Op8+eY1PdeLqJ#Ei~MgSkSlr|{LfCA15(g=4jT7C>=*SvRZ-DZESsu+#L?G00=C zNhIIinAfhZJ^dXZgSXXdXsRNY-Vbb3of60#hzEdS_>5G;GTXDKNe?X zP0nh=R`MAFmD?bF@L>v zHV?RWHf*Y#QNqU0{ao4KnY3Y}%I2oSW>>2uunRwvb>nQ+*S6XeEtpGRV-q|_5ngj9 zyw1*a)@>-SwUgCAdt5^8#rEL&z09r~NnxD(1R1p1Z6au$D(YiVvEvLO6l>YI$hL{W zzbA)&;2f=>e!P|I%Teksmd%>fdl(Ehp6GMEmCtu0fvsJ~NIffot<4Scb;t5~xzoZS z)GE33u@amT$>Y;zS(5pZg)D=VoH!1hO(&>>RxUrVj6xAKVi;xzm#KqscJRCh$*?kb zft_H@6$%&pjDi6P3lb(IY*?j=5_UY&0{Vg}30pG8ELf8;Ct***pn^pUCOx9DCdQ~Q zm`SSWvjoHLKSeMtW7~ftSeHT-3-)CUOjwvPF@-Naa1M2ll0_LqOOT8@@a{rbn=m(H zZyDdB27n#K=9}v1TbuFN7mt6PRb_B>7E9>4YJxdHnoH&NSo&vEQd2qq%a0GIVjVr2etkKgy9vu}kZey$Pj4*O(bUoD z50>*$SpSZh6xRR3>|pwyzx%`e-?;iW_x`{;-+HH;?{PzSOm7V55>-(&nmSs~5}pge zGEDSFE4`>K-EMfgjn{5 z-KZ@zEFy%v6(I~ZQYC&!7z0rC(3$cfod#qO#BQ*nqPUnes`k+&w<8K%olGiLQxHO# zKjfNyNEN)iN=l%Tz;RFx+tzHPLqbT`1NjrxFc3UF-Wym) z>tp{JfFB};!;U_Xk70#F{C?S7QB*0afQq&=Vi=W_;T%&8KNzlfzFDep8dQqSc>WU5 zyUfxC@D}HRtoFeGtdn83lraz-D;ccQ15MpH4a?|wKn{m0qS`oD{dZwbrs_pBAnjIA z3!DkJEi;DM)RaY4uU+~$_~Vf)fM)rvCe^I z2IXeURh74zTf_fvEY$)uLq_CpLKZ?Lc1)s9s|q)6t%k#Xj>%YSR$Niq1l-~}TdH(U zP~)Mhr_Zns0#o$98HqKLrnjlT)4C*wM9uD7r(r)rJgOARpuR;_HqP(4)wf&z{J*Vb ziudx(k@)84^L@ie(*xI3KwORj^&U9dm<&HS8ITD=LIb z6GcG^o5l+0NgX_0FyHis@$tI~1|%#^UiuPg^Ef|-vE@586z6Ar%WQ>Y~WC$Z`Wt-GY z2!_6gIPVx+--)sI5$AVYBn(bioG>|IbHeB<;9L;w-k)PEFV4Tyq6{+DXELZ9fJVt0 z;s(SKBuu8a*});F5Uv5Bi zzNcBj)niE@B2svEE;SVN#A20@dkHzgXgZl4N;hFSrk#o#DDkMAB4Fljl!{btb4pL_ zV@gVr#H0t5>(kII^{jmAjCM$lrk`GZ_R%wR6CO<;U%vl>a`}_RIy!yk@xk=p&A6Me ze_^@&-7 z6uRoi=W}F2>X2x-Tp1iD zm=1dlH@ijU5VL9vb~w9V_1YYO=?J*_F<2FQ(z57#u6RCgROTl{<%{zqy-mBR7N!6HHgL(qq-b$_-XfvuB3JTI_0FxLMKX6Y9GM+3DM zr^^=p#)b0(S*{2RRIY5Vb+ZCu{TeFqQeOyMa7sGJk>&oV` zyO0#xd0(KtpS4;ZzvO*#A?3NPYhkK-nAQp5uo4I)P>5;fIlEzfg!KpFaf$CyW~-0( zb?F5Jv6jT<%vBH*{mj7V2dRczmeNY^4VoUSw-Z0#%_<6I&n^q~R84XW5y>M$ZgL2l z(eH)yo)9Fngb3bN=U|PS>KVeNAu^iT@u z88a5_NEni^Bx6c0py%-`x!N`){nuU^^EfC~GBMv840CzSK(h4d6jXzHI;)^o|5J(IFe zN^<(Ta$QPxdSyBPo68~@pXB`Snv-?(kY)ZKLF#BZkF2Bbo@-(Kt$#NC!2k1m_xjz( zfBJ?0PDxWl1~E%`PD$YT(Mma8xq8-uX6QUGtv}mPz)T8C;Yi7#CX0@i>~4+Zv@WvO zGJ8uL^?pL%U2B5nLS_voMh<;<4yQZIRKsvtTy~xj#&|rOFO&skaA+spU2?pj5|Yvv zz9+R%ZZB2Wr@2A&3JM97SwJCx^8F2z7CM%>K`y6nT@?fwB!y21pr@5arEpm=j;~+~ z%}cDJL-i2WsR403DS2;Mfpd&*A1XT7G2V)abnT)tcv}lQ*-;%_rW|@F*OE1~)rAlY zv4e>^#r=Sk^ap#RDpg!Uy;>8$sLC053^PP#1BIeMU?-@8AUPM+X3HfMKMPS(qG^Qk zbXx&^fYt3tGER66L_%hjAn2P^a$?~~N?IrSw@rc?9SObNPbj_ie;MA7AqiQ&PErYl z#35}r4~So9zr)gZyTR|(=P7TfD3SIcB(;NTc{>7`E}jJ$)Y-jpYgG&r5No|p9!MfY zp?Y7+*`DLB%;^S1Q21}Z=?}C(ld+IRx2ei=Y_HnLk>@Z}GFL+Nbz|?5T_8yV zMY(ks#YtAtVYSOLN5wD{h7)VM*84+Y3)OHLbVY93?~kgWEU1E#79Ikuy4I?myw;(v z^|04VZf!1b7X&f{$Joz;G=M~IH*zZcgfP@9-VikS2 zU_?n3CG1ETQn4gq$~OqcoPIN7&O=VTmsHV$Nd=qs&z&Jvv|v}luye7BK8~?%!MKcd z4~Yy;rE{=gVa3GvXN=5PS%PE~Lu-&sZ$UDQxuth-XU-+`stz7f-Uq9L=V#I@eul9; zhek?}%$$1%r`PNHVE{95ZzFbb$Q4W}ab(Cib4|_@-y+lvexkTaK znR`->XlJ9p=bVOO4>Wc3Xi86bvyPVQ(J<}9=F-FR=s6`X9Z)wR?WpvhKc|41BbMEt zQLg{&ay}(DeObBeD`#B(Iekevet9|7!utMo<@k-|=cqLFE#-IrKshDZ|83>+pDmYD zVLjObe&z4~aR1k?{*$4~WRMA=l0mbPu856vlr&@}$znTc zJx_@8`n7mmU1wxA(<*5+q>XMQylG~C^KAxi#>4M#2MJstg#*QKSV!RnwV5rWx39E* z(Mr0^KI$EYq7q`Bk-yiOzspAcbe&0M6@s{$ElG4wi5QYbD?-=#DZ*r85X~h!Z*g53 zw-sUB9jqNy5BDMg4CmP#V&|$MEISLt(3B?uK?^|BfNLO!5rF1g0ifGU4u`hUWj%Sz zK$g$%_^K2_*!Y4S&j2sLZRr1l!c~#OVBbUmHCsa?i8B=s3Qr8g=&nY^!bqS6)%a~p z5X&BR>jfOgInl72-<@E&1CSo7blLBNgl&usv`@x98wS-#K)XC%cq|Nv2NLYp3u;Mr z!h|%}2^6F=QZc|bLh6A#gM>+tzuLx(3IYoSVE_-(JT@YQ|L3HqXTT=v4Ujp(JNvJ8^M6$+4I4AM-)eXtvZIi+H zcb&A!vo)wKaRqphfLfpuJ-^1Q*5PN*qs})>u#q9BP}+h**~N{DTx~M(?Sx>ZXbHs} zp(%ly?#tbQ`q=K+ds(&_LRdxV{_O=TH!1trgs8%vR{j4Zk7sA(vfd!@%?+~?w{B^# ziP>UZ#Lx~pB!W0aU5WJv4t{QJ_`7sN&eK8TtYGpvLOkAMpP9B7yj?D!VJl4KR-MEh?MtjU=3C4@m0i+&klQ^Kf(RT;B#IAZ_#jAaX^olBzrqZ#XR z(tiI?vx*i>tl0SD2`kSfl<}T~p|$7x&T~%|y`-3X7gkXTlA&Z#DWO-)eiprhjOmZK zcd*qlF?9&4I_QGYigJaDLj+zCxW=`)!H=o0*>aUID20*Tb7GLxP#mF~kgF&#N0_aK z!cs@Mz>@sOG?XfY@Nl|z%t|54(?kd-Gff>WKYw|Cs5KN~9sRg+84bfyLejMS3?(Ls zb@ZqwdHg}D5^^^o$>`L{y(oH|;r^UU%+brXtp^gs&h#X8zk>gcP> z^S{>$FXmsL?%;6@6BFr&1-Ublw`o}?5aIA*u?{v)zy%{_m5ufa#FZ>UUxOl7Q#Y$5lUqsh)y75ut`lYkPLT{ zA^`vuLqks59Y1L|{3LRC(%j)tSzMTV%<;og|XQFRy!vSfeeC3SfXdJL{|1l zs8$1I%)xmLurY%e(+jN>yK@r2yYYAp=>Kv^-s9g}^(qE3iR*|;lj{^z0?U@T*i}*S z-c^_-$yP0PcE1tA1I2ToI++Ev3u-4lZloTa>qHGaTV5~cS|Nj4mjOF$Bqu`h{Qtm! zeypIq?Tol!wiDNhDyJva*2>QUsZ!!u5d{mx0jTZNhTO_bAm-vsSq{&QK%f?EnZw^b zxNJ!3hQ~v~ck(Qu+biWUS}lLq>R{&0t$`M*gqc~q5456;vU{ zfd9aLx{SEu{bsnaF$q>`)IAtcxBJvpkC!R#XZ3j&LZ0I0kJ!3bug1<&vqZOx8%)cT zz}uq=E|9slCVwZ{LN5$1AI@Rd8)Kc#`iUCYa`0PJ2|1u@EXmZ9c1QrT)oy^ap+-Vx z{xJ8PLih_dm^>iHKTmRHBaJDeP6YM+CN~}glbc1Q@S~`O5oc_tv@k0Oe8M)_fhzcq znHwC=3s#|iL%S#{CRTiIa8fYd8w=JW%tzRdFd$(;!i0nk2_v#qv|vWXj&ITg`){9d z0e$~!#+ov&^kTxGghdIH5;i4_%2>5vR>H1?VF}9;re$nPR#EEVX3R^y+|vgs7QP>0 zW5vi*#>@pf6NVP6C{?==8SF1hb_b7ZO@t6mH;+XbTw_8gCG?^WS_yqsGm$k+CMy|i zloKdNsMAFQAsldx{#x(g$J!VELFfRHUXUJ@6W7JT&|{e^ToHwkcLbWC4rY;(K??iT zIS-<8X9-Ep=k$qoK|RVFbD1S9q>yCmsRYa%_Scu|(JscF%60ELmsvs%m?@{)O}PIF zqX_Z zNVb1jIsL|&6xM%h`MEb7OL^$`mg~Q@oJZEtpD3q4)b*#H`_Fm^ozYXmj$Kl(ntLc3OTPoiDW$+28DQu9d|G zyNAAZ;?5xyMOuxXvcjk<`3~c5xu4W!$bm3n@$O^!AlfY-cBJ?b3FLKJ*2Qr-E$dww(0IF+ckwc&Z9KVyKe z%>l@(74=N!#U$`-7KKlV6V!q@GrXh!hp5z|_!|l<=J!M`%z8NpwF6|CaSq@#X&SQq z-}Eu;V13p5K9>77(Z7*THFSf)wUI^u?ash7=AtBgqZMnt0rsH4R93mg|J_zRw)?EA zO7$E_{y5_G2^Ge|l=S(V7u6uKPs0)mH-@~PQR6Uy1rV0YGdU>Z{#Z>iHZpuO&o-9q zzRBYWyE9)m3HbNq-7Fg~AaY}Q{N;Ybg6gD@ZLRctJDcRWc1E5XlQDu)vQ`{);dP7W zNc~(u(q`=IiGNnypG!piSPkR=84xp94e9kIk6Gdw!o9I5gE4i~OXP**$^X9b**~j> zfRfkPNXlk|??-&f7-A&&VLRZ6lh&|CA|{Diis(rMkg!m}QfrKfMq&xo(`CnTK?yw1 z*$%D@7GijXa2(;f=RR@suL{+HY;TCkyD#2;bISg@mDNJ$kXY{?i?u;$kh z_9P5SSagn5QMQWqPZi8MeF9-v!m@;E3EL9JWvok~ii~~x2ND)0Oe_w%f{_I)Q|I8_ z2t&^}tdTHvFF`UgJ4oYNLRdJ1L>fp!VmofFjKK!HTpEixNgex;GujhHf!>N|l_ts0O)=~8o_ofoclZk35 zxU8N?Aw}7)%?|guhJuD!kB@ksa92oSe@O#o*gDEjXi*6%DT$uwv;#tMx|F2!iRDG| zNo75F#yu>YI!e}2D(j@-+s`>Z>>ppwe`5Kbl9~!B?Abb6u1AISUtTWzs&f1_%vtL!R3*`fV0kku z*I8c~DG@A0kG>DPUBhyF%p4+_bm5H_7Sn<4Vza5=#J2-M#PKpxxL_-7{B)W1RES{X zordLjmkD1122JBck68gx+Z5v0T)nI+;6?qAyF3;W2O@c~{Qf;%)eK@v zOYNxj%wnjoNTI?aEg^~B$t3V3f;d!7cL7cVA;d8PdZ5BeF|&ieoj^cr=RSNNiHU^- zqyTPH`%#J6X0A!!kR(RpHzbThVo7r~07GL1IPh;buc5XvaI0IsojG)#w@77g(B_KPIfG8o9`NUKcaZ^u~Y=E?? z`eY=pb+S(9LB&O|4}*MFq@?KDt)H%L=Ky9M@QWJgj}g=iCkk0MNh%vL<}Cx+P?E6~ zp8vRwNb2x^=I0YYd0s;P?7D#{hWqBTSMfF2+TS{{4GsUlSx^W)&pN$)6;|MJAc=Th zwst*wj4(GlIqm;rCW3h0+lBzhw{LJ%n^Y-0m+blL3M_9z;D4-@6i}3G10;v%C^iMo z$p3Mof0sR<#EU`CIm06^~CMfLMNhDy!8cWUwNDIceRKBzOuD zl)uRJw{!!AgJS4&xDz`l&jfa|nK}uH;}a#6 zuJ$D(nXdXZ+z~jmcKY0(kVD1@qeTp{i~z>t&B5_Pzu*ak5O`=kkUR6zg82cG@Ao8NQy-zTg`n2)fZV!(G1CM0aA7?H5zn;AP2h9oS>n6jq= z`j-pV?7v2^=k&`Ni}E-VW7DS+Rwc|T*tP$hxr8PDYsR*cD*8~yyaoF*28LDi2%UqR z(0_L&gE~9NnEH}p>|Md!Q>~fUC&%8}Tq@$uF;?d;aVCP=ImnnE_}+U5g#&Qs;Bnvy zI$j20>6G&d@QiDA(T~Y5Fm?JT9Un}~>aW8;P?W+L8!P{4m4v0NUZQ4+5GH-XU>89M z;X!}8-0m5bpQ)FSb|Ba~T9(yNkbFHCQh0H8uz&rGOEZ}i-bH0^dV=4xoKouOz02`^ z=9)TMp2#Gd|Esb{CFH{T@_Rl*RYEST*WuhRDnIwdWj(W8hpeOTeY4I003ZNKL_t(v zQqF(j@!|BV%k^Gd&LdCvE9O)ddep0RbZXYoa{V7HFG4CArLs|~qWJl8{x6ol?>$Ni zZ+hEz-Qn<#lRVFb6rOKJS7dH*1#^X0?Nny~nfx`P1fDg5xN`MeNFk-585w?FDTJ?n zqZ=xO7n)}24%&w9+@W^DItr7_9`d5&9Lnn(v6(JdJO-q2XFv)K@MxFeuJsp&?*VKT zr0yoSm*9I-50x0w<-GGuYG0dp7UJS+A%m+z0Qb7YWQ++=BOsg!U{cZtg)ztDWdyKY za@^WNg$0gjSz2nY6H<{rN&p@yq?jqR#MQQ5yC90miQWXH54W8=Pitk>Fsg_i@DPuq za%dncB?GVqNEN_&_=^Ilf!%6ziIr-&qIC*jiTkz)gr$~y5dlXkT`RR~vGOCiO48SJJpwGRMnJLB(4_IF#@MNqYv6snpLRUYi<8zC4dWy9cw zom_)xA^V+^2F&?^B#kx1rginm)h;NI$$&T%GE?uM!bN2P1TJU$xos%Rr(F?5LhA16 z#7YvAr*5c9;rG$wB|sC8A7(5k8YCiC+sxP71$oo^#@5(0BwxBQgn2(xQpZm4m~Be8m4q)$%&FGK{-%BhoIJnpG_tapa@J%<8vz1@jg^C$Ki zQUx5hZJ|A_%`b{d<&U3`z`Q`xCu32oCac5yiNDR2J)5%|u8i3`32VV@-q0Evt)Ou} zaA*e|+CS;^d^kN{U8bb4l?^T?gKaF2ukYiQZYphs_n&Ihz&>xYDt36EPC~|%q`5nU zUW1JhJF{ChS*@a?0`9HK=>)TW=nPEtadnx!kAaZlel5=Zxl#y>phUBY*ExADOG6)~ zhYs=0`hXDPykS_(u=5!sIXLg!AW@W8A%nS)!8=dd`A>cK9S#ZO5!NHjN7zp=AYsA& z?Su^pBf3>|Dppa#l3GBo81u!9ISckA3`$s(FezbE!Kl+OV9a{RV^5D^EK8VHuq}5E zGUjFMJH6kG3+Si!W^61NnXRIPofSjhK$x1a^}Mo*GWOnJEY6r*W(NtYGiE=K5_-b& z>ilb!5GKL=(m6<6U@inut0qEiop1=|6vQovV>ltaW*7aK{Gxx3{Ii4@{*T``HZKYx zWM5AUTEP=RcL#(N9`cZ>B#$0eD>lqp1YU9QCRa@}dGvP90@Zcr@KXz>E???k3bH zHa)@bIXm3nFTblV-&4;D$>fqcDy5tckr&MLk>z(jYIewpOeD8IZbnH>M^lpFpHg0o zPoGng(-EhRs&#a#*3tf@Gm-Vbxm<^=qpzQ76~#AtB$|RD1zmTb+#ncl?oepzvmy|fk&+c?iJS~b|!#>b^hQEC$s)nasHJs>UyJ;XZ+k1orlj!pt zDpxz0MbpO#_S0RnD?*9v%pxo*WHu`$DkE4iQPOA8_K}bd!1-jjg7Q23ehcT}eJ;D& z58}vxy3J~z%{KEkF>;&zF&qQ%=b9|FO3K=7|97Z!ZVlDPyv_Ew8n{n>-*@nSfcNA` z4zq707!iQ&m;cAIaUit>s@~@Ccj9++s<;Pbb4NFEcE_H4iGU#4kn#NiL&RMLq) zHe!j+LgIpJ!5kb3|F@)%nG^JFY&sC}=8aq-fI)&{CrS#0ke*1i zyRfRomS>K|I;yjTEK_U13_n39<(LCz=G;xlH562$dFQ#v-*+p=957R^f1~V-^!F{7 zaq4JU4=%?KopBs5$?HAI?4MO`hZ33|KR*!bsLm5UA{!_WmcbC)en@fx^dBiDolxzZQ9W9st(%=8#{;yv7)1FF7f9J`c zz4kZcIX``h6~ZfLS5~edZS+hbh!Qk2;@Sx*u!lVqWKS%j94IsLWp8p?Pa&33wS}(e z8)8%2N98yvNlbj(NF}8OC2&i3^Z0laj`hu4cKh5eauO-Thf^ekVpq#X3ZYg_lne?X zY}f)CcPwR=j}$;n1znX>B8FrYtyDlFUaST-tOC+)aSer%O;ZN5D~2GAZUGI)Sqko< z0ty*ar7)aNYT@Oi*J(xB0pVLl1TS_@6rIqu)oHYp!b0lAFjz_3Nb+)+H*6QIq)0W5 zGi_#Nw4aBX;b9dHl-q$_t5smuI#5elyPp(bfhZ=K6=blbyXh9gPO4x5gtoeP9uz|* zgyXha8%iG6u`8b<2nz~lf?X@w--UTZFN*i@nk}25Nfo$tt8H5yN2SkZ3oBw6EOQnR zk~Kg@&kLkc{nxl6Y%&5_2XyG`3^QrLo;Lw0HA0t}EbN`pp1HGX*;@q>gfgQW z31d}oR+o@0gy4j^P1r+W3$^QYtywv3bAq0KZENYnI|<}4Ir%g~=>%2OK# zBzp}9$g#dYVA14xDg3Xpt6;<99o$C{C!A-mU4MPr-=){LO&29O6SXv3DsC5NPnE2i z%{BQ9o+h}0%BGI0lj`k@ar_Vhip!;;0CdY zx?%{GFb3N#QwtZA!C({p$CJT;gGR0zUKk-rM!TU|5o~mJu(`r>gQrFXzm0AsEJv7* zupMDM!g_-F82eGh#M=}Tem`SG!HP6)#0B((B?(h1wtNv=MOlcLK3_5DGiGWP6^vT2 z>XD|377RO+F{pu-2zSFX5a^EqTYmW(j8!ZM!Dc(LP#7cU0EC zI6K^@Zo)g1%ULBXKSO;gcb{|FW=}~;El=yQ#3xs3CHunfBG z5z1j8#o4XQyV(^E+c+}9ln1J!k|0AE{J-ydGOW#`})U2I@wXZb%K&k*;KmwKcnTn|IX}rOdpjZZH zLc8cvV6sJj_c*H28qkuneOB5=j((;x5!6jad5s3b2m+^sj>sa0QBbjPit{e}oKObE~W?BG-gp|k|Z?4V%z97e;mVL)aF=Ncq48*l|v z3J<3X{NmczKY_1#)ekbPq2Pb`bv7i*sX^LHNIL~0AyfP;&l1kjOUUU&ZXKN;2`LnL znr8{A1ao~ZPf$?_DFKO-kfxW)_vHyq1F@8p#832(n{nAD_pJ2C5-?L<7*xtRW$Wmi zt)m>v`^edmq>h&3$Cl%NQ+_WcH$Cb2uzyPVy-zRSKWoPGgq%A1!gBo8B1J==U{N4`{Dg5gjZ~C$CxWnP(Z2E_E zopccjF+3&3^((L`h&43M3xX7$4+`NLC6KN(bxIbggsIWfk#*^a<=&*3-)f|%+zd3&R0E67N#BC<2M6G$PF=V*6QEG7QI0*exqMFe9|IvVY8vI3~# zFx34=N@4uKg2fc%a7TyZjWjAz6opU-;l-rH4CF6`Il>_+#N~k)UTRynjH((qR0~Z_ zR1$cxZ7cEz&>2%kVGR{)X%2+YkE4p`gs@Kald6r(>8RALNMuq7Xo!Z-s>UQGkam9O ziemhI0Tl1#pcu9u))GTM;%hN#~^816Sgloz56y#t#85mM$4WU!d9q(u&_NAs?v*^022V8QTFV zQ9=fC;YHc4sdzSzW{QXt98o@Vu+G9hIZ$GQV!0EEaZo4mxcK`|w*M7~kvSAhHH>61 zo9Zrhc2~-F5MC5*)gXO3AGl){VN=1`%rj$YcXVCZZq?tj<%^DTw@)~Xsi#`DFMP;9(RVi?r8wapk1 zKns2uyw;$+tq;!IYJ~vG`$Dj(o7%U$Hp1rqvXep~h`CY-{k^2M_Z_?kd00(r$|PR< zn;OdHVOO#NWMMiWbU7X;SI-kRM0Mj1R#7ElLaMTnIR3n3H4q!Cd7$8BQ;6LrnyZvj zBY_zkTw${*5XP+>R6Lz$+)7#nk@YxBundw#7sz0|Cv) zgmD?`7R<}ow_sq#!bcRkNP-CoCp2conECpdj9=}|B~_GW2e%k&A4viITzUu32_|=| z=p5=GkwMhT9Z8T3i$8~2LQjP75Wz9Mas;S@i!~G1tfK#fzG^~P5yMmB5mrf9eZl1k zdCGSPFiY5L6~z=!qHZ2iN9U>(&JLx9LjB966w*B5rp^=66IZ$kkEWMrT3A1)#H7RN zU1z)#qTPgS9i57Glnd+k$vXNeB(Kl8u)hDaImzxv)Z@Z3{Nu{^Pb}YmVYwc~`%($$ zv&(tUE8oAM{7qk3{+6#P*ZmLWHeX(jUpZqBIL{Nlp+1rH~!`;UbyoY=hNs4S5btJnX^y{8z*oehLR{sX`&4;>}Y`; zN`MT!?@9u#s9t9ev0FxOpyil)2{B8!X)}d>x;a<~p`kbLP21sX!fxP5iK6ZhYQ!`X z!-V8A>=5EZuhE^*#)#pLDrQWsmsyLD)=!ja05jcG62pNhJ}r4rDQDO@-W!D}yNz#cbrUN-OQ8 zWSD=RZnJ>si)N?wKpV54vX#~?q^>CDa9(!e2!PkRdSRh7ZJeF*Q?nL<;J})RuD`L& z1d7V1gbY^DRX?9qLlDKWfH9fX5gRJhMww3pXcMc~nyQ67f4C}3ZZoN>C{gh10G|LL zIfOq9l?Xj=c)o;GxQby`Fw8-PIje1(!;56XNi~Sh4!|@4J4@136wV1HFiSg%2le#*toU(1C`nA;vgu2xNaF?^1s{r z|FVU+Y{Mx4g#^i`(SjJ}B*kq2lH$LAGPplRTyvaRjESD^Qh*W}179#FSlOvTTH8R7 zR{ihV)xQlELb<#%3+^uLwq^@eA`oUFEtxfRZSwyS7Sim0YYYOx|Dy_%!u^kGGXBq8 zX5M+gkv^aC9QMrzY+5MMwG`Uc!=6y}5y&v=Wwvyd6uqOUo`GV&so!tpZ1zl3 z>3&XU2bm16@bMLLa;@djm2dot-M=6VM_7(99b>zK@fhm~=A$eLo*N`gsMzogj1>hl zzLGE`W66Rk8CxFm+~D&Va}xF}7?iLmVN%AX1*0-nrEw?0uCR)J3SnEpxMUTb-e+D} zML9@@YTCGfe#YZgVilc90sTbh2C4s>1emosY9=&DMzOi4iXKfZS#%~%0;UYYA$VK| zP%1~TGWw;Q;@a0gp|53RaHcBZ%#JNemd;xdQYf>8b9urTDV$R}(GmNQX*iXvqpQbS zSU;EYOAeTsdFrSY*26klZc|jkLoTep%UlZUsfOZSb9q7BdnUuRRL=Q;;{z_NmnsUf zjvn?@SpVp9xfa$>KTltPRQ~z28OioX{d49tPe@f1hds&qUt9jBuP>+HP%e8_IsT93 zdgKYG7~$_O$8RpjKTuA8WJdFZ2jnGZPx-sc`lSya?EmUN98Ev)H@|bQ-~FP`TKjLS z*HO}_tTUrix1Lc_2=Dp@_pn#Q5K7^Nrk*D}uQPbX40$IcO%Rg+>~a62^=ViJ%}R2ebac0BaaJkTR=!uvlVebEiSgL}Qjv zv4b`h!Q;6@yKa~ZY_eNK6Xpj8W%sGJkj52f35O~nltQ^ogJ<$UEo>uc%t8?PHWMFT zR+2ajn2`k0Ix!T=A@?Vi$Lab4@GqYs0;qP~X{Mc}np%$`7uw^tJ5vOAjVwYX zapH$#vy!G*SrDwI01mANUTDgo14;r$$-yClTRH(u93Df#F-#0yIV4qaJ;SyI1u!Ut zt%AA)HPO{a%oc8_vIz3XU@v*<9|9^sGS}N^KdbF&1_oQVv5}h2u>N@oKV2WNA;A#W~_XB}AtNuMdCsJ!fMY{7kyB=mPMJerc zvjQ`)N-kUfzV73M>esqe-BjH0xWcv?QdE(cipK;BVoc)1-(_SOe_N|c5mZyyIbpp; zkWf^4kCT@lf`EfkhG z6k{xNq*tS%MigM=D?A9CC4!A4kT5MOw^Krz#*eOvJ=qxxUXbcm<_EU1&;o=9Qag>n zz9rCt#;CO@fTB64f}KY#ZgioqyydOkyzmO#BI;_=Q7_gI;0tW9&d0dC4QivpB?DGtUd=#1MSoQ;i+jQL5tw{F;4dI5FEz>!xo(ztt3pz*6La<9%L)(-pq(pLpJ6 zcVGfM0I*}n6y^xxkZzLGk}wF zo5L$?bV{qGl6c$GuK%&)@*zLrRYO~1M&zf+yH6kP@+Pp5(G-dB*EIkq2XdAtX`ZkoR39kicTXUpfKqSGbvig^d=w%rRb<`!dfaeW_k z)Me>Fqm)VgC)L{M%e*ffy&#o+669hAM}_SmG_1Bb%70E>A&~pFEs@lIEfn zx~F{r$x^}eqs5I?A5Bg}&;%D5T{(-e`4^!@L*&h+<_!&9l^nhsce^UG9t{$<6x##l zXz9+Ggrqc+DJck!(6|Y;JP)0h*Ly7N2g6*m*p)`5yT6m`OA&g(J!1d(XAGYif*pnKA zfg80Z^Go2+J&J1lGq-|OxOmt>4QG_MW!dFe{*OHu#;Y>On04Z}goHft6q!{K@=OGh zt#P~!qFVgkgZl_v2k?|^{1D0*WP=@~RtbeBvZQ|Yr)oLma&736=B3@lse(hFKMUje z#Y`h_#!?Z3)wtRJ3x4|j_~!mBh+({fx0X|)n~{Q28G%=y1dnCS*CyInVYWO zfY&06*8)`6=II~$W$}#<_+VgVzVQJMs;Dmu^A}Y0&f?P^V}i?HGEe(UAq>w7<)YnJ zPjiP_h%oxeZV&*Uqvq~vtKGYu;~O1kT~%>3z(5YfGPG!#tj=5(6(98O+ob?AMYB~?ZY9;5j~BZr8+WcA?@;{?pl!GbwBp^izQAiZ z@UTHqadgKN4l_poavqNMy(;y(D3HvjD)p!b#7b?f*q8a903XDT&6N6M*i`Y|vi#>Y zTz_?-@uP4W+qtMC_-5h-{~FHf!aY0~80AP>$(WkP56h|XqrFInsPZeq0XVeA$f~$@^cWv_p^1{=j5U;K=6Pcw+)OB3t$%rIsV_Mz zYz}TqCPWL+r8SI?!K%_d)$0fH6W0tATd!05PkIw>n?UBzY11$qf7`YXl$42pe8SHk zZ6EyO_x@npM&VT#$qPj`&0DW>&+%8-B}d8&8i6G%V3mO7M-3=o07YCOr0w>%F2X`%@V5KYSZ2blBngm7m%w0#?M_~`CQ?wN^;TC zmilQZ7M)(FC%TB45x|&3NWL`)g@0156l*>nE)SJH?`A@Sjxs*U&7ZZye*P7<0b>w) zhlezn7jre}&wi}fs#O1y=2BZJG?Fm~jvh)@-&@`corNYc7)#Kck~|UtN6JK*U}zVF z)hKDCkg5W0J&j*q5EDn}6F^oJMII{Ujim7&I>=fIy5Y}cCGSeCtniV5KE`xqtXQ#_ zaYxmMbc$JNvSL%qARNVjWv6U$aR3KexuyzYLblD0Jubo|-}XWRG)O!8m&u*-sYBfj zfy9L@vq=&yMeh235S$j;zEQbEUnh4$83< z`%9&W8MUacLLHnb`C9pNiD&Bs^zHR*9bJ+@E{`E&<%LEx|J*&*iVCHE_EdVu3glHO z7mMzHDRQP=loSq6V^RE487|jRFjhk>5HzxarByoV9HL=C5kwEiUu}?Gkt4nV6H4a@ z_+hf0IQ4t+5OE4JtKyJZ=5>%6kpMpnL$ov6xFPaT=U)7@Mm7g(p7-DQSA2Tg$*<|4 ze@&&~R<`V+rm@mg38a~D8E74?J%;=DzsvF9W5Q~j{V&|Af}1_LOM8?UBCKq{#9(?- zT3)@E9|mczZc67lS$bj~8cj(*)~%2gn^)L=nOMmglLo)EwI%4|eH(%G6XFV*0Q&uU z?%jJ(S|MD#Mwv$cLwQqNH}mP;X;v31q^V%1ar?{IA6PdbjT~p)8A>ebi<=QQi^nU8 za_2RqcbJHjtzjPf0;t&Yw! z^PgHv9|T>_=7VM|Tb1gWZ8BMcaX@)ChTCYQ(qHI`#%R@f9A|^&7pg5;^fSAT$#|Wj zDcl7-s$4_{H~q|JWj8kOpNz~x49N!j-dJGnD!)D)YR4KQDMbrTKN@w=nz{|0M{XDK z=BE8d#T$P6Jr0qGfh!D`xs4B|INx!;jf4d7K$?4o{-ACE{gn(fR`Y^9CM1KMJaQ1P zDJx)9kspmLjt&PYHh?f$=P>9flWJqdlDk;qkPIDm0dYgKilZ*if|lz8{fjE;G+^bl z4hsEYfLz;Ko@;Zol6iJ4My7T)P104^{v#0YXl{H)<>biqKP6^Q=i6ot{fL0FcJ=EG z@5-0x7soVsx;^mp@#1GjkQ(9lk7mMLSZ&(Jl6T*$A7!iZ7DRFuaH?n6_;^TAF(o~$ zt}Bdhz#AaPSg7!zIVdLQ4xsoMr7hDHpRY7te`Hn~s4EB|M(c*zB!|0Yq)4Zrs~uz7 z-~?9|v|-BOCHx0Fdg5H?9Xe!mYDZOOvy~0;Z}LT>o|rBIe^w^K3Du*6^rR@=B%<@B z&vq+J$+U%gg}d@@7lNnf=1lTz_S#B+o89H z7_t@ME}tGb`KdKMvh=K+6Kzj2G}aMmp2NA;y4^2QHsJw<9gjht(Y#C(ssGwLnj?gm z)|ftsn1DwyAJx-dYA5(YyrJRbx*bhvk^qoF2Wb}=9@s-57ex0HFD%@lih}_^k+2C* z&cy0(cH82B4STZQ6gg=={mP}`g)#~tmIk957o4f)0HhuE8XNH}ut_F4bO-a`N{wgC}y#}yjL7#y! zVPNNPB`A}*Hn8=xJd!BuHj{MFl2PuQYXN9R>wRypp!${}P&FSYcg6F&O@m_7*buFc zQNzU&&==&#HQ68C;IKF97fdgtaB$Bnn$xr)<7Es*tto~Su~V_qOF8j;vT0gM^o`H`J^T5NZ7N7UjWfG0RLJZE=Wad zvK)5EY1{XK9xhgNGS$1svHN7)sO!m(l&N|{O2~uF)oO;umrESEF&CH0XJz6r??chV zT!RlRy22#Fp3#C}FPI(ER1ri8JCQ+;@fap$%G^TwMt0tKo6 zsnAWIboHmRSCh+H85H!cHgbiDsA89hDhHMah(*`j&(G$fD~<8d)91lXY8$`nLs~FT zTO9`NIbBenfkh5xF7XqWDoSOEx5FzC6UTdX-JgVI1(-|nMcLAf0|D*B&q5*M7JD$y zF#8|EZTd>=-MZ2x-}w@7*u8psn)SiwkNu~N@fl#tu_2T58#WU%45!AsA85=!G zWR!2HGn#`MO8!8863{e`@ka=}83sSR+H&6=x;}mNZ}e8X^WdDJN1vbxzh=~tss8Jt z6BpXxYUuj$C-R#ZiWzmj`B^*|-ftBPitTm~IX}+E21;cjO zrkW&Z%}Lxq3B$8H?<{70;!)Olam4ICn>>7k<;@8hX+`(%be&);alBCiJ!l2e;bE9G zQdAL79M8r+WcXJ-)Tg&0o$j1I{B^zc#^@-i_gH8q+R$DTjs?j?8+m*kv8lm=2u(nC ze0%i?3}YEv81OhFo@zjF8K~bI*@Muv9*5G>u}4#v?c(gxqqLO+@mnL(#M>Q~3?yId zD)DLuwKJX-9<&!YEZSb$($6eg$h01tvNf7=*f?wE@Rrg$;jI&bZJ;M199&t$r@uru zgm8Mvv6jFF=~Iyf%DhRkSo>C0p=dHje%EV1nIaCz8p@G%xJ9aQ1@+ne`^Iq03B#&+ z`0rZ$DIvk84s*f>XR7@&|CQra3bt}Wsd&$;du_*$)!KtO)WDWY(XgsBpx$OpvZ%Ic z9*Agba#MQypkWm`19*ufwJXSeLFQyN9I39zXyjs9`6eZ?4PajaV$+}{ieOHnVD*(E zI3Oui>^yJd$BL=|GWynyx?)!yY|TzcZMti>{ZCf{o2FH_{*8ye=I0pH;u(MIw`q}i z?wmwMPv(#B7VY;8zu#nBjv4!R3WtHtl_`5L2tIf0g@|%DfoM*2~3t;k& zUDhWiVE@%8zQkLpgGTz@Z~WMA!cDj?^HG+*Lk$ZCYZ1&yP}zUtn7B4Q zRF`yK7S5}rNm}!k1_lLOm;ef4)lH#z^NFe|Fus=o)f{bSCr8v9JZ<&taOv^kz=Pf{=A3^Kw5yM z)!y+cG@E&=r5w^-_H|iZhcIz{gt=f@BXnbQ>?hnsF&SGTC#4sO{kcX3@Ak4I#^Dl2 zF#fjz2F#^H3=1Sz${-W9uEcN7-@@oU!xlOyU4QK^!fotB(zAHTFq}s!49i7Cd?DbO z!k58Fl+v*#EBdhnXP(NY&Ms5FJA`zz-0qg7E-%L>$n%-PlLPmMyQIhqXw-q{sCT3kJddHZJPksd(WfJTCF7Oz}wYWTYX zx{@T;9(`oCXqb- z1A7ueEKEX*I-!!3?_Ug2gp>r^fGxd>R-6Qd=WIG|m^8v*G(^oL`3e%gT^}hE-y@uP zEEcc2Mx}*3J7+#gXe?bqmE)Iru+zuJZo3`tD|GCxU4zT!8Z0{vJ#FZv``eo8%@37| zFV}xCHPyf-B81ARzivvHvD9I&y!~0z_%_FGH|_s6nfU9~bVc9{9>PdnjnZz$Q+_UCkOpzlR*2RT0{W#*Iw_BW8m7 zVnUQ!wS4xdDc;YOC|v5rGi_f)ziLSbXB2TAfuZTn`B%gLbF!JYPyG=l-_nymGFn~p z4@PAk&5FeD*DvdU;PKCOCUx3R$Sqs6GRciy~4= zJBl^Kg!?457&R@&1pGkAHtFJqe>kO6+i8k~$0Jbs-me|UwtE*0BEyr%R*+p*Wjjc~ zb#)m6ALi@Bg~DsgjMS@BpD>52b7ZtN+3aUtY*WW? zs?sYQRb>Ug=Q>hwatfp62wA#*UT9U{{=Dh;2l9UQu`7=T-{)vD2mEL|YoI)62@vpU zLn#f<53p%F!yA#FvrO4~?!0;Q*WoQ{{f9GUm3>tT_JjJH^S&S4a7ZA0|E|>2us;2m zJl8Va8lL}oUB4;BzgLa#E&e=oA#a)d9EAtXvGGW+`vitfxE;KH+hKDZjyQ3eGAHUh0!0*p)gyhuH6T-#2l zB#?ur(06btYvDP<Y4+gsRNSkpHdF)dQ3OFgtu?hBCuh0p>ZGH^9o~Lq6iYd>3UF*Qq1^-W zCHINl!coM7njV9C)q^6d6p$jU9kd-g5WuqfA?L@6U8A9(eP)dfdkv!yCKbppK*8Mn zsxKy3z&XI0E-a$%1Zm9Q$}bsiLdY_1QkMaGPa6g6n559hH6|IQkAt? z5SRAki2HRLn)1YG=&F{e-hJ<3vR|GkL3yP2XvQRv4+(ykL;qHiQBM~u{kSHULuB4X z2Gay=NT-=Gx28X}inY_Tm`fS*+WY*gt14(a!wUe%vjANk$~?HhW%F2(mNAp$Sqm~X z((EeXm`aiEsbcbrkX}sr1*DPuTK7$+R9!Vliszw6ehW@$h_9UFq}@#P$brFi21c6JV zs2rX4ZXJk)C?jo~l&kp6c7f1XKq;bnn8DD$*;z=`0VD}t-Dk2*ytc?7^bSq?g34jH z7!)dpX~;@WIC8P)PR+3rz~^GcDO!MFyia)U;fwb(A z#KZwN0ZVoa1$irB&V3y8%fU66NO8i$OI;WL9QvJ+gDji=LkC`oZb;q+vCBpW8GTP$ z@J~y&GV&wxW`hx1zZqx>t^iFlLl!U?K>a_L&McFT7W&0kr6KqX{D+>A9IIiY!u7jDK-hX7K zzRq_8OehSz&g=%RXj+*NRY@QC`0Z;3_w}Lhu!i0ZP#<0dKc0dOp7}a6Zg$;U_(8DM zB`I`XDz!J0#6iwGn6-AC<4+O2O(4Y?JcVP!cn-G#svi{MONf`hp|j;S4)FG0CZNll ztF1r<0~Gc*F=dGa*SGd*-i(!@8WQ;sPHDYLFRA}iL5<&nTxHGLKd*mjOItDyJc6&B zaI!Ax{d{u77b7!eIaf|Ek{sbsLML?CPrUoyGb}x)|FIRhl(iiW_wN9`+1KJ1nO@>; z8<*+w!rPB2_Z0hwUfH#oGvGId(A$#Bv(E&qKd^mIxy9iLAYMC zn;`I`Sp;q-sh`p%(?o^mhrS@74xB)l*D}t2Gv-!Zlz2s=QB5AzQnf3xlsOK8|IwLME)MB$2(>K!bfrHigX2>PYBY zZ~A=yBKZ(&nM+>D)22UHWo1~IHgxInV~s`Ccy7{ssZ&|ZlmYnbe0Lpg7piG#n$M25?o*Ct(zWmN{PWW-Nx;QjgcRka3 z?kV^#kO{hNslu0IPWXqb^VD_ix>A*&7lRuibUSePS>NQ`-*1ixb6fBWYMiT=VD0Ha z%`O>da<1~KY=>qiVm>&B{6E$HyW5kB_qYwSRDQ!1;BHaZ{5|d^ORrKXY*$N zuin-BW>F7++k|0lLvtH4SUTQNrdB!+xqSDR=7#oW>MuJzDhae zeq!_c3OTrR4D1)RBl;PPrnKF)bJ)xoycGIT_tJOKea72*85}POt zGk6pg??Z@%QO}@E`nbqDik!KfWdQr0m?87m#^369*Q61oz3KfzZu+!k7|*Su$6-Cm z%J}z%E|PEEC+I4i?W<+-&_?6dlX13u=#PoJXU072L~+B;-0DLa#}sn3OwL4#q7$e-jk+`}6T3Co2jzzjr3XOwTj(vD3*M?hi7HG)Q#whETGt}F8rTLrG{ zkT%YGNl^Kw+l(&lFC1ki_|A}Wqx9KRv?OGPRyRd0t4{2;b*Dc)ifc4pNOT!MTfuE7 zK1)EJL;mHwD|XW`FL-0oS%BYgtSztBijn=Y&{$XS)7yaJ-<0OEsC_xpZ%q{_RrtSi zd|s=6nI%;Y@L^9B8?@z!K68#F6lohCwyd#-pzF)`Dg=Ie9#jok^pZ|O{>1KKutbq( ztEUnEz7aqX6qP;hSEmDf>DW1MbjdpBia*c+|L-FLGleIU;ZW&s+@tsA`fPdH zss{kXVaiI`R9EJ*{1_8P`qVqJ5%$fy-n8QI^0}zt+y|I77mHy7IIw7%3d~p5W@Vc~ zepm;aw{-~JZ8?q!8X>)DgE*M;E=A!Q(EBH~v-BWSp;yoTt+xY$zd(Lgn15TAEcvWB z9&f7otm!!*<1JMpKG(9yD~L7QGxdrum9sKWUiQir)nKU1=>yvua)hwOWCp4amrubP zdk*?Jfs>Zja4~NUtK?Yq{)wBwfAh2aGp(5k<+Lw8NvGhW;@KAs%sFKNq4gH}@D;L& zTQGV3#OhOL|AB@XYyVYijzGMv z%28P8WJ|mIGrRsMDhLo0P?@QG3li2_?681+{gmuF?s9^}|AhZX<^BNJ=D{wz&idac)2AvNcI&XbWvhYt*zm%BH(INgN-?|3>A1W#y zg-V20bapuO)X1O47c7hVj2ZHs?}%>ra!73AsVY-(>Qw6ei}`DRE-&{r(y*YnO>aud z{}s)REr_Ih9OF|A+~795zvc^+%dLR!)TsT_rP}F5zr8INT3t^~XqBH2&E7PMe4V&# zOqvHIVVyDLS`Hy1q%lKnu0VVn%|~OMM>-Sd+Vwal@hW~yv{{* z)LEwutW2}4p{=1I>^PxIG~!Di-PA4_7;+&P#bwzhY+Q09TRq5r$zqM@ZiiE%4hE4d zO`m(j@kj=u!_Tr~xrmdvmh$V#Ldr6F(mdP$g3}mmkjK)|gI$4?9qmJhW#@EAc@wz! z{7L)OA?KpuH}t|D8iIl3)!m0geoL*$XwvBRJ*rc!F17*jdQ`S<`89TJ#^SKnKpq>66VcFMfr~j)3P*;01xbMuh z|0-dEJN+neT6}V3iUqXfLE9mBLt2r-+~X*2LZEE+bJxw8e|ZI-q3k_AGvmQ0vZhUD zBs9X0wXAspSCtYVw-q8T-Q<(q9=V9ogOLBc+;ZB1FJ{T(#yL{Ut4ZadNjar{JwhnyC`r;Q z`-rH;F=p*I`QOH1TB!-%7qpOIfL&MBpTzy1uG7&*>@qs&HAak{gIE~f6>;P0@{NWq z*}(V*9oGHG2KrKy`~XJN=|Dl4pm4B9lg@aa*YZ0iyC*3Y2FM&{&SeTeN_sxyG?Xx-V(<2Q4Fq#AQSQEFrGera!iZ0LsxR;*u%H*9zD+% zD7&L-=yZOX^Q>i0lth`QV^0*NdK3ON(?-I+rdfq7sGgv&0R(nrFRHB8mLWi3LZUv%*6rn*5r`fQMRb*U%ro@3;cV^ zEy3M_OXJt#uuE(T#_7%?fOOoD)=jT$*$9@zy zQTHV{dEx3c=Xp(qEV$9s&7rVEn?YB$FB#TbJb_!FF39GEHk1^bS+DOxw>Fw9Xrt-R z28C+~gMi0qxe>VanK^ZdwrfGqGqB6kx(03!{8XB_jM;Kbx-3v_H9#B0RFyV02rm7l z>BMi-SSys~XVHO2XRRQG?xBi-E;kTe#)MpHT{f@fZW}f)d)6F33TVzSyT`fPMqXfL zCX3nh8b!#6FOM*#;R{7<`2x|b=3YJ>X5#^$Jj-az>2h+I)rjh3N>?I#%JxIF2}Ewy zyr`Kdr^?6@6MRL6l_-OcA)F1HXxg4xBfVD#1u^e1Af=}2rsUibW@B{Zf41(>UXrZS zunfo-&RWQ;dTx1lV{Tb;=WcF2k=;B744cy4+jsCVtJhvft5v>cizu!04z2e!s zli~v!Ga5ma-zUU{ge56S~&jFz)EZ_ipO7?LD}tlg-xnM zBAt8Mf4@RmD-hf43ui=jB4a63j`85ZM;=N?Fjcm#dA|>>K^jNGtWA)(u3vbEQ?e4I zRWTN1P2Srd-CBursLcN2?`0r#zZZUltJ2NKrT45PtXKRo8`bnHc4soOC8kf@@Mtx#9Q`<7`uDG z+vQcgWv&P&R0O7;nsx}a(fmk`<(hVva;hjjN!fO|o@sh&Gtc?n_ti$2B$I{zrF$eA z$JYXY4r^4$&MRJT3*}?pf?(XJ|MOU#D^PE*&SJoTlb`m)RJqJ z{843nqUhu%4iC^(VPA$LQ=g!9EbZtB*Lwa~40Nt83~VC44zv77{{NkWPRa+?n5*BR zz3vmc??>dhp>T?bD100pZfq^7vDj4l6Z>#@B;KnfZOEJ0P+|;DB=5Ujf2MBGgHwM# zc*Ag3Mtu$usex#Lbtb3Ol3mYs!S-829d4Tl`t<=vgLFm3jxj4pnw`58H@%*BdU_~W zT60#Te?73PjbxpHIu-LKRI5N!W%#CniYJFfFP`2z3iSi=Ih-G2#HAd%HijRTVOs!S zM3RL}Px_F(6hTa;L<}zG+xb!KE4(#MP*uULIP3{4Z{9rs&?4?%R9YjiB5qmDxd! zL+3G=?3yC{^3)OOm}gLNyN?`khIH6iz&eT1kMcdPR|Y{xl#n)9W(|Lp5rjFOacEw^i%FGuI`2;6ZgrUQzs@w#zil3nv3cQOs8#OYcKR>#@a;9B_P zG%AwPH6V1uop9ggz^&bjXuB;*wMo@_U!*bqBysc=gkb%*KO35($Xd*??{)X6U(RSv zYqt&&8&)`fBakIZYrQD(-J5oFqYW%#ic*Zq&dDPJN_uMl4lLhEtKa9=bQ%2ye=QW#bHVM^=`20I`D4hpj5hr3RRf zs^QcaU4;6je@Wh^rU89oR8pvdCH`gyy_*CHRl9X0H#RR>mlkdwD=QVfw+IjM`SCRg zYGo{pzEtI1x8_SXgHQ(IU@aR}NxiHEbZ%>Ti`6bP8IoK&IzT?pJ}7*tod|Q!zQdmW zeg=z&HiH*cg=$<>1=<*dkIRj3bA!V?Qw?wc^xJcIt=RVyh;9!M=1kt~2P=X~uU4E7 zKTX$CdtHYeCS=zk^K8EbYb7}mHr%AdPcIe^nNs+Wtlamg|@2iV@m-ar>2wM zE18Fua850FXvjVUz{}GYzv=g-f;eB5Y0hME)xpmTYQgz7QMpl?$#FBM_JB#V+8zR9 zJ+h!kH#(VvcxWcM!(93xy}+bb&i-i=tRnrdWvPE8W;M`^Q&GXYwCxyGu^P{=l+8Yf z=9ttRr5IR*?WURlvhQ)I(}C&&(w{P%cH$Gu`0Qq-g;aT0Mbyn4W!L0{$UE0(l6x5Pv6eKC{f z9Snl!o+`|_T078JAAbjJX+>LSUrCSOW6Pb!pp-WHe{ws#-+pihJl%5>ZaDML93w|0 z_BSvPvSN6&mH)(p9%syAAgoH|3*ELQ`)z`kgjXgNWN!AG`Kxoyni7$Y_^DT4Q*8$g z38Vwj2JRWALz!x5ZJLd7?S{}KLB_i%O?=`ix57ba=+(XS6RJK^8s0SK1vrO5Y~Gid zt&9m1R9p82kDC12{qFG^*7+Go^S6aN*{fYpW9XIM1#G0*Qx8oU(psbfdGlf$^V#$V*5MK-} zbW)R&5v{bpShi;*9xvDkPY2(U#;$g!$=FTo%XL=*Kg2(!%@f|?`!fWpP~y;>NgnE| zMJuuL@>r-?KwYYd1yZiz0c~(BmlAtosY9vDiC;`a`BwX;V*~3>J+(GI?A};t9Qt?A zkx1OSgBp+wjK}?|_Ai`uEYITa_+L;o9=Q^H{6DE*93}Wxj;$*Z*nU z7`BAACl)TUF~k{+fj1@%)nqc>V~ZV|jaTZU+9f;Uh%R)ZKEl4j@b60>$u&-jugSx|*xm3&3TgA+rnv5#=aUvzPBUo{aS^A9{f^VLWmDw#A zmZMk+jd}Zi%sKw&yH@5agMYQ&A~o%2QHgv~=!<+$fDu;`j$z%;1ed<43&cAGo)59r zkVIc0NYPS&dsJJaG9P9DJ$ZrhogZU3izMH~RXQVfMkqIBoW&n;7-P^_7pbmX)ACAjULUY57H8qGphsTq@Er}7S1Mz$DA zuSOC&I`yR5-*U@xbQZ$d*1eMgnks~4ZtCtrTxE6%vSjLF;cG?o2rIm81=`ZDF&QNF zhv|HJwACr)v_g4=TgtHR!e#o0efyRqy4?YuZD(`i#|49Hf>bdcUJ#GUv?I#&r*!6m z?@zJqX5)w-p>n4s-&LZ^Y!8MwPO^DVzOyBmsHW5S8u0p=>TGfB{`JO}$^Nivt8tv; z&h#KAIqT^l{B-dW_x{dXRJyzMl8kfi@8l}*0*AHqU1WKZ_UuQMRT@3c%I|p<<%Pf8 zk}b*E-^;K>y)m%(6Q(huPZDQK5u|nw#kUpj50pmqNP`DZeqTZCa0EZ0;xF*W-u+q$ z%K{WVbcSLctU@AGC=!Mo-Y%ezb<~}QhLLU%qbr*~;_^4)o{-2M$^Ctfmf=cRKOn}S zqzaOY)K(-6bNf-l+qQJ|z!*DZ1-l`CgsiarZJ8C8@{fZ&Q@Ys0O&~((Z8ZuA$gI_* z=4dM&a5>%kVI5$r#FaDJ5Sq#&P}MR=uQRwS?yl;SnfQkjt_i*&s+enWQLQD;;`2QV zb-GKVw2?G~)@{0-;i5sDojb8HnN*hT#in3HXO1OU2H$Gj_$v);lF9=0JgQv{JsDw8 z?~#BWsf5&c``&TB#pUf)D&h)!4r=hAkw4S2D9%q`j7q-==83Tc$}raDb5n~-6-hP? zXjWYmZrD6-HdJUX5mW)%MEwrY0P#6m_;F4=_IS)7=X!M#tC#)uvZfntT}D4S_wS1x z+ooxZGE~!(WI#zJz1NJ~^gg*Zyz1{TPkZWg-fX>QRWEDxHCH`&x(snV6OTnNpJo(q zcH&%AZFP!Jw7-FXsp$1$o9%ABE0yvflj%e6hJIDI1V@F+;Loz611Xaf>@kN%f6YSX z=hLI+Mc_ucS}+CtodmG+ValPJ^Q+QZeFsl2;J}FP{M)g%eePl&0n5@OktS3Fy6h%! zvK-Fl?~jzIw{u$SpnanKE2WprH_6~y>ImS~51sHw8H_eHr_Fg=pRsT-#nT*|>%{X` zS#tobab8gQD@w%_4^aFiMA7oYzep1>6Qhq;d4oO=;Eh!2V;~lrf1c2O(&Bu_;DunU55&py{@3>dtm@7I=YNece{aUGXFp_;#F#5`oO>tdZE2&$PL9xMNUCfoFYvrn z9}oXSp+ql%cm6UPAQ__ltay3X3llQc-Ii-_^02GwhPOY-5I);$0t0Wo|5m{{tsm%-;_ORk& znRJzU>fY8XCT4mp+#5g7_oue`E%pS3O;Gr{`reKrVUr%qjuOQzz~X}xVc*+3KdleD zmk*Tp>kr4CE9;C;93APIQKh9SOHCy*FLjfI`>Bhw_&t@UqlpYs3~}Z%Wd@Tj?Q65y z)J3ca!`3(hTtGH+qHguTd1{#<}(-c}9VQ)RN zTOAPwZ^szwo~JC`UvkCK^JzRg$l{(rEqUC{|}zQP(Sr?Y((F4pDB~jgi|M z(PhgW2T&0@(9WXm(~s#!{UV{$eu`g%618j3i^AAbv_zfo6Q1ExhdgHrdUaLgN^(SY z4X(nFYxu&Ym~~{uH6&RNpyOwW-B%C!i$aGzR6oxuCXHH>#FGMQmelDX%p6jA)NDGSAFob>hw-M zS$c9lW+B!f@aAOhpI8*;n4O#9mK9|MTW#1RE^TC=8KI%WbBW3daX5$2(W?gM0!vTclG8))cq}RE~%XO&uU~LX3zEkKW%IU|QB)o3PF|1Y`Gk z2(rpBZ&DD05_&N7 z%`wcB?!Oza7ei-E-WoVPv|;i}$<&D26q8yHHtGb_G?E2m-)sUiB&}LPW4`}YBj19} zOfYyD*mj|EW`@W_ zy@p0UH-)=|MYgL$fO5dJpUiD`?^rHcPCk@ZX((+J?L%(9m>>VDashS`WO9C}7*=ks zCVW12zDXX~2#3hTq+Z)tSp&JLKyY`8OYaY(d~mq&`e<{YYb$-wrd(Kg6BFPPDaa1~ zanwhoy3RBmV4_6&FobmB7_SD$iw?KPk1-YH$MedhrczKtGr(%8gr#b$*&zp`R_8~> zi}vpliYaRwu=<4U;&5kmOFv3v@5B_bClaC|^H(~u{n!`d*aSz`w8p}Ra=Esdg} zH(>7l7%VCvl+2^%AP}%HV;3)sl>;N+T#Wn-5B|;y$Z&Blsbov0x$W_J*ZBIaiJ3hX zv`MH4kj9El)93?*w-s*TEfb_&q8=mh1B!B3Yj*wn-z-0Oco#yHdBbt z-#p8yN{m#It8zLS9bdyc-%fmmVbZ#pw?4(6Ke!L>F@KCxbBrue@7dhTUj{txX*s@q zfAryRGxVFLV0qJUwGiPN^T?)A(r~_%-nV(2?;w zZ*XC^O{r9lmCa8I-65^<1N}nUY5y+PUWuu>3ak##O}<4-Gp(@eieB8d_?lf~bI4-Xy}Y`H1Wv|9I|ffHgLtE(2SRh8;V)v51hg)~{Y z=)>$2!>=&rZ5sP^$4Q#QvwYV0&E?w72bkWaUEaViD8q`*Q$_iw)c{>}3DW9!p`lWQ z3-L5F@@4wGM6?O%FgRUdGf!nri}r7-o?y*Z7xBQ=YQ99fGfK)i*Qg#Q`}ljB96(31 z@G;^E3DOQTQ3!ni_JTv=7*8bsSKnT=zc?rf#qn%!#@VA_`;>?rbUK!gVlv7RlSdn( zE+mIQUJ)wJ>9|d5uT>=Sb#m0=XaK7di<$_g)v;|oM*c(OM~Dg6?sO@h-L=)TZYGcu z(|0~`&v{v!WI4E)GNu@_NeP>|dDF4khQvU}CRuj9)tMZ3v;y~m(kGKHbwK8e7E=fN z(J-C;GEQk8Z5B~_x@Xxroyk+Ao`&POdkrj0EDP#Bm1~mB&ngL?*ybz22nNfi=>Er@ zVM$gtIWd5qKsB4?pJmu1dKX*h<}LAMl1eArGDmfo2&CRbIoK5dg3oA@x`{Szh%P<; zM0?k#ay7SFTemR6z4CIWsJO#ipC$g0QPk;XNA~$pqmtN3D5$80>4Zq zj@|8Y#U10@3{>KcCQYycc@mry7AtyxDv9<1L^4JJ4|lzsc13{=#^^uvFeR>88)`>C zjaq5IEMNVK8Vn)}M23K7WiG}DdmUr-0o&@hX>DT@Re7L1LLOSLQ9dk6@JqWlP3U9b zprXET4%~Ewpkml}5WC{m=e=J0)(6 z_3e)tTT^|QAVNH+$wZ{{{ozky#(w+cHA<7|TC5<=xdZMgQ#`yeLfk!<0ohAxiq8=@ zHxak&U?be2uesqPzO}+dw{Xp?$MZwXWR2oxX3nYb-g)5d(cY57+sgaqb@lhoa}Saa z70b^{z;po?U2qbobWQ~zA2a{QH(A=#wr@s~sLmMr9yJ^mnq1-RDv(6@qQAWTPzU6B zLQ8T9>Ejq)p~unxG92N_q;i7DabJ)U_HgT0#oCMq%sXr@1b^P@h&d#d`>f(LZ-{ll z8@GWC6C6cjuLx8jDIJ% z;D+jIkmOKIS3VEB0?;uaTGUkGnB*W&IYcZT=XTntVu}4ifxJaqD&$NLzkv{4GeFEX z86)FFjM41mC@FSYgpvRuF%emnJ5?2brSloe9gouYP;4DGn#tU=S%Z_xwInsVjk zmw&J%PD$uxa{1HPfo5vyZ>?_lUS1R^;4Yx*fB>tehN*K-9A0p&Juj|;O2Ev3l@O2V zy@1cbC|b+&+cG083hMG`8qV}fXzl9Faxb|r0?c|*3ydic$P3J}(`)jI%m*i|YeLPf>||3tM>%?chdQ<67N zWvkPRT=3=jSZL!+O*Ro^xnb&&brJ^(*DApq~9M~63QemFUi9|>Q{7yQX}jjxnIKyHL0wD z>zp^ZU*kwZ;7ia?WN`E%wg_1O8+04&MK-6F51?V;#RCca18-k z+=~(FyB8@QC=%SIxVuYn_aepJU5b}tH~%^Jyk%sJJno&f=ls^33uj9L{R$KR zia4q5b+Liq=~rUJ{e&+gskT=26*$WWw#>OH;ogp06JuaDX+#o6Ux}EUjlurfdn{Ew zq$gC?f>Bxqw8%`l3RMQW03ya(ae&^PTuI2^@V1|u`90m_lHUOm!nCHPUoGV&7bDo` z^(Z6(K6of}ACfr$#`PiT!?+f@HR1C2oP#c~BcK`e-&@!%+BFBjOewtDNS@>h!~Hd6Q_nqU41uRq5%M{V$_ zC!}EmLwE@KT*VQq6UH=wehZTc7^w~Z?9c}IWK+^68ne{G3<^=k%r{xA_m3{jufi%5 zwDOqo!*4M`s>R_76>O7Xtje9VB0b7qI{4|#!yb-5Oz&7SDo0jP|5keyi&4&%ec;q? z#-L}{!Lbd3*lOmaSFg~LbO+BPOO(hSc#q!~cqf%fI>vId7%_*DE3NLyN=;a&Ut&fb z!Nl(v8ZQl99TNG>7+^qpyq9Og%%xsObdL&!SPtE*9xeov@+BUC1wbiMK5jZt`&5gQZT{0YZo$XH_B8SsSj z%IKS%_#{umhV=eePDtU&%4|ycJqe=aRupgix~oxX7EhH&6Ij)sd`ufU7bFB9ahMTc zfwt*>1m=1D9}9r4d{C$6+NDmHKs1f6tb8Ntf~b6OTb69kEX#R6Y+U;ExhF^$G^%2p zh{)L#F$K@ex=3S@i{l>bY`FH6Cu<5OEkYWcXDJmjJS|Vr^#<50wURdm4*$Cj!p)y0 zVkT9WRhjVyJCh{JgW{=+l%MnPF~k=cCran;;~)by%KAGyp;zm{Ws&%cS~xx`Bh=oq zTUfd`??@lyCA|(97<|gd9Zkr?*Df97n^er%20z`T(3M7>C{p@f?M7sq zM>UyKTEo7BfL~_=TiC;`NvjD-c#F{T%w~PC%{wR#q@nx9>o!ObTws(34Q?q zM=SfD1x0*;B-L`}HRHJQQZwxpYUuhakL{|*c-;liPvHqxJB4`}KYcfnZY>=0Bqyl} zyLDuZub#RYgaRORnn;a^rFcTlZv^08Dho%niX`qBu{Zy~C|FLSD6TJk0RMY;ru#UuzcQq%)*-s!*W3Q$fC)eAajJ`J$tf2EW}B>ZlI9?==8QWiu%R3CinZ9gmCza%MpW0_K7ec$RO#KGpTvR=)W^tJ~n_jdBv zNtdAL%Y#>jW2&0fv)$E4uZO~ibOnp6$Jea(v-^*;UWxC(zoT(vL@QBCn#)e+s@MJ| zob#>!9n~#rKF5wJeR3CF-ThP)j`ze@!S5u=@mbu;zZXJFXBNK z#gN~)a67be$dYJ&A?9{4U4omu1eR1((ZBp0(`(L56{To_{SQ4M(Z9*&G_LEN@H!C^=uJ z1j(@#+MpL*RX`nij(&Jun6B6oZ`m^F8*V&O{Y#BH#Oya0V%1=?_&HdzlZSJlU%s}FSylILL zyjLtS@@4h+I+&{rVC%RgLxCslLRHDw7#qG_qprRx|5m_O>khw70r@;53^FzT`Nk+s zR<68kQh5ij!R;yn-a0uj4wida?4~cIwXHft#e$yorv^!xaR2T69KgyPCsv)2m|PU( zMw*L7KUzm6R**>YaNQbN6g!ssCfq)_m)9=xk!{JZ_^PAeZx)1aq9huQ5h-g%`l5lS zMEDqBrPxr88@_a7ESYTPE@kN<>Q`zXhsED~9Zajb8B(s4WNd48rbiZkDVi8rzB$8Z zV}aaqpBJrL%s!1yW3M0HKz0T8mOAvzIdI&yfkKBGKA%fMg?Q!I5D8Pyf@v}7=&+g6 zPdr)1e<=4(tMZ| z(B~6+E*s)OMv*#_THQstA?-3_uqKd{IjD;8;3X^jGl@{3UaQ!eB%Ob_F!nE&hsdq# zZ6Ndh*W?VnpJ7B*d8C4du{~oF&V(HwO&NQYp@nE_culmhLV`b{m5XEKlIR%}<>6Sy zyaNtqgn!wPf4ff-!-hhGpbwp@&_Eb6I)Tf&(S7SN2$Fiq0i{8fQ{A98H&lWb)$Xfb zqX2?kKIjZBCbBb2%A1Y<#AUbzE8KW`+VQaBl8 zH0O7#3F3AzZM-HtxJr-@u)VBZDEaNZJ_L_cZ+I%*8ya3>Kl-=(^7r6mL^KD;b38H<(>S#D7+v3pp75oqRtBR`5Cji*x&A9@4Nry^ZX!4pvP}z!8FQ zpgiLDDkL1q2?BRFE!>tvPn{c?D%yZ&cSx*kYdd7uwIYrr-6yQ`GYj3`LhQ5Ud%}MH zgii1)cz(a#--hmhATW$(y&b03aU zK)P2HKW;=gHtk2Nj32cY8ywX0StW$MjbvXmF&_WY_s3q%Hq9+@?{Ct0QX&QH=!S*m zk-PJ&Uxo39&Ij#V=M|1)+g038$SZGKeMtiHT6oWV?RL9m4XINAY3G7n&=}yZpRxhE zD)C4{0;|S;%Z=*W-wLvXk_yArqbvz1m3<0arQ5`W-JemW`NHnQDcgIE8|{4__aP-I zJ)t7X8c(dZBE?p)oxR#Hj<|Re=)9p#{%>pMxt*dXMK&JgH{Y`^O1kP(&lu^F`m2l4 z2HU$t-Uy966&^m=zAe?|*!B88k9v3lFSio5%PY2ze631~O($LS4)+p6(zvxX$G7rN zJzZopYpg)S`>K*n0>dNVp!!N|hRbZIi!WU5AjX!9I-3!nuB!C@CW545s5Jr2M1_YS zt4j%`lCQQH%R#eNs3G&TLwyK+%N)yz16O>EutG?x_aAD)J?F{oD+T8gGS(*HQEgt>n_eEWyZ2xHe7v@Tu}1@}<+8cSk%~!#iW=VgBH~Yn@-*_UiP7Ga7z4^B zs#ekY+k(uZo~{&y%SXs5(H`t+OC$ccE=HUQX~>c)-DaV-^=&@&C!kvbgA5_3Xun>- z*xz>}!B^<;asM4pnwaQTzxc`ZonhvJs5$F1RB2*ta(qR^k`;T%Fy($LKk$FI86KG|1+-a(?SEQ zpQ&=%wG~^o(}-7tXtL~9#LTp^h&K}~GLSHjky`M(e#9Pa5r)ltZpaKiphEo(p$n)R zX)nJAj3P|nz9aVY+f|vcOKF*5xQVCKy!LPbp^Y3h_pmh?W}lJ8LjL-M^2 z+Kzvn6?t`8n$1l~kE6IloDZL)D`Rc^HY~4QEjWi3xaT`AV%4QvGC9M*OiblroT=Pp zq%EHuKA;3=y?rz1iDhYx&q1D7@$2jo^YdC0U*6bOa{MPV2A8y>7WeD)Sv9+5AW|hC zQGaKl3fcCb)Ch9P{;6&(sJ@CCo7Cs`;4gWZBzYIC76>{{zSV4hR0%XV0V&_dkPcmj z=if{GYAIBP0>8 z&#|^ommhR285n1;75XK6vln?evSBJ2eLT@lETYBP7g zVu4$tr6@3u5HgREF}`~?>~W9rYCNUHpPzn`U+yI=5QERuZrRz%W2hFzyYz2{>hi^_ z4Hfc{@1CFzQsTd&I`_XUL0#)Vj74(c%9 z-xGMi-H3Db4c=muy`|mv5C7(_ZBI>*52mR`#zeD*l=hwHBEueDJq{(~0)SKQCgu+eO1#UHwm1|(+S)5oYz`SFFvcK_tPL1&g# z>E6a8G#F$8v!mzQLdj*Vp2EiR?>+{J&+?$ChzY> zxJ_t@6o_S7+iVzeXBa_9>h;9msbiL7(0T=Fw^It}Jvulf|HR6{b9ScRFgO{`_4od0 z)cC5dDjKegkG^V^hGno8J85bt+dLF{c-?Ch^bf!{yDH^F#(`vnF}zA)tIc^&({wDd z$f|&5x8h=2CW%yN=Lu%8fgl{EPuMCC4t4pyxyvjKvmcCd!0aRA>0lyPR?{X8lT9ts zW(I)&`s7kKMP+Qm^h$TvjSPtJO*@nEBsCi8EH64wr zGghjmgPey^cGI71j2)&(R3m{JSyB3kY+?_=Tx{RA-t*TXkh`%E?vo&ETa}`1*{Qp@#hO zlE2#CG^pXL{fU~F$gSRHJQk5XCDZ%o*OXp?^@#&!7W9samhShWAKz7y4d99YW!2o~ z*XcJ3k+t!p)Z-TC2Mup}#fnwM<8!9oe=jed=VbMsPvCvcWd9u{+Pbl_ajysr?&?ov zHf8D6!i-Ki^n=zAo7TVvND|O_ebN*+{ke?!dYw*bCsQ57eS?+gDx_1DYBz{6i0BCb zgP}15aNVHRlmI|PQgC%@3NZcEqJ9$y6CMEXcfw?mGw`LJ*#|42`j+c_C2*nf{5?Z( zI^QrJf#rKL+sT|kIWsI_>2*F++tR^|^87>bD9XYg<=^KdYyvc2kYWD+-57kWAMWwI zu|i140&ug^L}%%GA{3L1kAoTv;6ehq z&W4KTK_Kt0x5!pQn?`}xKROpe$rm_|cLb7D3A;W_F5AC#rH+q>5xSVVh)lV$iDr3JkFLO#iNs84##dIh-*1kG z1`t~xTU+^KUf}nH+z!a^r1SMTQsivg5XKY~be3pa0RbmnCaX>4<~uJo<3VomCu znJDK=Sm58HqjqV%O$cNOqX`XiEO-6!GXWp3eZ~TxpYXd%thh5>(vl>1nQM{pZ)ida zg4PX5#2fLevs5IEKWj~g5k)meO$nAeCqJ-y33He%JW^b8()YBt_%YkRtS)Hz%YGv- zw+0Q6^GY5a^pN1Bi9>O#KhyvDJjd9wCj0s$y#@q;6|oYnOyLA?L44>?=K4wrLU~`v ztA3)7sKw9UECh!I6*Rqp9hrtcFJhh%s2BeE9KPrGVt4p2Cn;X#g27H*7+etw@+=ZG z@h81O9mNvqs*0a@TN05rzUIPesHS}wdZ(w8R+%_(bzfq3gK&I=f>w|idmhu#j}`He zT;b!g33i7JNP>(A5>i5AkhRYop8f<&l&`WLIl_&g^|m16D*@P&hZ%X_d zd_O($c{BF-ey2%({IfQMs4FlGn@JZNYC;HerVZS}d!+P@O-JJ*r;?=;)CoT#DLpBR zFIG^SPya)rFM3z=zygZIre6rxP#vh!KW>g((LdJzgzoVC9IZq53tXpM*Ct>WF=?5g zZ{`zmh9)K9hDCOKaA2k<;t!iW`H1~o%*4OY#EIUWd-yStCfo_Z*zAfonbTt3!Snh` zNo6EuuKS0FHo6|`#_8>2<)TBeGJ3)t-x$aEwx!dm?KC4=LdtwO=Bz$pM_{VD1l!H} z@Pv&=4oR;QFnxgg(6qm#@`(#y_)`;$c7va2qUYd>e7iT2{eXvO#TxPO&V)=}3Usu! zzRSd~qTikb@P@}w9mL=yGw5RjD3S@8#W(sY|F z`ULP!e~Ku*kt_H_X_O?q2HzOis|Z1Peb=iFtK|GYoPj^WqnbuuYEhnJITE>^13)i5 zeZWyfXU9kq(@xjjTRMYfm3`SiwHA%S232oUray)OW3$qFf^@gI?wIW5zQ2H9tV#gEHuNW zYts#XIA=hfaPj5F#k=*W@M)Ud7#Qd$ZzWZj_I*?~?+I6u=@i_wPsPO7Mq80(!7FnP zEUZySA28Y{m)j%PdKU~}rZ{VX&kmYJ@)(WT$_f^{F++v2h8^Wrl*eYUc%ZPU)wUq<%i8eGo`!C6{ALf zkBnWL8oGaQCVcf!EO46Ndpo-;ef{?yGde%jOx5!ydw&7g1%vf|?YwQ;@I9qCSpOvC zy8p8Urm2YGW1cUC5s6|qaRwNMky&j1V!{&|>Z4;}<(-R?OB=>RZ->Sq;#D-H;66j$ zgs0LZQ1moVm>OH=O9id!Bj@u=%xdlkerwLmB<}V#S;tChxjIr?XoO?sxg}mBpEOZJ zKMA{#EL4-W@o5_f*Z_Ro`|#d#h+-7DI3~)62jN@26%NXmdfb7g<|s|VaCI(3-CT*s zL))Sr4Cr}g8NZ}fSjlQA-L@_9Yc*!Zf66<)?G$`C`_8GH5on!cy%@r>pKPU^T8S7h6SWAT5I2f zIVg+ic?W%Nt|;C$G|YDW4oyO9c{h50&R|F4#Jh&>3&D>JR8{+!LB=~z)>gP7EK>w7 zycv`kg?!bZ*?pC|66v?P@0z6}8pc)c|Csm=M`EN5pM=h%uV5O`0|m=<;<42W+!*g# zmFyGGve}(T8n2$)FHlL!o`PECPD*aGMssoot{|yppD#bm@_j(%xlu(FkQ;l98Dj92 zzrx>m@tb*Ucs@(m_Grz%fc#}`I{g%wr)%ICx`FEN5p|!eEowLeFQg^F`Uv6ZaGMU> zK<~G2{`#C7qv{TO#bar-Q#Qz61+>V{56OeEaeAM+RN+@7<3hh4K!H)wj`0?Z)vH^o%?^1UdfYr4Bo$~*l`>>^c zaA<8N+)5mzt0;E3Rx-j$t)({Zg|k4t5kUaPcXU{?TB;m-XRaq?r%GBrCUN^{IvDb&q`}RlO z*VR|g8)@0EK36|4##TD~6o2K{pATJmIR1+9k`qad8^NNO0!43sVUj+u7xkO`x_%kZ z*!5rgQrWrC7wmJPPb44Wdan=JVD)xo_*tgnC1ST7@v7+63ocVqGBgfjcgtU8gb`O6 zl`mTgf|I&5rMWg&%!9ptZtZjT6aZx(M&2jpc6)|G>_TTPWz35jzx%6A8m%`^pfGY^ z7gd`pmyY8Y?liq)D!g3zWIT1Ywtl8D)>a<+i`?-fJXz_kGGm#YA8P|Eq{;?0cT{wu7DmQYeRQT2jM#N;)#syNnkdrk=oe1QdHd!#RpD~$;ukQOBeGm z_k_K>uzn3cG-#sEngQ7w#?3UvCjCCf#GTDe8AGp>oD~@GJ!K{(84PYjbZ8vfMdihH zSq&R~?aj!%KbkRMT#hwQ=FPf!?idNWuTlIa4X-A zY5?W+e$GQF^K?)HOj!06S0Gbn0s3hz zKXzXewTa+EeaIgFvhr2LNd7J!uOi|ct)UOF7WUkg*>0v!OYA1<1J5jX^wCuL4jGO( z%V3XBSTjCcqEr2jUaOvbRf%{_eRI>HyTmanl#q-$|KhttT8nX$VQflp!qs;%=rjFv zUz{M{D5x{v`62;$o_RKznRwx9q^ft*jfs>Mtj$BJ)+jd0a4UaUw0))d_=9+8OG?&+ zzRy9v>6GNGBiQ2u&Ovxbi{8ks=5e;GB7ZSGfWLV28$)3sOIC4nJ7C`ac79;R0-vBt z2^h?nHayk(Ep~E8B<oziv}EuOk8P9liI!8ssjkG|(y-wSZ(@wlHrO z^sffB;uYJNu2%+{w2#krnT;lamrM%>3T#-<&#Q^Y2Y{R#vRW{9fN4E!nxx!(TxwB) zW0i{pUMV+5qEx$1fc_}^R|pd+hQV$az5`8bEX5EEWvF)EzYRt*^;ip1F#GvP?)vxJ zSGK_dn1XgoP6RJL=baXX*@sU{W_GrC1V2E*fVXU$wH%RVP68(4h=)nIkSE;x~&Nb0zgQZ88K&j-{A5BX2d z6hBlJfq5Xo5ynhK`Uvq%>1(R*ma0t$_4#WLFm#%wyBVseOn8oI{K;XZ7llB~IwPB< z>M;BsT6xY1Ns3majL(jgw*WP~Y&~?!V|*&Zd*ybfEcEL=zrNb(auVw)FyXv5f9R|p z-2ptfXC*lLD^R}DvSBi1Dt7Y3I2y)g%q6~)*%kWd`!MD?++~L)JpOw#uz)@isTZyeiT4&I!2xNwA4g248W>mtzntT{?L`}!lCVW zj3WU{#CHkbc6|HlGQ4O{Ri)02%qnRe+e8O(iFK?;$fivF=W`cvnA z>An80@=w7j5}A;)+Jts!>c;PyrVH|8BvH*SmUHwn3X+Q>aF7ByjO>vj5Gx1^?a!AT z^b$ygij%KeX4B9mBki)Jy zGvhSYUx9{I%3XR0 z=pD)J54IN%DT_!2q2VNyhCJ@*Y}2VeY$TymsB7Jfie3KmWNX-XSjA&}n>M8ZIZoUK zC|vMl6{-I^VN6?K|Il>V)3y4(w1osW;9b*;nVj9#F zcNnTbO@DRl5z!-7V`)r6LgL_1N8mH4b*L%r;er;`Tda#JcUWe7%Rl{89BveWa? z-p$qh&%f``O!IPYDIn6A3o4~wk^vDrODay3AAQgdxF#42P_#c%OvD%#$2ALNEXW=m zRwUSoI~#3(>osMiNb(b(aA_^`==^FZVY@aDcH(x!P`H1WP6z;qt?hb-9r40j7(#`I*i9NUlPn)TZ5#eC!o{+Ou6 z_SU&Ic<{~iRz{+4AlyFiv2yDy$I$7jCPS~#B`Vd1QTfhf8sB>HUw}30fSecK%2{}Xkq-iYRGa`S0 z$sFE_ZkHLxG@y~miM*V{ZmzU?eu40Pta?vhqMKnqa+0Cim{`=*^p&;-%8-h-ox+kC zkBh==x2{ziwg$?AsxlLYjf!wogH7w9jNGD?XoBD1vcyl+_q;G+hM_xyp}eBJaW_;j z{-*BOR>4z)2PgkkonZ;>C#D;LwDd#szD@-Yg>{HnUuJo|Vj61cIc(hflU<-C0pW7AT2tD3#Wo_(dTrRGRGD(%U&iL+= z8ggn&HWy0~P-o1-`ZB9L?&QaKjU|E^G_EX>qdB}$>*hqP3s5d0gGM+2raRk z(4~Ou>~;ikz+_u#Rf~*%Zy{e2G?5RJ?fkj%V~CrO=WzyxA{W{ zUR_c9;MK%n)*VE`{Og>uoYZ$&ijE^=|0;^*{Q>QXeH*#J(Zy%5J{s|#2EUDknN*p_`c#> ze6nm7S!WJyn4Cy1(%{HOpb4}mf&`s{7^N`3Bq=L-bkn`#wSV*BksK#x<0idLpH3dU zD8qqoj{SmY{Qt26^rle~IpAiOT2>GG_}Ur7G|>%_F09oX6=b8|xWg|GND>H@&CV?e{vuC- z#Tc_pAtm6H_4vjXGrQOpbFi`@vy8v?R@T_jf{?2Oj96Zls<5VxC|lpOH(s8S?t+v1 zv)6tLsd_iAx;48XK3ps}*I#0ay9B`AK{ zdwp#GGmfr?bvqm8z41&icEn&*aypQOZk1uCn1Gl!R9O$v6T2V5ra492^r}xooYs?k zq6b`Kkq2EMqSg6i42a;ARqXln6I(yOOJP`5AJGW6rZa+)B z--CTkI#v*vVbG?juD#<%i)`!U_UiTr*t9}SKyf+ST!Z7hJWdsKs(_I|{_HLudgruC z+O*%@9=T&3?5Dq0l(aJ-BJ#RkYd;r&XhmOBl`>+a@v#xThBI}PH`t|rq@Qp;Ndr`? zI*=$1t2qZV)O^M1Z*^8%Va?0n`*Lih@oTRnbzz3hiXl%H7}QE?MV-)>ha~uL&79Nz zjIgVMo@){)7p$rRv!N#J!wf{ray3_eL>;RTi|x^6<%wMAxcT!A4bwdH<^&q`-}?d+ zng-7`4*h4`s~%JdBz%z64z8v?l_Y`Hq?*)K)4>L{qN3h>VhD!qb%JZx2nbJni%hzt z35fJ$EN&U`rRe`75o_p-WqRYGOaR@we2}FvCIAN43>B7C)Mu74b5*_$XF7K%93CWI5WIP>YTv*gGfE|fmdia4Aw(WK zUNdKH>i0X$~c)r)%i%ZhFi#<7(HW8 z8_a{cls$>G-;Vzo+six%H2t1Z&Dnw4Jbwnas<2>$VgQPSa~hzC`YbmvlGBs`O`ZHJ zpO=|B>juv@#5x*L$wLz_pOZRDcXReC4EFrfYnF9#L1lo!>+yVO~YTTb43KPEX%pSAKa-C*yV7=)5gi+ z)j8u91*eYhr)cKvsV3I~uy_MM@JivIk)AB;V3987s-ur8&x$i$1m#I1Rm@{`6)E@Q zOuH6SWAF1K6(|qd6jr{0oi*x6mH7sKr*=ERm+UEU*tOundLq@}{9Z-7p4SHvpC;zV zmmu?ta#kfEW2oC#CmkIPIz}DyVsVyRj^THqqv$td$Foad4)?Sp@TLmh`7jLfCX}vB zc@P_DqGXQYev`A_R5$k-(e{DjtkJ-rnM!6=WIQwx=3>2tyD501MKkLI9a=yct$a5# ztUPf^?n64Zwa@oY)cQAP8WwnV%$V$}AyhS~_lz=)S)K3`uN9!M?8EegJMnJ40!`xT zNRhzXaubiwl^OottpS*Uugzy{RJ@yYpEYBHL&|Q6H zCoP+f_|{ar-P8OroD7J)-MMrv&A_h6%H2a=>Y#pB{=69Ea-q!G`SW`+<;Im6a?||~ z_!ghJH5qzbFc4k#{pnxhOLHjyV3;n5T=c8jp`qfD6nA3;bIx-$eAf|-+q^U7Zq6XP zrpr2#D+D(z8sd^2t6f0)g%}P;W=Bb#_-MUfil@o~>y9~<*YonqM$wE^fI8CRX#N4C ziQsbT-a3=O$Yarflj|g*c_A!48a>+JgGTj4m(=fRSPu5HRGxE~_phn!xW+WS;6N>0#X1)$LECDKD1LJ;L9@V(bR@ z+7S=KMzQ3QbKoK$5@T?01QbAQLVHa;5KmzWe>))Cdfc0w3P^6`KquKS%$@2=&y-RQ zoMwsL|JYGOPeG%pT1W{2NsOd>7M?#*ez9_*TGp!1CW-Z&M{K-b$cF0;R5uLseP3V6KRo0(qP-STRa-W^h< zyEMJ_&E{ZK1vwKcjgKj%*OSfd`j0htaXKooYE1rGnR#>YfH?x9KbR(F1LZsMdU>s9 ziK`eURKG@%cf-FB-zp`PzEtzVW!mM(5Jd3Xdt5T=2(R zg;%E@-cJ%cl*9b4p9jlI{iD1%;)wQ*iCU{#>cr`sp9z}6Zp!VhlQlcLi>H_pE~S`? zE7HJzEE+s7W4gBC4j_*!c7u@iM&buzEheKvh645&f+q%kHNE2vn}ua#F&*!X>ym0@ zod5;+ZXW68yvjNabdCygcy8R&d6W?kfB!ZMXhzFhCa*)4_BKyHRT@NXz}h8#WMa>n zhal4CSvC0hhT-nb%H#Fv+kn!ak_A#|B_h%&L8y&oK3Lt{u@o3&v!7W|70QAhKD3i9 z42uNSkTYBFlJ~kt`PQ_A4eE>Yum&f+)lg(=3JRyV$D8LXNpULWQ+^~gHtAcD=-GL$ zP}q{l{#|wESWZvI(77D57_p2-E8XwzkJLDYomhF{7Rs;obh7#2fTrhPb$R z|Dk!hO(*F2?9cOO-xV^i`NA|3V=tI&pmN?9mcLXHq`{up{_-*7r9WG$vv2)Qz0~*E z@21boM*F}Kj7ss$ry~%0u_uoyI$8Qc`>4-Jtm!lXZK$asNI_w|cRG2A-s4e1F&5H9 zD`lj}+ji!uja|i>FTo5)uG^s^!WY7GejU3BLN|sxrV3?e54(>Qa)lG~C$E%{98JK7 zxN7=cObcDPy&vu^6l0&%TFzrgeFOZSE>9NaR#HuHX2SdoE+&J^OJ1V|cu}4M_fas+ zRe=TcKq>hWvn!-fy{+p(vuHfAjp{nomd^A;Efdl?S+uBFOvPmD;_ zQZS5_k=d9v`Ii*bDT$_(WGe2el#*Fb5sbV?lAEOfpNO!;>E%g5nK`#u92n26=l zj$};V3;EwU!JEREc|fz8zM}DSJCf=D>du)IWhSlizj%MYgGi}*LUZYrIVnb|=A%TPF^q`IFI+Y=dK zJ;^e-W;D+7-UTkYn#EE)=tkP_bc(4U&*kTfB)d%6aGV)C(FGF>9RD!6|GnPxd+aq} ztlfz;N>LKuQ-DoQ=3|Xt6?Qdyn!w$Z_d{-Eh{Ma4>mbH6UcY-{Qm-s5KWAU}hQMK8 zbZq|eG>p{kD>1obPvf$By@LN}+krbAF{%Zs7oEVmC?hKwc}xnG zj~B&+n~ux*tp>V#3BIQYbHE|XY~6I^Jg$L{_V8yVwAHW59Hl!evi~sI;#REaEV#ae zZi7dqxKpDlRM!pC7salGJo0eFe)`e&g*$M4aI|JBe%rIGnANmS*h8p3psEm7w!<6u zGdD5(Ol4_B3w=Y!1ir_Cmb>`UW>Z5jH?X^Ks`n+S8?oC#*T?j3wl#i@Wrfh<(s+5Q zM6j@a11Zbq4VwxDxTZZRX8z}oz?x+_%I}IeQ)I&ssz7yyc!W^$s|to1&?}*(3WGqp z7sxzXQ8TA1%^2HamrR2~8nVoL#dH5x;0^ctC^W73P6bwu#u79Y1WELY!Ui{m;pAIn zosshLAgRx}>GSrWLWSg%7Gi{Q{tRZLxfU$HbCn&2{8AhYXjzKR=wNjRk?5zyHeeR{ zVM<{hp9)%yS*3G(c%|ze@gtf`^dT0LMCI9|@YJ`lJ|2x9cnu0=3Li1()cb9WzH9>aB&Q6Yio0hX< zoPZmul+l^mw4{@i!lty7^g=gv3%)~X1r#pq1xckjVe6s?sG388zFG=Hthh}}M>iKs zee@&x0c}_02-ZZe)6pTk_mhA(4Np~uXDwmn%Jh5!$h83H75)JRH&yn{oD`Vtl34XJ;}i{4?V9$d+OF$=k+n!gBxdKU?B92!07rwCcpQ%|#NM z_{!IRA=Ge z^M^DI2#@tiZBbbo34mipq)XS8gTOodh&NG5-)^uhSV1H0xE6T1C>Q|39e~bP^!k`@ zCbAy*VqBjHddl2T+AGE~go8W_m2u?6iJMnu68JtWeYML-$F?$3q@k}hp&b^Mw+o6> z`dfhniNPThKf;SQ_i(SsMVs9RF)9{pi!+09F^tV0>5HfkLZgz<&bbjn1l`)!5cEhk z>E9`MgiKlPn*Rur4yYNFYa2fd`S&N0ds84yc^0UY4J(~ZPU?tq3^hbd+nBt0p9o@J{$+ZyxoXc6q#?&% zZLL)ct{5;DpUf!D z_8RQjFH8IUP72<@;&L?8=qx~ecFQhZ4eeh7M7-BX&n^=@q0cnKxZ{<7$SbK(Z@9KM zQ2xDs9<9LA_6t6T$By3o$-XELzI25Xzh@`!zLe)|mTrCCS_EzuhqtU#EL#-u8!8TFj*_f(+}wlm@Svdj|piYzcM&HJ28;+O@Zu2V6&f| zI?r@cuQDlV3X3|CwWx^}3V@q$ni3#XE*uO-S>Q?**iio}!e&a|D+u-Cw}l^K9=J#l z1$;HAfvb#)ordg$aXm2j-h%V)!tOv&D?i5R!+)G2g|HgC&b>K20igiPf|GS_#%g?3{PAupQ#)NXM5WXHvXNEpwWkPj#87~m8}f| z`o^b%`7ryzx&x9G$SP^0EE9lU2^$o={0Zb0Ov(|cs?sy>$_TaGpI%i7+X`=ahI2{} zv1|h|5yx@Ge|v8I!l;9O+C4zYbwsE6G3cP%BFz4X%v2N~Ezl|$3uCb?7Jb7>9ZQS< zY+v3S&Tw3zGi|y8f91Q5cnf68iO@{UD=Ref$EZFWHlBAz+9t@p{9YFo9eR76oguRo zTqxD{B5!B8ka0VX+Sa91z6>Gor>n+r5>X`XQRYL`#`zknD-B4fWO{ zvtC?y62oOHyo);ey>~hc|X>PG*KX5^xMbZ?KQ&Nh)Zk z?A9cLfMr{P_CaX2ZY#C^s4Gn!m*&fO=3x#!e9}m&Jha@wm#L7eB9Hnp+_N+flfLoo zQ%8nQ@91R8XIRIdHRHGP3VqqxOMUXG^nn(5sG2!5vSX4q=@^ju>?>a#U3e`>9b+>F z)!yJo)>QhSNro)Gl>s5u)MO-9dERHJ=>`8k069U%z9uZ6UmgV+l;C+HgL!>Z-}$sJxbo+OafA#Wkuvz76$1$w zoDmu9ew4A21kZmTW2lU!7*l0z#TZMfvOHd5O7RktXA(9ej7C_EFxyV~H)}wZz36+W7L0C{R;e!byGFHr(k+CCTNNz=%+&ULWQOX;nGEohmXHSb=#-y{3 z`vwWC5@ua+wst3FqKs+TD`QPAgogcfiV0&L8h1}4a|DdcCGAYcj&84IHG54ieo;fuJ&p250_Pn0^ z3G*=LQ6`1bU`(X&artp{0Qnr4%;d*@30W8C=cNPA)A#^1ojmvWS|)|FObW&F_?zmd@0?5dXg;uYucrfD-tI^9@|*MZf5`9U=RgYI_wJ)#z44yz9e?und;gzL zdHlt{I9Cs@uPZ4$o3A&jJhW_-dJ3tZP*lU()WCCLm<2TQ39(M&D(t{s4+0T{`>2M| zTMvRan!|}So^&jXp6_2KhMqMRWM001BWNklL9k}>x2L^>3xVsbnzXnHBP$M#U<7HA?wy&2W7wVz36@hh40Xa zr4mIm462m`2E{M*4H^MeB~i9*t-LZ4A5rL{vKC750+E4AR`iE8Y9?Ziurgr4#N?yoiIc+56t4eUU zZ?fE97nQ(%UtrNcSb49YEvL{wNF}4aL5d+0LJ+|^SoY6y{7E`{!GDS9mh)uRudB$#c+h>*in=*9+5$H6eSEe7jFr| zgtse3e1Iy0_Z1Au5fdad+(R+uEs8k_d(t2inQg+Rj8SJWkr78x6*yQOJeF!WaTG1p zLB__4ksHO#f}sURSLW=$QX!l~!RC|7QbOO3m`8b@)EhlJM8D72nu zaqgAJZF7+-hwKqbNTd71KYC?|&wXy239=L6j22Ns-B*io*|oAWkr z2}vi53qNh%>{{GZ_V=5)IL~m3~`g;3PdNJ5}wo(*c+mSTum5awq~4f{cH01@Q!MFr&?+n}X|LLY=7Pnqw@IkSwUDa5&x5@=zjn zSI6i>Oj=^vvbw>K)xIGnX2ZI0H8mn=ief8@q>?h(7nHw-(oiMyhc)e=5NlahLcr=& zGD8~s45%DdRn~p|p01AN_1P(vz;^A#oQdRG<75>C8zgTH@1?Pv#;ZXUG^f_JKoB)v z1;h-$H{PeAt3je{qaRa#tN#0GZ9f*qpeN#2znmUA{mz0V& z4TecZT1#hKDQ9i0hfOA9WZ&a|3?-UE*jn4i-8Pla3uj*Z-;z%XSRZfeQ7QI&Q1?x` zFHR6d)0gP#={>v4Y9Gkm-irHThA3a-wmu*FYFEYCAgA=84r;sRkXp5Z5}20 zla#>zauFHPTaO4Oi<78b9b|KuBV9W-x2BIbeP;Zk`m{1~GmWsk8#?IkkS=>Yi zE2AX(%3utdKS3G1j%Dc=9KdCil|jNNU-+1dfB6S*`|#f(Y(p4_uuf102?M>EFcD*; zjFAW{F=ooxi7=F6sc$80B^Yb+b%ePDdl3d>7x=GWY?d(^W3`Og1iNvh7-6}`h^suu zOFUdLpO8Vpg10L+WJgiOjQ3#-NqvKiDJ6WKu;xOH4awkeSFxzz(u`3FtFnl}@e<^o zf3(4vR`Kn;$Q$eg3!AGb0_cwzJ2Qs9rm=3*5^I~eW0?eC6@BwlLU?-l$GR-nC96b@ zrq-zjVhSPToI?5GYCfUNa-?Hb3$=VyO=d(XoSXBgmX9Kza0<&_?kN_jKc1V<`hRUV=H5F9)0>k4oJ`A1C(SGzA#^ZvysAC#~FqBbu%fPP>v2A@ZON0 z^T+f+NC(89*8}9Q{O!Are(lD4y5D%`TW|ZF&;8W%f3*%$NadpxK~W)+qDD{Qb;&05 zenKIL>O6{mLPSuc+5+j%o8b(~Nzoq=!fLA(P3ct?G76RORYC@@pj1Ukp^>?z0n%6% zu4z}ABFb8k8oKe*vU2LDPM{MT6!+9AR>^kMczjK~uz% zkrAHxuia3``s-B1gGzV^a@Y8KXOkF^g`up6(ja8e&1Ck~S@f0-%{W}|^)a@|%x4Vr zH;v^s9w>l?qI!^^RwnBQgklLZnyaclielFmpO2L~wyyr}p+5_e7;5}-75R;3AXEzp z3`*eD6BNPX^A6XCYb7~92!<<&*G>kJF&J|OK>$D4GErT= zegS2of<^9(WN;%df8M8D_$$IP*E6OeY(p4FvChvc_IWd7A;v_6jV7-pti+g!u#=KO z#Z)h3jKySd@;t^~guw)hQP$v>Dn{e1LBei?;S|d~O0gYzM!2KsHS`TmK7z0zW5kRV zSsBdOkuW4-Nx_ujD5?Sky zd~d=)tgJMYiQ%wf0!U*k6W#4bjAlf^B!e3&%c*2`wyJcmj%1mpRYNS9w-MSpTCVT2iYKo02C2nzEtFvOQgh7epP)L?L z_tokISt|jA!G`p^?N(X>RyQ}`_Q@q;`WWunTbG_gRs+{+1L4Rn#5KJywvC6s;q{p zsm+0sNLHr#J<4O*eN_qdzI}GJDQs7btRpt04*i4Z30z*@kDuXKz8`n76;cOFe%Vfy zwOW462X6qoZVPQM`buOhkZO@#QW}&u<3DiCoLaycLEXQ zc7T7t*!my`9<$jSScmgkJilGR@<2&j@_2}TW}r>HR^j|ud6ka2g;pUxqAt(XON5Wk z?<>Ydy*|HUVEs86*LBc3;1MQ;G=aUAmp?0Gmv{Z*ZNI~1qNOtUbA)*a`^;rx{0)kU zUMm=>DRFuj@1v{#vC`X*#vOv59dstB05(^V; znG|-I?Z`j$BWjjqlNlz4GCR`hpJZgDa5h;xX6I4*LrLlALI@$vyyQRLk%rcH^oQJ0 zLP%~;hsQG^g?W1_9c7al&M2I9_sx%)h`H5v_8Y7p==(Lq!g6Kc@3|pkb60ZpSf}2%pefK+OGNFPnn2;2--=b z@~k5}0U^Ye*A0ppNz6(vE$8PFLg<0GLNMi|$611;@)5}!D(M?mOa|#TsfF7*hy?QX zAeZ5!xf#hEkHL-2{604aVp2mVa|RfV^cZea*(zW0r&6Q=HeIjTR zZgtt?t;gf7e4M^3;g0&o%y-(vVHgbulKQU%DB|;3YMFyIc(l z5(vld3!$aMN=*X^v}=$%J;z@NgfEi5K>myro(*Ksmd~6i$zUFzcE{QG{`Sw``n!Z- z2+OE4NZ97*73*m5{N#rh56O4yGvpa=x_XKa`;;v6P2Gxnlj6B)&nhYRT& zq*755A|!l1W6`8jWV445EzG9g$>a!<|Rv$8M#giz)vxIJ90!A^&N{d8}#eH7kXo zeDva6W@FrWlu6-)W^Tx6=5RsIqht-tCNr!Ql4Y$Dsom zlfpb+mX}|dAOGsS{JnYr{K5Q~ObRD&%CB`IDg1Al6h7)9Xa9P9#(N6aGZ|dZ2jTVV zjF3X=9ZY2HJh1Z7bLuEcWbkZt##F&`XT*V&2ggl#uHpIWOdyGaf)uV&31fMwTVBik zmn-jkxQv{`O8W}coQ5BlV5MD2StteH6A>JVGAKlFAnO{rpGVSi8<0SLUXa3pmDp_7 zLg1iCqEwZYIZ_ncK_-I|RUv(l(!YpOR(2B|H4-&ZRiPh507RUXj^M>hiY4o93$RE2sro+-W?f!$Op6l;Sl?s%k6QlQ@D{c2`^P z6O&%+=W%i+rItz_*HL0vTTdR;D<^~?n6>Szkz#=K*e8U~K@|)1X!-MMA0@2*Ybgoc ztCA@nlzDhK6jBn&E|DiENm{nXBr>n7l7Z|9x)1a@_X{!*iC|Fk_;aj7392fCTCRJL zzi;Y;gt7?LNgkWjOh*(!iR6%FCV^vlFL&EOsVk9AAxZpRbsXsXE=gZ%qXTPzKi(pFBEamEZokn~=d7k-^EE82ikG3=$?HY{VF8s$_7=@e(gm zEJc{=d4#bDYZ2yB?Db^EVi}V$HWOv=GYGR0b|VZYSg!j-!gh@DGS(x^r`Yc!*im!} zN70NC*?Xe9r((yu36>;BQ8JL32pOD#40dE9BYlHjCMsl*%S53JPJ|3jO%=3KQNqF^ znnu^Wd?vXqEWOW2hNnMWcR|WWCznO8@3fzA!u^DERtmY+`)+J9BMwn8nYnk~ z{%9d4GxyK0L8S0@IY3PEfr1VglZWN&d;sZ$6wbOwAG=cc*$WD;CsIfmh53M#Z+{t+ z!ddr>eEsaaE#=}oKd=9WeElLluu+(*kizNY)v6S}ZXpLmQ3{C^PP?C;Uo%qp%kLvn z_$S>ve&a3o`n^X#^z3^<3O6e4DXeLnxvu1odJT#EUEdgRh&>Nh1*=L4p^`!^E#>R_ zOdir}cy7>B1H;K9o?v3A?L{MlgFp^F<0vYIGDA90^$sERQWgsJkBH#rNSC1!wo(R4 zN+3v}l#~vP5MEAl%`>ufWkfWdT&1s2NFYT}aCvF%GrF5fr1(0&?hX&xj%K}Kbi?JQ zbveTvXT80Iw2~Qe1<(g5&D0#k9aZnPKzSM+A%O2 z02%|&Qn9dJLnXf4-&DuP3V`R&zY$gP5OE4n+B7mk$Wm=3k9%4I3UVeuIx2#3U1BAM zm6fJXFlr}$7#rH#r=_e$E&yg#6_Z$v${qvK8b9l+W)9F2vo>KqZnicV_SZ_MoL{!LU~?erOxfC=Z~e@zzn2fVe@zEoQU}ka>Q0WJs4F&_VMCc%$`MLF`lTOKGP>L+kWVaU zmS+)*lLv;Cw@8_&%rw@LSE$A_*2jPo-au8tBx92dWT^a;`vS!^lt|&GDukO2h8WB6 ziE_8!b6@zryUNgy{xHkGZp_kDJsg$Q4nxf&VA^@$B8}w2s;UT547PAd5 zbxR;WLgcY7;`48v zP+{FcBv!reMj`{$qywLw8H;!ioqRqOf4=-#5OGbiyszKeo+_}?@8|uYq+lKloupnJ z2SOZ_DlV%XSGtWWc77X#QoeU1uu$prHz3~+)Vs=vldGI{AjPV*r$|bqY?9UFR@C^z zAzW_dGm~=16#CrC->*+BEE}Z!Lk847c|Lz_Ct#~a>|YIJ7fPU#wLMdOy(}E%<0x&X zYd+?*`Wqjn&^sxm@~g@{F*#5ugmzu3pyq~JsEAJb%AVA6c@-Hvi3s+qHTv$LQ5D>b z_g6tJR3%WzAgV{a+GJDLZz&PHZ1>4_2zck~fiGV|wG1j}%(>gEYY-BT;c-wh85<*| zVk^f7MF#I$88r7$#u0LTXP*o{_KvfEO&Eo+3Skx_gBi;(rXey&7$;*L#ylDO2nG^m zkg$ip?HJSWPk8BLu?{mLp8peXL-- ziITyL{RjhQEJ&D;u%Ti^brj`%>#Kw%2~(=zK#^w>KA*9tV$chMNxO3kl!{KdOtc__ ztO`o*AYvvoUV_U+>k=aicAgsL1Ft-` zp29qSW`4~`;jjGdJ2NSKPxl*43hy}kUa8eT!v|zCnc2`;ytA3;ffUkgp7jBoaYc|# zWUOqoB#9TQGvTBWmbKsDTpgXpq_ormZG&2P87HGUxRpZ1YlQ$_$-v}tn~By?R6rUW zJ<%x9gQd2Of%a+CcAM^J#jr+C22R8SiKl2PGo9gH!!(eni-9PHTbSi1^(uoSCWMWa zrq;ERKpmzKIw9QFK13mwiNOQMSSYcJ(HGm=$3&oOOG%I@dzEC8jnMlS#t6%*umuvh zjWRa|tU@@LlqPvz26ZqN$wXp*WxB>}001BWNklT0j}D62US6x7X7(|RDdW``P{y$R46qS#WPu!qMOuU zzbYfHP+~yS2z2puN10X&7q4e@<=(*(5PF3>6Bt{%YO>tA=MP!2?w^3WR zpDTV&{H{jVQ(D&NHKIgBZwU1>75#yQvZf`foEw*%MC~Ofwe%SQ>>Ke?VpFK3RakD+ z#3huVVu0Mmb?AlUeQo7?ie^9uX68~C#0};^g+i2~x(Q`a*Q=_=#23*cqsG)pelC#w zy3vRTSKL8h`FE$}U`Hnd(9aqbNxKfEo%^*%JbXwa$@jF6*RRoomwNl)x0g&=0y#wV z1*`dEuPE42^3TVSMvY=xbqgK|NjAfu%1dTTLRc01=0q6^bWk|sh=lMaWbh<&nZD9@ zk}7EB{XH_cwPM)%%ERKfA{ngIRXf#g3{(5^X6+@SXrmB9=I20+%UYRoX%G~`%6si& z*(aBb2I7Y}DeLJE%Hv&;!Sh1yoD2>I{V0hgGI*|ctq$kbGf2uHlfjHp{^p%WUM4CS zh9x$Z_?U$R&wuhl97QQ>@S%$7JYFJWzPVJ19nCFkFk?f;h!a%?Cs!FmW-Q5=GGohy zD1%oRb7t(RJ%dszD%f;`u_}{6#;zm9vVv`=QYN~vzQGAxMG-u&<)RZ*+f@-$ufp7? z%HZkcpTuQZC44}k5<>EpAGOVL;D^t%B6F0EPA6o$+em#i509dlipdO1@KXt`U$8Xa zomWzLk!NeBJZnRwkoyT2RP)WQP?KBopPK&Qch@+I{Kx08Q6hzt1)0oDClW_7qw>-2 z!Fk(<(5%t|8HHq7Jez!KzNP~XXB5tz6jJWZmn=9GwW9;pQ}c6WQrJBwkFUx1Wl}hK z!JKBjB)IOTmC!K(gd(U$E<~nydr|`` zEeS&m0FjRk$pL_U=;f1=(n|Z#+<=BjoRzwvjLf4p#GED?&m?_~mCVPN0Z<~nKFg=6orJW!X&9Vo9#6ijWY98m8UfV#2rUZ^JQNIGi8++|(+16A2G zGnX+)OkmUo=hGQzFLieO&It!7!55{`CqcSTmW)kK=Vsp?aFaRW%wn zg3{f_`{8(09&+9!C&y4a6G$Z#&vXNECQN`E`fkzNS*u}6qt2&Z8Vcg+?z73_M4;&5 zcfN<^CFReRW;cFGE0&Yz@+kq2Mlm;YFJ+Re1}Q`{e~{~kne z>Aui2NM)cn=b%g!MlW&V@`|2=Y(jM4nSYTCimT|LTvww7qxLGB;27#eP_|*xR+r{6 ze;+bfD1(E6DT7fZ?32N>P6n3@WTRu{DMqubK~@IYM5d#O{@W#9 zf*nN(^KsUoV!>P0YvS&N6$vwnYrXaj&Zuv2vZWYP;w2b+W(-PLl-=-ADmqzH%qqQu zT=~X1gYB_a#3|;5GFY2XV%2pL*|u0x2On_SH+Xvar+JBFa6UWIAL>zFzTX-DAxpVv zh^DBdahCH{D*ZDkDO8nkCNn7ulG(+1G?PO5laawpM=BvZk1ja0UYwmcw0_oIS#UTg zkwS{2kbc6v{lQ#<>#0FF|KY`Xl;bF_b@!cLn{@dAMV7Kcy#CAQq!iMDY&v;P9$!Os@cCLvVV4hllb52W zP-e-xe>0b!LLr4v3VWoG%SY8{=COC2eeY-h_tEOkjWc$zW)i3bkw_e7_4J?*Qdl_= zTr!v`Pa5%rauE&b1DtpU7GGhdEvy7qOa`xz0yrA*HOA#e#+610iVdP$amWFW|U!epBB`@?J zk=h9`z2CxY#7Q8RudbzXUlhm-7{op`rY`Q)4$J{)z4u8;>JaKz<>ZD#+Ck_lRr&Pu zXq`arHKAv191LZm$qa|adpyTsh@-f=R*7*;FocO@>Tu*l4vLnM#Mm2%{ZZn>Dl2_2 zjl?QQexR3snh8mA!nKPSjNvlDTUG{rKdz2ZM!KSZan<|L@>`Vb_9H#a)Tc_8nRx)B z6ni-Bbs8gqv1bkC+8%?Fg4?Z{E;Xq~v{IpR?FOP2drU3QFOWhHf7i)}g8U^Xy0%>V zb1Q+|55L#F+V@lb`<3<)R-TIratMN_6D4xo2x_ZNxX^PPpgdiVNn9b3WU?r#eISTS z`F|jQp_JB3Y?oC*TL-du7eugs-(9JKtH>aZn>SMhmyBhqT94s1_oXip!ce(ls-7u# zwUIMU!e?s&}49+ZlYu$ z<7J{o1{J%AGANjas-Rw{SVxpWabSO`U?MIPeSu=7uOaLt7>cT{G8vrFgnPzVG6DYt z!d{HQBpOVE=QBnltR|T4j=2WU3#OYqh%g>wy^Q%5Y$5|PIJu`{L#igbs+e(qE_s7H zgeip#62|Nu;G|i-Sw3Wc48nSWKg0eyjQTAn|nVI z#QQO}F0uA0Aw0eO6THZeb7DVO`O%iO&zSu<<|qoTl~$!tLhI2_xR`PtOZ)>FDV%d% zHig#nA5TK-XC2jUi_wf^6jCP4R>&w+lNmUVBBPL-hQ(y&8e0uh80r1girx>Ll)VhJ zHUj}6axfB*s0!o|%Ij59&N&j2$>uYSo6hj_)#7AI>&d`|$1n`;drL+HceNZ8Dxvon zDwtEV2P1Pt&`8~&zQ7GB3q8=xz+El5BLKFggltcN8}|kxynW3bAtf|E6+Mi5!&qht z!ditW3)sG+cPnXW8Dcnk4v&b7P$h7Gn2eypXanpzQ>r2sol5I6;em1By*6 zDw6_AJ9INtCjKBTd}@E#Kt;g4_dk2@we~p?mGyYg+AUc5eeva-m6cT)vDR5@uT^Jc zE4L<&XpcQi-iG#2&J3o&mO6XiN6ZG|Z+Br_`8;PLSWv}+DS&B)E~#s>;BfW0$^vVc zJQ{576TcT{9yO(xGp?B(c?Un=7FR~ehK=vnR!s{rt*J}Yyq==hR|rW66B$gG{kjw2 z^qgLG#NfKCa8U5_Iu@H%hC)tj_n0JXl-?f}k8%>o-`8q$k^{kmZF=Od?q4Tqtg9YD z?4^e07Evy~WQ6aiuow%uNn|fi54|B(@J3rhkJ^0UuS%5>gUjm-QA23jxiTqw=R@%H z(P0&Z9=l40#-tA4-1^BmJ}$hjRVit785!(9{_wouGBWtll)*DYG8nOiV@*hSJr70c*Cx06A^Jc4}$0|^!qOayH7WMHMo3wAOLrC91~1Y2R@{Yy2+ zL9v&R!HC5KlbMT4D#I`{s0;dcF)XK;P8?vj6Rc;LPeNpLZqT|0O)$`U2_u8rH^{C* z>l^g0K~o3SDr(B$sm==MoeT=Eg5?Oo?_|jz+>VEM)*%3uj*nDB!9@@#O)&A@e@wTsw??Fi6H^iUun7E1M!R@1Q zlU1M43F%uYl?=+|^Qr(E30%iz4Vft` zx0UKvV`c&?rt4L*cMhYv*EowP>LUVYG<2pm`{~xC)J+3w>e51NLh#jDRRK#zf>%p> zr#Odbc2pyFn;@0jE28w3N&>fFH}%J1E=~az6iJ&AG#jbT0O~AY?N(8%iU>MaxDjfP zFXsxiD}=RyHzjVXrs!Rel+bv-vzpXJrj~lhO>HF8Euokt)Ib@Kygb2_b5%RAVD7q& zECEqh3o^iH>7gS}5$#n)fKXl}=^RsC99>~8hnAot2t)}9Dj0MI(v`~*o?Cf&cyETv zNl^w~>;C(klBgnZ=fWhZpGsKp8R<-)^b{gAhNNBI-xlnZ5=LUPfg=x+A&I0dG}%P! zUT>hhHj_dxX2gqXS|U(F2!oR!&e*YtJ)iGVf;a9HMuvmr#qmxAL9|RY>W94?-ZI7X z2$DEd0DG5LQcww%)GaI`Tp%%GaE;qF?f*g-6uisu5Mef6}mb}*CDAISsTQwkp%Qh;H6;e<8^MQGis#djRBx~w~7Z&spf?VW(G>nim z4EyXD3rS2S9%V$Vs$6NzlRhmGmti-3V(1DU-giy{w}#h;?xqUR> zhGfvMFHr`E;W17I?Q%Xd*dv32H3V~L>3ph|V4CQwFzUi;i5Is6Wl*usVrFD8Vj#mp zO=c4nS5+g*;9~?s36>H}CD=+ZmSU}ixU&>{$-?~o1d|Ci6O1NUO)#5ax6XQ|uRqX{ zAh(I;^%A!*EI7Lfu;E2u#T~_t3rQ4Jfnl9wutSK9;Z7-^Z%&~eO)Dmp3|f7fXJT}; zi7FYKrFsc$Oyf`Uf*iMMO2N{CsRdi-So`>NeEL^?V%kyL3z^v~@_|@Y4(Ir%pJ)Aq z^QP|nyr~Z)c@*)yY8{sC&Gqqq)KSD8j9C!w*~u!D_1oMpK2MdxR!HG|7D=Hfh0P=4 zZC}|cDV%+M+>t%zVBS0~UVlQ|o)qu<8lGe>h%#Ry==h+U2h!zq=+u@SFnHe0yuDq)&2bbBZP4QK7}^LLyCT0o3m2ccuZ_cm7dw`!Z|)8`40 zXTsQLZJu38$QvU&glU0U3( zK0(5oY?o9PceB2{tvVHL@7CFT70KTyg~_DQoV2-GxmxuCbo_HVk%C!FsbMj;5s_5K z5zMN4Y6Qz}RvD40gd~L*NCHn}q-m9ES2(N)4y~1}yr@UXUdd{JF<+-jsiGO-*vUT& zTKw>LOQAIQTqdbVp8bmX%;1GduKpb+gZV}^&T3frbCY5zwH_BT^_F(kU373>y~6(m z`?*u7qF!G>Wven9=`Mqja(nYA`<+R24w0_3r4S=noj*=OX#by?Wi({A*wFu()8Tul zhW95D$T?&0ARYB*@suQk1Ww1C6}0`?wiCfT{WDoX`8iplXx;mqw+9O04u9TJ8wq9A ze+?&v10r}-Xv~phFh4(ns&|lSqplE!qzdx*(65llX463k(|HAgm{LP&59N%! z9_#9C_Fl+gS^9J3a!MOD74ggxGB{KQd)Jqc!6ln58XHFFlfg2PLBSY;H3V}A_89aG zzDh8PVwDAyK_i1N5KJT3MlcSrj^rr(05H%~1rsSYiWo_;Qp8M(orDa|#U|Q3!m!os zp@Ovpa{+tZuhVL<+2<-YGmIw1^PgeZt+`&Y++t>3gAwB$fD8)u(-0ZOg6bZVv7!t8 zdI_Bw6r1Q8u%%>HoKeha*z=@eQH03Y%;1WRJ1G$yA6SZhonzcY2wfoQVPwP1d)Y`< zXz$(IVwbrB$ZPzJX_0=JzA2EV>FGD2fuB(2IDFfrnz zvwI*%q5x`2=n0a`D)sf%DK37RkylOMJOL7UqV`~kMEvTc3UYQ4NrbA_VP1)3l|(bm z6QSsy$^!yzwBUNB@}IYpr&m@fcAoQT{#dE3Ky`z>Univ#s2g?V)=&1HO$Q)56?fb_#hdArOSO7-#L zO8WU1C!?(U5tSi2Um2V@c5a;qx8Mj$4~70oX^zdMfILYnqMbzcBM8~-P5+LQ2tPIXhsC76!N_c`v#X0 z!JPQrP;ktRnH4-l{<3W&--202*Rg2GnL+Entp=pe`ft~9pDu=0X>QO7VO_!Ll7+<_ zIxZgGs1Pny4#N%9N_^~O@QRZ`O)$3wW=%AY*y5`r#`v3vH3V}A_Gt6cdBY~ZsaQoY zOT;dnxt)GiFb!N#f^nYF>Bx*=pXRB8g#;4`HWG|vSV`PfMh1bU9u61Q7YWvCK?Z@r z?yZ>2u-RvJP6i`()1W|h4bH9w#_}+OxWTspAAg|R?*r2a`c_n0Kty>^@ zbUu@i8Lw|gY#r3iyX?3Phb}Sk)6L&N-DL4J>Oewri ze9g~`_dif94Dt3z3TI+zczC@22u;LVG_qrRlLcCvgfJO=zGq;b%$2_am z9Ve8+h1o}2i)-dg;qPRmPote>Q~H~eH$Pa@f;!Ur2~R8q5fp`S%ggAcx}x+@8um}= z3?URrA${AE)Ni;=^-lt3Rx%Perll0bNu zP?ZpYtX@2k$eJgYPLg#{L8YsbLCF9uss@I$@^Asvn(jGDBz3SUammOV?WiQnJ0KU_ zc0nMoj--zBg#P>!`Ri2a`l*!kx|{U`k^p;61`{^(8Ml=Rfj}v3Rmlj8uR!7*3 zX;Q${epy#(HV>qWH5z71J;LreAf~wzm$4m(8WCis_jgXN% zea(^oZ>R8>WNVeAQ2o6Sz_i2fMwRTGQ>Kc#+E0a_Hq`XDNTe^>se3buRsZjo+d^+p z4ZHy&c%&jYRQ@sr(9@lBGB~*HC?a^&^&ts7LfgS}b_gwjzN6bvC)LNLW+BDN5W zAy`8&N1J8_{|hh)dIn(=RqP^er$z!~o(pWFHc`Pmz&_t$Sg3h|U?asy5i1#HQtb2y z!BT>$1Y5x-`ar{6v-?mPY^@?pi|2vW?$qkcU@D$BY&W~LVZG+&iv0uwMl2|pP_SWZ zBSw}es@PG<;CaQACOBx<-~f9jbxt4m?LAVd0c2no8)0iK54Z z@c8rzbvjH4XI$CHQb(Z@`ehE*s%KiHbhD0HPvHndxk3iVHmEBeZR;m&ZJzK1LT0Yg z7+~pzaka2nkI&yYnC~emj6ZYQ?l-%w)lo=sy+jP(G;WeIbxYe}%x)8Z{$9NAy3UI0 zC3#dk3fuj?xWk#hTEJ$(vOi1B_u!{9CQwnvaP==v}6mq8UadCS> z+@55sV~yHJHEGL9VG5e*kUrYY%|6;%dHpLu3jZKe3g7e(e{tfnpQ&%X)iZ=T%BEWkJ1>yb4NT zp9C5)Ed4;oWYTq7O!@e_a;0zsilA6T*GFj}KkqACugWyL5t0hntFtJD3|jDvlE8^2 zj(P&Ahsz)s0FTp;~FSu6)kt7ZQCk%(Vfb#a8)kKWchB=sZ+o1}ivxXxlz)lA0bWXK)yXMcT-G=I< zEGKX1W8`Nb6%hojB+eH+AZC*ftIBhnxeA|deZ|2*&WeP`$F!?pW&Uv*Pqoe@rg0(qen0VQelZYcyZ8@;ar z=!h(Jr4=&6DHwiC_r-em!{UA~sI`^Vjm!g--#ggci}JmUvc$5$Hx6UW<+q-iv(55n z1K7g}ao@93zT+l+rYyhPwBuz2ms57?c8M!rSAI#|AvU|n9`Y@?4h z8ex6{4Nz#Yx`rYxF#J z_QgEBnATh=QiIZoyiRoI2RLy+K@Ft)w-8mGW z%uJhzD-E+sdm-1&YtX;YLJi%Xj6rSY04;HR2QhK)7Oby)mS09^#;DIf^P*1MO#u6t z)0SIfikqh&ut=z3K%VfQnyJ4^TTI?dX&Ok-(O8Yel_egGe|8{10y`ZpX_D4YzLwER zc3D4vuTW%wTQYR>nlk2eFQ{oxvy`j%B4D@xTn%-{SRAWbe6_b12jZ~7i_JNkqXJhO zUp8924T1)qS-!q)O+mbT?~e9@z(HPHqK^1{*Z*|RK3_9pXKO<40#>;D4qmx#2Mq4} z^1H?zzMO*-S3k_IE?&`D(!l7NgY~Rh@(O-9m_^S><9G5B38YBk_c!1FF?dLvQ__P$ z%{3cu+Ri9jx>LFIuhdxMi;iKl{*D zX4j>wA;}S?c{T<*T$yT@yOEW|u^`cpOASY`M6tp@P2M=LnQ>dgVQ9)wMV?x*kCA3B zOcEtr&CoyFWm$fF2Sq>paZUwy4? z<|-hle)ERuM|8v-jXNDy&Rj621rl8Qm6_VA4|l*bOpAy`Op#+cJ>W78K9-7Uun}^U z`qgB9pX*PP2jm2Hq~XPB7Cb|!efiD_x#r?SiUXVlnQQbN1A(bhNV74p&RxteBpUPK zFeAAymMJAjE6kRo#*Le1=P>ah#!S8#=O0C-FU1A@3)!*Q!H{i?{~~yS$Nv`^z5OjK zt;5u-wU-1RGnRYh3F5`tv;%)j8S`hnb`_;u>Dn8INTjf{SZ??;o`(BucySBwf<&M2 zG}@0xm+k$v@RF3p0IMRItbu}cF<*B62vTpM}CIY1@Et40`XmGR!zTT7RLd z_>h?KxqAmyb#>o*yZmkoJ4Rj4qF_swqNJGs${ChKliMsTJa~RhfjIjZaM@Hx;M4FR zDn_juu3tO%R|y~RIhYfnm1)PZ>b2+C-U$v48FOm39Gf5SeMcbnmJbS8x1z)~=2WT_ z)H7@~F>tk4(ZF&{-I`8iAMC2V`NBp{w)N-dH@4^H11x=oqT6q)2HnmwTAztE0EfjO z0TS=gLc|QUckI0~EG{@`JAZbn-`xH(qeKIjZf4wI?@d2T`eiM`Ob2r(d_Nd&u$in0 z20?^Uwd?ES6A44QYa+$eYJr~E+4jTg7q^;N*;)Dw!_w>|v#}X4&@-g_LT>Y!=CR_e z@Z~NXf!Ut3j=kGMiQl#B7bX&9;ylO617Q&wO1t10(8#O#NXi0gn4@uPo!n`N0`8>jE>jrsjg5)4A8|z+Vv_2Z#(=XagCCD$=p}f&$ zsF3}2($$egqhqcGme^!)*cq#pZIQ9SfI_QAR4GGp6QV0Oa@@ztzC@9NXpU8&Puq#W zP926?hwc?iL&>+GhEm=FQ#-r-QqF=piOT$u-fWkP1`2POIrCmsF@r4(uvm?MBm(SK zZbg8!XZ<t28DvazpdsPA&nvAtEAQYtpF$hn2CJ(6~Flld#EZZl@-?`_!V z-5XJBNv9T%#>W(bb%Yg|P8Kj7%x=45$*@2?tkHE(Uo&sk)KKhCb8v{ha&_b{@Us}6 zA+E@}8Q7iY7WkTAHJmGJYcTjs;1jSkep(m*tyRN0@KFukhL;=tQafRDvr9WrAuwyv|5IBpzfdGPSSC8XC=(&Pk9Mi`V)P*J zZKGEh$L*eEJ)xmWjrBH$aoE#VdY?a2wN0(<+eYy;^qVpM)%jNq%A^6|o8G;euyI1@ zC#B-aw%qRh!@)@f*uV`HNz-!ZNf|vC6>E(et^RR)bq#i#K?=RF#&rS&>C^j;UP$`&y{LHl)8U7Ui;p-5yRMT1 zmL4cViohO^MF@|c5E*EyfuL~^PyT-%#xOJNe$p(S3IWYQ+UZ!-9Hh^p>b3~ISuxvg zh$owo#oI6*ZR}{O(4t@zOva~j(;Ar!VintHNad)JP~?WQcWjej|NaX+DWlEko~)3+J9vt~eoqyD$b`2byr!p6G>r28fmzyS0fo9+BF6?d zv*@$N0haBu*Sse4_~%C*BhFW2c{LpRl*8Wco)FA}2jfPWhqF6TEdUI}VYSjpQ2M*S zb{aInlCh!y2aOz#CE%6d-)gGAC4wlHHW2g$(ZiY#y*yI}R(b;V$W3cHk{o9F=bc8%J9 zOk@#&B$K{Yr!%BPLgjW@Q$@$%m6IB}BCwTsr(4eCuK=Zz((=?gn!E*D_9ktu_T8PG zG5yyCxHm*=Akk*-DzTun9380Hvy6%3D*(a{9&AIiNehOu+GBYr(%LB(bjt&%k+4d5 z^k}?nR8TUb3Q{Gf-ncALhoPJ)BNeU%&w!M((I;eSdE^?V5~^RdGKJr^@BAgSa}~y- zADgPFppJlM7_m<}CCZyYYW@)qGFG5BZJ{iZ*3D^VO{Bbcu8SVe^KJ?XL*hlX$pEY> z)9T7tc$@Q=Ms$(;O$?ao%>;#>FsI34>@Y!8BN$*d%G;IVQuN$chgR1iVisKyEw2}a z7+#2=-!#*2x}@jx!k}$$rj~pB8$>m|ZRgvK4<^<%DmU^UwWjGb@o2 z^)12RZJU-36y|UNw^~Vl=FA(bEwh*U=$QhRh3Sl~h1BP{FA*L|Na%}SBcQgkrr%xy!3aAOHt10M%1Z7cQR@=?2W-(0) zj-2;G0<~N@QvsRaNI@&S9`1FXfQm(>-yW+>apCORG}?Llt2wwgmLz#x_l=I@ z>AGrc*opd8IFSu$I8@x6D+NSTDYEJ$CsbV#S^ccK3RBc8Qd|*cSp6U}vOor|QCCcK z0=D8zt0IoFLwf`Q*}{xLgKRYh(haJUe46diGgFKXnTo_yZ^3#>T&WgJ!x~**gZt7E zN>HuOFDnhMOoXs&7qf`kEO!=(pJm8W_8sa!?6=H(5W9j$nq(aAKuA=BITgjH*`H#- zP7^k$WH!Aha7sbX=*+I&LOfNq0?#7#9BfN3N=}xv*y*f{j7W@U>s`Pe{IAJh+rHm%u@~KcV3+*>#a(^6Fd#$F zJ8-zvxLNnv?YHk#JgE?c_@6}JXug1&)WJCBH5=9v$1|2Ue-@?sRHKV)yG~fZwrp47 zjL{~+ZZ>^{UHPQUd%T}4Q>1dxZuEXB)1p%!0r5v}MhQ7W2gqTLW> zw=Q5G>tayMEAkK5{bcE!=5W~F8Cn=L)>E8T1F(XL$nmqGgvn=?P`5Tolxb<5FF@<+ z8!SEE%*Y_v7tFG6WW#Xs+r_|eSmLa{)JK3V8F#9D*r2RTnUah3Eq8BvV3`^UX%gMf zMASL$uU3{NEMs+&4BiGeF73%i?rJHpO_IV7jb~e0QtIrwSUu7|tZu1v5*Y*Xw>l$8 z=WT3dE7h8Vo>$0AkV=%#66pckDpaG zGuF>hX>>wx%cPw9JF0RrYR~;P0@i;6c&35nW*GhWVTf(A#f4D2=F+2|DohGBwnc#V zu3M*?fmVlL3fTA_Bgbyi0ZSLX)&K>2&y+QDtReY;Lloy7jyyUYLSijli9xVMMqxb% z(&&qf9~Am+V!okPgKf0VY@&+^z9X+2?@jD%$XK;~#9HRI@Di`i5OUUo45KTxN)+j7 zwU0gkCv-frB;Rql)Yx* z{wWctwUSX{`_>ywDSnDHo=4?`FOzXF+{`|dBv)7kjOqK*?8yM5j<9$OztKErj{EC6 zvfi3dTnb?x{!8=en`5LCm>t9CWZeT&)l-b+FM?OG+_+HEar`oP3H1*aY)DCrASd-nzb&-rbqT zw}*lR`f96vADg!YAwmH`ft(@azGtq_e+s&6Uewz4?{})`V-SLikvI|HoM^yDZe~&0 zU}zHU0DH12L+FEcTVq?Xu6A;=Om&6iZxwi*AuX5%Ts8m7eugKmY$)B>G*!IJ>3eV) zl8CDLA0m0o(x_fp-6E)Fnlj3)yN0PP+52{wvhnZ;X-?J0TqZVc_61>Vf1I;IdCB+d z6Z1N0+GK12w-8)-a*1Xh0iT5u5#*FHj6kw-pyA4&E{~jpZniWJYGMg7H{rf%*EI1{ zm&{r(cDVRHzl;a}%g*>k_aiN7%YlV0gIO>^I{yuP{LvWCo*{(d+NVl7rKR!;iy+87fB-U`QvVy?7&l5(4$F4!%= zI*b3u)+U)$_WUwb;GDSpa=zvS+bHW@Y~cU&!nA(7^N?W5@#mr?d|lD0&3v+~HX!EW zLT3#02;e{tBvILIS9Ns#ErxiC!9t$TKf~HLG%DT)``aDzK}I#$AC0ZHD|H@_1m(Qx zqVvvtB}SZs8k~1Bi^q$QM?tx#?(_jQRGtm9f;qOw*y-a-N=z!pbF{_ozgS`Hr29bnj`zpiYqCU^ zt0>*cQiEo`K$Ru^k8z+`Rx;2TBk4>-E`5x_rD(&}>#DIKMiv^L(->TBvIYPCW_*wu z^80)~Zw+472u$Ve!pPB%^hD`^%JakkrpZxLRoOxlf%yI9Yt#`z`?bTYU-QMYXkS4&^ zH$Jf^K(r6z{PU*KIpS)0X}KGBK-8K7$#e#do&5RdyrhAr1Mbadwp9fZVXvpOJEI#= z72Y<&H*uRvskGaDKkWBh?Mw^nBXT8ttVkYcXM)^Kn0Akgh@ZY@dbWqi(vo8BuDZJ` zDVd9M<+53`*5?8+vvvc`mA){y;X~NvLMLKq%~&-w3A{vfNp!jlNqVvY@9E&-y5Dqx z?hSjPS~mF3si&~iK2US~D>ttBc4Q!P1Q%?&3Vd4_!#6 z1n7z+Wc1IS$yAlYtRMq-e*MQO_Z(2RWL3Soh`pjGGX;I9^jDoJ<%#V=YLb@1n`-{i`gjiZ2M*tdAdUBEg#+Y3{>Pb$fexV9Sj!5 ziDCpvBiYkWyRBAVGPiwE=*dbPY;)TNBO0cJDc=Wdj49?mtF=1It95FFxgzMRYq;^! zL+xkA;-%B+^>4QZVaVX=?R5mu2>nru7~ML2O7Gmydb67P;XhKMs);jjFCYy)x1HFE}}{=CsODJRcPf zsI$4mNT;K)*oU9$5*a6RY=tQzS+0+MSmx%3jz(5EtBjA{n}X%*GxuRu=Am{BvD?kS zyOhlc@L61CQPZX#tx!#(PzvU2%$?(=dVmRRdfY5)8aoAtRzVVRaKw)@bEjGS&yYmV z6-?0olNn5aDV*RvW*NQ{4e2YrJ>5_-tB8I7Fr~H5RoPart%1v4UG6DbgkeG`#(RU& z0r8YgHvb%zd_YE)Yb)?As`g{!uc}N|3(i5a=5Ax*4 zi8HnmJW#;iZS19(0z~Ms)$iW=()LNGyP)JZp2Xel>Zuh*$o@rL!1q&ApX>Imm*%<$ z(|LBUrY5`NR3IN=bkT}pmJrJ!P?(PX^2Ur%+KvJ=)Lq{Is3<1AB{B#?V=uAgiuG&5 zQNx_w{g~q_n(1-0h1Zn1nzTCj$Gviww@i56!2vaC>DwPgW$okdxDz{LX+yYE7?6HK zehs8}r0_qqDA~omO*)9998Hhx{%OSDAw*&{5gz(8f_zRRQH7$qQkq$kN!rFM*KN8* z%yq?G7SJwQyFYlPgkLKO<-VAjV$*XKjB{((dr+5FS;a5Uy&E$ZL!bYHqI)7$Q+VZH zT!bG**aByiHg{0lFYLohIv1;e?{`={7H|}c3e<v9q1VrzoI>y7>nGPoKd~1pWer~Qyg!0%+1kk_VPi+%?OtSo;SV92(gbf9;KHk# z;nl_IqOsd}sA}v*bil=bJvw(3I?tV?t3Mu*I*ZVFgGruvDGYdD^lS6Uu%C)xeZKYvOOAEJukXJbsK?X!SfKbJk>U-w`EVR})~1?zoh{ET5WwxNeu{ zxnt}He8mZ=KrEn$9X5;|)slHBD$}w82O!W$Kypmx)H~WRc{Uzt4f|n$42eQ07*cPO#5Z$Aca)*8wT)f>LJj~%V(dmDX;;q$&C}Jem;(Tsf}oOs^$L)cZnk^{NQD${eG28{r!DS)O=QJg zL(`z@muG7{p~t^XEFI+IJNNFD7?E1?D4YdsNs77yDM!!BKK!;OvG~drlJ$D+kkvrpJyTd`yq9H~ z08MO<8~Hm%{=4Ay?M0?%Kt9CF;Z1f|cSZb~Way>uGFi$}39FsgqS4 z2b+;l)aKJO@IqnEge07>!-;Tb1nxglX=rK=XDd1q%T2(%!kayu8>qaFsi@m|^La^+ zdV0a8KpE|_r8tGJf@LV`pC%d*RChD4s_;)g=#eh^kmG^6pPb0#in%-0LL-ij9ll zZw}=Ng^x2(}xnHMKU}MbW;V z6A2FI%!^4^3jBeX8`aUP4gZPvD|M43yVdXGFiq5IOdEnTT2lFj zI5YA=foVa#<3M6+OYEO`-@0KiM0+>M6#WVo=?T?WXaNoB`-XJ0x*2)jIxRNFOciOQ zQd=$y{(h&h%_MAd4UX2Juk}}7Z@lk9yDLjWq!qc!W`JK#PK)gvDWiMi z3bt5CMusHNxh)LX+p9Z)jK!f(du59|D4VxyK$vyH^6m^sew-Rnn(k@+uynDgR_!{W zHx@_+WkX13U76BhcSd08rxu+w=~$`WfbL*CJ<4C3CmLR#OXh3<6qnbn+<=~%~G z_vE?&5@~>KVq&`(w+l6_`67D#@93m@V*4=V@3YlQ{=L_o(IN+{v!ly?=1e7S-=ZLQ z^Dd1{B3HUpXRP2rZ_$wRPg{+DBRlp&_5!v&&P~N{2~ID>^hto+wXgP>8a)(&c89}o zs3w8c%v{VVD@$0L5;>SiGD}J{-i@p^*Ec zDoZpB8Ap|wJr3s}V|2xg(3q|>f+6je+PIaSB@s;*$PAzzuoi$}vXHSsSJ$n)vs1qc#oVEAMo8K|18VWLAfElG+;lpBF$oM)9w#=!_2o*TJMF#?Hjf zYYD^-M3ed#z@D#52%Y{}#tu4m?om2PU zQ`0v1aoa8It%sov7OSNq_W?bLg-;M zmBBLJZXNr?-|6OV8XEQr6a+qrC?JwNBceJpK-dAL^ z4-s$$IZ=}$>+NdSuF0awOqsA`7W4AlN%xb7y+aMaMAt+R*s^0gX8{c#pR9&C!pw=~ z(GhvZcneC@F;a90+YR-wJOLe+4rI#ev*3@mE)lN9a_kXc&0@Cdjn7xJWpYL>Cm-yN zE|=mJRc<5CB31ihL#&JOqa-uQ9I`V$S$Xc_WT}X;7GeWtBHL6a6MQKiu&jJTr5Uup z3d60_yXVKfEc!Zh*e93yL*PSufQR>7ALcXcYoW8Uv4fU``O$6s8v{z%>$9a*m7?0E zDVkkQKL3Szh14KuWH=nuMh(-z=J#*OyQuYrD6{CGG!p3n7GX=mfcoe|!T9y*;S4I% zYn{AW`AWzN78rUeZCT=0RH9LXYvF!(wluFm2TscxkPo~}2F>u<$#?lU!KcD(g!RP? z`3#i4+0Vr#4XhIGom;$p`lWXE*;5-3qUbYJn=~-Y_A8SPoO_z^fOhGz;XeE9X)EFZ zj(^JY2~k%v-!P#gnAd$i^mhF>7kHaq9=x{{ATXy*inYmrmFf;5^(xcgJXQY8kYXaB z-Jk(fw1|2Dd@%xH=7JlVluiMT%oDPJJ*nF_I$GCW5SpxX(QI&-ciR=YBIp&HNGW_t zp`lfPqh}%vu=_w7Qiw8X@1jlburjpzNSZ%T&Ua^DT$I zn&I3h+9)Zme6)idM8o-IFBd5VbnvrEIl59q1rHpyGui|6_;2__Yy1nA&*pf|&xBc_vcE0ieP5E~PBSOP@q88*70D=Nz}~c^X*j=r zwoUWsB2}~cUzpK)M{lUg1m{=B3*xKoMeq`y5^dd!~~woKs!l1@2pL{8s6 zm}+9NnIEb=MyJik9S*!+(?a4!o2?@;!KLxss004!N*+eWGHR-%)%)y=9~*u62{9Z; zLz5^49YpGWf>+w2^jF^$5%vu#7qTKa;W3p!{dRN6mb; zOt}VZt|?2@@0e|xaddj4TzDu}Hh3pqHc6$|(&!YYWPCi#ML`JWd<0TsjeRN1Yo|A5 zi(YE-qwK4bE_Ng#8&js5LU@Z`usVv>Qs~o6nXD#Fc>H2|KjWG~@llNV1p1y5Z*9iT zRH3;hcCuz%m%7|C7+&3!i&yrOMA>E5bKG)iO=wF&=PwTe4fYFb*(sZU`JLB)uZDmXar3lG9Yd*z@JCTsj?5PXkERCL zvn)Nk5x8tzrajPu5BQkc0<4KnzwbHEC)0`W)t1-|qi|>3e2bLg#rs9fT;JZYuQ2r3 z$MdVCk1;=_hu+;gdyJvlsTdUVHiS`RqujfR+*ag=?a2A+<-G(|!S#0xX#h!c$DT{@ zI~UG`i@jwL-0WzPyZd~im5W)E>%MJbrQL0lzaxqNRIk%*gO+E$xNuWa#=*wqAb!H2 zWDrj%6xv_72$DuGdd&hBeKl$4n$Vy^!OE#Hs9%+gCB5f+gue zsOGDVz4+Yg`7#uTjNP%Q5<;mUO2gGw?Nuvm1MDD}TW!j_K}S_rR}59f?)-D2LPo5#Y0Ff2VW_tGWisyuO{_o+9xLMyC&M)z(>+omg8k` z8{novj0QP&S>tk{H`FxNM=NiS+dH8oPWi{{vk;tG_xHOw(mkMV*Zk)M}I6bRaf${FBxX{4HcM}aBiXx{B%h0IFVgma?l*6Q1Z#+GmKw1 z-^&G8_PvskKBEZzOMd=T_JWp!?t3b<3oBzzLUR=r+UxfAfw?b!; zG&8pI9W|$=A=-yJJe_eZP>gF@mt{m>?^v`UF>dZ74vRpS?Om$BCqw>%_nw>`=`v55&mnt<3FrIVXC;FXHaCUJlJxgsa(j!bP$~S%YnMRcf@+@mU?C{pHM-0LzVzMAjTUM z{ss5Z+=C$;v5VI%0+F4V{lr9 z1(|aC)kDt6si13Z%8w;V8-Pd-nD4Qo)?)KrFZ$#u3^bw9a<^OC9b8wU0nkMdbKI}M zPFA15=`r=m^mTWhRFr~P+5UlnJ+6-YcJjX6>ZeX+T)&cXIxO>_^h5wR7quiqOvVbEGtPI8OMbx?d+zp zPRi;wX0dT7duc9qF6rE+$3W&;Df$`2gSyrg;3HL0)~l`dx||-8x}$7NYok3&J5i7) z4Af$dt+vf%5dCNHG?^dVMJ`I@ZOiba(rcQdfK&O`ouO3hR}$2{ZDvtDrENX{*e(_2 z9Gu{Z7x+)h` zFL{z9aNNqEd^#9b1 zR@T^r+_84(1jFP_;vbKxzBh?aFORhTrf0V9$WQyiR2l>dl2kR|DoUzr77 z9%7JRZHB4heCA8Uu<>s(&s0Q5`%c=HOpx^n`C3$uJIRa&oM)=Y^ChJ}0Eu@~n;SX= ziK%q5!58?Jg>Y^58(=?u=`?GesbZ+pnX*}NK18y@UvV*R%r}swV2qI_yYZJgCKpAP zGM6qYYR#8gcu)H43`(|Oz?URF-RVa2`I9wa?=;ti`!>Qqeb*8JI#|9OcAq>_vA&z> zbHg39wu)*O<{A%PXiSg}+EOh82~<WQYry$3432fY`@vlo3t8?qj|>+h1xtta)L1UMD5_0~l2y!5p`mwIyz)8oniE zAaUW|x-+vr29xJD7nfVjRf5s;#~-)hmk+#q*9D8`v-ttk)qdBjvm@&*U&T#=H8)Iv zrZP&qp+qZ=?86w_;sH;ew%joT)%*ekUp0e_^*w6W5g}YP#~Edk%9arD7?Pp zID^5mIRsD(OzCDcYP;%3`0PG2Qbbj0WqIcI`b^Z0z(J%a&L=Bx2KvXcq_|Y%KX{qi zH*VxfC`p=h@Aw^nRUn@5xvcyvUkgbb^#v;YR6{-E&Y#`8(V;{hrO+!Hxm9_uIA(?< zQ=5osXl>earu4fC6d=Cgyj>osACcSOg}c7_5M5%z+Q0tqFV}#Bz!J-%E*F>&NOZrR zb>6Hp!MAL7IsQx7#9R_aZy5FYFNqG;Kh{tgvl*}4 znpPajl)t^mVa>eC4!j|PI#G8URK%~1?kAm#v?Vl~eM7QVjf^!XG0j~LYrk*jfh&}$ zimvtr&cU`m3jJ?6L+YIuYTTMvzs?iwQPjm%@E|f}8&p67oKMj^N%$#32R$ieAHqJe zDzQDvlEq5qtoDArHKp+`NN8}Alf(ZRqIj3?1K^+u?YaOr^J$`wM&vRRE8VAdicjIz z(ICa4s%~N14(k)PL=J!5Af7n=5LcOHmM1+ED2kkrB#xzWtFZ*hB!n4v>dVQEy|Q(A zLm(>F5u}LD{nl?^!%u}~^u$dGGPJ+KK6*3T^StnA`c$0LW1N7%eTHR7tO3?Asx&%@ zGP-GTCXEHgF#i8)Z$+eZ7P$RyzEY`c|19W>o}Q8$xn5+Ovel$m9=7zdPt$ri4 zws|d)JCENF@Zr4J4W2cF#Ms*I3hRaMIYRZ3x_=y*AZe6%=L=EV{1gNHLSY9 z694q$f~MVrT{j2u{Ir@d;7~w|^zF75K%|w~?%}BR3!m1?o3jfVyRuHp4e{FV$^g|d z2xJAZ>eob$tL#1@T15UP;ONd$t<6XQ5cAuoqPhOUtF@Lu;<Nz$<~&wrLaL?AA1o zgoYW#Hz{(PIx$=Q%`~yEI5l-l8@M_&auVetNUG4Ass^HWVvIQ1ycntNTT1xHBtK0* ztQt`h$UKUfYQe^luWC{TDfu#PW7LTVG6xM;UK&{1E%;DS;L5nVKy3 zg9ZJ#RTd^&sE@t@k8Kv1AK41H%j=I6mpZScHqTOEUxL!fJARhUvpjx362}a|;`6S! zjX}Y#BD(*9p>9 zng8A?1x^0KDB26$;~HbAKUpb5A&n%S&t?13c=h+k)Mxri8+s>fY|fSj4_;WJ&pAs@ zR%+)MkT*<;Xh9MlV^t*~m;n?Ef1drhG%G_Rp>1y1Ai7b3>I4z7Q=-XWX)1g zwZ$D=MDOzFXza>9eSaEf_7jWe@X%(+#el!mrpmRP5lHp6Czb)aM2bt;TW-i?7(dk! zbrLPyF4EgMYTS8gx<&-`{&Hlk4*hDmLg`0U@7Qm-n%jjslqRP>Euub8G5}xDBJG~b zuPm|6BV`=8yG-e)fS@PSvWyxqg_k$cBi3Oiz&UC6RRf}HM&VuCB)3VzAEASnBJ+v8$5xW5NHTT7p;y@qyHO{^VbB9)Rw?m@PuJoGOe2o@4cVo?6cSmi$L!)v z(x`g*s5R!ZghSZB<(_=R(q=wNmcmXTV2fUr0?i7Zk>7lXev{*q9<$vX2Pjj$4vWTY z8~p=B)Cy<`;|48Up>;NOAj~SYMz1R>B_+(2sn9fU5~Ne4aPDb?K*rox!)=9GC7>DS z)2n>xX8c? XGH7S_pVGdu+^{CM!oIrFo^ps$7?6gt%DmIFsuySL5=!%P3oH~H@h zhUZ|=?iKcKbN#l}het&@f6cXg?QO0b$QUa4(=?;F%c=xOmV96W ziaqtd_#nvmU#v@80l}pU4O!o{>0z)LB8TYnN_@5+94wo1Y|u(Z3k;n(5@sl?j*XlK zn(zAUMn=4*r41EPm22ga6l1&jP?d{G9SvKTo{b3p*`B_PL05VxT}G>x#3$V7Y{@{h z`kp#|CUPvsGn$G8v|3FoG^4mPgkoca{D#b3>*`>ckVb_!w5@b?_zg~0ae4J-CR~#T zyaPPhy9Jbk|PKEtTet(rzdOBT0m1r`;7XlRScOT`dkMK zreOuJSVrvl&aQGjb47dEt9Z6P1He_S6|nWIl#K_aAw@>13Pdv&;5J|`jR1uA}Cri z5=HslaQ|i0r5^Ftf5z}Bg1BmDZMNF(t0c~9*XNb~3Zt6Le;RWNN7qA71_~1@o2|Gd=0+KY^++gnTCa&Puuh zHUMp_XVZ5`1Vm5V_McLRU6JaZD;tRMUg^;oMgEcXc59u(dV9(gQ|yX69sQQQypu&Q zz z9?FK#9cuQfAJagnuf7#HtA*2;6jQyL2x!BPL$0}m{;z$NnK61rmMg}LsGlvym^M%z|ow>q+wYVH`cy&NN(6}?Z5P- zg^<}h{UeD_1T^PlXDhryvuRSQ<*qf3_iLXs;*!SzeLNZ%Gs`G>#_B!# zfh|EJ68dUQ;gFc`yG2<8Awn>p`R>V)$Dj9SxdP(HCHQE^N-3xYSQI}w{(NcssA4{; z3^<+(4QhcG*&|X44;5+4qmv1jl{@06@}?b zjuK!mXq(KH1aepK!!v~1B;8}>ZM4McJB-+@Qv zFF;P-P-xnKVDJuQbNjzJ!uIW;@9|yVI|o=&`V}$xofsqDv(-sx|27+{irGp3rbQo> zt(YBVTW1l4<6M$SAgb$*Ev%r(3WiI*CvQEiE z%AXmZt}5*FJm+H&bW5jsG7wKgrR~H@gm7P_iZ4!d9>w6^(a$=9K9a{jbrHy1rQQ>^ zy0HylOQH7ql%nD<5$&Q{X!M9^X29`G%%|4hYo1wnjd5W=6Hn>&rN@70N10Ardj?s} z{Apu2z<1xJ6@>=JA%}tNGi55V#H&X-Jdq;cXqI4Px8Dh3WyOXzlkTJ>r}CxROuS)F z!r5pvh$qLYz7tihNX@*rWC2T@2HUAVJc&j7q``jqU6>zhlZr6dte%MW@K++(m}Kam z;7=28`)Y^k)FzCLZ^zzzL0bLP4(k+qdLdm5@6#`>Y*E3TPL(_lDV?dwguD8WB~4@L z=+29pcb!c*RRFQPuHeZBXWT{=zkkl3`Od;+-ggWKx@E1JItIUlqeJ!Q-K*?&a(6zs z*yHstYN%t2g<;m&X7tF1HIM6S;MCW{>5Ei6Ms(8ZOsd5C1i}0MZa;;#&u-EF|9^nd4_KMsf0Op3gkgaw*h<`bHF+vlXe==M z5z$IiL(-8bJvximDN<(1qk#XJ^TS+|XOp4kQ~;H0w68+c;o`iAWV8h#oWpid+1|!2 zd0rOHvNik0g*W_s!>KrId||kh)LG!%jxcY1%Iwf;4#i4%LHUj38x57CJB@25As<;y zsZ$2wDO_n96;eLVoPt>%3n5mtNtUuaQ{Vp#HlyWBu4aKD8m^(pXKuvqb@-3hqK|zwv_pa&Row{5$l_t)pf@K+CdSEM}bL_n! zy!duju#*ztu(>{V_9^kQwU>MAcKY&3f~I#X^~e4Nv^2>W1_6o`JlO>%5Up^w$lf0A zU7L`a$^gz@JVn$?ew&#RD(*{Ojsm6F&3P{m|J~RBTUm@<-}JibXQ48)BHs1Fg6K_1 zDWNZWZ{hhsXu>@V%_~dvO=-fdoVJRtAdk(MN#Eu&g*(Xo+E{XN4tOJtti=eg>X_(~ zAMP|tW(K&i%)qRr@~GUl9VWW^eNdM6i&aIYaRU}qk041T?-~5&h&Tq_0iDnmB2*4* zpU&Un96)&nOO?07D#gG~tSWYgwTc+FF~&t5uCF!#G|g0bdxAW-+gYSN;j}TM&O#pf z$?^g%vYVEnB#y!0iMjzJ1Tv45w}DkUq6?&%-h?IUgQgCBb%r+Fe}u7!$9c`Y&`!us zi7I}D7XB*!n17fbVZgLAmBrc4Cwz>HDNa`Ux1f>@$B`g~YuITQ=H&D3kYv-vpew~H zqSy<&t~%${>1jfF4!Ul)kv0pN4k3i)2w?lmPpmTSiwcwRDlLHF|GWTLCK8QA=zp-U z{1=X280y!lD;J>CN!7Yaou7?UPz^w`On?>`1Pf-ZA5sroQZ2Zbu{Be>6O~1q@R{x$ zDtU1JGjs0lpRwbU#bCWel;SFdGJ5-N?H@Iv+`C7T2k-v}M?tv0DwE1Xgtkf018ut? zdU-$$FPHW^@c$_(u}Q(yN{5nUu1pD^B}inMNS!N${GEAUnK}zM@!T!Eb}w<1ge`Li za6h0#OReuv14Hm`#4RjB^+;mLiit!N4=I817{YmIR{}$>1{SGCLgoZH8<^QelS*jT z-p!G9&7OCHRwSZU(uq-+(gkp!eDubzG&@je#3g%Gk5iy8h5yK?2uM>>Yf(#0FQ4ABYOlvs_ z4`j7O3!A86pooPcCK7C9J%bI>L}#}X3}skqrqvRPu_V7iF<0{`g2BwSH8Y#2EZl3? zV6#DGP_dlmMA*z=i{kkM&J7|!MzA3;qG3i&u2-ko2$)jbXGs|}$6DZ=U^_??#r=w9 z71PdV#}yODr{mL&IXNL*%m&hWs-ws~*+0(`IAGc@6>pv0Ct*cNINSk;7(0(DAE3~e{g{~TE*vyCCF?(G+ z|I^FwZvO0bFTMHO?scb=?;phj%?TlYkrbX33n^@)rz}-e(@4b{dR0gyP_3gv1Pg}5 z&^k&ISlH!JNaPROxjO45)XEA`04q;wGiy)b>7;8TZt(yOGN>C~+YZ`kHP=%{N7h{^ z7Sfb1YUFSYRw505scA2zUDRU9H54Y;>r?fUfCD9e3`Ou2a)2w$BdQVz6>y6khpIFd zi3nmfTvI|(7a`Ae8>pAv2QR!=n<~KldZ@g%Vw1r%qkx1{Qv{d{>ftW5m3lpfk;Fv! zjJQpez+pBJwn|sU5C%e!nFqNT>BH>a3M((F-mIY)(tELbHq)iH%rYf}va4?;BaD1M zBcy!>BQVpfMBYeRnZj{KDTQ$}1NsS63vnu)EGJd3LU>M623?_?BqBTop>VYmB=Q2% zQ<=u9q_z$SN2x(*DlM{?^J$%Z)+?pkLG8McKUEi3lQnh<%P+%OHZgBFrOkAltD2Ro zfm4JCZ8`8!8cJ6=`o&5_#zVBY2PF)KhSwun*Kd`D~^LY+3f6m~xtvGVd%5ob$^R zd?$A74o#__Ng+(+kAK&^+c2M7JoLI1E#x4A=noWIsHuQRE7sRe0W&r)m}Zu}ZX&?i ziIA*B200g9_DEkI7L#`f^700QT$t>PeVC|wR4%Cm(s`kzuCjDd?yuL;J9sWIaEwY~ z@SqqkpATui@Ep&JqDK~;AZDa6CwoI;IJ`WZ4?Kzt_K0C-5k0+x49cv(xOqP3PN&{4 z$80%v%P}0sat)8cFc6d5%qKYjd#!#%W5O-3< z9ub46GALv)ViUnAohpMm^76%kVSr^G(78>t0U4Bz=Gom83mGQ5UNBNSPd$SzZK89` z3@XNA>3nkyFqo1-U^AH+lm+}m1}#PY46vQnOLUefs>Sobf@TvnjF{5uDK11zNqi|- z(=cbMmuLqVHPuTrOR??o>G*Vf`Y5NvgitP1W?#1YV#S{r<_#F;)#7@r=Ge-PlR;Ao z+qou3=}cjpDk)?KA?5W@2{mL!(x}90p!U&tu1aCtWEDyxjd#186fUxv!ujklDb(_M zwU1uksWn0?DP)KE+3_*5S{8Sdv-`x$_dA$34~RQEBZZ4d3g@#giT8h5d=1&*epP&b zUmI_Kl=l2AWXIe*q1$hy!2UbpZBM~!-uK7HOD%;I*#B63%#SN6)LM$!3*z&BIX>>i zMhcsk$DQ&kI+-in*SW$!I@q7R?nCd``_n6bcio%kuf5G*J>r4q{$Ap%#g1|+6kc9` zRTZq7LT#eq^2x%|MRhB(jzU!oVILK;H!|WUw>deqY718Zbw#uYJ|8GEhiQ@^1mk&X)V8^Uf{A<&@0O0*{3 z5e#KXcnqbfVD%gYFS*}bDRf3q<`Q-8h2#>UIBSfChx%x?(7v722w@3ZXr+qnJMg*%WnfX9e$@qz2uGsZt`hX%g_$-dQ=&PbyX-k+f3M(ke=l6`^PI zT}ag=vGp1aD4b$pCFycC%~ea{Q&T0%x3(b^9 zuki?8wP7SM1NEg5IFjHU1k6mGz?QI*T0jl$f3CpQNjc_c$KvwzxmEsmQl(Npj~YQS z`WctK;1efERJd?HB#W+Ym01rb(oao|E1{O*djK_wN-+P9^` zaxa8!a2vNYpKl7`DNhnD)GjKu5;89skD-?y8IRHP*WKo?O>tDfowKC7=vm z*9(u~c6>TM9iMLGDJg?{@ykPn@D5@fWr00cUP}97Vr9l8{49C2aitI|JY4Y^YqyN; z1Xi#^P(la`K_Z2w68cPGYo(^563RC1KnmN14l|2&A?~D_o3>(U*q>=nVJqeJmOd&o zh1bRB+`gUfNsRLKal6aGeDAKdO4cYT?9xo3Byh=&RDAbe7=P{;$M^6h@v&bPU+0m! z1D?;mHeP>Je9do+=Z`ZBhmb-ku$L%kwU2(ESw5sUD3ZcO^Wz5=HuJMc5tC?XNg$P| zX*p2*c6?quaP0j)Na1Tg__jz2-*erYWib7_9=-XVi|48j%Sz{fRrGjN`t{P7hntJ@0dbX zn7YXX&eFqeXc^tf6H-@Gt%0hjAP%Yb(YEO*sekqvfY6Uikipt3J<>d-y>>681!O-@ zhxPfzvCTkEbv7^{$OLL22{r!KBzUZX(2yV{3biX-Uef_JSN}Ic>A&MqByZVe62l%z zrEf%PC4S2`0h^tr|?peLUR z>}?h8pZpyw1U;2b43i=^u#CEjT4IKg|2rx5bG^)xhvjdE?-Pk3$!0#A%(*@;6nRig zHlvt`pY6Bu9>Ba*KEJJB7@tVsT1XWVLiW^c!CD^J@a6M3&#u4{6%!7yZzhiQA z*gl&3YT8K|EW^uG7LV!{R%R53xs2AwS&KNB|5?=uV$v4mlY zCt^h9aljmp5)5Kkq;f`KWzfiAqspLSAM0wqUNDhiqvkp+pj+v@ zbUp9u0{hK@t*%k51v1zrGPtSOET0*iqhp$6Fk-s{D1*R!OcPxJCUlIL;YP`&$Pz`p zUc$tPg6sfCU96ds`z z$`0@L2imQpt73P7fBtUqb>oh*xo5op-rd4TVZ8kTodwOv4pvs(Wc4kQ!kO%V|AUgk z`Rq|TQz%`9^V#F$W4|qKPu2v|dGj@6>N=EZm3`oid-f`v4a!AmDKaa0R%FVhlw zrZx+yDuZ=_bCk}5D6*{HtfiV*%3dY!Har7cs1w1lD1wEalLSigsLl}v3#&O>un4$J zc2bZ?Bal`z!RM|aw8m|xbw7brONwDBI-jY2=b;LoM?|@RlQpE1Zosaz83EWP?5LZo zX7|+ls4$imrLGDc)IcVT8i6zdwuQO~z08?IzE&AB5NVdtEw_AD`X07m>)RUBE=tQN zRF-j8ZNZ?Jd?s->5RSs<@2sS`K21P{y>p7d6judlwFCiV zwML$nDx}SSx3P6D5_E5sN!8gN(Q;e6vgOIAw1z^Vlu8c$%<&kryPEBiHbI;5tC9jZ zNtVbR%$aUhDI6uKPGxWQa~HFvtYFxzSWf{9EoSRzXWbt0b(4iriPaL4Hzb0?^WJT^ z%>G9yh$oTZXGi6iiv#Qd^uPNk{hd>&OqmGyI3>C2j3X6Is(n@Pc}Ir8^y?#%ZPn{C zNF=k*_)y>riCkqNQX8)PCGzQAm;SREWE1@VcpW4#EofB98k)WCTA2v)rvLoP7DO^4 zIP4TO#jkLCD6czFBoWLAp(u||!X$XBDxmlUoAqOfd~He1>lH~^HAw#~oE&n&&Gy-L znMBYOIuJ%7f<@UUg(1~OP-Q$%GDk%*Qvx|Fc$5;D-lQv&@9MPmSeRXvs;@Nlwi85|v}V9{U&CS1b#} zsFjeE^5%yS9`iKA5P~JNR^sukbqq>=!K1JsEg0mHz$9NH7^Txu7jZYaGALN)-hyou z<3y~ZISNV!o9hp}XVA#tA!Sf|1_e{402#qtioGoCZwr`g9T<%PGFC5fh4q|m>mW9mByra;S zLM4NHybPt#zQnD@1JAUhu$$XVVW;&JvI?Xfg%kCV&zn{F$xoQSyg|^6*+;Q+aiuVB zvIE-Gh+|2%+Mn&V`>CfeK40RHWmQWnDOw4dS@cO^tFg+uLljad-8&4Lxu>nBNqK$q z@8j+FkB|NQc>dtdNa4e52i!a|ZeQ7H`RnW(;`w9Z{c(paJMKmjNS_>E*GS=9Nul%y zJ)>J_*o+(ielp(ny!aTcrD!#QRObp`7VrPfPG=2t0R0c*_Q&zy^7;?$&)#(9Jpkvp;{B^daruO+g&>7hfq6nDfR~jR8X>%Fk=dF~DgiWh&=c#6*}i~szk7~*+K-%Sd9hBi8d!;Fo!O2lh3N7%aQqt^Xl=mU+a)Y+XDr7YaHPkc`F(a=R(1U2< zELEDZ8?i#7OhnTO1<2M)DvoDyyAjgbl%$fgVWo%e$Xr{l268r!%I9>FNa^khNvhqa zzZ*)``I_78(;F|F?+hCJBJXE2WcFg6Q_DW%QM$ZSTLP#i;wnL@d#R!P+mMu!=r|D! zAz2yu8emiQ-b;R- z&+2{LTbcehIU~1OC(H2`tiQ=#%9+9{_4ftZzN;&_OZw<}ULv!M{d`riJvy!}h17vVW1kWtFe!5&r21x*YRxs}tM3SglL}iZuo_9R) z{@1?rW^a{avK*V`7~NWU%pb_H+m7MQZ`v_kgXFAMA|CVg*e@6$VgbVhvu6M!{3k3V zf0tp1=36^kX#OU_7{D4RoNq`5AJ!Qed@!)e{RO)ShQZ9>Jr&!`H9+Pw4nPK5R7*G+ zT%dH`YP@dIT7rA(8H^Z9vDRFaLB(F1z+$cp3RY_u=o++2F`XGic#I^>uNvl4o9Lvq zG*QEbbA-n%XcKKHEM&^yUeV467}Um>23>=D8ICEU!=UmvndW1*P@QX z2X|8fDQu-SPpET+xzw+PqMiD}eHF-(M{Sh|_R&3f%Nq-tnL{bGc|ubPb;r|a9fc`{ zd)s1N=)9+JmU;^3TAV67wp$)#>7()dy0~-u)Og<=;(a<(7+*&^c;XJT`K)+;&-n8` zC*J?>oD?pa&yU-K<6|EZe|98=vxj$9`YNk*Uu}`k+Ew^X@wU`exM(C5?5Xjw-`h!n z{i1nBy!}TH=FPL??LQH(TiDEe_QH5s!e(T)K+?y4BVLyQbSbg_{didh)5Svi#w+i; z-J9R>+FSqi*M0H1_idaAAJJ-xaiN4zH?xdh)|tSHwG_RY3MYh05aoKX8N#z8QxvHP z3K2Z3bAmx<17LZlg0_jT;-&b1aOCh4v(2mpdPv<6t*)Yg^Chr7EmF45m=un5js;j zNfZmH5W(%795SgC;C*|PETU=|JyG}6M1piz$Y|}GaE>v!nwK7LAbO+9?0NazQ)Mch zD@7U6^fXkagW~>O&Mpce%q*!%MYEa0q)cL_QRh1Y>LL=Maf{`IuU%#D!G16ABRr9k zLm3dmq)U6fTIc?p*iMqAbvNsQRMiYNV<(SZBM~sCn9bY4?x^HBlEQ5k)2}3Q$;WQ^ zY+LQN#zg)ywQoSG@@Y%p-%ilRC zvb~PJjKmGYYi{hel<-z0cNOOR(mbq@_5R~&=iNeh)#iW*stuaTC~F-!qsZ`@kOjh2 znIc)1UL$cRF*Lhhe{Pu*N?K0KL#d*y-60_~M?@CdRfSXD zNy~Z%^wBa!l;o0InTVkW%4Fnl85v~pyw3!NaEJ`v(5&E@CAa1CgE<+L^Nc8FW%GJG z)uQ>0mFgp3_mK1Nd;1^X`mg0!EXQOyHscsA;~u|-Y* ziUBN1^cji`<{BRJRK*Oal~62U?xRNoV|=w>4#6IVK@^KTM6iiq6p}&1F0;=uETfp_ zZh~<-tKYg_u}{Q6f`x#Iu2qZ_u~J86(0c}F-ZN;UI(yry3|ffHIu`2B5vQ5E%K~H+ z%c%ow&y>MAl);714USMVL5parmJp{IGb-E;+6#_xEGpQv?S~=yc6>TM9iRRWPf2c{ zMItEMo^I%MaWaT57|s$FNPgmq4oKmQK{KqSz^V{KW^_}fQ2pf#>niLP>?lO?D0>RU zny_fpJ{oV60#s89&B_2$IJ>43rEo4vq3+;rdB{Gxn8^FErCyiUUg^{keGi3*v1OHuIv^2G8Yy@(Roq{@3{a{xCjI=L#>q zt9kQ3{^hlQ@r)-<-*wGe-AUZ_RdpnVGFMm{DLf^XQcETkB~S+8Z5UpwD=;${%uZ^v zgb15a5{Lv+C5MGtN6(<_UR1?1MQIyIq^OAJT}e!p6;^Iv=(#A2=d{$`I;e~Q7Tz0W zy@rLZET6^sc}bW<%AAlzu{x>UsV-1IQ9uzi61WDXPnAblOwSb{g8@KB6~AETAdf-_ zH_$n_0W0VReuh5QD=$*v{RRl&CT*rr5Y+|>qPjUs3Zy6no9sA*61kmiDRHn&M60nIqI~CA$t%**`B+4`P1X1oMoeY=gyes8Vuv@6h8%rOz&UI_3)I3t<;kTVvUu zr_%WTlA#|GoRSsL^Jnn))qorZ*`#e}#N^FnFSIHJOZ)WBL|R!ZhPlvkXtQ*AodLsg z+_E?+y;pIUN+-y<**MW#S)!%@z+3(geAaNBeXe68e4DN?(OyVPXh=VEg3kbUQ41Fd zAd;n*(VJprufvJ}t4u&(3^omT5#`dar~7Vj3)ySnJ?s09-+8H|*d1l08Nb&$NXHgc zDJQ#7Iy2j?{|}AJWSNEP#+ryNq^a^fZ~hB!R0usBhIKK)0;e`Z{&;(D-oaSmd&1wz zodm&W4-t#rxR`&B#NQ}??amG1hvw+!U2FKX#{i=v{Us%IjU|qmEkHxYA zR{WBR9qjqREc;?Fm2^=J`>HVOJ+giAS*mv->mF2f5clc)V1J)(`}GoAp{n1~txV@m z`1JU*d^?Nt(?@K>`+CR3>~eOz)WUgLRFz}w)#s{Cj=6H|z4Y!z=LO}MEXQU!M(eS9 zA>lE4?3QEri{zNzS(50_>9O9DM4zJ=K(K&x3`T4q7(uXtU9K!2xd|2GP{Rj8NoFBy5M~mV4XV%_8Hnl4I^n%`^^oKHT_KBf?Q42`;LI^`f2&;qnUL=HO zAI*k`$J|K_X9^EkNujGv%^7;rdrG0CkEWTzX^TpVHk&Domv7e1_u`Ij@0P6u&CHwI znnj|yF79kTHSSbpwe0$MyQGiGj`K6)>&U8FB!!LaSpQu-zi)ip=f!g=ca1yXChmw2 zcNNB;pFm6wew@I|Lq>BA`y#1#;nJKVA^Iwej z$${i0oeZK&*vw+~yYY4*g|Ci}l@j|m#LwqVSKi(H`OALhn*BT7YVv^-@!&NnoCJ!U zR4Xd9rb5z5dEgUkC>2ChPn;0~IL;Kps=(@LJa7g-cWpjKkwfL>dwCcjGq^a<} z^s@U+)L97dF*3-?3nZM@W|7)pNDYXfk-pL|`wSw9A(TZ{M^HK3Mq24scALJ3%3jy2 zDOk%u(&*}9NJ=6DZt~k#svZ%vnZ^P{v(RmO1fsfv1XB=El0G3ETk&&~jYN$BHVjwU zhD~uhv(p*amEJQ8;vo3d*#63XE_)icK}4Bks_(1r6GOXP*p?G5A%QEH4_r+|V-xiN zrlu77zT}()hjWM1_Q4`%#t6e@FXYQ4%2USCSv`c(YgHwLrj)D6$W(NV9?&adI+OB*MBetQx>)qr|Hq zAu9a$B7rgTUfAzhfvBqjR+w$H$jDCq*czAhZ)&$mTIfz~pP8p|%KIxY$5|GBzKpbO zEV*sjeH+>NvgfQ9sauris$TnZf~RtB;9It_z5oCq07*naRK4VN4XW;C|EF34Y2C*1bS$z(zsOL%Y#NwHyD2s(u?3i9Bfqh=Cz?mWkt8tx3 z=o%Ny@LFc;%t>89z*m8kXOP0m_LJv(5a%F}!4Cu(*uTjLUbt#pDAo|LJS?<(MnSUO5KKu~?4Da%|RP zv<1VxT#nsx43}fM9Me0S7yRkY(#9oV?wN`KthZP&!Bc<{p43@*%r^^$Ff6gRykjt8 z5WymfNer9Z7g$9CWbOeB^O=Ha1ltJ45v-$_2V@Xf=r)3l3?t2M)|(mh02y6$$IPJC zfF)&+Sr1kjrpn;KvYEj-l|ikQPz=~v#zd{yFvE(#j-mC`(7bDKmiG?!uxYzEu9rAI z9iRTiPQx!*B77HV5p~%`a8wf zy>q@4N0zZ+^us|Hs4cclIA5xw|yRjKir?0%rQhJ#y9BF~Q z%@>YPW{>b0D2l2E%DkZvNg;(=Pa(unRYX$*&pP=lvr>DK!VhBW^fhEMYAzT`k=3lv3J9MJX&m1VMx_o2VN|D2X5~qpBjpx;UH*oZ`Bro|Zm) z=mc*CGldhgu5QAl8S-mmtK*Zcqf{hhj>r=G6eL-nxtuJ>KvTJKtw$~xs3 z^4Ss)6hoSQrM#yI0FM!tZpc7>F18JmrJr?_HCFxyFIs(??xq|!j^3d z^OVhll_{!0=Li9y7|gLNEdxPiPFcPQu#rnCgMll0uFS@%yl`7TPY41U)p@eA-zmM8 z0BBkW7_y9#K#%;M+3+P;wqOQ~brE48U{N2hiv&fmxQZPC%W9lr(qebrmwsl3Knng! z{cPzt#sbP`#~k0dN`GtHB6p?Vu>#z(G^TAVpKn{v4?FVrp#kmYGAv+h6oM^8D0`>w zp)~tksDv{~*>~jF0DTJPw%oo-IJaazFnvezUW+nCL4+i=r@28nC*hoEvQ4mp1Fqq1zFHbo8FJ}{i?Elj@ets2!hld8X3@< zV(~=^{A54uo+0!zfj2fsxWd~JdE62Gd6nZNG|2SG1_oRVVdvfo~FJCJr4Cc(;N(zYFi0kVE8MF!5;~6_PTWL!UQn39M!+D)O1Pd-dPQ~= z6Q++Mk+IfoKIM?!Hk;B zG?0#p(F{umWVTRd3I!BOcs&C{a;kz9f!s$$uTJ6h9m4BpFq>(%=d=2NNE;v_J*g%A z`{dMk%+um+IN`B;bV?G5bGt+JB;MY{pDz$81%bl2T@r6YECtC&<9oPceB2Lrh^63= z*L$)9DKUljkJn%d*=%N3|783*g2Lvf<9(0mIKcji@#m++4WRHBJP-?^x^Lyn&QjNHDCYB z^FH8dh(J_KFe^@f}$8#CJ=riy`gRq`~!NN=lNERw=B1KU^0vca?YnhE_wnR3nAdpwI zOWq$a8%U2AIVk}_$0RB^v?fV5b<9(f1p;@{ESh9g9ZUxy0Z0Rp0t!WTx@|0AA=!l? z0YCwe+H~>lg)oM?u{&vE5*a`p=;a{p9OGr7JqA(0p_is+Qc`t8Rf($G6nrUg+fiAk zJZD@ca~;ZTGcX~*18iqi2)HW~sNLrP;8KyKv4h}%pfWE44wqHV${_H7uxe_eLg1xH z%{wzyWs;gIBWS>enKuT3CC^^&OET4MnGNH7wItT4SFnJXQZ5}nZl z#wwGol)X)0o`90vc0e-sR6@+mUtvrsZ^{Oi_8JOU{b%V*I~BBTyZd3d;-#Hqf4jSF zT$Kq73Ygo;zKg{6Z4VLyxMP3+!GS;qXf_5~ z#-he7r5eJhTe7Gk3TE8={W>4W@_C-^V~1ur-^$D&2g-Bkyvjp$Awn zRYk^np+WNL+`i!#>g=2!GA7V(Y*<#Yx7EnK5L&xLk{l9H5ZG>s3}@ zGliXiLa{Gi;ngU~DHKrHl6;gxQL&1J)hwLMAayt??yJ!ZR=>_@Ig;Y+mS+m%iBaUE z6w2C&(M)qIwq~XP`%627xe`+tPrRJ#gH<`K&T%Zo3@%^I1LN^8i}&FK4zn4!f&Ekm zcd%LW*mz=nLcB&S1qQ}Z2w*nz?3U&V;XvB_M%;hVeAc|IWwV*rv^-b%#(3dcH zVMh{D1l?LR#fQIp?c`(Mo7Gnz{h#N5{B1A0$@Es|?)%QMEO&t%^f2ZNSBDG;2?SDR zVIhI`QW&{7(p=$+0zSwOXur|m74V9I;82WamYDrx5Xk^=OJt?g=v1lkp(aQgpTr6#mTx5c z%HnCPh30LkyD42S>rA2;)ksz$K;iaM*v%+{C0geD6JRV1IPQqs>9z-oOQlIo&3HyZ zBFz|j8EJ4%q?Jik>3YbrKV|S#o@(x;`WlWw)cL?I1rIX2rp+@q&}9Na!iw_iGw9-D z6&VAla@GSwWdhyjGV>Y%8`8vYm-^a;Fl-_XtsFBo6u`1n2#Z(AXG_eag3|+#v&u2I z6_Awtc~y?8PNoM$PJ8@-S+i|oS&E|?y3P_r4@OG?MU`8R^JrKB4=p3HAJpzRTxLw%OvC0$08P%koOA6$Iu&%)zD@O)gb+%DH*OCDF zrP9FvPWD*^RLhKD2G~kv_0ndHUzuhucVt#`7aJ(x&;VbVWSJV)uD{0}eOxIE7Xq{l z&sCp(*m_f}~ z9oynmp5eD4Kr=ap28)qUr%!ti!r%dH(fp!g0rh-{+W-RfJgdr$&EBSLps|1k{$vv% zsE@V9KdB3=@;-3>$08u@%i^L3b6P{vevlfIM@96*<$J84g1@6H`E>$=WjGAu7}U;- z&)N5#x4rZxQ`A({R@7M3TB^CR_M!%N94YZ`)Ml#D$QP7(LDX=n<*}xtwxh;Vt*4sb zJOe!d^#ZXcklx_2)GNfEfqRGgC(%n#Pcfw&UEzJxzx1ipJM`SQFc&_w5P)prZdZN?NBXy*zqJ{Jm(L+%$#WRCga39G6e99RV zFxUwg>?~)nk(@zx6YZqOQ@N<`0htlx9&yf2^%iHQEMY#PR7>xfdQsgLm&Ijq`Tyb4 zW`Gc2aAK=7Ejc{(>3ji+Q+lif*-N;nn9O9La8}z)p~^?uXr?|!OlGj+1R28qZrU(Y zIAe=rtX6fbXWx=RXE>1JL`I-6ZV?m`Q+SgO^3kb*!m}j6{@nQ3NxTMAcs@CBQDAFx zv4BF7kG7a8oHci7kyXg6atM9BM|}Nz#pl8D`F`>EKNfGlYz~RXbOJXpoY;RVUO%eC zOu)4Mx%hZCo0-+W5O2d=;j`jKbA?nmWUeqi?v*X%CbQazMFpb!S`JMdIWQaCCL8p8nJ~u7qP;#g-7@Ee4*NEGh@gM zB7wbC#|8oj>IN{lDzk(dcCQjsNKRLr6v&&;uz5i+Ath`@Q7ql z#ombBL{E~1bo5RKT8{TZPqjro7BPbjyNP0ihn(OkChR!w(HfZ<^fFNcfjJoD{!d~h zh$tx0D^kyxNQK~g%hudPYw1B3?BL?ExcrM;GL~?vV37YgZ{UB_WHOVSN0UR;tY!=0 zDbEykDWi}B>`h7lqZwfe1r&B1M?s*lHKQ2yl9~-yF$LBvOZYT&CB!7C`o=Ko^ zR=W`U<|W;ff@@#Zvi#%?-Hft~kZJVJ_*l*>JT!sLH9+A9u!8xW&rPm8`jvy%eCu(EMaLfQrnaf1Td?_c~l-ljAC#_S_^gv zsc09$R&z}fWFRn@G;~t{AZ}YL)l@)cP6Pxp5EL2d5{KUN&kO{0zHn2Rzmb!Ls>7+8 z&=^Bl1z`$>g%k;@<`v>K$HLla#KpGTb_5WTL{)*J%^VhHEW_+yY2eYzL75ROQ|yHT zMw>%Sj3LQMm-RRb3_}7|`w}?Y$v|K(4?Q4k+yN&G-BD&lSU5Db<3eS3;(RFcXqqXP zz+3{B$IHGkNX7;x21;4M69lO3s0*q}SqG)XGmH&TG4LWes?6^Z5UCQl)c6nYoN98@ zC6NQ`F%{f886>fP!({xjBh08uCvAo+1P)6dls1!izyU@JDL2L}fv0RnQh_l&rm!fE z1SXl?Qn@CxUJeA6m6^jB%VwZTWtJ*kECp<)*QRKNP?}pQv4$S3Rqpra*xj8$VqQ%e z>gMjeNlOmcasZeC!hdorvpK>8GjnP;Q`}VfR-|G1bzqp?@nZ*DjTm# zGl>}qQ#TR@&_H477(r$9x&QRG_$RK(I8x zx~ZTr1ObnQsUXxXbR>?=98%Alf-gPyDeyB{zk)=QfEK%NEAstJAyUeGxfzg!q$(+S zL6MXr4iF}pXmYwHAXx0p4*KYb6@ILOKo1gWi#3fTqNtIlj|bgzpRn`gZ+&+1m#Cqr zrNRn+fNCsiEoyG8y{N&c#T|vs)4U)_M7d@+E^I#5bYAd%Ce?bX`Q#+}B<=;^Buc%( zBhf2#Y94clVb_YPaA)Y?57I)$RM^cANOP z+s4;Iz7O2IFvyJ%Se`4KiP_Ad`T;aoIBPHn{-0a8gv}rYX?`Z&{ zv=;J_8HLzCN9GCv3K3X~*@KtI=ODYtjo&**Q%q~fR^A^sl90yt@ZkssuRQ#v z=IW!@9sKw^UU8G@9d3EtxAp~cAw7y&LNI|VJVywFnIj4Y!5~V|JxfU?mcm#;HJvFX zw!+V9I6z1&p)!SKNNk`Q&J5VmH02Z~7g8@RH6S=ha#A&x*;*D*C~Tktz%6TdlpRzs z$n%97Tai}BLu!aZAz(0wt7%A473xq*E~SO-8#_o~uuKf3<|8g8Fv)p`${;#WxK9CN z0+$w1u`ij=>}C=f93JQc$fa;Jp9xgvLqL%{-p>c>T$CD*B-SjsEAB}1oaPQ$5(=s6 zjs9x^MO0G)wtInK5_z8dIQJjAd_pI3jk4p0&RE|OUd z{p}RhE=JEJqCsD~$mRf5=DFuqBw(nyKCZbFmWXP;V64qlqo?En@Zy&91z*7Pg7tHxw*Mm4`dIU+_QxK8dx7R> zq&IjN^$M|Ppxz<&5a=bOr?{u|7%PUu)ddNOR4i=MT+#Nf% zdcJE*ZeO)Ikalnbo7G}AL#uw5$Dc7M9zkLKn7BPIKIVz>`YAF?0J9m)7CbxN{wwhs zGY7vBZ%2szOXGWZW!zp9_g@$9r@TV3w?;I@d%HsvP4UO^{Qwkx@Y|o8{Ka<=WdGHJ z*IfI-n|SH3w_rVz=e;3za>j=h9rEn$55S>81cZpHt|w zvNlC7>hH5n?o*kS##Hd^p@P7IK%xG;Ewh3gTaip5%zqA`YE?wX{ka9K@kXJT-OEmGiM?^8nV zmy`ihNu|UOC@V>zs_GfvD6mTm86I=IF>1j~bCUT=+7bX&7FR(r|1K2x?FbkeWgw~) za3nvIe6^BTgM#8HR2rH-t4cykIbP8-xGA!kPMz_z_dE#M?||bLiXI!7X5l=Wx-Bz& zyCkC-SahzSy}!d`+7b+u;kE7WT)uw-T^bvqf5Sy$1NC>dt=BRm3}#tl8+;Um&-&BZ zS!D=~4J`E>P#91n$Iu?A)Z9pugcb=zZi}K|Oa2FSE>D4`kHoR}8Itjg4|G=$s4+P- zD`-H_FTOE*xM?!^bk3xC@1Qf_&J4`tqU9cpU;=Q&8oGr*1%uvMdRLBMPac|?#`L73 zH!2e?Qr_;KU@&kT6Tsl;m~aDXBWh#>gD{S{3bhk86t$FU>LHSdz8AHYYA$LoYH+N@ zRFhGgQKM%RHV=vDuSpGmHr4c4+fn1G)^p8&9C`rs0@M?*ljuXKSD0z61UreMr$BFk z9)o%fGPt7!=}V~>K~xs?Ch$I>ahIE;cR>$By$qN^>TPJ@`^=VNCF)ZpTH@p`NkorF zuf#o5Gn%u~O2A+(V32yP73sY&!Xr{qiI!lAXeJZwrV=`DeV)ifXDkzC09YrPsPv1< z5K2!enb@i4TmZqvWpVjebeTJw-=njeyZwtCQ`o;&eK^k&c4{593XQ2!fGB)#xHa;$|QOg6%-Dx{q=bLTk}JRrl?;LkNN6&{n~i_#`u^w z$NS$N_utu>3u%M7LUkeiNGxt2i=go8_}ZU*$umy)(k;$j{w`)E_NfbL1b<{OQ}H#) zNonSycU_oEn`IJe0p2f+pk)-Q$;?1vDqv1SV6Y@mNO2Xi+RQ9sVe^F>BJCteDS+T! zn+v&TFqlH?^|oEWPc~)#Y(7Tkf=Zb$gd?fUBaR%yH&RLH63;H09lOmR2D@KfMimI| zI1tI#9t`%jeWAzpl{SZ$*u!*xaxP8V*fVDKTy-jCXH<=hNKA#W9ECH=5a!H`Uc``v z4Q!IDDZQ3CGIH+Rj(ZO~!XnbPPiOv8Bm^3DV^? zoHPZLY?nEcma^^?*ztBi*iM_j6hM;Xq4M46ETOTLUQ(LCtja0J`aM}ZLuoAIxE$E= z@VPcEhf!pnj%iDut+Mx%^80d-XgPoK*%;K7mI0{7Ee1wQo(&`xEyyBCCJW73Hp}o+ z02ju!3$jkQ!4x6951p07*naRGdc#!4}IbY(9h(1!R)YG(TvsZ_-h)b|uR_ zg$dk1WQ1IkOtkFf4fX)v?rg!3JBTVv*aL*QMATi&eEfb3nP=k|)IJ2w-~7zw@4ooy zCwwW^%1@$3qE=o{krFh1@u#SzsHs$2xyHVoYi{#Ksllklub|o-YqZqr=S%H=R!3p; zG%pAvxhJF6OU-{YdI0JLVo$*Hg7t&ZE1+jU?|>enGbhpJF6c4PYsfi=Zc= z-X!)Y)TU?Kb23E&6zC*tpyZfb*&YnnU=B&8#0^e5KA$u zFNx1JvzfRwy=6dKZPT@l1`Ap&xVt+Ain|4Ohu~hpin}`mcWI#|SfMz@U5h)#rFii# z*Zq9&@BMrBoU_)kX4Z-s!G;^6?{LV1fPoug>mLh!HlFQ>HwSlIC2841aI->#d!@W1 zE(eK1i&kq|!YOg%`EPf}Kh%hcRz|E=RES)B5f`N?Hu{8N|oO$%*q zXcsmb(o&IvZG~PAz3r4C8M9BJw-L$UdB-ypr&_6#!n#*ovVSjv}$2#oI{m z?fhq5sSU%Pjm{Ye)*vSEL&X$-@W@H4ujHr%VWg}L$NP0KwpnVcIv%lxeIcgsxvutX zOKqxxU@Y(Lct|%RbA!%im6W1A8D*SO&3322FGU*VvVf83_^Fq z$d6QGWin@l?h=Vqr|os`Q6}_Y4?BJ^A#K>nB0&B!jrq_K|CJ$Q+?(3_qd~qMF3SNQ zK$PJ&jzSD=+l$quqF-IN(e);~i;z48!S#Vd`M2X(E~1^?O?C{NzY7(y@*-Ni*jPG) z8a?~#F;AeJ?6zIF6g{@T-N_O?if!ZJ?juCf&*y057$=R~@f3Lpxq7iBXUdu$FWHvz z(dHnm5Lx`9f*g`-&1A!i>-BDhWwZ|+lT=`*Cbp-j;I8gplU+SHWrSTy;5M=R3T0bn z2!b+SqhL?Aux(?|ckgYM&>P7iVb*Z(m5=?NiMIk1gH=HWu^=mQ9i4PFgY#ey)i;ID zaOjC_UIZyj@eVic*WGjRe3v4p_`|1ti?HQrvKV95n$4i&A$ft{Gln|V%@b;L4}dxI zIm@~2OnOFhB|);Lx4&J!t^EZ!yf~`@yd2HJPA{6OxPQS%7}oAm5;7-5E%pv)>JokN zV>V~2e5CL9cny;?4KYYJi-lt(VnIV5=U$1|e8T1H00|sF%3JMVwQISv2o`jFZM(H-{-rQpzoPzz2_u%)ZIohH=2E?#TTNu zagvht@(8Dm1EyO$djcj?;)3tshS|=$`dCXHb+{^D_dQTcb(-*o-6WvWC-Bnsrz}?kNhGLiJ%lzx#L%3J2nza71lAAA*X8@D3t_oDAP`VRy zOyCJiPRe0tC9z=L&D5*nC4wn&Gtwxj6~Pbpg{Q}U9ImH!5+X#2Wk`qiS=MX6O;k>t zsiEB`jKxT3nO~X=+su}Qrm;)C{&Td zTFSbYUNhif*>vMj+w`$;gb~;v2JBio4e;CL2oJX-zLxQwC(|DBe=b%JmrZprstPrte;!x=K>K=0B<#dX4i{i1?$#XC)mGgavur=&TJEd;b z16vxU9#fDj>0?AlQL$C_7j*u{oqyyf1jG`$_zKPLrX8hG{_9qO?A*&i~pRq-Ml zEK#LSTN;D%1N7LWDuKYNLfPDIvj@>X7-V>>HbMR5=@=~6v{!BWsJ>z1giY9jI8A4H zX_4M@@8+cDWai}N6y}twGlJCM&+zonz3Pfis8fx+N;hJ=FUSctw@adwpio=kEB$S2 zT&J~SAt{Xv7dJ#v`?QjZ<`(GyUeLi*h#g3NfNPv>227r4plw~~51SYVZ)dn0HmG76 zUVzep;g_C?yg!+SdfL#MRs3YP%TqXlZ@ODb10y(yNCz=6&g&~q6JXl|HHM`k$88qd zLeh=q{M8xZPh>!~qBqt(F*~hj*dCM0)>U!Fl&>ZsgH12iTpiD~^p*_UPk3d&#&RE0 zH#Ivq05o2A<&7~)oNEa0|31WO5(|d)Ry$7ge{TG}wQGkMdGgL_>*ft&7@EQzg^XvdBv{PfbF~QA~(xzruDDXcUcsDSQw5RyZGpUrK;phC-zAq?T=ed^75G_ ztUfmSc)9X=y4D;zKksqtqV4=}8lu{3;~LWgsYLLq;y0!2apLmS(+6EJcvhPx{ z?WRQ>(=IDQoxH4usx5o{A}tgi(kLP$#~))+Q|~%xH)H#nC6zah{&3%o=VI<5K`5bL zSNAzB;S3P={4cunow>DSL#P08$Z{lElyOu})N&MAv~hG!^#9s&Ois-5QhnOp3K-s% z2gu@#S3D`^RKa28#FAZhjFSy5`odjPUcdk9lx0e4I6Y2!)VgzJE#t_=F)N9s2b^VlNie-6%3BVR$w)k7#KQZ;n$ODMD#{-L1dyAV@s&bxHj_CL z9PON_#ga7yO2MI8$~%bx6gjK{_bmB;1yV!T6nBoPsNIou(6cy&a;@$-6U(y&?fVPe ziO-XYJosWJWeXXJo;19L4Hl(k-nyQxXgI_7lq~`4 zBOSig(PKFNBA5Y95)EMcM$}cml>4mk|F@f#+@&T+g1DAs;5jR~VW}qa7s!_5d)&%- zJr=7i*G(IZzhh+|u~YIhTG!PA438=Y&*Wc3Qo+?Bv&FlIqeHP@LQ*nha_00Ggk)MU z8Mjg-0PQnHB)v0CdAnU^&BxA%v8w;ah;n%fDUY*KFdl-(FmzmmrYe`u-<-*bX1atO z6FD~1o$>aNT+bT!MiyNeML=c9wcn1P8bf#qK; z>0xFPv+<>fzsfu4=)*yc0CT?cNO`2}5smH7=;YbM8iKJU@4W+;>)5|mUWIi)yC^*i z1*A|twDla_H2!@1)%$!B{GBh`4QDD(AG_#ht5OCOXXcUrZ*jK+x0GS}(j=RO;K%P@ zfQycs5)C!1r5?`Qtu=-Cjg!Wr0Ksvyqx11Dv`HQ|@T^jbX9lT2E@H+`RU9V_8iCf? zvExsyV?#D)IyiaV+A5#RPg&8W_uSThb>nVkkF40+y*w$u1tCtmNS-)^>QtqfuDt43 zL%7O^MFcNH_K{T6zUF#YsmLNDE96Tw0(+?Fm9(dd_$FzzXE*l{%{rYj!eneP&^Y2M zmwM_CKz&0W2A&vi-PR`2i4Rx5?CZU=zjAF{WJcg}byEOKm!XB9`F;NvP4uJ7pm|e; zirKS_nmJ@yZ{SgDrGUVh!imy}%8A;E#>pzzRPHr-kn`wMlMZ%Hr7EIh zqRMP7Vm{)6t|Y(2MgOs-mCb-_h6DAfQjhO5;2Jr07=cTXVgUxT)^}M6T%`SB7k3js zI*x4j*e{qXWH(?~R!KoD0xfCpFpQ78<@>BpjAI(mmPf409FN}$U_Y}0i?KYqzolUA zeUU~3khqn^jc#AMU)JZc+F~5uq*KqLMSw_k9fMI8#Y#aSr2=f&-I$_PpPcWan)b?Jux@tJFz%R*?u1q5GKj z!himOWaa@GdXgQ8^i$IOLnSmNe8ad39{5c{)oS zj47F1qI+ug*jWTT6HDE@Ue%WGIe=woAU5Rrq3BcaZFWy@$gh#?-qR6S-eurCbgtVo zL+VbX>_iswAaX0arrXdGU!ENHvj|ue%)CEW-90n8%Q&cp;rE@ek=bKd?SmIgT_fL( z9qaCH&#tM*?luPHH`)+80>!~b%2-e2HE4{YO6hx--Q{622p#17jfwa2N8)Ro_%iMD z=VR;9il^`QKyCgIT7|mwr|w=gYmqMsAZaM~``|gW(Mq*>TfAQ*5t|THZ%d^wF?b(G zC1kA;7Er?vYc_Lij&+Z!`6Dp_MitaEtqaiJYit{Fnrj!@hA@Az$QS;QqC!xk(WmgS z@7S0*Nl|LoA7K^6&BX)7zl-;ZZ;JuV5DJ}FX=drGDyXg)zCe<3Yz~>Tvm$}k7*uHGxX^~U{Mx-IB|dxS6IvMv_0o(Vj$cJGmh z9K-TD_Y54|;ecc8X)JzO6MO*W=WvR>H~V>`YM?Mm_6inzybgTsJbwP6QegsiUK?b| z3zx+OSW;L^jEW|)KmXCR=_Hdx-X3tTV_m>b|8f1V-$=u^yAwvZeFT@Dg+E?M)e+@d zKBJvCgp0EDsnMz`??>g>s;a?(F#ZV2NkXpS7zbtPVkMBx{VY)jqwb7 zLh+99;An7&ZIS5u;}E;iJ7R}MG6TYH>uN3yU;y^$_?(IDytM7WHb{ah#$?C}Bz1!h zObYV@1kNlzTn7~djoZJhEWPe{O2R&@v6_T^W0=j}9(vG536LG<+&ym55~B6W(-+Bm ziH=yrMIjvtph2M7!%RD_@}{ZvGdV=C0sui^Hx|pj5nnw>1siRp-r% z!1lxVLJ7F2%&uCdKsh3#r_488V~L~dv&W%)$p^MMG3Se!1~r(uRU}fLjB4P*CGFOj zkvn^BIpLMe-OL#L#ym0RN=mHgrEdh@_C;VAGcio>)`MOfF6_}EB57d) zP{(x38%o5r>$V!qn0S`){6_cH)Wx3ys`mVT~=d;5VV^hJ6$Gy?&t4iuiVcYBeuB@Mk;pyRPGDafeaFrENLcH z6L^^3%2(qdjK#-Z0o2qzHI_=29t#u=S&8=3@ zsSOlgaMOM&%9Mxr68##Ix6U52*?%+rfu zMI^-q;e#d<+ver(I@DnVl|1}IFoL<`F$Y_PaT}U9YhcJ!Ys{JEXF^{AiqTjOKp0=A zY=_}K1Yq`EL4v|hG&NE~kLf2l@U2w#P5dbm@PGWqa~xVYXYSx)lNbh}#B)mxl^|SV zf(-*FiM#@_+ma@LK&}`_emvxDvt%MOm+?HE$6^XUu`>0LLxtUE@oX7~KNy7CXA^{5 zHv*Q}Sdie}G_lxn2a!x9t8X>KlDS@=MZVU>-1W>KhvFdK&JN3Ssw#0iD$A%KZ~ll| z5HMJ*UjoXU@PmiEBhn3qXm84?goi@fyR^2O?mg9K9PS43)QSP8LE9YdnmnZ3qMa z=HnG?%jO((t%PZ=lNRQkk@Cl6z8Op?L8>h4lok+tMz{6f0$cg3Ys%c^!97L1u7KP0 z@;3Y>7Weh+iXp_3VAXtjio4(93h=6g%XM@+q|j*OZ1mgegjc zA6655Zfyhqy1i1}&NvJphBh>HYHGufYN@(GBr-!K06*&+Uf!_b4qa@mGG7A^6Cx&q zlZJ#5LL;1fKKrm_K2X-ju$U7GKhc`BL_cV`aFUi~tAypAdI*jkB>>X@{-bIGatCb0 zfrQ?W46i{{DPNM}=XrnFn6wx0CUyR#gI((V$w~{G`oPZ}K5BKYFW$a%_;$bfVbN@q z5>t;FH|O>)2%N(PL{$l2ZJ$auKdY{a=ov$~9Zp_MmO-(qUz6fljEE&Z7R|!X+tIf; z@;4p^^^2gm4X4Meyc~dgiIvTV`xf7x0+1B7VsZVs>6cFi(OMf$AVngj8N7~gp?5%3WiQpaSzDgfLfRoe7;;5Yv|qITiw{6vKvLH2>!m8$ zRBDKE&4Zp-Syj8!I#_H9$vzGNt)`=T2_-|VAjw{UySU|8Ki0EqmNRGSJ7XjidlVGk zbj3&h+u)-0+9qfZlTOHoVZ~mwY5R^6v~c(v7fw`?cU`|$6EQ%TLr!*SaxNW9L6PNk z;dIpH3BAWAvtQF7`60y$+ITE39!O&PtBUYF9lNE`Rg!JG|cx99Rl$c}P=(6j!6d2_yO66>NuXJgn|=;{;W=66miMK6Wn^ z`p*0*J$9=%`mifU1_v4wP9Ux2G>LH&zrF!GCA~UAT(Ced1vF9CE(?ep z`=`tW5=ynRy1Jq5rl&JX7(bT?4jnWN9q(`MFy(zmvZxa11R}#@U~#T+Z+2 zYbxt(Tp#YL)l69^5ZLoXfs&blXxkO7oPz=$TpL(no`tOj3}Ag?z)@OF^CqZW#x~<^ z5cB5Xs>|2j=XHWnwM6K(zvg}5jtofQxd4mzlQKDf=*z1#F+^#3gz?E7$48I%)rP6jtYhGS?RXk(K<~$&F~w!KjWfX-(gb(wHi`Z}lql!j*onL!v36 zcmOOy9b%_{!sXMZXdLFurSdDXaWjiH>n#+lMc2QI$K;(eTlH` z{oM`{Om(uWfqG-+xN|rZII%An&MjM1ER#F)%v&d1mUf>>O>>CND58q=1Mwx{ zLs?p5+)~tZApjkVzG;F3=#*G-)R7P2UeH?>xnoUxrWczUIJ@*7g>#1^tz~UYZE|i522Snt^VTB=f)Uj<6s$}vrfgNk;l~$ zWcLX5o<)jQ|BPn8g~yF#6oaw|4=RmMDD;D*B3b5S$MsX(-3EOp@g8Q1ffC%n{l`I@ z5C1obbG*|mWuV6=@a`vzhEKOdU@~x?R(DTk!I(8Kl9|74}6Xu1z^~pRxwpprMA){6)Af} z76v}XU1zT~L=qVBf)Nf38tn$AL=zzRL`a032je^EWPgUuX3>wYj`F!U}YEl}q02(?`00?hyBPx{m@%b(IThjbFot+3%azlAx zQ~HK%hPkt9Fa@UrVb4n@k;`q6!OG>QI>t#mV%`wx2Ql4X&S2kBL@t0=L4;<|0==iL z-lpv&7VAf=uX7w-mRKSt53gWC>nUx+b`P!?!4FVZ!NbcqPb0Z--VpOM)_q^!c0{p3Oefov zke<-pqPFHvPas3-BM3-Egf{&PA*@QdO8ry&AJ2_|t2hnlc$XCIl|gZ2ab|Iava4*u zBl0)j@wPHRy(e%``3Yx!#E^gA<+s8BZy%<%YdP7d^wlnchQ_95dJa5SsQs0isp*lq zEb}#c?)DK}t2mz2)May(O-&5>dwYOC#SWhA#u_2f;l}sJJmR!YqP0xUm$QG%tpwns zU=J}z#bo}d$qZ#7KS;4aD*2(XdNoI0s{oHk&DFHLi(xDg2&JDU@E|DX%^yfNnhC=e z8zvQyC#n94PPmK|WUs*IXyMmsHo%JoJ@~H~i*;PT4zHY`coa-vpJm9GrfM5GT4Trz z5)S||?IGSAxo?v-ZZDMMH6R44J?s|kNWW{~r7G$egX~DJz@N~s-54N)s)PQC3;Lh1 zOQH1P8&9ZAVmV%Oo#Tm&^DTVV-j#{Cj78S0*b zU>PjJSJ&dyX2A`~)L8oJr#x7swT#WyuLyxR8OZTrGNI>J&+x$KBaf8sw@cZ&e_4c6?JJN;`MWL{PDepD!&dJx&@N`W^+syHgPB$ zSQgm0clHcGa+BzQQOdrGv8YgK*Y%8;xte-TJG!rPrsUmTC(F$|iQ-{~c(Ok`#%g9V z`SegHYg|>s#Ms`jfXM%WMZXFRqrjtuwh=ZcSFU+5skZa3>2c&CHjyGyj>PV4{)`HJ zHUqoh`ctVCb9OO18Uwp(r&Svoc9G56nJJ27*S2%p)z>j(#9E}eW{Nn`)H@L_O7es3 z-zj5@t{DGTiET)qpU;44b7^I1NJBt$fLVA7xu^>vBu4W^O>XWQ= z0m5-g$m#B7D{Rmoba*G09FeI4y=^>{iF(Unp`39X(NV@^~mzziBS;6POm7Cyw7G3^e2fzanu(vUPfXb_laQUa{K@WGh)`rw0yluD3e8wh--C&X4+vni@sQCdVZavD z=LwZQ>xisb=EGC!xytWXo*Mu{UhwCx^0VkhDzJE3{_|9=xK0yzB2HZhzB9AokMFQ( z(>P}Ta){IvU{F4=tpM+062R}v(C%m2uzC>u8dh7B;m-+S3Y4sk9UoGUv&ZZqo)~g< z<~TDE^UgHFV~Ic4k)qu#?IZ4;xgRqmbz>uY@pkNf#2Y7~iYMQt>YQz>E zC)jziRxED8*5?aiJZr#WwIdedcI2gybgn~sSZ=X$pptHLKi!mj>nt)>u)`Y9+5U2M zqu6u>IT)O6SWJR%v4*f(-A;3Wba02|2&W=rcApBkJfIBjZzWRQZE zfjn3~rd!>XN_^T%s`Jqhv+q%~5$oJUnN|nt4nxt9O&iW|_!c7>D~!A4W?Nz{VZJKR z7dYGq!pRSJCiMbWeSN`{i|Rp?&q%q1BvJo83L2rsV!G2-hW-TBheU*S_emL_^mUJe z^g0Uvh!RF@?PEmIiV~@$xsLlE=Gd&I+v)Pqb?btpbHm<`zZj}n5#qUFdhq%djU(?B z*^lP9Snb3zXpNKd@-ZoY|FhJcUyQ7A=KD6xA!!BKknNX{_HXCx#M0pYY+)<(AJ_g^ zJ;9a(+HZ+O#CJ*34c4u4P zmk7dc^Rn~GSJO-c5+uIojnqep$Bj6irBXI!L877~NN|%+8AHdWO8?LSJJv_e?#zFMRhEDYq|!ecuO~&S>&_dH;iJyL-$D